From 4c66cbb0875cc4635fa45c96d9a7a36c76db5684 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 16 Dec 2016 16:57:05 -0500 Subject: [PATCH 1/2] legislature-tracker fix (new tabletopjs, additional referencingin the index.html) --- dist/js/legislature-tracker.0.0.3.min.js | 6 +- dist/js/legislature-tracker.latest.min.js | 6 +- index.html | 17 + js/lib/tabletop.js | 457 ++++++++++++++++++++++ 4 files changed, 480 insertions(+), 6 deletions(-) create mode 100644 js/lib/tabletop.js diff --git a/dist/js/legislature-tracker.0.0.3.min.js b/dist/js/legislature-tracker.0.0.3.min.js index 31c9ac3..bebeba8 100644 --- a/dist/js/legislature-tracker.0.0.3.min.js +++ b/dist/js/legislature-tracker.0.0.3.min.js @@ -1,5 +1,5 @@ -/*! legislature-tracker - v0.0.3 - 2013-06-17 +/*! legislature-tracker - v0.0.3 - 2016-12-16 * https://github.com/MinnPost/legislature-tracker -* Copyright (c) 2013 ; Licensed MIT */ +* Copyright (c) 2016 ; Licensed MIT */ -!function(a){_.mixin({trim:function(a){return _.isString(a)&&(a=String.prototype.trim?a.trim():a.replace(/^\s+|\s+$/g,"")),a},cssClass:function(a){return a.replace(/[^a-z0-9]/g,"-")},numberFormatCommas:function(a){return a.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")},ellipsisText:function(a,b){var c,d,e,f,g="",h="",i='[[[TEXT]]]',j='...',k='[[[TEXT]]]';return-1!==a.indexOf(h)?(c=a.indexOf(h),g+=i.replace("[[[TEXT]]]",a.substring(0,c))+" ",g+=j+" ",g+=k.replace("[[[TEXT]]]",a.substring(c,a.length))+" "):(f=a.split(" "),f.length<=b?g+=i.replace("[[[TEXT]]]",a):(d=f.slice(0,b),e=f.slice(b),g+=i.replace("[[[TEXT]]]",d.join(" "))+" ",g+=j+" ",g+=k.replace("[[[TEXT]]]",e.join(" "))+" ")),g},parseURL:function(a){var b=document.createElement("a");return b.href=a,b}}),_.isFunction(Backbone.$.jsonp)&&(Backbone.ajax=function(){return Backbone.$.jsonp.apply(Backbone.$,arguments)}),a.fn.hasScrollBar=function(){return this.get(0)&&this.get(0).scrollHeight?this.get(0).scrollHeight>this.height():!1}}(jQuery,window);var LT,originalLT,exports=exports||void 0;_.isUndefined(exports)?(originalLT=window.LT,LT={},LT.noConflict=function(){return window.LT=originalLT,this},window.LT=LT):LT=exports,function(a,b,c){LT.cache={},LT.cache.models={},LT.log=function(a){_.isUndefined(window.console)||window.console.log(a)},LT.utils={},LT.utils.getModel=function(a,b,c,d){var e=a+":"+b+":"+c[b];return d=d||LT.options,_.isUndefined(LT.cache.models[e])&&(LT.cache.models[e]=new LT[a](c,d)),LT.cache.models[e]},LT.utils.fetchModel=function(b){var c;return b.get("fetched")!==!0?b.fetch():(c=a.Deferred(),c.resolveWith(b),c)},LT.utils.translate=function(a,b){var c=b;return _.isObject(LT.options.wordTranslations[a])&&_.isString(LT.options.wordTranslations[a][b])&&(c=LT.options.wordTranslations[a][b]),c},LT.utils.imagePath=function(a){return 0===a.indexOf("http")?a:LT.options.imagePath+a},LT.templates=LT.templates||{},LT.utils.getTemplate=function(b,c,d,e){var f="js/app/templates/"+b+".html",g=LT.options.templatePath+b+".html";_.isUndefined(LT.templates[f])?a.ajax({url:g,method:"GET",async:!1,contentType:"text",success:function(a){LT.templates[f]=_.template(a),c[d]=LT.templates[f],_.isFunction(e)&&e.apply(this,[a])}}):c[d]=LT.templates[f]},LT.parse=LT.parse||{},LT.parse.eData=function(a){var b={};b.categories=LT.parse.eCategories(a.sheets("Categories").all());var c=a.sheets("Bills").all();return c.length>LT.options.maxBills&<.log("The number of bills in your spreadsheet exceeds maxBills. Set the maxBills option to display them, but be aware that this may significantly slow down the Legislature Tracker."),b.bills=LT.parse.eBills(c.slice(0,LT.options.maxBills)),b.events=LT.parse.eEvents(a.sheets("Events").all()),_.each(_.groupBy(b.events,"bill_id"),function(a,c){_.each(b.bills,function(d,e){d.bill===c&&(b.bills[e].custom_events=a)})}),b},LT.parse.validateBillNumber=function(a){return LT.options.billNumberFormat.test(a)},LT.parse.eBills=function(a){return _.map(a,function(a){return LT.parse.translateFields(LT.options.fieldTranslations.eBills,a),a.links=LT.parse.eLinks(a.links),a.categories=a.categories?a.categories.split(","):[],a.categories=_.map(a.categories,_.trim),a.bill_primary=c,a.bill&<.parse.validateBillNumber(a.bill)?a.bill_primary=LT.utils.getModel("OSBillModel","bill_id",{bill_id:_.trim(a.bill)}):a.bill&&!LT.parse.validateBillNumber(a.bill)&<.log('Invalid primary bill number "'+a.bill+'" for row '+a.rowNumber+", see documentation."),a.bill_companion&<.parse.validateBillNumber(a.bill_companion)?a.bill_companion=LT.utils.getModel("OSBillModel","bill_id",{bill_id:_.trim(a.bill_companion)}):a.bill_companion&&!LT.parse.validateBillNumber(a.bill_companion)&<.log('Invalid companion bill number "'+a.bill_companion+'" for row '+a.rowNumber+", see documentation."),a.bill_conference&<.parse.validateBillNumber(a.bill_conference)?a.bill_conference=LT.utils.getModel("OSBillModel","bill_id",{bill_id:_.trim(a.bill_conference)}):a.bill_conference&&!LT.parse.validateBillNumber(a.bill_conference)&<.log('Invalid conference bill number "'+a.bill_conference+'" for row '+a.rowNumber+", see documentation."),a.hasBill=!0,a.bill&&a.bill_primary!==c||(a.hasBill=!1,a.bill=_.cssClass(a.title.toLowerCase())),a})},LT.parse.eCategories=function(a){return _.map(a,function(a){return LT.parse.translateFields(LT.options.fieldTranslations.eCategories,a),a.links=LT.parse.eLinks(a.links),a})},LT.parse.eEvents=function(a){return _.map(a,function(a){return LT.parse.translateFields(LT.options.fieldTranslations.eEvents,a),a.links=LT.parse.eLinks(a.links),a.date=moment(a.date),a.type=["custom"],a})},LT.parse.eLinks=function(a){var b=[];return a=_.trim(a),0===a.length?b:(a='"'===a.substring(0,1)?a.substring(1):a,a='"'===a.substring(a.length-1,a.length)?a.slice(0,-1):a,b=a.split('", "'),b=_.map(b,function(a){return{title:a.split("|")[0],url:a.split("|")[1]}}))},LT.parse.csvCategories=function(a){return a=_.trim(a),0===a.length?[]:(a='"'===a.substring(0,1)?a.substring(1):a,a='"'===a.substring(a.length-1,a.length)?a.slice(0,-1):a,a.split('", "'))},LT.parse.detectCompanionBill=function(a){var b,d;return _.isFunction(LT.options.detectCompanionBill)?(b=LT.options.detectCompanionBill(a),d=LT.parse.validateBillNumber(b)?b:c):_.isRegExp(LT.options.detectCompanionBill)&&(b=LT.options.detectCompanionBill.exec(a),d=b&<.parse.validateBillNumber(b[1])?b[1]:c),_.trim(d)},LT.parse.translateFields=function(a,b){return _.each(a,function(a,c){b[c]=b[a],c!==a&&delete b[a]}),b},LT.defaultOptions={sheetsWanted:["Categories","Bills","Events"],fieldTranslations:{eCategories:{id:"categoryid",short_title:"shorttitle"},eBills:{bill:"bill",bill_companion:"companionbill",bill_conference:"conferencebill",categories:"categories",title:"title",description:"description"},eEvents:{bill_id:"bill",actor:"chamber",action:"title"}},wordTranslations:{chamber:{upper:"Senate",lower:"House"},partyAbbr:{"Democratic-Farmer-Labor":"DFL",Democratic:"D",Republican:"R"}},maxBills:30,substituteMatch:/substituted/i,imagePath:"./css/images/",templatePath:"./js/app/templates/",recentChangeThreshold:7,tabletopOptions:{},scrollOffset:!1,conferenceBill:!0,recentImage:"RecentUpdatedBill.png",chamberLabel:!1,detectCompanionBill:/([A-Z]+ [1-9][0-9]*)$/,billNumberFormat:/[A-Z]+ [1-9][0-9]*/,osBillParse:!1}}(jQuery,window),function(a){LT.OSModel=Backbone.Model.extend({urlBase:function(){return"http://openstates.org/api/v1/"},urlEnd:function(){return"/?apikey="+encodeURI(LT.options.OSKey)+"&callback=?"},url:function(){return this.urlBase()+encodeURI(this.osType)+"/"+encodeURI(this.id)+this.urlEnd()},initialize:function(a,b){this.options=b,this.on("sync",function(a){a.set("fetched",!0)})}}),LT.OSStateModel=LT.OSModel.extend({url:function(){return this.urlBase()+"metadata/"+encodeURI(this.options.state)+this.urlEnd()}}),LT.OSBillModel=LT.OSModel.extend({url:function(){return _.isUndefined(this.id)?this.urlBase()+"bills/"+encodeURI(this.options.state)+"/"+encodeURI(this.options.session)+"/"+encodeURI(this.get("bill_id"))+this.urlEnd():this.urlBase()+"bills/"+this.id+this.urlEnd()},initialize:function(){LT.OSBillModel.__super__.initialize.apply(this,arguments),this.on("sync",function(){this.parseOSData()})},parseOSData:function(){var a;this.set("created_at",moment(this.get("created_at"))),this.set("updated_at",moment(this.get("updated_at"))),a=this.get("action_dates"),_.each(a,function(b,c){a[c]=b?moment(b):b}),this.set("action_dates",a),a=this.get("actions"),_.each(a,function(b,c){a[c].date=b.date?moment(b.date):b.date}),this.set("actions",a),a=this.get("votes"),_.each(a,function(b,c){a[c].date=b.date?moment(b.date):b.date}),this.set("votes",a),a=this.get("custom_events"),_.isArray(a)&&a.length>0&&this.set("actions",_.union(this.get("actions"),a)),this.set("actions",_.sortBy(this.get("actions"),function(a,b){return-1*(a.date.unix()+b)})),this.set("newest_action",this.get("actions")[0]),LT.options.osBillParse&&_.isFunction(LT.options.osBillParse)&<.options.osBillParse(this)},getActionDate:function(a){return this.get("action_dates")[a]?this.get("action_dates")[a]:!1},isSubstituted:function(){var a=!1;return _.isBoolean(this.get("substitued"))?a=this.get("substitued"):LT.options.substituteMatch===!1?a=!1:(a=_.find(this.get("actions"),function(a){return a.action.match(LT.options.substituteMatch)}),a=a?!0:!1,this.set("substitued",a)),a}}),LT.OSLegislatorModel=LT.OSModel.extend({osType:"legislators"}),LT.OSCommitteeModel=LT.OSModel.extend({osType:"committees"}),LT.BillModel=Backbone.Model.extend({initialize:function(a,b){this.options=b},loadOSBills:function(){var b=this,c=[];return _.each(["bill_primary","bill_companion","bill_conference"],function(a){b.get("hasBill")&&b.get(a)&&c.push(LT.utils.fetchModel(b.get(a)))}),a.when.apply(a,c)},loadOSCompanion:function(){var b,c=[];return this.get("hasBill")===!0&&!this.get("bill_companion")&&_.isObject(this.get("bill_primary"))&&_.isArray(this.get("bill_primary").get("companions"))&&_.isObject(this.get("bill_primary").get("companions")[0])&&(b=LT.parse.detectCompanionBill(this.get("bill_primary").get("companions")[0].bill_id),b&&(this.set("bill_companion",LT.utils.getModel("OSBillModel","bill_id",{bill_id:b})),c.push(LT.utils.fetchModel(this.get("bill_companion"))))),a.when.apply(a,c)},loadCategories:function(){this.get("categories")&&this.set("categories",_.map(this.get("categories"),function(a){return _.isObject(a)||(a=LT.utils.getModel("CategoryModel","id",{id:a})),a}))},lastUpdatedAt:function(){var a,b=this.get("bill_primary"),c=this.get("bill_companion"),d=this.get("bill_conference");return _.isUndefined(this.get("last_updated_at"))&&b.get("updated_at")?(a=b.get("updated_at"),c&&c.get("updated_at")&&(a=c.get("updated_at").unix()>a.unix()?c.get("updated_at"):a),d&&d.get("updated_at")&&(a=d.get("updated_at").unix()>a.unix()?d.get("updated_at"):a),this.set("last_updated_at",a)):_.isUndefined(this.get("last_updated_at"))&&!b.get("updated_at")&<.log("Could not fetch primary bill data from OpenStates. Check that the id "+this.get("bill_primary").get("bill_id")+" is formatted properly."),this.get("last_updated_at")},newestAction:function(){var a,b=this.get("bill_primary"),c=this.get("bill_companion"),d=this.get("bill_conference");return this.get("hasBill")&&_.isUndefined(this.get("newest_action"))&&b.get("newest_action")&&(a=b.get("newest_action"),c&&c.get("newest_action")&&(a=c.get("newest_action").date.unix()>a.date.unix()?c.get("newest_action"):a),d&&d.get("newest_action")&&(a=d.get("newest_action").date.unix()>a.date.unix()?d.get("newest_action"):a),this.set("newest_action",a)),this.get("newest_action")},parseMeta:function(){var a={upper:!1,lower:!1,conference:!1,signed:!1,last:!1},b={companion:this.get("bill_companion")?!0:!1,conference:this.get("bill_conference")?!0:!1};if(this.get("custom_events")&&this.set("custom_events",_.sortBy(this.get("custom_events"),function(a,b){return-1*(a.date.unix()+b)})),this.get("hasBill")){if(b.companion&&(this.get("bill_companion").isSubstituted()&&(b.substituted=!0),this.get("bill_primary").isSubstituted()&&(b.substituted=!0)),(!b.companion||b.substituted)&&(a.lower=this.get("bill_primary").getActionDate("passed_lower"),a.upper=this.get("bill_primary").getActionDate("passed_upper")),b.companion&&!b.substituted&&("upper"===this.get("bill_primary").get("chamber")?(a.upper=this.get("bill_primary").getActionDate("passed_upper"),a.lower=this.get("bill_companion").getActionDate("passed_lower")):(a.lower=this.get("bill_primary").getActionDate("passed_lower"),a.upper=this.get("bill_companion").getActionDate("passed_upper"))),b.conference){var c=this.get("bill_conference").getActionDate("passed_lower"),d=this.get("bill_conference").getActionDate("passed_upper");c&&d&&(a.conference=c.unix()>=d.unix()?c:d)}a.signed=b.conference?this.get("bill_conference").getActionDate("signed"):this.get("bill_primary").getActionDate("signed"),a.last=b.conference?this.get("bill_conference").getActionDate("last"):b.companion?this.get("bill_companion").getActionDate("last").unix()>=this.get("bill_primary").getActionDate("last").unix()?this.get("bill_companion").getActionDate("last"):this.get("bill_primary").getActionDate("last"):this.get("bill_primary").getActionDate("last"),this.get("description")||this.set("description",this.get("bill_primary").get("summary"))}return this.set("actions",a),this.set("bill_type",b),this}}),LT.CategoryModel=Backbone.Model.extend({initialize:function(a,b){this.options=b,this.set("bills",new LT.BillsCollection(null)),this.getBills()},getBills:function(){var a=this,b=LT.app.bills,c=this.get("id");return b.each(function(b){-1!==_.indexOf(b.get("categories"),c)&&a.get("bills").push(LT.utils.getModel("BillModel","bill",b.attributes))}),this},loadBills:function(b,c){var d=[],e=this;return this.get("bills").each(function(a){d.push(a.loadOSBills())}),a.when.apply(a,d).done(function(){var d=[];e.get("bills").each(function(a){d.push(a.loadOSCompanion())}),a.when.apply(a,d).done(function(){e.get("bills").each(function(a){a.parseMeta()}),b()}).fail(c)}).fail(c),this}})}(jQuery,window),function(){LT.CategoriesCollection=Backbone.Collection.extend({model:LT.CategoryModel,comparator:function(a){return-1!==a.get("title").toLowerCase().indexOf("recent")?"zzzzz":a.get("title")}}),LT.BillsCollection=Backbone.Collection.extend({model:LT.BillModel,comparator:function(a){var b=a.newestAction()?-1*a.newestAction().date.unix():a.get("title");return b}}),LT.OSBillsCollection=Backbone.Collection.extend({model:LT.OSBillModel,comparator:function(a){var b=a.get("newest_action");return b&&(b=-1*b.date.unix()),b}})}(jQuery,window),function(a,b){LT.MainApplicationView=Backbone.View.extend({initialize:function(){this.$el.addClass("ls"),this.templates=this.templates||{},LT.utils.getTemplate("template-loading",this.templates,"loading"),LT.utils.getTemplate("template-error",this.templates,"error"),LT.utils.getTemplate("template-ebill",this.templates,"ebill"),LT.utils.getTemplate("template-osbill",this.templates,"osbill"),LT.utils.getTemplate("template-category",this.templates,"category"),LT.utils.getTemplate("template-categories",this.templates,"categories"),LT.utils.getTemplate("template-header",this.templates,"header"),_.bindAll(this)},events:{"click .bill-expand":"expandBill","click .expand-other-bills":"expandOtherBills"},loading:function(){return _.isNumber(LT.options.scrollOffset)&&(this.initialLoad===!0?this.resetScrollView():this.initialLoad=_.isUndefined(this.initialLoad)?!1:!0),this.$el.html(this.templates.loading({})),this},error:function(a){return this.$el.html(this.templates.error({error:a})),this},renderCategories:function(){this.$el.html(this.templates.categories({categories:LT.app.categories.toJSON(),options:LT.options}))},renderCategory:function(a){_.isObject(a)||(a=LT.app.categories.get(a)),a.get("bills").sort(),this.$el.html(this.templates.category({category:a.toJSON(),templates:this.templates,header:this.renderHeader()})),this.getLegislators().navigationGlue()},renderEBill:function(a){_.isObject(a)||(a=this.router.bills.get(a)),a.newestAction(),this.$el.html(this.templates.ebill({bill:a.toJSON(),expandable:!1,templates:this.templates,header:this.renderHeader()})),this.getLegislators().addTooltips().checkOverflows().navigationGlue()},renderOSBill:function(a){this.$el.html(this.templates.osbill({bill:a.toJSON(),detailed:!0,templates:this.templates,header:this.renderHeader()})),this.getLegislators().addTooltips().checkOverflows().navigationGlue()},renderHeader:function(){return this.templates.header({categories:LT.app.categories.toJSON()})},expandBill:function(b){b.preventDefault();var c=a(b.target),d=["More detail","Less detail"],e=c.text();return c.text(e===d[0]?d[1]:d[0]),c.parent().toggleClass("expanded").find(".bill-bottom").slideToggle(),this.checkOverflows(),this},expandOtherBills:function(b){b.preventDefault();var c=a(b.target),d=["Show other bills","Hide other bills"],e=c.text();return c.text(e===d[0]?d[1]:d[0]),c.parent().find(".has-conference-bill").toggleClass("showing").slideToggle(),this.checkOverflows(),this},getLegislators:function(){return this.$el.find(".sponsor:not(.found)").each(function(){var b=a(this),c=b.data();if(c.id=c.legId,c.id){var d=LT.utils.getModel("OSLegislatorModel","id",c);a.when(LT.utils.fetchModel(d)).then(function(){new LT.LegislatorView({el:b,model:d}).render()})}}),this},addTooltips:function(){return this.$el.find(".bill-progress .bill-progress-section.completed").qtip({style:{classes:"qtip-shadow qtip-light"},position:{my:"bottom center",at:"top center"}}),this},checkOverflows:function(){return this.$el.find(".actions-inner, .co-sponsors-inner").each(function(){a(this).hasScrollBar()&&a(this).addClass("overflowed")}),this},resetScrollView:function(){return a("html, body").animate({scrollTop:this.$el.offset().top-LT.options.scrollOffset},1e3),this},navigationGlue:function(){var c=this.$el.offset().top,d=a(".ls-header");return a(".ls-header-container").height(d.outerHeight()),a(b).scroll(function(){var b=a(this);b.scrollTop()>c&&!d.hasClass("glued")?d.addClass("glued"):b.scrollTop()<=c&&d.hasClass("glued")&&d.removeClass("glued")}),this}}),LT.LegislatorView=Backbone.View.extend({model:LT.OSLegislatorModel,initialize:function(){this.templates=this.templates||{},LT.utils.getTemplate("template-legislator",this.templates,"legislator"),_.bindAll(this)},render:function(){return this.$el.addClass("found").html(this.templates.legislator(this.model.toJSON())),this}})}(jQuery,window),function(a){LT.Application=Backbone.Router.extend({routes:{categories:"routeCategories","category/recent":"routeRecentCategory","category/:category":"routeCategory","bill/:bill":"routeEBill","bill-detail/:bill":"routeOSBill","*defaultR":"routeDefault"},initialize:function(a){LT.options=_.extend(LT.defaultOptions,a),LT.app=this,_.bindAll(this),this.mainView=new LT.MainApplicationView(LT.options),this.mainView.router=this,this.mainView.loading(),this.tabletop=Tabletop.init(_.extend(LT.options.tabletopOptions,{key:LT.options.eKey,callback:this.loadEBills,callbackContext:this,wanted:LT.options.sheetsWanted}))},loadEBills:function(b,c){var d=this,e=LT.parse.eData(c);this.categories=new LT.CategoriesCollection(null),this.bills=new LT.BillsCollection(null),_.each(e.bills,function(a){d.bills.add(LT.utils.getModel("BillModel","bill",a))}),_.each(e.categories,function(a){d.categories.add(LT.utils.getModel("CategoryModel","id",a))}),this.bills.each(function(a){a.loadCategories()}),LT.options.aggregateURL?a.jsonp({url:LT.options.aggregateURL,success:this.loadAggregateCounts}):this.start()},loadAggregateCounts:function(a){var b=this;_.each(a,function(a){"total-bills"===a.stat&&(b.totalBills=parseInt(a.value,10)),"total-bills-passed"===a.stat&&(b.totalBillsPassed=parseInt(a.value,10)),"total-bills-signed"===a.stat&&(b.totalBillsSigned=parseInt(a.value,10))}),this.start()},start:function(){Backbone.history.start()},routeDefault:function(){this.navigate("/categories",{trigger:!0,replace:!0}),this.mainView.render()},routeCategories:function(){var a=this;this.mainView.loading(),this.getOSBasicBills(function(){a.makeRecentCategory(),a.mainView.renderCategories()},this.error)},routeCategory:function(a){var b=this;a=decodeURI(a),a=this.categories.get(a),this.mainView.loading(),a.loadBills(function(){b.mainView.renderCategory(a)},b.error)},routeRecentCategory:function(){var a=this;this.mainView.loading(),this.getOSBasicBills(function(){a.makeRecentCategory();var b=a.categories.get("recent");b.loadBills(function(){a.mainView.renderCategory(b)},a.error)},this.error)},routeEBill:function(a){var b=this,c=decodeURI(a);return(a=this.bills.where({bill:c})[0])?(this.mainView.loading(),a.loadOSBills().done(function(){a.loadOSCompanion().done(function(){a.parseMeta(),b.mainView.renderEBill(a)})}).fail(b.error),void 0):(this.navigate("/bill-detail/"+encodeURI(c),{trigger:!0,replace:!0}),void 0)},routeOSBill:function(b){var c=this;b=decodeURI(b),b=LT.utils.getModel("OSBillModel","bill_id",{bill_id:b}),this.mainView.loading(),a.when.apply(a,[LT.utils.fetchModel(b)]).done(function(){c.mainView.renderOSBill(b)}).fail(c.error)},makeRecentCategory:function(){if(!this.madeRecentCategory){var a={id:"recent",title:"Recent Actions",description:"The following bills have been updated in the past "+LT.options.recentChangeThreshold+" days.",image:LT.options.recentImage};this.bills.each(function(b){var c=b.get("categories"),d=b.get("hasBill");d===!0&&Math.abs(parseInt(b.lastUpdatedAt().diff(moment(),"days"),10))this.height()}}(jQuery,window);var LT,originalLT,exports=exports||void 0;_.isUndefined(exports)?(originalLT=window.LT,LT={},LT.noConflict=function(){return window.LT=originalLT,this},window.LT=LT):LT=exports,function(a,b,c){LT.cache={},LT.cache.models={},LT.log=function(a){_.isUndefined(window.console)||window.console.log(a)},LT.utils={},LT.utils.getModel=function(a,b,c,d){var e=a+":"+b+":"+c[b];return d=d||LT.options,_.isUndefined(LT.cache.models[e])&&(LT.cache.models[e]=new LT[a](c,d)),LT.cache.models[e]},LT.utils.fetchModel=function(b){var c;return b.get("fetched")!==!0?b.fetch():(c=a.Deferred(),c.resolveWith(b),c)},LT.utils.translate=function(a,b){var c=b;return _.isObject(LT.options.wordTranslations[a])&&_.isString(LT.options.wordTranslations[a][b])&&(c=LT.options.wordTranslations[a][b]),c},LT.utils.imagePath=function(a){return 0===a.indexOf("http")?a:LT.options.imagePath+a},LT.templates=LT.templates||{},LT.utils.getTemplate=function(b,c,d,e){var f="js/app/templates/"+b+".html",g=LT.options.templatePath+b+".html";_.isUndefined(LT.templates[f])?a.ajax({url:g,method:"GET",async:!1,contentType:"text",success:function(a){LT.templates[f]=_.template(a),c[d]=LT.templates[f],_.isFunction(e)&&e.apply(this,[a])}}):c[d]=LT.templates[f]},LT.parse=LT.parse||{},LT.parse.eData=function(a){var b={};b.categories=LT.parse.eCategories(a.sheets("Categories").all());var c=a.sheets("Bills").all();return c.length>LT.options.maxBills&<.log("The number of bills in your spreadsheet exceeds maxBills. Set the maxBills option to display them, but be aware that this may significantly slow down the Legislature Tracker."),b.bills=LT.parse.eBills(c.slice(0,LT.options.maxBills)),b.events=LT.parse.eEvents(a.sheets("Events").all()),_.each(_.groupBy(b.events,"bill_id"),function(a,c){_.each(b.bills,function(d,e){d.bill===c&&(b.bills[e].custom_events=a)})}),b},LT.parse.validateBillNumber=function(a){return LT.options.billNumberFormat.test(a)},LT.parse.eBills=function(a){return _.map(a,function(a){return LT.parse.translateFields(LT.options.fieldTranslations.eBills,a),a.links=LT.parse.eLinks(a.links),a.categories=a.categories?a.categories.split(","):[],a.categories=_.map(a.categories,_.trim),a.bill_primary=c,a.bill&<.parse.validateBillNumber(a.bill)?a.bill_primary=LT.utils.getModel("OSBillModel","bill_id",{bill_id:_.trim(a.bill)}):a.bill&&!LT.parse.validateBillNumber(a.bill)&<.log('Invalid primary bill number "'+a.bill+'" for row '+a.rowNumber+", see documentation."),a.bill_companion&<.parse.validateBillNumber(a.bill_companion)?a.bill_companion=LT.utils.getModel("OSBillModel","bill_id",{bill_id:_.trim(a.bill_companion)}):a.bill_companion&&!LT.parse.validateBillNumber(a.bill_companion)&<.log('Invalid companion bill number "'+a.bill_companion+'" for row '+a.rowNumber+", see documentation."),a.bill_conference&<.parse.validateBillNumber(a.bill_conference)?a.bill_conference=LT.utils.getModel("OSBillModel","bill_id",{bill_id:_.trim(a.bill_conference)}):a.bill_conference&&!LT.parse.validateBillNumber(a.bill_conference)&<.log('Invalid conference bill number "'+a.bill_conference+'" for row '+a.rowNumber+", see documentation."),a.hasBill=!0,a.bill&&a.bill_primary!==c||(a.hasBill=!1,a.bill=_.cssClass(a.title.toLowerCase())),a})},LT.parse.eCategories=function(a){return _.map(a,function(a){return LT.parse.translateFields(LT.options.fieldTranslations.eCategories,a),a.links=LT.parse.eLinks(a.links),a})},LT.parse.eEvents=function(a){return _.map(a,function(a){return LT.parse.translateFields(LT.options.fieldTranslations.eEvents,a),a.links=LT.parse.eLinks(a.links),a.date=moment(a.date),a.type=["custom"],a})},LT.parse.eLinks=function(a){var b=[];return a=_.trim(a),0===a.length?b:(a='"'===a.substring(0,1)?a.substring(1):a,a='"'===a.substring(a.length-1,a.length)?a.slice(0,-1):a,b=a.split('", "'),b=_.map(b,function(a){return{title:a.split("|")[0],url:a.split("|")[1]}}))},LT.parse.csvCategories=function(a){return a=_.trim(a),0===a.length?[]:(a='"'===a.substring(0,1)?a.substring(1):a,a='"'===a.substring(a.length-1,a.length)?a.slice(0,-1):a,a.split('", "'))},LT.parse.detectCompanionBill=function(a){var b,d;return _.isFunction(LT.options.detectCompanionBill)?(b=LT.options.detectCompanionBill(a),d=LT.parse.validateBillNumber(b)?b:c):_.isRegExp(LT.options.detectCompanionBill)&&(b=LT.options.detectCompanionBill.exec(a),d=b&<.parse.validateBillNumber(b[1])?b[1]:c),_.trim(d)},LT.parse.translateFields=function(a,b){return _.each(a,function(a,c){b[c]=b[a],c!==a&&delete b[a]}),b},LT.defaultOptions={sheetsWanted:["Categories","Bills","Events"],fieldTranslations:{eCategories:{id:"categoryid",short_title:"shorttitle"},eBills:{bill:"bill",bill_companion:"companionbill",bill_conference:"conferencebill",categories:"categories",title:"title",description:"description"},eEvents:{bill_id:"bill",actor:"chamber",action:"title"}},wordTranslations:{chamber:{upper:"Senate",lower:"House"},partyAbbr:{"Democratic-Farmer-Labor":"DFL",Democratic:"D",Republican:"R"}},maxBills:30,substituteMatch:/substituted/i,imagePath:"./css/images/",templatePath:"./js/app/templates/",recentChangeThreshold:7,tabletopOptions:{},scrollOffset:!1,conferenceBill:!0,recentImage:"RecentUpdatedBill.png",chamberLabel:!1,detectCompanionBill:/([A-Z]+ [1-9][0-9]*)$/,billNumberFormat:/[A-Z]+ [1-9][0-9]*/,osBillParse:!1}}(jQuery,window),function(a,b,c){LT.OSModel=Backbone.Model.extend({urlBase:function(){return"http://openstates.org/api/v1/"},urlEnd:function(){return"/?apikey="+encodeURI(LT.options.OSKey)+"&callback=?"},url:function(){return this.urlBase()+encodeURI(this.osType)+"/"+encodeURI(this.id)+this.urlEnd()},initialize:function(a,b){this.options=b,this.on("sync",function(a,b){a.set("fetched",!0)})}}),LT.OSStateModel=LT.OSModel.extend({url:function(){return this.urlBase()+"metadata/"+encodeURI(this.options.state)+this.urlEnd()}}),LT.OSBillModel=LT.OSModel.extend({url:function(){return _.isUndefined(this.id)?this.urlBase()+"bills/"+encodeURI(this.options.state)+"/"+encodeURI(this.options.session)+"/"+encodeURI(this.get("bill_id"))+this.urlEnd():this.urlBase()+"bills/"+this.id+this.urlEnd()},initialize:function(a,b){LT.OSBillModel.__super__.initialize.apply(this,arguments),this.on("sync",function(a,b,c){this.parseOSData()})},parseOSData:function(){var a;this.set("created_at",moment(this.get("created_at"))),this.set("updated_at",moment(this.get("updated_at"))),a=this.get("action_dates"),_.each(a,function(b,c){a[c]=b?moment(b):b}),this.set("action_dates",a),a=this.get("actions"),_.each(a,function(b,c){a[c].date=b.date?moment(b.date):b.date}),this.set("actions",a),a=this.get("votes"),_.each(a,function(b,c){a[c].date=b.date?moment(b.date):b.date}),this.set("votes",a),a=this.get("custom_events"),_.isArray(a)&&a.length>0&&this.set("actions",_.union(this.get("actions"),a)),this.set("actions",_.sortBy(this.get("actions"),function(a,b){return(a.date.unix()+b)*-1})),this.set("newest_action",this.get("actions")[0]),LT.options.osBillParse&&_.isFunction(LT.options.osBillParse)&<.options.osBillParse(this)},getActionDate:function(a){return!!this.get("action_dates")[a]&&this.get("action_dates")[a]},isSubstituted:function(){var a=!1;return _.isBoolean(this.get("substitued"))?a=this.get("substitued"):LT.options.substituteMatch===!1?a=!1:(a=_.find(this.get("actions"),function(a){return a.action.match(LT.options.substituteMatch)}),a=!!a,this.set("substitued",a)),a}}),LT.OSLegislatorModel=LT.OSModel.extend({osType:"legislators"}),LT.OSCommitteeModel=LT.OSModel.extend({osType:"committees"}),LT.BillModel=Backbone.Model.extend({initialize:function(a,b){this.options=b},loadOSBills:function(b,c){var d=this,e=[];return _.each(["bill_primary","bill_companion","bill_conference"],function(a){d.get("hasBill")&&d.get(a)&&e.push(LT.utils.fetchModel(d.get(a)))}),a.when.apply(a,e)},loadOSCompanion:function(){var b,c=[];return this.get("hasBill")===!0&&!this.get("bill_companion")&&_.isObject(this.get("bill_primary"))&&_.isArray(this.get("bill_primary").get("companions"))&&_.isObject(this.get("bill_primary").get("companions")[0])&&(b=LT.parse.detectCompanionBill(this.get("bill_primary").get("companions")[0].bill_id),b&&(this.set("bill_companion",LT.utils.getModel("OSBillModel","bill_id",{bill_id:b})),c.push(LT.utils.fetchModel(this.get("bill_companion"))))),a.when.apply(a,c)},loadCategories:function(){this.get("categories")&&this.set("categories",_.map(this.get("categories"),function(a){return _.isObject(a)||(a=LT.utils.getModel("CategoryModel","id",{id:a})),a}))},lastUpdatedAt:function(){var a,b=this.get("bill_primary"),c=this.get("bill_companion"),d=this.get("bill_conference");return _.isUndefined(this.get("last_updated_at"))&&b.get("updated_at")?(a=b.get("updated_at"),c&&c.get("updated_at")&&(a=c.get("updated_at").unix()>a.unix()?c.get("updated_at"):a),d&&d.get("updated_at")&&(a=d.get("updated_at").unix()>a.unix()?d.get("updated_at"):a),this.set("last_updated_at",a)):_.isUndefined(this.get("last_updated_at"))&&!b.get("updated_at")&<.log("Could not fetch primary bill data from OpenStates. Check that the id "+this.get("bill_primary").get("bill_id")+" is formatted properly."),this.get("last_updated_at")},newestAction:function(){var a,b=this.get("bill_primary"),c=this.get("bill_companion"),d=this.get("bill_conference");return this.get("hasBill")&&_.isUndefined(this.get("newest_action"))&&b.get("newest_action")&&(a=b.get("newest_action"),c&&c.get("newest_action")&&(a=c.get("newest_action").date.unix()>a.date.unix()?c.get("newest_action"):a),d&&d.get("newest_action")&&(a=d.get("newest_action").date.unix()>a.date.unix()?d.get("newest_action"):a),this.set("newest_action",a)),this.get("newest_action")},parseMeta:function(){var a={upper:!1,lower:!1,conference:!1,signed:!1,last:!1},b={companion:!!this.get("bill_companion"),conference:!!this.get("bill_conference")};if(this.get("custom_events")&&this.set("custom_events",_.sortBy(this.get("custom_events"),function(a,b){return(a.date.unix()+b)*-1})),this.get("hasBill")){if(b.companion&&(this.get("bill_companion").isSubstituted()&&(b.substituted=!0),this.get("bill_primary").isSubstituted()&&(b.substituted=!0)),b.companion&&!b.substituted||(a.lower=this.get("bill_primary").getActionDate("passed_lower"),a.upper=this.get("bill_primary").getActionDate("passed_upper")),b.companion&&!b.substituted&&("upper"===this.get("bill_primary").get("chamber")?(a.upper=this.get("bill_primary").getActionDate("passed_upper"),a.lower=this.get("bill_companion").getActionDate("passed_lower")):(a.lower=this.get("bill_primary").getActionDate("passed_lower"),a.upper=this.get("bill_companion").getActionDate("passed_upper"))),b.conference){var c=this.get("bill_conference").getActionDate("passed_lower"),d=this.get("bill_conference").getActionDate("passed_upper");c&&d&&(a.conference=c.unix()>=d.unix()?c:d)}b.conference?a.signed=this.get("bill_conference").getActionDate("signed"):a.signed=this.get("bill_primary").getActionDate("signed"),b.conference?a.last=this.get("bill_conference").getActionDate("last"):b.companion?a.last=this.get("bill_companion").getActionDate("last").unix()>=this.get("bill_primary").getActionDate("last").unix()?this.get("bill_companion").getActionDate("last"):this.get("bill_primary").getActionDate("last"):a.last=this.get("bill_primary").getActionDate("last"),this.get("description")||this.set("description",this.get("bill_primary").get("summary"))}return this.set("actions",a),this.set("bill_type",b),this}}),LT.CategoryModel=Backbone.Model.extend({initialize:function(a,b){this.options=b,this.set("bills",new LT.BillsCollection(null)),this.getBills()},getBills:function(){var a=this,b=LT.app.bills,c=this.get("id");return b.each(function(b){_.indexOf(b.get("categories"),c)!==-1&&a.get("bills").push(LT.utils.getModel("BillModel","bill",b.attributes))}),this},loadBills:function(b,c){var d=[],e=this;return this.get("bills").each(function(a){d.push(a.loadOSBills())}),a.when.apply(a,d).done(function(){var d=[];e.get("bills").each(function(a){d.push(a.loadOSCompanion())}),a.when.apply(a,d).done(function(){e.get("bills").each(function(a){a.parseMeta()}),b()}).fail(c)}).fail(c),this}})}(jQuery,window),function(a,b,c){LT.CategoriesCollection=Backbone.Collection.extend({model:LT.CategoryModel,comparator:function(a){return a.get("title").toLowerCase().indexOf("recent")!==-1?"zzzzz":a.get("title")}}),LT.BillsCollection=Backbone.Collection.extend({model:LT.BillModel,comparator:function(a){var b=a.newestAction()?a.newestAction().date.unix()*-1:a.get("title");return b}}),LT.OSBillsCollection=Backbone.Collection.extend({model:LT.OSBillModel,comparator:function(a){var b=a.get("newest_action");return b&&(b=b.date.unix()*-1),b}})}(jQuery,window),function(a,b,c){LT.MainApplicationView=Backbone.View.extend({initialize:function(a){this.$el.addClass("ls"),this.templates=this.templates||{},LT.utils.getTemplate("template-loading",this.templates,"loading"),LT.utils.getTemplate("template-error",this.templates,"error"),LT.utils.getTemplate("template-ebill",this.templates,"ebill"),LT.utils.getTemplate("template-osbill",this.templates,"osbill"),LT.utils.getTemplate("template-category",this.templates,"category"),LT.utils.getTemplate("template-categories",this.templates,"categories"),LT.utils.getTemplate("template-header",this.templates,"header"),_.bindAll(this)},events:{"click .bill-expand":"expandBill","click .expand-other-bills":"expandOtherBills"},loading:function(){return _.isNumber(LT.options.scrollOffset)&&(this.initialLoad===!0?this.resetScrollView():this.initialLoad=!_.isUndefined(this.initialLoad)),this.$el.html(this.templates.loading({})),this},error:function(a){return this.$el.html(this.templates.error({error:a})),this},renderCategories:function(){this.$el.html(this.templates.categories({categories:LT.app.categories.toJSON(),options:LT.options}))},renderCategory:function(a){_.isObject(a)||(a=LT.app.categories.get(a)),a.get("bills").sort(),this.$el.html(this.templates.category({category:a.toJSON(),templates:this.templates,header:this.renderHeader()})),this.getLegislators().navigationGlue()},renderEBill:function(a){_.isObject(a)||(a=this.router.bills.get(a)),a.newestAction(),this.$el.html(this.templates.ebill({bill:a.toJSON(),expandable:!1,templates:this.templates,header:this.renderHeader()})),this.getLegislators().addTooltips().checkOverflows().navigationGlue()},renderOSBill:function(a){this.$el.html(this.templates.osbill({bill:a.toJSON(),detailed:!0,templates:this.templates,header:this.renderHeader()})),this.getLegislators().addTooltips().checkOverflows().navigationGlue()},renderHeader:function(){return this.templates.header({categories:LT.app.categories.toJSON()})},expandBill:function(b){b.preventDefault();var c=a(b.target),d=["More detail","Less detail"],e=c.text();return c.text(e===d[0]?d[1]:d[0]),c.parent().toggleClass("expanded").find(".bill-bottom").slideToggle(),this.checkOverflows(),this},expandOtherBills:function(b){b.preventDefault();var c=a(b.target),d=["Show other bills","Hide other bills"],e=c.text();return c.text(e===d[0]?d[1]:d[0]),c.parent().find(".has-conference-bill").toggleClass("showing").slideToggle(),this.checkOverflows(),this},getLegislators:function(){return this.$el.find(".sponsor:not(.found)").each(function(){var b=a(this),c=b.data();if(c.id=c.legId,c.id){var d=LT.utils.getModel("OSLegislatorModel","id",c);a.when(LT.utils.fetchModel(d)).then(function(){new LT.LegislatorView({el:b,model:d}).render()})}}),this},addTooltips:function(){return this.$el.find(".bill-progress .bill-progress-section.completed").qtip({style:{classes:"qtip-shadow qtip-light"},position:{my:"bottom center",at:"top center"}}),this},checkOverflows:function(){return this.$el.find(".actions-inner, .co-sponsors-inner").each(function(){a(this).hasScrollBar()&&a(this).addClass("overflowed")}),this},resetScrollView:function(){return a("html, body").animate({scrollTop:this.$el.offset().top-LT.options.scrollOffset},1e3),this},navigationGlue:function(){var c=this.$el.offset().top,d=a(".ls-header");return a(".ls-header-container").height(d.outerHeight()),a(b).scroll(function(){var b=a(this);b.scrollTop()>c&&!d.hasClass("glued")?d.addClass("glued"):b.scrollTop()<=c&&d.hasClass("glued")&&d.removeClass("glued")}),this}}),LT.LegislatorView=Backbone.View.extend({model:LT.OSLegislatorModel,initialize:function(a){this.templates=this.templates||{},LT.utils.getTemplate("template-legislator",this.templates,"legislator"),_.bindAll(this)},render:function(){return this.$el.addClass("found").html(this.templates.legislator(this.model.toJSON())),this}})}(jQuery,window),function(a,b,c){LT.Application=Backbone.Router.extend({routes:{categories:"routeCategories","category/recent":"routeRecentCategory","category/:category":"routeCategory","bill/:bill":"routeEBill","bill-detail/:bill":"routeOSBill","*defaultR":"routeDefault"},initialize:function(a){LT.options=_.extend(LT.defaultOptions,a),LT.app=this,_.bindAll(this),this.mainView=new LT.MainApplicationView(LT.options),this.mainView.router=this,this.mainView.loading(),this.tabletop=Tabletop.init(_.extend(LT.options.tabletopOptions,{key:LT.options.eKey,callback:this.loadEBills,callbackContext:this,wanted:LT.options.sheetsWanted}))},loadEBills:function(b,c){var d=this,e=LT.parse.eData(c);this.categories=new LT.CategoriesCollection(null),this.bills=new LT.BillsCollection(null),_.each(e.bills,function(a){d.bills.add(LT.utils.getModel("BillModel","bill",a))}),_.each(e.categories,function(a){d.categories.add(LT.utils.getModel("CategoryModel","id",a))}),this.bills.each(function(a){a.loadCategories()}),LT.options.aggregateURL?a.jsonp({url:LT.options.aggregateURL,success:this.loadAggregateCounts}):this.start()},loadAggregateCounts:function(a){var b=this;_.each(a,function(a){"total-bills"===a.stat&&(b.totalBills=parseInt(a.value,10)),"total-bills-passed"===a.stat&&(b.totalBillsPassed=parseInt(a.value,10)),"total-bills-signed"===a.stat&&(b.totalBillsSigned=parseInt(a.value,10))}),this.start()},start:function(){Backbone.history.start()},routeDefault:function(){this.navigate("/categories",{trigger:!0,replace:!0}),this.mainView.render()},routeCategories:function(){var a=this;this.mainView.loading(),this.getOSBasicBills(function(){a.makeRecentCategory(),a.mainView.renderCategories()},this.error)},routeCategory:function(a){var b=this;a=decodeURI(a),a=this.categories.get(a),this.mainView.loading(),a.loadBills(function(){b.mainView.renderCategory(a)},b.error)},routeRecentCategory:function(){var a=this;this.mainView.loading(),this.getOSBasicBills(function(){a.makeRecentCategory();var b=a.categories.get("recent");b.loadBills(function(){a.mainView.renderCategory(b)},a.error)},this.error)},routeEBill:function(a){var b=this,c=decodeURI(a);return(a=this.bills.where({bill:c})[0])?(this.mainView.loading(),void a.loadOSBills().done(function(){a.loadOSCompanion().done(function(){a.parseMeta(),b.mainView.renderEBill(a)})}).fail(b.error)):void this.navigate("/bill-detail/"+encodeURI(c),{trigger:!0,replace:!0})},routeOSBill:function(b){var c=this;b=decodeURI(b),b=LT.utils.getModel("OSBillModel","bill_id",{bill_id:b}),this.mainView.loading(),a.when.apply(a,[LT.utils.fetchModel(b)]).done(function(){c.mainView.renderOSBill(b)}).fail(c.error)},makeRecentCategory:function(){if(!this.madeRecentCategory){var a={id:"recent",title:"Recent Actions",description:"The following bills have been updated in the past "+LT.options.recentChangeThreshold+" days.",image:LT.options.recentImage};this.bills.each(function(b){var c=b.get("categories"),d=b.get("hasBill");d===!0&&Math.abs(parseInt(b.lastUpdatedAt().diff(moment(),"days"),10))this.height():!1}}(jQuery,window);var LT,originalLT,exports=exports||void 0;_.isUndefined(exports)?(originalLT=window.LT,LT={},LT.noConflict=function(){return window.LT=originalLT,this},window.LT=LT):LT=exports,function(a,b,c){LT.cache={},LT.cache.models={},LT.log=function(a){_.isUndefined(window.console)||window.console.log(a)},LT.utils={},LT.utils.getModel=function(a,b,c,d){var e=a+":"+b+":"+c[b];return d=d||LT.options,_.isUndefined(LT.cache.models[e])&&(LT.cache.models[e]=new LT[a](c,d)),LT.cache.models[e]},LT.utils.fetchModel=function(b){var c;return b.get("fetched")!==!0?b.fetch():(c=a.Deferred(),c.resolveWith(b),c)},LT.utils.translate=function(a,b){var c=b;return _.isObject(LT.options.wordTranslations[a])&&_.isString(LT.options.wordTranslations[a][b])&&(c=LT.options.wordTranslations[a][b]),c},LT.utils.imagePath=function(a){return 0===a.indexOf("http")?a:LT.options.imagePath+a},LT.templates=LT.templates||{},LT.utils.getTemplate=function(b,c,d,e){var f="js/app/templates/"+b+".html",g=LT.options.templatePath+b+".html";_.isUndefined(LT.templates[f])?a.ajax({url:g,method:"GET",async:!1,contentType:"text",success:function(a){LT.templates[f]=_.template(a),c[d]=LT.templates[f],_.isFunction(e)&&e.apply(this,[a])}}):c[d]=LT.templates[f]},LT.parse=LT.parse||{},LT.parse.eData=function(a){var b={};b.categories=LT.parse.eCategories(a.sheets("Categories").all());var c=a.sheets("Bills").all();return c.length>LT.options.maxBills&<.log("The number of bills in your spreadsheet exceeds maxBills. Set the maxBills option to display them, but be aware that this may significantly slow down the Legislature Tracker."),b.bills=LT.parse.eBills(c.slice(0,LT.options.maxBills)),b.events=LT.parse.eEvents(a.sheets("Events").all()),_.each(_.groupBy(b.events,"bill_id"),function(a,c){_.each(b.bills,function(d,e){d.bill===c&&(b.bills[e].custom_events=a)})}),b},LT.parse.validateBillNumber=function(a){return LT.options.billNumberFormat.test(a)},LT.parse.eBills=function(a){return _.map(a,function(a){return LT.parse.translateFields(LT.options.fieldTranslations.eBills,a),a.links=LT.parse.eLinks(a.links),a.categories=a.categories?a.categories.split(","):[],a.categories=_.map(a.categories,_.trim),a.bill_primary=c,a.bill&<.parse.validateBillNumber(a.bill)?a.bill_primary=LT.utils.getModel("OSBillModel","bill_id",{bill_id:_.trim(a.bill)}):a.bill&&!LT.parse.validateBillNumber(a.bill)&<.log('Invalid primary bill number "'+a.bill+'" for row '+a.rowNumber+", see documentation."),a.bill_companion&<.parse.validateBillNumber(a.bill_companion)?a.bill_companion=LT.utils.getModel("OSBillModel","bill_id",{bill_id:_.trim(a.bill_companion)}):a.bill_companion&&!LT.parse.validateBillNumber(a.bill_companion)&<.log('Invalid companion bill number "'+a.bill_companion+'" for row '+a.rowNumber+", see documentation."),a.bill_conference&<.parse.validateBillNumber(a.bill_conference)?a.bill_conference=LT.utils.getModel("OSBillModel","bill_id",{bill_id:_.trim(a.bill_conference)}):a.bill_conference&&!LT.parse.validateBillNumber(a.bill_conference)&<.log('Invalid conference bill number "'+a.bill_conference+'" for row '+a.rowNumber+", see documentation."),a.hasBill=!0,a.bill&&a.bill_primary!==c||(a.hasBill=!1,a.bill=_.cssClass(a.title.toLowerCase())),a})},LT.parse.eCategories=function(a){return _.map(a,function(a){return LT.parse.translateFields(LT.options.fieldTranslations.eCategories,a),a.links=LT.parse.eLinks(a.links),a})},LT.parse.eEvents=function(a){return _.map(a,function(a){return LT.parse.translateFields(LT.options.fieldTranslations.eEvents,a),a.links=LT.parse.eLinks(a.links),a.date=moment(a.date),a.type=["custom"],a})},LT.parse.eLinks=function(a){var b=[];return a=_.trim(a),0===a.length?b:(a='"'===a.substring(0,1)?a.substring(1):a,a='"'===a.substring(a.length-1,a.length)?a.slice(0,-1):a,b=a.split('", "'),b=_.map(b,function(a){return{title:a.split("|")[0],url:a.split("|")[1]}}))},LT.parse.csvCategories=function(a){return a=_.trim(a),0===a.length?[]:(a='"'===a.substring(0,1)?a.substring(1):a,a='"'===a.substring(a.length-1,a.length)?a.slice(0,-1):a,a.split('", "'))},LT.parse.detectCompanionBill=function(a){var b,d;return _.isFunction(LT.options.detectCompanionBill)?(b=LT.options.detectCompanionBill(a),d=LT.parse.validateBillNumber(b)?b:c):_.isRegExp(LT.options.detectCompanionBill)&&(b=LT.options.detectCompanionBill.exec(a),d=b&<.parse.validateBillNumber(b[1])?b[1]:c),_.trim(d)},LT.parse.translateFields=function(a,b){return _.each(a,function(a,c){b[c]=b[a],c!==a&&delete b[a]}),b},LT.defaultOptions={sheetsWanted:["Categories","Bills","Events"],fieldTranslations:{eCategories:{id:"categoryid",short_title:"shorttitle"},eBills:{bill:"bill",bill_companion:"companionbill",bill_conference:"conferencebill",categories:"categories",title:"title",description:"description"},eEvents:{bill_id:"bill",actor:"chamber",action:"title"}},wordTranslations:{chamber:{upper:"Senate",lower:"House"},partyAbbr:{"Democratic-Farmer-Labor":"DFL",Democratic:"D",Republican:"R"}},maxBills:30,substituteMatch:/substituted/i,imagePath:"./css/images/",templatePath:"./js/app/templates/",recentChangeThreshold:7,tabletopOptions:{},scrollOffset:!1,conferenceBill:!0,recentImage:"RecentUpdatedBill.png",chamberLabel:!1,detectCompanionBill:/([A-Z]+ [1-9][0-9]*)$/,billNumberFormat:/[A-Z]+ [1-9][0-9]*/,osBillParse:!1}}(jQuery,window),function(a){LT.OSModel=Backbone.Model.extend({urlBase:function(){return"http://openstates.org/api/v1/"},urlEnd:function(){return"/?apikey="+encodeURI(LT.options.OSKey)+"&callback=?"},url:function(){return this.urlBase()+encodeURI(this.osType)+"/"+encodeURI(this.id)+this.urlEnd()},initialize:function(a,b){this.options=b,this.on("sync",function(a){a.set("fetched",!0)})}}),LT.OSStateModel=LT.OSModel.extend({url:function(){return this.urlBase()+"metadata/"+encodeURI(this.options.state)+this.urlEnd()}}),LT.OSBillModel=LT.OSModel.extend({url:function(){return _.isUndefined(this.id)?this.urlBase()+"bills/"+encodeURI(this.options.state)+"/"+encodeURI(this.options.session)+"/"+encodeURI(this.get("bill_id"))+this.urlEnd():this.urlBase()+"bills/"+this.id+this.urlEnd()},initialize:function(){LT.OSBillModel.__super__.initialize.apply(this,arguments),this.on("sync",function(){this.parseOSData()})},parseOSData:function(){var a;this.set("created_at",moment(this.get("created_at"))),this.set("updated_at",moment(this.get("updated_at"))),a=this.get("action_dates"),_.each(a,function(b,c){a[c]=b?moment(b):b}),this.set("action_dates",a),a=this.get("actions"),_.each(a,function(b,c){a[c].date=b.date?moment(b.date):b.date}),this.set("actions",a),a=this.get("votes"),_.each(a,function(b,c){a[c].date=b.date?moment(b.date):b.date}),this.set("votes",a),a=this.get("custom_events"),_.isArray(a)&&a.length>0&&this.set("actions",_.union(this.get("actions"),a)),this.set("actions",_.sortBy(this.get("actions"),function(a,b){return-1*(a.date.unix()+b)})),this.set("newest_action",this.get("actions")[0]),LT.options.osBillParse&&_.isFunction(LT.options.osBillParse)&<.options.osBillParse(this)},getActionDate:function(a){return this.get("action_dates")[a]?this.get("action_dates")[a]:!1},isSubstituted:function(){var a=!1;return _.isBoolean(this.get("substitued"))?a=this.get("substitued"):LT.options.substituteMatch===!1?a=!1:(a=_.find(this.get("actions"),function(a){return a.action.match(LT.options.substituteMatch)}),a=a?!0:!1,this.set("substitued",a)),a}}),LT.OSLegislatorModel=LT.OSModel.extend({osType:"legislators"}),LT.OSCommitteeModel=LT.OSModel.extend({osType:"committees"}),LT.BillModel=Backbone.Model.extend({initialize:function(a,b){this.options=b},loadOSBills:function(){var b=this,c=[];return _.each(["bill_primary","bill_companion","bill_conference"],function(a){b.get("hasBill")&&b.get(a)&&c.push(LT.utils.fetchModel(b.get(a)))}),a.when.apply(a,c)},loadOSCompanion:function(){var b,c=[];return this.get("hasBill")===!0&&!this.get("bill_companion")&&_.isObject(this.get("bill_primary"))&&_.isArray(this.get("bill_primary").get("companions"))&&_.isObject(this.get("bill_primary").get("companions")[0])&&(b=LT.parse.detectCompanionBill(this.get("bill_primary").get("companions")[0].bill_id),b&&(this.set("bill_companion",LT.utils.getModel("OSBillModel","bill_id",{bill_id:b})),c.push(LT.utils.fetchModel(this.get("bill_companion"))))),a.when.apply(a,c)},loadCategories:function(){this.get("categories")&&this.set("categories",_.map(this.get("categories"),function(a){return _.isObject(a)||(a=LT.utils.getModel("CategoryModel","id",{id:a})),a}))},lastUpdatedAt:function(){var a,b=this.get("bill_primary"),c=this.get("bill_companion"),d=this.get("bill_conference");return _.isUndefined(this.get("last_updated_at"))&&b.get("updated_at")?(a=b.get("updated_at"),c&&c.get("updated_at")&&(a=c.get("updated_at").unix()>a.unix()?c.get("updated_at"):a),d&&d.get("updated_at")&&(a=d.get("updated_at").unix()>a.unix()?d.get("updated_at"):a),this.set("last_updated_at",a)):_.isUndefined(this.get("last_updated_at"))&&!b.get("updated_at")&<.log("Could not fetch primary bill data from OpenStates. Check that the id "+this.get("bill_primary").get("bill_id")+" is formatted properly."),this.get("last_updated_at")},newestAction:function(){var a,b=this.get("bill_primary"),c=this.get("bill_companion"),d=this.get("bill_conference");return this.get("hasBill")&&_.isUndefined(this.get("newest_action"))&&b.get("newest_action")&&(a=b.get("newest_action"),c&&c.get("newest_action")&&(a=c.get("newest_action").date.unix()>a.date.unix()?c.get("newest_action"):a),d&&d.get("newest_action")&&(a=d.get("newest_action").date.unix()>a.date.unix()?d.get("newest_action"):a),this.set("newest_action",a)),this.get("newest_action")},parseMeta:function(){var a={upper:!1,lower:!1,conference:!1,signed:!1,last:!1},b={companion:this.get("bill_companion")?!0:!1,conference:this.get("bill_conference")?!0:!1};if(this.get("custom_events")&&this.set("custom_events",_.sortBy(this.get("custom_events"),function(a,b){return-1*(a.date.unix()+b)})),this.get("hasBill")){if(b.companion&&(this.get("bill_companion").isSubstituted()&&(b.substituted=!0),this.get("bill_primary").isSubstituted()&&(b.substituted=!0)),(!b.companion||b.substituted)&&(a.lower=this.get("bill_primary").getActionDate("passed_lower"),a.upper=this.get("bill_primary").getActionDate("passed_upper")),b.companion&&!b.substituted&&("upper"===this.get("bill_primary").get("chamber")?(a.upper=this.get("bill_primary").getActionDate("passed_upper"),a.lower=this.get("bill_companion").getActionDate("passed_lower")):(a.lower=this.get("bill_primary").getActionDate("passed_lower"),a.upper=this.get("bill_companion").getActionDate("passed_upper"))),b.conference){var c=this.get("bill_conference").getActionDate("passed_lower"),d=this.get("bill_conference").getActionDate("passed_upper");c&&d&&(a.conference=c.unix()>=d.unix()?c:d)}a.signed=b.conference?this.get("bill_conference").getActionDate("signed"):this.get("bill_primary").getActionDate("signed"),a.last=b.conference?this.get("bill_conference").getActionDate("last"):b.companion?this.get("bill_companion").getActionDate("last").unix()>=this.get("bill_primary").getActionDate("last").unix()?this.get("bill_companion").getActionDate("last"):this.get("bill_primary").getActionDate("last"):this.get("bill_primary").getActionDate("last"),this.get("description")||this.set("description",this.get("bill_primary").get("summary"))}return this.set("actions",a),this.set("bill_type",b),this}}),LT.CategoryModel=Backbone.Model.extend({initialize:function(a,b){this.options=b,this.set("bills",new LT.BillsCollection(null)),this.getBills()},getBills:function(){var a=this,b=LT.app.bills,c=this.get("id");return b.each(function(b){-1!==_.indexOf(b.get("categories"),c)&&a.get("bills").push(LT.utils.getModel("BillModel","bill",b.attributes))}),this},loadBills:function(b,c){var d=[],e=this;return this.get("bills").each(function(a){d.push(a.loadOSBills())}),a.when.apply(a,d).done(function(){var d=[];e.get("bills").each(function(a){d.push(a.loadOSCompanion())}),a.when.apply(a,d).done(function(){e.get("bills").each(function(a){a.parseMeta()}),b()}).fail(c)}).fail(c),this}})}(jQuery,window),function(){LT.CategoriesCollection=Backbone.Collection.extend({model:LT.CategoryModel,comparator:function(a){return-1!==a.get("title").toLowerCase().indexOf("recent")?"zzzzz":a.get("title")}}),LT.BillsCollection=Backbone.Collection.extend({model:LT.BillModel,comparator:function(a){var b=a.newestAction()?-1*a.newestAction().date.unix():a.get("title");return b}}),LT.OSBillsCollection=Backbone.Collection.extend({model:LT.OSBillModel,comparator:function(a){var b=a.get("newest_action");return b&&(b=-1*b.date.unix()),b}})}(jQuery,window),function(a,b){LT.MainApplicationView=Backbone.View.extend({initialize:function(){this.$el.addClass("ls"),this.templates=this.templates||{},LT.utils.getTemplate("template-loading",this.templates,"loading"),LT.utils.getTemplate("template-error",this.templates,"error"),LT.utils.getTemplate("template-ebill",this.templates,"ebill"),LT.utils.getTemplate("template-osbill",this.templates,"osbill"),LT.utils.getTemplate("template-category",this.templates,"category"),LT.utils.getTemplate("template-categories",this.templates,"categories"),LT.utils.getTemplate("template-header",this.templates,"header"),_.bindAll(this)},events:{"click .bill-expand":"expandBill","click .expand-other-bills":"expandOtherBills"},loading:function(){return _.isNumber(LT.options.scrollOffset)&&(this.initialLoad===!0?this.resetScrollView():this.initialLoad=_.isUndefined(this.initialLoad)?!1:!0),this.$el.html(this.templates.loading({})),this},error:function(a){return this.$el.html(this.templates.error({error:a})),this},renderCategories:function(){this.$el.html(this.templates.categories({categories:LT.app.categories.toJSON(),options:LT.options}))},renderCategory:function(a){_.isObject(a)||(a=LT.app.categories.get(a)),a.get("bills").sort(),this.$el.html(this.templates.category({category:a.toJSON(),templates:this.templates,header:this.renderHeader()})),this.getLegislators().navigationGlue()},renderEBill:function(a){_.isObject(a)||(a=this.router.bills.get(a)),a.newestAction(),this.$el.html(this.templates.ebill({bill:a.toJSON(),expandable:!1,templates:this.templates,header:this.renderHeader()})),this.getLegislators().addTooltips().checkOverflows().navigationGlue()},renderOSBill:function(a){this.$el.html(this.templates.osbill({bill:a.toJSON(),detailed:!0,templates:this.templates,header:this.renderHeader()})),this.getLegislators().addTooltips().checkOverflows().navigationGlue()},renderHeader:function(){return this.templates.header({categories:LT.app.categories.toJSON()})},expandBill:function(b){b.preventDefault();var c=a(b.target),d=["More detail","Less detail"],e=c.text();return c.text(e===d[0]?d[1]:d[0]),c.parent().toggleClass("expanded").find(".bill-bottom").slideToggle(),this.checkOverflows(),this},expandOtherBills:function(b){b.preventDefault();var c=a(b.target),d=["Show other bills","Hide other bills"],e=c.text();return c.text(e===d[0]?d[1]:d[0]),c.parent().find(".has-conference-bill").toggleClass("showing").slideToggle(),this.checkOverflows(),this},getLegislators:function(){return this.$el.find(".sponsor:not(.found)").each(function(){var b=a(this),c=b.data();if(c.id=c.legId,c.id){var d=LT.utils.getModel("OSLegislatorModel","id",c);a.when(LT.utils.fetchModel(d)).then(function(){new LT.LegislatorView({el:b,model:d}).render()})}}),this},addTooltips:function(){return this.$el.find(".bill-progress .bill-progress-section.completed").qtip({style:{classes:"qtip-shadow qtip-light"},position:{my:"bottom center",at:"top center"}}),this},checkOverflows:function(){return this.$el.find(".actions-inner, .co-sponsors-inner").each(function(){a(this).hasScrollBar()&&a(this).addClass("overflowed")}),this},resetScrollView:function(){return a("html, body").animate({scrollTop:this.$el.offset().top-LT.options.scrollOffset},1e3),this},navigationGlue:function(){var c=this.$el.offset().top,d=a(".ls-header");return a(".ls-header-container").height(d.outerHeight()),a(b).scroll(function(){var b=a(this);b.scrollTop()>c&&!d.hasClass("glued")?d.addClass("glued"):b.scrollTop()<=c&&d.hasClass("glued")&&d.removeClass("glued")}),this}}),LT.LegislatorView=Backbone.View.extend({model:LT.OSLegislatorModel,initialize:function(){this.templates=this.templates||{},LT.utils.getTemplate("template-legislator",this.templates,"legislator"),_.bindAll(this)},render:function(){return this.$el.addClass("found").html(this.templates.legislator(this.model.toJSON())),this}})}(jQuery,window),function(a){LT.Application=Backbone.Router.extend({routes:{categories:"routeCategories","category/recent":"routeRecentCategory","category/:category":"routeCategory","bill/:bill":"routeEBill","bill-detail/:bill":"routeOSBill","*defaultR":"routeDefault"},initialize:function(a){LT.options=_.extend(LT.defaultOptions,a),LT.app=this,_.bindAll(this),this.mainView=new LT.MainApplicationView(LT.options),this.mainView.router=this,this.mainView.loading(),this.tabletop=Tabletop.init(_.extend(LT.options.tabletopOptions,{key:LT.options.eKey,callback:this.loadEBills,callbackContext:this,wanted:LT.options.sheetsWanted}))},loadEBills:function(b,c){var d=this,e=LT.parse.eData(c);this.categories=new LT.CategoriesCollection(null),this.bills=new LT.BillsCollection(null),_.each(e.bills,function(a){d.bills.add(LT.utils.getModel("BillModel","bill",a))}),_.each(e.categories,function(a){d.categories.add(LT.utils.getModel("CategoryModel","id",a))}),this.bills.each(function(a){a.loadCategories()}),LT.options.aggregateURL?a.jsonp({url:LT.options.aggregateURL,success:this.loadAggregateCounts}):this.start()},loadAggregateCounts:function(a){var b=this;_.each(a,function(a){"total-bills"===a.stat&&(b.totalBills=parseInt(a.value,10)),"total-bills-passed"===a.stat&&(b.totalBillsPassed=parseInt(a.value,10)),"total-bills-signed"===a.stat&&(b.totalBillsSigned=parseInt(a.value,10))}),this.start()},start:function(){Backbone.history.start()},routeDefault:function(){this.navigate("/categories",{trigger:!0,replace:!0}),this.mainView.render()},routeCategories:function(){var a=this;this.mainView.loading(),this.getOSBasicBills(function(){a.makeRecentCategory(),a.mainView.renderCategories()},this.error)},routeCategory:function(a){var b=this;a=decodeURI(a),a=this.categories.get(a),this.mainView.loading(),a.loadBills(function(){b.mainView.renderCategory(a)},b.error)},routeRecentCategory:function(){var a=this;this.mainView.loading(),this.getOSBasicBills(function(){a.makeRecentCategory();var b=a.categories.get("recent");b.loadBills(function(){a.mainView.renderCategory(b)},a.error)},this.error)},routeEBill:function(a){var b=this,c=decodeURI(a);return(a=this.bills.where({bill:c})[0])?(this.mainView.loading(),a.loadOSBills().done(function(){a.loadOSCompanion().done(function(){a.parseMeta(),b.mainView.renderEBill(a)})}).fail(b.error),void 0):(this.navigate("/bill-detail/"+encodeURI(c),{trigger:!0,replace:!0}),void 0)},routeOSBill:function(b){var c=this;b=decodeURI(b),b=LT.utils.getModel("OSBillModel","bill_id",{bill_id:b}),this.mainView.loading(),a.when.apply(a,[LT.utils.fetchModel(b)]).done(function(){c.mainView.renderOSBill(b)}).fail(c.error)},makeRecentCategory:function(){if(!this.madeRecentCategory){var a={id:"recent",title:"Recent Actions",description:"The following bills have been updated in the past "+LT.options.recentChangeThreshold+" days.",image:LT.options.recentImage};this.bills.each(function(b){var c=b.get("categories"),d=b.get("hasBill");d===!0&&Math.abs(parseInt(b.lastUpdatedAt().diff(moment(),"days"),10))this.height()}}(jQuery,window);var LT,originalLT,exports=exports||void 0;_.isUndefined(exports)?(originalLT=window.LT,LT={},LT.noConflict=function(){return window.LT=originalLT,this},window.LT=LT):LT=exports,function(a,b,c){LT.cache={},LT.cache.models={},LT.log=function(a){_.isUndefined(window.console)||window.console.log(a)},LT.utils={},LT.utils.getModel=function(a,b,c,d){var e=a+":"+b+":"+c[b];return d=d||LT.options,_.isUndefined(LT.cache.models[e])&&(LT.cache.models[e]=new LT[a](c,d)),LT.cache.models[e]},LT.utils.fetchModel=function(b){var c;return b.get("fetched")!==!0?b.fetch():(c=a.Deferred(),c.resolveWith(b),c)},LT.utils.translate=function(a,b){var c=b;return _.isObject(LT.options.wordTranslations[a])&&_.isString(LT.options.wordTranslations[a][b])&&(c=LT.options.wordTranslations[a][b]),c},LT.utils.imagePath=function(a){return 0===a.indexOf("http")?a:LT.options.imagePath+a},LT.templates=LT.templates||{},LT.utils.getTemplate=function(b,c,d,e){var f="js/app/templates/"+b+".html",g=LT.options.templatePath+b+".html";_.isUndefined(LT.templates[f])?a.ajax({url:g,method:"GET",async:!1,contentType:"text",success:function(a){LT.templates[f]=_.template(a),c[d]=LT.templates[f],_.isFunction(e)&&e.apply(this,[a])}}):c[d]=LT.templates[f]},LT.parse=LT.parse||{},LT.parse.eData=function(a){var b={};b.categories=LT.parse.eCategories(a.sheets("Categories").all());var c=a.sheets("Bills").all();return c.length>LT.options.maxBills&<.log("The number of bills in your spreadsheet exceeds maxBills. Set the maxBills option to display them, but be aware that this may significantly slow down the Legislature Tracker."),b.bills=LT.parse.eBills(c.slice(0,LT.options.maxBills)),b.events=LT.parse.eEvents(a.sheets("Events").all()),_.each(_.groupBy(b.events,"bill_id"),function(a,c){_.each(b.bills,function(d,e){d.bill===c&&(b.bills[e].custom_events=a)})}),b},LT.parse.validateBillNumber=function(a){return LT.options.billNumberFormat.test(a)},LT.parse.eBills=function(a){return _.map(a,function(a){return LT.parse.translateFields(LT.options.fieldTranslations.eBills,a),a.links=LT.parse.eLinks(a.links),a.categories=a.categories?a.categories.split(","):[],a.categories=_.map(a.categories,_.trim),a.bill_primary=c,a.bill&<.parse.validateBillNumber(a.bill)?a.bill_primary=LT.utils.getModel("OSBillModel","bill_id",{bill_id:_.trim(a.bill)}):a.bill&&!LT.parse.validateBillNumber(a.bill)&<.log('Invalid primary bill number "'+a.bill+'" for row '+a.rowNumber+", see documentation."),a.bill_companion&<.parse.validateBillNumber(a.bill_companion)?a.bill_companion=LT.utils.getModel("OSBillModel","bill_id",{bill_id:_.trim(a.bill_companion)}):a.bill_companion&&!LT.parse.validateBillNumber(a.bill_companion)&<.log('Invalid companion bill number "'+a.bill_companion+'" for row '+a.rowNumber+", see documentation."),a.bill_conference&<.parse.validateBillNumber(a.bill_conference)?a.bill_conference=LT.utils.getModel("OSBillModel","bill_id",{bill_id:_.trim(a.bill_conference)}):a.bill_conference&&!LT.parse.validateBillNumber(a.bill_conference)&<.log('Invalid conference bill number "'+a.bill_conference+'" for row '+a.rowNumber+", see documentation."),a.hasBill=!0,a.bill&&a.bill_primary!==c||(a.hasBill=!1,a.bill=_.cssClass(a.title.toLowerCase())),a})},LT.parse.eCategories=function(a){return _.map(a,function(a){return LT.parse.translateFields(LT.options.fieldTranslations.eCategories,a),a.links=LT.parse.eLinks(a.links),a})},LT.parse.eEvents=function(a){return _.map(a,function(a){return LT.parse.translateFields(LT.options.fieldTranslations.eEvents,a),a.links=LT.parse.eLinks(a.links),a.date=moment(a.date),a.type=["custom"],a})},LT.parse.eLinks=function(a){var b=[];return a=_.trim(a),0===a.length?b:(a='"'===a.substring(0,1)?a.substring(1):a,a='"'===a.substring(a.length-1,a.length)?a.slice(0,-1):a,b=a.split('", "'),b=_.map(b,function(a){return{title:a.split("|")[0],url:a.split("|")[1]}}))},LT.parse.csvCategories=function(a){return a=_.trim(a),0===a.length?[]:(a='"'===a.substring(0,1)?a.substring(1):a,a='"'===a.substring(a.length-1,a.length)?a.slice(0,-1):a,a.split('", "'))},LT.parse.detectCompanionBill=function(a){var b,d;return _.isFunction(LT.options.detectCompanionBill)?(b=LT.options.detectCompanionBill(a),d=LT.parse.validateBillNumber(b)?b:c):_.isRegExp(LT.options.detectCompanionBill)&&(b=LT.options.detectCompanionBill.exec(a),d=b&<.parse.validateBillNumber(b[1])?b[1]:c),_.trim(d)},LT.parse.translateFields=function(a,b){return _.each(a,function(a,c){b[c]=b[a],c!==a&&delete b[a]}),b},LT.defaultOptions={sheetsWanted:["Categories","Bills","Events"],fieldTranslations:{eCategories:{id:"categoryid",short_title:"shorttitle"},eBills:{bill:"bill",bill_companion:"companionbill",bill_conference:"conferencebill",categories:"categories",title:"title",description:"description"},eEvents:{bill_id:"bill",actor:"chamber",action:"title"}},wordTranslations:{chamber:{upper:"Senate",lower:"House"},partyAbbr:{"Democratic-Farmer-Labor":"DFL",Democratic:"D",Republican:"R"}},maxBills:30,substituteMatch:/substituted/i,imagePath:"./css/images/",templatePath:"./js/app/templates/",recentChangeThreshold:7,tabletopOptions:{},scrollOffset:!1,conferenceBill:!0,recentImage:"RecentUpdatedBill.png",chamberLabel:!1,detectCompanionBill:/([A-Z]+ [1-9][0-9]*)$/,billNumberFormat:/[A-Z]+ [1-9][0-9]*/,osBillParse:!1}}(jQuery,window),function(a,b,c){LT.OSModel=Backbone.Model.extend({urlBase:function(){return"http://openstates.org/api/v1/"},urlEnd:function(){return"/?apikey="+encodeURI(LT.options.OSKey)+"&callback=?"},url:function(){return this.urlBase()+encodeURI(this.osType)+"/"+encodeURI(this.id)+this.urlEnd()},initialize:function(a,b){this.options=b,this.on("sync",function(a,b){a.set("fetched",!0)})}}),LT.OSStateModel=LT.OSModel.extend({url:function(){return this.urlBase()+"metadata/"+encodeURI(this.options.state)+this.urlEnd()}}),LT.OSBillModel=LT.OSModel.extend({url:function(){return _.isUndefined(this.id)?this.urlBase()+"bills/"+encodeURI(this.options.state)+"/"+encodeURI(this.options.session)+"/"+encodeURI(this.get("bill_id"))+this.urlEnd():this.urlBase()+"bills/"+this.id+this.urlEnd()},initialize:function(a,b){LT.OSBillModel.__super__.initialize.apply(this,arguments),this.on("sync",function(a,b,c){this.parseOSData()})},parseOSData:function(){var a;this.set("created_at",moment(this.get("created_at"))),this.set("updated_at",moment(this.get("updated_at"))),a=this.get("action_dates"),_.each(a,function(b,c){a[c]=b?moment(b):b}),this.set("action_dates",a),a=this.get("actions"),_.each(a,function(b,c){a[c].date=b.date?moment(b.date):b.date}),this.set("actions",a),a=this.get("votes"),_.each(a,function(b,c){a[c].date=b.date?moment(b.date):b.date}),this.set("votes",a),a=this.get("custom_events"),_.isArray(a)&&a.length>0&&this.set("actions",_.union(this.get("actions"),a)),this.set("actions",_.sortBy(this.get("actions"),function(a,b){return(a.date.unix()+b)*-1})),this.set("newest_action",this.get("actions")[0]),LT.options.osBillParse&&_.isFunction(LT.options.osBillParse)&<.options.osBillParse(this)},getActionDate:function(a){return!!this.get("action_dates")[a]&&this.get("action_dates")[a]},isSubstituted:function(){var a=!1;return _.isBoolean(this.get("substitued"))?a=this.get("substitued"):LT.options.substituteMatch===!1?a=!1:(a=_.find(this.get("actions"),function(a){return a.action.match(LT.options.substituteMatch)}),a=!!a,this.set("substitued",a)),a}}),LT.OSLegislatorModel=LT.OSModel.extend({osType:"legislators"}),LT.OSCommitteeModel=LT.OSModel.extend({osType:"committees"}),LT.BillModel=Backbone.Model.extend({initialize:function(a,b){this.options=b},loadOSBills:function(b,c){var d=this,e=[];return _.each(["bill_primary","bill_companion","bill_conference"],function(a){d.get("hasBill")&&d.get(a)&&e.push(LT.utils.fetchModel(d.get(a)))}),a.when.apply(a,e)},loadOSCompanion:function(){var b,c=[];return this.get("hasBill")===!0&&!this.get("bill_companion")&&_.isObject(this.get("bill_primary"))&&_.isArray(this.get("bill_primary").get("companions"))&&_.isObject(this.get("bill_primary").get("companions")[0])&&(b=LT.parse.detectCompanionBill(this.get("bill_primary").get("companions")[0].bill_id),b&&(this.set("bill_companion",LT.utils.getModel("OSBillModel","bill_id",{bill_id:b})),c.push(LT.utils.fetchModel(this.get("bill_companion"))))),a.when.apply(a,c)},loadCategories:function(){this.get("categories")&&this.set("categories",_.map(this.get("categories"),function(a){return _.isObject(a)||(a=LT.utils.getModel("CategoryModel","id",{id:a})),a}))},lastUpdatedAt:function(){var a,b=this.get("bill_primary"),c=this.get("bill_companion"),d=this.get("bill_conference");return _.isUndefined(this.get("last_updated_at"))&&b.get("updated_at")?(a=b.get("updated_at"),c&&c.get("updated_at")&&(a=c.get("updated_at").unix()>a.unix()?c.get("updated_at"):a),d&&d.get("updated_at")&&(a=d.get("updated_at").unix()>a.unix()?d.get("updated_at"):a),this.set("last_updated_at",a)):_.isUndefined(this.get("last_updated_at"))&&!b.get("updated_at")&<.log("Could not fetch primary bill data from OpenStates. Check that the id "+this.get("bill_primary").get("bill_id")+" is formatted properly."),this.get("last_updated_at")},newestAction:function(){var a,b=this.get("bill_primary"),c=this.get("bill_companion"),d=this.get("bill_conference");return this.get("hasBill")&&_.isUndefined(this.get("newest_action"))&&b.get("newest_action")&&(a=b.get("newest_action"),c&&c.get("newest_action")&&(a=c.get("newest_action").date.unix()>a.date.unix()?c.get("newest_action"):a),d&&d.get("newest_action")&&(a=d.get("newest_action").date.unix()>a.date.unix()?d.get("newest_action"):a),this.set("newest_action",a)),this.get("newest_action")},parseMeta:function(){var a={upper:!1,lower:!1,conference:!1,signed:!1,last:!1},b={companion:!!this.get("bill_companion"),conference:!!this.get("bill_conference")};if(this.get("custom_events")&&this.set("custom_events",_.sortBy(this.get("custom_events"),function(a,b){return(a.date.unix()+b)*-1})),this.get("hasBill")){if(b.companion&&(this.get("bill_companion").isSubstituted()&&(b.substituted=!0),this.get("bill_primary").isSubstituted()&&(b.substituted=!0)),b.companion&&!b.substituted||(a.lower=this.get("bill_primary").getActionDate("passed_lower"),a.upper=this.get("bill_primary").getActionDate("passed_upper")),b.companion&&!b.substituted&&("upper"===this.get("bill_primary").get("chamber")?(a.upper=this.get("bill_primary").getActionDate("passed_upper"),a.lower=this.get("bill_companion").getActionDate("passed_lower")):(a.lower=this.get("bill_primary").getActionDate("passed_lower"),a.upper=this.get("bill_companion").getActionDate("passed_upper"))),b.conference){var c=this.get("bill_conference").getActionDate("passed_lower"),d=this.get("bill_conference").getActionDate("passed_upper");c&&d&&(a.conference=c.unix()>=d.unix()?c:d)}b.conference?a.signed=this.get("bill_conference").getActionDate("signed"):a.signed=this.get("bill_primary").getActionDate("signed"),b.conference?a.last=this.get("bill_conference").getActionDate("last"):b.companion?a.last=this.get("bill_companion").getActionDate("last").unix()>=this.get("bill_primary").getActionDate("last").unix()?this.get("bill_companion").getActionDate("last"):this.get("bill_primary").getActionDate("last"):a.last=this.get("bill_primary").getActionDate("last"),this.get("description")||this.set("description",this.get("bill_primary").get("summary"))}return this.set("actions",a),this.set("bill_type",b),this}}),LT.CategoryModel=Backbone.Model.extend({initialize:function(a,b){this.options=b,this.set("bills",new LT.BillsCollection(null)),this.getBills()},getBills:function(){var a=this,b=LT.app.bills,c=this.get("id");return b.each(function(b){_.indexOf(b.get("categories"),c)!==-1&&a.get("bills").push(LT.utils.getModel("BillModel","bill",b.attributes))}),this},loadBills:function(b,c){var d=[],e=this;return this.get("bills").each(function(a){d.push(a.loadOSBills())}),a.when.apply(a,d).done(function(){var d=[];e.get("bills").each(function(a){d.push(a.loadOSCompanion())}),a.when.apply(a,d).done(function(){e.get("bills").each(function(a){a.parseMeta()}),b()}).fail(c)}).fail(c),this}})}(jQuery,window),function(a,b,c){LT.CategoriesCollection=Backbone.Collection.extend({model:LT.CategoryModel,comparator:function(a){return a.get("title").toLowerCase().indexOf("recent")!==-1?"zzzzz":a.get("title")}}),LT.BillsCollection=Backbone.Collection.extend({model:LT.BillModel,comparator:function(a){var b=a.newestAction()?a.newestAction().date.unix()*-1:a.get("title");return b}}),LT.OSBillsCollection=Backbone.Collection.extend({model:LT.OSBillModel,comparator:function(a){var b=a.get("newest_action");return b&&(b=b.date.unix()*-1),b}})}(jQuery,window),function(a,b,c){LT.MainApplicationView=Backbone.View.extend({initialize:function(a){this.$el.addClass("ls"),this.templates=this.templates||{},LT.utils.getTemplate("template-loading",this.templates,"loading"),LT.utils.getTemplate("template-error",this.templates,"error"),LT.utils.getTemplate("template-ebill",this.templates,"ebill"),LT.utils.getTemplate("template-osbill",this.templates,"osbill"),LT.utils.getTemplate("template-category",this.templates,"category"),LT.utils.getTemplate("template-categories",this.templates,"categories"),LT.utils.getTemplate("template-header",this.templates,"header"),_.bindAll(this)},events:{"click .bill-expand":"expandBill","click .expand-other-bills":"expandOtherBills"},loading:function(){return _.isNumber(LT.options.scrollOffset)&&(this.initialLoad===!0?this.resetScrollView():this.initialLoad=!_.isUndefined(this.initialLoad)),this.$el.html(this.templates.loading({})),this},error:function(a){return this.$el.html(this.templates.error({error:a})),this},renderCategories:function(){this.$el.html(this.templates.categories({categories:LT.app.categories.toJSON(),options:LT.options}))},renderCategory:function(a){_.isObject(a)||(a=LT.app.categories.get(a)),a.get("bills").sort(),this.$el.html(this.templates.category({category:a.toJSON(),templates:this.templates,header:this.renderHeader()})),this.getLegislators().navigationGlue()},renderEBill:function(a){_.isObject(a)||(a=this.router.bills.get(a)),a.newestAction(),this.$el.html(this.templates.ebill({bill:a.toJSON(),expandable:!1,templates:this.templates,header:this.renderHeader()})),this.getLegislators().addTooltips().checkOverflows().navigationGlue()},renderOSBill:function(a){this.$el.html(this.templates.osbill({bill:a.toJSON(),detailed:!0,templates:this.templates,header:this.renderHeader()})),this.getLegislators().addTooltips().checkOverflows().navigationGlue()},renderHeader:function(){return this.templates.header({categories:LT.app.categories.toJSON()})},expandBill:function(b){b.preventDefault();var c=a(b.target),d=["More detail","Less detail"],e=c.text();return c.text(e===d[0]?d[1]:d[0]),c.parent().toggleClass("expanded").find(".bill-bottom").slideToggle(),this.checkOverflows(),this},expandOtherBills:function(b){b.preventDefault();var c=a(b.target),d=["Show other bills","Hide other bills"],e=c.text();return c.text(e===d[0]?d[1]:d[0]),c.parent().find(".has-conference-bill").toggleClass("showing").slideToggle(),this.checkOverflows(),this},getLegislators:function(){return this.$el.find(".sponsor:not(.found)").each(function(){var b=a(this),c=b.data();if(c.id=c.legId,c.id){var d=LT.utils.getModel("OSLegislatorModel","id",c);a.when(LT.utils.fetchModel(d)).then(function(){new LT.LegislatorView({el:b,model:d}).render()})}}),this},addTooltips:function(){return this.$el.find(".bill-progress .bill-progress-section.completed").qtip({style:{classes:"qtip-shadow qtip-light"},position:{my:"bottom center",at:"top center"}}),this},checkOverflows:function(){return this.$el.find(".actions-inner, .co-sponsors-inner").each(function(){a(this).hasScrollBar()&&a(this).addClass("overflowed")}),this},resetScrollView:function(){return a("html, body").animate({scrollTop:this.$el.offset().top-LT.options.scrollOffset},1e3),this},navigationGlue:function(){var c=this.$el.offset().top,d=a(".ls-header");return a(".ls-header-container").height(d.outerHeight()),a(b).scroll(function(){var b=a(this);b.scrollTop()>c&&!d.hasClass("glued")?d.addClass("glued"):b.scrollTop()<=c&&d.hasClass("glued")&&d.removeClass("glued")}),this}}),LT.LegislatorView=Backbone.View.extend({model:LT.OSLegislatorModel,initialize:function(a){this.templates=this.templates||{},LT.utils.getTemplate("template-legislator",this.templates,"legislator"),_.bindAll(this)},render:function(){return this.$el.addClass("found").html(this.templates.legislator(this.model.toJSON())),this}})}(jQuery,window),function(a,b,c){LT.Application=Backbone.Router.extend({routes:{categories:"routeCategories","category/recent":"routeRecentCategory","category/:category":"routeCategory","bill/:bill":"routeEBill","bill-detail/:bill":"routeOSBill","*defaultR":"routeDefault"},initialize:function(a){LT.options=_.extend(LT.defaultOptions,a),LT.app=this,_.bindAll(this),this.mainView=new LT.MainApplicationView(LT.options),this.mainView.router=this,this.mainView.loading(),this.tabletop=Tabletop.init(_.extend(LT.options.tabletopOptions,{key:LT.options.eKey,callback:this.loadEBills,callbackContext:this,wanted:LT.options.sheetsWanted}))},loadEBills:function(b,c){var d=this,e=LT.parse.eData(c);this.categories=new LT.CategoriesCollection(null),this.bills=new LT.BillsCollection(null),_.each(e.bills,function(a){d.bills.add(LT.utils.getModel("BillModel","bill",a))}),_.each(e.categories,function(a){d.categories.add(LT.utils.getModel("CategoryModel","id",a))}),this.bills.each(function(a){a.loadCategories()}),LT.options.aggregateURL?a.jsonp({url:LT.options.aggregateURL,success:this.loadAggregateCounts}):this.start()},loadAggregateCounts:function(a){var b=this;_.each(a,function(a){"total-bills"===a.stat&&(b.totalBills=parseInt(a.value,10)),"total-bills-passed"===a.stat&&(b.totalBillsPassed=parseInt(a.value,10)),"total-bills-signed"===a.stat&&(b.totalBillsSigned=parseInt(a.value,10))}),this.start()},start:function(){Backbone.history.start()},routeDefault:function(){this.navigate("/categories",{trigger:!0,replace:!0}),this.mainView.render()},routeCategories:function(){var a=this;this.mainView.loading(),this.getOSBasicBills(function(){a.makeRecentCategory(),a.mainView.renderCategories()},this.error)},routeCategory:function(a){var b=this;a=decodeURI(a),a=this.categories.get(a),this.mainView.loading(),a.loadBills(function(){b.mainView.renderCategory(a)},b.error)},routeRecentCategory:function(){var a=this;this.mainView.loading(),this.getOSBasicBills(function(){a.makeRecentCategory();var b=a.categories.get("recent");b.loadBills(function(){a.mainView.renderCategory(b)},a.error)},this.error)},routeEBill:function(a){var b=this,c=decodeURI(a);return(a=this.bills.where({bill:c})[0])?(this.mainView.loading(),void a.loadOSBills().done(function(){a.loadOSCompanion().done(function(){a.parseMeta(),b.mainView.renderEBill(a)})}).fail(b.error)):void this.navigate("/bill-detail/"+encodeURI(c),{trigger:!0,replace:!0})},routeOSBill:function(b){var c=this;b=decodeURI(b),b=LT.utils.getModel("OSBillModel","bill_id",{bill_id:b}),this.mainView.loading(),a.when.apply(a,[LT.utils.fetchModel(b)]).done(function(){c.mainView.renderOSBill(b)}).fail(c.error)},makeRecentCategory:function(){if(!this.madeRecentCategory){var a={id:"recent",title:"Recent Actions",description:"The following bills have been updated in the past "+LT.options.recentChangeThreshold+" days.",image:LT.options.recentImage};this.bills.each(function(b){var c=b.get("categories"),d=b.get("hasBill");d===!0&&Math.abs(parseInt(b.lastUpdatedAt().diff(moment(),"days"),10))FL Legislation Tracker + + + + + + + + + + + + + + + + + ').stripTags() +=> 'a linkalert("hello world!")' +``` + +**toSentence** _.toSentence(array, [delimiter, lastDelimiter]) + +Join an array into a human readable sentence. + +```javascript +_.toSentence(['jQuery', 'Mootools', 'Prototype']) +=> 'jQuery, Mootools and Prototype'; + +_.toSentence(['jQuery', 'Mootools', 'Prototype'], ', ', ' unt ') +=> 'jQuery, Mootools unt Prototype'; +``` + +**toSentenceSerial** _.toSentenceSerial(array, [delimiter, lastDelimiter]) + +The same as `toSentence`, but adjusts delimeters to use [Serial comma](http://en.wikipedia.org/wiki/Serial_comma). + +```javascript +_.toSentenceSerial(['jQuery', 'Mootools']) +=> 'jQuery and Mootools'; + +_.toSentenceSerial(['jQuery', 'Mootools', 'Prototype']) +=> 'jQuery, Mootools, and Prototype' + +_.toSentenceSerial(['jQuery', 'Mootools', 'Prototype'], ', ', ' unt '); +=> 'jQuery, Mootools, unt Prototype'; +``` + +**repeat** _.repeat(string, count, [separator]) + +Repeats a string count times. + +```javascript +_.repeat("foo", 3) +=> 'foofoofoo'; + +_.repeat("foo", 3, "bar") +=> 'foobarfoobarfoo' +``` + +**surround** _.surround(string, wrap) + +Surround a string with another string. + +```javascript +_.surround("foo", "ab") +=> 'abfooab'; +``` + +**quote** _.quote(string, quoteChar) or _.q(string, quoteChar) + +Quotes a string. `quoteChar` defaults to `"`. + +```javascript +_.quote('foo', quoteChar) +=> '"foo"'; +``` +**unquote** _.unquote(string, quoteChar) + +Unquotes a string. `quoteChar` defaults to `"`. + +```javascript +_.unquote('"foo"') +=> 'foo'; +_.unquote("'foo'", "'") +=> 'foo'; +``` + + +**slugify** _.slugify(string) + +Transform text into a URL slug. Replaces whitespaces, accentuated, and special characters with a dash. + +```javascript +_.slugify("Un éléphant à l'orée du bois") +=> 'un-elephant-a-loree-du-bois'; +``` + +***Caution: this function is charset dependent*** + +**naturalCmp** array.sort(_.naturalCmp) + +Naturally sort strings like humans would do. + +```javascript +['foo20', 'foo5'].sort(_.naturalCmp) +=> [ 'foo5', 'foo20' ] +``` + +**toBoolean** _.toBoolean(string) or _.toBool(string) + +Turn strings that can be commonly considered as booleas to real booleans. Such as "true", "false", "1" and "0". This function is case insensitive. + +```javascript +_.toBoolean("true") +=> true +_.toBoolean("FALSE") +=> false +_.toBoolean("random") +=> undefined +``` + +It can be customized by giving arrays of truth and falsy value matcher as parameters. Matchers can be also RegExp objects. + +```javascript +_.toBoolean("truthy", ["truthy"], ["falsy"]) +=> true +_.toBoolean("true only at start", [/^true/]) +=> true +``` + +## Roadmap ## + +Any suggestions or bug reports are welcome. Just email me or more preferably open an issue. + +#### Problems + +We lose two things for `include` and `reverse` methods from `_.string`: + +* Calls like `_('foobar').include('bar')` aren't available; +* Chaining isn't available too. + +But if you need this functionality you can create aliases for conflict functions which will be convenient for you: + +```javascript +_.mixin({ + includeString: _.str.include, + reverseString: _.str.reverse +}) + +// Now wrapper calls and chaining are available. +_('foobar').chain().reverseString().includeString('rab').value() +``` + +#### Standalone Usage + +If you are using Underscore.string without Underscore. You also have `_.string` namespace for it and `_.str` alias +But of course you can just reassign `_` variable with `_.string` + +```javascript +_ = _.string +``` + +## Changelog ## + +### 2.4.0 ### + +* Move from rake to gulp +* Add support form classify camelcase strings +* Fix bower.json +* [Full changelog](https://github.com/epeli/underscore.string/compare/v2.3.3...2.4.0) + +### 2.3.3 ### + +* Add `toBoolean` +* Add `unquote` +* Add quote char option to `quote` +* Support dash-separated words in `titleize` +* [Full changelog](https://github.com/epeli/underscore.string/compare/v2.3.2...2.3.3) + +### 2.3.2 ### + +* Add `naturalCmp` +* Bug fix to `camelize` +* Add ă, ș, ț and ś to `slugify` +* Doc updates +* Add support for [component](http://component.io/) +* [Full changelog](https://github.com/epeli/underscore.string/compare/v2.3.1...v2.3.2) + +### 2.3.1 ### + +* Bug fixes to `escapeHTML`, `classify`, `substr` +* Faster `count` +* Documentation fixes +* [Full changelog](https://github.com/epeli/underscore.string/compare/v2.3.0...v2.3.1) + +### 2.3.0 ### + +* Added `numberformat` method +* Added `levenshtein` method (Levenshtein distance calculation) +* Added `swapCase` method +* Changed default behavior of `words` method +* Added `toSentenceSerial` method +* Added `surround` and `quote` methods + +### 2.2.1 ### + +* Same as 2.2.0 (2.2.0rc on npm) to fix some npm drama + +### 2.2.0 ### + +* Capitalize method behavior changed +* Various perfomance tweaks + +### 2.1.1### + +* Fixed words method bug +* Added classify method + +### 2.1.0 ### + +* AMD support +* Added toSentence method +* Added slugify method +* Lots of speed optimizations + +### 2.0.0 ### + +* Added prune, humanize functions +* Added _.string (_.str) namespace for Underscore.string library +* Removed includes function + +For upgrading to this version you need to mix in Underscore.string library to Underscore object: + +```javascript +_.mixin(_.string.exports()); +``` + +and all non-conflict Underscore.string functions will be available through Underscore object. +Also function `includes` has been removed, you should replace this function by `_.str.include` +or create alias `_.includes = _.str.include` and all your code will work fine. + +### 1.1.6 ### + +* Fixed reverse and truncate +* Added isBlank, stripTags, inlude(alias for includes) +* Added uglifier compression + +### 1.1.5 ### + +* Added strRight, strRightBack, strLeft, strLeftBack + +### 1.1.4 ### + +* Added pad, lpad, rpad, lrpad methods and aliases center, ljust, rjust +* Integration with Underscore 1.1.6 + +### 1.1.3 ### + +* Added methods: underscored, camelize, dasherize +* Support newer version of npm + +### 1.1.2 ### + +* Created functions: lines, chars, words functions + +### 1.0.2 ### + +* Created integration test suite with underscore.js 1.1.4 (now it's absolutely compatible) +* Removed 'reverse' function, because this function override underscore.js 'reverse' + +## Contribute ## + +* Fork & pull request. Don't forget about tests. +* If you planning add some feature please create issue before. + +Otherwise changes will be rejected. + +## Contributors list ## +[Can be found here](https://github.com/epeli/underscore.string/graphs/contributors). + + +## Licence ## + +The MIT License + +Copyright (c) 2011 Esa-Matti Suuronen esa-matti@suuronen.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/argparse/node_modules/underscore.string/bower.json b/node_modules/argparse/node_modules/underscore.string/bower.json new file mode 100644 index 0000000..6aef0bd --- /dev/null +++ b/node_modules/argparse/node_modules/underscore.string/bower.json @@ -0,0 +1,33 @@ +{ + "name": "underscore.string", + "version": "2.4.0", + "description": "String manipulation extensions for Underscore.js javascript library.", + "homepage": "http://epeli.github.com/underscore.string/", + "contributors": [ + "Esa-Matti Suuronen (http://esa-matti.suuronen.org/)", + "Edward Tsech ", + "Pavel Pravosud ()", + "Sasha Koss (http://koss.nocorp.me/)", + "Vladimir Dronnikov ", + "Pete Kruckenberg ()", + "Paul Chavard ()", + "Ed Finkler ()" + ], + "keywords": [ + "underscore", + "string" + ], + "main": "./lib/underscore.string.js", + "repository": { + "type": "git", + "url": "https://github.com/epeli/underscore.string.git" + }, + "bugs": { + "url": "https://github.com/epeli/underscore.string/issues" + }, + "licenses": [ + { + "type": "MIT" + } + ] +} diff --git a/node_modules/argparse/node_modules/underscore.string/component.json b/node_modules/argparse/node_modules/underscore.string/component.json new file mode 100644 index 0000000..96e23d3 --- /dev/null +++ b/node_modules/argparse/node_modules/underscore.string/component.json @@ -0,0 +1,11 @@ +{ + "name": "underscore.string", + "repo": "epeli/underscore.string", + "description": "String manipulation extensions for Underscore.js javascript library", + "version": "2.4.0", + "keywords": ["underscore", "string"], + "dependencies": {}, + "development": {}, + "main": "lib/underscore.string.js", + "scripts": ["lib/underscore.string.js"] +} diff --git a/node_modules/argparse/node_modules/underscore.string/foo.js b/node_modules/argparse/node_modules/underscore.string/foo.js new file mode 100644 index 0000000..cdc1d08 --- /dev/null +++ b/node_modules/argparse/node_modules/underscore.string/foo.js @@ -0,0 +1,10 @@ + + function boolMatch(s, matchers) { + var i, matcher, down = s.toLowerCase(); + matchers = [].concat(matchers); + for (i = 0; i < matchers.length; i += 1) { + matcher = matchers[i]; + if (matcher.test && matcher.test(s)) return true; + if (matcher && matcher.toLowerCase() === down) return true; + } + } diff --git a/node_modules/argparse/node_modules/underscore.string/gulpfile.js b/node_modules/argparse/node_modules/underscore.string/gulpfile.js new file mode 100644 index 0000000..6eaead8 --- /dev/null +++ b/node_modules/argparse/node_modules/underscore.string/gulpfile.js @@ -0,0 +1,26 @@ +var gulp = require('gulp'), + qunit = require("gulp-qunit"), + uglify = require('gulp-uglify'), + clean = require('gulp-clean'), + rename = require('gulp-rename'), + SRC = 'lib/underscore.string.js', + DEST = 'dist', + MIN_FILE = 'underscore.string.min.js', + TEST_SUITES = ['test/test.html', 'test/test_underscore/index.html']; + +gulp.task('test', function() { + return gulp.src(TEST_SUITES) + .pipe(qunit()); +}); + +gulp.task('clean', function() { + return gulp.src(DEST) + .pipe(clean()); +}); + +gulp.task('build', ['test', 'clean'], function() { + return gulp.src(SRC) + .pipe(uglify()) + .pipe(rename(MIN_FILE)) + .pipe(gulp.dest(DEST)); +}); diff --git a/node_modules/argparse/node_modules/underscore.string/lib/underscore.string.js b/node_modules/argparse/node_modules/underscore.string/lib/underscore.string.js new file mode 100644 index 0000000..c9c8d47 --- /dev/null +++ b/node_modules/argparse/node_modules/underscore.string/lib/underscore.string.js @@ -0,0 +1,673 @@ +// Underscore.string +// (c) 2010 Esa-Matti Suuronen +// Underscore.string is freely distributable under the terms of the MIT license. +// Documentation: https://github.com/epeli/underscore.string +// Some code is borrowed from MooTools and Alexandru Marasteanu. +// Version '2.4.0' + +!function(root, String){ + 'use strict'; + + // Defining helper functions. + + var nativeTrim = String.prototype.trim; + var nativeTrimRight = String.prototype.trimRight; + var nativeTrimLeft = String.prototype.trimLeft; + + var parseNumber = function(source) { return source * 1 || 0; }; + + var strRepeat = function(str, qty){ + if (qty < 1) return ''; + var result = ''; + while (qty > 0) { + if (qty & 1) result += str; + qty >>= 1, str += str; + } + return result; + }; + + var slice = [].slice; + + var defaultToWhiteSpace = function(characters) { + if (characters == null) + return '\\s'; + else if (characters.source) + return characters.source; + else + return '[' + _s.escapeRegExp(characters) + ']'; + }; + + // Helper for toBoolean + function boolMatch(s, matchers) { + var i, matcher, down = s.toLowerCase(); + matchers = [].concat(matchers); + for (i = 0; i < matchers.length; i += 1) { + matcher = matchers[i]; + if (!matcher) continue; + if (matcher.test && matcher.test(s)) return true; + if (matcher.toLowerCase() === down) return true; + } + } + + var escapeChars = { + lt: '<', + gt: '>', + quot: '"', + amp: '&', + apos: "'" + }; + + var reversedEscapeChars = {}; + for(var key in escapeChars) reversedEscapeChars[escapeChars[key]] = key; + reversedEscapeChars["'"] = '#39'; + + // sprintf() for JavaScript 0.7-beta1 + // http://www.diveintojavascript.com/projects/javascript-sprintf + // + // Copyright (c) Alexandru Marasteanu + // All rights reserved. + + var sprintf = (function() { + function get_type(variable) { + return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase(); + } + + var str_repeat = strRepeat; + + var str_format = function() { + if (!str_format.cache.hasOwnProperty(arguments[0])) { + str_format.cache[arguments[0]] = str_format.parse(arguments[0]); + } + return str_format.format.call(null, str_format.cache[arguments[0]], arguments); + }; + + str_format.format = function(parse_tree, argv) { + var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length; + for (i = 0; i < tree_length; i++) { + node_type = get_type(parse_tree[i]); + if (node_type === 'string') { + output.push(parse_tree[i]); + } + else if (node_type === 'array') { + match = parse_tree[i]; // convenience purposes only + if (match[2]) { // keyword argument + arg = argv[cursor]; + for (k = 0; k < match[2].length; k++) { + if (!arg.hasOwnProperty(match[2][k])) { + throw new Error(sprintf('[_.sprintf] property "%s" does not exist', match[2][k])); + } + arg = arg[match[2][k]]; + } + } else if (match[1]) { // positional argument (explicit) + arg = argv[match[1]]; + } + else { // positional argument (implicit) + arg = argv[cursor++]; + } + + if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) { + throw new Error(sprintf('[_.sprintf] expecting number but found %s', get_type(arg))); + } + switch (match[8]) { + case 'b': arg = arg.toString(2); break; + case 'c': arg = String.fromCharCode(arg); break; + case 'd': arg = parseInt(arg, 10); break; + case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; + case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; + case 'o': arg = arg.toString(8); break; + case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break; + case 'u': arg = Math.abs(arg); break; + case 'x': arg = arg.toString(16); break; + case 'X': arg = arg.toString(16).toUpperCase(); break; + } + arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); + pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' '; + pad_length = match[6] - String(arg).length; + pad = match[6] ? str_repeat(pad_character, pad_length) : ''; + output.push(match[5] ? arg + pad : pad + arg); + } + } + return output.join(''); + }; + + str_format.cache = {}; + + str_format.parse = function(fmt) { + var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; + while (_fmt) { + if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { + parse_tree.push(match[0]); + } + else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { + parse_tree.push('%'); + } + else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { + if (match[2]) { + arg_names |= 1; + var field_list = [], replacement_field = match[2], field_match = []; + if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { + if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + } + else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + } + else { + throw new Error('[_.sprintf] huh?'); + } + } + } + else { + throw new Error('[_.sprintf] huh?'); + } + match[2] = field_list; + } + else { + arg_names |= 2; + } + if (arg_names === 3) { + throw new Error('[_.sprintf] mixing positional and named placeholders is not (yet) supported'); + } + parse_tree.push(match); + } + else { + throw new Error('[_.sprintf] huh?'); + } + _fmt = _fmt.substring(match[0].length); + } + return parse_tree; + }; + + return str_format; + })(); + + + + // Defining underscore.string + + var _s = { + + VERSION: '2.4.0', + + isBlank: function(str){ + if (str == null) str = ''; + return (/^\s*$/).test(str); + }, + + stripTags: function(str){ + if (str == null) return ''; + return String(str).replace(/<\/?[^>]+>/g, ''); + }, + + capitalize : function(str){ + str = str == null ? '' : String(str); + return str.charAt(0).toUpperCase() + str.slice(1); + }, + + chop: function(str, step){ + if (str == null) return []; + str = String(str); + step = ~~step; + return step > 0 ? str.match(new RegExp('.{1,' + step + '}', 'g')) : [str]; + }, + + clean: function(str){ + return _s.strip(str).replace(/\s+/g, ' '); + }, + + count: function(str, substr){ + if (str == null || substr == null) return 0; + + str = String(str); + substr = String(substr); + + var count = 0, + pos = 0, + length = substr.length; + + while (true) { + pos = str.indexOf(substr, pos); + if (pos === -1) break; + count++; + pos += length; + } + + return count; + }, + + chars: function(str) { + if (str == null) return []; + return String(str).split(''); + }, + + swapCase: function(str) { + if (str == null) return ''; + return String(str).replace(/\S/g, function(c){ + return c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase(); + }); + }, + + escapeHTML: function(str) { + if (str == null) return ''; + return String(str).replace(/[&<>"']/g, function(m){ return '&' + reversedEscapeChars[m] + ';'; }); + }, + + unescapeHTML: function(str) { + if (str == null) return ''; + return String(str).replace(/\&([^;]+);/g, function(entity, entityCode){ + var match; + + if (entityCode in escapeChars) { + return escapeChars[entityCode]; + } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) { + return String.fromCharCode(parseInt(match[1], 16)); + } else if (match = entityCode.match(/^#(\d+)$/)) { + return String.fromCharCode(~~match[1]); + } else { + return entity; + } + }); + }, + + escapeRegExp: function(str){ + if (str == null) return ''; + return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); + }, + + splice: function(str, i, howmany, substr){ + var arr = _s.chars(str); + arr.splice(~~i, ~~howmany, substr); + return arr.join(''); + }, + + insert: function(str, i, substr){ + return _s.splice(str, i, 0, substr); + }, + + include: function(str, needle){ + if (needle === '') return true; + if (str == null) return false; + return String(str).indexOf(needle) !== -1; + }, + + join: function() { + var args = slice.call(arguments), + separator = args.shift(); + + if (separator == null) separator = ''; + + return args.join(separator); + }, + + lines: function(str) { + if (str == null) return []; + return String(str).split("\n"); + }, + + reverse: function(str){ + return _s.chars(str).reverse().join(''); + }, + + startsWith: function(str, starts){ + if (starts === '') return true; + if (str == null || starts == null) return false; + str = String(str); starts = String(starts); + return str.length >= starts.length && str.slice(0, starts.length) === starts; + }, + + endsWith: function(str, ends){ + if (ends === '') return true; + if (str == null || ends == null) return false; + str = String(str); ends = String(ends); + return str.length >= ends.length && str.slice(str.length - ends.length) === ends; + }, + + succ: function(str){ + if (str == null) return ''; + str = String(str); + return str.slice(0, -1) + String.fromCharCode(str.charCodeAt(str.length-1) + 1); + }, + + titleize: function(str){ + if (str == null) return ''; + str = String(str).toLowerCase(); + return str.replace(/(?:^|\s|-)\S/g, function(c){ return c.toUpperCase(); }); + }, + + camelize: function(str){ + return _s.trim(str).replace(/[-_\s]+(.)?/g, function(match, c){ return c ? c.toUpperCase() : ""; }); + }, + + underscored: function(str){ + return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase(); + }, + + dasherize: function(str){ + return _s.trim(str).replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase(); + }, + + classify: function(str){ + return _s.capitalize(_s.camelize(String(str).replace(/[\W_]/g, ' ')).replace(/\s/g, '')); + }, + + humanize: function(str){ + return _s.capitalize(_s.underscored(str).replace(/_id$/,'').replace(/_/g, ' ')); + }, + + trim: function(str, characters){ + if (str == null) return ''; + if (!characters && nativeTrim) return nativeTrim.call(str); + characters = defaultToWhiteSpace(characters); + return String(str).replace(new RegExp('^' + characters + '+|' + characters + '+$', 'g'), ''); + }, + + ltrim: function(str, characters){ + if (str == null) return ''; + if (!characters && nativeTrimLeft) return nativeTrimLeft.call(str); + characters = defaultToWhiteSpace(characters); + return String(str).replace(new RegExp('^' + characters + '+'), ''); + }, + + rtrim: function(str, characters){ + if (str == null) return ''; + if (!characters && nativeTrimRight) return nativeTrimRight.call(str); + characters = defaultToWhiteSpace(characters); + return String(str).replace(new RegExp(characters + '+$'), ''); + }, + + truncate: function(str, length, truncateStr){ + if (str == null) return ''; + str = String(str); truncateStr = truncateStr || '...'; + length = ~~length; + return str.length > length ? str.slice(0, length) + truncateStr : str; + }, + + /** + * _s.prune: a more elegant version of truncate + * prune extra chars, never leaving a half-chopped word. + * @author github.com/rwz + */ + prune: function(str, length, pruneStr){ + if (str == null) return ''; + + str = String(str); length = ~~length; + pruneStr = pruneStr != null ? String(pruneStr) : '...'; + + if (str.length <= length) return str; + + var tmpl = function(c){ return c.toUpperCase() !== c.toLowerCase() ? 'A' : ' '; }, + template = str.slice(0, length+1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA' + + if (template.slice(template.length-2).match(/\w\w/)) + template = template.replace(/\s*\S+$/, ''); + else + template = _s.rtrim(template.slice(0, template.length-1)); + + return (template+pruneStr).length > str.length ? str : str.slice(0, template.length)+pruneStr; + }, + + words: function(str, delimiter) { + if (_s.isBlank(str)) return []; + return _s.trim(str, delimiter).split(delimiter || /\s+/); + }, + + pad: function(str, length, padStr, type) { + str = str == null ? '' : String(str); + length = ~~length; + + var padlen = 0; + + if (!padStr) + padStr = ' '; + else if (padStr.length > 1) + padStr = padStr.charAt(0); + + switch(type) { + case 'right': + padlen = length - str.length; + return str + strRepeat(padStr, padlen); + case 'both': + padlen = length - str.length; + return strRepeat(padStr, Math.ceil(padlen/2)) + str + + strRepeat(padStr, Math.floor(padlen/2)); + default: // 'left' + padlen = length - str.length; + return strRepeat(padStr, padlen) + str; + } + }, + + lpad: function(str, length, padStr) { + return _s.pad(str, length, padStr); + }, + + rpad: function(str, length, padStr) { + return _s.pad(str, length, padStr, 'right'); + }, + + lrpad: function(str, length, padStr) { + return _s.pad(str, length, padStr, 'both'); + }, + + sprintf: sprintf, + + vsprintf: function(fmt, argv){ + argv.unshift(fmt); + return sprintf.apply(null, argv); + }, + + toNumber: function(str, decimals) { + if (!str) return 0; + str = _s.trim(str); + if (!str.match(/^-?\d+(?:\.\d+)?$/)) return NaN; + return parseNumber(parseNumber(str).toFixed(~~decimals)); + }, + + numberFormat : function(number, dec, dsep, tsep) { + if (isNaN(number) || number == null) return ''; + + number = number.toFixed(~~dec); + tsep = typeof tsep == 'string' ? tsep : ','; + + var parts = number.split('.'), fnums = parts[0], + decimals = parts[1] ? (dsep || '.') + parts[1] : ''; + + return fnums.replace(/(\d)(?=(?:\d{3})+$)/g, '$1' + tsep) + decimals; + }, + + strRight: function(str, sep){ + if (str == null) return ''; + str = String(str); sep = sep != null ? String(sep) : sep; + var pos = !sep ? -1 : str.indexOf(sep); + return ~pos ? str.slice(pos+sep.length, str.length) : str; + }, + + strRightBack: function(str, sep){ + if (str == null) return ''; + str = String(str); sep = sep != null ? String(sep) : sep; + var pos = !sep ? -1 : str.lastIndexOf(sep); + return ~pos ? str.slice(pos+sep.length, str.length) : str; + }, + + strLeft: function(str, sep){ + if (str == null) return ''; + str = String(str); sep = sep != null ? String(sep) : sep; + var pos = !sep ? -1 : str.indexOf(sep); + return ~pos ? str.slice(0, pos) : str; + }, + + strLeftBack: function(str, sep){ + if (str == null) return ''; + str += ''; sep = sep != null ? ''+sep : sep; + var pos = str.lastIndexOf(sep); + return ~pos ? str.slice(0, pos) : str; + }, + + toSentence: function(array, separator, lastSeparator, serial) { + separator = separator || ', '; + lastSeparator = lastSeparator || ' and '; + var a = array.slice(), lastMember = a.pop(); + + if (array.length > 2 && serial) lastSeparator = _s.rtrim(separator) + lastSeparator; + + return a.length ? a.join(separator) + lastSeparator + lastMember : lastMember; + }, + + toSentenceSerial: function() { + var args = slice.call(arguments); + args[3] = true; + return _s.toSentence.apply(_s, args); + }, + + slugify: function(str) { + if (str == null) return ''; + + var from = "ąàáäâãåæăćęèéëêìíïîłńòóöôõøśșțùúüûñçżź", + to = "aaaaaaaaaceeeeeiiiilnoooooosstuuuunczz", + regex = new RegExp(defaultToWhiteSpace(from), 'g'); + + str = String(str).toLowerCase().replace(regex, function(c){ + var index = from.indexOf(c); + return to.charAt(index) || '-'; + }); + + return _s.dasherize(str.replace(/[^\w\s-]/g, '')); + }, + + surround: function(str, wrapper) { + return [wrapper, str, wrapper].join(''); + }, + + quote: function(str, quoteChar) { + return _s.surround(str, quoteChar || '"'); + }, + + unquote: function(str, quoteChar) { + quoteChar = quoteChar || '"'; + if (str[0] === quoteChar && str[str.length-1] === quoteChar) + return str.slice(1,str.length-1); + else return str; + }, + + exports: function() { + var result = {}; + + for (var prop in this) { + if (!this.hasOwnProperty(prop) || prop.match(/^(?:include|contains|reverse)$/)) continue; + result[prop] = this[prop]; + } + + return result; + }, + + repeat: function(str, qty, separator){ + if (str == null) return ''; + + qty = ~~qty; + + // using faster implementation if separator is not needed; + if (separator == null) return strRepeat(String(str), qty); + + // this one is about 300x slower in Google Chrome + for (var repeat = []; qty > 0; repeat[--qty] = str) {} + return repeat.join(separator); + }, + + naturalCmp: function(str1, str2){ + if (str1 == str2) return 0; + if (!str1) return -1; + if (!str2) return 1; + + var cmpRegex = /(\.\d+)|(\d+)|(\D+)/g, + tokens1 = String(str1).toLowerCase().match(cmpRegex), + tokens2 = String(str2).toLowerCase().match(cmpRegex), + count = Math.min(tokens1.length, tokens2.length); + + for(var i = 0; i < count; i++) { + var a = tokens1[i], b = tokens2[i]; + + if (a !== b){ + var num1 = parseInt(a, 10); + if (!isNaN(num1)){ + var num2 = parseInt(b, 10); + if (!isNaN(num2) && num1 - num2) + return num1 - num2; + } + return a < b ? -1 : 1; + } + } + + if (tokens1.length === tokens2.length) + return tokens1.length - tokens2.length; + + return str1 < str2 ? -1 : 1; + }, + + levenshtein: function(str1, str2) { + if (str1 == null && str2 == null) return 0; + if (str1 == null) return String(str2).length; + if (str2 == null) return String(str1).length; + + str1 = String(str1); str2 = String(str2); + + var current = [], prev, value; + + for (var i = 0; i <= str2.length; i++) + for (var j = 0; j <= str1.length; j++) { + if (i && j) + if (str1.charAt(j - 1) === str2.charAt(i - 1)) + value = prev; + else + value = Math.min(current[j], current[j - 1], prev) + 1; + else + value = i + j; + + prev = current[j]; + current[j] = value; + } + + return current.pop(); + }, + + toBoolean: function(str, trueValues, falseValues) { + if (typeof str === "number") str = "" + str; + if (typeof str !== "string") return !!str; + str = _s.trim(str); + if (boolMatch(str, trueValues || ["true", "1"])) return true; + if (boolMatch(str, falseValues || ["false", "0"])) return false; + } + }; + + // Aliases + + _s.strip = _s.trim; + _s.lstrip = _s.ltrim; + _s.rstrip = _s.rtrim; + _s.center = _s.lrpad; + _s.rjust = _s.lpad; + _s.ljust = _s.rpad; + _s.contains = _s.include; + _s.q = _s.quote; + _s.toBool = _s.toBoolean; + + // Exporting + + // CommonJS module is defined + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) + module.exports = _s; + + exports._s = _s; + } + + // Register as a named module with AMD. + if (typeof define === 'function' && define.amd) + define('underscore.string', [], function(){ return _s; }); + + + // Integrate with Underscore.js if defined + // or create our own underscore object. + root._ = root._ || {}; + root._.string = root._.str = _s; +}(this, String); diff --git a/node_modules/argparse/node_modules/underscore.string/libpeerconnection.log b/node_modules/argparse/node_modules/underscore.string/libpeerconnection.log new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/argparse/node_modules/underscore.string/package.json b/node_modules/argparse/node_modules/underscore.string/package.json new file mode 100644 index 0000000..8dc2667 --- /dev/null +++ b/node_modules/argparse/node_modules/underscore.string/package.json @@ -0,0 +1,141 @@ +{ + "_args": [ + [ + { + "raw": "underscore.string@~2.4.0", + "scope": null, + "escapedName": "underscore.string", + "name": "underscore.string", + "rawSpec": "~2.4.0", + "spec": ">=2.4.0 <2.5.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/argparse" + ] + ], + "_from": "underscore.string@>=2.4.0 <2.5.0", + "_id": "underscore.string@2.4.0", + "_inCache": true, + "_location": "/argparse/underscore.string", + "_npmUser": { + "name": "epeli", + "email": "esa-matti@suuronen.org" + }, + "_npmVersion": "1.3.24", + "_phantomChildren": {}, + "_requested": { + "raw": "underscore.string@~2.4.0", + "scope": null, + "escapedName": "underscore.string", + "name": "underscore.string", + "rawSpec": "~2.4.0", + "spec": ">=2.4.0 <2.5.0", + "type": "range" + }, + "_requiredBy": [ + "/argparse" + ], + "_resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz", + "_shasum": "8cdd8fbac4e2d2ea1e7e2e8097c42f442280f85b", + "_shrinkwrap": null, + "_spec": "underscore.string@~2.4.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/argparse", + "bugs": { + "url": "https://github.com/epeli/underscore.string/issues" + }, + "contributors": [ + { + "name": "Esa-Matti Suuronen", + "email": "esa-matti@suuronen.org", + "url": "http://esa-matti.suuronen.org/" + }, + { + "name": "Edward Tsech", + "email": "edtsech@gmail.com" + }, + { + "name": "Pavel Pravosud", + "email": "pavel@pravosud.com", + "url": "" + }, + { + "name": "Sasha Koss", + "email": "kossnocorp@gmail.com", + "url": "http://koss.nocorp.me/" + }, + { + "name": "Vladimir Dronnikov", + "email": "dronnikov@gmail.com" + }, + { + "name": "Pete Kruckenberg", + "email": "https://github.com/kruckenb", + "url": "" + }, + { + "name": "Paul Chavard", + "email": "paul@chavard.net", + "url": "" + }, + { + "name": "Ed Finkler", + "email": "coj@funkatron.com", + "url": "" + } + ], + "dependencies": {}, + "description": "String manipulation extensions for Underscore.js javascript library.", + "devDependencies": { + "gulp": "~3.8.10", + "gulp-clean": "~0.3.1", + "gulp-qunit": "~1.0.0", + "gulp-rename": "~1.2.0", + "gulp-uglify": "~1.0.1" + }, + "directories": { + "lib": "./lib" + }, + "dist": { + "shasum": "8cdd8fbac4e2d2ea1e7e2e8097c42f442280f85b", + "tarball": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz" + }, + "engines": { + "node": "*" + }, + "homepage": "http://epeli.github.com/underscore.string/", + "keywords": [ + "underscore", + "string" + ], + "licenses": [ + { + "type": "MIT" + } + ], + "main": "./lib/underscore.string.js", + "maintainers": [ + { + "name": "edtsech", + "email": "edtsech@gmail.com" + }, + { + "name": "rwz", + "email": "rwz@duckroll.ru" + }, + { + "name": "epeli", + "email": "esa-matti@suuronen.org" + } + ], + "name": "underscore.string", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/epeli/underscore.string.git" + }, + "scripts": { + "test": "gulp test" + }, + "version": "2.4.0" +} diff --git a/node_modules/argparse/package.json b/node_modules/argparse/package.json new file mode 100644 index 0000000..4c8d8e2 --- /dev/null +++ b/node_modules/argparse/package.json @@ -0,0 +1,95 @@ +{ + "_args": [ + [ + { + "raw": "argparse@~ 0.1.11", + "scope": null, + "escapedName": "argparse", + "name": "argparse", + "rawSpec": "~ 0.1.11", + "spec": ">=0.1.11 <0.2.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/js-yaml" + ] + ], + "_from": "argparse@>=0.1.11 <0.2.0", + "_id": "argparse@0.1.16", + "_inCache": true, + "_location": "/argparse", + "_npmUser": { + "name": "vitaly", + "email": "vitaly@rcdesign.ru" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "raw": "argparse@~ 0.1.11", + "scope": null, + "escapedName": "argparse", + "name": "argparse", + "rawSpec": "~ 0.1.11", + "spec": ">=0.1.11 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/js-yaml" + ], + "_resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz", + "_shasum": "cfd01e0fbba3d6caed049fbd758d40f65196f57c", + "_shrinkwrap": null, + "_spec": "argparse@~ 0.1.11", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/js-yaml", + "bugs": { + "url": "https://github.com/nodeca/argparse/issues" + }, + "contributors": [ + { + "name": "Eugene Shkuropat" + }, + { + "name": "Paul Jacobson" + } + ], + "dependencies": { + "underscore": "~1.7.0", + "underscore.string": "~2.4.0" + }, + "description": "Very powerful CLI arguments parser. Native port of argparse - python's options parsing library", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "cfd01e0fbba3d6caed049fbd758d40f65196f57c", + "tarball": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz" + }, + "gitHead": "9c32eb1405d5d4b5686087d95bac010774979659", + "homepage": "https://github.com/nodeca/argparse", + "keywords": [ + "cli", + "parser", + "argparse", + "option", + "args" + ], + "license": "MIT", + "main": "./index.js", + "maintainers": [ + { + "name": "vitaly", + "email": "vitaly@rcdesign.ru" + } + ], + "name": "argparse", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/nodeca/argparse.git" + }, + "scripts": { + "test": "make test" + }, + "version": "0.1.16" +} diff --git a/node_modules/array-find-index/index.js b/node_modules/array-find-index/index.js new file mode 100644 index 0000000..e2dcd9a --- /dev/null +++ b/node_modules/array-find-index/index.js @@ -0,0 +1,25 @@ +'use strict'; +module.exports = function (arr, predicate, ctx) { + if (typeof Array.prototype.findIndex === 'function') { + return arr.findIndex(predicate, ctx); + } + + if (typeof predicate !== 'function') { + throw new TypeError('predicate must be a function'); + } + + var list = Object(arr); + var len = list.length; + + if (len === 0) { + return -1; + } + + for (var i = 0; i < len; i++) { + if (predicate.call(ctx, list[i], i, list)) { + return i; + } + } + + return -1; +}; diff --git a/node_modules/array-find-index/license b/node_modules/array-find-index/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/array-find-index/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/array-find-index/package.json b/node_modules/array-find-index/package.json new file mode 100644 index 0000000..73b7268 --- /dev/null +++ b/node_modules/array-find-index/package.json @@ -0,0 +1,103 @@ +{ + "_args": [ + [ + { + "raw": "array-find-index@^1.0.1", + "scope": null, + "escapedName": "array-find-index", + "name": "array-find-index", + "rawSpec": "^1.0.1", + "spec": ">=1.0.1 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/currently-unhandled" + ] + ], + "_from": "array-find-index@>=1.0.1 <2.0.0", + "_id": "array-find-index@1.0.2", + "_inCache": true, + "_location": "/array-find-index", + "_nodeVersion": "4.5.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/array-find-index-1.0.2.tgz_1475224789159_0.7274378235451877" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.15.9", + "_phantomChildren": {}, + "_requested": { + "raw": "array-find-index@^1.0.1", + "scope": null, + "escapedName": "array-find-index", + "name": "array-find-index", + "rawSpec": "^1.0.1", + "spec": ">=1.0.1 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/currently-unhandled" + ], + "_resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "_shasum": "df010aa1287e164bbda6f9723b0a96a1ec4187a1", + "_shrinkwrap": null, + "_spec": "array-find-index@^1.0.1", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/currently-unhandled", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/array-find-index/issues" + }, + "dependencies": {}, + "description": "ES2015 `Array#findIndex()` ponyfill", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "df010aa1287e164bbda6f9723b0a96a1ec4187a1", + "tarball": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "983f4c827ad22fa0353182b1ddcbfaecd4412859", + "homepage": "https://github.com/sindresorhus/array-find-index#readme", + "keywords": [ + "es2015", + "ponyfill", + "polyfill", + "shim", + "find", + "index", + "findindex", + "array" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "array-find-index", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/array-find-index.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "1.0.2" +} diff --git a/node_modules/array-find-index/readme.md b/node_modules/array-find-index/readme.md new file mode 100644 index 0000000..3166341 --- /dev/null +++ b/node_modules/array-find-index/readme.md @@ -0,0 +1,30 @@ +# array-find-index [![Build Status](https://travis-ci.org/sindresorhus/array-find-index.svg?branch=master)](https://travis-ci.org/sindresorhus/array-find-index) + +> ES2015 [`Array#findIndex()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) [ponyfill](https://ponyfill.com) + + +## Install + +``` +$ npm install --save array-find-index +``` + + +## Usage + +```js +const arrayFindIndex = require('array-find-index'); + +arrayFindIndex(['rainbow', 'unicorn', 'pony'], x => x === 'unicorn'); +//=> 1 +``` + + +## API + +Same as `Array#findIndex()`, but with the input array as the first argument. + + +## License + +MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/asn1/.npmignore b/node_modules/asn1/.npmignore new file mode 100644 index 0000000..eb03e3e --- /dev/null +++ b/node_modules/asn1/.npmignore @@ -0,0 +1,2 @@ +node_modules +*.log diff --git a/node_modules/asn1/.travis.yml b/node_modules/asn1/.travis.yml new file mode 100644 index 0000000..09d3ef3 --- /dev/null +++ b/node_modules/asn1/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - 0.8 + - 0.10 diff --git a/node_modules/asn1/LICENSE b/node_modules/asn1/LICENSE new file mode 100644 index 0000000..9b5dcdb --- /dev/null +++ b/node_modules/asn1/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2011 Mark Cavage, All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE diff --git a/node_modules/asn1/README.md b/node_modules/asn1/README.md new file mode 100644 index 0000000..7cebf7a --- /dev/null +++ b/node_modules/asn1/README.md @@ -0,0 +1,50 @@ +node-asn1 is a library for encoding and decoding ASN.1 datatypes in pure JS. +Currently BER encoding is supported; at some point I'll likely have to do DER. + +## Usage + +Mostly, if you're *actually* needing to read and write ASN.1, you probably don't +need this readme to explain what and why. If you have no idea what ASN.1 is, +see this: ftp://ftp.rsa.com/pub/pkcs/ascii/layman.asc + +The source is pretty much self-explanatory, and has read/write methods for the +common types out there. + +### Decoding + +The following reads an ASN.1 sequence with a boolean. + + var Ber = require('asn1').Ber; + + var reader = new Ber.Reader(new Buffer([0x30, 0x03, 0x01, 0x01, 0xff])); + + reader.readSequence(); + console.log('Sequence len: ' + reader.length); + if (reader.peek() === Ber.Boolean) + console.log(reader.readBoolean()); + +### Encoding + +The following generates the same payload as above. + + var Ber = require('asn1').Ber; + + var writer = new Ber.Writer(); + + writer.startSequence(); + writer.writeBoolean(true); + writer.endSequence(); + + console.log(writer.buffer); + +## Installation + + npm install asn1 + +## License + +MIT. + +## Bugs + +See . diff --git a/node_modules/asn1/lib/ber/errors.js b/node_modules/asn1/lib/ber/errors.js new file mode 100644 index 0000000..ff21d4f --- /dev/null +++ b/node_modules/asn1/lib/ber/errors.js @@ -0,0 +1,13 @@ +// Copyright 2011 Mark Cavage All rights reserved. + + +module.exports = { + + newInvalidAsn1Error: function(msg) { + var e = new Error(); + e.name = 'InvalidAsn1Error'; + e.message = msg || ''; + return e; + } + +}; diff --git a/node_modules/asn1/lib/ber/index.js b/node_modules/asn1/lib/ber/index.js new file mode 100644 index 0000000..4fb90ae --- /dev/null +++ b/node_modules/asn1/lib/ber/index.js @@ -0,0 +1,27 @@ +// Copyright 2011 Mark Cavage All rights reserved. + +var errors = require('./errors'); +var types = require('./types'); + +var Reader = require('./reader'); +var Writer = require('./writer'); + + +///--- Exports + +module.exports = { + + Reader: Reader, + + Writer: Writer + +}; + +for (var t in types) { + if (types.hasOwnProperty(t)) + module.exports[t] = types[t]; +} +for (var e in errors) { + if (errors.hasOwnProperty(e)) + module.exports[e] = errors[e]; +} diff --git a/node_modules/asn1/lib/ber/reader.js b/node_modules/asn1/lib/ber/reader.js new file mode 100644 index 0000000..0a00e98 --- /dev/null +++ b/node_modules/asn1/lib/ber/reader.js @@ -0,0 +1,261 @@ +// Copyright 2011 Mark Cavage All rights reserved. + +var assert = require('assert'); + +var ASN1 = require('./types'); +var errors = require('./errors'); + + +///--- Globals + +var newInvalidAsn1Error = errors.newInvalidAsn1Error; + + + +///--- API + +function Reader(data) { + if (!data || !Buffer.isBuffer(data)) + throw new TypeError('data must be a node Buffer'); + + this._buf = data; + this._size = data.length; + + // These hold the "current" state + this._len = 0; + this._offset = 0; +} + +Object.defineProperty(Reader.prototype, 'length', { + enumerable: true, + get: function () { return (this._len); } +}); + +Object.defineProperty(Reader.prototype, 'offset', { + enumerable: true, + get: function () { return (this._offset); } +}); + +Object.defineProperty(Reader.prototype, 'remain', { + get: function () { return (this._size - this._offset); } +}); + +Object.defineProperty(Reader.prototype, 'buffer', { + get: function () { return (this._buf.slice(this._offset)); } +}); + + +/** + * Reads a single byte and advances offset; you can pass in `true` to make this + * a "peek" operation (i.e., get the byte, but don't advance the offset). + * + * @param {Boolean} peek true means don't move offset. + * @return {Number} the next byte, null if not enough data. + */ +Reader.prototype.readByte = function(peek) { + if (this._size - this._offset < 1) + return null; + + var b = this._buf[this._offset] & 0xff; + + if (!peek) + this._offset += 1; + + return b; +}; + + +Reader.prototype.peek = function() { + return this.readByte(true); +}; + + +/** + * Reads a (potentially) variable length off the BER buffer. This call is + * not really meant to be called directly, as callers have to manipulate + * the internal buffer afterwards. + * + * As a result of this call, you can call `Reader.length`, until the + * next thing called that does a readLength. + * + * @return {Number} the amount of offset to advance the buffer. + * @throws {InvalidAsn1Error} on bad ASN.1 + */ +Reader.prototype.readLength = function(offset) { + if (offset === undefined) + offset = this._offset; + + if (offset >= this._size) + return null; + + var lenB = this._buf[offset++] & 0xff; + if (lenB === null) + return null; + + if ((lenB & 0x80) == 0x80) { + lenB &= 0x7f; + + if (lenB == 0) + throw newInvalidAsn1Error('Indefinite length not supported'); + + if (lenB > 4) + throw newInvalidAsn1Error('encoding too long'); + + if (this._size - offset < lenB) + return null; + + this._len = 0; + for (var i = 0; i < lenB; i++) + this._len = (this._len << 8) + (this._buf[offset++] & 0xff); + + } else { + // Wasn't a variable length + this._len = lenB; + } + + return offset; +}; + + +/** + * Parses the next sequence in this BER buffer. + * + * To get the length of the sequence, call `Reader.length`. + * + * @return {Number} the sequence's tag. + */ +Reader.prototype.readSequence = function(tag) { + var seq = this.peek(); + if (seq === null) + return null; + if (tag !== undefined && tag !== seq) + throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) + + ': got 0x' + seq.toString(16)); + + var o = this.readLength(this._offset + 1); // stored in `length` + if (o === null) + return null; + + this._offset = o; + return seq; +}; + + +Reader.prototype.readInt = function() { + return this._readTag(ASN1.Integer); +}; + + +Reader.prototype.readBoolean = function() { + return (this._readTag(ASN1.Boolean) === 0 ? false : true); +}; + + +Reader.prototype.readEnumeration = function() { + return this._readTag(ASN1.Enumeration); +}; + + +Reader.prototype.readString = function(tag, retbuf) { + if (!tag) + tag = ASN1.OctetString; + + var b = this.peek(); + if (b === null) + return null; + + if (b !== tag) + throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) + + ': got 0x' + b.toString(16)); + + var o = this.readLength(this._offset + 1); // stored in `length` + + if (o === null) + return null; + + if (this.length > this._size - o) + return null; + + this._offset = o; + + if (this.length === 0) + return retbuf ? new Buffer(0) : ''; + + var str = this._buf.slice(this._offset, this._offset + this.length); + this._offset += this.length; + + return retbuf ? str : str.toString('utf8'); +}; + +Reader.prototype.readOID = function(tag) { + if (!tag) + tag = ASN1.OID; + + var b = this.readString(tag, true); + if (b === null) + return null; + + var values = []; + var value = 0; + + for (var i = 0; i < b.length; i++) { + var byte = b[i] & 0xff; + + value <<= 7; + value += byte & 0x7f; + if ((byte & 0x80) == 0) { + values.push(value); + value = 0; + } + } + + value = values.shift(); + values.unshift(value % 40); + values.unshift((value / 40) >> 0); + + return values.join('.'); +}; + + +Reader.prototype._readTag = function(tag) { + assert.ok(tag !== undefined); + + var b = this.peek(); + + if (b === null) + return null; + + if (b !== tag) + throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) + + ': got 0x' + b.toString(16)); + + var o = this.readLength(this._offset + 1); // stored in `length` + if (o === null) + return null; + + if (this.length > 4) + throw newInvalidAsn1Error('Integer too long: ' + this.length); + + if (this.length > this._size - o) + return null; + this._offset = o; + + var fb = this._buf[this._offset]; + var value = 0; + + for (var i = 0; i < this.length; i++) { + value <<= 8; + value |= (this._buf[this._offset++] & 0xff); + } + + if ((fb & 0x80) == 0x80 && i !== 4) + value -= (1 << (i * 8)); + + return value >> 0; +}; + + + +///--- Exported API + +module.exports = Reader; diff --git a/node_modules/asn1/lib/ber/types.js b/node_modules/asn1/lib/ber/types.js new file mode 100644 index 0000000..8aea000 --- /dev/null +++ b/node_modules/asn1/lib/ber/types.js @@ -0,0 +1,36 @@ +// Copyright 2011 Mark Cavage All rights reserved. + + +module.exports = { + EOC: 0, + Boolean: 1, + Integer: 2, + BitString: 3, + OctetString: 4, + Null: 5, + OID: 6, + ObjectDescriptor: 7, + External: 8, + Real: 9, // float + Enumeration: 10, + PDV: 11, + Utf8String: 12, + RelativeOID: 13, + Sequence: 16, + Set: 17, + NumericString: 18, + PrintableString: 19, + T61String: 20, + VideotexString: 21, + IA5String: 22, + UTCTime: 23, + GeneralizedTime: 24, + GraphicString: 25, + VisibleString: 26, + GeneralString: 28, + UniversalString: 29, + CharacterString: 30, + BMPString: 31, + Constructor: 32, + Context: 128 +}; diff --git a/node_modules/asn1/lib/ber/writer.js b/node_modules/asn1/lib/ber/writer.js new file mode 100644 index 0000000..d9d99af --- /dev/null +++ b/node_modules/asn1/lib/ber/writer.js @@ -0,0 +1,316 @@ +// Copyright 2011 Mark Cavage All rights reserved. + +var assert = require('assert'); +var ASN1 = require('./types'); +var errors = require('./errors'); + + +///--- Globals + +var newInvalidAsn1Error = errors.newInvalidAsn1Error; + +var DEFAULT_OPTS = { + size: 1024, + growthFactor: 8 +}; + + +///--- Helpers + +function merge(from, to) { + assert.ok(from); + assert.equal(typeof(from), 'object'); + assert.ok(to); + assert.equal(typeof(to), 'object'); + + var keys = Object.getOwnPropertyNames(from); + keys.forEach(function(key) { + if (to[key]) + return; + + var value = Object.getOwnPropertyDescriptor(from, key); + Object.defineProperty(to, key, value); + }); + + return to; +} + + + +///--- API + +function Writer(options) { + options = merge(DEFAULT_OPTS, options || {}); + + this._buf = new Buffer(options.size || 1024); + this._size = this._buf.length; + this._offset = 0; + this._options = options; + + // A list of offsets in the buffer where we need to insert + // sequence tag/len pairs. + this._seq = []; +} + +Object.defineProperty(Writer.prototype, 'buffer', { + get: function () { + if (this._seq.length) + throw new InvalidAsn1Error(this._seq.length + ' unended sequence(s)'); + + return (this._buf.slice(0, this._offset)); + } +}); + +Writer.prototype.writeByte = function(b) { + if (typeof(b) !== 'number') + throw new TypeError('argument must be a Number'); + + this._ensure(1); + this._buf[this._offset++] = b; +}; + + +Writer.prototype.writeInt = function(i, tag) { + if (typeof(i) !== 'number') + throw new TypeError('argument must be a Number'); + if (typeof(tag) !== 'number') + tag = ASN1.Integer; + + var sz = 4; + + while ((((i & 0xff800000) === 0) || ((i & 0xff800000) === 0xff800000 >> 0)) && + (sz > 1)) { + sz--; + i <<= 8; + } + + if (sz > 4) + throw new InvalidAsn1Error('BER ints cannot be > 0xffffffff'); + + this._ensure(2 + sz); + this._buf[this._offset++] = tag; + this._buf[this._offset++] = sz; + + while (sz-- > 0) { + this._buf[this._offset++] = ((i & 0xff000000) >>> 24); + i <<= 8; + } + +}; + + +Writer.prototype.writeNull = function() { + this.writeByte(ASN1.Null); + this.writeByte(0x00); +}; + + +Writer.prototype.writeEnumeration = function(i, tag) { + if (typeof(i) !== 'number') + throw new TypeError('argument must be a Number'); + if (typeof(tag) !== 'number') + tag = ASN1.Enumeration; + + return this.writeInt(i, tag); +}; + + +Writer.prototype.writeBoolean = function(b, tag) { + if (typeof(b) !== 'boolean') + throw new TypeError('argument must be a Boolean'); + if (typeof(tag) !== 'number') + tag = ASN1.Boolean; + + this._ensure(3); + this._buf[this._offset++] = tag; + this._buf[this._offset++] = 0x01; + this._buf[this._offset++] = b ? 0xff : 0x00; +}; + + +Writer.prototype.writeString = function(s, tag) { + if (typeof(s) !== 'string') + throw new TypeError('argument must be a string (was: ' + typeof(s) + ')'); + if (typeof(tag) !== 'number') + tag = ASN1.OctetString; + + var len = Buffer.byteLength(s); + this.writeByte(tag); + this.writeLength(len); + if (len) { + this._ensure(len); + this._buf.write(s, this._offset); + this._offset += len; + } +}; + + +Writer.prototype.writeBuffer = function(buf, tag) { + if (typeof(tag) !== 'number') + throw new TypeError('tag must be a number'); + if (!Buffer.isBuffer(buf)) + throw new TypeError('argument must be a buffer'); + + this.writeByte(tag); + this.writeLength(buf.length); + this._ensure(buf.length); + buf.copy(this._buf, this._offset, 0, buf.length); + this._offset += buf.length; +}; + + +Writer.prototype.writeStringArray = function(strings) { + if ((!strings instanceof Array)) + throw new TypeError('argument must be an Array[String]'); + + var self = this; + strings.forEach(function(s) { + self.writeString(s); + }); +}; + +// This is really to solve DER cases, but whatever for now +Writer.prototype.writeOID = function(s, tag) { + if (typeof(s) !== 'string') + throw new TypeError('argument must be a string'); + if (typeof(tag) !== 'number') + tag = ASN1.OID; + + if (!/^([0-9]+\.){3,}[0-9]+$/.test(s)) + throw new Error('argument is not a valid OID string'); + + function encodeOctet(bytes, octet) { + if (octet < 128) { + bytes.push(octet); + } else if (octet < 16384) { + bytes.push((octet >>> 7) | 0x80); + bytes.push(octet & 0x7F); + } else if (octet < 2097152) { + bytes.push((octet >>> 14) | 0x80); + bytes.push(((octet >>> 7) | 0x80) & 0xFF); + bytes.push(octet & 0x7F); + } else if (octet < 268435456) { + bytes.push((octet >>> 21) | 0x80); + bytes.push(((octet >>> 14) | 0x80) & 0xFF); + bytes.push(((octet >>> 7) | 0x80) & 0xFF); + bytes.push(octet & 0x7F); + } else { + bytes.push(((octet >>> 28) | 0x80) & 0xFF); + bytes.push(((octet >>> 21) | 0x80) & 0xFF); + bytes.push(((octet >>> 14) | 0x80) & 0xFF); + bytes.push(((octet >>> 7) | 0x80) & 0xFF); + bytes.push(octet & 0x7F); + } + } + + var tmp = s.split('.'); + var bytes = []; + bytes.push(parseInt(tmp[0], 10) * 40 + parseInt(tmp[1], 10)); + tmp.slice(2).forEach(function(b) { + encodeOctet(bytes, parseInt(b, 10)); + }); + + var self = this; + this._ensure(2 + bytes.length); + this.writeByte(tag); + this.writeLength(bytes.length); + bytes.forEach(function(b) { + self.writeByte(b); + }); +}; + + +Writer.prototype.writeLength = function(len) { + if (typeof(len) !== 'number') + throw new TypeError('argument must be a Number'); + + this._ensure(4); + + if (len <= 0x7f) { + this._buf[this._offset++] = len; + } else if (len <= 0xff) { + this._buf[this._offset++] = 0x81; + this._buf[this._offset++] = len; + } else if (len <= 0xffff) { + this._buf[this._offset++] = 0x82; + this._buf[this._offset++] = len >> 8; + this._buf[this._offset++] = len; + } else if (len <= 0xffffff) { + this._buf[this._offset++] = 0x83; + this._buf[this._offset++] = len >> 16; + this._buf[this._offset++] = len >> 8; + this._buf[this._offset++] = len; + } else { + throw new InvalidAsn1ERror('Length too long (> 4 bytes)'); + } +}; + +Writer.prototype.startSequence = function(tag) { + if (typeof(tag) !== 'number') + tag = ASN1.Sequence | ASN1.Constructor; + + this.writeByte(tag); + this._seq.push(this._offset); + this._ensure(3); + this._offset += 3; +}; + + +Writer.prototype.endSequence = function() { + var seq = this._seq.pop(); + var start = seq + 3; + var len = this._offset - start; + + if (len <= 0x7f) { + this._shift(start, len, -2); + this._buf[seq] = len; + } else if (len <= 0xff) { + this._shift(start, len, -1); + this._buf[seq] = 0x81; + this._buf[seq + 1] = len; + } else if (len <= 0xffff) { + this._buf[seq] = 0x82; + this._buf[seq + 1] = len >> 8; + this._buf[seq + 2] = len; + } else if (len <= 0xffffff) { + this._shift(start, len, 1); + this._buf[seq] = 0x83; + this._buf[seq + 1] = len >> 16; + this._buf[seq + 2] = len >> 8; + this._buf[seq + 3] = len; + } else { + throw new InvalidAsn1Error('Sequence too long'); + } +}; + + +Writer.prototype._shift = function(start, len, shift) { + assert.ok(start !== undefined); + assert.ok(len !== undefined); + assert.ok(shift); + + this._buf.copy(this._buf, start + shift, start, start + len); + this._offset += shift; +}; + +Writer.prototype._ensure = function(len) { + assert.ok(len); + + if (this._size - this._offset < len) { + var sz = this._size * this._options.growthFactor; + if (sz - this._offset < len) + sz += len; + + var buf = new Buffer(sz); + + this._buf.copy(buf, 0, 0, this._offset); + this._buf = buf; + this._size = sz; + } +}; + + + +///--- Exported API + +module.exports = Writer; diff --git a/node_modules/asn1/lib/index.js b/node_modules/asn1/lib/index.js new file mode 100644 index 0000000..d1766e7 --- /dev/null +++ b/node_modules/asn1/lib/index.js @@ -0,0 +1,20 @@ +// Copyright 2011 Mark Cavage All rights reserved. + +// If you have no idea what ASN.1 or BER is, see this: +// ftp://ftp.rsa.com/pub/pkcs/ascii/layman.asc + +var Ber = require('./ber/index'); + + + +///--- Exported API + +module.exports = { + + Ber: Ber, + + BerReader: Ber.Reader, + + BerWriter: Ber.Writer + +}; diff --git a/node_modules/asn1/package.json b/node_modules/asn1/package.json new file mode 100644 index 0000000..e5eea0a --- /dev/null +++ b/node_modules/asn1/package.json @@ -0,0 +1,98 @@ +{ + "_args": [ + [ + { + "raw": "asn1@~0.2.0", + "scope": null, + "escapedName": "asn1", + "name": "asn1", + "rawSpec": "~0.2.0", + "spec": ">=0.2.0 <0.3.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/ssh2-streams" + ] + ], + "_from": "asn1@>=0.2.0 <0.3.0", + "_id": "asn1@0.2.3", + "_inCache": true, + "_location": "/asn1", + "_npmUser": { + "name": "pfmooney", + "email": "patrick.f.mooney@gmail.com" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "raw": "asn1@~0.2.0", + "scope": null, + "escapedName": "asn1", + "name": "asn1", + "rawSpec": "~0.2.0", + "spec": ">=0.2.0 <0.3.0", + "type": "range" + }, + "_requiredBy": [ + "/ssh2-streams" + ], + "_resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "_shasum": "dac8787713c9966849fc8180777ebe9c1ddf3b86", + "_shrinkwrap": null, + "_spec": "asn1@~0.2.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/ssh2-streams", + "author": { + "name": "Mark Cavage", + "email": "mcavage@gmail.com" + }, + "bugs": { + "url": "https://github.com/mcavage/node-asn1/issues" + }, + "contributors": [ + { + "name": "David Gwynne", + "email": "loki@animata.net" + }, + { + "name": "Yunong Xiao", + "email": "yunong@joyent.com" + }, + { + "name": "Alex Wilson", + "email": "alex.wilson@joyent.com" + } + ], + "dependencies": {}, + "description": "Contains parsers and serializers for ASN.1 (currently BER only)", + "devDependencies": { + "tap": "0.4.8" + }, + "directories": {}, + "dist": { + "shasum": "dac8787713c9966849fc8180777ebe9c1ddf3b86", + "tarball": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz" + }, + "homepage": "https://github.com/mcavage/node-asn1", + "license": "MIT", + "main": "lib/index.js", + "maintainers": [ + { + "name": "mcavage", + "email": "mcavage@gmail.com" + }, + { + "name": "pfmooney", + "email": "patrick.f.mooney@gmail.com" + } + ], + "name": "asn1", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/mcavage/node-asn1.git" + }, + "scripts": { + "test": "tap ./tst" + }, + "version": "0.2.3" +} diff --git a/node_modules/asn1/tst/ber/reader.test.js b/node_modules/asn1/tst/ber/reader.test.js new file mode 100644 index 0000000..062fd7e --- /dev/null +++ b/node_modules/asn1/tst/ber/reader.test.js @@ -0,0 +1,208 @@ +// Copyright 2011 Mark Cavage All rights reserved. + +var test = require('tap').test; + + + +///--- Globals + +var BerReader; + + + +///--- Tests + +test('load library', function(t) { + BerReader = require('../../lib/index').BerReader; + t.ok(BerReader); + try { + new BerReader(); + t.fail('Should have thrown'); + } catch (e) { + t.ok(e instanceof TypeError, 'Should have been a type error'); + } + t.end(); +}); + + +test('read byte', function(t) { + var reader = new BerReader(new Buffer([0xde])); + t.ok(reader); + t.equal(reader.readByte(), 0xde, 'wrong value'); + t.end(); +}); + + +test('read 1 byte int', function(t) { + var reader = new BerReader(new Buffer([0x02, 0x01, 0x03])); + t.ok(reader); + t.equal(reader.readInt(), 0x03, 'wrong value'); + t.equal(reader.length, 0x01, 'wrong length'); + t.end(); +}); + + +test('read 2 byte int', function(t) { + var reader = new BerReader(new Buffer([0x02, 0x02, 0x7e, 0xde])); + t.ok(reader); + t.equal(reader.readInt(), 0x7ede, 'wrong value'); + t.equal(reader.length, 0x02, 'wrong length'); + t.end(); +}); + + +test('read 3 byte int', function(t) { + var reader = new BerReader(new Buffer([0x02, 0x03, 0x7e, 0xde, 0x03])); + t.ok(reader); + t.equal(reader.readInt(), 0x7ede03, 'wrong value'); + t.equal(reader.length, 0x03, 'wrong length'); + t.end(); +}); + + +test('read 4 byte int', function(t) { + var reader = new BerReader(new Buffer([0x02, 0x04, 0x7e, 0xde, 0x03, 0x01])); + t.ok(reader); + t.equal(reader.readInt(), 0x7ede0301, 'wrong value'); + t.equal(reader.length, 0x04, 'wrong length'); + t.end(); +}); + + +test('read 1 byte negative int', function(t) { + var reader = new BerReader(new Buffer([0x02, 0x01, 0xdc])); + t.ok(reader); + t.equal(reader.readInt(), -36, 'wrong value'); + t.equal(reader.length, 0x01, 'wrong length'); + t.end(); +}); + + +test('read 2 byte negative int', function(t) { + var reader = new BerReader(new Buffer([0x02, 0x02, 0xc0, 0x4e])); + t.ok(reader); + t.equal(reader.readInt(), -16306, 'wrong value'); + t.equal(reader.length, 0x02, 'wrong length'); + t.end(); +}); + + +test('read 3 byte negative int', function(t) { + var reader = new BerReader(new Buffer([0x02, 0x03, 0xff, 0x00, 0x19])); + t.ok(reader); + t.equal(reader.readInt(), -65511, 'wrong value'); + t.equal(reader.length, 0x03, 'wrong length'); + t.end(); +}); + + +test('read 4 byte negative int', function(t) { + var reader = new BerReader(new Buffer([0x02, 0x04, 0x91, 0x7c, 0x22, 0x1f])); + t.ok(reader); + t.equal(reader.readInt(), -1854135777, 'wrong value'); + t.equal(reader.length, 0x04, 'wrong length'); + t.end(); +}); + + +test('read boolean true', function(t) { + var reader = new BerReader(new Buffer([0x01, 0x01, 0xff])); + t.ok(reader); + t.equal(reader.readBoolean(), true, 'wrong value'); + t.equal(reader.length, 0x01, 'wrong length'); + t.end(); +}); + + +test('read boolean false', function(t) { + var reader = new BerReader(new Buffer([0x01, 0x01, 0x00])); + t.ok(reader); + t.equal(reader.readBoolean(), false, 'wrong value'); + t.equal(reader.length, 0x01, 'wrong length'); + t.end(); +}); + + +test('read enumeration', function(t) { + var reader = new BerReader(new Buffer([0x0a, 0x01, 0x20])); + t.ok(reader); + t.equal(reader.readEnumeration(), 0x20, 'wrong value'); + t.equal(reader.length, 0x01, 'wrong length'); + t.end(); +}); + + +test('read string', function(t) { + var dn = 'cn=foo,ou=unit,o=test'; + var buf = new Buffer(dn.length + 2); + buf[0] = 0x04; + buf[1] = Buffer.byteLength(dn); + buf.write(dn, 2); + var reader = new BerReader(buf); + t.ok(reader); + t.equal(reader.readString(), dn, 'wrong value'); + t.equal(reader.length, dn.length, 'wrong length'); + t.end(); +}); + + +test('read sequence', function(t) { + var reader = new BerReader(new Buffer([0x30, 0x03, 0x01, 0x01, 0xff])); + t.ok(reader); + t.equal(reader.readSequence(), 0x30, 'wrong value'); + t.equal(reader.length, 0x03, 'wrong length'); + t.equal(reader.readBoolean(), true, 'wrong value'); + t.equal(reader.length, 0x01, 'wrong length'); + t.end(); +}); + + +test('anonymous LDAPv3 bind', function(t) { + var BIND = new Buffer(14); + BIND[0] = 0x30; // Sequence + BIND[1] = 12; // len + BIND[2] = 0x02; // ASN.1 Integer + BIND[3] = 1; // len + BIND[4] = 0x04; // msgid (make up 4) + BIND[5] = 0x60; // Bind Request + BIND[6] = 7; // len + BIND[7] = 0x02; // ASN.1 Integer + BIND[8] = 1; // len + BIND[9] = 0x03; // v3 + BIND[10] = 0x04; // String (bind dn) + BIND[11] = 0; // len + BIND[12] = 0x80; // ContextSpecific (choice) + BIND[13] = 0; // simple bind + + // Start testing ^^ + var ber = new BerReader(BIND); + t.equal(ber.readSequence(), 48, 'Not an ASN.1 Sequence'); + t.equal(ber.length, 12, 'Message length should be 12'); + t.equal(ber.readInt(), 4, 'Message id should have been 4'); + t.equal(ber.readSequence(), 96, 'Bind Request should have been 96'); + t.equal(ber.length, 7, 'Bind length should have been 7'); + t.equal(ber.readInt(), 3, 'LDAP version should have been 3'); + t.equal(ber.readString(), '', 'Bind DN should have been empty'); + t.equal(ber.length, 0, 'string length should have been 0'); + t.equal(ber.readByte(), 0x80, 'Should have been ContextSpecific (choice)'); + t.equal(ber.readByte(), 0, 'Should have been simple bind'); + t.equal(null, ber.readByte(), 'Should be out of data'); + t.end(); +}); + + +test('long string', function(t) { + var buf = new Buffer(256); + var o; + var s = + '2;649;CN=Red Hat CS 71GA Demo,O=Red Hat CS 71GA Demo,C=US;' + + 'CN=RHCS Agent - admin01,UID=admin01,O=redhat,C=US [1] This is ' + + 'Teena Vradmin\'s description.'; + buf[0] = 0x04; + buf[1] = 0x81; + buf[2] = 0x94; + buf.write(s, 3); + var ber = new BerReader(buf.slice(0, 3 + s.length)); + t.equal(ber.readString(), s); + t.end(); +}); diff --git a/node_modules/asn1/tst/ber/writer.test.js b/node_modules/asn1/tst/ber/writer.test.js new file mode 100644 index 0000000..d87cb7b --- /dev/null +++ b/node_modules/asn1/tst/ber/writer.test.js @@ -0,0 +1,370 @@ +// Copyright 2011 Mark Cavage All rights reserved. + +var test = require('tap').test; +var sys = require('sys'); + +///--- Globals + +var BerWriter; + +var BerReader; + + +///--- Tests + +test('load library', function(t) { + BerWriter = require('../../lib/index').BerWriter; + t.ok(BerWriter); + t.ok(new BerWriter()); + t.end(); +}); + + +test('write byte', function(t) { + var writer = new BerWriter(); + + writer.writeByte(0xC2); + var ber = writer.buffer; + + t.ok(ber); + t.equal(ber.length, 1, 'Wrong length'); + t.equal(ber[0], 0xC2, 'value wrong'); + + t.end(); +}); + + +test('write 1 byte int', function(t) { + var writer = new BerWriter(); + + writer.writeInt(0x7f); + var ber = writer.buffer; + + t.ok(ber); + t.equal(ber.length, 3, 'Wrong length for an int: ' + ber.length); + t.equal(ber[0], 0x02, 'ASN.1 tag wrong (2) -> ' + ber[0]); + t.equal(ber[1], 0x01, 'length wrong(1) -> ' + ber[1]); + t.equal(ber[2], 0x7f, 'value wrong(3) -> ' + ber[2]); + + t.end(); +}); + + +test('write 2 byte int', function(t) { + var writer = new BerWriter(); + + writer.writeInt(0x7ffe); + var ber = writer.buffer; + + t.ok(ber); + t.equal(ber.length, 4, 'Wrong length for an int'); + t.equal(ber[0], 0x02, 'ASN.1 tag wrong'); + t.equal(ber[1], 0x02, 'length wrong'); + t.equal(ber[2], 0x7f, 'value wrong (byte 1)'); + t.equal(ber[3], 0xfe, 'value wrong (byte 2)'); + + t.end(); +}); + + +test('write 3 byte int', function(t) { + var writer = new BerWriter(); + + writer.writeInt(0x7ffffe); + var ber = writer.buffer; + + t.ok(ber); + t.equal(ber.length, 5, 'Wrong length for an int'); + t.equal(ber[0], 0x02, 'ASN.1 tag wrong'); + t.equal(ber[1], 0x03, 'length wrong'); + t.equal(ber[2], 0x7f, 'value wrong (byte 1)'); + t.equal(ber[3], 0xff, 'value wrong (byte 2)'); + t.equal(ber[4], 0xfe, 'value wrong (byte 3)'); + + t.end(); +}); + + +test('write 4 byte int', function(t) { + var writer = new BerWriter(); + + writer.writeInt(0x7ffffffe); + var ber = writer.buffer; + + t.ok(ber); + + t.equal(ber.length, 6, 'Wrong length for an int'); + t.equal(ber[0], 0x02, 'ASN.1 tag wrong'); + t.equal(ber[1], 0x04, 'length wrong'); + t.equal(ber[2], 0x7f, 'value wrong (byte 1)'); + t.equal(ber[3], 0xff, 'value wrong (byte 2)'); + t.equal(ber[4], 0xff, 'value wrong (byte 3)'); + t.equal(ber[5], 0xfe, 'value wrong (byte 4)'); + + t.end(); +}); + + +test('write 1 byte negative int', function(t) { + var writer = new BerWriter(); + + writer.writeInt(-128); + var ber = writer.buffer; + + t.ok(ber); + + t.equal(ber.length, 3, 'Wrong length for an int'); + t.equal(ber[0], 0x02, 'ASN.1 tag wrong'); + t.equal(ber[1], 0x01, 'length wrong'); + t.equal(ber[2], 0x80, 'value wrong (byte 1)'); + + t.end(); +}); + + +test('write 2 byte negative int', function(t) { + var writer = new BerWriter(); + + writer.writeInt(-22400); + var ber = writer.buffer; + + t.ok(ber); + + t.equal(ber.length, 4, 'Wrong length for an int'); + t.equal(ber[0], 0x02, 'ASN.1 tag wrong'); + t.equal(ber[1], 0x02, 'length wrong'); + t.equal(ber[2], 0xa8, 'value wrong (byte 1)'); + t.equal(ber[3], 0x80, 'value wrong (byte 2)'); + + t.end(); +}); + + +test('write 3 byte negative int', function(t) { + var writer = new BerWriter(); + + writer.writeInt(-481653); + var ber = writer.buffer; + + t.ok(ber); + + t.equal(ber.length, 5, 'Wrong length for an int'); + t.equal(ber[0], 0x02, 'ASN.1 tag wrong'); + t.equal(ber[1], 0x03, 'length wrong'); + t.equal(ber[2], 0xf8, 'value wrong (byte 1)'); + t.equal(ber[3], 0xa6, 'value wrong (byte 2)'); + t.equal(ber[4], 0x8b, 'value wrong (byte 3)'); + + t.end(); +}); + + +test('write 4 byte negative int', function(t) { + var writer = new BerWriter(); + + writer.writeInt(-1522904131); + var ber = writer.buffer; + + t.ok(ber); + + t.equal(ber.length, 6, 'Wrong length for an int'); + t.equal(ber[0], 0x02, 'ASN.1 tag wrong'); + t.equal(ber[1], 0x04, 'length wrong'); + t.equal(ber[2], 0xa5, 'value wrong (byte 1)'); + t.equal(ber[3], 0x3a, 'value wrong (byte 2)'); + t.equal(ber[4], 0x53, 'value wrong (byte 3)'); + t.equal(ber[5], 0xbd, 'value wrong (byte 4)'); + + t.end(); +}); + + +test('write boolean', function(t) { + var writer = new BerWriter(); + + writer.writeBoolean(true); + writer.writeBoolean(false); + var ber = writer.buffer; + + t.ok(ber); + t.equal(ber.length, 6, 'Wrong length'); + t.equal(ber[0], 0x01, 'tag wrong'); + t.equal(ber[1], 0x01, 'length wrong'); + t.equal(ber[2], 0xff, 'value wrong'); + t.equal(ber[3], 0x01, 'tag wrong'); + t.equal(ber[4], 0x01, 'length wrong'); + t.equal(ber[5], 0x00, 'value wrong'); + + t.end(); +}); + + +test('write string', function(t) { + var writer = new BerWriter(); + writer.writeString('hello world'); + var ber = writer.buffer; + + t.ok(ber); + t.equal(ber.length, 13, 'wrong length'); + t.equal(ber[0], 0x04, 'wrong tag'); + t.equal(ber[1], 11, 'wrong length'); + t.equal(ber.slice(2).toString('utf8'), 'hello world', 'wrong value'); + + t.end(); +}); + +test('write buffer', function(t) { + var writer = new BerWriter(); + // write some stuff to start with + writer.writeString('hello world'); + var ber = writer.buffer; + var buf = new Buffer([0x04, 0x0b, 0x30, 0x09, 0x02, 0x01, 0x0f, 0x01, 0x01, + 0xff, 0x01, 0x01, 0xff]); + writer.writeBuffer(buf.slice(2, buf.length), 0x04); + ber = writer.buffer; + + t.ok(ber); + t.equal(ber.length, 26, 'wrong length'); + t.equal(ber[0], 0x04, 'wrong tag'); + t.equal(ber[1], 11, 'wrong length'); + t.equal(ber.slice(2, 13).toString('utf8'), 'hello world', 'wrong value'); + t.equal(ber[13], buf[0], 'wrong tag'); + t.equal(ber[14], buf[1], 'wrong length'); + for (var i = 13, j = 0; i < ber.length && j < buf.length; i++, j++) { + t.equal(ber[i], buf[j], 'buffer contents not identical'); + } + t.end(); +}); + +test('write string array', function(t) { + var writer = new BerWriter(); + writer.writeStringArray(['hello world', 'fubar!']); + var ber = writer.buffer; + + t.ok(ber); + + t.equal(ber.length, 21, 'wrong length'); + t.equal(ber[0], 0x04, 'wrong tag'); + t.equal(ber[1], 11, 'wrong length'); + t.equal(ber.slice(2, 13).toString('utf8'), 'hello world', 'wrong value'); + + t.equal(ber[13], 0x04, 'wrong tag'); + t.equal(ber[14], 6, 'wrong length'); + t.equal(ber.slice(15).toString('utf8'), 'fubar!', 'wrong value'); + + t.end(); +}); + + +test('resize internal buffer', function(t) { + var writer = new BerWriter({size: 2}); + writer.writeString('hello world'); + var ber = writer.buffer; + + t.ok(ber); + t.equal(ber.length, 13, 'wrong length'); + t.equal(ber[0], 0x04, 'wrong tag'); + t.equal(ber[1], 11, 'wrong length'); + t.equal(ber.slice(2).toString('utf8'), 'hello world', 'wrong value'); + + t.end(); +}); + + +test('sequence', function(t) { + var writer = new BerWriter({size: 25}); + writer.startSequence(); + writer.writeString('hello world'); + writer.endSequence(); + var ber = writer.buffer; + + t.ok(ber); + console.log(ber); + t.equal(ber.length, 15, 'wrong length'); + t.equal(ber[0], 0x30, 'wrong tag'); + t.equal(ber[1], 13, 'wrong length'); + t.equal(ber[2], 0x04, 'wrong tag'); + t.equal(ber[3], 11, 'wrong length'); + t.equal(ber.slice(4).toString('utf8'), 'hello world', 'wrong value'); + + t.end(); +}); + + +test('nested sequence', function(t) { + var writer = new BerWriter({size: 25}); + writer.startSequence(); + writer.writeString('hello world'); + writer.startSequence(); + writer.writeString('hello world'); + writer.endSequence(); + writer.endSequence(); + var ber = writer.buffer; + + t.ok(ber); + t.equal(ber.length, 30, 'wrong length'); + t.equal(ber[0], 0x30, 'wrong tag'); + t.equal(ber[1], 28, 'wrong length'); + t.equal(ber[2], 0x04, 'wrong tag'); + t.equal(ber[3], 11, 'wrong length'); + t.equal(ber.slice(4, 15).toString('utf8'), 'hello world', 'wrong value'); + t.equal(ber[15], 0x30, 'wrong tag'); + t.equal(ber[16], 13, 'wrong length'); + t.equal(ber[17], 0x04, 'wrong tag'); + t.equal(ber[18], 11, 'wrong length'); + t.equal(ber.slice(19, 30).toString('utf8'), 'hello world', 'wrong value'); + + t.end(); +}); + + +test('LDAP bind message', function(t) { + var dn = 'cn=foo,ou=unit,o=test'; + var writer = new BerWriter(); + writer.startSequence(); + writer.writeInt(3); // msgid = 3 + writer.startSequence(0x60); // ldap bind + writer.writeInt(3); // ldap v3 + writer.writeString(dn); + writer.writeByte(0x80); + writer.writeByte(0x00); + writer.endSequence(); + writer.endSequence(); + var ber = writer.buffer; + + t.ok(ber); + t.equal(ber.length, 35, 'wrong length (buffer)'); + t.equal(ber[0], 0x30, 'wrong tag'); + t.equal(ber[1], 33, 'wrong length'); + t.equal(ber[2], 0x02, 'wrong tag'); + t.equal(ber[3], 1, 'wrong length'); + t.equal(ber[4], 0x03, 'wrong value'); + t.equal(ber[5], 0x60, 'wrong tag'); + t.equal(ber[6], 28, 'wrong length'); + t.equal(ber[7], 0x02, 'wrong tag'); + t.equal(ber[8], 1, 'wrong length'); + t.equal(ber[9], 0x03, 'wrong value'); + t.equal(ber[10], 0x04, 'wrong tag'); + t.equal(ber[11], dn.length, 'wrong length'); + t.equal(ber.slice(12, 33).toString('utf8'), dn, 'wrong value'); + t.equal(ber[33], 0x80, 'wrong tag'); + t.equal(ber[34], 0x00, 'wrong len'); + + t.end(); +}); + + +test('Write OID', function(t) { + var oid = '1.2.840.113549.1.1.1'; + var writer = new BerWriter(); + writer.writeOID(oid); + + var ber = writer.buffer; + t.ok(ber); + console.log(require('util').inspect(ber)); + console.log(require('util').inspect(new Buffer([0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x01]))); + + t.end(); +}); diff --git a/node_modules/async/.gitmodules b/node_modules/async/.gitmodules new file mode 100644 index 0000000..a9aae98 --- /dev/null +++ b/node_modules/async/.gitmodules @@ -0,0 +1,9 @@ +[submodule "deps/nodeunit"] + path = deps/nodeunit + url = git://github.com/caolan/nodeunit.git +[submodule "deps/UglifyJS"] + path = deps/UglifyJS + url = https://github.com/mishoo/UglifyJS.git +[submodule "deps/nodelint"] + path = deps/nodelint + url = https://github.com/tav/nodelint.git diff --git a/node_modules/async/.npmignore b/node_modules/async/.npmignore new file mode 100644 index 0000000..9bdfc97 --- /dev/null +++ b/node_modules/async/.npmignore @@ -0,0 +1,4 @@ +deps +dist +test +nodelint.cfg \ No newline at end of file diff --git a/node_modules/async/LICENSE b/node_modules/async/LICENSE new file mode 100644 index 0000000..b7f9d50 --- /dev/null +++ b/node_modules/async/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010 Caolan McMahon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/async/Makefile b/node_modules/async/Makefile new file mode 100644 index 0000000..bad647c --- /dev/null +++ b/node_modules/async/Makefile @@ -0,0 +1,25 @@ +PACKAGE = asyncjs +NODEJS = $(if $(shell test -f /usr/bin/nodejs && echo "true"),nodejs,node) +CWD := $(shell pwd) +NODEUNIT = $(CWD)/node_modules/nodeunit/bin/nodeunit +UGLIFY = $(CWD)/node_modules/uglify-js/bin/uglifyjs +NODELINT = $(CWD)/node_modules/nodelint/nodelint + +BUILDDIR = dist + +all: clean test build + +build: $(wildcard lib/*.js) + mkdir -p $(BUILDDIR) + $(UGLIFY) lib/async.js > $(BUILDDIR)/async.min.js + +test: + $(NODEUNIT) test + +clean: + rm -rf $(BUILDDIR) + +lint: + $(NODELINT) --config nodelint.cfg lib/async.js + +.PHONY: test build all diff --git a/node_modules/async/README.md b/node_modules/async/README.md new file mode 100644 index 0000000..1bbbc47 --- /dev/null +++ b/node_modules/async/README.md @@ -0,0 +1,1021 @@ +# Async.js + +Async is a utility module which provides straight-forward, powerful functions +for working with asynchronous JavaScript. Although originally designed for +use with [node.js](http://nodejs.org), it can also be used directly in the +browser. + +Async provides around 20 functions that include the usual 'functional' +suspects (map, reduce, filter, forEach…) as well as some common patterns +for asynchronous control flow (parallel, series, waterfall…). All these +functions assume you follow the node.js convention of providing a single +callback as the last argument of your async function. + + +## Quick Examples + + async.map(['file1','file2','file3'], fs.stat, function(err, results){ + // results is now an array of stats for each file + }); + + async.filter(['file1','file2','file3'], path.exists, function(results){ + // results now equals an array of the existing files + }); + + async.parallel([ + function(){ ... }, + function(){ ... } + ], callback); + + async.series([ + function(){ ... }, + function(){ ... } + ]); + +There are many more functions available so take a look at the docs below for a +full list. This module aims to be comprehensive, so if you feel anything is +missing please create a GitHub issue for it. + + +## Download + +Releases are available for download from +[GitHub](http://github.com/caolan/async/downloads). +Alternatively, you can install using Node Package Manager (npm): + + npm install async + + +__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 17.5kb Uncompressed + +__Production:__ [async.min.js](https://github.com/caolan/async/raw/master/dist/async.min.js) - 1.7kb Packed and Gzipped + + +## In the Browser + +So far its been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage: + + + + + +## Documentation + +### Collections + +* [forEach](#forEach) +* [map](#map) +* [filter](#filter) +* [reject](#reject) +* [reduce](#reduce) +* [detect](#detect) +* [sortBy](#sortBy) +* [some](#some) +* [every](#every) +* [concat](#concat) + +### Control Flow + +* [series](#series) +* [parallel](#parallel) +* [whilst](#whilst) +* [until](#until) +* [waterfall](#waterfall) +* [queue](#queue) +* [auto](#auto) +* [iterator](#iterator) +* [apply](#apply) +* [nextTick](#nextTick) + +### Utils + +* [memoize](#memoize) +* [unmemoize](#unmemoize) +* [log](#log) +* [dir](#dir) +* [noConflict](#noConflict) + + +## Collections + + +### forEach(arr, iterator, callback) + +Applies an iterator function to each item in an array, in parallel. +The iterator is called with an item from the list and a callback for when it +has finished. If the iterator passes an error to this callback, the main +callback for the forEach function is immediately called with the error. + +Note, that since this function applies the iterator to each item in parallel +there is no guarantee that the iterator functions will complete in order. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(err) - A callback which is called after all the iterator functions + have finished, or an error has occurred. + +__Example__ + + // assuming openFiles is an array of file names and saveFile is a function + // to save the modified contents of that file: + + async.forEach(openFiles, saveFile, function(err){ + // if any of the saves produced an error, err would equal that error + }); + +--------------------------------------- + + +### forEachSeries(arr, iterator, callback) + +The same as forEach only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. This means the iterator functions will complete in order. + + +--------------------------------------- + + +### forEachLimit(arr, limit, iterator, callback) + +The same as forEach only the iterator is applied to batches of items in the +array, in series. The next batch of iterators is only called once the current +one has completed processing. + +__Arguments__ + +* arr - An array to iterate over. +* limit - How many items should be in each batch. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(err) - A callback which is called after all the iterator functions + have finished, or an error has occurred. + +__Example__ + + // Assume documents is an array of JSON objects and requestApi is a + // function that interacts with a rate-limited REST api. + + async.forEachLimit(documents, 20, requestApi, function(err){ + // if any of the saves produced an error, err would equal that error + }); +--------------------------------------- + + +### map(arr, iterator, callback) + +Produces a new array of values by mapping each value in the given array through +the iterator function. The iterator is called with an item from the array and a +callback for when it has finished processing. The callback takes 2 arguments, +an error and the transformed item from the array. If the iterator passes an +error to this callback, the main callback for the map function is immediately +called with the error. + +Note, that since this function applies the iterator to each item in parallel +there is no guarantee that the iterator functions will complete in order, however +the results array will be in the same order as the original array. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed + with an error (which can be null) and a transformed item. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is an array of the + transformed items from the original array. + +__Example__ + + async.map(['file1','file2','file3'], fs.stat, function(err, results){ + // results is now an array of stats for each file + }); + +--------------------------------------- + + +### mapSeries(arr, iterator, callback) + +The same as map only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. The results array will be in the same order as the original. + + +--------------------------------------- + + +### filter(arr, iterator, callback) + +__Alias:__ select + +Returns a new array of all the values which pass an async truth test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like path.exists. This operation is +performed in parallel, but the results array will be in the same order as the +original. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(results) - A callback which is called after all the iterator + functions have finished. + +__Example__ + + async.filter(['file1','file2','file3'], path.exists, function(results){ + // results now equals an array of the existing files + }); + +--------------------------------------- + + +### filterSeries(arr, iterator, callback) + +__alias:__ selectSeries + +The same as filter only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. The results array will be in the same order as the original. + +--------------------------------------- + + +### reject(arr, iterator, callback) + +The opposite of filter. Removes values that pass an async truth test. + +--------------------------------------- + + +### rejectSeries(arr, iterator, callback) + +The same as filter, only the iterator is applied to each item in the array +in series. + + +--------------------------------------- + + +### reduce(arr, memo, iterator, callback) + +__aliases:__ inject, foldl + +Reduces a list of values into a single value using an async iterator to return +each successive step. Memo is the initial state of the reduction. This +function only operates in series. For performance reasons, it may make sense to +split a call to this function into a parallel map, then use the normal +Array.prototype.reduce on the results. This function is for situations where +each step in the reduction needs to be async, if you can get the data before +reducing it then its probably a good idea to do so. + +__Arguments__ + +* arr - An array to iterate over. +* memo - The initial state of the reduction. +* iterator(memo, item, callback) - A function applied to each item in the + array to produce the next step in the reduction. The iterator is passed a + callback which accepts an optional error as its first argument, and the state + of the reduction as the second. If an error is passed to the callback, the + reduction is stopped and the main callback is immediately called with the + error. +* callback(err, result) - A callback which is called after all the iterator + functions have finished. Result is the reduced value. + +__Example__ + + async.reduce([1,2,3], 0, function(memo, item, callback){ + // pointless async: + process.nextTick(function(){ + callback(null, memo + item) + }); + }, function(err, result){ + // result is now equal to the last value of memo, which is 6 + }); + +--------------------------------------- + + +### reduceRight(arr, memo, iterator, callback) + +__Alias:__ foldr + +Same as reduce, only operates on the items in the array in reverse order. + + +--------------------------------------- + + +### detect(arr, iterator, callback) + +Returns the first value in a list that passes an async truth test. The +iterator is applied in parallel, meaning the first iterator to return true will +fire the detect callback with that result. That means the result might not be +the first item in the original array (in terms of order) that passes the test. + +If order within the original array is important then look at detectSeries. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(result) - A callback which is called as soon as any iterator returns + true, or after all the iterator functions have finished. Result will be + the first item in the array that passes the truth test (iterator) or the + value undefined if none passed. + +__Example__ + + async.detect(['file1','file2','file3'], path.exists, function(result){ + // result now equals the first file in the list that exists + }); + +--------------------------------------- + + +### detectSeries(arr, iterator, callback) + +The same as detect, only the iterator is applied to each item in the array +in series. This means the result is always the first in the original array (in +terms of array order) that passes the truth test. + + +--------------------------------------- + + +### sortBy(arr, iterator, callback) + +Sorts a list by the results of running each value through an async iterator. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed + with an error (which can be null) and a value to use as the sort criteria. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is the items from + the original array sorted by the values returned by the iterator calls. + +__Example__ + + async.sortBy(['file1','file2','file3'], function(file, callback){ + fs.stat(file, function(err, stats){ + callback(err, stats.mtime); + }); + }, function(err, results){ + // results is now the original array of files sorted by + // modified date + }); + + +--------------------------------------- + + +### some(arr, iterator, callback) + +__Alias:__ any + +Returns true if at least one element in the array satisfies an async test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like path.exists. Once any iterator +call returns true, the main callback is immediately called. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(result) - A callback which is called as soon as any iterator returns + true, or after all the iterator functions have finished. Result will be + either true or false depending on the values of the async tests. + +__Example__ + + async.some(['file1','file2','file3'], path.exists, function(result){ + // if result is true then at least one of the files exists + }); + +--------------------------------------- + + +### every(arr, iterator, callback) + +__Alias:__ all + +Returns true if every element in the array satisfies an async test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like path.exists. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(result) - A callback which is called after all the iterator + functions have finished. Result will be either true or false depending on + the values of the async tests. + +__Example__ + + async.every(['file1','file2','file3'], path.exists, function(result){ + // if result is true then every file exists + }); + +--------------------------------------- + + +### concat(arr, iterator, callback) + +Applies an iterator to each item in a list, concatenating the results. Returns the +concatenated list. The iterators are called in parallel, and the results are +concatenated as they return. There is no guarantee that the results array will +be returned in the original order of the arguments passed to the iterator function. + +__Arguments__ + +* arr - An array to iterate over +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed + with an error (which can be null) and an array of results. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is an array containing + the concatenated results of the iterator function. + +__Example__ + + async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){ + // files is now a list of filenames that exist in the 3 directories + }); + +--------------------------------------- + + +### concatSeries(arr, iterator, callback) + +Same as async.concat, but executes in series instead of parallel. + + +## Control Flow + + +### series(tasks, [callback]) + +Run an array of functions in series, each one running once the previous +function has completed. If any functions in the series pass an error to its +callback, no more functions are run and the callback for the series is +immediately called with the value of the error. Once the tasks have completed, +the results are passed to the final callback as an array. + +It is also possible to use an object instead of an array. Each property will be +run as a function and the results will be passed to the final callback as an object +instead of an array. This can be a more readable way of handling results from +async.series. + + +__Arguments__ + +* tasks - An array or object containing functions to run, each function is passed + a callback it must call on completion. +* callback(err, results) - An optional callback to run once all the functions + have completed. This function gets an array of all the arguments passed to + the callbacks used in the array. + +__Example__ + + async.series([ + function(callback){ + // do some stuff ... + callback(null, 'one'); + }, + function(callback){ + // do some more stuff ... + callback(null, 'two'); + }, + ], + // optional callback + function(err, results){ + // results is now equal to ['one', 'two'] + }); + + + // an example using an object instead of an array + async.series({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + }, + }, + function(err, results) { + // results is now equal to: {one: 1, two: 2} + }); + + +--------------------------------------- + + +### parallel(tasks, [callback]) + +Run an array of functions in parallel, without waiting until the previous +function has completed. If any of the functions pass an error to its +callback, the main callback is immediately called with the value of the error. +Once the tasks have completed, the results are passed to the final callback as an +array. + +It is also possible to use an object instead of an array. Each property will be +run as a function and the results will be passed to the final callback as an object +instead of an array. This can be a more readable way of handling results from +async.parallel. + + +__Arguments__ + +* tasks - An array or object containing functions to run, each function is passed a + callback it must call on completion. +* callback(err, results) - An optional callback to run once all the functions + have completed. This function gets an array of all the arguments passed to + the callbacks used in the array. + +__Example__ + + async.parallel([ + function(callback){ + setTimeout(function(){ + callback(null, 'one'); + }, 200); + }, + function(callback){ + setTimeout(function(){ + callback(null, 'two'); + }, 100); + }, + ], + // optional callback + function(err, results){ + // the results array will equal ['one','two'] even though + // the second function had a shorter timeout. + }); + + + // an example using an object instead of an array + async.parallel({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + }, + }, + function(err, results) { + // results is now equals to: {one: 1, two: 2} + }); + + +--------------------------------------- + + +### whilst(test, fn, callback) + +Repeatedly call fn, while test returns true. Calls the callback when stopped, +or an error occurs. + +__Arguments__ + +* test() - synchronous truth test to perform before each execution of fn. +* fn(callback) - A function to call each time the test passes. The function is + passed a callback which must be called once it has completed with an optional + error as the first argument. +* callback(err) - A callback which is called after the test fails and repeated + execution of fn has stopped. + +__Example__ + + var count = 0; + + async.whilst( + function () { return count < 5; }, + function (callback) { + count++; + setTimeout(callback, 1000); + }, + function (err) { + // 5 seconds have passed + } + ); + + +--------------------------------------- + + +### until(test, fn, callback) + +Repeatedly call fn, until test returns true. Calls the callback when stopped, +or an error occurs. + +The inverse of async.whilst. + + +--------------------------------------- + + +### waterfall(tasks, [callback]) + +Runs an array of functions in series, each passing their results to the next in +the array. However, if any of the functions pass an error to the callback, the +next function is not executed and the main callback is immediately called with +the error. + +__Arguments__ + +* tasks - An array of functions to run, each function is passed a callback it + must call on completion. +* callback(err, [results]) - An optional callback to run once all the functions + have completed. This will be passed the results of the last task's callback. + + + +__Example__ + + async.waterfall([ + function(callback){ + callback(null, 'one', 'two'); + }, + function(arg1, arg2, callback){ + callback(null, 'three'); + }, + function(arg1, callback){ + // arg1 now equals 'three' + callback(null, 'done'); + } + ], function (err, result) { + // result now equals 'done' + }); + + +--------------------------------------- + + +### queue(worker, concurrency) + +Creates a queue object with the specified concurrency. Tasks added to the +queue will be processed in parallel (up to the concurrency limit). If all +workers are in progress, the task is queued until one is available. Once +a worker has completed a task, the task's callback is called. + +__Arguments__ + +* worker(task, callback) - An asynchronous function for processing a queued + task. +* concurrency - An integer for determining how many worker functions should be + run in parallel. + +__Queue objects__ + +The queue object returned by this function has the following properties and +methods: + +* length() - a function returning the number of items waiting to be processed. +* concurrency - an integer for determining how many worker functions should be + run in parallel. This property can be changed after a queue is created to + alter the concurrency on-the-fly. +* push(task, [callback]) - add a new task to the queue, the callback is called + once the worker has finished processing the task. + instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list. +* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued +* empty - a callback that is called when the last item from the queue is given to a worker +* drain - a callback that is called when the last item from the queue has returned from the worker + +__Example__ + + // create a queue object with concurrency 2 + + var q = async.queue(function (task, callback) { + console.log('hello ' + task.name); + callback(); + }, 2); + + + // assign a callback + q.drain = function() { + console.log('all items have been processed'); + } + + // add some items to the queue + + q.push({name: 'foo'}, function (err) { + console.log('finished processing foo'); + }); + q.push({name: 'bar'}, function (err) { + console.log('finished processing bar'); + }); + + // add some items to the queue (batch-wise) + + q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) { + console.log('finished processing bar'); + }); + + +--------------------------------------- + + +### auto(tasks, [callback]) + +Determines the best order for running functions based on their requirements. +Each function can optionally depend on other functions being completed first, +and each function is run as soon as its requirements are satisfied. If any of +the functions pass an error to their callback, that function will not complete +(so any other functions depending on it will not run) and the main callback +will be called immediately with the error. Functions also receive an object +containing the results of functions which have completed so far. + +__Arguments__ + +* tasks - An object literal containing named functions or an array of + requirements, with the function itself the last item in the array. The key + used for each function or array is used when specifying requirements. The + syntax is easier to understand by looking at the example. +* callback(err, results) - An optional callback which is called when all the + tasks have been completed. The callback will receive an error as an argument + if any tasks pass an error to their callback. If all tasks complete + successfully, it will receive an object containing their results. + +__Example__ + + async.auto({ + get_data: function(callback){ + // async code to get some data + }, + make_folder: function(callback){ + // async code to create a directory to store a file in + // this is run at the same time as getting the data + }, + write_file: ['get_data', 'make_folder', function(callback){ + // once there is some data and the directory exists, + // write the data to a file in the directory + callback(null, filename); + }], + email_link: ['write_file', function(callback, results){ + // once the file is written let's email a link to it... + // results.write_file contains the filename returned by write_file. + }] + }); + +This is a fairly trivial example, but to do this using the basic parallel and +series functions would look like this: + + async.parallel([ + function(callback){ + // async code to get some data + }, + function(callback){ + // async code to create a directory to store a file in + // this is run at the same time as getting the data + } + ], + function(results){ + async.series([ + function(callback){ + // once there is some data and the directory exists, + // write the data to a file in the directory + }, + email_link: function(callback){ + // once the file is written let's email a link to it... + } + ]); + }); + +For a complicated series of async tasks using the auto function makes adding +new tasks much easier and makes the code more readable. + + +--------------------------------------- + + +### iterator(tasks) + +Creates an iterator function which calls the next function in the array, +returning a continuation to call the next one after that. Its also possible to +'peek' the next iterator by doing iterator.next(). + +This function is used internally by the async module but can be useful when +you want to manually control the flow of functions in series. + +__Arguments__ + +* tasks - An array of functions to run, each function is passed a callback it + must call on completion. + +__Example__ + + var iterator = async.iterator([ + function(){ sys.p('one'); }, + function(){ sys.p('two'); }, + function(){ sys.p('three'); } + ]); + + node> var iterator2 = iterator(); + 'one' + node> var iterator3 = iterator2(); + 'two' + node> iterator3(); + 'three' + node> var nextfn = iterator2.next(); + node> nextfn(); + 'three' + + +--------------------------------------- + + +### apply(function, arguments..) + +Creates a continuation function with some arguments already applied, a useful +shorthand when combined with other control flow functions. Any arguments +passed to the returned function are added to the arguments originally passed +to apply. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to automatically apply when the + continuation is called. + +__Example__ + + // using apply + + async.parallel([ + async.apply(fs.writeFile, 'testfile1', 'test1'), + async.apply(fs.writeFile, 'testfile2', 'test2'), + ]); + + + // the same process without using apply + + async.parallel([ + function(callback){ + fs.writeFile('testfile1', 'test1', callback); + }, + function(callback){ + fs.writeFile('testfile2', 'test2', callback); + }, + ]); + +It's possible to pass any number of additional arguments when calling the +continuation: + + node> var fn = async.apply(sys.puts, 'one'); + node> fn('two', 'three'); + one + two + three + +--------------------------------------- + + +### nextTick(callback) + +Calls the callback on a later loop around the event loop. In node.js this just +calls process.nextTick, in the browser it falls back to setTimeout(callback, 0), +which means other higher priority events may precede the execution of the callback. + +This is used internally for browser-compatibility purposes. + +__Arguments__ + +* callback - The function to call on a later loop around the event loop. + +__Example__ + + var call_order = []; + async.nextTick(function(){ + call_order.push('two'); + // call_order now equals ['one','two] + }); + call_order.push('one') + + +## Utils + + +### memoize(fn, [hasher]) + +Caches the results of an async function. When creating a hash to store function +results against, the callback is omitted from the hash and an optional hash +function can be used. + +__Arguments__ + +* fn - the function you to proxy and cache results from. +* hasher - an optional function for generating a custom hash for storing + results, it has all the arguments applied to it apart from the callback, and + must be synchronous. + +__Example__ + + var slow_fn = function (name, callback) { + // do something + callback(null, result); + }; + var fn = async.memoize(slow_fn); + + // fn can now be used as if it were slow_fn + fn('some name', function () { + // callback + }); + + +### unmemoize(fn) + +Undoes a memoized function, reverting it to the original, unmemoized +form. Comes handy in tests. + +__Arguments__ + +* fn - the memoized function + + +### log(function, arguments) + +Logs the result of an async function to the console. Only works in node.js or +in browsers that support console.log and console.error (such as FF and Chrome). +If multiple arguments are returned from the async function, console.log is +called on each argument in order. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to apply to the function. + +__Example__ + + var hello = function(name, callback){ + setTimeout(function(){ + callback(null, 'hello ' + name); + }, 1000); + }; + + node> async.log(hello, 'world'); + 'hello world' + + +--------------------------------------- + + +### dir(function, arguments) + +Logs the result of an async function to the console using console.dir to +display the properties of the resulting object. Only works in node.js or +in browsers that support console.dir and console.error (such as FF and Chrome). +If multiple arguments are returned from the async function, console.dir is +called on each argument in order. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to apply to the function. + +__Example__ + + var hello = function(name, callback){ + setTimeout(function(){ + callback(null, {hello: name}); + }, 1000); + }; + + node> async.dir(hello, 'world'); + {hello: 'world'} + + +--------------------------------------- + + +### noConflict() + +Changes the value of async back to its original value, returning a reference to the +async object. diff --git a/node_modules/async/index.js b/node_modules/async/index.js new file mode 100644 index 0000000..8e23845 --- /dev/null +++ b/node_modules/async/index.js @@ -0,0 +1,3 @@ +// This file is just added for convenience so this repository can be +// directly checked out into a project's deps folder +module.exports = require('./lib/async'); diff --git a/node_modules/async/lib/async.js b/node_modules/async/lib/async.js new file mode 100644 index 0000000..7cc4f5e --- /dev/null +++ b/node_modules/async/lib/async.js @@ -0,0 +1,692 @@ +/*global setTimeout: false, console: false */ +(function () { + + var async = {}; + + // global on the server, window in the browser + var root = this, + previous_async = root.async; + + if (typeof module !== 'undefined' && module.exports) { + module.exports = async; + } + else { + root.async = async; + } + + async.noConflict = function () { + root.async = previous_async; + return async; + }; + + //// cross-browser compatiblity functions //// + + var _forEach = function (arr, iterator) { + if (arr.forEach) { + return arr.forEach(iterator); + } + for (var i = 0; i < arr.length; i += 1) { + iterator(arr[i], i, arr); + } + }; + + var _map = function (arr, iterator) { + if (arr.map) { + return arr.map(iterator); + } + var results = []; + _forEach(arr, function (x, i, a) { + results.push(iterator(x, i, a)); + }); + return results; + }; + + var _reduce = function (arr, iterator, memo) { + if (arr.reduce) { + return arr.reduce(iterator, memo); + } + _forEach(arr, function (x, i, a) { + memo = iterator(memo, x, i, a); + }); + return memo; + }; + + var _keys = function (obj) { + if (Object.keys) { + return Object.keys(obj); + } + var keys = []; + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + keys.push(k); + } + } + return keys; + }; + + //// exported async module functions //// + + //// nextTick implementation with browser-compatible fallback //// + if (typeof process === 'undefined' || !(process.nextTick)) { + async.nextTick = function (fn) { + setTimeout(fn, 0); + }; + } + else { + async.nextTick = process.nextTick; + } + + async.forEach = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); + } + var completed = 0; + _forEach(arr, function (x) { + iterator(x, function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed === arr.length) { + callback(null); + } + } + }); + }); + }; + + async.forEachSeries = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); + } + var completed = 0; + var iterate = function () { + iterator(arr[completed], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed === arr.length) { + callback(null); + } + else { + iterate(); + } + } + }); + }; + iterate(); + }; + + async.forEachLimit = function (arr, limit, iterator, callback) { + callback = callback || function () {}; + if (!arr.length || limit <= 0) { + return callback(); + } + var completed = 0; + var started = 0; + var running = 0; + + (function replenish () { + if (completed === arr.length) { + return callback(); + } + + while (running < limit && started < arr.length) { + started += 1; + running += 1; + iterator(arr[started - 1], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + running -= 1; + if (completed === arr.length) { + callback(); + } + else { + replenish(); + } + } + }); + } + })(); + }; + + + var doParallel = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.forEach].concat(args)); + }; + }; + var doSeries = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.forEachSeries].concat(args)); + }; + }; + + + var _asyncMap = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (err, v) { + results[x.index] = v; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + }; + async.map = doParallel(_asyncMap); + async.mapSeries = doSeries(_asyncMap); + + + // reduce only has a series version, as doing reduce in parallel won't + // work in many situations. + async.reduce = function (arr, memo, iterator, callback) { + async.forEachSeries(arr, function (x, callback) { + iterator(memo, x, function (err, v) { + memo = v; + callback(err); + }); + }, function (err) { + callback(err, memo); + }); + }; + // inject alias + async.inject = async.reduce; + // foldl alias + async.foldl = async.reduce; + + async.reduceRight = function (arr, memo, iterator, callback) { + var reversed = _map(arr, function (x) { + return x; + }).reverse(); + async.reduce(reversed, memo, iterator, callback); + }; + // foldr alias + async.foldr = async.reduceRight; + + var _filter = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.filter = doParallel(_filter); + async.filterSeries = doSeries(_filter); + // select alias + async.select = async.filter; + async.selectSeries = async.filterSeries; + + var _reject = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (!v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.reject = doParallel(_reject); + async.rejectSeries = doSeries(_reject); + + var _detect = function (eachfn, arr, iterator, main_callback) { + eachfn(arr, function (x, callback) { + iterator(x, function (result) { + if (result) { + main_callback(x); + main_callback = function () {}; + } + else { + callback(); + } + }); + }, function (err) { + main_callback(); + }); + }; + async.detect = doParallel(_detect); + async.detectSeries = doSeries(_detect); + + async.some = function (arr, iterator, main_callback) { + async.forEach(arr, function (x, callback) { + iterator(x, function (v) { + if (v) { + main_callback(true); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(false); + }); + }; + // any alias + async.any = async.some; + + async.every = function (arr, iterator, main_callback) { + async.forEach(arr, function (x, callback) { + iterator(x, function (v) { + if (!v) { + main_callback(false); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(true); + }); + }; + // all alias + async.all = async.every; + + async.sortBy = function (arr, iterator, callback) { + async.map(arr, function (x, callback) { + iterator(x, function (err, criteria) { + if (err) { + callback(err); + } + else { + callback(null, {value: x, criteria: criteria}); + } + }); + }, function (err, results) { + if (err) { + return callback(err); + } + else { + var fn = function (left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }; + callback(null, _map(results.sort(fn), function (x) { + return x.value; + })); + } + }); + }; + + async.auto = function (tasks, callback) { + callback = callback || function () {}; + var keys = _keys(tasks); + if (!keys.length) { + return callback(null); + } + + var results = {}; + + var listeners = []; + var addListener = function (fn) { + listeners.unshift(fn); + }; + var removeListener = function (fn) { + for (var i = 0; i < listeners.length; i += 1) { + if (listeners[i] === fn) { + listeners.splice(i, 1); + return; + } + } + }; + var taskComplete = function () { + _forEach(listeners.slice(0), function (fn) { + fn(); + }); + }; + + addListener(function () { + if (_keys(results).length === keys.length) { + callback(null, results); + callback = function () {}; + } + }); + + _forEach(keys, function (k) { + var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; + var taskCallback = function (err) { + if (err) { + callback(err); + // stop subsequent errors hitting callback multiple times + callback = function () {}; + } + else { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + taskComplete(); + } + }; + var requires = task.slice(0, Math.abs(task.length - 1)) || []; + var ready = function () { + return _reduce(requires, function (a, x) { + return (a && results.hasOwnProperty(x)); + }, true) && !results.hasOwnProperty(k); + }; + if (ready()) { + task[task.length - 1](taskCallback, results); + } + else { + var listener = function () { + if (ready()) { + removeListener(listener); + task[task.length - 1](taskCallback, results); + } + }; + addListener(listener); + } + }); + }; + + async.waterfall = function (tasks, callback) { + callback = callback || function () {}; + if (!tasks.length) { + return callback(); + } + var wrapIterator = function (iterator) { + return function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + var args = Array.prototype.slice.call(arguments, 1); + var next = iterator.next(); + if (next) { + args.push(wrapIterator(next)); + } + else { + args.push(callback); + } + async.nextTick(function () { + iterator.apply(null, args); + }); + } + }; + }; + wrapIterator(async.iterator(tasks))(); + }; + + async.parallel = function (tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor === Array) { + async.map(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + async.forEach(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.series = function (tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor === Array) { + async.mapSeries(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + async.forEachSeries(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.iterator = function (tasks) { + var makeCallback = function (index) { + var fn = function () { + if (tasks.length) { + tasks[index].apply(null, arguments); + } + return fn.next(); + }; + fn.next = function () { + return (index < tasks.length - 1) ? makeCallback(index + 1): null; + }; + return fn; + }; + return makeCallback(0); + }; + + async.apply = function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + return function () { + return fn.apply( + null, args.concat(Array.prototype.slice.call(arguments)) + ); + }; + }; + + var _concat = function (eachfn, arr, fn, callback) { + var r = []; + eachfn(arr, function (x, cb) { + fn(x, function (err, y) { + r = r.concat(y || []); + cb(err); + }); + }, function (err) { + callback(err, r); + }); + }; + async.concat = doParallel(_concat); + async.concatSeries = doSeries(_concat); + + async.whilst = function (test, iterator, callback) { + if (test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.whilst(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.until = function (test, iterator, callback) { + if (!test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.until(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.queue = function (worker, concurrency) { + var workers = 0; + var q = { + tasks: [], + concurrency: concurrency, + saturated: null, + empty: null, + drain: null, + push: function (data, callback) { + if(data.constructor !== Array) { + data = [data]; + } + _forEach(data, function(task) { + q.tasks.push({ + data: task, + callback: typeof callback === 'function' ? callback : null + }); + if (q.saturated && q.tasks.length == concurrency) { + q.saturated(); + } + async.nextTick(q.process); + }); + }, + process: function () { + if (workers < q.concurrency && q.tasks.length) { + var task = q.tasks.shift(); + if(q.empty && q.tasks.length == 0) q.empty(); + workers += 1; + worker(task.data, function () { + workers -= 1; + if (task.callback) { + task.callback.apply(task, arguments); + } + if(q.drain && q.tasks.length + workers == 0) q.drain(); + q.process(); + }); + } + }, + length: function () { + return q.tasks.length; + }, + running: function () { + return workers; + } + }; + return q; + }; + + var _console_fn = function (name) { + return function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + fn.apply(null, args.concat([function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (typeof console !== 'undefined') { + if (err) { + if (console.error) { + console.error(err); + } + } + else if (console[name]) { + _forEach(args, function (x) { + console[name](x); + }); + } + } + }])); + }; + }; + async.log = _console_fn('log'); + async.dir = _console_fn('dir'); + /*async.info = _console_fn('info'); + async.warn = _console_fn('warn'); + async.error = _console_fn('error');*/ + + async.memoize = function (fn, hasher) { + var memo = {}; + var queues = {}; + hasher = hasher || function (x) { + return x; + }; + var memoized = function () { + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + var key = hasher.apply(null, args); + if (key in memo) { + callback.apply(null, memo[key]); + } + else if (key in queues) { + queues[key].push(callback); + } + else { + queues[key] = [callback]; + fn.apply(null, args.concat([function () { + memo[key] = arguments; + var q = queues[key]; + delete queues[key]; + for (var i = 0, l = q.length; i < l; i++) { + q[i].apply(null, arguments); + } + }])); + } + }; + memoized.unmemoized = fn; + return memoized; + }; + + async.unmemoize = function (fn) { + return function () { + return (fn.unmemoized || fn).apply(null, arguments); + }; + }; + +}()); diff --git a/node_modules/async/package.json b/node_modules/async/package.json new file mode 100644 index 0000000..466e05d --- /dev/null +++ b/node_modules/async/package.json @@ -0,0 +1,90 @@ +{ + "_args": [ + [ + { + "raw": "async@~0.1.22", + "scope": null, + "escapedName": "async", + "name": "async", + "rawSpec": "~0.1.22", + "spec": ">=0.1.22 <0.2.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt" + ] + ], + "_defaultsLoaded": true, + "_engineSupported": true, + "_from": "async@>=0.1.22 <0.2.0", + "_id": "async@0.1.22", + "_inCache": true, + "_location": "/async", + "_nodeVersion": "v0.6.18", + "_npmUser": { + "name": "caolan", + "email": "caolan@caolanmcmahon.com" + }, + "_npmVersion": "1.1.21", + "_phantomChildren": {}, + "_requested": { + "raw": "async@~0.1.22", + "scope": null, + "escapedName": "async", + "name": "async", + "rawSpec": "~0.1.22", + "spec": ">=0.1.22 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt", + "/grunt-legacy-util" + ], + "_resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz", + "_shasum": "0fc1aaa088a0e3ef0ebe2d8831bab0dcf8845061", + "_shrinkwrap": null, + "_spec": "async@~0.1.22", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt", + "author": { + "name": "Caolan McMahon" + }, + "bugs": { + "url": "http://github.com/caolan/async/issues" + }, + "dependencies": {}, + "description": "Higher-order functions and common patterns for asynchronous code", + "devDependencies": { + "nodelint": ">0.0.0", + "nodeunit": ">0.0.0", + "uglify-js": "1.2.x" + }, + "directories": {}, + "dist": { + "shasum": "0fc1aaa088a0e3ef0ebe2d8831bab0dcf8845061", + "tarball": "https://registry.npmjs.org/async/-/async-0.1.22.tgz" + }, + "engines": { + "node": "*" + }, + "homepage": "https://github.com/caolan/async#readme", + "licenses": [ + { + "type": "MIT", + "url": "http://github.com/caolan/async/raw/master/LICENSE" + } + ], + "main": "./index", + "maintainers": [ + { + "name": "caolan", + "email": "caolan@caolanmcmahon.com" + } + ], + "name": "async", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/caolan/async.git" + }, + "version": "0.1.22" +} diff --git a/node_modules/balanced-match/.npmignore b/node_modules/balanced-match/.npmignore new file mode 100644 index 0000000..ae5d8c3 --- /dev/null +++ b/node_modules/balanced-match/.npmignore @@ -0,0 +1,5 @@ +test +.gitignore +.travis.yml +Makefile +example.js diff --git a/node_modules/balanced-match/LICENSE.md b/node_modules/balanced-match/LICENSE.md new file mode 100644 index 0000000..2cdc8e4 --- /dev/null +++ b/node_modules/balanced-match/LICENSE.md @@ -0,0 +1,21 @@ +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/balanced-match/README.md b/node_modules/balanced-match/README.md new file mode 100644 index 0000000..08e918c --- /dev/null +++ b/node_modules/balanced-match/README.md @@ -0,0 +1,91 @@ +# balanced-match + +Match balanced string pairs, like `{` and `}` or `` and ``. Supports regular expressions as well! + +[![build status](https://secure.travis-ci.org/juliangruber/balanced-match.svg)](http://travis-ci.org/juliangruber/balanced-match) +[![downloads](https://img.shields.io/npm/dm/balanced-match.svg)](https://www.npmjs.org/package/balanced-match) + +[![testling badge](https://ci.testling.com/juliangruber/balanced-match.png)](https://ci.testling.com/juliangruber/balanced-match) + +## Example + +Get the first matching pair of braces: + +```js +var balanced = require('balanced-match'); + +console.log(balanced('{', '}', 'pre{in{nested}}post')); +console.log(balanced('{', '}', 'pre{first}between{second}post')); +console.log(balanced(/\s+\{\s+/, /\s+\}\s+/, 'pre { in{nest} } post')); +``` + +The matches are: + +```bash +$ node example.js +{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' } +{ start: 3, + end: 9, + pre: 'pre', + body: 'first', + post: 'between{second}post' } +{ start: 3, end: 17, pre: 'pre', body: 'in{nest}', post: 'post' } +``` + +## API + +### var m = balanced(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +object with those keys: + +* **start** the index of the first match of `a` +* **end** the index of the matching `b` +* **pre** the preamble, `a` and `b` not included +* **body** the match, `a` and `b` not included +* **post** the postscript, `a` and `b` not included + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']` and `{a}}` will match `['', 'a', '}']`. + +### var r = balanced.range(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +array with indexes: `[ , ]`. + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]` and `{a}}` will match `[0, 2]`. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install balanced-match +``` + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/balanced-match/index.js b/node_modules/balanced-match/index.js new file mode 100644 index 0000000..e8d8587 --- /dev/null +++ b/node_modules/balanced-match/index.js @@ -0,0 +1,58 @@ +module.exports = balanced; +function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); + + var r = range(a, b, str); + + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} + +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; +} + +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; + + if (ai >= 0 && bi > 0) { + begs = []; + left = str.length; + + while (i >= 0 && !result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; + } + + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; + } + + if (begs.length) { + result = [ left, right ]; + } + } + + return result; +} diff --git a/node_modules/balanced-match/package.json b/node_modules/balanced-match/package.json new file mode 100644 index 0000000..55f2829 --- /dev/null +++ b/node_modules/balanced-match/package.json @@ -0,0 +1,110 @@ +{ + "_args": [ + [ + { + "raw": "balanced-match@^0.4.1", + "scope": null, + "escapedName": "balanced-match", + "name": "balanced-match", + "rawSpec": "^0.4.1", + "spec": ">=0.4.1 <0.5.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/brace-expansion" + ] + ], + "_from": "balanced-match@>=0.4.1 <0.5.0", + "_id": "balanced-match@0.4.2", + "_inCache": true, + "_location": "/balanced-match", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/balanced-match-0.4.2.tgz_1468834991581_0.6590619895141572" + }, + "_npmUser": { + "name": "juliangruber", + "email": "julian@juliangruber.com" + }, + "_npmVersion": "2.15.8", + "_phantomChildren": {}, + "_requested": { + "raw": "balanced-match@^0.4.1", + "scope": null, + "escapedName": "balanced-match", + "name": "balanced-match", + "rawSpec": "^0.4.1", + "spec": ">=0.4.1 <0.5.0", + "type": "range" + }, + "_requiredBy": [ + "/brace-expansion" + ], + "_resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "_shasum": "cb3f3e3c732dc0f01ee70b403f302e61d7709838", + "_shrinkwrap": null, + "_spec": "balanced-match@^0.4.1", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/brace-expansion", + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "bugs": { + "url": "https://github.com/juliangruber/balanced-match/issues" + }, + "dependencies": {}, + "description": "Match balanced character pairs, like \"{\" and \"}\"", + "devDependencies": { + "tape": "^4.6.0" + }, + "directories": {}, + "dist": { + "shasum": "cb3f3e3c732dc0f01ee70b403f302e61d7709838", + "tarball": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz" + }, + "gitHead": "57c2ea29d89a2844ae3bdcc637c6e2cbb73725e2", + "homepage": "https://github.com/juliangruber/balanced-match", + "keywords": [ + "match", + "regexp", + "test", + "balanced", + "parse" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "juliangruber", + "email": "julian@juliangruber.com" + } + ], + "name": "balanced-match", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/balanced-match.git" + }, + "scripts": { + "test": "make test" + }, + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + }, + "version": "0.4.2" +} diff --git a/node_modules/brace-expansion/README.md b/node_modules/brace-expansion/README.md new file mode 100644 index 0000000..1793929 --- /dev/null +++ b/node_modules/brace-expansion/README.md @@ -0,0 +1,122 @@ +# brace-expansion + +[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html), +as known from sh/bash, in JavaScript. + +[![build status](https://secure.travis-ci.org/juliangruber/brace-expansion.svg)](http://travis-ci.org/juliangruber/brace-expansion) +[![downloads](https://img.shields.io/npm/dm/brace-expansion.svg)](https://www.npmjs.org/package/brace-expansion) + +[![testling badge](https://ci.testling.com/juliangruber/brace-expansion.png)](https://ci.testling.com/juliangruber/brace-expansion) + +## Example + +```js +var expand = require('brace-expansion'); + +expand('file-{a,b,c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('-v{,,}') +// => ['-v', '-v', '-v'] + +expand('file{0..2}.jpg') +// => ['file0.jpg', 'file1.jpg', 'file2.jpg'] + +expand('file-{a..c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('file{2..0}.jpg') +// => ['file2.jpg', 'file1.jpg', 'file0.jpg'] + +expand('file{0..4..2}.jpg') +// => ['file0.jpg', 'file2.jpg', 'file4.jpg'] + +expand('file-{a..e..2}.jpg') +// => ['file-a.jpg', 'file-c.jpg', 'file-e.jpg'] + +expand('file{00..10..5}.jpg') +// => ['file00.jpg', 'file05.jpg', 'file10.jpg'] + +expand('{{A..C},{a..c}}') +// => ['A', 'B', 'C', 'a', 'b', 'c'] + +expand('ppp{,config,oe{,conf}}') +// => ['ppp', 'pppconfig', 'pppoe', 'pppoeconf'] +``` + +## API + +```js +var expand = require('brace-expansion'); +``` + +### var expanded = expand(str) + +Return an array of all possible and valid expansions of `str`. If none are +found, `[str]` is returned. + +Valid expansions are: + +```js +/^(.*,)+(.+)?$/ +// {a,b,...} +``` + +A comma seperated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +A numeric sequence from `x` to `y` inclusive, with optional increment. +If `x` or `y` start with a leading `0`, all the numbers will be padded +to have equal length. Negative numbers and backwards iteration work too. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +An alphabetic sequence from `x` to `y` inclusive, with optional increment. +`x` and `y` must be exactly one character, and if given, `incr` must be a +number. + +For compatibility reasons, the string `${` is not eligible for brace expansion. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install brace-expansion +``` + +## Contributors + +- [Julian Gruber](https://github.com/juliangruber) +- [Isaac Z. Schlueter](https://github.com/isaacs) + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/brace-expansion/index.js b/node_modules/brace-expansion/index.js new file mode 100644 index 0000000..955f27c --- /dev/null +++ b/node_modules/brace-expansion/index.js @@ -0,0 +1,201 @@ +var concatMap = require('concat-map'); +var balanced = require('balanced-match'); + +module.exports = expandTop; + +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} + + +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balanced('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function identity(e) { + return e; +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = /^(.*,)+(.+)?$/.test(m.body); + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + + return expansions; +} + diff --git a/node_modules/brace-expansion/package.json b/node_modules/brace-expansion/package.json new file mode 100644 index 0000000..4335c29 --- /dev/null +++ b/node_modules/brace-expansion/package.json @@ -0,0 +1,115 @@ +{ + "_args": [ + [ + { + "raw": "brace-expansion@^1.0.0", + "scope": null, + "escapedName": "brace-expansion", + "name": "brace-expansion", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt-contrib-clean/node_modules/minimatch" + ] + ], + "_from": "brace-expansion@>=1.0.0 <2.0.0", + "_id": "brace-expansion@1.1.6", + "_inCache": true, + "_location": "/brace-expansion", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/brace-expansion-1.1.6.tgz_1469047715600_0.9362958471756428" + }, + "_npmUser": { + "name": "juliangruber", + "email": "julian@juliangruber.com" + }, + "_npmVersion": "2.15.8", + "_phantomChildren": {}, + "_requested": { + "raw": "brace-expansion@^1.0.0", + "scope": null, + "escapedName": "brace-expansion", + "name": "brace-expansion", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/cli/minimatch", + "/grunt-contrib-clean/minimatch", + "/grunt-sftp-deploy/minimatch", + "/jshint/minimatch" + ], + "_resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", + "_shasum": "7197d7eaa9b87e648390ea61fc66c84427420df9", + "_shrinkwrap": null, + "_spec": "brace-expansion@^1.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt-contrib-clean/node_modules/minimatch", + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "bugs": { + "url": "https://github.com/juliangruber/brace-expansion/issues" + }, + "dependencies": { + "balanced-match": "^0.4.1", + "concat-map": "0.0.1" + }, + "description": "Brace expansion as known from sh/bash", + "devDependencies": { + "tape": "^4.6.0" + }, + "directories": {}, + "dist": { + "shasum": "7197d7eaa9b87e648390ea61fc66c84427420df9", + "tarball": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz" + }, + "gitHead": "791262fa06625e9c5594cde529a21d82086af5f2", + "homepage": "https://github.com/juliangruber/brace-expansion", + "keywords": [], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "juliangruber", + "email": "julian@juliangruber.com" + }, + { + "name": "isaacs", + "email": "isaacs@npmjs.com" + } + ], + "name": "brace-expansion", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/brace-expansion.git" + }, + "scripts": { + "gentest": "bash test/generate.sh", + "test": "tape test/*.js" + }, + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + }, + "version": "1.1.6" +} diff --git a/node_modules/browserify-zlib/.npmignore b/node_modules/browserify-zlib/.npmignore new file mode 100644 index 0000000..2752eb9 --- /dev/null +++ b/node_modules/browserify-zlib/.npmignore @@ -0,0 +1,2 @@ +node_modules/ +.DS_Store diff --git a/node_modules/browserify-zlib/.travis.yml b/node_modules/browserify-zlib/.travis.yml new file mode 100644 index 0000000..87f8cd9 --- /dev/null +++ b/node_modules/browserify-zlib/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "0.10" \ No newline at end of file diff --git a/node_modules/browserify-zlib/README.md b/node_modules/browserify-zlib/README.md new file mode 100644 index 0000000..61f323a --- /dev/null +++ b/node_modules/browserify-zlib/README.md @@ -0,0 +1,22 @@ +# browserify-zlib + +Emulates Node's [zlib](http://nodejs.org/api/zlib.html) module for [Browserify](http://browserify.org) +using [pako](https://github.com/nodeca/pako). It uses the actual Node source code and passes the Node zlib tests +by emulating the C++ binding that actually calls zlib. + +[![browser support](https://ci.testling.com/devongovett/browserify-zlib.png) +](https://ci.testling.com/devongovett/browserify-zlib) + +[![node tests](https://travis-ci.org/devongovett/browserify-zlib.svg) +](https://travis-ci.org/devongovett/browserify-zlib) + +## Not implemented + +The following options/methods are not supported because pako does not support them yet. + +* The `params` method +* The `dictionary` option + +## License + +MIT diff --git a/node_modules/browserify-zlib/package.json b/node_modules/browserify-zlib/package.json new file mode 100644 index 0000000..6d082ae --- /dev/null +++ b/node_modules/browserify-zlib/package.json @@ -0,0 +1,102 @@ +{ + "_args": [ + [ + { + "raw": "browserify-zlib@^0.1.4", + "scope": null, + "escapedName": "browserify-zlib", + "name": "browserify-zlib", + "rawSpec": "^0.1.4", + "spec": ">=0.1.4 <0.2.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/gzip-size" + ] + ], + "_from": "browserify-zlib@>=0.1.4 <0.2.0", + "_id": "browserify-zlib@0.1.4", + "_inCache": true, + "_location": "/browserify-zlib", + "_npmUser": { + "name": "devongovett", + "email": "devongovett@gmail.com" + }, + "_npmVersion": "1.4.4", + "_phantomChildren": {}, + "_requested": { + "raw": "browserify-zlib@^0.1.4", + "scope": null, + "escapedName": "browserify-zlib", + "name": "browserify-zlib", + "rawSpec": "^0.1.4", + "spec": ">=0.1.4 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/gzip-size" + ], + "_resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "_shasum": "bb35f8a519f600e0fa6b8485241c979d0141fb2d", + "_shrinkwrap": null, + "_spec": "browserify-zlib@^0.1.4", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/gzip-size", + "author": { + "name": "Devon Govett", + "email": "devongovett@gmail.com" + }, + "bugs": { + "url": "https://github.com/devongovett/browserify-zlib/issues" + }, + "dependencies": { + "pako": "~0.2.0" + }, + "description": "Full zlib module for browserify", + "devDependencies": { + "brfs": "^1.0.1", + "tape": "^2.12.3" + }, + "directories": { + "test": "test" + }, + "dist": { + "shasum": "bb35f8a519f600e0fa6b8485241c979d0141fb2d", + "tarball": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz" + }, + "homepage": "https://github.com/devongovett/browserify-zlib", + "keywords": [ + "zlib", + "browserify" + ], + "license": "MIT", + "main": "src/index.js", + "maintainers": [ + { + "name": "devongovett", + "email": "devongovett@gmail.com" + } + ], + "name": "browserify-zlib", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/devongovett/browserify-zlib.git" + }, + "scripts": { + "test": "node_modules/tape/bin/tape test/*.js" + }, + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/6..latest", + "chrome/22..latest", + "firefox/16..latest", + "safari/latest", + "opera/11.0..latest", + "iphone/6", + "ipad/6", + "android-browser/latest" + ] + }, + "version": "0.1.4" +} diff --git a/node_modules/browserify-zlib/src/binding.js b/node_modules/browserify-zlib/src/binding.js new file mode 100644 index 0000000..7244b43 --- /dev/null +++ b/node_modules/browserify-zlib/src/binding.js @@ -0,0 +1,236 @@ +var msg = require('pako/lib/zlib/messages'); +var zstream = require('pako/lib/zlib/zstream'); +var zlib_deflate = require('pako/lib/zlib/deflate.js'); +var zlib_inflate = require('pako/lib/zlib/inflate.js'); +var constants = require('pako/lib/zlib/constants'); + +for (var key in constants) { + exports[key] = constants[key]; +} + +// zlib modes +exports.NONE = 0; +exports.DEFLATE = 1; +exports.INFLATE = 2; +exports.GZIP = 3; +exports.GUNZIP = 4; +exports.DEFLATERAW = 5; +exports.INFLATERAW = 6; +exports.UNZIP = 7; + +/** + * Emulate Node's zlib C++ layer for use by the JS layer in index.js + */ +function Zlib(mode) { + if (mode < exports.DEFLATE || mode > exports.UNZIP) + throw new TypeError("Bad argument"); + + this.mode = mode; + this.init_done = false; + this.write_in_progress = false; + this.pending_close = false; + this.windowBits = 0; + this.level = 0; + this.memLevel = 0; + this.strategy = 0; + this.dictionary = null; +} + +Zlib.prototype.init = function(windowBits, level, memLevel, strategy, dictionary) { + this.windowBits = windowBits; + this.level = level; + this.memLevel = memLevel; + this.strategy = strategy; + // dictionary not supported. + + if (this.mode === exports.GZIP || this.mode === exports.GUNZIP) + this.windowBits += 16; + + if (this.mode === exports.UNZIP) + this.windowBits += 32; + + if (this.mode === exports.DEFLATERAW || this.mode === exports.INFLATERAW) + this.windowBits = -this.windowBits; + + this.strm = new zstream(); + + switch (this.mode) { + case exports.DEFLATE: + case exports.GZIP: + case exports.DEFLATERAW: + var status = zlib_deflate.deflateInit2( + this.strm, + this.level, + exports.Z_DEFLATED, + this.windowBits, + this.memLevel, + this.strategy + ); + break; + case exports.INFLATE: + case exports.GUNZIP: + case exports.INFLATERAW: + case exports.UNZIP: + var status = zlib_inflate.inflateInit2( + this.strm, + this.windowBits + ); + break; + default: + throw new Error("Unknown mode " + this.mode); + } + + if (status !== exports.Z_OK) { + this._error(status); + return; + } + + this.write_in_progress = false; + this.init_done = true; +}; + +Zlib.prototype.params = function() { + throw new Error("deflateParams Not supported"); +}; + +Zlib.prototype._writeCheck = function() { + if (!this.init_done) + throw new Error("write before init"); + + if (this.mode === exports.NONE) + throw new Error("already finalized"); + + if (this.write_in_progress) + throw new Error("write already in progress"); + + if (this.pending_close) + throw new Error("close is pending"); +}; + +Zlib.prototype.write = function(flush, input, in_off, in_len, out, out_off, out_len) { + this._writeCheck(); + this.write_in_progress = true; + + var self = this; + process.nextTick(function() { + self.write_in_progress = false; + var res = self._write(flush, input, in_off, in_len, out, out_off, out_len); + self.callback(res[0], res[1]); + + if (self.pending_close) + self.close(); + }); + + return this; +}; + +// set method for Node buffers, used by pako +function bufferSet(data, offset) { + for (var i = 0; i < data.length; i++) { + this[offset + i] = data[i]; + } +} + +Zlib.prototype.writeSync = function(flush, input, in_off, in_len, out, out_off, out_len) { + this._writeCheck(); + return this._write(flush, input, in_off, in_len, out, out_off, out_len); +}; + +Zlib.prototype._write = function(flush, input, in_off, in_len, out, out_off, out_len) { + this.write_in_progress = true; + + if (flush !== exports.Z_NO_FLUSH && + flush !== exports.Z_PARTIAL_FLUSH && + flush !== exports.Z_SYNC_FLUSH && + flush !== exports.Z_FULL_FLUSH && + flush !== exports.Z_FINISH && + flush !== exports.Z_BLOCK) { + throw new Error("Invalid flush value"); + } + + if (input == null) { + input = new Buffer(0); + in_len = 0; + in_off = 0; + } + + if (out._set) + out.set = out._set; + else + out.set = bufferSet; + + var strm = this.strm; + strm.avail_in = in_len; + strm.input = input; + strm.next_in = in_off; + strm.avail_out = out_len; + strm.output = out; + strm.next_out = out_off; + + switch (this.mode) { + case exports.DEFLATE: + case exports.GZIP: + case exports.DEFLATERAW: + var status = zlib_deflate.deflate(strm, flush); + break; + case exports.UNZIP: + case exports.INFLATE: + case exports.GUNZIP: + case exports.INFLATERAW: + var status = zlib_inflate.inflate(strm, flush); + break; + default: + throw new Error("Unknown mode " + this.mode); + } + + if (status !== exports.Z_STREAM_END && status !== exports.Z_OK) { + this._error(status); + } + + this.write_in_progress = false; + return [strm.avail_in, strm.avail_out]; +}; + +Zlib.prototype.close = function() { + if (this.write_in_progress) { + this.pending_close = true; + return; + } + + this.pending_close = false; + + if (this.mode === exports.DEFLATE || this.mode === exports.GZIP || this.mode === exports.DEFLATERAW) { + zlib_deflate.deflateEnd(this.strm); + } else { + zlib_inflate.inflateEnd(this.strm); + } + + this.mode = exports.NONE; +}; + +Zlib.prototype.reset = function() { + switch (this.mode) { + case exports.DEFLATE: + case exports.DEFLATERAW: + var status = zlib_deflate.deflateReset(this.strm); + break; + case exports.INFLATE: + case exports.INFLATERAW: + var status = zlib_inflate.inflateReset(this.strm); + break; + } + + if (status !== exports.Z_OK) { + this._error(status); + } +}; + +Zlib.prototype._error = function(status) { + this.onerror(msg[status] + ': ' + this.strm.msg, status); + + this.write_in_progress = false; + if (this.pending_close) + this.close(); +}; + +exports.Zlib = Zlib; diff --git a/node_modules/browserify-zlib/src/index.js b/node_modules/browserify-zlib/src/index.js new file mode 100644 index 0000000..032689c --- /dev/null +++ b/node_modules/browserify-zlib/src/index.js @@ -0,0 +1,610 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var Transform = require('_stream_transform'); + +var binding = require('./binding'); +var util = require('util'); +var assert = require('assert').ok; + +// zlib doesn't provide these, so kludge them in following the same +// const naming scheme zlib uses. +binding.Z_MIN_WINDOWBITS = 8; +binding.Z_MAX_WINDOWBITS = 15; +binding.Z_DEFAULT_WINDOWBITS = 15; + +// fewer than 64 bytes per chunk is stupid. +// technically it could work with as few as 8, but even 64 bytes +// is absurdly low. Usually a MB or more is best. +binding.Z_MIN_CHUNK = 64; +binding.Z_MAX_CHUNK = Infinity; +binding.Z_DEFAULT_CHUNK = (16 * 1024); + +binding.Z_MIN_MEMLEVEL = 1; +binding.Z_MAX_MEMLEVEL = 9; +binding.Z_DEFAULT_MEMLEVEL = 8; + +binding.Z_MIN_LEVEL = -1; +binding.Z_MAX_LEVEL = 9; +binding.Z_DEFAULT_LEVEL = binding.Z_DEFAULT_COMPRESSION; + +// expose all the zlib constants +Object.keys(binding).forEach(function(k) { + if (k.match(/^Z/)) exports[k] = binding[k]; +}); + +// translation table for return codes. +exports.codes = { + Z_OK: binding.Z_OK, + Z_STREAM_END: binding.Z_STREAM_END, + Z_NEED_DICT: binding.Z_NEED_DICT, + Z_ERRNO: binding.Z_ERRNO, + Z_STREAM_ERROR: binding.Z_STREAM_ERROR, + Z_DATA_ERROR: binding.Z_DATA_ERROR, + Z_MEM_ERROR: binding.Z_MEM_ERROR, + Z_BUF_ERROR: binding.Z_BUF_ERROR, + Z_VERSION_ERROR: binding.Z_VERSION_ERROR +}; + +Object.keys(exports.codes).forEach(function(k) { + exports.codes[exports.codes[k]] = k; +}); + +exports.Deflate = Deflate; +exports.Inflate = Inflate; +exports.Gzip = Gzip; +exports.Gunzip = Gunzip; +exports.DeflateRaw = DeflateRaw; +exports.InflateRaw = InflateRaw; +exports.Unzip = Unzip; + +exports.createDeflate = function(o) { + return new Deflate(o); +}; + +exports.createInflate = function(o) { + return new Inflate(o); +}; + +exports.createDeflateRaw = function(o) { + return new DeflateRaw(o); +}; + +exports.createInflateRaw = function(o) { + return new InflateRaw(o); +}; + +exports.createGzip = function(o) { + return new Gzip(o); +}; + +exports.createGunzip = function(o) { + return new Gunzip(o); +}; + +exports.createUnzip = function(o) { + return new Unzip(o); +}; + + +// Convenience methods. +// compress/decompress a string or buffer in one step. +exports.deflate = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new Deflate(opts), buffer, callback); +}; + +exports.deflateSync = function(buffer, opts) { + return zlibBufferSync(new Deflate(opts), buffer); +}; + +exports.gzip = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new Gzip(opts), buffer, callback); +}; + +exports.gzipSync = function(buffer, opts) { + return zlibBufferSync(new Gzip(opts), buffer); +}; + +exports.deflateRaw = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new DeflateRaw(opts), buffer, callback); +}; + +exports.deflateRawSync = function(buffer, opts) { + return zlibBufferSync(new DeflateRaw(opts), buffer); +}; + +exports.unzip = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new Unzip(opts), buffer, callback); +}; + +exports.unzipSync = function(buffer, opts) { + return zlibBufferSync(new Unzip(opts), buffer); +}; + +exports.inflate = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new Inflate(opts), buffer, callback); +}; + +exports.inflateSync = function(buffer, opts) { + return zlibBufferSync(new Inflate(opts), buffer); +}; + +exports.gunzip = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new Gunzip(opts), buffer, callback); +}; + +exports.gunzipSync = function(buffer, opts) { + return zlibBufferSync(new Gunzip(opts), buffer); +}; + +exports.inflateRaw = function(buffer, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + return zlibBuffer(new InflateRaw(opts), buffer, callback); +}; + +exports.inflateRawSync = function(buffer, opts) { + return zlibBufferSync(new InflateRaw(opts), buffer); +}; + +function zlibBuffer(engine, buffer, callback) { + var buffers = []; + var nread = 0; + + engine.on('error', onError); + engine.on('end', onEnd); + + engine.end(buffer); + flow(); + + function flow() { + var chunk; + while (null !== (chunk = engine.read())) { + buffers.push(chunk); + nread += chunk.length; + } + engine.once('readable', flow); + } + + function onError(err) { + engine.removeListener('end', onEnd); + engine.removeListener('readable', flow); + callback(err); + } + + function onEnd() { + var buf = Buffer.concat(buffers, nread); + buffers = []; + callback(null, buf); + engine.close(); + } +} + +function zlibBufferSync(engine, buffer) { + if (typeof buffer === 'string') + buffer = new Buffer(buffer); + if (!Buffer.isBuffer(buffer)) + throw new TypeError('Not a string or buffer'); + + var flushFlag = binding.Z_FINISH; + + return engine._processChunk(buffer, flushFlag); +} + +// generic zlib +// minimal 2-byte header +function Deflate(opts) { + if (!(this instanceof Deflate)) return new Deflate(opts); + Zlib.call(this, opts, binding.DEFLATE); +} + +function Inflate(opts) { + if (!(this instanceof Inflate)) return new Inflate(opts); + Zlib.call(this, opts, binding.INFLATE); +} + + + +// gzip - bigger header, same deflate compression +function Gzip(opts) { + if (!(this instanceof Gzip)) return new Gzip(opts); + Zlib.call(this, opts, binding.GZIP); +} + +function Gunzip(opts) { + if (!(this instanceof Gunzip)) return new Gunzip(opts); + Zlib.call(this, opts, binding.GUNZIP); +} + + + +// raw - no header +function DeflateRaw(opts) { + if (!(this instanceof DeflateRaw)) return new DeflateRaw(opts); + Zlib.call(this, opts, binding.DEFLATERAW); +} + +function InflateRaw(opts) { + if (!(this instanceof InflateRaw)) return new InflateRaw(opts); + Zlib.call(this, opts, binding.INFLATERAW); +} + + +// auto-detect header. +function Unzip(opts) { + if (!(this instanceof Unzip)) return new Unzip(opts); + Zlib.call(this, opts, binding.UNZIP); +} + + +// the Zlib class they all inherit from +// This thing manages the queue of requests, and returns +// true or false if there is anything in the queue when +// you call the .write() method. + +function Zlib(opts, mode) { + this._opts = opts = opts || {}; + this._chunkSize = opts.chunkSize || exports.Z_DEFAULT_CHUNK; + + Transform.call(this, opts); + + if (opts.flush) { + if (opts.flush !== binding.Z_NO_FLUSH && + opts.flush !== binding.Z_PARTIAL_FLUSH && + opts.flush !== binding.Z_SYNC_FLUSH && + opts.flush !== binding.Z_FULL_FLUSH && + opts.flush !== binding.Z_FINISH && + opts.flush !== binding.Z_BLOCK) { + throw new Error('Invalid flush flag: ' + opts.flush); + } + } + this._flushFlag = opts.flush || binding.Z_NO_FLUSH; + + if (opts.chunkSize) { + if (opts.chunkSize < exports.Z_MIN_CHUNK || + opts.chunkSize > exports.Z_MAX_CHUNK) { + throw new Error('Invalid chunk size: ' + opts.chunkSize); + } + } + + if (opts.windowBits) { + if (opts.windowBits < exports.Z_MIN_WINDOWBITS || + opts.windowBits > exports.Z_MAX_WINDOWBITS) { + throw new Error('Invalid windowBits: ' + opts.windowBits); + } + } + + if (opts.level) { + if (opts.level < exports.Z_MIN_LEVEL || + opts.level > exports.Z_MAX_LEVEL) { + throw new Error('Invalid compression level: ' + opts.level); + } + } + + if (opts.memLevel) { + if (opts.memLevel < exports.Z_MIN_MEMLEVEL || + opts.memLevel > exports.Z_MAX_MEMLEVEL) { + throw new Error('Invalid memLevel: ' + opts.memLevel); + } + } + + if (opts.strategy) { + if (opts.strategy != exports.Z_FILTERED && + opts.strategy != exports.Z_HUFFMAN_ONLY && + opts.strategy != exports.Z_RLE && + opts.strategy != exports.Z_FIXED && + opts.strategy != exports.Z_DEFAULT_STRATEGY) { + throw new Error('Invalid strategy: ' + opts.strategy); + } + } + + if (opts.dictionary) { + if (!Buffer.isBuffer(opts.dictionary)) { + throw new Error('Invalid dictionary: it should be a Buffer instance'); + } + } + + this._binding = new binding.Zlib(mode); + + var self = this; + this._hadError = false; + this._binding.onerror = function(message, errno) { + // there is no way to cleanly recover. + // continuing only obscures problems. + self._binding = null; + self._hadError = true; + + var error = new Error(message); + error.errno = errno; + error.code = exports.codes[errno]; + self.emit('error', error); + }; + + var level = exports.Z_DEFAULT_COMPRESSION; + if (typeof opts.level === 'number') level = opts.level; + + var strategy = exports.Z_DEFAULT_STRATEGY; + if (typeof opts.strategy === 'number') strategy = opts.strategy; + + this._binding.init(opts.windowBits || exports.Z_DEFAULT_WINDOWBITS, + level, + opts.memLevel || exports.Z_DEFAULT_MEMLEVEL, + strategy, + opts.dictionary); + + this._buffer = new Buffer(this._chunkSize); + this._offset = 0; + this._closed = false; + this._level = level; + this._strategy = strategy; + + this.once('end', this.close); +} + +util.inherits(Zlib, Transform); + +Zlib.prototype.params = function(level, strategy, callback) { + if (level < exports.Z_MIN_LEVEL || + level > exports.Z_MAX_LEVEL) { + throw new RangeError('Invalid compression level: ' + level); + } + if (strategy != exports.Z_FILTERED && + strategy != exports.Z_HUFFMAN_ONLY && + strategy != exports.Z_RLE && + strategy != exports.Z_FIXED && + strategy != exports.Z_DEFAULT_STRATEGY) { + throw new TypeError('Invalid strategy: ' + strategy); + } + + if (this._level !== level || this._strategy !== strategy) { + var self = this; + this.flush(binding.Z_SYNC_FLUSH, function() { + self._binding.params(level, strategy); + if (!self._hadError) { + self._level = level; + self._strategy = strategy; + if (callback) callback(); + } + }); + } else { + process.nextTick(callback); + } +}; + +Zlib.prototype.reset = function() { + return this._binding.reset(); +}; + +// This is the _flush function called by the transform class, +// internally, when the last chunk has been written. +Zlib.prototype._flush = function(callback) { + this._transform(new Buffer(0), '', callback); +}; + +Zlib.prototype.flush = function(kind, callback) { + var ws = this._writableState; + + if (typeof kind === 'function' || (kind === void 0 && !callback)) { + callback = kind; + kind = binding.Z_FULL_FLUSH; + } + + if (ws.ended) { + if (callback) + process.nextTick(callback); + } else if (ws.ending) { + if (callback) + this.once('end', callback); + } else if (ws.needDrain) { + var self = this; + this.once('drain', function() { + self.flush(callback); + }); + } else { + this._flushFlag = kind; + this.write(new Buffer(0), '', callback); + } +}; + +Zlib.prototype.close = function(callback) { + if (callback) + process.nextTick(callback); + + if (this._closed) + return; + + this._closed = true; + + this._binding.close(); + + var self = this; + process.nextTick(function() { + self.emit('close'); + }); +}; + +Zlib.prototype._transform = function(chunk, encoding, cb) { + var flushFlag; + var ws = this._writableState; + var ending = ws.ending || ws.ended; + var last = ending && (!chunk || ws.length === chunk.length); + + if (!chunk === null && !Buffer.isBuffer(chunk)) + return cb(new Error('invalid input')); + + // If it's the last chunk, or a final flush, we use the Z_FINISH flush flag. + // If it's explicitly flushing at some other time, then we use + // Z_FULL_FLUSH. Otherwise, use Z_NO_FLUSH for maximum compression + // goodness. + if (last) + flushFlag = binding.Z_FINISH; + else { + flushFlag = this._flushFlag; + // once we've flushed the last of the queue, stop flushing and + // go back to the normal behavior. + if (chunk.length >= ws.length) { + this._flushFlag = this._opts.flush || binding.Z_NO_FLUSH; + } + } + + var self = this; + this._processChunk(chunk, flushFlag, cb); +}; + +Zlib.prototype._processChunk = function(chunk, flushFlag, cb) { + var availInBefore = chunk && chunk.length; + var availOutBefore = this._chunkSize - this._offset; + var inOff = 0; + + var self = this; + + var async = typeof cb === 'function'; + + if (!async) { + var buffers = []; + var nread = 0; + + var error; + this.on('error', function(er) { + error = er; + }); + + do { + var res = this._binding.writeSync(flushFlag, + chunk, // in + inOff, // in_off + availInBefore, // in_len + this._buffer, // out + this._offset, //out_off + availOutBefore); // out_len + } while (!this._hadError && callback(res[0], res[1])); + + if (this._hadError) { + throw error; + } + + var buf = Buffer.concat(buffers, nread); + this.close(); + + return buf; + } + + var req = this._binding.write(flushFlag, + chunk, // in + inOff, // in_off + availInBefore, // in_len + this._buffer, // out + this._offset, //out_off + availOutBefore); // out_len + + req.buffer = chunk; + req.callback = callback; + + function callback(availInAfter, availOutAfter) { + if (self._hadError) + return; + + var have = availOutBefore - availOutAfter; + assert(have >= 0, 'have should not go down'); + + if (have > 0) { + var out = self._buffer.slice(self._offset, self._offset + have); + self._offset += have; + // serve some output to the consumer. + if (async) { + self.push(out); + } else { + buffers.push(out); + nread += out.length; + } + } + + // exhausted the output buffer, or used all the input create a new one. + if (availOutAfter === 0 || self._offset >= self._chunkSize) { + availOutBefore = self._chunkSize; + self._offset = 0; + self._buffer = new Buffer(self._chunkSize); + } + + if (availOutAfter === 0) { + // Not actually done. Need to reprocess. + // Also, update the availInBefore to the availInAfter value, + // so that if we have to hit it a third (fourth, etc.) time, + // it'll have the correct byte counts. + inOff += (availInBefore - availInAfter); + availInBefore = availInAfter; + + if (!async) + return true; + + var newReq = self._binding.write(flushFlag, + chunk, + inOff, + availInBefore, + self._buffer, + self._offset, + self._chunkSize); + newReq.callback = callback; // this same function + newReq.buffer = chunk; + return; + } + + if (!async) + return false; + + // finished with the chunk. + cb(); + } +}; + +util.inherits(Deflate, Zlib); +util.inherits(Inflate, Zlib); +util.inherits(Gzip, Zlib); +util.inherits(Gunzip, Zlib); +util.inherits(DeflateRaw, Zlib); +util.inherits(InflateRaw, Zlib); +util.inherits(Unzip, Zlib); diff --git a/node_modules/browserify-zlib/test/fixtures/elipses.txt b/node_modules/browserify-zlib/test/fixtures/elipses.txt new file mode 100644 index 0000000..6105600 --- /dev/null +++ b/node_modules/browserify-zlib/test/fixtures/elipses.txt @@ -0,0 +1 @@ +………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………… \ No newline at end of file diff --git a/node_modules/browserify-zlib/test/fixtures/empty.txt b/node_modules/browserify-zlib/test/fixtures/empty.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/node_modules/browserify-zlib/test/fixtures/empty.txt @@ -0,0 +1 @@ + diff --git a/node_modules/browserify-zlib/test/fixtures/person.jpg b/node_modules/browserify-zlib/test/fixtures/person.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4f71881c5584d824d5993245c839fff1c9636544 GIT binary patch literal 57928 zcmbTc1yo!?wl;bicXxO9;O_1kJV@j25G+`5r*Q}t90CLlgoNPk1P>nE3C`=x+&44- zUF+WW)?eLS=R3Q0_1U${zS`X{KVNb0Q}72-Gm10Vwk05B#E>(4-_ML*)ro z`iuXaZsq~#Hvzy5yP_r))xYKczYw;Sn}-(wfHa}nudKnIR!|%P#ZJCnZhz%xP>g5k z_!q;#{ly+o1EHAcFSh+BX8VWEKe6OrZ0+n~4b}N;vzxWE^r_;R(4R#1;uC{y4o^OED8WfXtw`>E&l_1 zf&HL%0)ULGo4<#>t(_MYlNB=+w~&w^l_J>J3GC&?u4!TAXyIW^CFAPsX5r!w0RL?B z-&z39U*A$eoy^ZI#Lv&p!vS^wztaC&_%E&h9sKRve`;K6{iDx71f&0!{k!hJWv;~l zAb1V+P4d5Gme~N%8VLYIOaGS9eEcAw{2ecLUS4j(oSeSCz8v;oD~`Vo z{a5<`RQQ+X{|x@)c^rSA_b=a3$%1Vxyq&zL{yNpl)ydV{gUZv*!U{~q{@(}j|8>Rx zFzY|;VABTMfIYx2&`0S*N145gEwsB`tnIz*U0tZ`UH+#Y{=cmDA2$4j{~Xs)fLripniN1wK>zADRb+kO@60ox-23Oahhk{?Kl1-0gGqwk!g$)- zQvDUnXzNm0d3*T$#n3tNH-iUI089W6AOfVPIj6F;N0PY;o{+P;40u+;CkU^;5OjS;GW^p;mP1x z;f3Lq;9tYr!u!HU!9(Cb!Z*YB!Oy|(z~3MsAP^uhA_yQTA{Zh#AiPD0N61I0NBD*? zg|LNijfjXyjL3>8hNyvPf#`)8g_w<4gV>EYjktq&i-d|qiNu2>k7R`8f)s`XL8?Of ziZqS1hxCAqg-nkujI4odjqHz{gj|Z;fjoh{gZzMkjlzf`hN6q&fbtF{3#AUF4`l`A z5)~Dd22}`E3)LPq6g3O=6Y3!92I?Ie4jK!Z44Mg=H(DZEIodb0MYKzFbaV!ENpvH0 zFZ4w8O7tJ-Yv{KaxELH5N*LA{AsD$BEf~`nCz!~X^q5kZW|#q(5X>gb3CtrbWGn_O z87vE|V60rMcB}=gYiwL>Zfp%~XY6?FD(oTb-#Cak3^;N));JM3B{)BDws2u_X>nz6 zt#HF}OL6;fckmGK81aj9f?zjTZvam;7C|Vv`BnO z3P}1$j!5xHMM$kkV@VrHm&jnqSje==-jbD&jgnoHQ;;i=yOC#;{~$l2AfS+>aG*%1 z_)4))iAyO?X-}C>*-d#sg-<0#k4!H}Z%3a=KS2M7fsw(0;XOku!*50+MkU4o#%jhD zCUhnVCU>S{rdehLWJ6Eqezv=Z&5~3uxP31mKcqgg;>IKa*(Q#I+5m*_KMWO^alQo!JDc#j}{sh#TM6=N|t$+XI3&+nO29^ zlGf?g`(QC}DtOOE%qG?5x2>3Mn(e-wgdN20$X>=i$NtdoXG>Am42 z?vv|t>#OhEcDq_8$nV*MZut8%ix|6+K`Bl zolu3)igzgQ9N&$FafPLZU4oC#YRjg}PR@SJvCEmumCmitBg>1)`;%{-KV2YMP*+G^ z7*}}z!T!U~B88%sVuoT!2||fa$!@8B=|GuaS>;EPk8vNL%3aETRcKfARti*BR*_XD zRl`(!SMS%D)J)dO*0$BL*A>+h)W>}SK6!sSXn4~w->A~q(8t5Jr8|)ks9%>&J9Bv)qA88ro8*Lur8*3itA8(lu zm}r|6n(UYoo%%X0G5vi;cBX$;X?A2zeQs)AZ~o_k$-=Ln)<1tQIxU_r`7Avwhpxb{ z#I9nkLe|LEir1Of>woe8>e`Uq7~Ry_T;8(UI^6c$e%y)JMc;+&QSMd#=K0;ZFTX!| zV0^H1=yv#U6m^V!oOi->^7&NqboA`?+0MDg`O8K8CGlnX74KEgwdVEOjq}aJpV(XC z+lo8EyMcRy`@IL>N5sdhC+4S)XO-ub7w4Ckmt*BTO*>aFS5G@vH>y`0T!5gok{ays zUt$1YL3i)JoC5U!UjLTC{ev_BCS)*BS^>b2!4Lxo7FK@=(qD*TFVnB7b5)=a&!OVIe&RPptSxE3jpBTKgkV@ zBmjLwAj)qQzg++vifq{YdH^acg{)Za&KQCzib@}gA|9SuN z4Zuc%a!R4 z?0=R*1+Z}N2>&R=0$@O}urP2i2#B!I48{`#1B(p@z*FOJOKBnCTF|(^!{bRQLd0*7 zrv0uxwegC;@{G=Gv+3hQ^cVtFcbKl&~wT({{55mq*G2#C$8>KI-+xQ8|$25KcdJhTmPNU*TZ(Dq=% z!u_=vUJGh5g8RD^o}z{`yzf&Rw9@$6mLBJ?=y+wq2vT+Ei>(@a5Iv{)Hf6&JbPQx?$ra%Jh8MHw&0P0d_IR~?KZYkX!_WQY=(wqIpUAt&f%MgDRi{yK3S$hN32 z8Ycbz48qOtyjxISK_sCq7~w}$JKEeHHxIuPuPRJmPXEdM=~UuAoufQ93!~lpUJ^bkoX?ab2D2u0(v0=j zM&BAoy>z=9rk%ImbQ@I@>Xm<_!LUEaxEkq~K|;C4SwRM&@6Pzmd!h@(Pp~GMz+;;B`!S{xUyPI&+j|D~H@U63eMH_Dcb&IvaZ}it4 zwHMO+F;(`20_sK^vdGRT33nY87`=(q`nAvc2HjYw$rbA*n8QNIA1KS{%9wSYGnm%d z3-y0``u{naDR0qU8R@Kc`!W1%*@}ZzTfRDISvL^xAOuQ%zwqpsz;>H@ne( z33o4-n^IoZhAp};-%grM!c0pW7F#zvDk@5M?=N_^a+Lep%>FVc;AFVhlxNhrj)dPf zB}cfb$#W%8X7j0jdE`8oAx!E7`Q)7=d~<0^52GFq){w_3ErKR!b3%KlWq=LT2ona5 z%o*GZQ}9ZZ^Nl`F(R;@dFcrEVTi<6I+ll(@L3_z>N0&Rq-!gcnMy74P(%|B~H>yBH ziUO~1BV;Y-GDmBZ^=S6yQXrFIitVu(`*V`PWUcFUeO1*MZ?Yr|-zd_C9!Ib3mL&bP z-=l;rM1>l^BO#64Yhce zXx-t?5+Iu#waLe4lz(8bc_6Y|%^__qC)g-bv>W?9Vksgx@BCaxmfG5d@nKC_rkY)x zGwx_x^?QuYT2c8ZLyqFuegb}%Tte2xay=pA=2O}LbA)2XpmsS)Ttl;P{P$7Cogz)+ z=)^oFYL->RDDVMoA2#)q>!o4ApK*!HRBbu2-2~nsy896`+zP3Mdw{+EtLLgZ&c!j>lHjhGOk0-XI%Sfad(Ly8G-wt8|l&7+$Jinhn^@O_B zBg!G_c5qyHj^+_L2HundSOUm}bS@W{4%tTjF+EB(GBIpCD=w;EM9Q&}e0ewG=Qv!_k{mANuIGkcr6A(TNy zZ!krMY1nY#y7zvL#&y~k3!=G}wic+OWk!b*yY0mND>I<`*6MPH-_%Iw#04*@&;3&; z&gmP9w~tMaOQ`Pkjym+iGV%~lnpfxL81E3R1}LZoC9kE7p0%Hy4{!8I;$Yd_jTH!T zSygGhnt`k-F)pTbmluG5u5rVw@G@yVTW(~?I#p3k<-Rj3ZLQSGQ4w9|!hGT$oZkA! z$diqrdTjOeD?lP0{e010WiWs+_c|y5`6?pk z(Jp|=`R;V%Hi6#NIYF9^9a@7gNr|n;Tc#1E!nKi9Y9v`cVSbsWUt~MEYH64LWLdTU zZQ)N)*Yg7B($KH3=*#Y%X~P~G7++v}R_IDXXKO*)m>Y?%rFA;{)`fXYKV&boTyE|& z)jBjVjN|WR%*2%p(&x-a#Z8iKa#V~cGceD3Jq=5|iApKc1+=yNIO={SGcB(v3y7VK zR67ZEuAqfmaa?#2V(z>EJc{@Up94(Kb{<4WS?tXzXwe*d$*;C1plj%Ky3_}UOfCDH zg+C3!kJygR?mWF`tqj{mrv8#qDpdDNL#YC^-2yyHbp*XfD2&J^1$yDh$dmpsDDRhSJbRzGU2?U4&^uG z%hQMK99y{s>D$xlkuu@^#MTttX$wsV9TiQw%wd|D_^OJgqV*e?-YKjj`yEWAb z4C``sX2BQZmF3GOuS-#5PbOH52-Yp#p82_bvs?*`8!0}o#SA)Ao5AHvl|U6|f3 z{OUC)B5|vAWyi8Xt(~ zx2cm6&V@&BEju+SEA=Ap_K+o0LKqDB$T6^8@lr^0J*JhUf5g@=o-R|T&;B5$)RaE3 zl(^F&$zUGiOC?$eI^BKPQJ32r+((c<_Wx0Ret>c8Q?0b)b= z+>&YtDP(3TUuFa^mWHZL$@mV%uuzxbIEtTuP(m zo2$Q9RUDFwaU^Zf_gPCd$E$OJOkx|<&+ANa7B%sVT|TCR~yie^y4Y9=HdTPiXEVTB>%Vq@MM4ZHFk znwj*O^HOaFID%k`VV^1a$1rhBGM9Tn8zh5lLhx30>t!QOd-anT0lmlcMR!cJFj_^2?N>QT!J@VdnkQC$zV?Co(%o?KX%fczm^!X0gp zj)9tk6cPEmSvq#}Zo1&&Rl@Yx8Cb@mVDllEJIrxKjnlQBqkeJ9Ms^L353TMuh6Z=- z*2O`(Gqhh`W-%RW4hbCI#87oKM$#o|e9fSXPCfx)-(XU5MhN_|zj3nS@~-lOtp(8$lKjSxmK0x$~i%h8QehugQ@8 zkryn&;(EQ4qLcFlMVr`1wB?%crZEvM>Pa$$&+cS|o%aycksxu}T>6HpW!hXg+j{p~ zAoX@Rk7H9%-Vk8gdCxb-@?>G#grTY%JY-Y24irM`lc zkE2?*+Pm_kh->+X!HY?00!WQJ7C(A*zU+Iy0Bq~__YnjaCT9DdNj1Zo>BZBrR}3E( zj^9K{`he5WLchk(Ji8y*=9*rTm4*cMJ9l7e%ex^y5}0j?{lNEOInr~iu#lN)|0Y*W zIa}Ofh{faCWClRG2_-a+RjyVzJS3EE7rWr+5mf6;1^uWqkhx5n&8((!B65Y%t4)>FTilur4vST_kG!A zZ-2(?;0jpKTIBP>1LaN+{UNAW0lEmy30!J_taMp`_;SK8e<~0mj*a7Mv1IwJWvDmj zR}!giqLcgR|Bi-1>R@Zci|=EtqpcP3yi*GMN{Wj`irE>jvKSXVe8DP-#{9FkY4I6Bdim51)P;9K#L-~r0$XdE{3XFXLmjY8uXWrFDEGjGxs3T&1ZmK&^?i%Fhty z&U{z?>?*aY0}m;N#@I=*_}CfQ=w7Y>y%KwjmEZ-uQM5}K>3b10EC!Jf++e$l^7Ptf za!#qKYmuSrFSaj$+V!3G1{jPznY8*y);1+!d;Dl9h&{b4&BiO+({^V6I$-du2vcC0;d=j?gLT$@}9{#>NrPYM_PIUHk(To+}i$l~# zkd|YkBu3pF6h4$NUo}qL4SKu)C8BXd;VF(4Q{QV9s$FGFpYxiOU5VH%ndrOI{|KWv zEXfKu3}~iqQc5egVttlI#BLCMcbGDaoP1*GvOHHIL3?_T&S(^jAzb)}=DO~6aPb<2 z)>2lZt(o*E-;0o3Z{P($6ZSqrCl_gMrJAds8o&y&C^pv&d6`eY+mdP^amg)zJuOmL z)o3C^E02>h+lYYvtwT{LP$9MMjZF+04ejiV_^)qQwer3x#YzeS?`LdMOZ%fcv126d ziYgx{M>6_>xPv*lLc`w|Jv6O;B^_<|U&NYmR6NcD3cFHE!-(7Q-zP1{e4SV{`6_r% zFhyA8k8^YI^ME8UUhTO0K6O8;&MGeSs#gc6p_MapX~aF1&HLGrDKjHD@DLQZzFl4U zq?eSO-zB#tIn%qM7cxkR3T_Y~wZ=GNy$sl=f9$^m8O54Z6hUW?M>dycPuyvwu~|4) zMLrGg*nXEfTxR*R>2ISN$o+g-xeQ}He5b}441u{?f_@j;JLIjb`>a(VBl{G)Ze|mE z;iO%P1b6hXpWj`1h+$cnwu_rNFd1)KZ_ljoM_a)8iMk^%039r6e&Ou6E!4lAJI2Dtt&AnK?rF(c7OJXKR6F^uWfiwC&xNiJ(k|s zKSp(%U6zr#aZ7JfBYSNz$2Z-4%DC@C#&I3dKKJ?Igqf}pk!D(;ykwNPIK|pbSC34u z+Y!z}rf!H7L5XnpeKI(~>BE=LGe;j0=Q!21GFW!&A~Ja%mE<;KqJd-G77FIOjlFtK z$7j0+67Xz-^G5;&Hr0Iv>ttT-{OxV=>DE6^ojij*?=G!jaW4^bt{lf)?oXBs!L4oS zqUz`AmN1dk%#2B@f<@o4DR!`nl>9E?BLli0F>iL_l%itl_Pfj2ek^w#WT&W=Q=a;h zxE+Yk1-h$=LoN)q2Qscn7n{FS(dVXLeSR$tACrMdO&ewDFz3Rwew0h9h-uz3?e(C7 z|EcL6yR)ViO*EX=6@c?ZS zxu;WsG1|z*{fthBdquVpE1za0vE4L@fn|slXNnyt<*t65gfpW?`$6BHU`Yv1v_$&K z2mU>kutCfqJ@s_AuxNPY`ggFaKh2oicdQX&*~(`d5e`&+<9kO1iSsAd7l2mhenUUk zWXhoS>C+2P06l!05Y)Jie)XJ!Z<0eOLX>mW7Ku&|Ys6@Fjgb?lf2!%5wdRxL8`gk( z0rE2EKOZZ3F*}`T?`^j2p0}k0Fw7xVh=AML`DM~ZI^Q|NFXYrxw?PDp!0AoH-?7|d z5|2DcLRFEF#;zJeCRCny_LMG+UYoKHw!YUkv^zNI{1~28IdBAlX%~h0088Yd62gA8 zaleyT=5}66aJkILV1q$Y^zK7( zD!0e@@yXq0EU+N6e6YYiLpqnp`2;SZ&mY;g<(D|i#pZYMiNzk!COXe9G+r@z=^-i= zj6tpRl%rW#f<%3^s!unKO`HwOQetFxrpv+PpvOt+XI2DOA zt>&c6KE0@dresGoMp=yHtgiQos0`g}K{inD-n~rGb*OSj`H84V-d}0DHtj}lhYBM% zCA5@^gK2)8NLR-#*bkAnKoO~@(h`81E+1g{o^3}nc9d)~M&tHt2oBp5BJ<2b$ zqKQ%yzgRwKZ3(a@iR`6Et92&wM;%1LTDKI4+cb|9r+bjF#QvLX{;6$ z_$hc-PcBjutCWicOmCcu)5+BB`ef2m@F`hVYSZx?Q%+|hm(Mz z5-&gH&KPklPWdwYc-6wZhi=MyR&C8;Vq7Iptyvtt5l?{B{J=VLw5uwfGS?!SDm+7% zG3-`7C&A%t**Zz_OIV40G)f8k^(&T&&8lxMn8zWFeazcNC4Ck0=iG)?_z7RaHCZpe zWlnw7yF_THzYAcDqG@IBO!K%UN{B`biR<&If*frSncWmF@t3+(^170Yu2T$4f+QvdBz%F-h)wnd+pRMk!6k6w;Pi=TiyJkxD z8!*(b;IJPn+n!32g#hQX7*bK=i_0th^1CK58%e;D{meQfPTlID#!l%L*|quEF^#@P zyh+?_5~&FKKfkjp+7}?lU7BEPC|IY>jAx%9LcbKr3jbK3#n2nG@4QITl)qJYL1MfW7lYO7H!4{>u&)GFYzdLj+W=JT~C^M3?Ni{X6YbY+3 zpkooI3Uyw~4$ey>A8WDNK5tJtq1?$#bef=pxfWtT>mKpBuNecH67?g9B2G#4BrQQ` zt6#~gsgm^D7j&047jZ9QcjfR|EAe+U8lJO8lwW{!9@&$1Jb`rZG}Xng zVOIvvh1aTTpucC|!R?MlF--=qIF3Lp@)ROscPHfsSKrEA9OcM;zPaxTJMhu(Htc9l zwGuW_opx8Wq<)^Y2vRb*@pr#XI~o=QNKsgO0I6p)f7@Z<{t}O8hq*U1N4*hBcIGoY zF%BW#ET6dDf`zDIeRQy*XSOc*3;lQ1NOkA@jrMg02F#*ly;F%5U#ALYbyr+5Fk2_3 zu?~!EBrL#vT4|-o;A+}FUl(1rhkSLJJ^uV!q<{Vq1vxFOz-qs0S5^+;`w(*@ zzx0lH2idag0a69!$Jsh{zPF|8vfCkHLP6EjUrx`$FZLnNr(^XC+p#SKQ&~IH))1!U zo7IZPsQywNr-5O)qwUR@+8Hra?JnVc<2}n!Aih}u#j%+i(HdLsigSA*o5Sgv+KRlp zo}zfe@Es_EK@cP;)h_9!Q;nKN$-m64PhcxP5n2b4kbt?dKr}<;` zU3eYeg|NNb(tsZ^Q6=H4r_@sKqD1-4V6y%p*>yKhT3Vt7fB(Hqvl+?9oz`eo@p_En z!Y&7<&21cw_e&!stkE32eTwhrwno=X#Q2O~L8Coe&|%x?GhgDnOUXGzi9cUUeQqJD zcfM4cocy(dO~>?-F~ur}F?W=JOM{e~A}<9e82jcYZcjJi;_X+?_uM>|Nm|`kA?tjD zh+!e)QU~{Zy9qlLSIdK(aIPLUcCk$t)GX8Z>|easH%EBCMQb??3~i=Su1JjVAoAO$ zf<(5nUP-VyvhoQ8qo23Yux*7y zUS=)@v3>L&xu)yQkUK)lm%{PQE;2n%{2LB5zA|}q!Y0vts2k?5K>UI4AYYT~!rbt! z)&SoGgC(hH){G82=UnG3W!3-`Cpey#%dT!{Dr?@A!txEI4|t1j%l$^@AgI z3q{3ylfk)jFUpfb`e#Va!x+~ps0jsqD1Mq>r}9Qn10u;M;~} zIYX_8^KiF1vr2ipFI^DtG9E|9#P4PABMRjpI%^fG_W@ayJE5LR+wVwmL=sCFzGvAP zUH9jIRC9DG729^8khIr>Jv#1=Im}QekaEmwe5dmM1wgz99>v?~LYf#EjIG8{KRR66 zKUXA38QKpP6z4CT4iC1Rv#8Zcc2o zDt0G=S$fv2gD9Ntnk*or^P$vj#pLXzCga}%0qxv1 zsMw``Up|xusTk#N#ZBUJxvE8z34tU7&_<(wFAh@K#40lQfwfcn`^YskrHcAkrTSPi z@vRFKIlO%}5eeVTD~RbSnH9cLWwIpVI<~+)=R&YwmwOsaV!~oZJCkBN~5?rNPAsr+O-)O@@Yx-a;OWm$ttPg znZ{_7)juY#{5W|@QC^SiZCo8AOK4}M;($X7o#VXP!B`{aI?t%AQOAq#F~08^p+R@W ztR_S`0qpQTR54V|bM=~#p%LW8{eZA2)7q~gd-_qkj`;x#+$#qx;o^nHrif%Ggqs?VehncASP=A%<^px+B1 zK$aLhIS@a!(pbAl-@UUASs(5v9bv6_^EqQ%rLur7N1aWp$4zZ6?7}E%EqL4tJbz{~ zP(5=MERj$%T)=%dQo1kfv}6)s!occJ>wEk2O9SIEH+2Bi%2%v%6+%V*a;{e|0AGR7 z>(99tjT4GrE?e?3J`HyGo)(1Yp3C$zu#`eKtXX24;#(EAZe@|n1}8$TslLcBON*Vj zDz0b|gxG_Y;B5u-3&#f`cCIVFt?ho^PZu><#o?MY*Uy@WtB^74kJTEi+(#Tlu+O6# z?BO}u!Q*nxY5q>1`BP=5AgS^gO1yf~%w6I$0vB5h+#xS>drR`w-uFrjt?y1~QNSs* zd`~~|d{RRz;&nE6J3S2xF~x66lH${)?L8G6jF;&-PO>9ZgwL;0xnKlGCOu5UgD3i; z^ZnhP)P?$`sx(N4_bu6}=Sr==L_(M?wRGjA9f<=xY#vPf;wugW|G?T9&}cn}G|up9 zFs~~d40iaGV9upZ8QH2h#&jmIXam{G@T-QTrg{l~8HC zULq5?i637QgSA{-Y1MAVxx6{nLLFRCl>QNxWS%CKU3*jba&z6W{{va0`$h^{5eHLP zD9hFW)lh?0tl7IeXY{tuo%wmF?^86fB*Ah$+}R?n7?VY7Tm^dbXqUjPwOMQ>(XzS!06UkY4`jh) zc}Ue(5F3S+^NEplrp`4>l8F0K{o0*}IRR9bA!eV}WY5>JDWhRf?#mYt-H&hn+I^3U zV!6sOZKTpvV{9j3)gb)*O8!Rz?fQn#3&6VZR5NM)4crEstJOH<#FyKHhVk4~FSuiu z!-exo?>d+uU^;QU`>eY;{!AH;a^TXK)~m>S_s}m#uw=_~UtR&h-DOsOix{cblWpLJ zaPtMQNN&gew2gT6+V6eZUg3nZI=O;QV_Rf?=AYPpNvWL%QGeHO1{-4w;P4F>rezll zRnDR3m`n8N{3k(`M<+=OWnZ`o36@cOusF%p^&f@8k23@9(i>zK(gUpv6!m2TgW#)Q8rNuA9gZiok;c0R4czq zpWnrNJhn=Zo{Lr|d3F366ZRR3j=p z6Z6`Wp^a9HBHem9b9w+8Wo(YiO%UE3|MloDiqq*Xa8kmHBt$c(nqYp4yf;8!9Cd>o ztIasXJmb~P-?ww?qL5j)H^ZK8`sA*N?Vb|HDq#Mu`bK=l#@cfWSG?Zvs!5ctAxQsT zWL5rcclDFW=-d_Utrind9P2#8N&g8wx$aO$j-~v=^9ss}$5QyiAnGF>Xtb8J$q7?q z=cz_7>rTF3hz%|tgd-Bj=rHL%ygkUH#QO!@0@l-0r)x}WuxP6f0Q>x;gDfr5_8Vdm zNNP6xbYZ>Su2n7QzB3E#a;!2sAat_ILWt7m-uh${}W7p}YA1LV--TUvDN?E7N9y<`r1Kz2d}ES9@r2>PbnL zr1N@oYry`@w>lr4vbKN7D&-C%F|UFm>lY1GgWi@Cx*DO(&H+ER zbfCE?gX#gAtLi=N=b$7FLVW>1*$gLD$E47Z$EYFipTzH- zo3~B&WeM_mqqNpdLy)l3QG#Rw7EA#)ctxbh7KG;g8H|sCT=WntP1C#BQP*0~#~uew zfO*sl_M?Wf3(&mDk0l(GF*nq5MZ4Fh7jvUElr+h+IEZ1N0`g+HxHGg$AW?W5{vBI| zTXg6rpd?t}oU)tmucA~ixn}A>aOz5?7-?k9x{|{rapb`s$vk)ZwZUWDN7Kg~^wR=~ z^JO8_p;0Viesg!)euwFED!e5!X`qxAq!eYxC>|KR|N61wgxqo0g8fp70J3`^i*3w1 zdhYJp*opWtdSaPdJ{?t)b4=B0g7Ap- zXmIx?3OB_KU&zj_>t}}9I8tm+uB(#NT1Bi->j+y-KYv;K5`-F5Nhk-*B!YK5=IudIc4{4@%& zQ0xxDT!^h9s-6_hWo^kM!CXw4Q%Jlsxobp&_+t(1H-(Nhz}D#-8eL(<`MlmA2>Ec` zhg_Ie&lXipCeSxOy%WUj_sK~2$ak5RR*KW+(qZuq%)4AGke8!(!PngDbl59^WyM=z zIWpkHU?9s@7Pv0J_Fnq&+rpdIWnR8nL>tKi!_12|ltfPjY|SPGuO;904HZl3A4UB! zny#s{NEAaZwRb))D@u+uu$z~X8pKf9%9tQ{rLSp;jeHl@{Us_0k4JV>H%cC@GnCeS zD45`>W3^^ zrqG5pWbiaPr526UFnO2dX@#*(neEk9UsKwm(rRBKc}Ay&BKiR{vONecZz!@t3!e*T+2T^wh&7`^b`LTi>Ed%D~k9GTB9V@niI>MQf~MZd608^=(2= zrj6MPfI=Y>QXkHcqmy5t&Q@-cwU8geUN8D(_n1`9RMA1L0uiz*YeNkag;Mnb;69a% zJR`z+Z4#P{SkuoLn_sAxTZqNW87bCTgde6QqdB^t2mIKs_!7czX&q5C>NKcG9*%YC zQ+BvQC$$fDh_s@$=uFG0Yk_x_ODcw{{0MO;qgp={erq-&fVr-%c-J?Wm@+W( z3%b$gJVt4cvN;o!Amawn+9*`UkLF{4a-ci(c_+U|EKtxm8xuJZzRyE4V}h2b$xD*xsntE3{IISe<; zwPN6X%l8^>Eg6>B_wnbwRcrB5-9#890m7G0aXqRuThdobRf;~dhgG{o=lS=867IF|TLV~}Esg$zC!mbT_h=(liXNNW%#>J=x( zY7kgGckJ3mGxu$*?o((zw$7YlEv`BUaINH)jn~etqfA4k4ONa^0}^jqPIqR?zP9Bm z&((jIv2!yZI76(p-ytZH1<456J@>6*zn;JqE}NJqqoR$j zQS12PnL_M0^GwLN(Qhh58y)dygg_!I;3)cDS%Z#2b3p(Y_#Hk~;UXI|TA{h(Z>3w} zTY86iQMJ2ZL}7JlUh=kPX^wYJ=Rm=w6f~&IavvIq+82x&m$Woo?va`75>vE0&KKl? zN>{oKvkb3ew9DXh-IVqo{$zkJUwK4prhp5UEwths?g()!tJBA%h=LGuc&Sn5z_To- zD-EUi1|Mxh56MgK`ka=8tPE|qu@6|Nyen72wUH&LV-gy1sE)20>iyr23QI5*91JU% zaeQ1;P&YdOJ(99OkSKpcZXLiB!Q~Sa-h@jwmAqWAqJb6hMahLXIPgwZ(Jf@>oG;Tf z)7@-=twC?n{2{)Hex^^H%3IS~q$HsZ0uD^u9zQq9Ut5nVExz9;Aqe*^F|U34VKj1` zvp+@1vSN@Sgt?5j`2~88W{bD5Pp?X?jzgE{RHl`T>1cPrS(`iJQo+lX;gv2ZgTD$R z%|>YtSrxU{_ugb3s}MZrD_oYa7gt+dEIHp-SObMCBY-!+lv^S!CT~sJHl(a#}C|9kCD5C)9ykalw z#?mXCt=vC*UQCR{H>dbjuvrEsv_ z9s?UsIjG11`#z=8t?V1C*}7;bTh$^`_r=HdnxFOyJS(dMXn8WP`8Rz*eyQl>Fadc3 zizAjsJLIXZ{6-4S6(*}at(f+e5O=(obGV9flJI7HBn!wSyNUeF3ov3%W$3?U_@$%G zIIDKD+C({zHsLjvo?S^2znQr$uxumaI}P#CH*!uF_9?_!UN)|fmBm9Tx!nGsz=jTim{&dk%%a+8YuDdj$h+PU|jH|rEew;jm8i`V^mnfav=#G59s8gI{( zteYl{*xjNCVLIh<)XB|Sl1JxCFdSn(=YK+M=31H-QJpO+kPEYAm(ow@(+Mez^cWnf z(=ultYwlY9&TBy|J{qlzgYoOux-GI{gEy`#z~121k8y|o;eI}ScddsvN5F&0!i`5~ z*7wys9?H_r{qL2-xdfYasM-iD`THbePgQP-F3PzqTyQ`jrb$G&4L6vd!hW7!2PuVC z8?!g&JZL*Fnv`E1PoHgi@MhP*o-%XEN~fK2fMsZCbm~&=T0(%nJ|j(8Sns-PG`YsU zqH~yirLtadW~y?(@xB`ajG^9Wu4QFkp(NJvIn$Lc@|h|7KGu7aIfXji+Rz}~yP+h= z<}`eeMqRmK)Oo3k^?=Fp%Uf$i{-G!4`p24lVGE6^v?7U{mNwTPVLOm14I5}2C3wzT zO@8;}q-W~bt0TZyN6njWSOl|?)}Z)4&O9bcCym`nsO1Nx&d`2=(`8+Lk>TL9a?vdA zIr+H72=g{sr(ZzkxbV(R{awNyDmw?w5cyFt&BL^ayMB(e!Xg77*!&6?qWBG^qBsqE+!JZFz#|%%kHyg%VfTew;6852>}eHHdx%yENry*V zk1#Y1f0^C=^HqC_{kYwDiPyq%m%-MSJ`Vqlzdll@T1q4}Zq$|)n zQqCUX2eeR|=;@*Ap~;pXzt`!obkNQ7AoHz=#{*}I8W*@{+tEuu6>=CQ3;at{@ys<< zBZ*vlA^Rp&HQ}V~IZH}JL~z=bEC+S)NW3%=VD@PJE8hIdW`^-{)$f}@M26{hqaaTGp`jE8Qpy?WcAK`I43dftsTVuyZisc-dD#(xkUXh z9nu2Q4bri6N_TgNu)+dMcL@^G(kV!HcY`1z4Wgu!w1h~bl=^$ndyRX&@B6!dy#L+( zz``@<%$YOa=ggUzXJ^l$W3TQng~L`0ZHk848k<(@qpT%o6l~x3svGAmWh;M^t6DDU zzZn!v-*};<-1nL4t&(TT%MSC0hc*LK^Bs9GzY@Nw4{iqfO?Ow_qI?WO&s&&=k=s3+ zBi?lmS71vW4z@esG$(lxLDVCNLua(__`4F9ttM8D%tUhGdn2P1oe7U*-j98k)*huQzAg%-Zr1ma8p9#)&CEy5xtBJ|T$B!C=i@M`yh@?0@>A89iYnaih zaTwT|A2BUv-b^-sMA>_n^fpGPn{AP|XZ`WVqs*#`cbG$p)k*PF=xOtcFzH(dntCgg zjf>bv7ON6Pc<^!wmG3bX5TCn9doAk6FUlsR$MIw*^KPm+ z7DB8GZo+UvY9om41?3sbT1>9*#ggVHZknKuh07o`K83a`3z&SFT*@lsg_T+)CL`%z zKOiYt!|u7WN*5wUndVxyASSHhA{*@ybwDSM@6-O7M9n^6+T_`F*cRoRey}Kap?N(f%bGjavu`^{VyQ#tltryFy z?F~P`a|dCBnfLm}@Lia1YAhW!;WF{pCMJ1*ul zSqV!F-teR~=aFo%V;OLmaeCVIB8ksWuQe>XiEyVVWq@JfetLfsLU60YhE|(*{E6PQFcC6)bdVd5l$2oz0>1*A=M_37!j|;Ph0&_kXUv`()HZo(Bm*# zcz~@Ti@QICcKo^#OeWmCYQ`p**5S103kWIk)UHqT(0nmN%tgpy($&ai>)EUJ>2!B^ z`cn;Nu~FdZY_M{o_|5sJ2}EZD9DqCY3^$RRsG9J5!Y>yypiOx?$9d@IxfYYNb>DQ7 zrlBToJ~~ljK4FfnC+KYoDsY0d&`Xx_;6}t*$lg2t#;NdX7>NPCC&L%e0c{2k6%C>s z)zMLE99U!s`La7HB!g`@YeAZcs7QDJY|UlJ!V`H9ulcT0|Dx6B_Q{mH_)A`R4T#sL zaT5Df>LxfU^BSrflXth(Y8((9SfdW5ks2#cQ#HfpzDymB)Nf88zC2wE#HFaHcUz3x zzs(m+KS@FAKQ;JjF&KA>VIA=d%=v-ACaz|+uj8=+v+|SThIt#(2S6g z;j2*S;v1H2$yXumG0f4L3euwPw(Fxpi>fG3sgb!m^f~b|Z6Q>rNQbr=5}!O5(ySeI zz55e=llPsPBJ_os{+gJN-X)$}YHtY;J|z>@)hIr!e-Iz1j)c0^*oRJl-Y1AO_bT~u znvP*sAAFIR`gp}|dr#5RX*Ens&7! zAJ*`8M5%!FSj#BTW%RK^sZ=~zO{E>409*N^Sdyg_lZhvSUXDzloYKo{otNBX(Oh*F zTHBQydB8Uh1P91&B`bJvJH|{V%eh>ZNnCOxYusdl8(1kfO>P(kcT~9UH0V!;g>WEI z*83jij>CExr%hH|Nzymys*3h&9@|(nPt)7e2e(VGOiV_3oMH6eER!(;UA~@>-eFq- z89rr3x)pbMleXdhvY@4wRAc)jB1h zOJ3ou^`}q?uBbHM=`+1Et^Ci%XTBBh;TLS0s8#byTgQQoGYwW5hR!K1$|r}Y)Y>Nl zM|NbiS!2Lio9QEMSC*Eu7+dD*Bt7#BBW+3_RK41}J-cva;sk+B-qj}E_<3|4&5sB@ zZoam?g%K-ZeqU$8ZskeX!o<@P0}u}{Ii{@gLkx-BENjF1#-pBd-24gJ`1U|fia2~8 z%hwJ`+~RM#Dr_+E(-OIQU+TTm5$Ru_s%Y>wZ7?>=9&(_IE=nnuQZLSpW!hi0Qof(( zs+-Ge`F@DNEdEStIOWDDYc3YX^FaL_mg;Qs>WW&G8-rX%x9Nv#U0UJOyQt7lvY$P) zB#~+BEsuB>$!PQB{w1{{rPiVDgHl493@~AQ5OE&-O~h01fvtuusm5h_&B=^yWq#me zR_8Gt%91ajlNP*W!5}`; zuTBxYXzthbRw_(s6FBDXt0jHeNCJK4tNYe~Jbn(En~J9Hv70K&5O2moOp#onTZ%#n z63+La5jKD{hk1wSu5RTZ(g0J+3D1X-`WJIT%`Q?Z{1cWfjVIbFj3?{@Y2Y&K(9ih3 z>ABo1c3ee4pUth;_hwNWW1KYou-_$GGpsE|4>J%H)4gSMHYi$qQI!v)Ov^OvoJ^N9 z!+eF!;+qJg^;`uOgmm)nlGfMef((jgXFIC=tVjec4agTVZ_H>txV{y!%dgJ=*|trM zyu99qPQX8`BJ|v0#Sb_fhno^5@TpXNrHmj-VJ{+&71JUOcgiY5-7k?5I24N8gI>+6 z&B=@C5Ra-{q0fphsy#tDnSd1T&7Yk7!j}Op8$^o^j)*08hkRT^HBV=2ze9vmvL!bo zE>Msi(uRS)O5h!-gNtak=6j$$HUTaX%ebf4NTAc!mH}~CAY96SWuw(35tXwxyYW`G z63T>BQxmH#5bGT4PAWilf5$F~?)yj&z3 zJ2;i6ud~6eym(OMW;LNrMy5~*S>FTCSuw!n&-GwWzQ#FTrzJ@^0KSeWJnlDh>P(kZ z)NtO|0U67ks-Rsbi<>fi3hrI=mqNd!syX!=9Ijw5{RDoyV$JhO(!i|1z+hg%S0uiV z$Lu2xI8mc>4)m$uv(|+{GV~q_MX`OKThEEz-iguxT4Y_nxyG{yAx5g>KGU}NvpxN` zdn2;2N6APrB&QY_>(EjE?7Zjs5@8p9mg@nGFp^pvZ_HYHj`CZqZiTIvl`lJ$R6nAA zc#n}FxVA;oMniHcvmbNfd`SgY7nLcix$x!H;nLP#L=}Rqjt0GzdGxZ_ggJ>%l#{l~ z*ts6K+)n;X2lQF@G-Y2v{b6HExEa}OG`3Ho5*|gs8cTnE#L9x26Gwx5PSJ9F?CeWo zsJJltI_x&ZqcWeq`^|XmqB24&r7tJtA#((BM(q$(hElbeO((_nIz!R6oBSAXTb~?R z;3qCqinjR~Y>MLLN{VjUl|``?kaWf$e-e9U^jIHpycbT#gVz3S{s*G5IkfoWwz7CH zs@&Mg>?&mg!(40rbcGEa;3OrANf8p;6Q#p@M|i6WZG0Y;km}}a@VTt(Hp_q)Q{jxN zgi)g;f89jGD36VvP-9l1mlZ72`k}g|MNR4(rWMro{wmNGrXYoKt+&Je+WxjpMZ?>1 zkI*!)x}zc4NuKvoLq$V`X+ALg1MlHcN0nh#9YSy}IBedp{T8H-ag9D#AeVx9M^qA4 z=b&8Cz#k!C-d3+Jh95Q{)hvP&ce*xW`<&~A^lsn%A{L8tv%@zmZ6-sQxb~}7ltCjT z9rL;Ix{QlArG~(chfdrseqY9xDa;RrHgzp*+FoZr;W@6aeaF^?2#l(Dnic-j>Nt7i z*Nupkinz~@Z&eY<47N|r09$#StesqX?4=v{93h}XBsNX&fMA2^gtfYwSntOvWWes7 z%~=AG+fk>L^A_!D0On_bGFMylC)W3XL!nNH6m55li*X|=43oA3nBQMh2Th3b??tq* z4&1_%Ho1s(bhDCY!7QpPaGv-0L%}PxCZ#!e^J{+Goygy2R2-RBW{EmD8(wo~fL? zs5#X>?ZJ_}-WaYW-7q%yDybq>es!NI?r|*H=fO4CC1+J5pV5mxk^DEZ3o#~PyB@=Z zAxdkDOdOA7W)&%Jm7#uO3RtCNFwb6Sa>K4yOh;K3gm6OmP$CW5{T`6*6abmCp4Y zINyAY!B-#k>T-lP9LK4>q#5&zN4aeQ_e z-lxTh;qDtB)XX9@YM#NBR%^_`=iV5D^vwG2aA|9+*%p>t-{?kfH#ws5>?@_3c1?P0&%E<)=N1?YmPIAdpk%OgIBeAE!}rv6 zZpxG+moG!-kDeUzx1oQRm2xZPjZ^y=J6%(422CsND=&o*K4vQfgw8X?nUo-Pz7=RJ zouw@`SM((&%@szZ3tTv^+`;VTxPheOJ z5;KS|?&n3TlXk!25j3~M6L=?y5#fVG%FXG^PMEh19IQIR>`ymVWQQ~8u1-=@f4a+s zu3Z*UNoh$SZFuQuEOQ})`0xuzWJK+f$yU7TPJsS%`?tEiB|~rD_}BAEUDd= zM8kNS?_RPOlvBeRA%o;TZ(4ANJ~=l`VxOV8wB3QZnw~{#B3%dWUO^vQS6m)ST!kuu z#7Kc`esHAT93GB;{AiS7F`XL)5ffi`gYk_!M&ZM_&P|Dj=oKBG`w&=^SdX(fZ{MLW zGZ^3&c8U^Y*1mil{8WWy({BiyZu?v`+`uPEv|*xTP(?$mjJ1}ZM#k%gcxlCRW{j%d zto@KX_}Jj%$032_eAT{r)Q_$Ilw=a@XUURm;D%=xP4uznXfe%I zxI)RWy`=*)=XFV`uWNmLzy4&iH1T7<57$y8Wz#H>cH-t{VD4o;toC&24Rt#CI*JES zyF|V2KGtw?6<3ASV;vrZiKKJaZEk*)v1MzqqA!z2S!ofC)rSF6%(R{7a}UmIIoD=V zwiR9|R5%~^=yh?0m?z07l8irhrQISbtuMj9j?>orR79?a)UC%T+Vunh4FBMRllJ)7 zc;&NLu`+6&QyHz@r^yQ0URp!Wocz;)?!5Va_+}1HpB%I2SZfaV63r6n8=kZcwnfWL zI6Mh|76JquDK5=MB1Iy_K$WIPox`t+2Fu*K9#INB3ic=(kI1cfcCac=+yq)uESg+Q zp|0L906hz0>xqr6p}a60oqg{GWkoGPDa*_9k9(B#`n?23hd#iD*vFzxg5^%{u zxU17NReFbh8(EtfY;3&Oyx5_UPIyfCR6d7Xh|Y>Az~k2p@6ToUaRzZv1Y7v5=q!;W zL-tISlG|!d!UHVz(F+FQbXlnb{ttB?$~`zn+0wU9m~hZ#qN?gsQ|+`o^Bb(BhE;JG zdy5%|6Ave)&Qf3IgcTQ!aywEgg{FIF0o%fqG<|Y)txv~Em(BpbkGB;@l@kn?#|az= zq=(TO8t?MMO?7mY-dfQwjiH_+(1~`BagtPJ4vSH5F%Bw_^XH)qL4tmkY)ISFFiK_j zq+=+Jx}z#zfO00_UBaPEcsZgV?7qoaqi5u%(MFk}%3MZt?M>O7?}1{wb2Vv+7y^mp zT62<7EJBsbd5x0AwlmRG=FK_y?6ow#n=3pF{_5{<>%Mf6VbR76=uJZ5afz7T`Ou}H zw4paY=D$=Rl`K+nUd{6GdN8U|3nAUxg~8Ix*Dvq4>%@rVc_-J*y}TyZ?8ZH@dwer` zM6IrKW`JIF%mOVxH;_CopX~|C?CZ$EXTI$08h{&^`5JEuk^XBWB%D3#TB#IdJw7Fo z#ysXGx#KU(w4VAZ>L4Hrsl5w3hbP35gNvP$10-_G6Nn3H19hdk3$=vV zi_+}1b<$A5%tdMRcvU!69HpREFnMohsFt^?wwbq$nV>n%EirTvPa#h`M?0u1gv!&- z*4{|i!CPB14G7dsc2hm&7` zl}g(UN~HyLq~hYD0&{ZmQ-QgKz+6H+oK%0jXvEN|M4ZhngfyjP|7Z}n5~cYmzN!Z| zyMwbO2M}*okb@J<0S2=H9BeLL_O1|5HhUM^D-qvhNCSa(onek&1Cn0Jgxqy-a}}kb z0q9hJ2zP~9{E+?&Zda7A!2Qe)^@RNc`xWJH>;U%PRsTi!pEu=a*$_7X+CTdF3-fo; z00+mlJd zd@m5n^{O)GFO?ntjC}Tc5#Px_DqbNdqyn*liqc3y>>cdCs{XCe!5nJ)M=6!Gf}Dc3 zgff+azK#}^04FDvg4PdC1v?-fnjXyD)k>5G%*iMC7m6~}-tsGnpZ6z{z9!Vg!Pf2S zz5}&*I61g}R5SP=Xg^3g_AtOuz+bCf!7n5Oyy-%nUA~Is1cNz$COJB|xH&_$VRk@I zxj1+@e{ zNgAl*3iE~n4&eWzmW=1OUP{6sE`O-P$-(_Yc@>D~Uo_sH>I3m9{@9vM^hy77+5-43PMfGE#0X zt`2sZPemI*KcCIEP_zk>0V_g72h;sS0GV99?B zfv=|V6}Ydw|AXbK!#tt3`qF@L0w8`J5PuG%uQI-p4Spv7Ig|h&B?O=Zv+%mIn4gS9 zP@7Xwh*Lm_m+L3fy5g2{h60>_;r^{5e&=>@)^>0J?DpHt@gusT@>N`MX8_f&C<2a8 z2rv*A1$zqsVP3#Ve6EdF2DxnW(QN*{SYK;3vsc!3QP_N zyt-w8kNDF=T(u($bGGw3^fH>pMstzz0 zs3z3h?Q1~GU&vO@4t790W)grq`_`c5|3a7inXU`7v%R71umY5j zzw)dMi};161~mUa zR5gIw+B$grW9_fl{3BJu$qn+4#4Diwk*MzG>}dPXWRF_WO4%fA9Y9 zxc-j9@3{U3#_yQ^iplSI{tC_Sc>a#i@3?*g)c2wLk2w8?a^*18AjmsU&Kct60xZw~ZzKz`b%B0w8!!>5 z6p;S`stSNFN&}>jfkK?WQ>DJ{nbe&fEPyqrD2)uTbT>DLn*W{-EEAzubFnm^geS>ttLf+~O^}zD`&XKT zz2#L8**Mt+1bGCxf0g>@-t5m+sJzRv^}gq9F9F9mgNsXx(`k>!(+1oLnU@^kX>@^ka?NODU_@=0)m zB_#QI_+@#%J{h1A`L=exS_OW65b*61=6u!64+Eh3TC52LR!mn5#IIm|EBm%{__hi8 zRwC$B*gOD)wfGqnAo>q z;UXMYPcMMWuljx`{s&}bp$Nxc z01&w{kM9HSCrq@UPJih(Co2`_ud=@*0*oqFD&Xx`^0%u$1&MI{t*LJeKRqo1TKrZ9 zJcR-tfpL6)2KI+4e>|-Ezxwm-HveBq|3mJ7jr=Qs|AXs4xc(Ia|BCrP>-rC_e}%xm zV*by%{)6jZA@Hx5|Ff?D;QChx{43`Ftm{9x{uKiMiuph5`VX#uhro|hG{C3JqBI`B z85tmtniL2D$VCSH053$~2MHC(;)RHWj)H=Wih+)SaSi?2HB2l#984@+tZUbB2yt+) z;}Z}NU|`=MBE%=c!zaMM5(0;Cm5U7t4G9SiAM+X}{=a^G&7}q;psW8Wm)dh6RV@e( z@hVZ;w-jo?I|`6t3>6*$4Gx6<0=fK)m%Lg}z>9t(C_a6i$<~BS7WRU`uk$!6FDsS#p zPBUZ_fXIsrf&)^rAs{3Dsm|BbVbq9MIoTjiNY`ls;`V_IXI-!GX_pVUB{k^?q<+mX z)+SQWe1~EPlQ+DACvH+R0i{c8Hi2}DBBsW&#|B?d{~e6}UM=IU;jLc90&dxOdrVgt0XS1@1pN&FLB zl@gZAh>OG$n#2%h`J+H3WHj1vQV4}QZQ;FAZfuRjn6OrvN~FS#br{;4!=50_ z!4nQNO;bI_>sFF&Mn#Y$;ZPuR#>yCna2W@>(ZH_Jw2NA5@;&;Fn3dJiQp1Siqk0+T zS{CJDm)IQDYgkV=3bC%2qMLDj&?Xb1tL*ZWPO1{Z*0RnA88zsZwcU9?EJVyi;X(#B zdo3hQ=F^R^*YhZW9l;-AtvpwRyLao|qvSHvJ$vv+U4&SYAu77wV!Q4#2YU&Hf zVbErSoWN~t$Ux0fJ2SHeQdnu&T$=aj`Kec`c~nAaPfHj|Au$^1K@WNU9uW_NF(@*B zK0Ff#X<$xeTsvWZtCP}i?5)Rp>TsHkCuxi&Q}LNBBr+JxIg+^(%BArBKvKpfvmA01 zaxpAFIYre)S7S`}p!9?Y^za7!>+;nJ;`9c0WZ~S!R``mA!^uH?&Zx8zTv|&3oijR- zZHDQWYL$xw(>@6aTF}uipa(L&Z)v!(9&DzCp7v!;0vTSqwp!Fmx2&WmZy1#BoaiLs zRraf+uWJWOkUmCAPku4pyku(WznLO9X)ca1wX8jMZ;3X-`rrYvs^>)L?8paWY#Fi4 zxVZ7H!xfzdg!r+X{p=HjyIb;e;m;2;1|8*!-B4a1$iFOOw#x5dF3arHvf6H8CMnqF z>0vFjU{!j+b4nMBCeYWkJdP5`gi+7bBv0vFw_gz=vC<|r_%Q#x$mC7^asA1Jp@q`j z0SP6?DC-^{AakvfaBQvgML(P~@|q)dzEf!M?smKXeD*`0DDnBxadS2f(sb0CIfJ)Z zuIpo>&_W~?zQ+v%O2y3Ug_VI7nAZZ{dfnBN6<)LR?{y~&rHBl4v?s|cEPn7)3vm~8l1Yy4H(c^MS3ZhS0=mEkc_lq!~c3QN2&Mkd2kvL&pD(wP2d>w^_H z%iSmiPviu7RZ9XxO7|GTs;Y|PbCb3b*;wl#m|}g%Om{t3nW$N1pOHEVlHe~ScdLlC zUYt|Q*W7#);WBjJMZc)Uh!3NwiV9(mtD=n3M!`F2%b^Zxg=VjN;7gJ z7j1o$JZoN?c5;>XN zY)xQ8Qxu;m6LPoM9Fv%;HY1z=#4$t6nvIpsP={orR$4yFESpedBsu|37A}2C%Vr?H z@fAgJ#KZS3V)TVYhO`H=j7o3~w1d%Y_)Gjg3FB1Tt4tUw%$~`oVccYJlZ_9zNE~`G zr)hZ<-%`GZ=hAU;QJWBNRwxfq8O%mzsLif31+~z{yZeJxk-7S$g6{jU@k`q{+@d~| zQ;(mKVwdgaDxP22{vVI84-1q(xqnM zD8Wa_M<>w)gfF1#+*RwEcp=1NX-=$?Hb&;%|ydt$-!m%q7$x12bGROep~A41Krch*=?Qy(hZqG zkUsQjKT6BH9xb@OI89fmmI<*ozV3)y{ubNG{`_Y4IDVXro@zO5B5Pd^t)Df5E^t#{QKw-M}b5|KPowC@H}B~TvWS!%g(^R0s;3gpMhOl8wwp&K2HAEK7o zz)G2^Ll{bNyVnVaAcY`80g!psZ49!2XdZIC77Fg{js<0t@jynh*34qz6{D22l#KNB zW<%B#Ug_pX8$3GJHRbO}%e${5vyj;9fBvvMZ&^dI+}-vn?1gizDFrhB65q5Rqd9vx z-}GWy_GQZcXi3AK&>ji80*vh>xr%3@)LJ2q1{X|AfGYRsB10Qvl~`~U`T~BLR$lwY zjG@{^t37VU%Xf+Vk zxop`H&W}DtjHG8BgXF=??xXG8brx!ySIJYNo}?3~A73?$F3tS-#Yaf<`Cq2@ zv*M{Z@gn>_YHkZG6sR~s!Ph4q`$VX%0N>+cC%nhBZV3I9Z1|MVY>JTZ7GH>|Ute%4 zYYyn059jtnY+;z7i-8=5UTbT8QDJeaTmp~kFrlM&MzF?X@=tUg%SYm|kN9j`vz8Z= z&mSkwx72RgOxm?Rv3u3-cU^w0Zm4A@F=MrGlF|Pj(iupgI9??O*n}jc(T#L8k(&YlE5V`=m)QJ!SPLk(1D;lN>5ZnIsdU9r&4uKC0mmmI2x`U`UoYcofO(mB~tjMz{pMHPzUA%BQM%@9ER z)HP&7(A&f;#!Z$*zGE&>x021_()+HFD{-&g5X#^%s_501g;aAf{`|Mf_t+-YWLZ) ztsMxbgH1ik8%1ZxT|W3?dCrwM3L)7@qpCO>F_#>pa9U(Wd$SEd8Q+(Q8_P?rx1b z?pmG?7ub}R%}t)8x;&9(D&`|)CUU(~hWWtEp090`qon=y22*}XS2E#z^nK=Xs1Zf> z{rjIzX|Z;WiI(^-5|Jq{O)JA;WqeUN9di}3Cz|YdFQ}U5H;bvtbE9hs&8~+V`={~D z$Ag)dmT=o91m5-t(KHvY;@U{7wr*QG6=?=r=(ZX8hKH?Z0{~|)tL%eb~*Jd zN;{$LQo1%o&59>b1Rc8NEc-sEPgYdmWl2Obob>!76s31J)^ItB)q>N?TQrI*#w61o zs%vPD-9|j&k;yjGVVU$V;i5CA3$^ei)uv_KQH8ft)K0g#i~2GQ&z`p$`Jg+JQOiXx zd~WVALP$yDH7|KQoaC{~3{!qlNCb?TP-O$bs@qKuCHsW}Z4vTP4L*xTgu9KM%YAsu z`=}wJRkl$C8f&se4KNd;`47#;HjwP>+`!h-++2%iy$`jJSNzr|j>&A>_6t!#7b`KX zF+Cxn)mFv4ws+Uv#*d~*h{_mCl01gt=-mf5yK^)1oltK|_bd@<*Y(_ZIG4q}uncK~#rt6rbrAq0>R5Lmdw-ya!+OpCodfKCO*%i|9 zb^X!8oX$M~6bru1(r{3|vaIEzUZkOvdLY1{_4&JwygC`h8qI8+0Upggx|X=t-0)bO z`l|?JTn>ou{RnL8KSq4QzMsPzX|KBtWu{OpHJwwS!w8!hbvj(GZ411A&`K2pwr{-H zh`O&k|9-qjPr*n8vy zn$0mL*ApohGinQfNQB(Bqsdhl-|B*_j+KMsmd6NMF z{{183$oC#t;M-t!JySt4Q};GZLpIFRg#G!g?)A4pJ#PmQl<`A*(|q_N$t81w9s`L| zyZUX7HqRdseQOe(@~mA_$Y^C7~FXsg+NZo10Z zbFe$?xo!YF?*{cX*?WDA8_|J_9}WpM8eMCQ#EP9e;$E)474m6yw5Y&qFoK{W zz#VRvJhD3;tOyaf6DgdPG8%dvCHLX;An}88mfrI9vsO)dq~R?Rzwp9nYP`Oiy}IUz zlpY%~Rfy{LhAOtOGYJiQT~L)C+k=<-OuIK2LOvD6FY?Z2F7Wc4@VIY33V1jYcVmpw zb5`dGah%6epx&eI2ag&>XyoIl{EUUN^;P}#v8nf7=`Sd#!HS<;t2eA=&LDSxJX|=A ze|$ir;1-d|D;r_)T$Nxo>gcnB=QdaKL7h4R)`(ft^}PWi>D0%zf)z<59r1Gz{E2vt zIkpJ`I|bb4G4KMT&CAkIHX_$#gU8dIND6O=VzG%QM?FEd`bWd49dnnhr3%B;?LJ+o z0VN!{jZcS@^~R1}r-ihnv@~H`Z%UFLRQ6{P)9pUXETRRSSF7k%Yr4#XWka3;A^2Xd zggG_Fb-7GyAHMf0T9JCL%6{VB4asd?G?UjSD6#g+abVEMES9*nT`hGfAPfox$sQb` z8`dZC*?Bp~$S4$CE_`UQx!V#XIt4*fj)|pi{frR4$NVTT*I7H+ZGf@}PnB1NKP{?C zR)OfKW;*OKftd#U5N&->RGXRc&hTq=6lc#Q|M;>%TU-wXYegnk=ri7gk>s1QkNb^B z$gH35(Y8=zgHe>t4@`XEhS0}D8OWJcvR(7jw0ck&i|&mttafN<+<{>D;>W!>5eO73 z8Y@uva3btV#vMi@SyMp+XUu)4JFMu=e!Pieyn;=7AC42Xc=mGG7FQe`~+HpsXS4otDui9&9^5J4i;299ZJXPomePqE{bIDlD|G z!K36~phcH6*0j{q?UAZ=#@`^k_6P;9Ko(XPR;iyidk+g8W)C1S-@-im);&p0oX{DIQMp3>|U_i>`k z!GH#@Y}+faw#KInVVIT27>^QeP{eFk)7@g7O%!n9C<0auEPWWg7!jL#JUH4Y?@5E7~w*%h33UpJsDAO z#u0t*13~PShaAQyk{jDFxfQM}J-d)3oMdy&uWL&{~Gq{^>oOMR@jWX*bbH@jBDZ?tSb!kzm95fKB zl;bkzG4D*jHpUIb+i8o3=Ut5UALsGFSpY+K)8C`D##7N0{Qs|lR4 zZ1XQh199~cxmw@7jnMG;j6JP@jEfx+2dOB+e1DOMY=1pmaf^jIdY#PmNHOH5mHyeo zi`rpzWJ^SNS^d>c(h9!Yt7!=3trNmdyqX__;xB^Y#|0S?{6`*q)LRr4IzTa8riYur zHMSmO?w4W{q4ybd3muM^O?io5(+?qzdxY8iey&pRQiddH_6{7K-S7d!b3O~&x5bVO zpFaf;EzYt?ACvXJavj&!)=|SsXQG>A)LDa=Xr)k{40(vkzl)U@A)c8SA){qVt#L2( zV2lv|Xi9*)Z{pH8#~V_9p;((6PBC!NR8W-cbvry3Ov6%&485DPCLsB=s>%W3L$a1i zZgvfwPsMdRyUS-qgd#Mq${j*9rw&A|rL0JY1$Bits(U&jT|WsdAbgl<3SuI7&)euN zCiyOPtyV!viT|~2k_&5ub)8FitNpW`cUvqc1Mi-?X7QFb@yv~Fr)i}Rs;$lwY#dv^ zQn+3b7+^rQQMq+N=_qWuNTx4_yK!R3MyRtLVOh|sJ{%Mpkt?XTsWTaRL?+P8lv(td zziNCt$|h%zSK#Q~alKZvhCf1(J#EVvXAdw<-|F| zB64niS%pD%$VVi4?Mkw#4@tp_J064h36P^(FM0=6^$$i-Zav-3CycW>_$;_-8(d7~ znW#JGoHisUIG!?9^N0#pZ%R~oL_@#wT`0YVA>sm6RH8STndc~un@a+V;Sy4jN&DFy z9hrR*5*G4;6N{7%1?%FL!^#1Cfb^#__>=g>q{hs8do11 zG|(7u;ZkH%b|TbrRU*EPB8VO*Ai1Txb&tI$S~`yH#YfB&>skf;$QO5Hqm+=G4Z-{7kKW~%JxE)k?9#-fsn-Pp*km%5FjAcw>emOKXyOFJgQ&LZKaf$N za=L3;5o0hvG~$}iyY;klH<~p`H=NkVZrds0(>za+{H~c7kh^1I88ERt|Aqzx@zFI zs^4kgE5*}3F-VFZ6HQX)_5Bnl<#&Lc9{ zi^_-w5)~_7YTV};Za_vgE2l!9ZP*tOPI_puz8KDeT|GZT(N@^yY->gY*LeP2-q8=9 z3x)ILaHe{GUfRv5#;oMc4d_q4J(?Gxi~Ryh#eFqk-A-6gcC=RD?V@Q4TSD!&!Hjf= z_b?Oa_0IG^c;OyqQ`f_95r#|$+Y&QeH0M>-61z-c2O4j97O^#KM{MMP#bnKM5bIT! zI^Ws*f)Y%z;YgeF6l8`_gkp;Ji3N>VAr*1p#(Zvx55k*Gvt{?swrQoG5D0lbq7#+8 zjkJIMRGYTkoWpUrlq+trq}LOrA>0nfs61oU-u)w^j{&BQ!s@#LuhmdAAO@2bb4es} zt$%Q>wr_@901&xt=HqG}Vw&Aef892>4mK5^R%g;XFX!`N@3jYtf_dIDP-s?k5vcP! zv|Z9RM^eBQs6>@%j7&Tb%k8(O@`$FUJ9tM!iGyMuBH!^W`*1+eF7>g!Gu#WV#i~0D zL-lN&5WPVjyxUf>IQ-hOEl^gW=3Nv`u?L-ak0~NJs-^wN9T3yIU%gEWRD#|*w%{Vi zZ$pq26RNuw1gCv3SR)t_Bi(!m+2Vn+)A`kwOr>@EPQ^Oi{7}c7>w;|6*z;GgDMN4U z=;E@HFah^~aVJ^d{_MINUAPbG>^&^?o{c@9F!f5$6+e^ze3?k8tnGR|TgQE}V0&kJ zEr`=aLbksMQiQLCOwUIq{?0D?*E|-+* z#*G;F%gtyK_HL=l%EoY-ap(CR{sQkI0s=S35ZGFPlWxMJ>$pSQp!HPA4FA9uNEdab z$9W)DUkt+VK};G`6S+NZiqiBvTdQ|h;hP;dowvyahQvEAGHR@@$ASE(?id6&#fg|K z?24RdC$jOUwQUTi`MK8aQo%gq_RNF)`L_mK&YM#4Ui+we`kx9iuScxkozRY^_l=J= zlO$2j5kPX5y&)k14gM&!Q`E_0^^$c zd3ZxFGmCB&p>I7)dgc7~#P#KgP%D0(4KIPYYl3~Lh9;dy)D7EPUWxT#{MathxKsGS z4Z1^dnW!i3_0~$!xzQ^0(EbEorq4!igi5zz$y@nR$w%V8oLlcuwlmn= z2UV0Ryo@T!>{Xy7y73|YbDuH#>$>sd!8lzH=z?x7bdk5Yk=cV&cLUtZDDpx*rDT$h zLQMGZ6KtrUm<_!|mak*Xp5yC!Ez<$xv|WTQQCM%9J?n6rr1Z(k(N>d`{CXy*IV033 z{p@~D5<-c_%ac`F0-jqgf)DjgJhL(bG>?)GTXZhu?BZSvrsUaeBB1*U-Q~7}D}+{L z7`#Sy&@k<(eZH2tAl`{OUr)kOGHvWJ^?9eNzycKXhP0@K^i4s?SOf0-&Bh))J&nTi zG)`-?`2+SbrRrnXF1T=%92EZgd6Gew5~nCnl~svpV}7YswczZF8Y2+Y#QE-YihS<26!v2V1z5?!3_MUQgz~Jvpe`?nb~A;(JOUK z#iy_Di~2Eoi+hB?FRYg4>m1DsN)QnW;nt|Sr;m)ch~8==W0=W-@lorY-+kzmcO)Op zA;{0oE^gdS7ck)ucA7t6OpX;`a7&!-h0YrFHoQ6kPgV4)ZO+3EV8l@t8b-Rf&tmxk zbL4Mh052z2j*u`Ll~`@RUV7EgXfeo`hUTj|SUI7$0G)y|58p>E7Di@%#j*M>cf7}h zGRFB)PgHI3=W>(pSPPpSsFm#q1qwItvSk!tQ5c%3usUkT-i{G8OHw*<7yY#F?YaUV z%t>WchHtoV{h?>iTb|^{&_=^^h0ThZuoBv|$HO>Ovyz4SiNrDjw=EF_m!rvppxoq| zJOQ}$0)4CZ(j26mvoG$%j?b?|r&W#Q8yM=pBF0q`ybE83!ztG^6f`f&2ag!*nR=ej z1fo&I7^rZAt0*nI@ZLIbbE@YhU}!Yq%jJVJHus&&&k|a;8gm@k)8|;j0~24 z0i7&<77?;qX&isUuKe^`l%C(^$1k85RC>5Ow-8gD2HSYqtII~*#@4kqh|n05BD8Eg zdahT_$uleCsU=z}{KtFh{gM64bS;YA%>qnI1yn!xD2@@x=4gfEvR#n=1+?cFCZZX{GSyknpUVGsM5R-?t#TylgHMZQ z`EdSyAk92K?gT}~r&IV!_@uj(n&u87>+0JQy_@u-FWl~&tvZh1xH#9W7!)=e7s!q5 zBZe>4C6ZK~M@B#>1T9s+972?0z}J#>u{anEYSW%6v0`Ru9lPdJVGI}BL$S1;N1d3L z(Wc~fT!-y*pjF)1Ja`sUr9-kq0D`F)eoW(!c08g#@jZi?wdpCykqyb9MUYA1t20c} zt-iwBsPg%+gAPxE0*6kwTSU^SV|;5Trx?=cBO2LbUzl7e#23f}HOvygF&d`}Di6qT zX@lJ)@7G?^^WBwbk~)^ssvF)-IL&?1aFo`Gw`&5eOh#gh3^w7WTBs!n$vwrO@6Q5r_gM$TgzIY3K>Br#q>TVg07` z7to4O;L$Lq5wx|>DzEViXleiX1k6=|kO5Co9-Fn`HQDaa^^YC;OA%g%^V!l=kLD|a zIsGtOy>mx-?K<@rw)1g9qf?JJHRFjRyj%u0c2xS!+?d`HV#zKlh+v;5Kkqx(VJ0_3 zd^QQ)Z=oNQw;^E0_Xr_i7@}#w*%AgmX+$WrLG4vij;6S&f zbk~iL^Lr<3gNk-i8ob7sxrKXcW9kKp)e+ZkCil=CZxFG2bKH&$6v$qALowBu9(cD; z)fe9WY$lHxFEgQsUidbVCwIT3U-{CYA7>JNm8E&$k6s zt60O8APrJdYQeer0ZcjQ_vlQSvns_$SDy*pL|;2)-^k}D=fa9=oye)kBi(|!ZyzLC zm?Mz8-2n=^`yZO zZhMi_GsXwI+c~Txq(a(r?s^fnv6!_H!82032Nl2dxU_0J1ni86f`tQ>EyR(z-tQfq9njdr$D*)9hogNC$42un6|BicA#FyL ze5sY0J}kB=!-lv#!BH%$+3_^;v-$o7V3%0BL(JZ-GkRR=BwzUc4sJbCy1h5xEFD;SMm?^g1@!MNO{$+XU> z!^8xyYtDNvR{Y~KWjep3?OnR!`DIl7i8JdWcb$E~+29ws2V!jXO^M+m$x^f6(VDf6 zw*af+{HEW)-HeC~BZ`@5>%AWY9;Jd88sLAYn z5*N8iYeQIJVP(TO(IPCQwO)c2D;27VrEPw1Uxt~XxCWslSgRCS|G{Sdxr_WFPtREV zk=+ELq4l6143eDu#QZTc$TUoSEp`p-k*N3aD4sj{2;@ElAx)*2V(BI38PnukMiYOX z(!nu)l^)Hbl@kAYqgFpWH?7EfX8!sst4QP;0S`EJZ^jxvW1*kzF=h<$CcY`9Lsnm= zNmqpA0U`1?L2%Bp07YifsU$(`pc6`L_v5FN(`=r!&s8S6$z!;2;JQS5az+ zJ}fB$sS^tgG-|PGsqYM{()bVd#R}qOaA;p+NUqE+l990%q>ch@B0mH54F%33h$D!H zxICP{y-HW<>he&*TH!1!hvy{loq-H;X^{=y^UCe&0kYDaF+@SD%T|AV%i^%(C02QM zP*WI1nF*@l3;|MhmQuC}e?41Yq8ODJ{23XV=7@^!d&T7yzh%qFJXE z{?fK1UsEn}bwp}N$h&&<EqbSFA6-&Gv(I!9h2lpNiX6nc6klGF_XmUDv z(f9#)^hr`-)*r|QC3sIZ8f(@x3xt?g0?;TiRsmwAP(C=_TUDJo$H+Q zYryl>QA`r@;#2pGr~`A+QU{KhO=zJhF=C`{d2u9%*}d3~*y2q-0p_%tFAIHnvsctl zaTl7pr^3Wn1&u*O18{Z&qjV?gdL9RHv_jm-0QjW~^)8jCx!z~0r*TG-V6 zeE2Dq2xtcDHl`ds<-*D}7c+H4ELn90YOrx8%kcsbpz34WN!rdH$ORn zT`a9#tnW7@o>-=yD$3W9CurAfWZPWq6%45hRH#~pP!C3x zKn?w1Fn(M-1t_#Ax=E0F_B=^C_W`;vR{TbIWRmMmV%x4X)m~D!lOTPd4!!>Xyqo6@Lj;dE5#kaWb za8F*mRLo0rWN?CX{3+JK)D1P8a5d%pD+bSsfS$z(#y&)U$Agw?23@R{EkDf4EB(#F zN2KU(H&~@73WBG~f-|4>5^;~4ahF!9rsong)0xy{A@pcZ8r9d^>+@Ud*1xm**f(N2=z4*oEt*21kXp>&w zql%ucSYtt5CKW@F0Ll4dgK~rjG81KIjXrHM;ByC1ss7D#juuqv2dR8ab2|MunOV#& zQ&7M#QrBtyA%++My8sc;f!uWBm(Zh7hdqFixe}`^YmB%kj=9$t&2LYqYV`%;y7gHF z6Tr0>3WlCQf_EWzF((5(2M95&@U%czv_OEOS4_PMU=!;Hr(a{lm~~H6WQNt1uA&5B z`N`1t`{RpMD4(k@_G)fgTWxll7^AtpOm!DKimUmP$Ryk&C7S_P(}1c25uf4e8yfRf z#rj@4A(@-JCE6_<@xRn+K442(Q8P<0qJll_Nyr6ScLMo=MW(jt09Ue> zVI-+dMqYs+{fG4tEiZ=j2ELcFj2I^eY2d!yzyPLBBP~ z;%Yw&RJG>Arurs1d2yxVrg+-Na*lQg(bPR`j-(8S8$cb-Fmv13p1f&O#G0;v;iu1Q z`k~p0d3XiFJvv=6$)K$?)f0(mT^1JtWiv^-EaRcef)0H>M}C}4)_sWG6zZ;N4c$8G z8#gX&I(=oD-0@sxGQkXRR?AT0Pb@TU;7Ncp-`Em5V<5FEm8!VLgWPeSa;y$}g};x? z{E%9f-%~ZdTCo$n5RkG+7a(MToc<(!ylLf-PX&1*VQU8%?Zi{8)aU!SNhJuxHbKLC z6YayKtlpHcQ&#DFU2Jxk{HC@+6UQuS(kR#iGkfl1mfhdfIA;k~Fv5Q2aMs+v)rnE3 zt_ev=TTk$nHB!y8CZ%FGB;W#iV>^{uhBBu;I1TiJyq3KR<$_1$c0))}$wh0nRo7S3 zS5?nQh}BmA05NH1Cj~sEX&mEd7&#?}Qg|$A7DLRF3X=HK@c~zTxLowsnVywxR%+31 zy){f^Ni4gt7|438P&wRJvkk}Ca2tziKP!fsbA�l6O~%xe0FuZ~%ylj05tW`q7l-%Y~xSfQt zg-~wCq!tCRLhd7qv0b5t!8AV*@X&PU?@p<&F}YI9CxYDtsq`9E(_LbYx`wV*t-GzF zu_gpr$3qMOXYv z^7hxu4P|MvS><|~6}KeGQ0NoQ-sF}F9q>AwdX7K`rg+i7;@gkIw-V2V(;HeyxH=vv zicSw`aNRq2U*$%V=9TMI4QpEV`yH0fw+E<-6FEs5qBxY8!3^p*oywn78sqIt)XhAS{&Eii{1;jr6uw>fT>t3?vqt<<#?iybQO#ALw>Ki?&WT(Q9? z1d;8=!wD<|rWzzSqH}}U89f}p{uEi ziHR_|D^KSyw1GUS4iB*;5&-B1Gf7|;0T3%a*Cje>ooXnx2rQL<0a%h26zZ9o83=FU z%7xq9Fg}x05%qyJdIDwcEV?9Qe>9&gkt{vF7xPd1A{n=}x(>1z=3JNP6EvT>a zqQHI{T-ABRlB-U+8NkMKwUDa!wM`wqpVS?;?O5b>DI*ug?VzHT1dw-QJ=oDzq3s7L<{EiV4?FAvxvr~O z@bNt@=gBa5osN%8Tl9XCx@rh#md9ODSw@gDOGg#CV)9WpK?WtL+@pMjjzC_g0Pt^S z{{3q87(p!|k|aqNw2d#X83?L5oLqQYh50J~05>kLdSb^}OD$as8e3zT){d*qSyDt3 zFI8L|t05qqspxP)$7Mp9uEP3v03VjBZ^Tn$fG1K1nirOKT!bofoa5VyB^Iy@{{S!;;0wc^)I z?`LZ2sG)_T@8vOh6k!~U^~gp53@$jVlLP}3qL~fM9Bwy3eIemXRdc^X>S?5&pG`ew z6!xoZ6txXpDymvlnd@t+9Y#>Nz}ltRSQSvHH&KTHr^MjmEMt$)>aWFOJH}*a_4)-& zo5Sw9x$_e1%lh`CwQ8GeO*HgZYS`dN)Gl+qMh;Y|QJkrZYIJ^{zRAOL3@>M^|pG(~D=0no3)3zBy?miKBLrjQCd(KG?^lR0I3~ zHhA((O$XvboW>Ur=9w-a0@%vnIO<6x88HGOX1UqNgh(6v)P3{{f1{qCP1^>arP6eE zL`L$y0?TJu;)5Z)x|UM8D6%saJ=4l3aAp9<5roAx!xM=mz=LuLCg1E`ZAgI=0$OGf zl-*D?$-a^Y*L`>|uNwB!lu*#sTGst(pry=-M-sIz=;iX2rAfeV-j_SJm;2j5%DW1U zYPA^5gER)%1E~h^;9!|KMuI@Gu%On=8VhIn{Qeg;d}m!K?;O^ms-UV`>NdBk$5OEf zgn?YIMGBw+j0`Bq8OL5dE3ha30G&!kQ+XT-B$4Ef!kpBBO@0|*rm5Gmd}NU&JT$(0 zM=MC4X4eD&(fWgYk44G#5V_)guI#vCb7j{0!Hap5WU-Ny5@HlDo)u!Zp4x(cF{Sfs z;D0hh>TJgsQ}sR1*F0}gB+_Yj1e@@t`@PJ*lc}JMcEJqrOvU3xV^IsjxZp);ky4IILbF?JlKG z0BngCynz!WSctQhH|_^IsBr?&b@Uv4?4w-A=JicJv$Egxj1-AePiPb|m5C)O7U?9B zB9!Fg_s^LWhG5zB^~u;?&7+9HzK$`@BR+CVh?8j2AP62E4)U#IL8KjAo0;dpPveb~ zdc*ctHsm(R#!P&513R} zE}-jMsB1Mna96xr(OVYArRL_$(HA*DSqFY0TRnCLJqMv?;ZA+Ibn^Z zh$8@C0HYY}?Q!C-H2{JI{#_9}l^RCRczT*Uq&`y#UTRn=kq^WjkuxVz=_O;B2FFHa z$i{f7_cql*j>@{dr>~S3?pn!l(>2u95LD92C~(3hg^I99pQ+eWDj0ihJw3Ry4%Sg- zx}o1Q1#^DcanYAQ78hiZ?sqL!c%3cMTI=IVm_*R0nG~TyM$U)f(THX~hHkH%5PMFM z7-znjjHJ7fCfA;2XVq`*65T;1OJe3OlGb(d+2&D4Q#~|L{9Ru9rlpz{Wm$Iv8p9dL zVyxvFM_^S{u6Y33)aWtQ8Kj$UwShko>uK@>F{Sxu>%YBvq<1@>pSMGMvqf@Sb?GT& zma}TIQx(|q86lH!EHLa@4&no35)Vx3cryG$E3lEAl6Y+v8`{?Nx)?Rhs07BdufLa? z3sy-)0#;=2O{qc;{$W%YgfWRl*jP%Yp?Jx~A@ZqooO@iLT z0x5t}o<&(ByWOvIN#&72ZS#Uj0GVCc!YY+Lfh2meHsBrs?ONiECXzLDeowtsU7+CB zH9>icBTLO%_k8X(RM{kT{{S}^9R)iu0IX-g7Q4l+x*HW`bJIG}HBB@kX3h(=o7I03 zqdh&b#6#L%S`F{``lvO{F3L4ediv2{d)D=0-$7Mg@Y6zNS~_=|V8O=ipyTuTaR@Mt zq6A$|uOb~0pzQPpABVcs(MKfFup&rQpw98!GZNiBvfn=BILWwJ4S3Y4Ik6!#+ zbsnhatOdtQ+-Op(OIF^B(#FqMMhZko1q!$kG6GNo?f3FWw-k1U4vXv5532?Di*%nj zS#24ZTQNNrHhyN^h1#;NpF*g*)r6ikxYSIKG)Ol|98vj88>^}v%Yl$euT~4jQ0)2@ z+FHy(IdzD(x~feEyhB~5zAN2#&$+d23HYv5)7p}09zygI)kG(E&!CN%WhWkv#Gub^ z2f=ntEF(buTc2E(jdOT8U^ zN1rRG-U9@YoGt-Ep;bzcSMeP2ULJ)SFCnI0H8!3yVlH*!paXLOGDo|h2%iA_v&MqH z7P(xK0qKsXgq=xwZBW#@-pwK$xv1HJ->NX;F8E4us@tLUa62ES-{yF)K#?KF%VibF+b_O+YWaeuIY*Sl5JuCt zr(=wMyg4&4oGZNzs>5gGJY2`n>r)Np-#T3CBbKx*azBvlg%}vKyKp!o z-0^)z(ta3>K=7Z7)NSa1cxzhe(Pdq%qNJj;m~;)krK+f;NtU9nNg`%7GN>#?Slsvu zcQHMG006J0f-P*gfwU?M83GNu^XQky&&%yIQ_>`8fuC-Dg{Es-fK1tftzu|44ucWeq3(SEG(7+2Ld4Zt!f|v374037it%| zJ+j`F=_N3Rr6(V_NQ(>^4&?x67$o#RhIpp1pmO))LnDmx@>Sy6*EPBLq};=^#ZRj$ zs~ShRT`D9F7D&Y;P|Fgac)(V5m-t9!a48MO2L-Ayl4#gOEPB974*iS4}xv;S#r+mdXo_`%<+e6VoKGPi&qWq>>

+
+
+ chalk +
+
+
+

+ +> Terminal string styling done right + +[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) +[![Coverage Status](https://coveralls.io/repos/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/r/chalk/chalk?branch=master) +[![](http://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) + + +[colors.js](https://github.com/Marak/colors.js) used to be the most popular string styling module, but it has serious deficiencies like extending `String.prototype` which causes all kinds of [problems](https://github.com/yeoman/yo/issues/68). Although there are other ones, they either do too much or not enough. + +**Chalk is a clean and focused alternative.** + +![](https://github.com/chalk/ansi-styles/raw/master/screenshot.png) + + +## Why + +- Highly performant +- Doesn't extend `String.prototype` +- Expressive API +- Ability to nest styles +- Clean and focused +- Auto-detects color support +- Actively maintained +- [Used by ~4500 modules](https://www.npmjs.com/browse/depended/chalk) as of July 15, 2015 + + +## Install + +``` +$ npm install --save chalk +``` + + +## Usage + +Chalk comes with an easy to use composable API where you just chain and nest the styles you want. + +```js +var chalk = require('chalk'); + +// style a string +chalk.blue('Hello world!'); + +// combine styled and normal strings +chalk.blue('Hello') + 'World' + chalk.red('!'); + +// compose multiple styles using the chainable API +chalk.blue.bgRed.bold('Hello world!'); + +// pass in multiple arguments +chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz'); + +// nest styles +chalk.red('Hello', chalk.underline.bgBlue('world') + '!'); + +// nest styles of the same type even (color, underline, background) +chalk.green( + 'I am a green line ' + + chalk.blue.underline.bold('with a blue substring') + + ' that becomes green again!' +); +``` + +Easily define your own themes. + +```js +var chalk = require('chalk'); +var error = chalk.bold.red; +console.log(error('Error!')); +``` + +Take advantage of console.log [string substitution](http://nodejs.org/docs/latest/api/console.html#console_console_log_data). + +```js +var name = 'Sindre'; +console.log(chalk.green('Hello %s'), name); +//=> Hello Sindre +``` + + +## API + +### chalk.`", + "expected": [ + { + "type": "style", + "name": "style", + "attribs": { + "type": "text/css" + }, + "children": [ + { + "data": "\n body > p\n\t{ font-weight: bold; }", + "type": "text" + } + ] + } + ] +} \ No newline at end of file diff --git a/node_modules/domhandler/test/cases/08-extra_spaces_in_tag.json b/node_modules/domhandler/test/cases/08-extra_spaces_in_tag.json new file mode 100644 index 0000000..5c2492e --- /dev/null +++ b/node_modules/domhandler/test/cases/08-extra_spaces_in_tag.json @@ -0,0 +1,20 @@ +{ + "name": "Extra spaces in tag", + "options": {}, + "html": "the text", + "expected": [ + { + "type": "tag", + "name": "font", + "attribs": { + "size": "14" + }, + "children": [ + { + "data": "the text", + "type": "text" + } + ] + } + ] +} \ No newline at end of file diff --git a/node_modules/domhandler/test/cases/09-unquoted_attrib.json b/node_modules/domhandler/test/cases/09-unquoted_attrib.json new file mode 100644 index 0000000..543ccee --- /dev/null +++ b/node_modules/domhandler/test/cases/09-unquoted_attrib.json @@ -0,0 +1,20 @@ +{ + "name": "Unquoted attributes", + "options": {}, + "html": "the text", + "expected": [ + { + "type": "tag", + "name": "font", + "attribs": { + "size": "14" + }, + "children": [ + { + "data": "the text", + "type": "text" + } + ] + } + ] +} \ No newline at end of file diff --git a/node_modules/domhandler/test/cases/10-singular_attribute.json b/node_modules/domhandler/test/cases/10-singular_attribute.json new file mode 100644 index 0000000..544636e --- /dev/null +++ b/node_modules/domhandler/test/cases/10-singular_attribute.json @@ -0,0 +1,15 @@ +{ + "name": "Singular attribute", + "options": {}, + "html": ""; + var dom = makeDom(markup)[0]; + var p = dom.children[0]; + var span = p.children[0]; + var a = dom.children[1]; + + it("reports when the first node occurs before the second indirectly", function() { + assert.equal(compareDocumentPosition(span, a), 2); + }); + + it("reports when the first node contains the second", function() { + assert.equal(compareDocumentPosition(p, span), 10); + }); + + it("reports when the first node occurs after the second indirectly", function() { + assert.equal(compareDocumentPosition(a, span), 4); + }); + + it("reports when the first node is contained by the second", function() { + assert.equal(compareDocumentPosition(span, p), 20); + }); + + it("reports when the nodes belong to separate documents", function() { + var other = makeDom(markup)[0].children[0].children[0]; + + assert.equal(compareDocumentPosition(span, other), 1); + }); + + it("reports when the nodes are identical", function() { + assert.equal(compareDocumentPosition(span, span), 0); + }); + }); + + describe("uniqueSort", function() { + var uniqueSort = helpers.uniqueSort; + var dom, p, span, a; + + beforeEach(function() { + dom = makeDom("

")[0]; + p = dom.children[0]; + span = p.children[0]; + a = dom.children[1]; + }); + + it("leaves unique elements untouched", function() { + assert.deepEqual(uniqueSort([p, a]), [p, a]); + }); + + it("removes duplicate elements", function() { + assert.deepEqual(uniqueSort([p, a, p]), [p, a]); + }); + + it("sorts nodes in document order", function() { + assert.deepEqual(uniqueSort([a, dom, span, p]), [dom, p, span, a]); + }); + }); +}); diff --git a/node_modules/domutils/test/tests/legacy.js b/node_modules/domutils/test/tests/legacy.js new file mode 100644 index 0000000..87fabfa --- /dev/null +++ b/node_modules/domutils/test/tests/legacy.js @@ -0,0 +1,119 @@ +var DomUtils = require("../.."); +var fixture = require("../fixture"); +var assert = require("assert"); + +// Set up expected structures +var expected = { + idAsdf: fixture[1], + tag2: [], + typeScript: [] +}; +for (var idx = 0; idx < 20; ++idx) { + expected.tag2.push(fixture[idx*2 + 1].children[5]); + expected.typeScript.push(fixture[idx*2 + 1].children[1]); +} + +describe("legacy", function() { + describe("getElements", function() { + var getElements = DomUtils.getElements; + it("returns the node with the specified ID", function() { + assert.deepEqual( + getElements({ id: "asdf" }, fixture, true, 1), + [expected.idAsdf] + ); + }); + it("returns empty array for unknown IDs", function() { + assert.deepEqual(getElements({ id: "asdfs" }, fixture, true), []); + }); + it("returns the nodes with the specified tag name", function() { + assert.deepEqual( + getElements({ tag_name:"tag2" }, fixture, true), + expected.tag2 + ); + }); + it("returns empty array for unknown tag names", function() { + assert.deepEqual( + getElements({ tag_name : "asdfs" }, fixture, true), + [] + ); + }); + it("returns the nodes with the specified tag type", function() { + assert.deepEqual( + getElements({ tag_type: "script" }, fixture, true), + expected.typeScript + ); + }); + it("returns empty array for unknown tag types", function() { + assert.deepEqual( + getElements({ tag_type: "video" }, fixture, true), + [] + ); + }); + }); + + describe("getElementById", function() { + var getElementById = DomUtils.getElementById; + it("returns the specified node", function() { + assert.equal( + expected.idAsdf, + getElementById("asdf", fixture, true) + ); + }); + it("returns `null` for unknown IDs", function() { + assert.equal(null, getElementById("asdfs", fixture, true)); + }); + }); + + describe("getElementsByTagName", function() { + var getElementsByTagName = DomUtils.getElementsByTagName; + it("returns the specified nodes", function() { + assert.deepEqual( + getElementsByTagName("tag2", fixture, true), + expected.tag2 + ); + }); + it("returns empty array for unknown tag names", function() { + assert.deepEqual( + getElementsByTagName("tag23", fixture, true), + [] + ); + }); + }); + + describe("getElementsByTagType", function() { + var getElementsByTagType = DomUtils.getElementsByTagType; + it("returns the specified nodes", function() { + assert.deepEqual( + getElementsByTagType("script", fixture, true), + expected.typeScript + ); + }); + it("returns empty array for unknown tag types", function() { + assert.deepEqual( + getElementsByTagType("video", fixture, true), + [] + ); + }); + }); + + describe("getOuterHTML", function() { + var getOuterHTML = DomUtils.getOuterHTML; + it("Correctly renders the outer HTML", function() { + assert.equal( + getOuterHTML(fixture[1]), + " text " + ); + }); + }); + + describe("getInnerHTML", function() { + var getInnerHTML = DomUtils.getInnerHTML; + it("Correctly renders the inner HTML", function() { + assert.equal( + getInnerHTML(fixture[1]), + " text " + ); + }); + }); + +}); diff --git a/node_modules/domutils/test/tests/traversal.js b/node_modules/domutils/test/tests/traversal.js new file mode 100644 index 0000000..f500e08 --- /dev/null +++ b/node_modules/domutils/test/tests/traversal.js @@ -0,0 +1,17 @@ +var makeDom = require("../utils").makeDom; +var traversal = require("../.."); +var assert = require("assert"); + +describe("traversal", function() { + describe("hasAttrib", function() { + var hasAttrib = traversal.hasAttrib; + + it("doesn't throw on text nodes", function() { + var dom = makeDom("textnode"); + assert.doesNotThrow(function() { + hasAttrib(dom[0], "some-attrib"); + }); + }); + + }); +}); diff --git a/node_modules/domutils/test/utils.js b/node_modules/domutils/test/utils.js new file mode 100644 index 0000000..676e8f6 --- /dev/null +++ b/node_modules/domutils/test/utils.js @@ -0,0 +1,9 @@ +var htmlparser = require("htmlparser2"); + +exports.makeDom = function(markup) { + var handler = new htmlparser.DomHandler(), + parser = new htmlparser.Parser(handler); + parser.write(markup); + parser.done(); + return handler.dom; +}; diff --git a/node_modules/duplexer/.npmignore b/node_modules/duplexer/.npmignore new file mode 100644 index 0000000..062c11e --- /dev/null +++ b/node_modules/duplexer/.npmignore @@ -0,0 +1,3 @@ +node_modules +*.log +*.err \ No newline at end of file diff --git a/node_modules/duplexer/.travis.yml b/node_modules/duplexer/.travis.yml new file mode 100644 index 0000000..ed05f88 --- /dev/null +++ b/node_modules/duplexer/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - "0.11" + - "0.10" + - "0.8" + - "0.6" diff --git a/node_modules/duplexer/LICENCE b/node_modules/duplexer/LICENCE new file mode 100644 index 0000000..a23e08a --- /dev/null +++ b/node_modules/duplexer/LICENCE @@ -0,0 +1,19 @@ +Copyright (c) 2012 Raynos. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/duplexer/README.md b/node_modules/duplexer/README.md new file mode 100644 index 0000000..61ff71a --- /dev/null +++ b/node_modules/duplexer/README.md @@ -0,0 +1,47 @@ +# duplexer + +[![build status][1]][2] [![dependency status][3]][4] + +[![browser support][5]][6] + +Creates a duplex stream + +Taken from [event-stream][7] + +## duplex (writeStream, readStream) + +Takes a writable stream and a readable stream and makes them appear as a readable writable stream. + +It is assumed that the two streams are connected to each other in some way. + +## Example + +```js +var grep = cp.exec('grep Stream') + +duplex(grep.stdin, grep.stdout) +``` + +## Installation + +`npm install duplexer` + +## Tests + +`npm test` + +## Contributors + + - Dominictarr + - Raynos + - samccone + +## MIT Licenced + + [1]: https://secure.travis-ci.org/Raynos/duplexer.png + [2]: https://travis-ci.org/Raynos/duplexer + [3]: https://david-dm.org/Raynos/duplexer.png + [4]: https://david-dm.org/Raynos/duplexer + [5]: https://ci.testling.com/Raynos/duplexer.png + [6]: https://ci.testling.com/Raynos/duplexer + [7]: https://github.com/dominictarr/event-stream#duplex-writestream-readstream diff --git a/node_modules/duplexer/index.js b/node_modules/duplexer/index.js new file mode 100644 index 0000000..a188a21 --- /dev/null +++ b/node_modules/duplexer/index.js @@ -0,0 +1,87 @@ +var Stream = require("stream") +var writeMethods = ["write", "end", "destroy"] +var readMethods = ["resume", "pause"] +var readEvents = ["data", "close"] +var slice = Array.prototype.slice + +module.exports = duplex + +function forEach (arr, fn) { + if (arr.forEach) { + return arr.forEach(fn) + } + + for (var i = 0; i < arr.length; i++) { + fn(arr[i], i) + } +} + +function duplex(writer, reader) { + var stream = new Stream() + var ended = false + + forEach(writeMethods, proxyWriter) + + forEach(readMethods, proxyReader) + + forEach(readEvents, proxyStream) + + reader.on("end", handleEnd) + + writer.on("drain", function() { + stream.emit("drain") + }) + + writer.on("error", reemit) + reader.on("error", reemit) + + stream.writable = writer.writable + stream.readable = reader.readable + + return stream + + function proxyWriter(methodName) { + stream[methodName] = method + + function method() { + return writer[methodName].apply(writer, arguments) + } + } + + function proxyReader(methodName) { + stream[methodName] = method + + function method() { + stream.emit(methodName) + var func = reader[methodName] + if (func) { + return func.apply(reader, arguments) + } + reader.emit(methodName) + } + } + + function proxyStream(methodName) { + reader.on(methodName, reemit) + + function reemit() { + var args = slice.call(arguments) + args.unshift(methodName) + stream.emit.apply(stream, args) + } + } + + function handleEnd() { + if (ended) { + return + } + ended = true + var args = slice.call(arguments) + args.unshift("end") + stream.emit.apply(stream, args) + } + + function reemit(err) { + stream.emit("error", err) + } +} diff --git a/node_modules/duplexer/package.json b/node_modules/duplexer/package.json new file mode 100644 index 0000000..3bf5258 --- /dev/null +++ b/node_modules/duplexer/package.json @@ -0,0 +1,113 @@ +{ + "_args": [ + [ + { + "raw": "duplexer@~0.1.1", + "scope": null, + "escapedName": "duplexer", + "name": "duplexer", + "rawSpec": "~0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/stream-combiner" + ] + ], + "_from": "duplexer@>=0.1.1 <0.2.0", + "_id": "duplexer@0.1.1", + "_inCache": true, + "_location": "/duplexer", + "_npmUser": { + "name": "raynos", + "email": "raynos2@gmail.com" + }, + "_npmVersion": "1.2.18", + "_phantomChildren": {}, + "_requested": { + "raw": "duplexer@~0.1.1", + "scope": null, + "escapedName": "duplexer", + "name": "duplexer", + "rawSpec": "~0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/stream-combiner" + ], + "_resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "_shasum": "ace6ff808c1ce66b57d1ebf97977acb02334cfc1", + "_shrinkwrap": null, + "_spec": "duplexer@~0.1.1", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/stream-combiner", + "author": { + "name": "Raynos", + "email": "raynos2@gmail.com" + }, + "bugs": { + "url": "https://github.com/Raynos/duplexer/issues", + "email": "raynos2@gmail.com" + }, + "contributors": [ + { + "name": "Jake Verbaten" + } + ], + "dependencies": {}, + "description": "Creates a duplex stream", + "devDependencies": { + "tape": "0.3.3", + "through": "~0.1.4" + }, + "directories": {}, + "dist": { + "shasum": "ace6ff808c1ce66b57d1ebf97977acb02334cfc1", + "tarball": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz" + }, + "homepage": "https://github.com/Raynos/duplexer", + "keywords": [], + "licenses": [ + { + "type": "MIT", + "url": "http://github.com/Raynos/duplexer/raw/master/LICENSE" + } + ], + "main": "index", + "maintainers": [ + { + "name": "raynos", + "email": "raynos2@gmail.com" + }, + { + "name": "dominictarr", + "email": "dominic.tarr@gmail.com" + } + ], + "name": "duplexer", + "optionalDependencies": {}, + "readme": "# duplexer\n\n[![build status][1]][2] [![dependency status][3]][4]\n\n[![browser support][5]][6]\n\nCreates a duplex stream\n\nTaken from [event-stream][7]\n\n## duplex (writeStream, readStream)\n\nTakes a writable stream and a readable stream and makes them appear as a readable writable stream.\n\nIt is assumed that the two streams are connected to each other in some way.\n\n## Example\n\n```js\nvar grep = cp.exec('grep Stream')\n\nduplex(grep.stdin, grep.stdout)\n```\n\n## Installation\n\n`npm install duplexer`\n\n## Tests\n\n`npm test`\n\n## Contributors\n\n - Dominictarr\n - Raynos\n - samccone\n\n## MIT Licenced\n\n [1]: https://secure.travis-ci.org/Raynos/duplexer.png\n [2]: https://travis-ci.org/Raynos/duplexer\n [3]: https://david-dm.org/Raynos/duplexer.png\n [4]: https://david-dm.org/Raynos/duplexer\n [5]: https://ci.testling.com/Raynos/duplexer.png\n [6]: https://ci.testling.com/Raynos/duplexer\n [7]: https://github.com/dominictarr/event-stream#duplex-writestream-readstream\n", + "readmeFilename": "README.md", + "repository": { + "type": "git", + "url": "git://github.com/Raynos/duplexer.git" + }, + "scripts": { + "test": "node test" + }, + "testling": { + "files": "test/index.js", + "browsers": [ + "ie/8..latest", + "firefox/16..latest", + "firefox/nightly", + "chrome/22..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest" + ] + }, + "version": "0.1.1" +} diff --git a/node_modules/duplexer/test/index.js b/node_modules/duplexer/test/index.js new file mode 100644 index 0000000..4988e0d --- /dev/null +++ b/node_modules/duplexer/test/index.js @@ -0,0 +1,31 @@ +var through = require("through") +var test = require("tape") + +var duplex = require("../index") + +var readable = through() +var writable = through(write) +var written = 0 +var data = 0 + +var stream = duplex(writable, readable) + +function write() { + written++ +} + +stream.on("data", ondata) + +function ondata() { + data++ +} + +test("emit and write", function(t) { + t.plan(2) + + stream.write() + readable.emit("data") + + t.equal(written, 1, "should have written once") + t.equal(data, 1, "should have recived once") +}) diff --git a/node_modules/entities/.travis.yml b/node_modules/entities/.travis.yml new file mode 100644 index 0000000..8724b6c --- /dev/null +++ b/node_modules/entities/.travis.yml @@ -0,0 +1,7 @@ +language: node_js +node_js: + - 0.8 + - "0.10" + - 0.11 + +script: npm run coveralls diff --git a/node_modules/entities/LICENSE b/node_modules/entities/LICENSE new file mode 100644 index 0000000..c464f86 --- /dev/null +++ b/node_modules/entities/LICENSE @@ -0,0 +1,11 @@ +Copyright (c) Felix Böhm +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/node_modules/entities/index.js b/node_modules/entities/index.js new file mode 100644 index 0000000..fc55809 --- /dev/null +++ b/node_modules/entities/index.js @@ -0,0 +1,31 @@ +var encode = require("./lib/encode.js"), + decode = require("./lib/decode.js"); + +exports.decode = function(data, level){ + return (!level || level <= 0 ? decode.XML : decode.HTML)(data); +}; + +exports.decodeStrict = function(data, level){ + return (!level || level <= 0 ? decode.XML : decode.HTMLStrict)(data); +}; + +exports.encode = function(data, level){ + return (!level || level <= 0 ? encode.XML : encode.HTML)(data); +}; + +exports.encodeXML = encode.XML; + +exports.encodeHTML4 = +exports.encodeHTML5 = +exports.encodeHTML = encode.HTML; + +exports.decodeXML = +exports.decodeXMLStrict = decode.XML; + +exports.decodeHTML4 = +exports.decodeHTML5 = +exports.decodeHTML = decode.HTML; + +exports.decodeHTML4Strict = +exports.decodeHTML5Strict = +exports.decodeHTMLStrict = decode.HTMLStrict; diff --git a/node_modules/entities/lib/decode.js b/node_modules/entities/lib/decode.js new file mode 100644 index 0000000..5e48bdb --- /dev/null +++ b/node_modules/entities/lib/decode.js @@ -0,0 +1,72 @@ +var entityMap = require("../maps/entities.json"), + legacyMap = require("../maps/legacy.json"), + xmlMap = require("../maps/xml.json"), + decodeCodePoint = require("./decode_codepoint.js"); + +var decodeXMLStrict = getStrictDecoder(xmlMap), + decodeHTMLStrict = getStrictDecoder(entityMap); + +function getStrictDecoder(map){ + var keys = Object.keys(map).join("|"), + replace = getReplacer(map); + + keys += "|#[xX][\\da-fA-F]+|#\\d+"; + + var re = new RegExp("&(?:" + keys + ");", "g"); + + return function(str){ + return String(str).replace(re, replace); + }; +} + +var decodeHTML = (function(){ + var legacy = Object.keys(legacyMap) + .sort(sorter); + + var keys = Object.keys(entityMap) + .sort(sorter); + + for(var i = 0, j = 0; i < keys.length; i++){ + if(legacy[j] === keys[i]){ + keys[i] += ";?"; + j++; + } else { + keys[i] += ";"; + } + } + + var re = new RegExp("&(?:" + keys.join("|") + "|#[xX][\\da-fA-F]+;?|#\\d+;?)", "g"), + replace = getReplacer(entityMap); + + function replacer(str){ + if(str.substr(-1) !== ";") str += ";"; + return replace(str); + } + + //TODO consider creating a merged map + return function(str){ + return String(str).replace(re, replacer); + }; +}()); + +function sorter(a, b){ + return a < b ? 1 : -1; +} + +function getReplacer(map){ + return function replace(str){ + if(str.charAt(1) === "#"){ + if(str.charAt(2) === "X" || str.charAt(2) === "x"){ + return decodeCodePoint(parseInt(str.substr(3), 16)); + } + return decodeCodePoint(parseInt(str.substr(2), 10)); + } + return map[str.slice(1, -1)]; + }; +} + +module.exports = { + XML: decodeXMLStrict, + HTML: decodeHTML, + HTMLStrict: decodeHTMLStrict +}; \ No newline at end of file diff --git a/node_modules/entities/lib/decode_codepoint.js b/node_modules/entities/lib/decode_codepoint.js new file mode 100644 index 0000000..730d5bf --- /dev/null +++ b/node_modules/entities/lib/decode_codepoint.js @@ -0,0 +1,26 @@ +var decodeMap = require("../maps/decode.json"); + +module.exports = decodeCodePoint; + +// modified version of https://github.com/mathiasbynens/he/blob/master/src/he.js#L94-L119 +function decodeCodePoint(codePoint){ + + if((codePoint >= 0xD800 && codePoint <= 0xDFFF) || codePoint > 0x10FFFF){ + return "\uFFFD"; + } + + if(codePoint in decodeMap){ + codePoint = decodeMap[codePoint]; + } + + var output = ""; + + if(codePoint > 0xFFFF){ + codePoint -= 0x10000; + output += String.fromCharCode(codePoint >>> 10 & 0x3FF | 0xD800); + codePoint = 0xDC00 | codePoint & 0x3FF; + } + + output += String.fromCharCode(codePoint); + return output; +} diff --git a/node_modules/entities/lib/encode.js b/node_modules/entities/lib/encode.js new file mode 100644 index 0000000..04f1d2a --- /dev/null +++ b/node_modules/entities/lib/encode.js @@ -0,0 +1,48 @@ +var inverseXML = getInverseObj(require("../maps/xml.json")), + xmlReplacer = getInverseReplacer(inverseXML); + +exports.XML = getInverse(inverseXML, xmlReplacer); + +var inverseHTML = getInverseObj(require("../maps/entities.json")), + htmlReplacer = getInverseReplacer(inverseHTML); + +exports.HTML = getInverse(inverseHTML, htmlReplacer); + +function getInverseObj(obj){ + return Object.keys(obj).sort().reduce(function(inverse, name){ + inverse[obj[name]] = "&" + name + ";"; + return inverse; + }, {}); +} + +function getInverseReplacer(inverse){ + return new RegExp("\\" + Object.keys(inverse).sort().join("|\\"), "g"); +} + +var re_nonASCII = /[^\0-\x7F]/g, + re_astralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; + +function nonUTF8Replacer(c){ + return "&#x" + c.charCodeAt(0).toString(16).toUpperCase() + ";"; +} + +function astralReplacer(c){ + // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae + var high = c.charCodeAt(0); + var low = c.charCodeAt(1); + var codePoint = (high - 0xD800) * 0x400 + low - 0xDC00 + 0x10000; + return "&#x" + codePoint.toString(16).toUpperCase() + ";"; +} + +function getInverse(inverse, re){ + function func(name){ + return inverse[name]; + } + + return function(data){ + return data + .replace(re, func) + .replace(re_astralSymbols, astralReplacer) + .replace(re_nonASCII, nonUTF8Replacer); + }; +} \ No newline at end of file diff --git a/node_modules/entities/maps/decode.json b/node_modules/entities/maps/decode.json new file mode 100644 index 0000000..44e5d0b --- /dev/null +++ b/node_modules/entities/maps/decode.json @@ -0,0 +1 @@ +{"0":65533,"128":8364,"130":8218,"131":402,"132":8222,"133":8230,"134":8224,"135":8225,"136":710,"137":8240,"138":352,"139":8249,"140":338,"142":381,"145":8216,"146":8217,"147":8220,"148":8221,"149":8226,"150":8211,"151":8212,"152":732,"153":8482,"154":353,"155":8250,"156":339,"158":382,"159":376} \ No newline at end of file diff --git a/node_modules/entities/maps/entities.json b/node_modules/entities/maps/entities.json new file mode 100644 index 0000000..7ccfcd8 --- /dev/null +++ b/node_modules/entities/maps/entities.json @@ -0,0 +1 @@ +{"Aacute":"\u00C1","aacute":"\u00E1","Abreve":"\u0102","abreve":"\u0103","ac":"\u223E","acd":"\u223F","acE":"\u223E\u0333","Acirc":"\u00C2","acirc":"\u00E2","acute":"\u00B4","Acy":"\u0410","acy":"\u0430","AElig":"\u00C6","aelig":"\u00E6","af":"\u2061","Afr":"\uD835\uDD04","afr":"\uD835\uDD1E","Agrave":"\u00C0","agrave":"\u00E0","alefsym":"\u2135","aleph":"\u2135","Alpha":"\u0391","alpha":"\u03B1","Amacr":"\u0100","amacr":"\u0101","amalg":"\u2A3F","amp":"&","AMP":"&","andand":"\u2A55","And":"\u2A53","and":"\u2227","andd":"\u2A5C","andslope":"\u2A58","andv":"\u2A5A","ang":"\u2220","ange":"\u29A4","angle":"\u2220","angmsdaa":"\u29A8","angmsdab":"\u29A9","angmsdac":"\u29AA","angmsdad":"\u29AB","angmsdae":"\u29AC","angmsdaf":"\u29AD","angmsdag":"\u29AE","angmsdah":"\u29AF","angmsd":"\u2221","angrt":"\u221F","angrtvb":"\u22BE","angrtvbd":"\u299D","angsph":"\u2222","angst":"\u00C5","angzarr":"\u237C","Aogon":"\u0104","aogon":"\u0105","Aopf":"\uD835\uDD38","aopf":"\uD835\uDD52","apacir":"\u2A6F","ap":"\u2248","apE":"\u2A70","ape":"\u224A","apid":"\u224B","apos":"'","ApplyFunction":"\u2061","approx":"\u2248","approxeq":"\u224A","Aring":"\u00C5","aring":"\u00E5","Ascr":"\uD835\uDC9C","ascr":"\uD835\uDCB6","Assign":"\u2254","ast":"*","asymp":"\u2248","asympeq":"\u224D","Atilde":"\u00C3","atilde":"\u00E3","Auml":"\u00C4","auml":"\u00E4","awconint":"\u2233","awint":"\u2A11","backcong":"\u224C","backepsilon":"\u03F6","backprime":"\u2035","backsim":"\u223D","backsimeq":"\u22CD","Backslash":"\u2216","Barv":"\u2AE7","barvee":"\u22BD","barwed":"\u2305","Barwed":"\u2306","barwedge":"\u2305","bbrk":"\u23B5","bbrktbrk":"\u23B6","bcong":"\u224C","Bcy":"\u0411","bcy":"\u0431","bdquo":"\u201E","becaus":"\u2235","because":"\u2235","Because":"\u2235","bemptyv":"\u29B0","bepsi":"\u03F6","bernou":"\u212C","Bernoullis":"\u212C","Beta":"\u0392","beta":"\u03B2","beth":"\u2136","between":"\u226C","Bfr":"\uD835\uDD05","bfr":"\uD835\uDD1F","bigcap":"\u22C2","bigcirc":"\u25EF","bigcup":"\u22C3","bigodot":"\u2A00","bigoplus":"\u2A01","bigotimes":"\u2A02","bigsqcup":"\u2A06","bigstar":"\u2605","bigtriangledown":"\u25BD","bigtriangleup":"\u25B3","biguplus":"\u2A04","bigvee":"\u22C1","bigwedge":"\u22C0","bkarow":"\u290D","blacklozenge":"\u29EB","blacksquare":"\u25AA","blacktriangle":"\u25B4","blacktriangledown":"\u25BE","blacktriangleleft":"\u25C2","blacktriangleright":"\u25B8","blank":"\u2423","blk12":"\u2592","blk14":"\u2591","blk34":"\u2593","block":"\u2588","bne":"=\u20E5","bnequiv":"\u2261\u20E5","bNot":"\u2AED","bnot":"\u2310","Bopf":"\uD835\uDD39","bopf":"\uD835\uDD53","bot":"\u22A5","bottom":"\u22A5","bowtie":"\u22C8","boxbox":"\u29C9","boxdl":"\u2510","boxdL":"\u2555","boxDl":"\u2556","boxDL":"\u2557","boxdr":"\u250C","boxdR":"\u2552","boxDr":"\u2553","boxDR":"\u2554","boxh":"\u2500","boxH":"\u2550","boxhd":"\u252C","boxHd":"\u2564","boxhD":"\u2565","boxHD":"\u2566","boxhu":"\u2534","boxHu":"\u2567","boxhU":"\u2568","boxHU":"\u2569","boxminus":"\u229F","boxplus":"\u229E","boxtimes":"\u22A0","boxul":"\u2518","boxuL":"\u255B","boxUl":"\u255C","boxUL":"\u255D","boxur":"\u2514","boxuR":"\u2558","boxUr":"\u2559","boxUR":"\u255A","boxv":"\u2502","boxV":"\u2551","boxvh":"\u253C","boxvH":"\u256A","boxVh":"\u256B","boxVH":"\u256C","boxvl":"\u2524","boxvL":"\u2561","boxVl":"\u2562","boxVL":"\u2563","boxvr":"\u251C","boxvR":"\u255E","boxVr":"\u255F","boxVR":"\u2560","bprime":"\u2035","breve":"\u02D8","Breve":"\u02D8","brvbar":"\u00A6","bscr":"\uD835\uDCB7","Bscr":"\u212C","bsemi":"\u204F","bsim":"\u223D","bsime":"\u22CD","bsolb":"\u29C5","bsol":"\\","bsolhsub":"\u27C8","bull":"\u2022","bullet":"\u2022","bump":"\u224E","bumpE":"\u2AAE","bumpe":"\u224F","Bumpeq":"\u224E","bumpeq":"\u224F","Cacute":"\u0106","cacute":"\u0107","capand":"\u2A44","capbrcup":"\u2A49","capcap":"\u2A4B","cap":"\u2229","Cap":"\u22D2","capcup":"\u2A47","capdot":"\u2A40","CapitalDifferentialD":"\u2145","caps":"\u2229\uFE00","caret":"\u2041","caron":"\u02C7","Cayleys":"\u212D","ccaps":"\u2A4D","Ccaron":"\u010C","ccaron":"\u010D","Ccedil":"\u00C7","ccedil":"\u00E7","Ccirc":"\u0108","ccirc":"\u0109","Cconint":"\u2230","ccups":"\u2A4C","ccupssm":"\u2A50","Cdot":"\u010A","cdot":"\u010B","cedil":"\u00B8","Cedilla":"\u00B8","cemptyv":"\u29B2","cent":"\u00A2","centerdot":"\u00B7","CenterDot":"\u00B7","cfr":"\uD835\uDD20","Cfr":"\u212D","CHcy":"\u0427","chcy":"\u0447","check":"\u2713","checkmark":"\u2713","Chi":"\u03A7","chi":"\u03C7","circ":"\u02C6","circeq":"\u2257","circlearrowleft":"\u21BA","circlearrowright":"\u21BB","circledast":"\u229B","circledcirc":"\u229A","circleddash":"\u229D","CircleDot":"\u2299","circledR":"\u00AE","circledS":"\u24C8","CircleMinus":"\u2296","CirclePlus":"\u2295","CircleTimes":"\u2297","cir":"\u25CB","cirE":"\u29C3","cire":"\u2257","cirfnint":"\u2A10","cirmid":"\u2AEF","cirscir":"\u29C2","ClockwiseContourIntegral":"\u2232","CloseCurlyDoubleQuote":"\u201D","CloseCurlyQuote":"\u2019","clubs":"\u2663","clubsuit":"\u2663","colon":":","Colon":"\u2237","Colone":"\u2A74","colone":"\u2254","coloneq":"\u2254","comma":",","commat":"@","comp":"\u2201","compfn":"\u2218","complement":"\u2201","complexes":"\u2102","cong":"\u2245","congdot":"\u2A6D","Congruent":"\u2261","conint":"\u222E","Conint":"\u222F","ContourIntegral":"\u222E","copf":"\uD835\uDD54","Copf":"\u2102","coprod":"\u2210","Coproduct":"\u2210","copy":"\u00A9","COPY":"\u00A9","copysr":"\u2117","CounterClockwiseContourIntegral":"\u2233","crarr":"\u21B5","cross":"\u2717","Cross":"\u2A2F","Cscr":"\uD835\uDC9E","cscr":"\uD835\uDCB8","csub":"\u2ACF","csube":"\u2AD1","csup":"\u2AD0","csupe":"\u2AD2","ctdot":"\u22EF","cudarrl":"\u2938","cudarrr":"\u2935","cuepr":"\u22DE","cuesc":"\u22DF","cularr":"\u21B6","cularrp":"\u293D","cupbrcap":"\u2A48","cupcap":"\u2A46","CupCap":"\u224D","cup":"\u222A","Cup":"\u22D3","cupcup":"\u2A4A","cupdot":"\u228D","cupor":"\u2A45","cups":"\u222A\uFE00","curarr":"\u21B7","curarrm":"\u293C","curlyeqprec":"\u22DE","curlyeqsucc":"\u22DF","curlyvee":"\u22CE","curlywedge":"\u22CF","curren":"\u00A4","curvearrowleft":"\u21B6","curvearrowright":"\u21B7","cuvee":"\u22CE","cuwed":"\u22CF","cwconint":"\u2232","cwint":"\u2231","cylcty":"\u232D","dagger":"\u2020","Dagger":"\u2021","daleth":"\u2138","darr":"\u2193","Darr":"\u21A1","dArr":"\u21D3","dash":"\u2010","Dashv":"\u2AE4","dashv":"\u22A3","dbkarow":"\u290F","dblac":"\u02DD","Dcaron":"\u010E","dcaron":"\u010F","Dcy":"\u0414","dcy":"\u0434","ddagger":"\u2021","ddarr":"\u21CA","DD":"\u2145","dd":"\u2146","DDotrahd":"\u2911","ddotseq":"\u2A77","deg":"\u00B0","Del":"\u2207","Delta":"\u0394","delta":"\u03B4","demptyv":"\u29B1","dfisht":"\u297F","Dfr":"\uD835\uDD07","dfr":"\uD835\uDD21","dHar":"\u2965","dharl":"\u21C3","dharr":"\u21C2","DiacriticalAcute":"\u00B4","DiacriticalDot":"\u02D9","DiacriticalDoubleAcute":"\u02DD","DiacriticalGrave":"`","DiacriticalTilde":"\u02DC","diam":"\u22C4","diamond":"\u22C4","Diamond":"\u22C4","diamondsuit":"\u2666","diams":"\u2666","die":"\u00A8","DifferentialD":"\u2146","digamma":"\u03DD","disin":"\u22F2","div":"\u00F7","divide":"\u00F7","divideontimes":"\u22C7","divonx":"\u22C7","DJcy":"\u0402","djcy":"\u0452","dlcorn":"\u231E","dlcrop":"\u230D","dollar":"$","Dopf":"\uD835\uDD3B","dopf":"\uD835\uDD55","Dot":"\u00A8","dot":"\u02D9","DotDot":"\u20DC","doteq":"\u2250","doteqdot":"\u2251","DotEqual":"\u2250","dotminus":"\u2238","dotplus":"\u2214","dotsquare":"\u22A1","doublebarwedge":"\u2306","DoubleContourIntegral":"\u222F","DoubleDot":"\u00A8","DoubleDownArrow":"\u21D3","DoubleLeftArrow":"\u21D0","DoubleLeftRightArrow":"\u21D4","DoubleLeftTee":"\u2AE4","DoubleLongLeftArrow":"\u27F8","DoubleLongLeftRightArrow":"\u27FA","DoubleLongRightArrow":"\u27F9","DoubleRightArrow":"\u21D2","DoubleRightTee":"\u22A8","DoubleUpArrow":"\u21D1","DoubleUpDownArrow":"\u21D5","DoubleVerticalBar":"\u2225","DownArrowBar":"\u2913","downarrow":"\u2193","DownArrow":"\u2193","Downarrow":"\u21D3","DownArrowUpArrow":"\u21F5","DownBreve":"\u0311","downdownarrows":"\u21CA","downharpoonleft":"\u21C3","downharpoonright":"\u21C2","DownLeftRightVector":"\u2950","DownLeftTeeVector":"\u295E","DownLeftVectorBar":"\u2956","DownLeftVector":"\u21BD","DownRightTeeVector":"\u295F","DownRightVectorBar":"\u2957","DownRightVector":"\u21C1","DownTeeArrow":"\u21A7","DownTee":"\u22A4","drbkarow":"\u2910","drcorn":"\u231F","drcrop":"\u230C","Dscr":"\uD835\uDC9F","dscr":"\uD835\uDCB9","DScy":"\u0405","dscy":"\u0455","dsol":"\u29F6","Dstrok":"\u0110","dstrok":"\u0111","dtdot":"\u22F1","dtri":"\u25BF","dtrif":"\u25BE","duarr":"\u21F5","duhar":"\u296F","dwangle":"\u29A6","DZcy":"\u040F","dzcy":"\u045F","dzigrarr":"\u27FF","Eacute":"\u00C9","eacute":"\u00E9","easter":"\u2A6E","Ecaron":"\u011A","ecaron":"\u011B","Ecirc":"\u00CA","ecirc":"\u00EA","ecir":"\u2256","ecolon":"\u2255","Ecy":"\u042D","ecy":"\u044D","eDDot":"\u2A77","Edot":"\u0116","edot":"\u0117","eDot":"\u2251","ee":"\u2147","efDot":"\u2252","Efr":"\uD835\uDD08","efr":"\uD835\uDD22","eg":"\u2A9A","Egrave":"\u00C8","egrave":"\u00E8","egs":"\u2A96","egsdot":"\u2A98","el":"\u2A99","Element":"\u2208","elinters":"\u23E7","ell":"\u2113","els":"\u2A95","elsdot":"\u2A97","Emacr":"\u0112","emacr":"\u0113","empty":"\u2205","emptyset":"\u2205","EmptySmallSquare":"\u25FB","emptyv":"\u2205","EmptyVerySmallSquare":"\u25AB","emsp13":"\u2004","emsp14":"\u2005","emsp":"\u2003","ENG":"\u014A","eng":"\u014B","ensp":"\u2002","Eogon":"\u0118","eogon":"\u0119","Eopf":"\uD835\uDD3C","eopf":"\uD835\uDD56","epar":"\u22D5","eparsl":"\u29E3","eplus":"\u2A71","epsi":"\u03B5","Epsilon":"\u0395","epsilon":"\u03B5","epsiv":"\u03F5","eqcirc":"\u2256","eqcolon":"\u2255","eqsim":"\u2242","eqslantgtr":"\u2A96","eqslantless":"\u2A95","Equal":"\u2A75","equals":"=","EqualTilde":"\u2242","equest":"\u225F","Equilibrium":"\u21CC","equiv":"\u2261","equivDD":"\u2A78","eqvparsl":"\u29E5","erarr":"\u2971","erDot":"\u2253","escr":"\u212F","Escr":"\u2130","esdot":"\u2250","Esim":"\u2A73","esim":"\u2242","Eta":"\u0397","eta":"\u03B7","ETH":"\u00D0","eth":"\u00F0","Euml":"\u00CB","euml":"\u00EB","euro":"\u20AC","excl":"!","exist":"\u2203","Exists":"\u2203","expectation":"\u2130","exponentiale":"\u2147","ExponentialE":"\u2147","fallingdotseq":"\u2252","Fcy":"\u0424","fcy":"\u0444","female":"\u2640","ffilig":"\uFB03","fflig":"\uFB00","ffllig":"\uFB04","Ffr":"\uD835\uDD09","ffr":"\uD835\uDD23","filig":"\uFB01","FilledSmallSquare":"\u25FC","FilledVerySmallSquare":"\u25AA","fjlig":"fj","flat":"\u266D","fllig":"\uFB02","fltns":"\u25B1","fnof":"\u0192","Fopf":"\uD835\uDD3D","fopf":"\uD835\uDD57","forall":"\u2200","ForAll":"\u2200","fork":"\u22D4","forkv":"\u2AD9","Fouriertrf":"\u2131","fpartint":"\u2A0D","frac12":"\u00BD","frac13":"\u2153","frac14":"\u00BC","frac15":"\u2155","frac16":"\u2159","frac18":"\u215B","frac23":"\u2154","frac25":"\u2156","frac34":"\u00BE","frac35":"\u2157","frac38":"\u215C","frac45":"\u2158","frac56":"\u215A","frac58":"\u215D","frac78":"\u215E","frasl":"\u2044","frown":"\u2322","fscr":"\uD835\uDCBB","Fscr":"\u2131","gacute":"\u01F5","Gamma":"\u0393","gamma":"\u03B3","Gammad":"\u03DC","gammad":"\u03DD","gap":"\u2A86","Gbreve":"\u011E","gbreve":"\u011F","Gcedil":"\u0122","Gcirc":"\u011C","gcirc":"\u011D","Gcy":"\u0413","gcy":"\u0433","Gdot":"\u0120","gdot":"\u0121","ge":"\u2265","gE":"\u2267","gEl":"\u2A8C","gel":"\u22DB","geq":"\u2265","geqq":"\u2267","geqslant":"\u2A7E","gescc":"\u2AA9","ges":"\u2A7E","gesdot":"\u2A80","gesdoto":"\u2A82","gesdotol":"\u2A84","gesl":"\u22DB\uFE00","gesles":"\u2A94","Gfr":"\uD835\uDD0A","gfr":"\uD835\uDD24","gg":"\u226B","Gg":"\u22D9","ggg":"\u22D9","gimel":"\u2137","GJcy":"\u0403","gjcy":"\u0453","gla":"\u2AA5","gl":"\u2277","glE":"\u2A92","glj":"\u2AA4","gnap":"\u2A8A","gnapprox":"\u2A8A","gne":"\u2A88","gnE":"\u2269","gneq":"\u2A88","gneqq":"\u2269","gnsim":"\u22E7","Gopf":"\uD835\uDD3E","gopf":"\uD835\uDD58","grave":"`","GreaterEqual":"\u2265","GreaterEqualLess":"\u22DB","GreaterFullEqual":"\u2267","GreaterGreater":"\u2AA2","GreaterLess":"\u2277","GreaterSlantEqual":"\u2A7E","GreaterTilde":"\u2273","Gscr":"\uD835\uDCA2","gscr":"\u210A","gsim":"\u2273","gsime":"\u2A8E","gsiml":"\u2A90","gtcc":"\u2AA7","gtcir":"\u2A7A","gt":">","GT":">","Gt":"\u226B","gtdot":"\u22D7","gtlPar":"\u2995","gtquest":"\u2A7C","gtrapprox":"\u2A86","gtrarr":"\u2978","gtrdot":"\u22D7","gtreqless":"\u22DB","gtreqqless":"\u2A8C","gtrless":"\u2277","gtrsim":"\u2273","gvertneqq":"\u2269\uFE00","gvnE":"\u2269\uFE00","Hacek":"\u02C7","hairsp":"\u200A","half":"\u00BD","hamilt":"\u210B","HARDcy":"\u042A","hardcy":"\u044A","harrcir":"\u2948","harr":"\u2194","hArr":"\u21D4","harrw":"\u21AD","Hat":"^","hbar":"\u210F","Hcirc":"\u0124","hcirc":"\u0125","hearts":"\u2665","heartsuit":"\u2665","hellip":"\u2026","hercon":"\u22B9","hfr":"\uD835\uDD25","Hfr":"\u210C","HilbertSpace":"\u210B","hksearow":"\u2925","hkswarow":"\u2926","hoarr":"\u21FF","homtht":"\u223B","hookleftarrow":"\u21A9","hookrightarrow":"\u21AA","hopf":"\uD835\uDD59","Hopf":"\u210D","horbar":"\u2015","HorizontalLine":"\u2500","hscr":"\uD835\uDCBD","Hscr":"\u210B","hslash":"\u210F","Hstrok":"\u0126","hstrok":"\u0127","HumpDownHump":"\u224E","HumpEqual":"\u224F","hybull":"\u2043","hyphen":"\u2010","Iacute":"\u00CD","iacute":"\u00ED","ic":"\u2063","Icirc":"\u00CE","icirc":"\u00EE","Icy":"\u0418","icy":"\u0438","Idot":"\u0130","IEcy":"\u0415","iecy":"\u0435","iexcl":"\u00A1","iff":"\u21D4","ifr":"\uD835\uDD26","Ifr":"\u2111","Igrave":"\u00CC","igrave":"\u00EC","ii":"\u2148","iiiint":"\u2A0C","iiint":"\u222D","iinfin":"\u29DC","iiota":"\u2129","IJlig":"\u0132","ijlig":"\u0133","Imacr":"\u012A","imacr":"\u012B","image":"\u2111","ImaginaryI":"\u2148","imagline":"\u2110","imagpart":"\u2111","imath":"\u0131","Im":"\u2111","imof":"\u22B7","imped":"\u01B5","Implies":"\u21D2","incare":"\u2105","in":"\u2208","infin":"\u221E","infintie":"\u29DD","inodot":"\u0131","intcal":"\u22BA","int":"\u222B","Int":"\u222C","integers":"\u2124","Integral":"\u222B","intercal":"\u22BA","Intersection":"\u22C2","intlarhk":"\u2A17","intprod":"\u2A3C","InvisibleComma":"\u2063","InvisibleTimes":"\u2062","IOcy":"\u0401","iocy":"\u0451","Iogon":"\u012E","iogon":"\u012F","Iopf":"\uD835\uDD40","iopf":"\uD835\uDD5A","Iota":"\u0399","iota":"\u03B9","iprod":"\u2A3C","iquest":"\u00BF","iscr":"\uD835\uDCBE","Iscr":"\u2110","isin":"\u2208","isindot":"\u22F5","isinE":"\u22F9","isins":"\u22F4","isinsv":"\u22F3","isinv":"\u2208","it":"\u2062","Itilde":"\u0128","itilde":"\u0129","Iukcy":"\u0406","iukcy":"\u0456","Iuml":"\u00CF","iuml":"\u00EF","Jcirc":"\u0134","jcirc":"\u0135","Jcy":"\u0419","jcy":"\u0439","Jfr":"\uD835\uDD0D","jfr":"\uD835\uDD27","jmath":"\u0237","Jopf":"\uD835\uDD41","jopf":"\uD835\uDD5B","Jscr":"\uD835\uDCA5","jscr":"\uD835\uDCBF","Jsercy":"\u0408","jsercy":"\u0458","Jukcy":"\u0404","jukcy":"\u0454","Kappa":"\u039A","kappa":"\u03BA","kappav":"\u03F0","Kcedil":"\u0136","kcedil":"\u0137","Kcy":"\u041A","kcy":"\u043A","Kfr":"\uD835\uDD0E","kfr":"\uD835\uDD28","kgreen":"\u0138","KHcy":"\u0425","khcy":"\u0445","KJcy":"\u040C","kjcy":"\u045C","Kopf":"\uD835\uDD42","kopf":"\uD835\uDD5C","Kscr":"\uD835\uDCA6","kscr":"\uD835\uDCC0","lAarr":"\u21DA","Lacute":"\u0139","lacute":"\u013A","laemptyv":"\u29B4","lagran":"\u2112","Lambda":"\u039B","lambda":"\u03BB","lang":"\u27E8","Lang":"\u27EA","langd":"\u2991","langle":"\u27E8","lap":"\u2A85","Laplacetrf":"\u2112","laquo":"\u00AB","larrb":"\u21E4","larrbfs":"\u291F","larr":"\u2190","Larr":"\u219E","lArr":"\u21D0","larrfs":"\u291D","larrhk":"\u21A9","larrlp":"\u21AB","larrpl":"\u2939","larrsim":"\u2973","larrtl":"\u21A2","latail":"\u2919","lAtail":"\u291B","lat":"\u2AAB","late":"\u2AAD","lates":"\u2AAD\uFE00","lbarr":"\u290C","lBarr":"\u290E","lbbrk":"\u2772","lbrace":"{","lbrack":"[","lbrke":"\u298B","lbrksld":"\u298F","lbrkslu":"\u298D","Lcaron":"\u013D","lcaron":"\u013E","Lcedil":"\u013B","lcedil":"\u013C","lceil":"\u2308","lcub":"{","Lcy":"\u041B","lcy":"\u043B","ldca":"\u2936","ldquo":"\u201C","ldquor":"\u201E","ldrdhar":"\u2967","ldrushar":"\u294B","ldsh":"\u21B2","le":"\u2264","lE":"\u2266","LeftAngleBracket":"\u27E8","LeftArrowBar":"\u21E4","leftarrow":"\u2190","LeftArrow":"\u2190","Leftarrow":"\u21D0","LeftArrowRightArrow":"\u21C6","leftarrowtail":"\u21A2","LeftCeiling":"\u2308","LeftDoubleBracket":"\u27E6","LeftDownTeeVector":"\u2961","LeftDownVectorBar":"\u2959","LeftDownVector":"\u21C3","LeftFloor":"\u230A","leftharpoondown":"\u21BD","leftharpoonup":"\u21BC","leftleftarrows":"\u21C7","leftrightarrow":"\u2194","LeftRightArrow":"\u2194","Leftrightarrow":"\u21D4","leftrightarrows":"\u21C6","leftrightharpoons":"\u21CB","leftrightsquigarrow":"\u21AD","LeftRightVector":"\u294E","LeftTeeArrow":"\u21A4","LeftTee":"\u22A3","LeftTeeVector":"\u295A","leftthreetimes":"\u22CB","LeftTriangleBar":"\u29CF","LeftTriangle":"\u22B2","LeftTriangleEqual":"\u22B4","LeftUpDownVector":"\u2951","LeftUpTeeVector":"\u2960","LeftUpVectorBar":"\u2958","LeftUpVector":"\u21BF","LeftVectorBar":"\u2952","LeftVector":"\u21BC","lEg":"\u2A8B","leg":"\u22DA","leq":"\u2264","leqq":"\u2266","leqslant":"\u2A7D","lescc":"\u2AA8","les":"\u2A7D","lesdot":"\u2A7F","lesdoto":"\u2A81","lesdotor":"\u2A83","lesg":"\u22DA\uFE00","lesges":"\u2A93","lessapprox":"\u2A85","lessdot":"\u22D6","lesseqgtr":"\u22DA","lesseqqgtr":"\u2A8B","LessEqualGreater":"\u22DA","LessFullEqual":"\u2266","LessGreater":"\u2276","lessgtr":"\u2276","LessLess":"\u2AA1","lesssim":"\u2272","LessSlantEqual":"\u2A7D","LessTilde":"\u2272","lfisht":"\u297C","lfloor":"\u230A","Lfr":"\uD835\uDD0F","lfr":"\uD835\uDD29","lg":"\u2276","lgE":"\u2A91","lHar":"\u2962","lhard":"\u21BD","lharu":"\u21BC","lharul":"\u296A","lhblk":"\u2584","LJcy":"\u0409","ljcy":"\u0459","llarr":"\u21C7","ll":"\u226A","Ll":"\u22D8","llcorner":"\u231E","Lleftarrow":"\u21DA","llhard":"\u296B","lltri":"\u25FA","Lmidot":"\u013F","lmidot":"\u0140","lmoustache":"\u23B0","lmoust":"\u23B0","lnap":"\u2A89","lnapprox":"\u2A89","lne":"\u2A87","lnE":"\u2268","lneq":"\u2A87","lneqq":"\u2268","lnsim":"\u22E6","loang":"\u27EC","loarr":"\u21FD","lobrk":"\u27E6","longleftarrow":"\u27F5","LongLeftArrow":"\u27F5","Longleftarrow":"\u27F8","longleftrightarrow":"\u27F7","LongLeftRightArrow":"\u27F7","Longleftrightarrow":"\u27FA","longmapsto":"\u27FC","longrightarrow":"\u27F6","LongRightArrow":"\u27F6","Longrightarrow":"\u27F9","looparrowleft":"\u21AB","looparrowright":"\u21AC","lopar":"\u2985","Lopf":"\uD835\uDD43","lopf":"\uD835\uDD5D","loplus":"\u2A2D","lotimes":"\u2A34","lowast":"\u2217","lowbar":"_","LowerLeftArrow":"\u2199","LowerRightArrow":"\u2198","loz":"\u25CA","lozenge":"\u25CA","lozf":"\u29EB","lpar":"(","lparlt":"\u2993","lrarr":"\u21C6","lrcorner":"\u231F","lrhar":"\u21CB","lrhard":"\u296D","lrm":"\u200E","lrtri":"\u22BF","lsaquo":"\u2039","lscr":"\uD835\uDCC1","Lscr":"\u2112","lsh":"\u21B0","Lsh":"\u21B0","lsim":"\u2272","lsime":"\u2A8D","lsimg":"\u2A8F","lsqb":"[","lsquo":"\u2018","lsquor":"\u201A","Lstrok":"\u0141","lstrok":"\u0142","ltcc":"\u2AA6","ltcir":"\u2A79","lt":"<","LT":"<","Lt":"\u226A","ltdot":"\u22D6","lthree":"\u22CB","ltimes":"\u22C9","ltlarr":"\u2976","ltquest":"\u2A7B","ltri":"\u25C3","ltrie":"\u22B4","ltrif":"\u25C2","ltrPar":"\u2996","lurdshar":"\u294A","luruhar":"\u2966","lvertneqq":"\u2268\uFE00","lvnE":"\u2268\uFE00","macr":"\u00AF","male":"\u2642","malt":"\u2720","maltese":"\u2720","Map":"\u2905","map":"\u21A6","mapsto":"\u21A6","mapstodown":"\u21A7","mapstoleft":"\u21A4","mapstoup":"\u21A5","marker":"\u25AE","mcomma":"\u2A29","Mcy":"\u041C","mcy":"\u043C","mdash":"\u2014","mDDot":"\u223A","measuredangle":"\u2221","MediumSpace":"\u205F","Mellintrf":"\u2133","Mfr":"\uD835\uDD10","mfr":"\uD835\uDD2A","mho":"\u2127","micro":"\u00B5","midast":"*","midcir":"\u2AF0","mid":"\u2223","middot":"\u00B7","minusb":"\u229F","minus":"\u2212","minusd":"\u2238","minusdu":"\u2A2A","MinusPlus":"\u2213","mlcp":"\u2ADB","mldr":"\u2026","mnplus":"\u2213","models":"\u22A7","Mopf":"\uD835\uDD44","mopf":"\uD835\uDD5E","mp":"\u2213","mscr":"\uD835\uDCC2","Mscr":"\u2133","mstpos":"\u223E","Mu":"\u039C","mu":"\u03BC","multimap":"\u22B8","mumap":"\u22B8","nabla":"\u2207","Nacute":"\u0143","nacute":"\u0144","nang":"\u2220\u20D2","nap":"\u2249","napE":"\u2A70\u0338","napid":"\u224B\u0338","napos":"\u0149","napprox":"\u2249","natural":"\u266E","naturals":"\u2115","natur":"\u266E","nbsp":"\u00A0","nbump":"\u224E\u0338","nbumpe":"\u224F\u0338","ncap":"\u2A43","Ncaron":"\u0147","ncaron":"\u0148","Ncedil":"\u0145","ncedil":"\u0146","ncong":"\u2247","ncongdot":"\u2A6D\u0338","ncup":"\u2A42","Ncy":"\u041D","ncy":"\u043D","ndash":"\u2013","nearhk":"\u2924","nearr":"\u2197","neArr":"\u21D7","nearrow":"\u2197","ne":"\u2260","nedot":"\u2250\u0338","NegativeMediumSpace":"\u200B","NegativeThickSpace":"\u200B","NegativeThinSpace":"\u200B","NegativeVeryThinSpace":"\u200B","nequiv":"\u2262","nesear":"\u2928","nesim":"\u2242\u0338","NestedGreaterGreater":"\u226B","NestedLessLess":"\u226A","NewLine":"\n","nexist":"\u2204","nexists":"\u2204","Nfr":"\uD835\uDD11","nfr":"\uD835\uDD2B","ngE":"\u2267\u0338","nge":"\u2271","ngeq":"\u2271","ngeqq":"\u2267\u0338","ngeqslant":"\u2A7E\u0338","nges":"\u2A7E\u0338","nGg":"\u22D9\u0338","ngsim":"\u2275","nGt":"\u226B\u20D2","ngt":"\u226F","ngtr":"\u226F","nGtv":"\u226B\u0338","nharr":"\u21AE","nhArr":"\u21CE","nhpar":"\u2AF2","ni":"\u220B","nis":"\u22FC","nisd":"\u22FA","niv":"\u220B","NJcy":"\u040A","njcy":"\u045A","nlarr":"\u219A","nlArr":"\u21CD","nldr":"\u2025","nlE":"\u2266\u0338","nle":"\u2270","nleftarrow":"\u219A","nLeftarrow":"\u21CD","nleftrightarrow":"\u21AE","nLeftrightarrow":"\u21CE","nleq":"\u2270","nleqq":"\u2266\u0338","nleqslant":"\u2A7D\u0338","nles":"\u2A7D\u0338","nless":"\u226E","nLl":"\u22D8\u0338","nlsim":"\u2274","nLt":"\u226A\u20D2","nlt":"\u226E","nltri":"\u22EA","nltrie":"\u22EC","nLtv":"\u226A\u0338","nmid":"\u2224","NoBreak":"\u2060","NonBreakingSpace":"\u00A0","nopf":"\uD835\uDD5F","Nopf":"\u2115","Not":"\u2AEC","not":"\u00AC","NotCongruent":"\u2262","NotCupCap":"\u226D","NotDoubleVerticalBar":"\u2226","NotElement":"\u2209","NotEqual":"\u2260","NotEqualTilde":"\u2242\u0338","NotExists":"\u2204","NotGreater":"\u226F","NotGreaterEqual":"\u2271","NotGreaterFullEqual":"\u2267\u0338","NotGreaterGreater":"\u226B\u0338","NotGreaterLess":"\u2279","NotGreaterSlantEqual":"\u2A7E\u0338","NotGreaterTilde":"\u2275","NotHumpDownHump":"\u224E\u0338","NotHumpEqual":"\u224F\u0338","notin":"\u2209","notindot":"\u22F5\u0338","notinE":"\u22F9\u0338","notinva":"\u2209","notinvb":"\u22F7","notinvc":"\u22F6","NotLeftTriangleBar":"\u29CF\u0338","NotLeftTriangle":"\u22EA","NotLeftTriangleEqual":"\u22EC","NotLess":"\u226E","NotLessEqual":"\u2270","NotLessGreater":"\u2278","NotLessLess":"\u226A\u0338","NotLessSlantEqual":"\u2A7D\u0338","NotLessTilde":"\u2274","NotNestedGreaterGreater":"\u2AA2\u0338","NotNestedLessLess":"\u2AA1\u0338","notni":"\u220C","notniva":"\u220C","notnivb":"\u22FE","notnivc":"\u22FD","NotPrecedes":"\u2280","NotPrecedesEqual":"\u2AAF\u0338","NotPrecedesSlantEqual":"\u22E0","NotReverseElement":"\u220C","NotRightTriangleBar":"\u29D0\u0338","NotRightTriangle":"\u22EB","NotRightTriangleEqual":"\u22ED","NotSquareSubset":"\u228F\u0338","NotSquareSubsetEqual":"\u22E2","NotSquareSuperset":"\u2290\u0338","NotSquareSupersetEqual":"\u22E3","NotSubset":"\u2282\u20D2","NotSubsetEqual":"\u2288","NotSucceeds":"\u2281","NotSucceedsEqual":"\u2AB0\u0338","NotSucceedsSlantEqual":"\u22E1","NotSucceedsTilde":"\u227F\u0338","NotSuperset":"\u2283\u20D2","NotSupersetEqual":"\u2289","NotTilde":"\u2241","NotTildeEqual":"\u2244","NotTildeFullEqual":"\u2247","NotTildeTilde":"\u2249","NotVerticalBar":"\u2224","nparallel":"\u2226","npar":"\u2226","nparsl":"\u2AFD\u20E5","npart":"\u2202\u0338","npolint":"\u2A14","npr":"\u2280","nprcue":"\u22E0","nprec":"\u2280","npreceq":"\u2AAF\u0338","npre":"\u2AAF\u0338","nrarrc":"\u2933\u0338","nrarr":"\u219B","nrArr":"\u21CF","nrarrw":"\u219D\u0338","nrightarrow":"\u219B","nRightarrow":"\u21CF","nrtri":"\u22EB","nrtrie":"\u22ED","nsc":"\u2281","nsccue":"\u22E1","nsce":"\u2AB0\u0338","Nscr":"\uD835\uDCA9","nscr":"\uD835\uDCC3","nshortmid":"\u2224","nshortparallel":"\u2226","nsim":"\u2241","nsime":"\u2244","nsimeq":"\u2244","nsmid":"\u2224","nspar":"\u2226","nsqsube":"\u22E2","nsqsupe":"\u22E3","nsub":"\u2284","nsubE":"\u2AC5\u0338","nsube":"\u2288","nsubset":"\u2282\u20D2","nsubseteq":"\u2288","nsubseteqq":"\u2AC5\u0338","nsucc":"\u2281","nsucceq":"\u2AB0\u0338","nsup":"\u2285","nsupE":"\u2AC6\u0338","nsupe":"\u2289","nsupset":"\u2283\u20D2","nsupseteq":"\u2289","nsupseteqq":"\u2AC6\u0338","ntgl":"\u2279","Ntilde":"\u00D1","ntilde":"\u00F1","ntlg":"\u2278","ntriangleleft":"\u22EA","ntrianglelefteq":"\u22EC","ntriangleright":"\u22EB","ntrianglerighteq":"\u22ED","Nu":"\u039D","nu":"\u03BD","num":"#","numero":"\u2116","numsp":"\u2007","nvap":"\u224D\u20D2","nvdash":"\u22AC","nvDash":"\u22AD","nVdash":"\u22AE","nVDash":"\u22AF","nvge":"\u2265\u20D2","nvgt":">\u20D2","nvHarr":"\u2904","nvinfin":"\u29DE","nvlArr":"\u2902","nvle":"\u2264\u20D2","nvlt":"<\u20D2","nvltrie":"\u22B4\u20D2","nvrArr":"\u2903","nvrtrie":"\u22B5\u20D2","nvsim":"\u223C\u20D2","nwarhk":"\u2923","nwarr":"\u2196","nwArr":"\u21D6","nwarrow":"\u2196","nwnear":"\u2927","Oacute":"\u00D3","oacute":"\u00F3","oast":"\u229B","Ocirc":"\u00D4","ocirc":"\u00F4","ocir":"\u229A","Ocy":"\u041E","ocy":"\u043E","odash":"\u229D","Odblac":"\u0150","odblac":"\u0151","odiv":"\u2A38","odot":"\u2299","odsold":"\u29BC","OElig":"\u0152","oelig":"\u0153","ofcir":"\u29BF","Ofr":"\uD835\uDD12","ofr":"\uD835\uDD2C","ogon":"\u02DB","Ograve":"\u00D2","ograve":"\u00F2","ogt":"\u29C1","ohbar":"\u29B5","ohm":"\u03A9","oint":"\u222E","olarr":"\u21BA","olcir":"\u29BE","olcross":"\u29BB","oline":"\u203E","olt":"\u29C0","Omacr":"\u014C","omacr":"\u014D","Omega":"\u03A9","omega":"\u03C9","Omicron":"\u039F","omicron":"\u03BF","omid":"\u29B6","ominus":"\u2296","Oopf":"\uD835\uDD46","oopf":"\uD835\uDD60","opar":"\u29B7","OpenCurlyDoubleQuote":"\u201C","OpenCurlyQuote":"\u2018","operp":"\u29B9","oplus":"\u2295","orarr":"\u21BB","Or":"\u2A54","or":"\u2228","ord":"\u2A5D","order":"\u2134","orderof":"\u2134","ordf":"\u00AA","ordm":"\u00BA","origof":"\u22B6","oror":"\u2A56","orslope":"\u2A57","orv":"\u2A5B","oS":"\u24C8","Oscr":"\uD835\uDCAA","oscr":"\u2134","Oslash":"\u00D8","oslash":"\u00F8","osol":"\u2298","Otilde":"\u00D5","otilde":"\u00F5","otimesas":"\u2A36","Otimes":"\u2A37","otimes":"\u2297","Ouml":"\u00D6","ouml":"\u00F6","ovbar":"\u233D","OverBar":"\u203E","OverBrace":"\u23DE","OverBracket":"\u23B4","OverParenthesis":"\u23DC","para":"\u00B6","parallel":"\u2225","par":"\u2225","parsim":"\u2AF3","parsl":"\u2AFD","part":"\u2202","PartialD":"\u2202","Pcy":"\u041F","pcy":"\u043F","percnt":"%","period":".","permil":"\u2030","perp":"\u22A5","pertenk":"\u2031","Pfr":"\uD835\uDD13","pfr":"\uD835\uDD2D","Phi":"\u03A6","phi":"\u03C6","phiv":"\u03D5","phmmat":"\u2133","phone":"\u260E","Pi":"\u03A0","pi":"\u03C0","pitchfork":"\u22D4","piv":"\u03D6","planck":"\u210F","planckh":"\u210E","plankv":"\u210F","plusacir":"\u2A23","plusb":"\u229E","pluscir":"\u2A22","plus":"+","plusdo":"\u2214","plusdu":"\u2A25","pluse":"\u2A72","PlusMinus":"\u00B1","plusmn":"\u00B1","plussim":"\u2A26","plustwo":"\u2A27","pm":"\u00B1","Poincareplane":"\u210C","pointint":"\u2A15","popf":"\uD835\uDD61","Popf":"\u2119","pound":"\u00A3","prap":"\u2AB7","Pr":"\u2ABB","pr":"\u227A","prcue":"\u227C","precapprox":"\u2AB7","prec":"\u227A","preccurlyeq":"\u227C","Precedes":"\u227A","PrecedesEqual":"\u2AAF","PrecedesSlantEqual":"\u227C","PrecedesTilde":"\u227E","preceq":"\u2AAF","precnapprox":"\u2AB9","precneqq":"\u2AB5","precnsim":"\u22E8","pre":"\u2AAF","prE":"\u2AB3","precsim":"\u227E","prime":"\u2032","Prime":"\u2033","primes":"\u2119","prnap":"\u2AB9","prnE":"\u2AB5","prnsim":"\u22E8","prod":"\u220F","Product":"\u220F","profalar":"\u232E","profline":"\u2312","profsurf":"\u2313","prop":"\u221D","Proportional":"\u221D","Proportion":"\u2237","propto":"\u221D","prsim":"\u227E","prurel":"\u22B0","Pscr":"\uD835\uDCAB","pscr":"\uD835\uDCC5","Psi":"\u03A8","psi":"\u03C8","puncsp":"\u2008","Qfr":"\uD835\uDD14","qfr":"\uD835\uDD2E","qint":"\u2A0C","qopf":"\uD835\uDD62","Qopf":"\u211A","qprime":"\u2057","Qscr":"\uD835\uDCAC","qscr":"\uD835\uDCC6","quaternions":"\u210D","quatint":"\u2A16","quest":"?","questeq":"\u225F","quot":"\"","QUOT":"\"","rAarr":"\u21DB","race":"\u223D\u0331","Racute":"\u0154","racute":"\u0155","radic":"\u221A","raemptyv":"\u29B3","rang":"\u27E9","Rang":"\u27EB","rangd":"\u2992","range":"\u29A5","rangle":"\u27E9","raquo":"\u00BB","rarrap":"\u2975","rarrb":"\u21E5","rarrbfs":"\u2920","rarrc":"\u2933","rarr":"\u2192","Rarr":"\u21A0","rArr":"\u21D2","rarrfs":"\u291E","rarrhk":"\u21AA","rarrlp":"\u21AC","rarrpl":"\u2945","rarrsim":"\u2974","Rarrtl":"\u2916","rarrtl":"\u21A3","rarrw":"\u219D","ratail":"\u291A","rAtail":"\u291C","ratio":"\u2236","rationals":"\u211A","rbarr":"\u290D","rBarr":"\u290F","RBarr":"\u2910","rbbrk":"\u2773","rbrace":"}","rbrack":"]","rbrke":"\u298C","rbrksld":"\u298E","rbrkslu":"\u2990","Rcaron":"\u0158","rcaron":"\u0159","Rcedil":"\u0156","rcedil":"\u0157","rceil":"\u2309","rcub":"}","Rcy":"\u0420","rcy":"\u0440","rdca":"\u2937","rdldhar":"\u2969","rdquo":"\u201D","rdquor":"\u201D","rdsh":"\u21B3","real":"\u211C","realine":"\u211B","realpart":"\u211C","reals":"\u211D","Re":"\u211C","rect":"\u25AD","reg":"\u00AE","REG":"\u00AE","ReverseElement":"\u220B","ReverseEquilibrium":"\u21CB","ReverseUpEquilibrium":"\u296F","rfisht":"\u297D","rfloor":"\u230B","rfr":"\uD835\uDD2F","Rfr":"\u211C","rHar":"\u2964","rhard":"\u21C1","rharu":"\u21C0","rharul":"\u296C","Rho":"\u03A1","rho":"\u03C1","rhov":"\u03F1","RightAngleBracket":"\u27E9","RightArrowBar":"\u21E5","rightarrow":"\u2192","RightArrow":"\u2192","Rightarrow":"\u21D2","RightArrowLeftArrow":"\u21C4","rightarrowtail":"\u21A3","RightCeiling":"\u2309","RightDoubleBracket":"\u27E7","RightDownTeeVector":"\u295D","RightDownVectorBar":"\u2955","RightDownVector":"\u21C2","RightFloor":"\u230B","rightharpoondown":"\u21C1","rightharpoonup":"\u21C0","rightleftarrows":"\u21C4","rightleftharpoons":"\u21CC","rightrightarrows":"\u21C9","rightsquigarrow":"\u219D","RightTeeArrow":"\u21A6","RightTee":"\u22A2","RightTeeVector":"\u295B","rightthreetimes":"\u22CC","RightTriangleBar":"\u29D0","RightTriangle":"\u22B3","RightTriangleEqual":"\u22B5","RightUpDownVector":"\u294F","RightUpTeeVector":"\u295C","RightUpVectorBar":"\u2954","RightUpVector":"\u21BE","RightVectorBar":"\u2953","RightVector":"\u21C0","ring":"\u02DA","risingdotseq":"\u2253","rlarr":"\u21C4","rlhar":"\u21CC","rlm":"\u200F","rmoustache":"\u23B1","rmoust":"\u23B1","rnmid":"\u2AEE","roang":"\u27ED","roarr":"\u21FE","robrk":"\u27E7","ropar":"\u2986","ropf":"\uD835\uDD63","Ropf":"\u211D","roplus":"\u2A2E","rotimes":"\u2A35","RoundImplies":"\u2970","rpar":")","rpargt":"\u2994","rppolint":"\u2A12","rrarr":"\u21C9","Rrightarrow":"\u21DB","rsaquo":"\u203A","rscr":"\uD835\uDCC7","Rscr":"\u211B","rsh":"\u21B1","Rsh":"\u21B1","rsqb":"]","rsquo":"\u2019","rsquor":"\u2019","rthree":"\u22CC","rtimes":"\u22CA","rtri":"\u25B9","rtrie":"\u22B5","rtrif":"\u25B8","rtriltri":"\u29CE","RuleDelayed":"\u29F4","ruluhar":"\u2968","rx":"\u211E","Sacute":"\u015A","sacute":"\u015B","sbquo":"\u201A","scap":"\u2AB8","Scaron":"\u0160","scaron":"\u0161","Sc":"\u2ABC","sc":"\u227B","sccue":"\u227D","sce":"\u2AB0","scE":"\u2AB4","Scedil":"\u015E","scedil":"\u015F","Scirc":"\u015C","scirc":"\u015D","scnap":"\u2ABA","scnE":"\u2AB6","scnsim":"\u22E9","scpolint":"\u2A13","scsim":"\u227F","Scy":"\u0421","scy":"\u0441","sdotb":"\u22A1","sdot":"\u22C5","sdote":"\u2A66","searhk":"\u2925","searr":"\u2198","seArr":"\u21D8","searrow":"\u2198","sect":"\u00A7","semi":";","seswar":"\u2929","setminus":"\u2216","setmn":"\u2216","sext":"\u2736","Sfr":"\uD835\uDD16","sfr":"\uD835\uDD30","sfrown":"\u2322","sharp":"\u266F","SHCHcy":"\u0429","shchcy":"\u0449","SHcy":"\u0428","shcy":"\u0448","ShortDownArrow":"\u2193","ShortLeftArrow":"\u2190","shortmid":"\u2223","shortparallel":"\u2225","ShortRightArrow":"\u2192","ShortUpArrow":"\u2191","shy":"\u00AD","Sigma":"\u03A3","sigma":"\u03C3","sigmaf":"\u03C2","sigmav":"\u03C2","sim":"\u223C","simdot":"\u2A6A","sime":"\u2243","simeq":"\u2243","simg":"\u2A9E","simgE":"\u2AA0","siml":"\u2A9D","simlE":"\u2A9F","simne":"\u2246","simplus":"\u2A24","simrarr":"\u2972","slarr":"\u2190","SmallCircle":"\u2218","smallsetminus":"\u2216","smashp":"\u2A33","smeparsl":"\u29E4","smid":"\u2223","smile":"\u2323","smt":"\u2AAA","smte":"\u2AAC","smtes":"\u2AAC\uFE00","SOFTcy":"\u042C","softcy":"\u044C","solbar":"\u233F","solb":"\u29C4","sol":"/","Sopf":"\uD835\uDD4A","sopf":"\uD835\uDD64","spades":"\u2660","spadesuit":"\u2660","spar":"\u2225","sqcap":"\u2293","sqcaps":"\u2293\uFE00","sqcup":"\u2294","sqcups":"\u2294\uFE00","Sqrt":"\u221A","sqsub":"\u228F","sqsube":"\u2291","sqsubset":"\u228F","sqsubseteq":"\u2291","sqsup":"\u2290","sqsupe":"\u2292","sqsupset":"\u2290","sqsupseteq":"\u2292","square":"\u25A1","Square":"\u25A1","SquareIntersection":"\u2293","SquareSubset":"\u228F","SquareSubsetEqual":"\u2291","SquareSuperset":"\u2290","SquareSupersetEqual":"\u2292","SquareUnion":"\u2294","squarf":"\u25AA","squ":"\u25A1","squf":"\u25AA","srarr":"\u2192","Sscr":"\uD835\uDCAE","sscr":"\uD835\uDCC8","ssetmn":"\u2216","ssmile":"\u2323","sstarf":"\u22C6","Star":"\u22C6","star":"\u2606","starf":"\u2605","straightepsilon":"\u03F5","straightphi":"\u03D5","strns":"\u00AF","sub":"\u2282","Sub":"\u22D0","subdot":"\u2ABD","subE":"\u2AC5","sube":"\u2286","subedot":"\u2AC3","submult":"\u2AC1","subnE":"\u2ACB","subne":"\u228A","subplus":"\u2ABF","subrarr":"\u2979","subset":"\u2282","Subset":"\u22D0","subseteq":"\u2286","subseteqq":"\u2AC5","SubsetEqual":"\u2286","subsetneq":"\u228A","subsetneqq":"\u2ACB","subsim":"\u2AC7","subsub":"\u2AD5","subsup":"\u2AD3","succapprox":"\u2AB8","succ":"\u227B","succcurlyeq":"\u227D","Succeeds":"\u227B","SucceedsEqual":"\u2AB0","SucceedsSlantEqual":"\u227D","SucceedsTilde":"\u227F","succeq":"\u2AB0","succnapprox":"\u2ABA","succneqq":"\u2AB6","succnsim":"\u22E9","succsim":"\u227F","SuchThat":"\u220B","sum":"\u2211","Sum":"\u2211","sung":"\u266A","sup1":"\u00B9","sup2":"\u00B2","sup3":"\u00B3","sup":"\u2283","Sup":"\u22D1","supdot":"\u2ABE","supdsub":"\u2AD8","supE":"\u2AC6","supe":"\u2287","supedot":"\u2AC4","Superset":"\u2283","SupersetEqual":"\u2287","suphsol":"\u27C9","suphsub":"\u2AD7","suplarr":"\u297B","supmult":"\u2AC2","supnE":"\u2ACC","supne":"\u228B","supplus":"\u2AC0","supset":"\u2283","Supset":"\u22D1","supseteq":"\u2287","supseteqq":"\u2AC6","supsetneq":"\u228B","supsetneqq":"\u2ACC","supsim":"\u2AC8","supsub":"\u2AD4","supsup":"\u2AD6","swarhk":"\u2926","swarr":"\u2199","swArr":"\u21D9","swarrow":"\u2199","swnwar":"\u292A","szlig":"\u00DF","Tab":"\t","target":"\u2316","Tau":"\u03A4","tau":"\u03C4","tbrk":"\u23B4","Tcaron":"\u0164","tcaron":"\u0165","Tcedil":"\u0162","tcedil":"\u0163","Tcy":"\u0422","tcy":"\u0442","tdot":"\u20DB","telrec":"\u2315","Tfr":"\uD835\uDD17","tfr":"\uD835\uDD31","there4":"\u2234","therefore":"\u2234","Therefore":"\u2234","Theta":"\u0398","theta":"\u03B8","thetasym":"\u03D1","thetav":"\u03D1","thickapprox":"\u2248","thicksim":"\u223C","ThickSpace":"\u205F\u200A","ThinSpace":"\u2009","thinsp":"\u2009","thkap":"\u2248","thksim":"\u223C","THORN":"\u00DE","thorn":"\u00FE","tilde":"\u02DC","Tilde":"\u223C","TildeEqual":"\u2243","TildeFullEqual":"\u2245","TildeTilde":"\u2248","timesbar":"\u2A31","timesb":"\u22A0","times":"\u00D7","timesd":"\u2A30","tint":"\u222D","toea":"\u2928","topbot":"\u2336","topcir":"\u2AF1","top":"\u22A4","Topf":"\uD835\uDD4B","topf":"\uD835\uDD65","topfork":"\u2ADA","tosa":"\u2929","tprime":"\u2034","trade":"\u2122","TRADE":"\u2122","triangle":"\u25B5","triangledown":"\u25BF","triangleleft":"\u25C3","trianglelefteq":"\u22B4","triangleq":"\u225C","triangleright":"\u25B9","trianglerighteq":"\u22B5","tridot":"\u25EC","trie":"\u225C","triminus":"\u2A3A","TripleDot":"\u20DB","triplus":"\u2A39","trisb":"\u29CD","tritime":"\u2A3B","trpezium":"\u23E2","Tscr":"\uD835\uDCAF","tscr":"\uD835\uDCC9","TScy":"\u0426","tscy":"\u0446","TSHcy":"\u040B","tshcy":"\u045B","Tstrok":"\u0166","tstrok":"\u0167","twixt":"\u226C","twoheadleftarrow":"\u219E","twoheadrightarrow":"\u21A0","Uacute":"\u00DA","uacute":"\u00FA","uarr":"\u2191","Uarr":"\u219F","uArr":"\u21D1","Uarrocir":"\u2949","Ubrcy":"\u040E","ubrcy":"\u045E","Ubreve":"\u016C","ubreve":"\u016D","Ucirc":"\u00DB","ucirc":"\u00FB","Ucy":"\u0423","ucy":"\u0443","udarr":"\u21C5","Udblac":"\u0170","udblac":"\u0171","udhar":"\u296E","ufisht":"\u297E","Ufr":"\uD835\uDD18","ufr":"\uD835\uDD32","Ugrave":"\u00D9","ugrave":"\u00F9","uHar":"\u2963","uharl":"\u21BF","uharr":"\u21BE","uhblk":"\u2580","ulcorn":"\u231C","ulcorner":"\u231C","ulcrop":"\u230F","ultri":"\u25F8","Umacr":"\u016A","umacr":"\u016B","uml":"\u00A8","UnderBar":"_","UnderBrace":"\u23DF","UnderBracket":"\u23B5","UnderParenthesis":"\u23DD","Union":"\u22C3","UnionPlus":"\u228E","Uogon":"\u0172","uogon":"\u0173","Uopf":"\uD835\uDD4C","uopf":"\uD835\uDD66","UpArrowBar":"\u2912","uparrow":"\u2191","UpArrow":"\u2191","Uparrow":"\u21D1","UpArrowDownArrow":"\u21C5","updownarrow":"\u2195","UpDownArrow":"\u2195","Updownarrow":"\u21D5","UpEquilibrium":"\u296E","upharpoonleft":"\u21BF","upharpoonright":"\u21BE","uplus":"\u228E","UpperLeftArrow":"\u2196","UpperRightArrow":"\u2197","upsi":"\u03C5","Upsi":"\u03D2","upsih":"\u03D2","Upsilon":"\u03A5","upsilon":"\u03C5","UpTeeArrow":"\u21A5","UpTee":"\u22A5","upuparrows":"\u21C8","urcorn":"\u231D","urcorner":"\u231D","urcrop":"\u230E","Uring":"\u016E","uring":"\u016F","urtri":"\u25F9","Uscr":"\uD835\uDCB0","uscr":"\uD835\uDCCA","utdot":"\u22F0","Utilde":"\u0168","utilde":"\u0169","utri":"\u25B5","utrif":"\u25B4","uuarr":"\u21C8","Uuml":"\u00DC","uuml":"\u00FC","uwangle":"\u29A7","vangrt":"\u299C","varepsilon":"\u03F5","varkappa":"\u03F0","varnothing":"\u2205","varphi":"\u03D5","varpi":"\u03D6","varpropto":"\u221D","varr":"\u2195","vArr":"\u21D5","varrho":"\u03F1","varsigma":"\u03C2","varsubsetneq":"\u228A\uFE00","varsubsetneqq":"\u2ACB\uFE00","varsupsetneq":"\u228B\uFE00","varsupsetneqq":"\u2ACC\uFE00","vartheta":"\u03D1","vartriangleleft":"\u22B2","vartriangleright":"\u22B3","vBar":"\u2AE8","Vbar":"\u2AEB","vBarv":"\u2AE9","Vcy":"\u0412","vcy":"\u0432","vdash":"\u22A2","vDash":"\u22A8","Vdash":"\u22A9","VDash":"\u22AB","Vdashl":"\u2AE6","veebar":"\u22BB","vee":"\u2228","Vee":"\u22C1","veeeq":"\u225A","vellip":"\u22EE","verbar":"|","Verbar":"\u2016","vert":"|","Vert":"\u2016","VerticalBar":"\u2223","VerticalLine":"|","VerticalSeparator":"\u2758","VerticalTilde":"\u2240","VeryThinSpace":"\u200A","Vfr":"\uD835\uDD19","vfr":"\uD835\uDD33","vltri":"\u22B2","vnsub":"\u2282\u20D2","vnsup":"\u2283\u20D2","Vopf":"\uD835\uDD4D","vopf":"\uD835\uDD67","vprop":"\u221D","vrtri":"\u22B3","Vscr":"\uD835\uDCB1","vscr":"\uD835\uDCCB","vsubnE":"\u2ACB\uFE00","vsubne":"\u228A\uFE00","vsupnE":"\u2ACC\uFE00","vsupne":"\u228B\uFE00","Vvdash":"\u22AA","vzigzag":"\u299A","Wcirc":"\u0174","wcirc":"\u0175","wedbar":"\u2A5F","wedge":"\u2227","Wedge":"\u22C0","wedgeq":"\u2259","weierp":"\u2118","Wfr":"\uD835\uDD1A","wfr":"\uD835\uDD34","Wopf":"\uD835\uDD4E","wopf":"\uD835\uDD68","wp":"\u2118","wr":"\u2240","wreath":"\u2240","Wscr":"\uD835\uDCB2","wscr":"\uD835\uDCCC","xcap":"\u22C2","xcirc":"\u25EF","xcup":"\u22C3","xdtri":"\u25BD","Xfr":"\uD835\uDD1B","xfr":"\uD835\uDD35","xharr":"\u27F7","xhArr":"\u27FA","Xi":"\u039E","xi":"\u03BE","xlarr":"\u27F5","xlArr":"\u27F8","xmap":"\u27FC","xnis":"\u22FB","xodot":"\u2A00","Xopf":"\uD835\uDD4F","xopf":"\uD835\uDD69","xoplus":"\u2A01","xotime":"\u2A02","xrarr":"\u27F6","xrArr":"\u27F9","Xscr":"\uD835\uDCB3","xscr":"\uD835\uDCCD","xsqcup":"\u2A06","xuplus":"\u2A04","xutri":"\u25B3","xvee":"\u22C1","xwedge":"\u22C0","Yacute":"\u00DD","yacute":"\u00FD","YAcy":"\u042F","yacy":"\u044F","Ycirc":"\u0176","ycirc":"\u0177","Ycy":"\u042B","ycy":"\u044B","yen":"\u00A5","Yfr":"\uD835\uDD1C","yfr":"\uD835\uDD36","YIcy":"\u0407","yicy":"\u0457","Yopf":"\uD835\uDD50","yopf":"\uD835\uDD6A","Yscr":"\uD835\uDCB4","yscr":"\uD835\uDCCE","YUcy":"\u042E","yucy":"\u044E","yuml":"\u00FF","Yuml":"\u0178","Zacute":"\u0179","zacute":"\u017A","Zcaron":"\u017D","zcaron":"\u017E","Zcy":"\u0417","zcy":"\u0437","Zdot":"\u017B","zdot":"\u017C","zeetrf":"\u2128","ZeroWidthSpace":"\u200B","Zeta":"\u0396","zeta":"\u03B6","zfr":"\uD835\uDD37","Zfr":"\u2128","ZHcy":"\u0416","zhcy":"\u0436","zigrarr":"\u21DD","zopf":"\uD835\uDD6B","Zopf":"\u2124","Zscr":"\uD835\uDCB5","zscr":"\uD835\uDCCF","zwj":"\u200D","zwnj":"\u200C"} \ No newline at end of file diff --git a/node_modules/entities/maps/legacy.json b/node_modules/entities/maps/legacy.json new file mode 100644 index 0000000..f0e82a4 --- /dev/null +++ b/node_modules/entities/maps/legacy.json @@ -0,0 +1 @@ +{"Aacute":"\u00C1","aacute":"\u00E1","Acirc":"\u00C2","acirc":"\u00E2","acute":"\u00B4","AElig":"\u00C6","aelig":"\u00E6","Agrave":"\u00C0","agrave":"\u00E0","amp":"&","AMP":"&","Aring":"\u00C5","aring":"\u00E5","Atilde":"\u00C3","atilde":"\u00E3","Auml":"\u00C4","auml":"\u00E4","brvbar":"\u00A6","Ccedil":"\u00C7","ccedil":"\u00E7","cedil":"\u00B8","cent":"\u00A2","copy":"\u00A9","COPY":"\u00A9","curren":"\u00A4","deg":"\u00B0","divide":"\u00F7","Eacute":"\u00C9","eacute":"\u00E9","Ecirc":"\u00CA","ecirc":"\u00EA","Egrave":"\u00C8","egrave":"\u00E8","ETH":"\u00D0","eth":"\u00F0","Euml":"\u00CB","euml":"\u00EB","frac12":"\u00BD","frac14":"\u00BC","frac34":"\u00BE","gt":">","GT":">","Iacute":"\u00CD","iacute":"\u00ED","Icirc":"\u00CE","icirc":"\u00EE","iexcl":"\u00A1","Igrave":"\u00CC","igrave":"\u00EC","iquest":"\u00BF","Iuml":"\u00CF","iuml":"\u00EF","laquo":"\u00AB","lt":"<","LT":"<","macr":"\u00AF","micro":"\u00B5","middot":"\u00B7","nbsp":"\u00A0","not":"\u00AC","Ntilde":"\u00D1","ntilde":"\u00F1","Oacute":"\u00D3","oacute":"\u00F3","Ocirc":"\u00D4","ocirc":"\u00F4","Ograve":"\u00D2","ograve":"\u00F2","ordf":"\u00AA","ordm":"\u00BA","Oslash":"\u00D8","oslash":"\u00F8","Otilde":"\u00D5","otilde":"\u00F5","Ouml":"\u00D6","ouml":"\u00F6","para":"\u00B6","plusmn":"\u00B1","pound":"\u00A3","quot":"\"","QUOT":"\"","raquo":"\u00BB","reg":"\u00AE","REG":"\u00AE","sect":"\u00A7","shy":"\u00AD","sup1":"\u00B9","sup2":"\u00B2","sup3":"\u00B3","szlig":"\u00DF","THORN":"\u00DE","thorn":"\u00FE","times":"\u00D7","Uacute":"\u00DA","uacute":"\u00FA","Ucirc":"\u00DB","ucirc":"\u00FB","Ugrave":"\u00D9","ugrave":"\u00F9","uml":"\u00A8","Uuml":"\u00DC","uuml":"\u00FC","Yacute":"\u00DD","yacute":"\u00FD","yen":"\u00A5","yuml":"\u00FF"} \ No newline at end of file diff --git a/node_modules/entities/maps/xml.json b/node_modules/entities/maps/xml.json new file mode 100644 index 0000000..de8db10 --- /dev/null +++ b/node_modules/entities/maps/xml.json @@ -0,0 +1 @@ +{"amp":"&","apos":"'","gt":">","lt":"<","quot":"\""} diff --git a/node_modules/entities/package.json b/node_modules/entities/package.json new file mode 100644 index 0000000..fe2288a --- /dev/null +++ b/node_modules/entities/package.json @@ -0,0 +1,114 @@ +{ + "_args": [ + [ + { + "raw": "entities@1.0", + "scope": null, + "escapedName": "entities", + "name": "entities", + "rawSpec": "1.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/htmlparser2" + ] + ], + "_from": "entities@>=1.0.0 <1.1.0", + "_id": "entities@1.0.0", + "_inCache": true, + "_location": "/entities", + "_npmUser": { + "name": "feedic", + "email": "me@feedic.com" + }, + "_npmVersion": "1.4.4", + "_phantomChildren": {}, + "_requested": { + "raw": "entities@1.0", + "scope": null, + "escapedName": "entities", + "name": "entities", + "rawSpec": "1.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/htmlparser2" + ], + "_resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "_shasum": "b2987aa3821347fcde642b24fdfc9e4fb712bf26", + "_shrinkwrap": null, + "_spec": "entities@1.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/htmlparser2", + "author": { + "name": "Felix Boehm", + "email": "me@feedic.com" + }, + "bugs": { + "url": "https://github.com/fb55/node-entities/issues" + }, + "dependencies": {}, + "description": "Encode & decode XML/HTML entities with ease", + "devDependencies": { + "coveralls": "*", + "istanbul": "*", + "jshint": "2", + "mocha": "1", + "mocha-lcov-reporter": "*" + }, + "directories": { + "test": "test" + }, + "dist": { + "shasum": "b2987aa3821347fcde642b24fdfc9e4fb712bf26", + "tarball": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz" + }, + "homepage": "https://github.com/fb55/node-entities", + "jshintConfig": { + "eqeqeq": true, + "freeze": true, + "latedef": "nofunc", + "noarg": true, + "nonbsp": true, + "quotmark": "double", + "undef": true, + "unused": true, + "trailing": true, + "eqnull": true, + "proto": true, + "smarttabs": true, + "node": true, + "globals": { + "describe": true, + "it": true + } + }, + "keywords": [ + "html", + "xml", + "entity", + "encoding" + ], + "license": "BSD-like", + "main": "./index.js", + "maintainers": [ + { + "name": "feedic", + "email": "me@feedic.com" + } + ], + "name": "entities", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/fb55/node-entities.git" + }, + "scripts": { + "coveralls": "npm run lint && npm run lcov && (cat coverage/lcov.info | coveralls || exit 0)", + "lcov": "istanbul cover _mocha --report lcovonly -- -R spec", + "lint": "jshint index.js lib/*.js test/*.js", + "test": "mocha && npm run lint" + }, + "version": "1.0.0" +} diff --git a/node_modules/entities/readme.md b/node_modules/entities/readme.md new file mode 100644 index 0000000..88dfa26 --- /dev/null +++ b/node_modules/entities/readme.md @@ -0,0 +1,31 @@ +#entities [![NPM version](http://img.shields.io/npm/v/entities.svg)](https://npmjs.org/package/entities) [![Downloads](https://img.shields.io/npm/dm/entities.svg)](https://npmjs.org/package/entities) [![Build Status](http://img.shields.io/travis/fb55/node-entities.svg)](http://travis-ci.org/fb55/node-entities) [![Coverage](http://img.shields.io/coveralls/fb55/node-entities.svg)](https://coveralls.io/r/fb55/node-entities) + +En- & decoder for XML/HTML entities. + +####Features: +* Focussed on ___speed___ +* Supports three levels of entities: __XML__, __HTML4__ & __HTML5__ + * Supports _char code_ entities (eg. `U`) + +##How to… + +###…install `entities` + + npm i entities + +###…use `entities` + +```javascript +//encoding +require("entities").encode( data[, level]); +//decoding +require("entities").decode( data[, level]); +``` + +The `level` attribute indicates what level of entities should be decoded (0 = XML, 1 = HTML4 and 2 = HTML5). The default is 0 (read: XML). + +There are also methods to access the level directly. Just append the name of the level to the action and you're ready to go (e.g. `encodeHTML4(data)`, `decodeXML(data)`). + +--- + +License: BSD-like diff --git a/node_modules/entities/test/mocha.opts b/node_modules/entities/test/mocha.opts new file mode 100644 index 0000000..af53e24 --- /dev/null +++ b/node_modules/entities/test/mocha.opts @@ -0,0 +1,2 @@ +--check-leaks +--reporter spec diff --git a/node_modules/entities/test/test.js b/node_modules/entities/test/test.js new file mode 100644 index 0000000..9c09fe9 --- /dev/null +++ b/node_modules/entities/test/test.js @@ -0,0 +1,150 @@ +var assert = require("assert"), + path = require("path"), + entities = require("../"); + +describe("Encode->decode test", function(){ + var testcases = [ + { + input: "asdf & ÿ ü '", + xml: "asdf & ÿ ü '", + html: "asdf & ÿ ü '" + }, { + input: "&", + xml: "&#38;", + html: "&#38;" + }, + ]; + testcases.forEach(function(tc) { + var encodedXML = entities.encodeXML(tc.input); + it("should XML encode " + tc.input, function(){ + assert.equal(encodedXML, tc.xml); + }); + it("should default to XML encode " + tc.input, function(){ + assert.equal(entities.encode(tc.input), tc.xml); + }); + it("should XML decode " + encodedXML, function(){ + assert.equal(entities.decodeXML(encodedXML), tc.input); + }); + it("should default to XML encode " + encodedXML, function(){ + assert.equal(entities.decode(encodedXML), tc.input); + }); + it("should default strict to XML encode " + encodedXML, function(){ + assert.equal(entities.decodeStrict(encodedXML), tc.input); + }); + + var encodedHTML5 = entities.encodeHTML5(tc.input); + it("should HTML5 encode " + tc.input, function(){ + assert.equal(encodedHTML5, tc.html); + }); + it("should HTML5 decode " + encodedHTML5, function(){ + assert.equal(entities.decodeHTML(encodedHTML5), tc.input); + }); + }); +}); + +describe("Decode test", function(){ + var testcases = [ + { input: "&amp;", output: "&" }, + { input: "&#38;", output: "&" }, + { input: "&#x26;", output: "&" }, + { input: "&#X26;", output: "&" }, + { input: "&#38;", output: "&" }, + { input: "&#38;", output: "&" }, + { input: "&#38;", output: "&" }, + { input: ":", output: ":" }, + { input: ":", output: ":" }, + { input: ":", output: ":" }, + { input: ":", output: ":" } + ]; + testcases.forEach(function(tc) { + it("should XML decode " + tc.input, function(){ + assert.equal(entities.decodeXML(tc.input), tc.output); + }); + it("should HTML4 decode " + tc.input, function(){ + assert.equal(entities.decodeHTML(tc.input), tc.output); + }); + it("should HTML5 decode " + tc.input, function(){ + assert.equal(entities.decodeHTML(tc.input), tc.output); + }); + }); +}); + +var levels = ["xml", "entities"]; + +describe("Documents", function(){ + levels + .map(function(n){ return path.join("..", "maps", n); }) + .map(require) + .forEach(function(doc, i){ + describe("Decode", function(){ + it(levels[i], function(){ + Object.keys(doc).forEach(function(e){ + for(var l = i; l < levels.length; l++){ + assert.equal(entities.decode("&" + e + ";", l), doc[e]); + } + }); + }); + }); + + describe("Decode strict", function(){ + it(levels[i], function(){ + Object.keys(doc).forEach(function(e){ + for(var l = i; l < levels.length; l++){ + assert.equal(entities.decodeStrict("&" + e + ";", l), doc[e]); + } + }); + }); + }); + + describe("Encode", function(){ + it(levels[i], function(){ + Object.keys(doc).forEach(function(e){ + for(var l = i; l < levels.length; l++){ + assert.equal(entities.decode(entities.encode(doc[e], l), l), doc[e]); + } + }); + }); + }); + }); + + var legacy = require("../maps/legacy.json"); + + describe("Legacy", function(){ + it("should decode", runLegacy); + }); + + function runLegacy(){ + Object.keys(legacy).forEach(function(e){ + assert.equal(entities.decodeHTML("&" + e), legacy[e]); + }); + } +}); + +var astral = { + "1D306": "\uD834\uDF06", + "1D11E": "\uD834\uDD1E" +}; + +var astralSpecial = { + "80": "\u20AC", + "110000": "\uFFFD" +}; + + +describe("Astral entities", function(){ + Object.keys(astral).forEach(function(c){ + it("should decode " + astral[c], function(){ + assert.equal(entities.decode("&#x" + c + ";"), astral[c]); + }); + + it("should encode " + astral[c], function(){ + assert.equal(entities.encode(astral[c]), "&#x" + c + ";"); + }); + }); + + Object.keys(astralSpecial).forEach(function(c){ + it("special should decode \\u" + c, function(){ + assert.equal(entities.decode("&#x" + c + ";"), astralSpecial[c]); + }); + }); +}); diff --git a/node_modules/error-ex/LICENSE b/node_modules/error-ex/LICENSE new file mode 100644 index 0000000..0a5f461 --- /dev/null +++ b/node_modules/error-ex/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 JD Ballard + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/error-ex/README.md b/node_modules/error-ex/README.md new file mode 100644 index 0000000..97f744a --- /dev/null +++ b/node_modules/error-ex/README.md @@ -0,0 +1,144 @@ +# node-error-ex [![Travis-CI.org Build Status](https://img.shields.io/travis/Qix-/node-error-ex.svg?style=flat-square)](https://travis-ci.org/Qix-/node-error-ex) [![Coveralls.io Coverage Rating](https://img.shields.io/coveralls/Qix-/node-error-ex.svg?style=flat-square)](https://coveralls.io/r/Qix-/node-error-ex) +> Easily subclass and customize new Error types + +## Examples +To include in your project: +```javascript +var errorEx = require('error-ex'); +``` + +To create an error message type with a specific name (note, that `ErrorFn.name` +will not reflect this): +```javascript +var JSONError = errorEx('JSONError'); + +var err = new JSONError('error'); +err.name; //-> JSONError +throw err; //-> JSONError: error +``` + +To add a stack line: +```javascript +var JSONError = errorEx('JSONError', {fileName: errorEx.line('in %s')}); + +var err = new JSONError('error') +err.fileName = '/a/b/c/foo.json'; +throw err; //-> (line 2)-> in /a/b/c/foo.json +``` + +To append to the error message: +```javascript +var JSONError = errorEx('JSONError', {fileName: errorEx.append('in %s')}); + +var err = new JSONError('error'); +err.fileName = '/a/b/c/foo.json'; +throw err; //-> JSONError: error in /a/b/c/foo.json +``` + +## API + +#### `errorEx([name], [properties])` +Creates a new ErrorEx error type + +- `name`: the name of the new type (appears in the error message upon throw; + defaults to `Error.name`) +- `properties`: if supplied, used as a key/value dictionary of properties to + use when building up the stack message. Keys are property names that are + looked up on the error message, and then passed to function values. + - `line`: if specified and is a function, return value is added as a stack + entry (error-ex will indent for you). Passed the property value given + the key. + - `stack`: if specified and is a function, passed the value of the property + using the key, and the raw stack lines as a second argument. Takes no + return value (but the stack can be modified directly). + - `message`: if specified and is a function, return value is used as new + `.message` value upon get. Passed the property value of the property named + by key, and the existing message is passed as the second argument as an + array of lines (suitable for multi-line messages). + +Returns a constructor (Function) that can be used just like the regular Error +constructor. + +```javascript +var errorEx = require('error-ex'); + +var BasicError = errorEx(); + +var NamedError = errorEx('NamedError'); + +// -- + +var AdvancedError = errorEx('AdvancedError', { + foo: { + line: function (value, stack) { + if (value) { + return 'bar ' + value; + } + return null; + } + } +} + +var err = new AdvancedError('hello, world'); +err.foo = 'baz'; +throw err; + +/* + AdvancedError: hello, world + bar baz + at tryReadme() (readme.js:20:1) +*/ +``` + +#### `errorEx.line(str)` +Creates a stack line using a delimiter + +> This is a helper function. It is to be used in lieu of writing a value object +> for `properties` values. + +- `str`: The string to create + - Use the delimiter `%s` to specify where in the string the value should go + +```javascript +var errorEx = require('error-ex'); + +var FileError = errorEx('FileError', {fileName: errorEx.line('in %s')}); + +var err = new FileError('problem reading file'); +err.fileName = '/a/b/c/d/foo.js'; +throw err; + +/* + FileError: problem reading file + in /a/b/c/d/foo.js + at tryReadme() (readme.js:7:1) +*/ +``` + +#### `errorEx.append(str)` +Appends to the `error.message` string + +> This is a helper function. It is to be used in lieu of writing a value object +> for `properties` values. + +- `str`: The string to append + - Use the delimiter `%s` to specify where in the string the value should go + +```javascript +var errorEx = require('error-ex'); + +var SyntaxError = errorEx('SyntaxError', {fileName: errorEx.append('in %s')}); + +var err = new SyntaxError('improper indentation'); +err.fileName = '/a/b/c/d/foo.js'; +throw err; + +/* + SyntaxError: improper indentation in /a/b/c/d/foo.js + at tryReadme() (readme.js:7:1) +*/ +``` + +## License +Licensed under the [MIT License](http://opensource.org/licenses/MIT). +You can find a copy of it in [LICENSE](LICENSE). diff --git a/node_modules/error-ex/index.js b/node_modules/error-ex/index.js new file mode 100644 index 0000000..1bdc943 --- /dev/null +++ b/node_modules/error-ex/index.js @@ -0,0 +1,115 @@ +'use strict'; + +var util = require('util'); +var isArrayish = require('is-arrayish'); + +var errorEx = function errorEx(name, properties) { + if (!name || name.constructor !== String) { + properties = name || {}; + name = Error.name; + } + + var errorExError = function ErrorEXError(message) { + if (!this) { + return new ErrorEXError(message); + } + + message = message instanceof Error + ? message.message + : (message || this.message); + + Error.call(this, message); + Error.captureStackTrace(this, errorExError); + this.name = name; + + delete this.message; + + Object.defineProperty(this, 'message', { + configurable: true, + enumerable: false, + get: function () { + var newMessage = message.split(/\r?\n/g); + + for (var key in properties) { + if (properties.hasOwnProperty(key) && 'message' in properties[key]) { + newMessage = properties[key].message(this[key], newMessage) || + newMessage; + if (!isArrayish(newMessage)) { + newMessage = [newMessage]; + } + } + } + + return newMessage.join('\n'); + }, + set: function (v) { + message = v; + } + }); + + var stackDescriptor = Object.getOwnPropertyDescriptor(this, 'stack'); + var stackGetter = stackDescriptor.get; + + stackDescriptor.get = function () { + var stack = stackGetter.call(this).split(/\r?\n+/g); + + var lineCount = 1; + for (var key in properties) { + if (!properties.hasOwnProperty(key)) { + continue; + } + + var modifier = properties[key]; + + if ('line' in modifier) { + var line = modifier.line(this[key]); + if (line) { + stack.splice(lineCount, 0, ' ' + line); + } + } + + if ('stack' in modifier) { + modifier.stack(this[key], stack); + } + } + + return stack.join('\n'); + }; + + Object.defineProperty(this, 'stack', stackDescriptor); + }; + + util.inherits(errorExError, Error); + + return errorExError; +}; + +errorEx.append = function (str, def) { + return { + message: function (v, message) { + v = v || def; + + if (v) { + message[0] += ' ' + str.replace('%s', v.toString()); + } + + return message; + } + }; +}; + +errorEx.line = function (str, def) { + return { + line: function (v) { + v = v || def; + + if (v) { + return str.replace('%s', v.toString()); + } + + return null; + } + }; +}; + +module.exports = errorEx; diff --git a/node_modules/error-ex/package.json b/node_modules/error-ex/package.json new file mode 100644 index 0000000..20a131b --- /dev/null +++ b/node_modules/error-ex/package.json @@ -0,0 +1,109 @@ +{ + "_args": [ + [ + { + "raw": "error-ex@^1.2.0", + "scope": null, + "escapedName": "error-ex", + "name": "error-ex", + "rawSpec": "^1.2.0", + "spec": ">=1.2.0 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/parse-json" + ] + ], + "_from": "error-ex@>=1.2.0 <2.0.0", + "_id": "error-ex@1.3.0", + "_inCache": true, + "_location": "/error-ex", + "_nodeVersion": "4.1.1", + "_npmUser": { + "name": "qix", + "email": "i.am.qix@gmail.com" + }, + "_npmVersion": "3.3.6", + "_phantomChildren": {}, + "_requested": { + "raw": "error-ex@^1.2.0", + "scope": null, + "escapedName": "error-ex", + "name": "error-ex", + "rawSpec": "^1.2.0", + "spec": ">=1.2.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/parse-json" + ], + "_resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.0.tgz", + "_shasum": "e67b43f3e82c96ea3a584ffee0b9fc3325d802d9", + "_shrinkwrap": null, + "_spec": "error-ex@^1.2.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/parse-json", + "bugs": { + "url": "https://github.com/qix-/node-error-ex/issues" + }, + "dependencies": { + "is-arrayish": "^0.2.1" + }, + "description": "Easy error subclassing and stack customization", + "devDependencies": { + "coffee-script": "^1.9.3", + "coveralls": "^2.11.2", + "istanbul": "^0.3.17", + "mocha": "^2.2.5", + "should": "^7.0.1", + "xo": "^0.7.1" + }, + "directories": {}, + "dist": { + "shasum": "e67b43f3e82c96ea3a584ffee0b9fc3325d802d9", + "tarball": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.0.tgz" + }, + "files": [ + "index.js" + ], + "gitHead": "118bb63206f736f2450480e73f9d7d22692ae328", + "homepage": "https://github.com/qix-/node-error-ex#readme", + "keywords": [ + "error", + "errors", + "extend", + "extending", + "extension", + "subclass", + "stack", + "custom" + ], + "license": "MIT", + "maintainers": [ + { + "name": "qix", + "email": "i.am.qix@gmail.com" + }, + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "error-ex", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/qix-/node-error-ex.git" + }, + "scripts": { + "pretest": "xo", + "test": "mocha --compilers coffee:coffee-script/register" + }, + "version": "1.3.0", + "xo": { + "rules": { + "operator-linebreak": [ + 0 + ] + } + } +} diff --git a/node_modules/escape-string-regexp/index.js b/node_modules/escape-string-regexp/index.js new file mode 100644 index 0000000..7834bf9 --- /dev/null +++ b/node_modules/escape-string-regexp/index.js @@ -0,0 +1,11 @@ +'use strict'; + +var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; + +module.exports = function (str) { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); + } + + return str.replace(matchOperatorsRe, '\\$&'); +}; diff --git a/node_modules/escape-string-regexp/license b/node_modules/escape-string-regexp/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/escape-string-regexp/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/escape-string-regexp/package.json b/node_modules/escape-string-regexp/package.json new file mode 100644 index 0000000..781f348 --- /dev/null +++ b/node_modules/escape-string-regexp/package.json @@ -0,0 +1,110 @@ +{ + "_args": [ + [ + { + "raw": "escape-string-regexp@^1.0.2", + "scope": null, + "escapedName": "escape-string-regexp", + "name": "escape-string-regexp", + "rawSpec": "^1.0.2", + "spec": ">=1.0.2 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/chalk" + ] + ], + "_from": "escape-string-regexp@>=1.0.2 <2.0.0", + "_id": "escape-string-regexp@1.0.5", + "_inCache": true, + "_location": "/escape-string-regexp", + "_nodeVersion": "4.2.6", + "_npmOperationalInternal": { + "host": "packages-9-west.internal.npmjs.com", + "tmp": "tmp/escape-string-regexp-1.0.5.tgz_1456059312074_0.7245344955008477" + }, + "_npmUser": { + "name": "jbnicolai", + "email": "jappelman@xebia.com" + }, + "_npmVersion": "2.14.12", + "_phantomChildren": {}, + "_requested": { + "raw": "escape-string-regexp@^1.0.2", + "scope": null, + "escapedName": "escape-string-regexp", + "name": "escape-string-regexp", + "rawSpec": "^1.0.2", + "spec": ">=1.0.2 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/chalk", + "/figures" + ], + "_resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "_shasum": "1b61c0562190a8dff6ae3bb2cf0200ca130b86d4", + "_shrinkwrap": null, + "_spec": "escape-string-regexp@^1.0.2", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/chalk", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/escape-string-regexp/issues" + }, + "dependencies": {}, + "description": "Escape RegExp special characters", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "1b61c0562190a8dff6ae3bb2cf0200ca130b86d4", + "tarball": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + }, + "engines": { + "node": ">=0.8.0" + }, + "files": [ + "index.js" + ], + "gitHead": "db124a3e1aae9d692c4899e42a5c6c3e329eaa20", + "homepage": "https://github.com/sindresorhus/escape-string-regexp", + "keywords": [ + "escape", + "regex", + "regexp", + "re", + "regular", + "expression", + "string", + "str", + "special", + "characters" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + { + "name": "jbnicolai", + "email": "jappelman@xebia.com" + } + ], + "name": "escape-string-regexp", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/escape-string-regexp.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "1.0.5" +} diff --git a/node_modules/escape-string-regexp/readme.md b/node_modules/escape-string-regexp/readme.md new file mode 100644 index 0000000..87ac82d --- /dev/null +++ b/node_modules/escape-string-regexp/readme.md @@ -0,0 +1,27 @@ +# escape-string-regexp [![Build Status](https://travis-ci.org/sindresorhus/escape-string-regexp.svg?branch=master)](https://travis-ci.org/sindresorhus/escape-string-regexp) + +> Escape RegExp special characters + + +## Install + +``` +$ npm install --save escape-string-regexp +``` + + +## Usage + +```js +const escapeStringRegexp = require('escape-string-regexp'); + +const escapedString = escapeStringRegexp('how much $ for a unicorn?'); +//=> 'how much \$ for a unicorn\?' + +new RegExp(escapedString); +``` + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/esprima/README.md b/node_modules/esprima/README.md new file mode 100644 index 0000000..a74bd12 --- /dev/null +++ b/node_modules/esprima/README.md @@ -0,0 +1,73 @@ +**Esprima** ([esprima.org](http://esprima.org)) is a high performance, +standard-compliant [ECMAScript](http://www.ecma-international.org/publications/standards/Ecma-262.htm) +parser written in ECMAScript (also popularly known as +[JavaScript](http://en.wikipedia.org/wiki/JavaScript>JavaScript)). +Esprima is created and maintained by [Ariya Hidayat](http://twitter.com/ariyahidayat), +with the help of [many contributors](https://github.com/ariya/esprima/contributors). + +Esprima runs on web browsers (IE 6+, Firefox 1+, Safari 3+, Chrome 1+, Konqueror 4.6+, Opera 8+) as well as +[Node.js](http://nodejs.org). + +### Features + +- Full support for [ECMAScript 5.1](http://www.ecma-international.org/publications/standards/Ecma-262.htm)(ECMA-262) +- Sensible [syntax tree format](http://esprima.org/doc/index.html#ast) compatible with Mozilla +[Parser AST](https://developer.mozilla.org/en/SpiderMonkey/Parser_API) +- Heavily tested (> 550 [unit tests](http://esprima.org/test/) with solid 100% statement coverage) +- Optional tracking of syntax node location (index-based and line-column) +- Experimental support for ES6/Harmony (module, class, destructuring, ...) + +Esprima is blazing fast (see the [benchmark suite](http://esprima.org/test/benchmarks.html)). +It is up to 3x faster than UglifyJS v1 and it is still [competitive](http://esprima.org/test/compare.html) +with the new generation of fast parsers. + +### Applications + +Esprima serves as the basis for many popular JavaScript development tools: + +- Code coverage analysis: [node-cover](https://github.com/itay/node-cover), [Istanbul](https://github.com/yahoo/Istanbul) +- Documentation tool: [JFDoc](https://github.com/thejohnfreeman/jfdoc), [JSDuck](https://github.com/senchalabs/jsduck) +- Language extension: [LLJS](http://mbebenita.github.com/LLJS/) (low-level JS), +[Sweet.js](http://sweetjs.org/) (macro) +- ES6/Harmony transpiler: [Six](https://github.com/matthewrobb/six), [Harmonizr](https://github.com/jdiamond/harmonizr) +- Eclipse Orion smart editing ([outline view](https://github.com/aclement/esprima-outline), [content assist](http://contraptionsforprogramming.blogspot.com/2012/02/better-javascript-content-assist-in.html)) +- Source code modification: [Esmorph](https://github.com/ariya/esmorph), [Code Painter](https://github.com/fawek/codepainter), +- Source transformation: [node-falafel](https://github.com/substack/node-falafel), [Esmangle](https://github.com/Constellation/esmangle), [escodegen](https://github.com/Constellation/escodegen) + +### Questions? +- [Documentation](http://esprima.org/doc) +- [Issue tracker](http://issues.esprima.org): [known problems](http://code.google.com/p/esprima/issues/list?q=Defect) +and [future plans](http://code.google.com/p/esprima/issues/list?q=Enhancement) +- [Mailing list](http://groups.google.com/group/esprima) +- [Contribution guide](http://esprima.org/doc/index.html#contribution) + +Follow [@Esprima](http://twitter.com/Esprima) on Twitter to get the +development updates. +Feedback and contribution are welcomed! + +### License + +Copyright (C) 2012, 2011 [Ariya Hidayat](http://ariya.ofilabs.com/about) + and other contributors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/node_modules/esprima/bin/esparse.js b/node_modules/esprima/bin/esparse.js new file mode 100644 index 0000000..3e7bb81 --- /dev/null +++ b/node_modules/esprima/bin/esparse.js @@ -0,0 +1,117 @@ +#!/usr/bin/env node +/* + Copyright (C) 2012 Ariya Hidayat + Copyright (C) 2011 Ariya Hidayat + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/*jslint sloppy:true node:true rhino:true */ + +var fs, esprima, fname, content, options, syntax; + +if (typeof require === 'function') { + fs = require('fs'); + esprima = require('esprima'); +} else if (typeof load === 'function') { + try { + load('esprima.js'); + } catch (e) { + load('../esprima.js'); + } +} + +// Shims to Node.js objects when running under Rhino. +if (typeof console === 'undefined' && typeof process === 'undefined') { + console = { log: print }; + fs = { readFileSync: readFile }; + process = { argv: arguments, exit: quit }; + process.argv.unshift('esparse.js'); + process.argv.unshift('rhino'); +} + +function showUsage() { + console.log('Usage:'); + console.log(' esparse [options] file.js'); + console.log(); + console.log('Available options:'); + console.log(); + console.log(' --comment Gather all line and block comments in an array'); + console.log(' --loc Include line-column location info for each syntax node'); + console.log(' --range Include index-based range for each syntax node'); + console.log(' --raw Display the raw value of literals'); + console.log(' --tokens List all tokens in an array'); + console.log(' --tolerant Tolerate errors on a best-effort basis (experimental)'); + console.log(' -v, --version Shows program version'); + console.log(); + process.exit(1); +} + +if (process.argv.length <= 2) { + showUsage(); +} + +options = {}; + +process.argv.splice(2).forEach(function (entry) { + + if (entry === '-h' || entry === '--help') { + showUsage(); + } else if (entry === '-v' || entry === '--version') { + console.log('ECMAScript Parser (using Esprima version', esprima.version, ')'); + console.log(); + process.exit(0); + } else if (entry === '--comment') { + options.comment = true; + } else if (entry === '--loc') { + options.loc = true; + } else if (entry === '--range') { + options.range = true; + } else if (entry === '--raw') { + options.raw = true; + } else if (entry === '--tokens') { + options.tokens = true; + } else if (entry === '--tolerant') { + options.tolerant = true; + } else if (entry.slice(0, 2) === '--') { + console.log('Error: unknown option ' + entry + '.'); + process.exit(1); + } else if (typeof fname === 'string') { + console.log('Error: more than one input file.'); + process.exit(1); + } else { + fname = entry; + } +}); + +if (typeof fname !== 'string') { + console.log('Error: no input file.'); + process.exit(1); +} + +try { + content = fs.readFileSync(fname, 'utf-8'); + syntax = esprima.parse(content, options); + console.log(JSON.stringify(syntax, null, 4)); +} catch (e) { + console.log('Error: ' + e.message); + process.exit(1); +} diff --git a/node_modules/esprima/bin/esvalidate.js b/node_modules/esprima/bin/esvalidate.js new file mode 100644 index 0000000..e0af3f7 --- /dev/null +++ b/node_modules/esprima/bin/esvalidate.js @@ -0,0 +1,177 @@ +#!/usr/bin/env node +/* + Copyright (C) 2012 Ariya Hidayat + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/*jslint sloppy:true plusplus:true node:true rhino:true */ + +var fs, esprima, options, fnames, count; + +if (typeof require === 'function') { + fs = require('fs'); + esprima = require('esprima'); +} else if (typeof load === 'function') { + try { + load('esprima.js'); + } catch (e) { + load('../esprima.js'); + } +} + +// Shims to Node.js objects when running under Rhino. +if (typeof console === 'undefined' && typeof process === 'undefined') { + console = { log: print }; + fs = { readFileSync: readFile }; + process = { argv: arguments, exit: quit }; + process.argv.unshift('esvalidate.js'); + process.argv.unshift('rhino'); +} + +function showUsage() { + console.log('Usage:'); + console.log(' esvalidate [options] file.js'); + console.log(); + console.log('Available options:'); + console.log(); + console.log(' --format=type Set the report format, plain (default) or junit'); + console.log(' -v, --version Print program version'); + console.log(); + process.exit(1); +} + +if (process.argv.length <= 2) { + showUsage(); +} + +options = { + format: 'plain' +}; + +fnames = []; + +process.argv.splice(2).forEach(function (entry) { + + if (entry === '-h' || entry === '--help') { + showUsage(); + } else if (entry === '-v' || entry === '--version') { + console.log('ECMAScript Validator (using Esprima version', esprima.version, ')'); + console.log(); + process.exit(0); + } else if (entry.slice(0, 9) === '--format=') { + options.format = entry.slice(9); + if (options.format !== 'plain' && options.format !== 'junit') { + console.log('Error: unknown report format ' + options.format + '.'); + process.exit(1); + } + } else if (entry.slice(0, 2) === '--') { + console.log('Error: unknown option ' + entry + '.'); + process.exit(1); + } else { + fnames.push(entry); + } +}); + +if (fnames.length === 0) { + console.log('Error: no input file.'); + process.exit(1); +} + +if (options.format === 'junit') { + console.log(''); + console.log(''); +} + +count = 0; +fnames.forEach(function (fname) { + var content, timestamp, syntax, name; + try { + content = fs.readFileSync(fname, 'utf-8'); + + if (content[0] === '#' && content[1] === '!') { + content = '//' + content.substr(2, content.length); + } + + timestamp = Date.now(); + syntax = esprima.parse(content, { tolerant: true }); + + if (options.format === 'junit') { + + name = fname; + if (name.lastIndexOf('/') >= 0) { + name = name.slice(name.lastIndexOf('/') + 1); + } + + console.log(''); + + syntax.errors.forEach(function (error) { + var msg = error.message; + msg = msg.replace(/^Line\ [0-9]*\:\ /, ''); + console.log(' '); + console.log(' ' + + error.message + '(' + name + ':' + error.lineNumber + ')' + + ''); + console.log(' '); + }); + + console.log(''); + + } else if (options.format === 'plain') { + + syntax.errors.forEach(function (error) { + var msg = error.message; + msg = msg.replace(/^Line\ [0-9]*\:\ /, ''); + msg = fname + ':' + error.lineNumber + ': ' + msg; + console.log(msg); + ++count; + }); + + } + } catch (e) { + ++count; + if (options.format === 'junit') { + console.log(''); + console.log(' '); + console.log(' ' + + e.message + '(' + fname + ((e.lineNumber) ? ':' + e.lineNumber : '') + + ')'); + console.log(' '); + console.log(''); + } else { + console.log('Error: ' + e.message); + } + } +}); + +if (options.format === 'junit') { + console.log(''); +} + +if (count > 0) { + process.exit(1); +} diff --git a/node_modules/esprima/esprima.js b/node_modules/esprima/esprima.js new file mode 100644 index 0000000..f1320da --- /dev/null +++ b/node_modules/esprima/esprima.js @@ -0,0 +1,3908 @@ +/* + Copyright (C) 2012 Ariya Hidayat + Copyright (C) 2012 Mathias Bynens + Copyright (C) 2012 Joost-Wim Boekesteijn + Copyright (C) 2012 Kris Kowal + Copyright (C) 2012 Yusuke Suzuki + Copyright (C) 2012 Arpad Borsos + Copyright (C) 2011 Ariya Hidayat + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/*jslint bitwise:true plusplus:true */ +/*global esprima:true, define:true, exports:true, window: true, +throwError: true, createLiteral: true, generateStatement: true, +parseAssignmentExpression: true, parseBlock: true, parseExpression: true, +parseFunctionDeclaration: true, parseFunctionExpression: true, +parseFunctionSourceElements: true, parseVariableIdentifier: true, +parseLeftHandSideExpression: true, +parseStatement: true, parseSourceElement: true */ + +(function (root, factory) { + 'use strict'; + + // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, + // Rhino, and plain browser loading. + if (typeof define === 'function' && define.amd) { + define(['exports'], factory); + } else if (typeof exports !== 'undefined') { + factory(exports); + } else { + factory((root.esprima = {})); + } +}(this, function (exports) { + 'use strict'; + + var Token, + TokenName, + Syntax, + PropertyKind, + Messages, + Regex, + source, + strict, + index, + lineNumber, + lineStart, + length, + buffer, + state, + extra; + + Token = { + BooleanLiteral: 1, + EOF: 2, + Identifier: 3, + Keyword: 4, + NullLiteral: 5, + NumericLiteral: 6, + Punctuator: 7, + StringLiteral: 8 + }; + + TokenName = {}; + TokenName[Token.BooleanLiteral] = 'Boolean'; + TokenName[Token.EOF] = ''; + TokenName[Token.Identifier] = 'Identifier'; + TokenName[Token.Keyword] = 'Keyword'; + TokenName[Token.NullLiteral] = 'Null'; + TokenName[Token.NumericLiteral] = 'Numeric'; + TokenName[Token.Punctuator] = 'Punctuator'; + TokenName[Token.StringLiteral] = 'String'; + + Syntax = { + AssignmentExpression: 'AssignmentExpression', + ArrayExpression: 'ArrayExpression', + BlockStatement: 'BlockStatement', + BinaryExpression: 'BinaryExpression', + BreakStatement: 'BreakStatement', + CallExpression: 'CallExpression', + CatchClause: 'CatchClause', + ConditionalExpression: 'ConditionalExpression', + ContinueStatement: 'ContinueStatement', + DoWhileStatement: 'DoWhileStatement', + DebuggerStatement: 'DebuggerStatement', + EmptyStatement: 'EmptyStatement', + ExpressionStatement: 'ExpressionStatement', + ForStatement: 'ForStatement', + ForInStatement: 'ForInStatement', + FunctionDeclaration: 'FunctionDeclaration', + FunctionExpression: 'FunctionExpression', + Identifier: 'Identifier', + IfStatement: 'IfStatement', + Literal: 'Literal', + LabeledStatement: 'LabeledStatement', + LogicalExpression: 'LogicalExpression', + MemberExpression: 'MemberExpression', + NewExpression: 'NewExpression', + ObjectExpression: 'ObjectExpression', + Program: 'Program', + Property: 'Property', + ReturnStatement: 'ReturnStatement', + SequenceExpression: 'SequenceExpression', + SwitchStatement: 'SwitchStatement', + SwitchCase: 'SwitchCase', + ThisExpression: 'ThisExpression', + ThrowStatement: 'ThrowStatement', + TryStatement: 'TryStatement', + UnaryExpression: 'UnaryExpression', + UpdateExpression: 'UpdateExpression', + VariableDeclaration: 'VariableDeclaration', + VariableDeclarator: 'VariableDeclarator', + WhileStatement: 'WhileStatement', + WithStatement: 'WithStatement' + }; + + PropertyKind = { + Data: 1, + Get: 2, + Set: 4 + }; + + // Error messages should be identical to V8. + Messages = { + UnexpectedToken: 'Unexpected token %0', + UnexpectedNumber: 'Unexpected number', + UnexpectedString: 'Unexpected string', + UnexpectedIdentifier: 'Unexpected identifier', + UnexpectedReserved: 'Unexpected reserved word', + UnexpectedEOS: 'Unexpected end of input', + NewlineAfterThrow: 'Illegal newline after throw', + InvalidRegExp: 'Invalid regular expression', + UnterminatedRegExp: 'Invalid regular expression: missing /', + InvalidLHSInAssignment: 'Invalid left-hand side in assignment', + InvalidLHSInForIn: 'Invalid left-hand side in for-in', + MultipleDefaultsInSwitch: 'More than one default clause in switch statement', + NoCatchOrFinally: 'Missing catch or finally after try', + UnknownLabel: 'Undefined label \'%0\'', + Redeclaration: '%0 \'%1\' has already been declared', + IllegalContinue: 'Illegal continue statement', + IllegalBreak: 'Illegal break statement', + IllegalReturn: 'Illegal return statement', + StrictModeWith: 'Strict mode code may not include a with statement', + StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', + StrictVarName: 'Variable name may not be eval or arguments in strict mode', + StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', + StrictParamDupe: 'Strict mode function may not have duplicate parameter names', + StrictFunctionName: 'Function name may not be eval or arguments in strict mode', + StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', + StrictDelete: 'Delete of an unqualified identifier in strict mode.', + StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode', + AccessorDataProperty: 'Object literal may not have data and accessor property with the same name', + AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name', + StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', + StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', + StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', + StrictReservedWord: 'Use of future reserved word in strict mode' + }; + + // See also tools/generate-unicode-regex.py. + Regex = { + NonAsciiIdentifierStart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]'), + NonAsciiIdentifierPart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u0487\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f2\u0610-\u061a\u0620-\u0669\u066e-\u06d3\u06d5-\u06dc\u06df-\u06e8\u06ea-\u06fc\u06ff\u0710-\u074a\u074d-\u07b1\u07c0-\u07f5\u07fa\u0800-\u082d\u0840-\u085b\u08a0\u08a2-\u08ac\u08e4-\u08fe\u0900-\u0963\u0966-\u096f\u0971-\u0977\u0979-\u097f\u0981-\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bc-\u09c4\u09c7\u09c8\u09cb-\u09ce\u09d7\u09dc\u09dd\u09df-\u09e3\u09e6-\u09f1\u0a01-\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a59-\u0a5c\u0a5e\u0a66-\u0a75\u0a81-\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abc-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ad0\u0ae0-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3c-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f-\u0b63\u0b66-\u0b6f\u0b71\u0b82\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd0\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbc-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0cde\u0ce0-\u0ce3\u0ce6-\u0cef\u0cf1\u0cf2\u0d02\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d44\u0d46-\u0d48\u0d4a-\u0d4e\u0d57\u0d60-\u0d63\u0d66-\u0d6f\u0d7a-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e01-\u0e3a\u0e40-\u0e4e\u0e50-\u0e59\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb9\u0ebb-\u0ebd\u0ec0-\u0ec4\u0ec6\u0ec8-\u0ecd\u0ed0-\u0ed9\u0edc-\u0edf\u0f00\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e-\u0f47\u0f49-\u0f6c\u0f71-\u0f84\u0f86-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1049\u1050-\u109d\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u135d-\u135f\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176c\u176e-\u1770\u1772\u1773\u1780-\u17d3\u17d7\u17dc\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1820-\u1877\u1880-\u18aa\u18b0-\u18f5\u1900-\u191c\u1920-\u192b\u1930-\u193b\u1946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19d9\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1aa7\u1b00-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1bf3\u1c00-\u1c37\u1c40-\u1c49\u1c4d-\u1c7d\u1cd0-\u1cd2\u1cd4-\u1cf6\u1d00-\u1de6\u1dfc-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u200c\u200d\u203f\u2040\u2054\u2071\u207f\u2090-\u209c\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d7f-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2de0-\u2dff\u2e2f\u3005-\u3007\u3021-\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u3099\u309a\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua62b\ua640-\ua66f\ua674-\ua67d\ua67f-\ua697\ua69f-\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua827\ua840-\ua873\ua880-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f7\ua8fb\ua900-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf-\ua9d9\uaa00-\uaa36\uaa40-\uaa4d\uaa50-\uaa59\uaa60-\uaa76\uaa7a\uaa7b\uaa80-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabea\uabec\uabed\uabf0-\uabf9\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\ufe70-\ufe74\ufe76-\ufefc\uff10-\uff19\uff21-\uff3a\uff3f\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]') + }; + + // Ensure the condition is true, otherwise throw an error. + // This is only to have a better contract semantic, i.e. another safety net + // to catch a logic error. The condition shall be fulfilled in normal case. + // Do NOT use this to enforce a certain condition on any user input. + + function assert(condition, message) { + if (!condition) { + throw new Error('ASSERT: ' + message); + } + } + + function sliceSource(from, to) { + return source.slice(from, to); + } + + if (typeof 'esprima'[0] === 'undefined') { + sliceSource = function sliceArraySource(from, to) { + return source.slice(from, to).join(''); + }; + } + + function isDecimalDigit(ch) { + return '0123456789'.indexOf(ch) >= 0; + } + + function isHexDigit(ch) { + return '0123456789abcdefABCDEF'.indexOf(ch) >= 0; + } + + function isOctalDigit(ch) { + return '01234567'.indexOf(ch) >= 0; + } + + + // 7.2 White Space + + function isWhiteSpace(ch) { + return (ch === ' ') || (ch === '\u0009') || (ch === '\u000B') || + (ch === '\u000C') || (ch === '\u00A0') || + (ch.charCodeAt(0) >= 0x1680 && + '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF'.indexOf(ch) >= 0); + } + + // 7.3 Line Terminators + + function isLineTerminator(ch) { + return (ch === '\n' || ch === '\r' || ch === '\u2028' || ch === '\u2029'); + } + + // 7.6 Identifier Names and Identifiers + + function isIdentifierStart(ch) { + return (ch === '$') || (ch === '_') || (ch === '\\') || + (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || + ((ch.charCodeAt(0) >= 0x80) && Regex.NonAsciiIdentifierStart.test(ch)); + } + + function isIdentifierPart(ch) { + return (ch === '$') || (ch === '_') || (ch === '\\') || + (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || + ((ch >= '0') && (ch <= '9')) || + ((ch.charCodeAt(0) >= 0x80) && Regex.NonAsciiIdentifierPart.test(ch)); + } + + // 7.6.1.2 Future Reserved Words + + function isFutureReservedWord(id) { + switch (id) { + + // Future reserved words. + case 'class': + case 'enum': + case 'export': + case 'extends': + case 'import': + case 'super': + return true; + } + + return false; + } + + function isStrictModeReservedWord(id) { + switch (id) { + + // Strict Mode reserved words. + case 'implements': + case 'interface': + case 'package': + case 'private': + case 'protected': + case 'public': + case 'static': + case 'yield': + case 'let': + return true; + } + + return false; + } + + function isRestrictedWord(id) { + return id === 'eval' || id === 'arguments'; + } + + // 7.6.1.1 Keywords + + function isKeyword(id) { + var keyword = false; + switch (id.length) { + case 2: + keyword = (id === 'if') || (id === 'in') || (id === 'do'); + break; + case 3: + keyword = (id === 'var') || (id === 'for') || (id === 'new') || (id === 'try'); + break; + case 4: + keyword = (id === 'this') || (id === 'else') || (id === 'case') || (id === 'void') || (id === 'with'); + break; + case 5: + keyword = (id === 'while') || (id === 'break') || (id === 'catch') || (id === 'throw'); + break; + case 6: + keyword = (id === 'return') || (id === 'typeof') || (id === 'delete') || (id === 'switch'); + break; + case 7: + keyword = (id === 'default') || (id === 'finally'); + break; + case 8: + keyword = (id === 'function') || (id === 'continue') || (id === 'debugger'); + break; + case 10: + keyword = (id === 'instanceof'); + break; + } + + if (keyword) { + return true; + } + + switch (id) { + // Future reserved words. + // 'const' is specialized as Keyword in V8. + case 'const': + return true; + + // For compatiblity to SpiderMonkey and ES.next + case 'yield': + case 'let': + return true; + } + + if (strict && isStrictModeReservedWord(id)) { + return true; + } + + return isFutureReservedWord(id); + } + + // 7.4 Comments + + function skipComment() { + var ch, blockComment, lineComment; + + blockComment = false; + lineComment = false; + + while (index < length) { + ch = source[index]; + + if (lineComment) { + ch = source[index++]; + if (isLineTerminator(ch)) { + lineComment = false; + if (ch === '\r' && source[index] === '\n') { + ++index; + } + ++lineNumber; + lineStart = index; + } + } else if (blockComment) { + if (isLineTerminator(ch)) { + if (ch === '\r' && source[index + 1] === '\n') { + ++index; + } + ++lineNumber; + ++index; + lineStart = index; + if (index >= length) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } else { + ch = source[index++]; + if (index >= length) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + if (ch === '*') { + ch = source[index]; + if (ch === '/') { + ++index; + blockComment = false; + } + } + } + } else if (ch === '/') { + ch = source[index + 1]; + if (ch === '/') { + index += 2; + lineComment = true; + } else if (ch === '*') { + index += 2; + blockComment = true; + if (index >= length) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } else { + break; + } + } else if (isWhiteSpace(ch)) { + ++index; + } else if (isLineTerminator(ch)) { + ++index; + if (ch === '\r' && source[index] === '\n') { + ++index; + } + ++lineNumber; + lineStart = index; + } else { + break; + } + } + } + + function scanHexEscape(prefix) { + var i, len, ch, code = 0; + + len = (prefix === 'u') ? 4 : 2; + for (i = 0; i < len; ++i) { + if (index < length && isHexDigit(source[index])) { + ch = source[index++]; + code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); + } else { + return ''; + } + } + return String.fromCharCode(code); + } + + function scanIdentifier() { + var ch, start, id, restore; + + ch = source[index]; + if (!isIdentifierStart(ch)) { + return; + } + + start = index; + if (ch === '\\') { + ++index; + if (source[index] !== 'u') { + return; + } + ++index; + restore = index; + ch = scanHexEscape('u'); + if (ch) { + if (ch === '\\' || !isIdentifierStart(ch)) { + return; + } + id = ch; + } else { + index = restore; + id = 'u'; + } + } else { + id = source[index++]; + } + + while (index < length) { + ch = source[index]; + if (!isIdentifierPart(ch)) { + break; + } + if (ch === '\\') { + ++index; + if (source[index] !== 'u') { + return; + } + ++index; + restore = index; + ch = scanHexEscape('u'); + if (ch) { + if (ch === '\\' || !isIdentifierPart(ch)) { + return; + } + id += ch; + } else { + index = restore; + id += 'u'; + } + } else { + id += source[index++]; + } + } + + // There is no keyword or literal with only one character. + // Thus, it must be an identifier. + if (id.length === 1) { + return { + type: Token.Identifier, + value: id, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + if (isKeyword(id)) { + return { + type: Token.Keyword, + value: id, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + // 7.8.1 Null Literals + + if (id === 'null') { + return { + type: Token.NullLiteral, + value: id, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + // 7.8.2 Boolean Literals + + if (id === 'true' || id === 'false') { + return { + type: Token.BooleanLiteral, + value: id, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + return { + type: Token.Identifier, + value: id, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + // 7.7 Punctuators + + function scanPunctuator() { + var start = index, + ch1 = source[index], + ch2, + ch3, + ch4; + + // Check for most common single-character punctuators. + + if (ch1 === ';' || ch1 === '{' || ch1 === '}') { + ++index; + return { + type: Token.Punctuator, + value: ch1, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + if (ch1 === ',' || ch1 === '(' || ch1 === ')') { + ++index; + return { + type: Token.Punctuator, + value: ch1, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + // Dot (.) can also start a floating-point number, hence the need + // to check the next character. + + ch2 = source[index + 1]; + if (ch1 === '.' && !isDecimalDigit(ch2)) { + return { + type: Token.Punctuator, + value: source[index++], + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + // Peek more characters. + + ch3 = source[index + 2]; + ch4 = source[index + 3]; + + // 4-character punctuator: >>>= + + if (ch1 === '>' && ch2 === '>' && ch3 === '>') { + if (ch4 === '=') { + index += 4; + return { + type: Token.Punctuator, + value: '>>>=', + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + } + + // 3-character punctuators: === !== >>> <<= >>= + + if (ch1 === '=' && ch2 === '=' && ch3 === '=') { + index += 3; + return { + type: Token.Punctuator, + value: '===', + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + if (ch1 === '!' && ch2 === '=' && ch3 === '=') { + index += 3; + return { + type: Token.Punctuator, + value: '!==', + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + if (ch1 === '>' && ch2 === '>' && ch3 === '>') { + index += 3; + return { + type: Token.Punctuator, + value: '>>>', + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + if (ch1 === '<' && ch2 === '<' && ch3 === '=') { + index += 3; + return { + type: Token.Punctuator, + value: '<<=', + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + if (ch1 === '>' && ch2 === '>' && ch3 === '=') { + index += 3; + return { + type: Token.Punctuator, + value: '>>=', + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + // 2-character punctuators: <= >= == != ++ -- << >> && || + // += -= *= %= &= |= ^= /= + + if (ch2 === '=') { + if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) { + index += 2; + return { + type: Token.Punctuator, + value: ch1 + ch2, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + } + + if (ch1 === ch2 && ('+-<>&|'.indexOf(ch1) >= 0)) { + if ('+-<>&|'.indexOf(ch2) >= 0) { + index += 2; + return { + type: Token.Punctuator, + value: ch1 + ch2, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + } + + // The remaining 1-character punctuators. + + if ('[]<>+-*%&|^!~?:=/'.indexOf(ch1) >= 0) { + return { + type: Token.Punctuator, + value: source[index++], + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + } + + // 7.8.3 Numeric Literals + + function scanNumericLiteral() { + var number, start, ch; + + ch = source[index]; + assert(isDecimalDigit(ch) || (ch === '.'), + 'Numeric literal must start with a decimal digit or a decimal point'); + + start = index; + number = ''; + if (ch !== '.') { + number = source[index++]; + ch = source[index]; + + // Hex number starts with '0x'. + // Octal number starts with '0'. + if (number === '0') { + if (ch === 'x' || ch === 'X') { + number += source[index++]; + while (index < length) { + ch = source[index]; + if (!isHexDigit(ch)) { + break; + } + number += source[index++]; + } + + if (number.length <= 2) { + // only 0x + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + if (index < length) { + ch = source[index]; + if (isIdentifierStart(ch)) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + return { + type: Token.NumericLiteral, + value: parseInt(number, 16), + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } else if (isOctalDigit(ch)) { + number += source[index++]; + while (index < length) { + ch = source[index]; + if (!isOctalDigit(ch)) { + break; + } + number += source[index++]; + } + + if (index < length) { + ch = source[index]; + if (isIdentifierStart(ch) || isDecimalDigit(ch)) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + return { + type: Token.NumericLiteral, + value: parseInt(number, 8), + octal: true, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + // decimal number starts with '0' such as '09' is illegal. + if (isDecimalDigit(ch)) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + + while (index < length) { + ch = source[index]; + if (!isDecimalDigit(ch)) { + break; + } + number += source[index++]; + } + } + + if (ch === '.') { + number += source[index++]; + while (index < length) { + ch = source[index]; + if (!isDecimalDigit(ch)) { + break; + } + number += source[index++]; + } + } + + if (ch === 'e' || ch === 'E') { + number += source[index++]; + + ch = source[index]; + if (ch === '+' || ch === '-') { + number += source[index++]; + } + + ch = source[index]; + if (isDecimalDigit(ch)) { + number += source[index++]; + while (index < length) { + ch = source[index]; + if (!isDecimalDigit(ch)) { + break; + } + number += source[index++]; + } + } else { + ch = 'character ' + ch; + if (index >= length) { + ch = ''; + } + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + + if (index < length) { + ch = source[index]; + if (isIdentifierStart(ch)) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + + return { + type: Token.NumericLiteral, + value: parseFloat(number), + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + // 7.8.4 String Literals + + function scanStringLiteral() { + var str = '', quote, start, ch, code, unescaped, restore, octal = false; + + quote = source[index]; + assert((quote === '\'' || quote === '"'), + 'String literal must starts with a quote'); + + start = index; + ++index; + + while (index < length) { + ch = source[index++]; + + if (ch === quote) { + quote = ''; + break; + } else if (ch === '\\') { + ch = source[index++]; + if (!isLineTerminator(ch)) { + switch (ch) { + case 'n': + str += '\n'; + break; + case 'r': + str += '\r'; + break; + case 't': + str += '\t'; + break; + case 'u': + case 'x': + restore = index; + unescaped = scanHexEscape(ch); + if (unescaped) { + str += unescaped; + } else { + index = restore; + str += ch; + } + break; + case 'b': + str += '\b'; + break; + case 'f': + str += '\f'; + break; + case 'v': + str += '\x0B'; + break; + + default: + if (isOctalDigit(ch)) { + code = '01234567'.indexOf(ch); + + // \0 is not octal escape sequence + if (code !== 0) { + octal = true; + } + + if (index < length && isOctalDigit(source[index])) { + octal = true; + code = code * 8 + '01234567'.indexOf(source[index++]); + + // 3 digits are only allowed when string starts + // with 0, 1, 2, 3 + if ('0123'.indexOf(ch) >= 0 && + index < length && + isOctalDigit(source[index])) { + code = code * 8 + '01234567'.indexOf(source[index++]); + } + } + str += String.fromCharCode(code); + } else { + str += ch; + } + break; + } + } else { + ++lineNumber; + if (ch === '\r' && source[index] === '\n') { + ++index; + } + } + } else if (isLineTerminator(ch)) { + break; + } else { + str += ch; + } + } + + if (quote !== '') { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.StringLiteral, + value: str, + octal: octal, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + function scanRegExp() { + var str, ch, start, pattern, flags, value, classMarker = false, restore, terminated = false; + + buffer = null; + skipComment(); + + start = index; + ch = source[index]; + assert(ch === '/', 'Regular expression literal must start with a slash'); + str = source[index++]; + + while (index < length) { + ch = source[index++]; + str += ch; + if (ch === '\\') { + ch = source[index++]; + // ECMA-262 7.8.5 + if (isLineTerminator(ch)) { + throwError({}, Messages.UnterminatedRegExp); + } + str += ch; + } else if (classMarker) { + if (ch === ']') { + classMarker = false; + } + } else { + if (ch === '/') { + terminated = true; + break; + } else if (ch === '[') { + classMarker = true; + } else if (isLineTerminator(ch)) { + throwError({}, Messages.UnterminatedRegExp); + } + } + } + + if (!terminated) { + throwError({}, Messages.UnterminatedRegExp); + } + + // Exclude leading and trailing slash. + pattern = str.substr(1, str.length - 2); + + flags = ''; + while (index < length) { + ch = source[index]; + if (!isIdentifierPart(ch)) { + break; + } + + ++index; + if (ch === '\\' && index < length) { + ch = source[index]; + if (ch === 'u') { + ++index; + restore = index; + ch = scanHexEscape('u'); + if (ch) { + flags += ch; + str += '\\u'; + for (; restore < index; ++restore) { + str += source[restore]; + } + } else { + index = restore; + flags += 'u'; + str += '\\u'; + } + } else { + str += '\\'; + } + } else { + flags += ch; + str += ch; + } + } + + try { + value = new RegExp(pattern, flags); + } catch (e) { + throwError({}, Messages.InvalidRegExp); + } + + return { + literal: str, + value: value, + range: [start, index] + }; + } + + function isIdentifierName(token) { + return token.type === Token.Identifier || + token.type === Token.Keyword || + token.type === Token.BooleanLiteral || + token.type === Token.NullLiteral; + } + + function advance() { + var ch, token; + + skipComment(); + + if (index >= length) { + return { + type: Token.EOF, + lineNumber: lineNumber, + lineStart: lineStart, + range: [index, index] + }; + } + + token = scanPunctuator(); + if (typeof token !== 'undefined') { + return token; + } + + ch = source[index]; + + if (ch === '\'' || ch === '"') { + return scanStringLiteral(); + } + + if (ch === '.' || isDecimalDigit(ch)) { + return scanNumericLiteral(); + } + + token = scanIdentifier(); + if (typeof token !== 'undefined') { + return token; + } + + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + function lex() { + var token; + + if (buffer) { + index = buffer.range[1]; + lineNumber = buffer.lineNumber; + lineStart = buffer.lineStart; + token = buffer; + buffer = null; + return token; + } + + buffer = null; + return advance(); + } + + function lookahead() { + var pos, line, start; + + if (buffer !== null) { + return buffer; + } + + pos = index; + line = lineNumber; + start = lineStart; + buffer = advance(); + index = pos; + lineNumber = line; + lineStart = start; + + return buffer; + } + + // Return true if there is a line terminator before the next token. + + function peekLineTerminator() { + var pos, line, start, found; + + pos = index; + line = lineNumber; + start = lineStart; + skipComment(); + found = lineNumber !== line; + index = pos; + lineNumber = line; + lineStart = start; + + return found; + } + + // Throw an exception + + function throwError(token, messageFormat) { + var error, + args = Array.prototype.slice.call(arguments, 2), + msg = messageFormat.replace( + /%(\d)/g, + function (whole, index) { + return args[index] || ''; + } + ); + + if (typeof token.lineNumber === 'number') { + error = new Error('Line ' + token.lineNumber + ': ' + msg); + error.index = token.range[0]; + error.lineNumber = token.lineNumber; + error.column = token.range[0] - lineStart + 1; + } else { + error = new Error('Line ' + lineNumber + ': ' + msg); + error.index = index; + error.lineNumber = lineNumber; + error.column = index - lineStart + 1; + } + + throw error; + } + + function throwErrorTolerant() { + try { + throwError.apply(null, arguments); + } catch (e) { + if (extra.errors) { + extra.errors.push(e); + } else { + throw e; + } + } + } + + + // Throw an exception because of the token. + + function throwUnexpected(token) { + if (token.type === Token.EOF) { + throwError(token, Messages.UnexpectedEOS); + } + + if (token.type === Token.NumericLiteral) { + throwError(token, Messages.UnexpectedNumber); + } + + if (token.type === Token.StringLiteral) { + throwError(token, Messages.UnexpectedString); + } + + if (token.type === Token.Identifier) { + throwError(token, Messages.UnexpectedIdentifier); + } + + if (token.type === Token.Keyword) { + if (isFutureReservedWord(token.value)) { + throwError(token, Messages.UnexpectedReserved); + } else if (strict && isStrictModeReservedWord(token.value)) { + throwErrorTolerant(token, Messages.StrictReservedWord); + return; + } + throwError(token, Messages.UnexpectedToken, token.value); + } + + // BooleanLiteral, NullLiteral, or Punctuator. + throwError(token, Messages.UnexpectedToken, token.value); + } + + // Expect the next token to match the specified punctuator. + // If not, an exception will be thrown. + + function expect(value) { + var token = lex(); + if (token.type !== Token.Punctuator || token.value !== value) { + throwUnexpected(token); + } + } + + // Expect the next token to match the specified keyword. + // If not, an exception will be thrown. + + function expectKeyword(keyword) { + var token = lex(); + if (token.type !== Token.Keyword || token.value !== keyword) { + throwUnexpected(token); + } + } + + // Return true if the next token matches the specified punctuator. + + function match(value) { + var token = lookahead(); + return token.type === Token.Punctuator && token.value === value; + } + + // Return true if the next token matches the specified keyword + + function matchKeyword(keyword) { + var token = lookahead(); + return token.type === Token.Keyword && token.value === keyword; + } + + // Return true if the next token is an assignment operator + + function matchAssign() { + var token = lookahead(), + op = token.value; + + if (token.type !== Token.Punctuator) { + return false; + } + return op === '=' || + op === '*=' || + op === '/=' || + op === '%=' || + op === '+=' || + op === '-=' || + op === '<<=' || + op === '>>=' || + op === '>>>=' || + op === '&=' || + op === '^=' || + op === '|='; + } + + function consumeSemicolon() { + var token, line; + + // Catch the very common case first. + if (source[index] === ';') { + lex(); + return; + } + + line = lineNumber; + skipComment(); + if (lineNumber !== line) { + return; + } + + if (match(';')) { + lex(); + return; + } + + token = lookahead(); + if (token.type !== Token.EOF && !match('}')) { + throwUnexpected(token); + } + } + + // Return true if provided expression is LeftHandSideExpression + + function isLeftHandSide(expr) { + return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression; + } + + // 11.1.4 Array Initialiser + + function parseArrayInitialiser() { + var elements = []; + + expect('['); + + while (!match(']')) { + if (match(',')) { + lex(); + elements.push(null); + } else { + elements.push(parseAssignmentExpression()); + + if (!match(']')) { + expect(','); + } + } + } + + expect(']'); + + return { + type: Syntax.ArrayExpression, + elements: elements + }; + } + + // 11.1.5 Object Initialiser + + function parsePropertyFunction(param, first) { + var previousStrict, body; + + previousStrict = strict; + body = parseFunctionSourceElements(); + if (first && strict && isRestrictedWord(param[0].name)) { + throwErrorTolerant(first, Messages.StrictParamName); + } + strict = previousStrict; + + return { + type: Syntax.FunctionExpression, + id: null, + params: param, + defaults: [], + body: body, + rest: null, + generator: false, + expression: false + }; + } + + function parseObjectPropertyKey() { + var token = lex(); + + // Note: This function is called only from parseObjectProperty(), where + // EOF and Punctuator tokens are already filtered out. + + if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) { + if (strict && token.octal) { + throwErrorTolerant(token, Messages.StrictOctalLiteral); + } + return createLiteral(token); + } + + return { + type: Syntax.Identifier, + name: token.value + }; + } + + function parseObjectProperty() { + var token, key, id, param; + + token = lookahead(); + + if (token.type === Token.Identifier) { + + id = parseObjectPropertyKey(); + + // Property Assignment: Getter and Setter. + + if (token.value === 'get' && !match(':')) { + key = parseObjectPropertyKey(); + expect('('); + expect(')'); + return { + type: Syntax.Property, + key: key, + value: parsePropertyFunction([]), + kind: 'get' + }; + } else if (token.value === 'set' && !match(':')) { + key = parseObjectPropertyKey(); + expect('('); + token = lookahead(); + if (token.type !== Token.Identifier) { + expect(')'); + throwErrorTolerant(token, Messages.UnexpectedToken, token.value); + return { + type: Syntax.Property, + key: key, + value: parsePropertyFunction([]), + kind: 'set' + }; + } else { + param = [ parseVariableIdentifier() ]; + expect(')'); + return { + type: Syntax.Property, + key: key, + value: parsePropertyFunction(param, token), + kind: 'set' + }; + } + } else { + expect(':'); + return { + type: Syntax.Property, + key: id, + value: parseAssignmentExpression(), + kind: 'init' + }; + } + } else if (token.type === Token.EOF || token.type === Token.Punctuator) { + throwUnexpected(token); + } else { + key = parseObjectPropertyKey(); + expect(':'); + return { + type: Syntax.Property, + key: key, + value: parseAssignmentExpression(), + kind: 'init' + }; + } + } + + function parseObjectInitialiser() { + var properties = [], property, name, kind, map = {}, toString = String; + + expect('{'); + + while (!match('}')) { + property = parseObjectProperty(); + + if (property.key.type === Syntax.Identifier) { + name = property.key.name; + } else { + name = toString(property.key.value); + } + kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set; + if (Object.prototype.hasOwnProperty.call(map, name)) { + if (map[name] === PropertyKind.Data) { + if (strict && kind === PropertyKind.Data) { + throwErrorTolerant({}, Messages.StrictDuplicateProperty); + } else if (kind !== PropertyKind.Data) { + throwErrorTolerant({}, Messages.AccessorDataProperty); + } + } else { + if (kind === PropertyKind.Data) { + throwErrorTolerant({}, Messages.AccessorDataProperty); + } else if (map[name] & kind) { + throwErrorTolerant({}, Messages.AccessorGetSet); + } + } + map[name] |= kind; + } else { + map[name] = kind; + } + + properties.push(property); + + if (!match('}')) { + expect(','); + } + } + + expect('}'); + + return { + type: Syntax.ObjectExpression, + properties: properties + }; + } + + // 11.1.6 The Grouping Operator + + function parseGroupExpression() { + var expr; + + expect('('); + + expr = parseExpression(); + + expect(')'); + + return expr; + } + + + // 11.1 Primary Expressions + + function parsePrimaryExpression() { + var token = lookahead(), + type = token.type; + + if (type === Token.Identifier) { + return { + type: Syntax.Identifier, + name: lex().value + }; + } + + if (type === Token.StringLiteral || type === Token.NumericLiteral) { + if (strict && token.octal) { + throwErrorTolerant(token, Messages.StrictOctalLiteral); + } + return createLiteral(lex()); + } + + if (type === Token.Keyword) { + if (matchKeyword('this')) { + lex(); + return { + type: Syntax.ThisExpression + }; + } + + if (matchKeyword('function')) { + return parseFunctionExpression(); + } + } + + if (type === Token.BooleanLiteral) { + lex(); + token.value = (token.value === 'true'); + return createLiteral(token); + } + + if (type === Token.NullLiteral) { + lex(); + token.value = null; + return createLiteral(token); + } + + if (match('[')) { + return parseArrayInitialiser(); + } + + if (match('{')) { + return parseObjectInitialiser(); + } + + if (match('(')) { + return parseGroupExpression(); + } + + if (match('/') || match('/=')) { + return createLiteral(scanRegExp()); + } + + return throwUnexpected(lex()); + } + + // 11.2 Left-Hand-Side Expressions + + function parseArguments() { + var args = []; + + expect('('); + + if (!match(')')) { + while (index < length) { + args.push(parseAssignmentExpression()); + if (match(')')) { + break; + } + expect(','); + } + } + + expect(')'); + + return args; + } + + function parseNonComputedProperty() { + var token = lex(); + + if (!isIdentifierName(token)) { + throwUnexpected(token); + } + + return { + type: Syntax.Identifier, + name: token.value + }; + } + + function parseNonComputedMember() { + expect('.'); + + return parseNonComputedProperty(); + } + + function parseComputedMember() { + var expr; + + expect('['); + + expr = parseExpression(); + + expect(']'); + + return expr; + } + + function parseNewExpression() { + var expr; + + expectKeyword('new'); + + expr = { + type: Syntax.NewExpression, + callee: parseLeftHandSideExpression(), + 'arguments': [] + }; + + if (match('(')) { + expr['arguments'] = parseArguments(); + } + + return expr; + } + + function parseLeftHandSideExpressionAllowCall() { + var expr; + + expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); + + while (match('.') || match('[') || match('(')) { + if (match('(')) { + expr = { + type: Syntax.CallExpression, + callee: expr, + 'arguments': parseArguments() + }; + } else if (match('[')) { + expr = { + type: Syntax.MemberExpression, + computed: true, + object: expr, + property: parseComputedMember() + }; + } else { + expr = { + type: Syntax.MemberExpression, + computed: false, + object: expr, + property: parseNonComputedMember() + }; + } + } + + return expr; + } + + + function parseLeftHandSideExpression() { + var expr; + + expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); + + while (match('.') || match('[')) { + if (match('[')) { + expr = { + type: Syntax.MemberExpression, + computed: true, + object: expr, + property: parseComputedMember() + }; + } else { + expr = { + type: Syntax.MemberExpression, + computed: false, + object: expr, + property: parseNonComputedMember() + }; + } + } + + return expr; + } + + // 11.3 Postfix Expressions + + function parsePostfixExpression() { + var expr = parseLeftHandSideExpressionAllowCall(), token; + + token = lookahead(); + if (token.type !== Token.Punctuator) { + return expr; + } + + if ((match('++') || match('--')) && !peekLineTerminator()) { + // 11.3.1, 11.3.2 + if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { + throwErrorTolerant({}, Messages.StrictLHSPostfix); + } + if (!isLeftHandSide(expr)) { + throwErrorTolerant({}, Messages.InvalidLHSInAssignment); + } + + expr = { + type: Syntax.UpdateExpression, + operator: lex().value, + argument: expr, + prefix: false + }; + } + + return expr; + } + + // 11.4 Unary Operators + + function parseUnaryExpression() { + var token, expr; + + token = lookahead(); + if (token.type !== Token.Punctuator && token.type !== Token.Keyword) { + return parsePostfixExpression(); + } + + if (match('++') || match('--')) { + token = lex(); + expr = parseUnaryExpression(); + // 11.4.4, 11.4.5 + if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { + throwErrorTolerant({}, Messages.StrictLHSPrefix); + } + + if (!isLeftHandSide(expr)) { + throwErrorTolerant({}, Messages.InvalidLHSInAssignment); + } + + expr = { + type: Syntax.UpdateExpression, + operator: token.value, + argument: expr, + prefix: true + }; + return expr; + } + + if (match('+') || match('-') || match('~') || match('!')) { + expr = { + type: Syntax.UnaryExpression, + operator: lex().value, + argument: parseUnaryExpression(), + prefix: true + }; + return expr; + } + + if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) { + expr = { + type: Syntax.UnaryExpression, + operator: lex().value, + argument: parseUnaryExpression(), + prefix: true + }; + if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) { + throwErrorTolerant({}, Messages.StrictDelete); + } + return expr; + } + + return parsePostfixExpression(); + } + + // 11.5 Multiplicative Operators + + function parseMultiplicativeExpression() { + var expr = parseUnaryExpression(); + + while (match('*') || match('/') || match('%')) { + expr = { + type: Syntax.BinaryExpression, + operator: lex().value, + left: expr, + right: parseUnaryExpression() + }; + } + + return expr; + } + + // 11.6 Additive Operators + + function parseAdditiveExpression() { + var expr = parseMultiplicativeExpression(); + + while (match('+') || match('-')) { + expr = { + type: Syntax.BinaryExpression, + operator: lex().value, + left: expr, + right: parseMultiplicativeExpression() + }; + } + + return expr; + } + + // 11.7 Bitwise Shift Operators + + function parseShiftExpression() { + var expr = parseAdditiveExpression(); + + while (match('<<') || match('>>') || match('>>>')) { + expr = { + type: Syntax.BinaryExpression, + operator: lex().value, + left: expr, + right: parseAdditiveExpression() + }; + } + + return expr; + } + // 11.8 Relational Operators + + function parseRelationalExpression() { + var expr, previousAllowIn; + + previousAllowIn = state.allowIn; + state.allowIn = true; + + expr = parseShiftExpression(); + + while (match('<') || match('>') || match('<=') || match('>=') || (previousAllowIn && matchKeyword('in')) || matchKeyword('instanceof')) { + expr = { + type: Syntax.BinaryExpression, + operator: lex().value, + left: expr, + right: parseShiftExpression() + }; + } + + state.allowIn = previousAllowIn; + return expr; + } + + // 11.9 Equality Operators + + function parseEqualityExpression() { + var expr = parseRelationalExpression(); + + while (match('==') || match('!=') || match('===') || match('!==')) { + expr = { + type: Syntax.BinaryExpression, + operator: lex().value, + left: expr, + right: parseRelationalExpression() + }; + } + + return expr; + } + + // 11.10 Binary Bitwise Operators + + function parseBitwiseANDExpression() { + var expr = parseEqualityExpression(); + + while (match('&')) { + lex(); + expr = { + type: Syntax.BinaryExpression, + operator: '&', + left: expr, + right: parseEqualityExpression() + }; + } + + return expr; + } + + function parseBitwiseXORExpression() { + var expr = parseBitwiseANDExpression(); + + while (match('^')) { + lex(); + expr = { + type: Syntax.BinaryExpression, + operator: '^', + left: expr, + right: parseBitwiseANDExpression() + }; + } + + return expr; + } + + function parseBitwiseORExpression() { + var expr = parseBitwiseXORExpression(); + + while (match('|')) { + lex(); + expr = { + type: Syntax.BinaryExpression, + operator: '|', + left: expr, + right: parseBitwiseXORExpression() + }; + } + + return expr; + } + + // 11.11 Binary Logical Operators + + function parseLogicalANDExpression() { + var expr = parseBitwiseORExpression(); + + while (match('&&')) { + lex(); + expr = { + type: Syntax.LogicalExpression, + operator: '&&', + left: expr, + right: parseBitwiseORExpression() + }; + } + + return expr; + } + + function parseLogicalORExpression() { + var expr = parseLogicalANDExpression(); + + while (match('||')) { + lex(); + expr = { + type: Syntax.LogicalExpression, + operator: '||', + left: expr, + right: parseLogicalANDExpression() + }; + } + + return expr; + } + + // 11.12 Conditional Operator + + function parseConditionalExpression() { + var expr, previousAllowIn, consequent; + + expr = parseLogicalORExpression(); + + if (match('?')) { + lex(); + previousAllowIn = state.allowIn; + state.allowIn = true; + consequent = parseAssignmentExpression(); + state.allowIn = previousAllowIn; + expect(':'); + + expr = { + type: Syntax.ConditionalExpression, + test: expr, + consequent: consequent, + alternate: parseAssignmentExpression() + }; + } + + return expr; + } + + // 11.13 Assignment Operators + + function parseAssignmentExpression() { + var token, expr; + + token = lookahead(); + expr = parseConditionalExpression(); + + if (matchAssign()) { + // LeftHandSideExpression + if (!isLeftHandSide(expr)) { + throwErrorTolerant({}, Messages.InvalidLHSInAssignment); + } + + // 11.13.1 + if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { + throwErrorTolerant(token, Messages.StrictLHSAssignment); + } + + expr = { + type: Syntax.AssignmentExpression, + operator: lex().value, + left: expr, + right: parseAssignmentExpression() + }; + } + + return expr; + } + + // 11.14 Comma Operator + + function parseExpression() { + var expr = parseAssignmentExpression(); + + if (match(',')) { + expr = { + type: Syntax.SequenceExpression, + expressions: [ expr ] + }; + + while (index < length) { + if (!match(',')) { + break; + } + lex(); + expr.expressions.push(parseAssignmentExpression()); + } + + } + return expr; + } + + // 12.1 Block + + function parseStatementList() { + var list = [], + statement; + + while (index < length) { + if (match('}')) { + break; + } + statement = parseSourceElement(); + if (typeof statement === 'undefined') { + break; + } + list.push(statement); + } + + return list; + } + + function parseBlock() { + var block; + + expect('{'); + + block = parseStatementList(); + + expect('}'); + + return { + type: Syntax.BlockStatement, + body: block + }; + } + + // 12.2 Variable Statement + + function parseVariableIdentifier() { + var token = lex(); + + if (token.type !== Token.Identifier) { + throwUnexpected(token); + } + + return { + type: Syntax.Identifier, + name: token.value + }; + } + + function parseVariableDeclaration(kind) { + var id = parseVariableIdentifier(), + init = null; + + // 12.2.1 + if (strict && isRestrictedWord(id.name)) { + throwErrorTolerant({}, Messages.StrictVarName); + } + + if (kind === 'const') { + expect('='); + init = parseAssignmentExpression(); + } else if (match('=')) { + lex(); + init = parseAssignmentExpression(); + } + + return { + type: Syntax.VariableDeclarator, + id: id, + init: init + }; + } + + function parseVariableDeclarationList(kind) { + var list = []; + + do { + list.push(parseVariableDeclaration(kind)); + if (!match(',')) { + break; + } + lex(); + } while (index < length); + + return list; + } + + function parseVariableStatement() { + var declarations; + + expectKeyword('var'); + + declarations = parseVariableDeclarationList(); + + consumeSemicolon(); + + return { + type: Syntax.VariableDeclaration, + declarations: declarations, + kind: 'var' + }; + } + + // kind may be `const` or `let` + // Both are experimental and not in the specification yet. + // see http://wiki.ecmascript.org/doku.php?id=harmony:const + // and http://wiki.ecmascript.org/doku.php?id=harmony:let + function parseConstLetDeclaration(kind) { + var declarations; + + expectKeyword(kind); + + declarations = parseVariableDeclarationList(kind); + + consumeSemicolon(); + + return { + type: Syntax.VariableDeclaration, + declarations: declarations, + kind: kind + }; + } + + // 12.3 Empty Statement + + function parseEmptyStatement() { + expect(';'); + + return { + type: Syntax.EmptyStatement + }; + } + + // 12.4 Expression Statement + + function parseExpressionStatement() { + var expr = parseExpression(); + + consumeSemicolon(); + + return { + type: Syntax.ExpressionStatement, + expression: expr + }; + } + + // 12.5 If statement + + function parseIfStatement() { + var test, consequent, alternate; + + expectKeyword('if'); + + expect('('); + + test = parseExpression(); + + expect(')'); + + consequent = parseStatement(); + + if (matchKeyword('else')) { + lex(); + alternate = parseStatement(); + } else { + alternate = null; + } + + return { + type: Syntax.IfStatement, + test: test, + consequent: consequent, + alternate: alternate + }; + } + + // 12.6 Iteration Statements + + function parseDoWhileStatement() { + var body, test, oldInIteration; + + expectKeyword('do'); + + oldInIteration = state.inIteration; + state.inIteration = true; + + body = parseStatement(); + + state.inIteration = oldInIteration; + + expectKeyword('while'); + + expect('('); + + test = parseExpression(); + + expect(')'); + + if (match(';')) { + lex(); + } + + return { + type: Syntax.DoWhileStatement, + body: body, + test: test + }; + } + + function parseWhileStatement() { + var test, body, oldInIteration; + + expectKeyword('while'); + + expect('('); + + test = parseExpression(); + + expect(')'); + + oldInIteration = state.inIteration; + state.inIteration = true; + + body = parseStatement(); + + state.inIteration = oldInIteration; + + return { + type: Syntax.WhileStatement, + test: test, + body: body + }; + } + + function parseForVariableDeclaration() { + var token = lex(); + + return { + type: Syntax.VariableDeclaration, + declarations: parseVariableDeclarationList(), + kind: token.value + }; + } + + function parseForStatement() { + var init, test, update, left, right, body, oldInIteration; + + init = test = update = null; + + expectKeyword('for'); + + expect('('); + + if (match(';')) { + lex(); + } else { + if (matchKeyword('var') || matchKeyword('let')) { + state.allowIn = false; + init = parseForVariableDeclaration(); + state.allowIn = true; + + if (init.declarations.length === 1 && matchKeyword('in')) { + lex(); + left = init; + right = parseExpression(); + init = null; + } + } else { + state.allowIn = false; + init = parseExpression(); + state.allowIn = true; + + if (matchKeyword('in')) { + // LeftHandSideExpression + if (!isLeftHandSide(init)) { + throwErrorTolerant({}, Messages.InvalidLHSInForIn); + } + + lex(); + left = init; + right = parseExpression(); + init = null; + } + } + + if (typeof left === 'undefined') { + expect(';'); + } + } + + if (typeof left === 'undefined') { + + if (!match(';')) { + test = parseExpression(); + } + expect(';'); + + if (!match(')')) { + update = parseExpression(); + } + } + + expect(')'); + + oldInIteration = state.inIteration; + state.inIteration = true; + + body = parseStatement(); + + state.inIteration = oldInIteration; + + if (typeof left === 'undefined') { + return { + type: Syntax.ForStatement, + init: init, + test: test, + update: update, + body: body + }; + } + + return { + type: Syntax.ForInStatement, + left: left, + right: right, + body: body, + each: false + }; + } + + // 12.7 The continue statement + + function parseContinueStatement() { + var token, label = null; + + expectKeyword('continue'); + + // Optimize the most common form: 'continue;'. + if (source[index] === ';') { + lex(); + + if (!state.inIteration) { + throwError({}, Messages.IllegalContinue); + } + + return { + type: Syntax.ContinueStatement, + label: null + }; + } + + if (peekLineTerminator()) { + if (!state.inIteration) { + throwError({}, Messages.IllegalContinue); + } + + return { + type: Syntax.ContinueStatement, + label: null + }; + } + + token = lookahead(); + if (token.type === Token.Identifier) { + label = parseVariableIdentifier(); + + if (!Object.prototype.hasOwnProperty.call(state.labelSet, label.name)) { + throwError({}, Messages.UnknownLabel, label.name); + } + } + + consumeSemicolon(); + + if (label === null && !state.inIteration) { + throwError({}, Messages.IllegalContinue); + } + + return { + type: Syntax.ContinueStatement, + label: label + }; + } + + // 12.8 The break statement + + function parseBreakStatement() { + var token, label = null; + + expectKeyword('break'); + + // Optimize the most common form: 'break;'. + if (source[index] === ';') { + lex(); + + if (!(state.inIteration || state.inSwitch)) { + throwError({}, Messages.IllegalBreak); + } + + return { + type: Syntax.BreakStatement, + label: null + }; + } + + if (peekLineTerminator()) { + if (!(state.inIteration || state.inSwitch)) { + throwError({}, Messages.IllegalBreak); + } + + return { + type: Syntax.BreakStatement, + label: null + }; + } + + token = lookahead(); + if (token.type === Token.Identifier) { + label = parseVariableIdentifier(); + + if (!Object.prototype.hasOwnProperty.call(state.labelSet, label.name)) { + throwError({}, Messages.UnknownLabel, label.name); + } + } + + consumeSemicolon(); + + if (label === null && !(state.inIteration || state.inSwitch)) { + throwError({}, Messages.IllegalBreak); + } + + return { + type: Syntax.BreakStatement, + label: label + }; + } + + // 12.9 The return statement + + function parseReturnStatement() { + var token, argument = null; + + expectKeyword('return'); + + if (!state.inFunctionBody) { + throwErrorTolerant({}, Messages.IllegalReturn); + } + + // 'return' followed by a space and an identifier is very common. + if (source[index] === ' ') { + if (isIdentifierStart(source[index + 1])) { + argument = parseExpression(); + consumeSemicolon(); + return { + type: Syntax.ReturnStatement, + argument: argument + }; + } + } + + if (peekLineTerminator()) { + return { + type: Syntax.ReturnStatement, + argument: null + }; + } + + if (!match(';')) { + token = lookahead(); + if (!match('}') && token.type !== Token.EOF) { + argument = parseExpression(); + } + } + + consumeSemicolon(); + + return { + type: Syntax.ReturnStatement, + argument: argument + }; + } + + // 12.10 The with statement + + function parseWithStatement() { + var object, body; + + if (strict) { + throwErrorTolerant({}, Messages.StrictModeWith); + } + + expectKeyword('with'); + + expect('('); + + object = parseExpression(); + + expect(')'); + + body = parseStatement(); + + return { + type: Syntax.WithStatement, + object: object, + body: body + }; + } + + // 12.10 The swith statement + + function parseSwitchCase() { + var test, + consequent = [], + statement; + + if (matchKeyword('default')) { + lex(); + test = null; + } else { + expectKeyword('case'); + test = parseExpression(); + } + expect(':'); + + while (index < length) { + if (match('}') || matchKeyword('default') || matchKeyword('case')) { + break; + } + statement = parseStatement(); + if (typeof statement === 'undefined') { + break; + } + consequent.push(statement); + } + + return { + type: Syntax.SwitchCase, + test: test, + consequent: consequent + }; + } + + function parseSwitchStatement() { + var discriminant, cases, clause, oldInSwitch, defaultFound; + + expectKeyword('switch'); + + expect('('); + + discriminant = parseExpression(); + + expect(')'); + + expect('{'); + + cases = []; + + if (match('}')) { + lex(); + return { + type: Syntax.SwitchStatement, + discriminant: discriminant, + cases: cases + }; + } + + oldInSwitch = state.inSwitch; + state.inSwitch = true; + defaultFound = false; + + while (index < length) { + if (match('}')) { + break; + } + clause = parseSwitchCase(); + if (clause.test === null) { + if (defaultFound) { + throwError({}, Messages.MultipleDefaultsInSwitch); + } + defaultFound = true; + } + cases.push(clause); + } + + state.inSwitch = oldInSwitch; + + expect('}'); + + return { + type: Syntax.SwitchStatement, + discriminant: discriminant, + cases: cases + }; + } + + // 12.13 The throw statement + + function parseThrowStatement() { + var argument; + + expectKeyword('throw'); + + if (peekLineTerminator()) { + throwError({}, Messages.NewlineAfterThrow); + } + + argument = parseExpression(); + + consumeSemicolon(); + + return { + type: Syntax.ThrowStatement, + argument: argument + }; + } + + // 12.14 The try statement + + function parseCatchClause() { + var param; + + expectKeyword('catch'); + + expect('('); + if (match(')')) { + throwUnexpected(lookahead()); + } + + param = parseVariableIdentifier(); + // 12.14.1 + if (strict && isRestrictedWord(param.name)) { + throwErrorTolerant({}, Messages.StrictCatchVariable); + } + + expect(')'); + + return { + type: Syntax.CatchClause, + param: param, + body: parseBlock() + }; + } + + function parseTryStatement() { + var block, handlers = [], finalizer = null; + + expectKeyword('try'); + + block = parseBlock(); + + if (matchKeyword('catch')) { + handlers.push(parseCatchClause()); + } + + if (matchKeyword('finally')) { + lex(); + finalizer = parseBlock(); + } + + if (handlers.length === 0 && !finalizer) { + throwError({}, Messages.NoCatchOrFinally); + } + + return { + type: Syntax.TryStatement, + block: block, + guardedHandlers: [], + handlers: handlers, + finalizer: finalizer + }; + } + + // 12.15 The debugger statement + + function parseDebuggerStatement() { + expectKeyword('debugger'); + + consumeSemicolon(); + + return { + type: Syntax.DebuggerStatement + }; + } + + // 12 Statements + + function parseStatement() { + var token = lookahead(), + expr, + labeledBody; + + if (token.type === Token.EOF) { + throwUnexpected(token); + } + + if (token.type === Token.Punctuator) { + switch (token.value) { + case ';': + return parseEmptyStatement(); + case '{': + return parseBlock(); + case '(': + return parseExpressionStatement(); + default: + break; + } + } + + if (token.type === Token.Keyword) { + switch (token.value) { + case 'break': + return parseBreakStatement(); + case 'continue': + return parseContinueStatement(); + case 'debugger': + return parseDebuggerStatement(); + case 'do': + return parseDoWhileStatement(); + case 'for': + return parseForStatement(); + case 'function': + return parseFunctionDeclaration(); + case 'if': + return parseIfStatement(); + case 'return': + return parseReturnStatement(); + case 'switch': + return parseSwitchStatement(); + case 'throw': + return parseThrowStatement(); + case 'try': + return parseTryStatement(); + case 'var': + return parseVariableStatement(); + case 'while': + return parseWhileStatement(); + case 'with': + return parseWithStatement(); + default: + break; + } + } + + expr = parseExpression(); + + // 12.12 Labelled Statements + if ((expr.type === Syntax.Identifier) && match(':')) { + lex(); + + if (Object.prototype.hasOwnProperty.call(state.labelSet, expr.name)) { + throwError({}, Messages.Redeclaration, 'Label', expr.name); + } + + state.labelSet[expr.name] = true; + labeledBody = parseStatement(); + delete state.labelSet[expr.name]; + + return { + type: Syntax.LabeledStatement, + label: expr, + body: labeledBody + }; + } + + consumeSemicolon(); + + return { + type: Syntax.ExpressionStatement, + expression: expr + }; + } + + // 13 Function Definition + + function parseFunctionSourceElements() { + var sourceElement, sourceElements = [], token, directive, firstRestricted, + oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody; + + expect('{'); + + while (index < length) { + token = lookahead(); + if (token.type !== Token.StringLiteral) { + break; + } + + sourceElement = parseSourceElement(); + sourceElements.push(sourceElement); + if (sourceElement.expression.type !== Syntax.Literal) { + // this is not directive + break; + } + directive = sliceSource(token.range[0] + 1, token.range[1] - 1); + if (directive === 'use strict') { + strict = true; + if (firstRestricted) { + throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral); + } + } else { + if (!firstRestricted && token.octal) { + firstRestricted = token; + } + } + } + + oldLabelSet = state.labelSet; + oldInIteration = state.inIteration; + oldInSwitch = state.inSwitch; + oldInFunctionBody = state.inFunctionBody; + + state.labelSet = {}; + state.inIteration = false; + state.inSwitch = false; + state.inFunctionBody = true; + + while (index < length) { + if (match('}')) { + break; + } + sourceElement = parseSourceElement(); + if (typeof sourceElement === 'undefined') { + break; + } + sourceElements.push(sourceElement); + } + + expect('}'); + + state.labelSet = oldLabelSet; + state.inIteration = oldInIteration; + state.inSwitch = oldInSwitch; + state.inFunctionBody = oldInFunctionBody; + + return { + type: Syntax.BlockStatement, + body: sourceElements + }; + } + + function parseFunctionDeclaration() { + var id, param, params = [], body, token, stricted, firstRestricted, message, previousStrict, paramSet; + + expectKeyword('function'); + token = lookahead(); + id = parseVariableIdentifier(); + if (strict) { + if (isRestrictedWord(token.value)) { + throwErrorTolerant(token, Messages.StrictFunctionName); + } + } else { + if (isRestrictedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictFunctionName; + } else if (isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictReservedWord; + } + } + + expect('('); + + if (!match(')')) { + paramSet = {}; + while (index < length) { + token = lookahead(); + param = parseVariableIdentifier(); + if (strict) { + if (isRestrictedWord(token.value)) { + stricted = token; + message = Messages.StrictParamName; + } + if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) { + stricted = token; + message = Messages.StrictParamDupe; + } + } else if (!firstRestricted) { + if (isRestrictedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictParamName; + } else if (isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictReservedWord; + } else if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) { + firstRestricted = token; + message = Messages.StrictParamDupe; + } + } + params.push(param); + paramSet[param.name] = true; + if (match(')')) { + break; + } + expect(','); + } + } + + expect(')'); + + previousStrict = strict; + body = parseFunctionSourceElements(); + if (strict && firstRestricted) { + throwError(firstRestricted, message); + } + if (strict && stricted) { + throwErrorTolerant(stricted, message); + } + strict = previousStrict; + + return { + type: Syntax.FunctionDeclaration, + id: id, + params: params, + defaults: [], + body: body, + rest: null, + generator: false, + expression: false + }; + } + + function parseFunctionExpression() { + var token, id = null, stricted, firstRestricted, message, param, params = [], body, previousStrict, paramSet; + + expectKeyword('function'); + + if (!match('(')) { + token = lookahead(); + id = parseVariableIdentifier(); + if (strict) { + if (isRestrictedWord(token.value)) { + throwErrorTolerant(token, Messages.StrictFunctionName); + } + } else { + if (isRestrictedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictFunctionName; + } else if (isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictReservedWord; + } + } + } + + expect('('); + + if (!match(')')) { + paramSet = {}; + while (index < length) { + token = lookahead(); + param = parseVariableIdentifier(); + if (strict) { + if (isRestrictedWord(token.value)) { + stricted = token; + message = Messages.StrictParamName; + } + if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) { + stricted = token; + message = Messages.StrictParamDupe; + } + } else if (!firstRestricted) { + if (isRestrictedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictParamName; + } else if (isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictReservedWord; + } else if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) { + firstRestricted = token; + message = Messages.StrictParamDupe; + } + } + params.push(param); + paramSet[param.name] = true; + if (match(')')) { + break; + } + expect(','); + } + } + + expect(')'); + + previousStrict = strict; + body = parseFunctionSourceElements(); + if (strict && firstRestricted) { + throwError(firstRestricted, message); + } + if (strict && stricted) { + throwErrorTolerant(stricted, message); + } + strict = previousStrict; + + return { + type: Syntax.FunctionExpression, + id: id, + params: params, + defaults: [], + body: body, + rest: null, + generator: false, + expression: false + }; + } + + // 14 Program + + function parseSourceElement() { + var token = lookahead(); + + if (token.type === Token.Keyword) { + switch (token.value) { + case 'const': + case 'let': + return parseConstLetDeclaration(token.value); + case 'function': + return parseFunctionDeclaration(); + default: + return parseStatement(); + } + } + + if (token.type !== Token.EOF) { + return parseStatement(); + } + } + + function parseSourceElements() { + var sourceElement, sourceElements = [], token, directive, firstRestricted; + + while (index < length) { + token = lookahead(); + if (token.type !== Token.StringLiteral) { + break; + } + + sourceElement = parseSourceElement(); + sourceElements.push(sourceElement); + if (sourceElement.expression.type !== Syntax.Literal) { + // this is not directive + break; + } + directive = sliceSource(token.range[0] + 1, token.range[1] - 1); + if (directive === 'use strict') { + strict = true; + if (firstRestricted) { + throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral); + } + } else { + if (!firstRestricted && token.octal) { + firstRestricted = token; + } + } + } + + while (index < length) { + sourceElement = parseSourceElement(); + if (typeof sourceElement === 'undefined') { + break; + } + sourceElements.push(sourceElement); + } + return sourceElements; + } + + function parseProgram() { + var program; + strict = false; + program = { + type: Syntax.Program, + body: parseSourceElements() + }; + return program; + } + + // The following functions are needed only when the option to preserve + // the comments is active. + + function addComment(type, value, start, end, loc) { + assert(typeof start === 'number', 'Comment must have valid position'); + + // Because the way the actual token is scanned, often the comments + // (if any) are skipped twice during the lexical analysis. + // Thus, we need to skip adding a comment if the comment array already + // handled it. + if (extra.comments.length > 0) { + if (extra.comments[extra.comments.length - 1].range[1] > start) { + return; + } + } + + extra.comments.push({ + type: type, + value: value, + range: [start, end], + loc: loc + }); + } + + function scanComment() { + var comment, ch, loc, start, blockComment, lineComment; + + comment = ''; + blockComment = false; + lineComment = false; + + while (index < length) { + ch = source[index]; + + if (lineComment) { + ch = source[index++]; + if (isLineTerminator(ch)) { + loc.end = { + line: lineNumber, + column: index - lineStart - 1 + }; + lineComment = false; + addComment('Line', comment, start, index - 1, loc); + if (ch === '\r' && source[index] === '\n') { + ++index; + } + ++lineNumber; + lineStart = index; + comment = ''; + } else if (index >= length) { + lineComment = false; + comment += ch; + loc.end = { + line: lineNumber, + column: length - lineStart + }; + addComment('Line', comment, start, length, loc); + } else { + comment += ch; + } + } else if (blockComment) { + if (isLineTerminator(ch)) { + if (ch === '\r' && source[index + 1] === '\n') { + ++index; + comment += '\r\n'; + } else { + comment += ch; + } + ++lineNumber; + ++index; + lineStart = index; + if (index >= length) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } else { + ch = source[index++]; + if (index >= length) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + comment += ch; + if (ch === '*') { + ch = source[index]; + if (ch === '/') { + comment = comment.substr(0, comment.length - 1); + blockComment = false; + ++index; + loc.end = { + line: lineNumber, + column: index - lineStart + }; + addComment('Block', comment, start, index, loc); + comment = ''; + } + } + } + } else if (ch === '/') { + ch = source[index + 1]; + if (ch === '/') { + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + start = index; + index += 2; + lineComment = true; + if (index >= length) { + loc.end = { + line: lineNumber, + column: index - lineStart + }; + lineComment = false; + addComment('Line', comment, start, index, loc); + } + } else if (ch === '*') { + start = index; + index += 2; + blockComment = true; + loc = { + start: { + line: lineNumber, + column: index - lineStart - 2 + } + }; + if (index >= length) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } else { + break; + } + } else if (isWhiteSpace(ch)) { + ++index; + } else if (isLineTerminator(ch)) { + ++index; + if (ch === '\r' && source[index] === '\n') { + ++index; + } + ++lineNumber; + lineStart = index; + } else { + break; + } + } + } + + function filterCommentLocation() { + var i, entry, comment, comments = []; + + for (i = 0; i < extra.comments.length; ++i) { + entry = extra.comments[i]; + comment = { + type: entry.type, + value: entry.value + }; + if (extra.range) { + comment.range = entry.range; + } + if (extra.loc) { + comment.loc = entry.loc; + } + comments.push(comment); + } + + extra.comments = comments; + } + + function collectToken() { + var start, loc, token, range, value; + + skipComment(); + start = index; + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + + token = extra.advance(); + loc.end = { + line: lineNumber, + column: index - lineStart + }; + + if (token.type !== Token.EOF) { + range = [token.range[0], token.range[1]]; + value = sliceSource(token.range[0], token.range[1]); + extra.tokens.push({ + type: TokenName[token.type], + value: value, + range: range, + loc: loc + }); + } + + return token; + } + + function collectRegex() { + var pos, loc, regex, token; + + skipComment(); + + pos = index; + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + + regex = extra.scanRegExp(); + loc.end = { + line: lineNumber, + column: index - lineStart + }; + + // Pop the previous token, which is likely '/' or '/=' + if (extra.tokens.length > 0) { + token = extra.tokens[extra.tokens.length - 1]; + if (token.range[0] === pos && token.type === 'Punctuator') { + if (token.value === '/' || token.value === '/=') { + extra.tokens.pop(); + } + } + } + + extra.tokens.push({ + type: 'RegularExpression', + value: regex.literal, + range: [pos, index], + loc: loc + }); + + return regex; + } + + function filterTokenLocation() { + var i, entry, token, tokens = []; + + for (i = 0; i < extra.tokens.length; ++i) { + entry = extra.tokens[i]; + token = { + type: entry.type, + value: entry.value + }; + if (extra.range) { + token.range = entry.range; + } + if (extra.loc) { + token.loc = entry.loc; + } + tokens.push(token); + } + + extra.tokens = tokens; + } + + function createLiteral(token) { + return { + type: Syntax.Literal, + value: token.value + }; + } + + function createRawLiteral(token) { + return { + type: Syntax.Literal, + value: token.value, + raw: sliceSource(token.range[0], token.range[1]) + }; + } + + function createLocationMarker() { + var marker = {}; + + marker.range = [index, index]; + marker.loc = { + start: { + line: lineNumber, + column: index - lineStart + }, + end: { + line: lineNumber, + column: index - lineStart + } + }; + + marker.end = function () { + this.range[1] = index; + this.loc.end.line = lineNumber; + this.loc.end.column = index - lineStart; + }; + + marker.applyGroup = function (node) { + if (extra.range) { + node.groupRange = [this.range[0], this.range[1]]; + } + if (extra.loc) { + node.groupLoc = { + start: { + line: this.loc.start.line, + column: this.loc.start.column + }, + end: { + line: this.loc.end.line, + column: this.loc.end.column + } + }; + } + }; + + marker.apply = function (node) { + if (extra.range) { + node.range = [this.range[0], this.range[1]]; + } + if (extra.loc) { + node.loc = { + start: { + line: this.loc.start.line, + column: this.loc.start.column + }, + end: { + line: this.loc.end.line, + column: this.loc.end.column + } + }; + } + }; + + return marker; + } + + function trackGroupExpression() { + var marker, expr; + + skipComment(); + marker = createLocationMarker(); + expect('('); + + expr = parseExpression(); + + expect(')'); + + marker.end(); + marker.applyGroup(expr); + + return expr; + } + + function trackLeftHandSideExpression() { + var marker, expr; + + skipComment(); + marker = createLocationMarker(); + + expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); + + while (match('.') || match('[')) { + if (match('[')) { + expr = { + type: Syntax.MemberExpression, + computed: true, + object: expr, + property: parseComputedMember() + }; + marker.end(); + marker.apply(expr); + } else { + expr = { + type: Syntax.MemberExpression, + computed: false, + object: expr, + property: parseNonComputedMember() + }; + marker.end(); + marker.apply(expr); + } + } + + return expr; + } + + function trackLeftHandSideExpressionAllowCall() { + var marker, expr; + + skipComment(); + marker = createLocationMarker(); + + expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); + + while (match('.') || match('[') || match('(')) { + if (match('(')) { + expr = { + type: Syntax.CallExpression, + callee: expr, + 'arguments': parseArguments() + }; + marker.end(); + marker.apply(expr); + } else if (match('[')) { + expr = { + type: Syntax.MemberExpression, + computed: true, + object: expr, + property: parseComputedMember() + }; + marker.end(); + marker.apply(expr); + } else { + expr = { + type: Syntax.MemberExpression, + computed: false, + object: expr, + property: parseNonComputedMember() + }; + marker.end(); + marker.apply(expr); + } + } + + return expr; + } + + function filterGroup(node) { + var n, i, entry; + + n = (Object.prototype.toString.apply(node) === '[object Array]') ? [] : {}; + for (i in node) { + if (node.hasOwnProperty(i) && i !== 'groupRange' && i !== 'groupLoc') { + entry = node[i]; + if (entry === null || typeof entry !== 'object' || entry instanceof RegExp) { + n[i] = entry; + } else { + n[i] = filterGroup(entry); + } + } + } + return n; + } + + function wrapTrackingFunction(range, loc) { + + return function (parseFunction) { + + function isBinary(node) { + return node.type === Syntax.LogicalExpression || + node.type === Syntax.BinaryExpression; + } + + function visit(node) { + var start, end; + + if (isBinary(node.left)) { + visit(node.left); + } + if (isBinary(node.right)) { + visit(node.right); + } + + if (range) { + if (node.left.groupRange || node.right.groupRange) { + start = node.left.groupRange ? node.left.groupRange[0] : node.left.range[0]; + end = node.right.groupRange ? node.right.groupRange[1] : node.right.range[1]; + node.range = [start, end]; + } else if (typeof node.range === 'undefined') { + start = node.left.range[0]; + end = node.right.range[1]; + node.range = [start, end]; + } + } + if (loc) { + if (node.left.groupLoc || node.right.groupLoc) { + start = node.left.groupLoc ? node.left.groupLoc.start : node.left.loc.start; + end = node.right.groupLoc ? node.right.groupLoc.end : node.right.loc.end; + node.loc = { + start: start, + end: end + }; + } else if (typeof node.loc === 'undefined') { + node.loc = { + start: node.left.loc.start, + end: node.right.loc.end + }; + } + } + } + + return function () { + var marker, node; + + skipComment(); + + marker = createLocationMarker(); + node = parseFunction.apply(null, arguments); + marker.end(); + + if (range && typeof node.range === 'undefined') { + marker.apply(node); + } + + if (loc && typeof node.loc === 'undefined') { + marker.apply(node); + } + + if (isBinary(node)) { + visit(node); + } + + return node; + }; + }; + } + + function patch() { + + var wrapTracking; + + if (extra.comments) { + extra.skipComment = skipComment; + skipComment = scanComment; + } + + if (extra.raw) { + extra.createLiteral = createLiteral; + createLiteral = createRawLiteral; + } + + if (extra.range || extra.loc) { + + extra.parseGroupExpression = parseGroupExpression; + extra.parseLeftHandSideExpression = parseLeftHandSideExpression; + extra.parseLeftHandSideExpressionAllowCall = parseLeftHandSideExpressionAllowCall; + parseGroupExpression = trackGroupExpression; + parseLeftHandSideExpression = trackLeftHandSideExpression; + parseLeftHandSideExpressionAllowCall = trackLeftHandSideExpressionAllowCall; + + wrapTracking = wrapTrackingFunction(extra.range, extra.loc); + + extra.parseAdditiveExpression = parseAdditiveExpression; + extra.parseAssignmentExpression = parseAssignmentExpression; + extra.parseBitwiseANDExpression = parseBitwiseANDExpression; + extra.parseBitwiseORExpression = parseBitwiseORExpression; + extra.parseBitwiseXORExpression = parseBitwiseXORExpression; + extra.parseBlock = parseBlock; + extra.parseFunctionSourceElements = parseFunctionSourceElements; + extra.parseCatchClause = parseCatchClause; + extra.parseComputedMember = parseComputedMember; + extra.parseConditionalExpression = parseConditionalExpression; + extra.parseConstLetDeclaration = parseConstLetDeclaration; + extra.parseEqualityExpression = parseEqualityExpression; + extra.parseExpression = parseExpression; + extra.parseForVariableDeclaration = parseForVariableDeclaration; + extra.parseFunctionDeclaration = parseFunctionDeclaration; + extra.parseFunctionExpression = parseFunctionExpression; + extra.parseLogicalANDExpression = parseLogicalANDExpression; + extra.parseLogicalORExpression = parseLogicalORExpression; + extra.parseMultiplicativeExpression = parseMultiplicativeExpression; + extra.parseNewExpression = parseNewExpression; + extra.parseNonComputedProperty = parseNonComputedProperty; + extra.parseObjectProperty = parseObjectProperty; + extra.parseObjectPropertyKey = parseObjectPropertyKey; + extra.parsePostfixExpression = parsePostfixExpression; + extra.parsePrimaryExpression = parsePrimaryExpression; + extra.parseProgram = parseProgram; + extra.parsePropertyFunction = parsePropertyFunction; + extra.parseRelationalExpression = parseRelationalExpression; + extra.parseStatement = parseStatement; + extra.parseShiftExpression = parseShiftExpression; + extra.parseSwitchCase = parseSwitchCase; + extra.parseUnaryExpression = parseUnaryExpression; + extra.parseVariableDeclaration = parseVariableDeclaration; + extra.parseVariableIdentifier = parseVariableIdentifier; + + parseAdditiveExpression = wrapTracking(extra.parseAdditiveExpression); + parseAssignmentExpression = wrapTracking(extra.parseAssignmentExpression); + parseBitwiseANDExpression = wrapTracking(extra.parseBitwiseANDExpression); + parseBitwiseORExpression = wrapTracking(extra.parseBitwiseORExpression); + parseBitwiseXORExpression = wrapTracking(extra.parseBitwiseXORExpression); + parseBlock = wrapTracking(extra.parseBlock); + parseFunctionSourceElements = wrapTracking(extra.parseFunctionSourceElements); + parseCatchClause = wrapTracking(extra.parseCatchClause); + parseComputedMember = wrapTracking(extra.parseComputedMember); + parseConditionalExpression = wrapTracking(extra.parseConditionalExpression); + parseConstLetDeclaration = wrapTracking(extra.parseConstLetDeclaration); + parseEqualityExpression = wrapTracking(extra.parseEqualityExpression); + parseExpression = wrapTracking(extra.parseExpression); + parseForVariableDeclaration = wrapTracking(extra.parseForVariableDeclaration); + parseFunctionDeclaration = wrapTracking(extra.parseFunctionDeclaration); + parseFunctionExpression = wrapTracking(extra.parseFunctionExpression); + parseLeftHandSideExpression = wrapTracking(parseLeftHandSideExpression); + parseLogicalANDExpression = wrapTracking(extra.parseLogicalANDExpression); + parseLogicalORExpression = wrapTracking(extra.parseLogicalORExpression); + parseMultiplicativeExpression = wrapTracking(extra.parseMultiplicativeExpression); + parseNewExpression = wrapTracking(extra.parseNewExpression); + parseNonComputedProperty = wrapTracking(extra.parseNonComputedProperty); + parseObjectProperty = wrapTracking(extra.parseObjectProperty); + parseObjectPropertyKey = wrapTracking(extra.parseObjectPropertyKey); + parsePostfixExpression = wrapTracking(extra.parsePostfixExpression); + parsePrimaryExpression = wrapTracking(extra.parsePrimaryExpression); + parseProgram = wrapTracking(extra.parseProgram); + parsePropertyFunction = wrapTracking(extra.parsePropertyFunction); + parseRelationalExpression = wrapTracking(extra.parseRelationalExpression); + parseStatement = wrapTracking(extra.parseStatement); + parseShiftExpression = wrapTracking(extra.parseShiftExpression); + parseSwitchCase = wrapTracking(extra.parseSwitchCase); + parseUnaryExpression = wrapTracking(extra.parseUnaryExpression); + parseVariableDeclaration = wrapTracking(extra.parseVariableDeclaration); + parseVariableIdentifier = wrapTracking(extra.parseVariableIdentifier); + } + + if (typeof extra.tokens !== 'undefined') { + extra.advance = advance; + extra.scanRegExp = scanRegExp; + + advance = collectToken; + scanRegExp = collectRegex; + } + } + + function unpatch() { + if (typeof extra.skipComment === 'function') { + skipComment = extra.skipComment; + } + + if (extra.raw) { + createLiteral = extra.createLiteral; + } + + if (extra.range || extra.loc) { + parseAdditiveExpression = extra.parseAdditiveExpression; + parseAssignmentExpression = extra.parseAssignmentExpression; + parseBitwiseANDExpression = extra.parseBitwiseANDExpression; + parseBitwiseORExpression = extra.parseBitwiseORExpression; + parseBitwiseXORExpression = extra.parseBitwiseXORExpression; + parseBlock = extra.parseBlock; + parseFunctionSourceElements = extra.parseFunctionSourceElements; + parseCatchClause = extra.parseCatchClause; + parseComputedMember = extra.parseComputedMember; + parseConditionalExpression = extra.parseConditionalExpression; + parseConstLetDeclaration = extra.parseConstLetDeclaration; + parseEqualityExpression = extra.parseEqualityExpression; + parseExpression = extra.parseExpression; + parseForVariableDeclaration = extra.parseForVariableDeclaration; + parseFunctionDeclaration = extra.parseFunctionDeclaration; + parseFunctionExpression = extra.parseFunctionExpression; + parseGroupExpression = extra.parseGroupExpression; + parseLeftHandSideExpression = extra.parseLeftHandSideExpression; + parseLeftHandSideExpressionAllowCall = extra.parseLeftHandSideExpressionAllowCall; + parseLogicalANDExpression = extra.parseLogicalANDExpression; + parseLogicalORExpression = extra.parseLogicalORExpression; + parseMultiplicativeExpression = extra.parseMultiplicativeExpression; + parseNewExpression = extra.parseNewExpression; + parseNonComputedProperty = extra.parseNonComputedProperty; + parseObjectProperty = extra.parseObjectProperty; + parseObjectPropertyKey = extra.parseObjectPropertyKey; + parsePrimaryExpression = extra.parsePrimaryExpression; + parsePostfixExpression = extra.parsePostfixExpression; + parseProgram = extra.parseProgram; + parsePropertyFunction = extra.parsePropertyFunction; + parseRelationalExpression = extra.parseRelationalExpression; + parseStatement = extra.parseStatement; + parseShiftExpression = extra.parseShiftExpression; + parseSwitchCase = extra.parseSwitchCase; + parseUnaryExpression = extra.parseUnaryExpression; + parseVariableDeclaration = extra.parseVariableDeclaration; + parseVariableIdentifier = extra.parseVariableIdentifier; + } + + if (typeof extra.scanRegExp === 'function') { + advance = extra.advance; + scanRegExp = extra.scanRegExp; + } + } + + function stringToArray(str) { + var length = str.length, + result = [], + i; + for (i = 0; i < length; ++i) { + result[i] = str.charAt(i); + } + return result; + } + + function parse(code, options) { + var program, toString; + + toString = String; + if (typeof code !== 'string' && !(code instanceof String)) { + code = toString(code); + } + + source = code; + index = 0; + lineNumber = (source.length > 0) ? 1 : 0; + lineStart = 0; + length = source.length; + buffer = null; + state = { + allowIn: true, + labelSet: {}, + inFunctionBody: false, + inIteration: false, + inSwitch: false + }; + + extra = {}; + if (typeof options !== 'undefined') { + extra.range = (typeof options.range === 'boolean') && options.range; + extra.loc = (typeof options.loc === 'boolean') && options.loc; + extra.raw = (typeof options.raw === 'boolean') && options.raw; + if (typeof options.tokens === 'boolean' && options.tokens) { + extra.tokens = []; + } + if (typeof options.comment === 'boolean' && options.comment) { + extra.comments = []; + } + if (typeof options.tolerant === 'boolean' && options.tolerant) { + extra.errors = []; + } + } + + if (length > 0) { + if (typeof source[0] === 'undefined') { + // Try first to convert to a string. This is good as fast path + // for old IE which understands string indexing for string + // literals only and not for string object. + if (code instanceof String) { + source = code.valueOf(); + } + + // Force accessing the characters via an array. + if (typeof source[0] === 'undefined') { + source = stringToArray(code); + } + } + } + + patch(); + try { + program = parseProgram(); + if (typeof extra.comments !== 'undefined') { + filterCommentLocation(); + program.comments = extra.comments; + } + if (typeof extra.tokens !== 'undefined') { + filterTokenLocation(); + program.tokens = extra.tokens; + } + if (typeof extra.errors !== 'undefined') { + program.errors = extra.errors; + } + if (extra.range || extra.loc) { + program.body = filterGroup(program.body); + } + } catch (e) { + throw e; + } finally { + unpatch(); + extra = {}; + } + + return program; + } + + // Sync with package.json. + exports.version = '1.0.4'; + + exports.parse = parse; + + // Deep copy. + exports.Syntax = (function () { + var name, types = {}; + + if (typeof Object.create === 'function') { + types = Object.create(null); + } + + for (name in Syntax) { + if (Syntax.hasOwnProperty(name)) { + types[name] = Syntax[name]; + } + } + + if (typeof Object.freeze === 'function') { + Object.freeze(types); + } + + return types; + }()); + +})); +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/esprima/package.json b/node_modules/esprima/package.json new file mode 100644 index 0000000..e839a55 --- /dev/null +++ b/node_modules/esprima/package.json @@ -0,0 +1,104 @@ +{ + "_args": [ + [ + { + "raw": "esprima@~ 1.0.2", + "scope": null, + "escapedName": "esprima", + "name": "esprima", + "rawSpec": "~ 1.0.2", + "spec": ">=1.0.2 <1.1.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/js-yaml" + ] + ], + "_from": "esprima@>=1.0.2 <1.1.0", + "_id": "esprima@1.0.4", + "_inCache": true, + "_location": "/esprima", + "_npmUser": { + "name": "ariya", + "email": "ariya.hidayat@gmail.com" + }, + "_npmVersion": "1.1.61", + "_phantomChildren": {}, + "_requested": { + "raw": "esprima@~ 1.0.2", + "scope": null, + "escapedName": "esprima", + "name": "esprima", + "rawSpec": "~ 1.0.2", + "spec": ">=1.0.2 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/js-yaml" + ], + "_resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", + "_shasum": "9f557e08fc3b4d26ece9dd34f8fbf476b62585ad", + "_shrinkwrap": null, + "_spec": "esprima@~ 1.0.2", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/js-yaml", + "bin": { + "esparse": "./bin/esparse.js", + "esvalidate": "./bin/esvalidate.js" + }, + "bugs": { + "url": "https://github.com/ariya/esprima/issues" + }, + "dependencies": {}, + "description": "ECMAScript parsing infrastructure for multipurpose analysis", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "9f557e08fc3b4d26ece9dd34f8fbf476b62585ad", + "tarball": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz" + }, + "engines": { + "node": ">=0.4.0" + }, + "files": [ + "bin", + "test/run.js", + "test/runner.js", + "test/test.js", + "test/compat.js", + "test/reflect.js", + "esprima.js" + ], + "homepage": "http://esprima.org", + "keywords": [ + "ast", + "ecmascript", + "javascript", + "parser", + "syntax" + ], + "licenses": [ + { + "type": "BSD", + "url": "http://github.com/ariya/esprima/raw/master/LICENSE.BSD" + } + ], + "main": "esprima.js", + "maintainers": [ + { + "name": "ariya", + "email": "ariya.hidayat@gmail.com" + } + ], + "name": "esprima", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/ariya/esprima.git" + }, + "scripts": { + "benchmark": "node test/benchmarks.js", + "benchmark-quick": "node test/benchmarks.js quick", + "test": "node test/run.js" + }, + "version": "1.0.4" +} diff --git a/node_modules/esprima/test/compat.js b/node_modules/esprima/test/compat.js new file mode 100644 index 0000000..ee3a629 --- /dev/null +++ b/node_modules/esprima/test/compat.js @@ -0,0 +1,239 @@ +/* + Copyright (C) 2012 Joost-Wim Boekesteijn + Copyright (C) 2011 Ariya Hidayat + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/*jslint node: true */ +/*global document: true, window:true, esprima: true, testReflect: true */ + +var runTests; + +function getContext(esprima, reportCase, reportFailure) { + 'use strict'; + + var Reflect, Pattern; + + // Maps Mozilla Reflect object to our Esprima parser. + Reflect = { + parse: function (code) { + var result; + + reportCase(code); + + try { + result = esprima.parse(code); + } catch (error) { + result = error; + } + + return result; + } + }; + + // This is used by Reflect test suite to match a syntax tree. + Pattern = function (obj) { + var pattern; + + // Poor man's deep object cloning. + pattern = JSON.parse(JSON.stringify(obj)); + + // Special handling for regular expression literal since we need to + // convert it to a string literal, otherwise it will be decoded + // as object "{}" and the regular expression would be lost. + if (obj.type && obj.type === 'Literal') { + if (obj.value instanceof RegExp) { + pattern = { + type: obj.type, + value: obj.value.toString() + }; + } + } + + // Special handling for branch statement because SpiderMonkey + // prefers to put the 'alternate' property before 'consequent'. + if (obj.type && obj.type === 'IfStatement') { + pattern = { + type: pattern.type, + test: pattern.test, + consequent: pattern.consequent, + alternate: pattern.alternate + }; + } + + // Special handling for do while statement because SpiderMonkey + // prefers to put the 'test' property before 'body'. + if (obj.type && obj.type === 'DoWhileStatement') { + pattern = { + type: pattern.type, + body: pattern.body, + test: pattern.test + }; + } + + function adjustRegexLiteralAndRaw(key, value) { + if (key === 'value' && value instanceof RegExp) { + value = value.toString(); + } else if (key === 'raw' && typeof value === "string") { + // Ignore Esprima-specific 'raw' property. + return undefined; + } + return value; + } + + if (obj.type && (obj.type === 'Program')) { + pattern.assert = function (tree) { + var actual, expected; + actual = JSON.stringify(tree, adjustRegexLiteralAndRaw, 4); + expected = JSON.stringify(obj, null, 4); + + if (expected !== actual) { + reportFailure(expected, actual); + } + }; + } + + return pattern; + }; + + return { + Reflect: Reflect, + Pattern: Pattern + }; +} + +if (typeof window !== 'undefined') { + // Run all tests in a browser environment. + runTests = function () { + 'use strict'; + + var total = 0, + failures = 0; + + function setText(el, str) { + if (typeof el.innerText === 'string') { + el.innerText = str; + } else { + el.textContent = str; + } + } + + function reportCase(code) { + var report, e; + report = document.getElementById('report'); + e = document.createElement('pre'); + e.setAttribute('class', 'code'); + setText(e, code); + report.appendChild(e); + total += 1; + } + + function reportFailure(expected, actual) { + var report, e; + + failures += 1; + + report = document.getElementById('report'); + + e = document.createElement('p'); + setText(e, 'Expected'); + report.appendChild(e); + + e = document.createElement('pre'); + e.setAttribute('class', 'expected'); + setText(e, expected); + report.appendChild(e); + + e = document.createElement('p'); + setText(e, 'Actual'); + report.appendChild(e); + + e = document.createElement('pre'); + e.setAttribute('class', 'actual'); + setText(e, actual); + report.appendChild(e); + } + + setText(document.getElementById('version'), esprima.version); + + window.setTimeout(function () { + var tick, context = getContext(esprima, reportCase, reportFailure); + + tick = new Date(); + testReflect(context.Reflect, context.Pattern); + tick = (new Date()) - tick; + + if (failures > 0) { + setText(document.getElementById('status'), total + ' tests. ' + + 'Failures: ' + failures + '. ' + tick + ' ms'); + } else { + setText(document.getElementById('status'), total + ' tests. ' + + 'No failure. ' + tick + ' ms'); + } + }, 513); + }; +} else { + (function (global) { + 'use strict'; + var esprima = require('../esprima'), + tick, + total = 0, + failures = [], + header, + current, + context; + + function reportCase(code) { + total += 1; + current = code; + } + + function reportFailure(expected, actual) { + failures.push({ + source: current, + expected: expected.toString(), + actual: actual.toString() + }); + } + + context = getContext(esprima, reportCase, reportFailure); + + tick = new Date(); + require('./reflect').testReflect(context.Reflect, context.Pattern); + tick = (new Date()) - tick; + + header = total + ' tests. ' + failures.length + ' failures. ' + + tick + ' ms'; + if (failures.length) { + console.error(header); + failures.forEach(function (failure) { + console.error(failure.source + ': Expected\n ' + + failure.expected.split('\n').join('\n ') + + '\nto match\n ' + failure.actual); + }); + } else { + console.log(header); + } + process.exit(failures.length === 0 ? 0 : 1); + }(this)); +} +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/esprima/test/reflect.js b/node_modules/esprima/test/reflect.js new file mode 100644 index 0000000..dba1ba8 --- /dev/null +++ b/node_modules/esprima/test/reflect.js @@ -0,0 +1,422 @@ +// This is modified from Mozilla Reflect.parse test suite (the file is located +// at js/src/tests/js1_8_5/extensions/reflect-parse.js in the source tree). +// +// Some notable changes: +// * Removed unsupported features (destructuring, let, comprehensions...). +// * Removed tests for E4X (ECMAScript for XML). +// * Removed everything related to builder. +// * Enclosed every 'Pattern' construct with a scope. +// * Tweaked some expected tree to remove generator field. +// * Removed the test for bug 632030 and bug 632024. + +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +(function (exports) { + +function testReflect(Reflect, Pattern) { + +function program(elts) { return Pattern({ type: "Program", body: elts }) } +function exprStmt(expr) { return Pattern({ type: "ExpressionStatement", expression: expr }) } +function throwStmt(expr) { return Pattern({ type: "ThrowStatement", argument: expr }) } +function returnStmt(expr) { return Pattern({ type: "ReturnStatement", argument: expr }) } +function yieldExpr(expr) { return Pattern({ type: "YieldExpression", argument: expr }) } +function lit(val) { return Pattern({ type: "Literal", value: val }) } +var thisExpr = Pattern({ type: "ThisExpression" }); +function funDecl(id, params, body) { return Pattern({ type: "FunctionDeclaration", + id: id, + params: params, + defaults: [], + body: body, + rest: null, + generator: false, + expression: false + }) } +function genFunDecl(id, params, body) { return Pattern({ type: "FunctionDeclaration", + id: id, + params: params, + defaults: [], + body: body, + rest: null, + generator: false, + expression: false + }) } +function declarator(id, init) { return Pattern({ type: "VariableDeclarator", id: id, init: init }) } +function varDecl(decls) { return Pattern({ type: "VariableDeclaration", declarations: decls, kind: "var" }) } +function letDecl(decls) { return Pattern({ type: "VariableDeclaration", declarations: decls, kind: "let" }) } +function constDecl(decls) { return Pattern({ type: "VariableDeclaration", declarations: decls, kind: "const" }) } +function ident(name) { return Pattern({ type: "Identifier", name: name }) } +function dotExpr(obj, id) { return Pattern({ type: "MemberExpression", computed: false, object: obj, property: id }) } +function memExpr(obj, id) { return Pattern({ type: "MemberExpression", computed: true, object: obj, property: id }) } +function forStmt(init, test, update, body) { return Pattern({ type: "ForStatement", init: init, test: test, update: update, body: body }) } +function forInStmt(lhs, rhs, body) { return Pattern({ type: "ForInStatement", left: lhs, right: rhs, body: body, each: false }) } +function forEachInStmt(lhs, rhs, body) { return Pattern({ type: "ForInStatement", left: lhs, right: rhs, body: body, each: true }) } +function breakStmt(lab) { return Pattern({ type: "BreakStatement", label: lab }) } +function continueStmt(lab) { return Pattern({ type: "ContinueStatement", label: lab }) } +function blockStmt(body) { return Pattern({ type: "BlockStatement", body: body }) } +var emptyStmt = Pattern({ type: "EmptyStatement" }); +function ifStmt(test, cons, alt) { return Pattern({ type: "IfStatement", test: test, alternate: alt, consequent: cons }) } +function labStmt(lab, stmt) { return Pattern({ type: "LabeledStatement", label: lab, body: stmt }) } +function withStmt(obj, stmt) { return Pattern({ type: "WithStatement", object: obj, body: stmt }) } +function whileStmt(test, stmt) { return Pattern({ type: "WhileStatement", test: test, body: stmt }) } +function doStmt(stmt, test) { return Pattern({ type: "DoWhileStatement", test: test, body: stmt }) } +function switchStmt(disc, cases) { return Pattern({ type: "SwitchStatement", discriminant: disc, cases: cases }) } +function caseClause(test, stmts) { return Pattern({ type: "SwitchCase", test: test, consequent: stmts }) } +function defaultClause(stmts) { return Pattern({ type: "SwitchCase", test: null, consequent: stmts }) } +function catchClause(id, guard, body) { if (guard) { return Pattern({ type: "GuardedCatchClause", param: id, guard: guard, body: body }) } else { return Pattern({ type: "CatchClause", param: id, body: body }) } } +function tryStmt(body, guarded, catches, fin) { return Pattern({ type: "TryStatement", block: body, guardedHandlers: guarded, handlers: catches, finalizer: fin }) } +function letStmt(head, body) { return Pattern({ type: "LetStatement", head: head, body: body }) } +function funExpr(id, args, body, gen) { return Pattern({ type: "FunctionExpression", + id: id, + params: args, + defaults: [], + body: body, + rest: null, + generator: false, + expression: false + }) } +function genFunExpr(id, args, body) { return Pattern({ type: "FunctionExpression", + id: id, + params: args, + defaults: [], + body: body, + rest: null, + generator: false, + expression: false + }) } + +function unExpr(op, arg) { return Pattern({ type: "UnaryExpression", operator: op, argument: arg, prefix: true }) } +function binExpr(op, left, right) { return Pattern({ type: "BinaryExpression", operator: op, left: left, right: right }) } +function aExpr(op, left, right) { return Pattern({ type: "AssignmentExpression", operator: op, left: left, right: right }) } +function updExpr(op, arg, prefix) { return Pattern({ type: "UpdateExpression", operator: op, argument: arg, prefix: prefix }) } +function logExpr(op, left, right) { return Pattern({ type: "LogicalExpression", operator: op, left: left, right: right }) } + +function condExpr(test, cons, alt) { return Pattern({ type: "ConditionalExpression", test: test, consequent: cons, alternate: alt }) } +function seqExpr(exprs) { return Pattern({ type: "SequenceExpression", expressions: exprs }) } +function newExpr(callee, args) { return Pattern({ type: "NewExpression", callee: callee, arguments: args }) } +function callExpr(callee, args) { return Pattern({ type: "CallExpression", callee: callee, arguments: args }) } +function arrExpr(elts) { return Pattern({ type: "ArrayExpression", elements: elts }) } +function objExpr(elts) { return Pattern({ type: "ObjectExpression", properties: elts }) } +function objProp(key, value, kind) { return Pattern({ type: "Property", key: key, value: value, kind: kind }) } + +function arrPatt(elts) { return Pattern({ type: "ArrayPattern", elements: elts }) } +function objPatt(elts) { return Pattern({ type: "ObjectPattern", properties: elts }) } + +function localSrc(src) { return "(function(){ " + src + " })" } +function localPatt(patt) { return program([exprStmt(funExpr(null, [], blockStmt([patt])))]) } +function blockSrc(src) { return "(function(){ { " + src + " } })" } +function blockPatt(patt) { return program([exprStmt(funExpr(null, [], blockStmt([blockStmt([patt])])))]) } + +function assertBlockStmt(src, patt) { + blockPatt(patt).assert(Reflect.parse(blockSrc(src))); +} + +function assertBlockExpr(src, patt) { + assertBlockStmt(src, exprStmt(patt)); +} + +function assertBlockDecl(src, patt, builder) { + blockPatt(patt).assert(Reflect.parse(blockSrc(src), {builder: builder})); +} + +function assertLocalStmt(src, patt) { + localPatt(patt).assert(Reflect.parse(localSrc(src))); +} + +function assertLocalExpr(src, patt) { + assertLocalStmt(src, exprStmt(patt)); +} + +function assertLocalDecl(src, patt) { + localPatt(patt).assert(Reflect.parse(localSrc(src))); +} + +function assertGlobalStmt(src, patt, builder) { + program([patt]).assert(Reflect.parse(src, {builder: builder})); +} + +function assertGlobalExpr(src, patt, builder) { + program([exprStmt(patt)]).assert(Reflect.parse(src, {builder: builder})); + //assertStmt(src, exprStmt(patt)); +} + +function assertGlobalDecl(src, patt) { + program([patt]).assert(Reflect.parse(src)); +} + +function assertProg(src, patt) { + program(patt).assert(Reflect.parse(src)); +} + +function assertStmt(src, patt) { + assertLocalStmt(src, patt); + assertGlobalStmt(src, patt); + assertBlockStmt(src, patt); +} + +function assertExpr(src, patt) { + assertLocalExpr(src, patt); + assertGlobalExpr(src, patt); + assertBlockExpr(src, patt); +} + +function assertDecl(src, patt) { + assertLocalDecl(src, patt); + assertGlobalDecl(src, patt); + assertBlockDecl(src, patt); +} + +function assertError(src, errorType) { + try { + Reflect.parse(src); + } catch (e) { + return; + } + throw new Error("expected " + errorType.name + " for " + uneval(src)); +} + + +// general tests + +// NB: These are useful but for now jit-test doesn't do I/O reliably. + +//program(_).assert(Reflect.parse(snarf('data/flapjax.txt'))); +//program(_).assert(Reflect.parse(snarf('data/jquery-1.4.2.txt'))); +//program(_).assert(Reflect.parse(snarf('data/prototype.js'))); +//program(_).assert(Reflect.parse(snarf('data/dojo.js.uncompressed.js'))); +//program(_).assert(Reflect.parse(snarf('data/mootools-1.2.4-core-nc.js'))); + + +// declarations + +assertDecl("var x = 1, y = 2, z = 3", + varDecl([declarator(ident("x"), lit(1)), + declarator(ident("y"), lit(2)), + declarator(ident("z"), lit(3))])); +assertDecl("var x, y, z", + varDecl([declarator(ident("x"), null), + declarator(ident("y"), null), + declarator(ident("z"), null)])); +assertDecl("function foo() { }", + funDecl(ident("foo"), [], blockStmt([]))); +assertDecl("function foo() { return 42 }", + funDecl(ident("foo"), [], blockStmt([returnStmt(lit(42))]))); + + +// Bug 591437: rebound args have their defs turned into uses +assertDecl("function f(a) { function a() { } }", + funDecl(ident("f"), [ident("a")], blockStmt([funDecl(ident("a"), [], blockStmt([]))]))); +assertDecl("function f(a,b,c) { function b() { } }", + funDecl(ident("f"), [ident("a"),ident("b"),ident("c")], blockStmt([funDecl(ident("b"), [], blockStmt([]))]))); + +// expressions + +assertExpr("true", lit(true)); +assertExpr("false", lit(false)); +assertExpr("42", lit(42)); +assertExpr("(/asdf/)", lit(/asdf/)); +assertExpr("this", thisExpr); +assertExpr("foo", ident("foo")); +assertExpr("foo.bar", dotExpr(ident("foo"), ident("bar"))); +assertExpr("foo[bar]", memExpr(ident("foo"), ident("bar"))); +assertExpr("(function(){})", funExpr(null, [], blockStmt([]))); +assertExpr("(function f() {})", funExpr(ident("f"), [], blockStmt([]))); +assertExpr("(function f(x,y,z) {})", funExpr(ident("f"), [ident("x"),ident("y"),ident("z")], blockStmt([]))); +assertExpr("(++x)", updExpr("++", ident("x"), true)); +assertExpr("(x++)", updExpr("++", ident("x"), false)); +assertExpr("(+x)", unExpr("+", ident("x"))); +assertExpr("(-x)", unExpr("-", ident("x"))); +assertExpr("(!x)", unExpr("!", ident("x"))); +assertExpr("(~x)", unExpr("~", ident("x"))); +assertExpr("(delete x)", unExpr("delete", ident("x"))); +assertExpr("(typeof x)", unExpr("typeof", ident("x"))); +assertExpr("(void x)", unExpr("void", ident("x"))); +assertExpr("(x == y)", binExpr("==", ident("x"), ident("y"))); +assertExpr("(x != y)", binExpr("!=", ident("x"), ident("y"))); +assertExpr("(x === y)", binExpr("===", ident("x"), ident("y"))); +assertExpr("(x !== y)", binExpr("!==", ident("x"), ident("y"))); +assertExpr("(x < y)", binExpr("<", ident("x"), ident("y"))); +assertExpr("(x <= y)", binExpr("<=", ident("x"), ident("y"))); +assertExpr("(x > y)", binExpr(">", ident("x"), ident("y"))); +assertExpr("(x >= y)", binExpr(">=", ident("x"), ident("y"))); +assertExpr("(x << y)", binExpr("<<", ident("x"), ident("y"))); +assertExpr("(x >> y)", binExpr(">>", ident("x"), ident("y"))); +assertExpr("(x >>> y)", binExpr(">>>", ident("x"), ident("y"))); +assertExpr("(x + y)", binExpr("+", ident("x"), ident("y"))); +assertExpr("(w + x + y + z)", binExpr("+", binExpr("+", binExpr("+", ident("w"), ident("x")), ident("y")), ident("z"))); +assertExpr("(x - y)", binExpr("-", ident("x"), ident("y"))); +assertExpr("(w - x - y - z)", binExpr("-", binExpr("-", binExpr("-", ident("w"), ident("x")), ident("y")), ident("z"))); +assertExpr("(x * y)", binExpr("*", ident("x"), ident("y"))); +assertExpr("(x / y)", binExpr("/", ident("x"), ident("y"))); +assertExpr("(x % y)", binExpr("%", ident("x"), ident("y"))); +assertExpr("(x | y)", binExpr("|", ident("x"), ident("y"))); +assertExpr("(x ^ y)", binExpr("^", ident("x"), ident("y"))); +assertExpr("(x & y)", binExpr("&", ident("x"), ident("y"))); +assertExpr("(x in y)", binExpr("in", ident("x"), ident("y"))); +assertExpr("(x instanceof y)", binExpr("instanceof", ident("x"), ident("y"))); +assertExpr("(x = y)", aExpr("=", ident("x"), ident("y"))); +assertExpr("(x += y)", aExpr("+=", ident("x"), ident("y"))); +assertExpr("(x -= y)", aExpr("-=", ident("x"), ident("y"))); +assertExpr("(x *= y)", aExpr("*=", ident("x"), ident("y"))); +assertExpr("(x /= y)", aExpr("/=", ident("x"), ident("y"))); +assertExpr("(x %= y)", aExpr("%=", ident("x"), ident("y"))); +assertExpr("(x <<= y)", aExpr("<<=", ident("x"), ident("y"))); +assertExpr("(x >>= y)", aExpr(">>=", ident("x"), ident("y"))); +assertExpr("(x >>>= y)", aExpr(">>>=", ident("x"), ident("y"))); +assertExpr("(x |= y)", aExpr("|=", ident("x"), ident("y"))); +assertExpr("(x ^= y)", aExpr("^=", ident("x"), ident("y"))); +assertExpr("(x &= y)", aExpr("&=", ident("x"), ident("y"))); +assertExpr("(x || y)", logExpr("||", ident("x"), ident("y"))); +assertExpr("(x && y)", logExpr("&&", ident("x"), ident("y"))); +assertExpr("(w || x || y || z)", logExpr("||", logExpr("||", logExpr("||", ident("w"), ident("x")), ident("y")), ident("z"))) +assertExpr("(x ? y : z)", condExpr(ident("x"), ident("y"), ident("z"))); +assertExpr("(x,y)", seqExpr([ident("x"),ident("y")])) +assertExpr("(x,y,z)", seqExpr([ident("x"),ident("y"),ident("z")])) +assertExpr("(a,b,c,d,e,f,g)", seqExpr([ident("a"),ident("b"),ident("c"),ident("d"),ident("e"),ident("f"),ident("g")])); +assertExpr("(new Object)", newExpr(ident("Object"), [])); +assertExpr("(new Object())", newExpr(ident("Object"), [])); +assertExpr("(new Object(42))", newExpr(ident("Object"), [lit(42)])); +assertExpr("(new Object(1,2,3))", newExpr(ident("Object"), [lit(1),lit(2),lit(3)])); +assertExpr("(String())", callExpr(ident("String"), [])); +assertExpr("(String(42))", callExpr(ident("String"), [lit(42)])); +assertExpr("(String(1,2,3))", callExpr(ident("String"), [lit(1),lit(2),lit(3)])); +assertExpr("[]", arrExpr([])); +assertExpr("[1]", arrExpr([lit(1)])); +assertExpr("[1,2]", arrExpr([lit(1),lit(2)])); +assertExpr("[1,2,3]", arrExpr([lit(1),lit(2),lit(3)])); +assertExpr("[1,,2,3]", arrExpr([lit(1),,lit(2),lit(3)])); +assertExpr("[1,,,2,3]", arrExpr([lit(1),,,lit(2),lit(3)])); +assertExpr("[1,,,2,,3]", arrExpr([lit(1),,,lit(2),,lit(3)])); +assertExpr("[1,,,2,,,3]", arrExpr([lit(1),,,lit(2),,,lit(3)])); +assertExpr("[,1,2,3]", arrExpr([,lit(1),lit(2),lit(3)])); +assertExpr("[,,1,2,3]", arrExpr([,,lit(1),lit(2),lit(3)])); +assertExpr("[,,,1,2,3]", arrExpr([,,,lit(1),lit(2),lit(3)])); +assertExpr("[,,,1,2,3,]", arrExpr([,,,lit(1),lit(2),lit(3)])); +assertExpr("[,,,1,2,3,,]", arrExpr([,,,lit(1),lit(2),lit(3),undefined])); +assertExpr("[,,,1,2,3,,,]", arrExpr([,,,lit(1),lit(2),lit(3),undefined,undefined])); +assertExpr("[,,,,,]", arrExpr([undefined,undefined,undefined,undefined,undefined])); +assertExpr("({})", objExpr([])); +assertExpr("({x:1})", objExpr([objProp(ident("x"), lit(1), "init")])); +assertExpr("({x:1, y:2})", objExpr([objProp(ident("x"), lit(1), "init"), + objProp(ident("y"), lit(2), "init")])); +assertExpr("({x:1, y:2, z:3})", objExpr([objProp(ident("x"), lit(1), "init"), + objProp(ident("y"), lit(2), "init"), + objProp(ident("z"), lit(3), "init") ])); +assertExpr("({x:1, 'y':2, z:3})", objExpr([objProp(ident("x"), lit(1), "init"), + objProp(lit("y"), lit(2), "init"), + objProp(ident("z"), lit(3), "init") ])); +assertExpr("({'x':1, 'y':2, z:3})", objExpr([objProp(lit("x"), lit(1), "init"), + objProp(lit("y"), lit(2), "init"), + objProp(ident("z"), lit(3), "init") ])); +assertExpr("({'x':1, 'y':2, 3:3})", objExpr([objProp(lit("x"), lit(1), "init"), + objProp(lit("y"), lit(2), "init"), + objProp(lit(3), lit(3), "init") ])); + +// Bug 571617: eliminate constant-folding +assertExpr("2 + 3", binExpr("+", lit(2), lit(3))); + +// Bug 632026: constant-folding +assertExpr("typeof(0?0:a)", unExpr("typeof", condExpr(lit(0), lit(0), ident("a")))); + +// Bug 632056: constant-folding +program([exprStmt(ident("f")), + ifStmt(lit(1), + funDecl(ident("f"), [], blockStmt([])), + null)]).assert(Reflect.parse("f; if (1) function f(){}")); + +// statements + +assertStmt("throw 42", throwStmt(lit(42))); +assertStmt("for (;;) break", forStmt(null, null, null, breakStmt(null))); +assertStmt("for (x; y; z) break", forStmt(ident("x"), ident("y"), ident("z"), breakStmt(null))); +assertStmt("for (var x; y; z) break", forStmt(varDecl([declarator(ident("x"), null)]), ident("y"), ident("z"), breakStmt(null))); +assertStmt("for (var x = 42; y; z) break", forStmt(varDecl([declarator(ident("x"), lit(42))]), ident("y"), ident("z"), breakStmt(null))); +assertStmt("for (x; ; z) break", forStmt(ident("x"), null, ident("z"), breakStmt(null))); +assertStmt("for (var x; ; z) break", forStmt(varDecl([declarator(ident("x"), null)]), null, ident("z"), breakStmt(null))); +assertStmt("for (var x = 42; ; z) break", forStmt(varDecl([declarator(ident("x"), lit(42))]), null, ident("z"), breakStmt(null))); +assertStmt("for (x; y; ) break", forStmt(ident("x"), ident("y"), null, breakStmt(null))); +assertStmt("for (var x; y; ) break", forStmt(varDecl([declarator(ident("x"), null)]), ident("y"), null, breakStmt(null))); +assertStmt("for (var x = 42; y; ) break", forStmt(varDecl([declarator(ident("x"),lit(42))]), ident("y"), null, breakStmt(null))); +assertStmt("for (var x in y) break", forInStmt(varDecl([declarator(ident("x"),null)]), ident("y"), breakStmt(null))); +assertStmt("for (x in y) break", forInStmt(ident("x"), ident("y"), breakStmt(null))); +assertStmt("{ }", blockStmt([])); +assertStmt("{ throw 1; throw 2; throw 3; }", blockStmt([ throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))])); +assertStmt(";", emptyStmt); +assertStmt("if (foo) throw 42;", ifStmt(ident("foo"), throwStmt(lit(42)), null)); +assertStmt("if (foo) throw 42; else true;", ifStmt(ident("foo"), throwStmt(lit(42)), exprStmt(lit(true)))); +assertStmt("if (foo) { throw 1; throw 2; throw 3; }", + ifStmt(ident("foo"), + blockStmt([throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))]), + null)); +assertStmt("if (foo) { throw 1; throw 2; throw 3; } else true;", + ifStmt(ident("foo"), + blockStmt([throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))]), + exprStmt(lit(true)))); +assertStmt("foo: for(;;) break foo;", labStmt(ident("foo"), forStmt(null, null, null, breakStmt(ident("foo"))))); +assertStmt("foo: for(;;) continue foo;", labStmt(ident("foo"), forStmt(null, null, null, continueStmt(ident("foo"))))); +assertStmt("with (obj) { }", withStmt(ident("obj"), blockStmt([]))); +assertStmt("with (obj) { obj; }", withStmt(ident("obj"), blockStmt([exprStmt(ident("obj"))]))); +assertStmt("while (foo) { }", whileStmt(ident("foo"), blockStmt([]))); +assertStmt("while (foo) { foo; }", whileStmt(ident("foo"), blockStmt([exprStmt(ident("foo"))]))); +assertStmt("do { } while (foo);", doStmt(blockStmt([]), ident("foo"))); +assertStmt("do { foo; } while (foo)", doStmt(blockStmt([exprStmt(ident("foo"))]), ident("foo"))); +assertStmt("switch (foo) { case 1: 1; break; case 2: 2; break; default: 3; }", + switchStmt(ident("foo"), + [ caseClause(lit(1), [ exprStmt(lit(1)), breakStmt(null) ]), + caseClause(lit(2), [ exprStmt(lit(2)), breakStmt(null) ]), + defaultClause([ exprStmt(lit(3)) ]) ])); +assertStmt("switch (foo) { case 1: 1; break; case 2: 2; break; default: 3; case 42: 42; }", + switchStmt(ident("foo"), + [ caseClause(lit(1), [ exprStmt(lit(1)), breakStmt(null) ]), + caseClause(lit(2), [ exprStmt(lit(2)), breakStmt(null) ]), + defaultClause([ exprStmt(lit(3)) ]), + caseClause(lit(42), [ exprStmt(lit(42)) ]) ])); +assertStmt("try { } catch (e) { }", + tryStmt(blockStmt([]), + [], + [ catchClause(ident("e"), null, blockStmt([])) ], + null)); +assertStmt("try { } catch (e) { } finally { }", + tryStmt(blockStmt([]), + [], + [ catchClause(ident("e"), null, blockStmt([])) ], + blockStmt([]))); +assertStmt("try { } finally { }", + tryStmt(blockStmt([]), + [], + [], + blockStmt([]))); + +// redeclarations (TOK_NAME nodes with lexdef) + +assertStmt("function f() { function g() { } function g() { } }", + funDecl(ident("f"), [], blockStmt([funDecl(ident("g"), [], blockStmt([])), + funDecl(ident("g"), [], blockStmt([]))]))); + +assertStmt("function f() { function g() { } function g() { return 42 } }", + funDecl(ident("f"), [], blockStmt([funDecl(ident("g"), [], blockStmt([])), + funDecl(ident("g"), [], blockStmt([returnStmt(lit(42))]))]))); + +assertStmt("function f() { var x = 42; var x = 43; }", + funDecl(ident("f"), [], blockStmt([varDecl([declarator(ident("x"),lit(42))]), + varDecl([declarator(ident("x"),lit(43))])]))); + +// getters and setters + + assertExpr("({ get x() { return 42 } })", + objExpr([ objProp(ident("x"), + funExpr(null, [], blockStmt([returnStmt(lit(42))])), + "get" ) ])); + assertExpr("({ set x(v) { return 42 } })", + objExpr([ objProp(ident("x"), + funExpr(null, [ident("v")], blockStmt([returnStmt(lit(42))])), + "set" ) ])); + +} + +exports.testReflect = testReflect; + +}(typeof exports === 'undefined' ? this : exports)); diff --git a/node_modules/esprima/test/run.js b/node_modules/esprima/test/run.js new file mode 100644 index 0000000..32ca3fa --- /dev/null +++ b/node_modules/esprima/test/run.js @@ -0,0 +1,66 @@ +/* + Copyright (C) 2012 Yusuke Suzuki + Copyright (C) 2012 Ariya Hidayat + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/*jslint node:true */ + +(function () { + 'use strict'; + + var child = require('child_process'), + nodejs = '"' + process.execPath + '"', + ret = 0, + suites, + index; + + suites = [ + 'runner', + 'compat' + ]; + + function nextTest() { + var suite = suites[index]; + + if (index < suites.length) { + child.exec(nodejs + ' ./test/' + suite + '.js', function (err, stdout, stderr) { + if (stdout) { + process.stdout.write(suite + ': ' + stdout); + } + if (stderr) { + process.stderr.write(suite + ': ' + stderr); + } + if (err) { + ret = err.code; + } + index += 1; + nextTest(); + }); + } else { + process.exit(ret); + } + } + + index = 0; + nextTest(); +}()); diff --git a/node_modules/esprima/test/runner.js b/node_modules/esprima/test/runner.js new file mode 100644 index 0000000..c1a3fc9 --- /dev/null +++ b/node_modules/esprima/test/runner.js @@ -0,0 +1,387 @@ +/* + Copyright (C) 2012 Ariya Hidayat + Copyright (C) 2012 Joost-Wim Boekesteijn + Copyright (C) 2012 Yusuke Suzuki + Copyright (C) 2012 Arpad Borsos + Copyright (C) 2011 Ariya Hidayat + Copyright (C) 2011 Yusuke Suzuki + Copyright (C) 2011 Arpad Borsos + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/*jslint browser:true node:true */ +/*global esprima:true, testFixture:true */ + +var runTests; + +// Special handling for regular expression literal since we need to +// convert it to a string literal, otherwise it will be decoded +// as object "{}" and the regular expression would be lost. +function adjustRegexLiteral(key, value) { + 'use strict'; + if (key === 'value' && value instanceof RegExp) { + value = value.toString(); + } + return value; +} + +function NotMatchingError(expected, actual) { + 'use strict'; + Error.call(this, 'Expected '); + this.expected = expected; + this.actual = actual; +} +NotMatchingError.prototype = new Error(); + +function errorToObject(e) { + 'use strict'; + var msg = e.toString(); + + // Opera 9.64 produces an non-standard string in toString(). + if (msg.substr(0, 6) !== 'Error:') { + if (typeof e.message === 'string') { + msg = 'Error: ' + e.message; + } + } + + return { + index: e.index, + lineNumber: e.lineNumber, + column: e.column, + message: msg + }; +} + +function testParse(esprima, code, syntax) { + 'use strict'; + var expected, tree, actual, options, StringObject, i, len, err; + + // alias, so that JSLint does not complain. + StringObject = String; + + options = { + comment: (typeof syntax.comments !== 'undefined'), + range: true, + loc: true, + tokens: (typeof syntax.tokens !== 'undefined'), + raw: true, + tolerant: (typeof syntax.errors !== 'undefined') + }; + + if (typeof syntax.tokens !== 'undefined') { + if (syntax.tokens.length > 0) { + options.range = (typeof syntax.tokens[0].range !== 'undefined'); + options.loc = (typeof syntax.tokens[0].loc !== 'undefined'); + } + } + + if (typeof syntax.comments !== 'undefined') { + if (syntax.comments.length > 0) { + options.range = (typeof syntax.comments[0].range !== 'undefined'); + options.loc = (typeof syntax.comments[0].loc !== 'undefined'); + } + } + + expected = JSON.stringify(syntax, null, 4); + try { + tree = esprima.parse(code, options); + tree = (options.comment || options.tokens || options.tolerant) ? tree : tree.body[0]; + + if (options.tolerant) { + for (i = 0, len = tree.errors.length; i < len; i += 1) { + tree.errors[i] = errorToObject(tree.errors[i]); + } + } + + actual = JSON.stringify(tree, adjustRegexLiteral, 4); + + // Only to ensure that there is no error when using string object. + esprima.parse(new StringObject(code), options); + + } catch (e) { + throw new NotMatchingError(expected, e.toString()); + } + if (expected !== actual) { + throw new NotMatchingError(expected, actual); + } + + function filter(key, value) { + if (key === 'value' && value instanceof RegExp) { + value = value.toString(); + } + return (key === 'loc' || key === 'range') ? undefined : value; + } + + if (options.tolerant) { + return; + } + + + // Check again without any location info. + options.range = false; + options.loc = false; + expected = JSON.stringify(syntax, filter, 4); + try { + tree = esprima.parse(code, options); + tree = (options.comment || options.tokens) ? tree : tree.body[0]; + + if (options.tolerant) { + for (i = 0, len = tree.errors.length; i < len; i += 1) { + tree.errors[i] = errorToObject(tree.errors[i]); + } + } + + actual = JSON.stringify(tree, filter, 4); + } catch (e) { + throw new NotMatchingError(expected, e.toString()); + } + if (expected !== actual) { + throw new NotMatchingError(expected, actual); + } +} + +function testError(esprima, code, exception) { + 'use strict'; + var i, options, expected, actual, handleInvalidRegexFlag; + + // Different parsing options should give the same error. + options = [ + {}, + { comment: true }, + { raw: true }, + { raw: true, comment: true } + ]; + + // If handleInvalidRegexFlag is true, an invalid flag in a regular expression + // will throw an exception. In some old version V8, this is not the case + // and hence handleInvalidRegexFlag is false. + handleInvalidRegexFlag = false; + try { + 'test'.match(new RegExp('[a-z]', 'x')); + } catch (e) { + handleInvalidRegexFlag = true; + } + + expected = JSON.stringify(exception); + + for (i = 0; i < options.length; i += 1) { + + try { + esprima.parse(code, options[i]); + } catch (e) { + actual = JSON.stringify(errorToObject(e)); + } + + if (expected !== actual) { + + // Compensate for old V8 which does not handle invalid flag. + if (exception.message.indexOf('Invalid regular expression') > 0) { + if (typeof actual === 'undefined' && !handleInvalidRegexFlag) { + return; + } + } + + throw new NotMatchingError(expected, actual); + } + + } +} + +function testAPI(esprima, code, result) { + 'use strict'; + var expected, res, actual; + + expected = JSON.stringify(result.result, null, 4); + try { + if (typeof result.property !== 'undefined') { + res = esprima[result.property]; + } else { + res = esprima[result.call].apply(esprima, result.args); + } + actual = JSON.stringify(res, adjustRegexLiteral, 4); + } catch (e) { + throw new NotMatchingError(expected, e.toString()); + } + if (expected !== actual) { + throw new NotMatchingError(expected, actual); + } +} + +function runTest(esprima, code, result) { + 'use strict'; + if (result.hasOwnProperty('lineNumber')) { + testError(esprima, code, result); + } else if (result.hasOwnProperty('result')) { + testAPI(esprima, code, result); + } else { + testParse(esprima, code, result); + } +} + +if (typeof window !== 'undefined') { + // Run all tests in a browser environment. + runTests = function () { + 'use strict'; + var total = 0, + failures = 0, + category, + fixture, + source, + tick, + expected, + index, + len; + + function setText(el, str) { + if (typeof el.innerText === 'string') { + el.innerText = str; + } else { + el.textContent = str; + } + } + + function startCategory(category) { + var report, e; + report = document.getElementById('report'); + e = document.createElement('h4'); + setText(e, category); + report.appendChild(e); + } + + function reportSuccess(code) { + var report, e; + report = document.getElementById('report'); + e = document.createElement('pre'); + e.setAttribute('class', 'code'); + setText(e, code); + report.appendChild(e); + } + + function reportFailure(code, expected, actual) { + var report, e; + + report = document.getElementById('report'); + + e = document.createElement('p'); + setText(e, 'Code:'); + report.appendChild(e); + + e = document.createElement('pre'); + e.setAttribute('class', 'code'); + setText(e, code); + report.appendChild(e); + + e = document.createElement('p'); + setText(e, 'Expected'); + report.appendChild(e); + + e = document.createElement('pre'); + e.setAttribute('class', 'expected'); + setText(e, expected); + report.appendChild(e); + + e = document.createElement('p'); + setText(e, 'Actual'); + report.appendChild(e); + + e = document.createElement('pre'); + e.setAttribute('class', 'actual'); + setText(e, actual); + report.appendChild(e); + } + + setText(document.getElementById('version'), esprima.version); + + tick = new Date(); + for (category in testFixture) { + if (testFixture.hasOwnProperty(category)) { + startCategory(category); + fixture = testFixture[category]; + for (source in fixture) { + if (fixture.hasOwnProperty(source)) { + expected = fixture[source]; + total += 1; + try { + runTest(esprima, source, expected); + reportSuccess(source, JSON.stringify(expected, null, 4)); + } catch (e) { + failures += 1; + reportFailure(source, e.expected, e.actual); + } + } + } + } + } + tick = (new Date()) - tick; + + if (failures > 0) { + setText(document.getElementById('status'), total + ' tests. ' + + 'Failures: ' + failures + '. ' + tick + ' ms'); + } else { + setText(document.getElementById('status'), total + ' tests. ' + + 'No failure. ' + tick + ' ms'); + } + }; +} else { + (function () { + 'use strict'; + + var esprima = require('../esprima'), + vm = require('vm'), + fs = require('fs'), + total = 0, + failures = [], + tick = new Date(), + expected, + header; + + vm.runInThisContext(fs.readFileSync(__dirname + '/test.js', 'utf-8')); + + Object.keys(testFixture).forEach(function (category) { + Object.keys(testFixture[category]).forEach(function (source) { + total += 1; + expected = testFixture[category][source]; + try { + runTest(esprima, source, expected); + } catch (e) { + e.source = source; + failures.push(e); + } + }); + }); + tick = (new Date()) - tick; + + header = total + ' tests. ' + failures.length + ' failures. ' + + tick + ' ms'; + if (failures.length) { + console.error(header); + failures.forEach(function (failure) { + console.error(failure.source + ': Expected\n ' + + failure.expected.split('\n').join('\n ') + + '\nto match\n ' + failure.actual); + }); + } else { + console.log(header); + } + process.exit(failures.length === 0 ? 0 : 1); + }()); +} diff --git a/node_modules/esprima/test/test.js b/node_modules/esprima/test/test.js new file mode 100644 index 0000000..8ceee54 --- /dev/null +++ b/node_modules/esprima/test/test.js @@ -0,0 +1,20238 @@ +/* + Copyright (C) 2012 Ariya Hidayat + Copyright (C) 2012 Joost-Wim Boekesteijn + Copyright (C) 2012 Yusuke Suzuki + Copyright (C) 2012 Arpad Borsos + Copyright (C) 2011 Ariya Hidayat + Copyright (C) 2011 Yusuke Suzuki + Copyright (C) 2011 Arpad Borsos + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +var testFixture = { + + 'Primary Expression': { + + 'this\n': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'ThisExpression', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 0 } + } + }], + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 0 } + }, + tokens: [{ + type: 'Keyword', + value: 'this', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }] + }, + + 'null\n': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: null, + raw: 'null', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 0 } + } + }], + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 0 } + }, + tokens: [{ + type: 'Null', + value: 'null', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }] + }, + + '\n 42\n\n': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }, + range: [5, 9], + loc: { + start: { line: 2, column: 4 }, + end: { line: 4, column: 0 } + } + }], + range: [5, 9], + loc: { + start: { line: 2, column: 4 }, + end: { line: 4, column: 0 } + }, + tokens: [{ + type: 'Numeric', + value: '42', + range: [5, 7], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }] + }, + + '(1 + 2 ) * 3': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'Literal', + value: 1, + raw: '1', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + right: { + type: 'Literal', + value: 2, + raw: '2', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [1, 6], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 6 } + } + }, + right: { + type: 'Literal', + value: 3, + raw: '3', + range: [11, 12], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + } + + }, + + 'Grouping Operator': { + + '(1) + (2 ) + 3': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'Literal', + value: 1, + raw: '1', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + right: { + type: 'Literal', + value: 2, + raw: '2', + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + right: { + type: 'Literal', + value: 3, + raw: '3', + range: [14, 15], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + + '4 + 5 << (6)': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '<<', + left: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'Literal', + value: 4, + raw: '4', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 5, + raw: '5', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Literal', + value: 6, + raw: '6', + range: [10, 11], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + } + + }, + + 'Array Initializer': { + + 'x = []': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }], + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + }, + tokens: [{ + type: 'Identifier', + value: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, { + type: 'Punctuator', + value: '=', + range: [2, 3], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Punctuator', + value: '[', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: ']', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }] + }, + + 'x = [ ]': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x = [ 42 ]': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ArrayExpression', + elements: [{ + type: 'Literal', + value: 42, + raw: '42', + range: [6, 8], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 8 } + } + }], + range: [4, 10], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 10 } + } + }, + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + }, + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + }, + + 'x = [ 42, ]': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ArrayExpression', + elements: [{ + type: 'Literal', + value: 42, + raw: '42', + range: [6, 8], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 8 } + } + }], + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'x = [ ,, 42 ]': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ArrayExpression', + elements: [ + null, + null, + { + type: 'Literal', + value: 42, + raw: '42', + range: [9, 11], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 11 } + } + }], + range: [4, 13], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + + 'x = [ 1, 2, 3, ]': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ArrayExpression', + elements: [{ + type: 'Literal', + value: 1, + raw: '1', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'Literal', + value: 2, + raw: '2', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, { + type: 'Literal', + value: 3, + raw: '3', + range: [12, 13], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 13 } + } + }], + range: [4, 16], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + 'x = [ 1, 2,, 3, ]': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ArrayExpression', + elements: [{ + type: 'Literal', + value: 1, + raw: '1', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'Literal', + value: 2, + raw: '2', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, null, { + type: 'Literal', + value: 3, + raw: '3', + range: [13, 14], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 14 } + } + }], + range: [4, 17], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + + '日本語 = []': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: '日本語', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [6, 8], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + + 'T\u203F = []': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'T\u203F', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'T\u200C = []': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'T\u200C', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'T\u200D = []': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'T\u200D', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + '\u2163\u2161 = []': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: '\u2163\u2161', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + '\u2163\u2161\u200A=\u2009[]': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: '\u2163\u2161', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + } + + }, + + 'Object Initializer': { + + 'x = {}': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [], + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x = { }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [], + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x = { answer: 42 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'answer', + range: [6, 12], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 12 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [14, 16], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 16 } + } + }, + kind: 'init', + range: [6, 16], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 16 } + } + }], + range: [4, 18], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 18 } + } + }, + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + } + }, + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + } + }, + + 'x = { if: 42 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'if', + range: [6, 8], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 8 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + kind: 'init', + range: [6, 12], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 12 } + } + }], + range: [4, 14], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + + 'x = { true: 42 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'true', + range: [6, 10], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 10 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [12, 14], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 14 } + } + }, + kind: 'init', + range: [6, 14], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 14 } + } + }], + range: [4, 16], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + 'x = { false: 42 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'false', + range: [6, 11], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 11 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [13, 15], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 15 } + } + }, + kind: 'init', + range: [6, 15], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 15 } + } + }], + range: [4, 17], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + + 'x = { null: 42 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'null', + range: [6, 10], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 10 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [12, 14], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 14 } + } + }, + kind: 'init', + range: [6, 14], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 14 } + } + }], + range: [4, 16], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + 'x = { "answer": 42 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Literal', + value: 'answer', + raw: '"answer"', + range: [6, 14], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 14 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [16, 18], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 18 } + } + }, + kind: 'init', + range: [6, 18], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 18 } + } + }], + range: [4, 20], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 20 } + } + }, + range: [0, 20], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 20 } + } + }, + range: [0, 20], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 20 } + } + }, + + 'x = { x: 1, x: 2 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + value: { + type: 'Literal', + value: 1, + raw: '1', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + kind: 'init', + range: [6, 10], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 10 } + } + }, + { + type: 'Property', + key: { + type: 'Identifier', + name: 'x', + range: [12, 13], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 13 } + } + }, + value: { + type: 'Literal', + value: 2, + raw: '2', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }, + kind: 'init', + range: [12, 16], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 16 } + } + } + ], + range: [4, 18], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 18 } + } + }, + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + } + }, + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + } + }, + + 'x = { get width() { return m_width } }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'width', + range: [10, 15], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 15 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ReturnStatement', + argument: { + type: 'Identifier', + name: 'm_width', + range: [27, 34], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 34 } + } + }, + range: [20, 35], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 35 } + } + }], + range: [18, 36], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 36 } + } + }, + rest: null, + generator: false, + expression: false, + range: [18, 36], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 36 } + } + }, + kind: 'get', + range: [6, 36], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 36 } + } + }], + range: [4, 38], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 38 } + } + }, + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + } + }, + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + } + }, + + 'x = { get undef() {} }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'undef', + range: [10, 15], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 15 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [18, 20], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 20 } + } + }, + rest: null, + generator: false, + expression: false, + range: [18, 20], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 20 } + } + }, + kind: 'get', + range: [6, 20], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 20 } + } + }], + range: [4, 22], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }, + + 'x = { get if() {} }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'if', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [15, 17], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 17 } + } + }, + rest: null, + generator: false, + expression: false, + range: [15, 17], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 17 } + } + }, + kind: 'get', + range: [6, 17], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 17 } + } + }], + range: [4, 19], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 19 } + } + }, + range: [0, 19], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 19 } + } + }, + range: [0, 19], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 19 } + } + }, + + 'x = { get true() {} }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'true', + range: [10, 14], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 14 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [17, 19], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 19 } + } + }, + rest: null, + generator: false, + expression: false, + range: [17, 19], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 19 } + } + }, + kind: 'get', + range: [6, 19], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 19 } + } + }], + range: [4, 21], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + + 'x = { get false() {} }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'false', + range: [10, 15], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 15 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [18, 20], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 20 } + } + }, + rest: null, + generator: false, + expression: false, + range: [18, 20], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 20 } + } + }, + kind: 'get', + range: [6, 20], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 20 } + } + }], + range: [4, 22], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }, + + 'x = { get null() {} }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'null', + range: [10, 14], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 14 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [17, 19], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 19 } + } + }, + rest: null, + generator: false, + expression: false, + range: [17, 19], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 19 } + } + }, + kind: 'get', + range: [6, 19], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 19 } + } + }], + range: [4, 21], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + + 'x = { get "undef"() {} }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Literal', + value: 'undef', + raw: '"undef"', + range: [10, 17], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 17 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [20, 22], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 22 } + } + }, + rest: null, + generator: false, + expression: false, + range: [20, 22], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 22 } + } + }, + kind: 'get', + range: [6, 22], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 22 } + } + }], + range: [4, 24], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 24 } + } + }, + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + } + }, + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + } + }, + + 'x = { get 10() {} }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Literal', + value: 10, + raw: '10', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [15, 17], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 17 } + } + }, + rest: null, + generator: false, + expression: false, + range: [15, 17], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 17 } + } + }, + kind: 'get', + range: [6, 17], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 17 } + } + }], + range: [4, 19], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 19 } + } + }, + range: [0, 19], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 19 } + } + }, + range: [0, 19], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 19 } + } + }, + + 'x = { set width(w) { m_width = w } }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'width', + range: [10, 15], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 15 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'w', + range: [16, 17], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 17 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'm_width', + range: [21, 28], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 28 } + } + }, + right: { + type: 'Identifier', + name: 'w', + range: [31, 32], + loc: { + start: { line: 1, column: 31 }, + end: { line: 1, column: 32 } + } + }, + range: [21, 32], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 32 } + } + }, + range: [21, 33], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 33 } + } + }], + range: [19, 34], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 34 } + } + }, + rest: null, + generator: false, + expression: false, + range: [19, 34], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 34 } + } + }, + kind: 'set', + range: [6, 34], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 34 } + } + }], + range: [4, 36], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 36 } + } + }, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + + 'x = { set if(w) { m_if = w } }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'if', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'w', + range: [13, 14], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 14 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'm_if', + range: [18, 22], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 22 } + } + }, + right: { + type: 'Identifier', + name: 'w', + range: [25, 26], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 26 } + } + }, + range: [18, 26], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 26 } + } + }, + range: [18, 27], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 27 } + } + }], + range: [16, 28], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 28 } + } + }, + rest: null, + generator: false, + expression: false, + range: [16, 28], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 28 } + } + }, + kind: 'set', + range: [6, 28], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 28 } + } + }], + range: [4, 30], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 30 } + } + }, + range: [0, 30], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 30 } + } + }, + range: [0, 30], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 30 } + } + }, + + 'x = { set true(w) { m_true = w } }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'true', + range: [10, 14], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 14 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'w', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'm_true', + range: [20, 26], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 26 } + } + }, + right: { + type: 'Identifier', + name: 'w', + range: [29, 30], + loc: { + start: { line: 1, column: 29 }, + end: { line: 1, column: 30 } + } + }, + range: [20, 30], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 30 } + } + }, + range: [20, 31], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 31 } + } + }], + range: [18, 32], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 32 } + } + }, + rest: null, + generator: false, + expression: false, + range: [18, 32], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 32 } + } + }, + kind: 'set', + range: [6, 32], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 32 } + } + }], + range: [4, 34], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 34 } + } + }, + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + } + }, + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + } + }, + + 'x = { set false(w) { m_false = w } }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'false', + range: [10, 15], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 15 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'w', + range: [16, 17], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 17 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'm_false', + range: [21, 28], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 28 } + } + }, + right: { + type: 'Identifier', + name: 'w', + range: [31, 32], + loc: { + start: { line: 1, column: 31 }, + end: { line: 1, column: 32 } + } + }, + range: [21, 32], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 32 } + } + }, + range: [21, 33], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 33 } + } + }], + range: [19, 34], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 34 } + } + }, + rest: null, + generator: false, + expression: false, + range: [19, 34], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 34 } + } + }, + kind: 'set', + range: [6, 34], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 34 } + } + }], + range: [4, 36], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 36 } + } + }, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + + 'x = { set null(w) { m_null = w } }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'null', + range: [10, 14], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 14 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'w', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'm_null', + range: [20, 26], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 26 } + } + }, + right: { + type: 'Identifier', + name: 'w', + range: [29, 30], + loc: { + start: { line: 1, column: 29 }, + end: { line: 1, column: 30 } + } + }, + range: [20, 30], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 30 } + } + }, + range: [20, 31], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 31 } + } + }], + range: [18, 32], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 32 } + } + }, + rest: null, + generator: false, + expression: false, + range: [18, 32], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 32 } + } + }, + kind: 'set', + range: [6, 32], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 32 } + } + }], + range: [4, 34], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 34 } + } + }, + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + } + }, + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + } + }, + + 'x = { set "null"(w) { m_null = w } }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Literal', + value: 'null', + raw: '"null"', + range: [10, 16], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 16 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'w', + range: [17, 18], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 18 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'm_null', + range: [22, 28], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 28 } + } + }, + right: { + type: 'Identifier', + name: 'w', + range: [31, 32], + loc: { + start: { line: 1, column: 31 }, + end: { line: 1, column: 32 } + } + }, + range: [22, 32], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 32 } + } + }, + range: [22, 33], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 33 } + } + }], + range: [20, 34], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 34 } + } + }, + rest: null, + generator: false, + expression: false, + range: [20, 34], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 34 } + } + }, + kind: 'set', + range: [6, 34], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 34 } + } + }], + range: [4, 36], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 36 } + } + }, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + + 'x = { set 10(w) { m_null = w } }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Literal', + value: 10, + raw: '10', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'w', + range: [13, 14], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 14 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'm_null', + range: [18, 24], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 24 } + } + }, + right: { + type: 'Identifier', + name: 'w', + range: [27, 28], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 28 } + } + }, + range: [18, 28], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 28 } + } + }, + range: [18, 29], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 29 } + } + }], + range: [16, 30], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 30 } + } + }, + rest: null, + generator: false, + expression: false, + range: [16, 30], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 30 } + } + }, + kind: 'set', + range: [6, 30], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 30 } + } + }], + range: [4, 32], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 32 } + } + }, + range: [0, 32], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 32 } + } + }, + range: [0, 32], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 32 } + } + }, + + 'x = { get: 42 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'get', + range: [6, 9], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 9 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [11, 13], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 13 } + } + }, + kind: 'init', + range: [6, 13], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 13 } + } + }], + range: [4, 15], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + + 'x = { set: 43 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'set', + range: [6, 9], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 9 } + } + }, + value: { + type: 'Literal', + value: 43, + raw: '43', + range: [11, 13], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 13 } + } + }, + kind: 'init', + range: [6, 13], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 13 } + } + }], + range: [4, 15], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + } + + }, + + 'Comments': { + + '/* block comment */ 42': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [20, 22], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 22 } + } + }, + range: [20, 22], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 22 } + } + }, + + '42 /*The*/ /*Answer*/': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }], + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + }, + comments: [{ + type: 'Block', + value: 'The', + range: [3, 10], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 10 } + } + }, { + type: 'Block', + value: 'Answer', + range: [11, 21], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 21 } + } + }] + }, + + '42 /*the*/ /*answer*/': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [0, 2] + }, + range: [0, 21] + }], + range: [0, 21], + comments: [{ + type: 'Block', + value: 'the', + range: [3, 10] + }, { + type: 'Block', + value: 'answer', + range: [11, 21] + }] + }, + + '/* multiline\ncomment\nshould\nbe\nignored */ 42': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [42, 44], + loc: { + start: { line: 5, column: 11 }, + end: { line: 5, column: 13 } + } + }, + range: [42, 44], + loc: { + start: { line: 5, column: 11 }, + end: { line: 5, column: 13 } + } + }, + + '/*a\r\nb*/ 42': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [9, 11], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }, + range: [9, 11], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }], + range: [9, 11], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + }, + comments: [{ + type: 'Block', + value: 'a\r\nb', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 3 } + } + }] + }, + + '/*a\rb*/ 42': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [8, 10], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }, + range: [8, 10], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }], + range: [8, 10], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + }, + comments: [{ + type: 'Block', + value: 'a\rb', + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 3 } + } + }] + }, + + '/*a\nb*/ 42': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [8, 10], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }, + range: [8, 10], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }], + range: [8, 10], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + }, + comments: [{ + type: 'Block', + value: 'a\nb', + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 3 } + } + }] + }, + + '/*a\nc*/ 42': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }, + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + }, + comments: [{ + type: 'Block', + value: 'a\nc', + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 3 } + } + }] + }, + + '// line comment\n42': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [16, 18], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + }, + range: [16, 18], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + }, + + '42 // line comment': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + } + }], + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + }, + comments: [{ + type: 'Line', + value: ' line comment', + range: [3, 18], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 18 } + } + }] + }, + + '// Hello, world!\n42': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [17, 19], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + }, + range: [17, 19], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + }], + range: [17, 19], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + }, + comments: [{ + type: 'Line', + value: ' Hello, world!', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }] + }, + + '// Hello, world!\n': { + type: 'Program', + body: [], + range: [17, 17], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 0 } + }, + comments: [{ + type: 'Line', + value: ' Hello, world!', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }] + }, + + '// Hallo, world!\n': { + type: 'Program', + body: [], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 0 } + }, + comments: [{ + type: 'Line', + value: ' Hallo, world!', + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }] + }, + + '//\n42': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [3, 5], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + }, + range: [3, 5], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + }], + range: [3, 5], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + }, + comments: [{ + type: 'Line', + value: '', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }] + }, + + '//': { + type: 'Program', + body: [], + range: [2, 2], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 2 } + }, + comments: [{ + type: 'Line', + value: '', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }] + }, + + '// ': { + type: 'Program', + body: [], + range: [3, 3], + comments: [{ + type: 'Line', + value: ' ', + range: [0, 3] + }] + }, + + '/**/42': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + } + }, + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + } + }], + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + }, + comments: [{ + type: 'Block', + value: '', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }] + }, + + '// Hello, world!\n\n// Another hello\n42': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [37, 39], + loc: { + start: { line: 4, column: 0 }, + end: { line: 4, column: 2 } + } + }, + range: [37, 39], + loc: { + start: { line: 4, column: 0 }, + end: { line: 4, column: 2 } + } + }], + range: [37, 39], + loc: { + start: { line: 4, column: 0 }, + end: { line: 4, column: 2 } + }, + comments: [{ + type: 'Line', + value: ' Hello, world!', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, { + type: 'Line', + value: ' Another hello', + range: [18, 36], + loc: { + start: { line: 3, column: 0 }, + end: { line: 3, column: 18 } + } + }] + }, + + 'if (x) { // Some comment\ndoThat(); }': { + type: 'Program', + body: [{ + type: 'IfStatement', + test: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + consequent: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'doThat', + range: [25, 31], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 6 } + } + }, + 'arguments': [], + range: [25, 33], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 8 } + } + }, + range: [25, 34], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 9 } + } + }], + range: [7, 36], + loc: { + start: { line: 1, column: 7 }, + end: { line: 2, column: 11 } + } + }, + alternate: null, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 11 } + } + }], + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 11 } + }, + comments: [{ + type: 'Line', + value: ' Some comment', + range: [9, 24], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 24 } + } + }] + }, + + 'switch (answer) { case 42: /* perfect */ bingo() }': { + type: 'Program', + body: [{ + type: 'SwitchStatement', + discriminant: { + type: 'Identifier', + name: 'answer', + range: [8, 14], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 14 } + } + }, + cases: [{ + type: 'SwitchCase', + test: { + type: 'Literal', + value: 42, + raw: '42', + range: [23, 25], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 25 } + } + }, + consequent: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'bingo', + range: [41, 46], + loc: { + start: { line: 1, column: 41 }, + end: { line: 1, column: 46 } + } + }, + 'arguments': [], + range: [41, 48], + loc: { + start: { line: 1, column: 41 }, + end: { line: 1, column: 48 } + } + }, + range: [41, 49], + loc: { + start: { line: 1, column: 41 }, + end: { line: 1, column: 49 } + } + }], + range: [18, 49], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 49 } + } + }], + range: [0, 50], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 50 } + } + }], + range: [0, 50], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 50 } + }, + comments: [{ + type: 'Block', + value: ' perfect ', + range: [27, 40], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 40 } + } + }] + } + + }, + + 'Numeric Literals': { + + '0': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0, + raw: '0', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + + '42': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + + '3': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 3, + raw: '3', + range: [0, 1] + }, + range: [0, 1] + }], + range: [0, 1], + tokens: [{ + type: 'Numeric', + value: '3', + range: [0, 1] + }] + }, + + '5': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 5, + raw: '5', + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + }, + tokens: [{ + type: 'Numeric', + value: '5', + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }] + }, + + '.14': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0.14, + raw: '.14', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + + '3.14159': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 3.14159, + raw: '3.14159', + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + '6.02214179e+23': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 6.02214179e+23, + raw: '6.02214179e+23', + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + + '1.492417830e-10': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 1.49241783e-10, + raw: '1.492417830e-10', + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + + '0x0': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0, + raw: '0x0', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + + '0e+100': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0, + raw: '0e+100', + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + '0xabc': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0xabc, + raw: '0xabc', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + '0xdef': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0xdef, + raw: '0xdef', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + '0X1A': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0x1A, + raw: '0X1A', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + + '0x10': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0x10, + raw: '0x10', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + + '0x100': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0x100, + raw: '0x100', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + '0X04': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0X04, + raw: '0X04', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + + '02': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 2, + raw: '02', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + + '012': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 10, + raw: '012', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + + '0012': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 10, + raw: '0012', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + } + + }, + + 'String Literals': { + + '"Hello"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello', + raw: '"Hello"', + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + '"\\n\\r\\t\\v\\b\\f\\\\\\\'\\"\\0"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: '\n\r\t\x0B\b\f\\\'"\x00', + raw: '"\\n\\r\\t\\v\\b\\f\\\\\\\'\\"\\0"', + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }, + + '"\\u0061"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'a', + raw: '"\\u0061"', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + + '"\\x61"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'a', + raw: '"\\x61"', + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + '"\\u00"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'u00', + raw: '"\\u00"', + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + '"\\xt"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'xt', + raw: '"\\xt"', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + '"Hello\\nworld"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\nworld', + raw: '"Hello\\nworld"', + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + + '"Hello\\\nworld"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Helloworld', + raw: '"Hello\\\nworld"', + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 14 } + } + }, + + '"Hello\\02World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\u0002World', + raw: '"Hello\\02World"', + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + + '"Hello\\012World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\u000AWorld', + raw: '"Hello\\012World"', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + '"Hello\\122World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\122World', + raw: '"Hello\\122World"', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + '"Hello\\0122World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\u000A2World', + raw: '"Hello\\0122World"', + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + + '"Hello\\312World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\u00CAWorld', + raw: '"Hello\\312World"', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + '"Hello\\412World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\412World', + raw: '"Hello\\412World"', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + '"Hello\\812World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello812World', + raw: '"Hello\\812World"', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + '"Hello\\712World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\712World', + raw: '"Hello\\712World"', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + '"Hello\\0World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\u0000World', + raw: '"Hello\\0World"', + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + + '"Hello\\\r\nworld"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Helloworld', + raw: '"Hello\\\r\nworld"', + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 15 } + } + }, + + '"Hello\\1World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\u0001World', + raw: '"Hello\\1World"', + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + } + }, + + 'Regular Expression Literals': { + + 'var x = /[a-z]/i': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: '/[a-z]/i', + raw: '/[a-z]/i', + range: [8, 16], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 16 } + } + }, + range: [4, 16], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 16 } + } + }], + kind: 'var', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }], + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + }, + tokens: [{ + type: 'Keyword', + value: 'var', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Identifier', + value: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: '=', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'RegularExpression', + value: '/[a-z]/i', + range: [8, 16], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 16 } + } + }] + }, + + 'var x = /[x-z]/i': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5] + }, + init: { + type: 'Literal', + value: '/[x-z]/i', + raw: '/[x-z]/i', + range: [8, 16] + }, + range: [4, 16] + }], + kind: 'var', + range: [0, 16] + }], + range: [0, 16], + tokens: [{ + type: 'Keyword', + value: 'var', + range: [0, 3] + }, { + type: 'Identifier', + value: 'x', + range: [4, 5] + }, { + type: 'Punctuator', + value: '=', + range: [6, 7] + }, { + type: 'RegularExpression', + value: '/[x-z]/i', + range: [8, 16] + }] + }, + + 'var x = /[a-c]/i': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: '/[a-c]/i', + raw: '/[a-c]/i', + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 16 } + } + }, + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 16 } + } + }], + kind: 'var', + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + }, + tokens: [{ + type: 'Keyword', + value: 'var', + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Identifier', + value: 'x', + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: '=', + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'RegularExpression', + value: '/[a-c]/i', + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 16 } + } + }] + }, + + 'var x = /[P QR]/i': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: '/[P QR]/i', + raw: '/[P QR]/i', + range: [8, 17], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 17 } + } + }, + range: [4, 17], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 17 } + } + }], + kind: 'var', + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }], + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + }, + tokens: [{ + type: 'Keyword', + value: 'var', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Identifier', + value: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: '=', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'RegularExpression', + value: '/[P QR]/i', + range: [8, 17], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 17 } + } + }] + }, + + 'var x = /[\\]/]/': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: new RegExp('[\\]/]').toString(), + raw: '/[\\]/]/', + range: [8, 15], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 15 } + } + }, + range: [4, 15], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 15 } + } + }], + kind: 'var', + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }], + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + }, + tokens: [{ + type: 'Keyword', + value: 'var', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Identifier', + value: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: '=', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'RegularExpression', + value: '/[\\]/]/', + range: [8, 15], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 15 } + } + }] + }, + + 'var x = /foo\\/bar/': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: '/foo\\/bar/', + raw: '/foo\\/bar/', + range: [8, 18], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 18 } + } + }, + range: [4, 18], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 18 } + } + }], + kind: 'var', + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + } + }], + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + }, + tokens: [{ + type: 'Keyword', + value: 'var', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Identifier', + value: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: '=', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'RegularExpression', + value: '/foo\\/bar/', + range: [8, 18], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 18 } + } + }] + }, + + 'var x = /=([^=\\s])+/g': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: '/=([^=\\s])+/g', + raw: '/=([^=\\s])+/g', + range: [8, 21], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 21 } + } + }, + range: [4, 21], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 21 } + } + }], + kind: 'var', + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }], + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + }, + tokens: [{ + type: 'Keyword', + value: 'var', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Identifier', + value: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: '=', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'RegularExpression', + value: '/=([^=\\s])+/g', + range: [8, 21], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 21 } + } + }] + }, + + 'var x = /[P QR]/\\u0067': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: '/[P QR]/g', + raw: '/[P QR]/\\u0067', + range: [8, 22], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 22 } + } + }, + range: [4, 22], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 22 } + } + }], + kind: 'var', + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }], + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + }, + tokens: [{ + type: 'Keyword', + value: 'var', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Identifier', + value: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: '=', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'RegularExpression', + value: '/[P QR]/\\u0067', + range: [8, 22], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 22 } + } + }] + }, + + 'var x = /[P QR]/\\g': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: '/[P QR]/g', + raw: '/[P QR]/\\g', + range: [8, 18], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 18 } + } + }, + range: [4, 18], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 18 } + } + }], + kind: 'var', + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + } + }], + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + }, + tokens: [{ + type: 'Keyword', + value: 'var', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Identifier', + value: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: '=', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'RegularExpression', + value: '/[P QR]/\\g', + range: [8, 18], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 18 } + } + }] + } + + }, + + 'Left-Hand-Side Expression': { + + 'new Button': { + type: 'ExpressionStatement', + expression: { + type: 'NewExpression', + callee: { + type: 'Identifier', + name: 'Button', + range: [4, 10], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 10 } + } + }, + 'arguments': [], + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + }, + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + }, + + 'new Button()': { + type: 'ExpressionStatement', + expression: { + type: 'NewExpression', + callee: { + type: 'Identifier', + name: 'Button', + range: [4, 10], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 10 } + } + }, + 'arguments': [], + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + + 'new new foo': { + type: 'ExpressionStatement', + expression: { + type: 'NewExpression', + callee: { + type: 'NewExpression', + callee: { + type: 'Identifier', + name: 'foo', + range: [8, 11], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 11 } + } + }, + 'arguments': [], + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + 'arguments': [], + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'new new foo()': { + type: 'ExpressionStatement', + expression: { + type: 'NewExpression', + callee: { + type: 'NewExpression', + callee: { + type: 'Identifier', + name: 'foo', + range: [8, 11], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 11 } + } + }, + 'arguments': [], + range: [4, 13], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 13 } + } + }, + 'arguments': [], + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + + 'new foo().bar()': { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + computed: false, + object: { + type: 'NewExpression', + callee: { + type: 'Identifier', + name: 'foo', + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + 'arguments': [], + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + property: { + type: 'Identifier', + name: 'bar', + range: [10, 13], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + 'arguments': [], + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + + 'new foo[bar]': { + type: 'ExpressionStatement', + expression: { + type: 'NewExpression', + callee: { + type: 'MemberExpression', + computed: true, + object: { + type: 'Identifier', + name: 'foo', + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + property: { + type: 'Identifier', + name: 'bar', + range: [8, 11], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 11 } + } + }, + range: [4, 12], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 12 } + } + }, + 'arguments': [], + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + + 'new foo.bar()': { + type: 'ExpressionStatement', + expression: { + type: 'NewExpression', + callee: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'foo', + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + property: { + type: 'Identifier', + name: 'bar', + range: [8, 11], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 11 } + } + }, + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + 'arguments': [], + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + + '( new foo).bar()': { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + computed: false, + object: { + type: 'NewExpression', + callee: { + type: 'Identifier', + name: 'foo', + range: [6, 9], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 9 } + } + }, + 'arguments': [], + range: [2, 9], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 9 } + } + }, + property: { + type: 'Identifier', + name: 'bar', + range: [11, 14], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + 'arguments': [], + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + 'foo(bar, baz)': { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'foo', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'bar', + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, { + type: 'Identifier', + name: 'baz', + range: [9, 12], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 12 } + } + }], + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + + '( foo )()': { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'foo', + range: [5, 8], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 8 } + } + }, + 'arguments': [], + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + + 'universe.milkyway': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Identifier', + name: 'milkyway', + range: [9, 17], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + + 'universe.milkyway.solarsystem': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Identifier', + name: 'milkyway', + range: [9, 17], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + property: { + type: 'Identifier', + name: 'solarsystem', + range: [18, 29], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 29 } + } + }, + range: [0, 29], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 29 } + } + }, + range: [0, 29], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 29 } + } + }, + + 'universe.milkyway.solarsystem.Earth': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'MemberExpression', + computed: false, + object: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Identifier', + name: 'milkyway', + range: [9, 17], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + property: { + type: 'Identifier', + name: 'solarsystem', + range: [18, 29], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 29 } + } + }, + range: [0, 29], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 29 } + } + }, + property: { + type: 'Identifier', + name: 'Earth', + range: [30, 35], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 35 } + } + }, + range: [0, 35], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 35 } + } + }, + range: [0, 35], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 35 } + } + }, + + 'universe[galaxyName, otherUselessName]': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: true, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'SequenceExpression', + expressions: [{ + type: 'Identifier', + name: 'galaxyName', + range: [9, 19], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 19 } + } + }, { + type: 'Identifier', + name: 'otherUselessName', + range: [21, 37], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 37 } + } + }], + range: [9, 37], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 37 } + } + }, + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + } + }, + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + } + }, + + 'universe[galaxyName]': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: true, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Identifier', + name: 'galaxyName', + range: [9, 19], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 19 } + } + }, + range: [0, 20], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 20 } + } + }, + range: [0, 20], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 20 } + } + }, + + 'universe[42].galaxies': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'MemberExpression', + computed: true, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Literal', + value: 42, + raw: '42', + range: [9, 11], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + property: { + type: 'Identifier', + name: 'galaxies', + range: [13, 21], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + + 'universe(42).galaxies': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + 'arguments': [{ + type: 'Literal', + value: 42, + raw: '42', + range: [9, 11], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 11 } + } + }], + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + property: { + type: 'Identifier', + name: 'galaxies', + range: [13, 21], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + + 'universe(42).galaxies(14, 3, 77).milkyway': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + computed: false, + object: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + 'arguments': [{ + type: 'Literal', + value: 42, + raw: '42', + range: [9, 11], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 11 } + } + }], + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + property: { + type: 'Identifier', + name: 'galaxies', + range: [13, 21], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + 'arguments': [{ + type: 'Literal', + value: 14, + raw: '14', + range: [22, 24], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 24 } + } + }, { + type: 'Literal', + value: 3, + raw: '3', + range: [26, 27], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 27 } + } + }, { + type: 'Literal', + value: 77, + raw: '77', + range: [29, 31], + loc: { + start: { line: 1, column: 29 }, + end: { line: 1, column: 31 } + } + }], + range: [0, 32], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 32 } + } + }, + property: { + type: 'Identifier', + name: 'milkyway', + range: [33, 41], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 41 } + } + }, + range: [0, 41], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 41 } + } + }, + range: [0, 41], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 41 } + } + }, + + 'earth.asia.Indonesia.prepareForElection(2014)': { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + computed: false, + object: { + type: 'MemberExpression', + computed: false, + object: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'earth', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + property: { + type: 'Identifier', + name: 'asia', + range: [6, 10], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 10 } + } + }, + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + }, + property: { + type: 'Identifier', + name: 'Indonesia', + range: [11, 20], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 20 } + } + }, + range: [0, 20], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 20 } + } + }, + property: { + type: 'Identifier', + name: 'prepareForElection', + range: [21, 39], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 39 } + } + }, + range: [0, 39], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 39 } + } + }, + 'arguments': [{ + type: 'Literal', + value: 2014, + raw: '2014', + range: [40, 44], + loc: { + start: { line: 1, column: 40 }, + end: { line: 1, column: 44 } + } + }], + range: [0, 45], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 45 } + } + }, + range: [0, 45], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 45 } + } + }, + + 'universe.if': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Identifier', + name: 'if', + range: [9, 11], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'universe.true': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Identifier', + name: 'true', + range: [9, 13], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + + 'universe.false': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Identifier', + name: 'false', + range: [9, 14], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + + 'universe.null': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Identifier', + name: 'null', + range: [9, 13], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + } + + }, + + 'Postfix Expressions': { + + 'x++': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + prefix: false, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + + 'x--': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + prefix: false, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + + 'eval++': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'eval', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + prefix: false, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'eval--': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'eval', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + prefix: false, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'arguments++': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'arguments', + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + prefix: false, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'arguments--': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'arguments', + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + prefix: false, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + } + + }, + + 'Unary Operators': { + + '++x': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'x', + range: [2, 3], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 3 } + } + }, + prefix: true, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + + '--x': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'x', + range: [2, 3], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 3 } + } + }, + prefix: true, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + + '++eval': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'eval', + range: [2, 6], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 6 } + } + }, + prefix: true, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + '--eval': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'eval', + range: [2, 6], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 6 } + } + }, + prefix: true, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + '++arguments': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'arguments', + range: [2, 11], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 11 } + } + }, + prefix: true, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + '--arguments': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'arguments', + range: [2, 11], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 11 } + } + }, + prefix: true, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + '+x': { + type: 'ExpressionStatement', + expression: { + type: 'UnaryExpression', + operator: '+', + argument: { + type: 'Identifier', + name: 'x', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + prefix: true, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + + '-x': { + type: 'ExpressionStatement', + expression: { + type: 'UnaryExpression', + operator: '-', + argument: { + type: 'Identifier', + name: 'x', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + prefix: true, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + + '~x': { + type: 'ExpressionStatement', + expression: { + type: 'UnaryExpression', + operator: '~', + argument: { + type: 'Identifier', + name: 'x', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + prefix: true, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + + '!x': { + type: 'ExpressionStatement', + expression: { + type: 'UnaryExpression', + operator: '!', + argument: { + type: 'Identifier', + name: 'x', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + prefix: true, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + + 'void x': { + type: 'ExpressionStatement', + expression: { + type: 'UnaryExpression', + operator: 'void', + argument: { + type: 'Identifier', + name: 'x', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + prefix: true, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'delete x': { + type: 'ExpressionStatement', + expression: { + type: 'UnaryExpression', + operator: 'delete', + argument: { + type: 'Identifier', + name: 'x', + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }, + prefix: true, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + + 'typeof x': { + type: 'ExpressionStatement', + expression: { + type: 'UnaryExpression', + operator: 'typeof', + argument: { + type: 'Identifier', + name: 'x', + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }, + prefix: true, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + } + + }, + + 'Multiplicative Operators': { + + 'x * y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + 'x / y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '/', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + 'x % y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '%', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + } + + }, + + 'Additive Operators': { + + 'x + y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + 'x - y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '-', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + } + + }, + + 'Bitwise Shift Operator': { + + 'x << y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '<<', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x >> y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '>>', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x >>> y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '>>>', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + } + + }, + + 'Relational Operators': { + + 'x < y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '<', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + 'x > y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '>', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + 'x <= y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '<=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x >= y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '>=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x in y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: 'in', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x instanceof y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: 'instanceof', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [13, 14], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + + 'x < y < z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '<', + left: { + type: 'BinaryExpression', + operator: '<', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + } + + }, + + 'Equality Operators': { + + 'x == y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '==', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x != y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '!=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x === y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '===', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x !== y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '!==', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + } + + }, + + 'Binary Bitwise Operators': { + + 'x & y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '&', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + 'x ^ y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '^', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + 'x | y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '|', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + } + + }, + + 'Binary Expressions': { + + 'x + y + z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x - y + z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'BinaryExpression', + operator: '-', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x + y - z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '-', + left: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x - y - z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '-', + left: { + type: 'BinaryExpression', + operator: '-', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x + y * z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x + y / z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'BinaryExpression', + operator: '/', + left: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x - y % z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '-', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'BinaryExpression', + operator: '%', + left: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x * y * z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x * y / z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '/', + left: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x * y % z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '%', + left: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x % y * z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'BinaryExpression', + operator: '%', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x << y << z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '<<', + left: { + type: 'BinaryExpression', + operator: '<<', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [10, 11], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'x | y | z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '|', + left: { + type: 'BinaryExpression', + operator: '|', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x & y & z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '&', + left: { + type: 'BinaryExpression', + operator: '&', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x ^ y ^ z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '^', + left: { + type: 'BinaryExpression', + operator: '^', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x & y | z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '|', + left: { + type: 'BinaryExpression', + operator: '&', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x | y ^ z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '|', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'BinaryExpression', + operator: '^', + left: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x | y & z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '|', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'BinaryExpression', + operator: '&', + left: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + } + + }, + + 'Binary Logical Operators': { + + 'x || y': { + type: 'ExpressionStatement', + expression: { + type: 'LogicalExpression', + operator: '||', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x && y': { + type: 'ExpressionStatement', + expression: { + type: 'LogicalExpression', + operator: '&&', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x || y || z': { + type: 'ExpressionStatement', + expression: { + type: 'LogicalExpression', + operator: '||', + left: { + type: 'LogicalExpression', + operator: '||', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [10, 11], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'x && y && z': { + type: 'ExpressionStatement', + expression: { + type: 'LogicalExpression', + operator: '&&', + left: { + type: 'LogicalExpression', + operator: '&&', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [10, 11], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'x || y && z': { + type: 'ExpressionStatement', + expression: { + type: 'LogicalExpression', + operator: '||', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'LogicalExpression', + operator: '&&', + left: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [10, 11], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 11 } + } + }, + range: [5, 11], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'x || y ^ z': { + type: 'ExpressionStatement', + expression: { + type: 'LogicalExpression', + operator: '||', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'BinaryExpression', + operator: '^', + left: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + range: [5, 10], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 10 } + } + }, + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + }, + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + } + + }, + + 'Conditional Operator': { + + 'y ? 1 : 2': { + type: 'ExpressionStatement', + expression: { + type: 'ConditionalExpression', + test: { + type: 'Identifier', + name: 'y', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + consequent: { + type: 'Literal', + value: 1, + raw: '1', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + alternate: { + type: 'Literal', + value: 2, + raw: '2', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x && y ? 1 : 2': { + type: 'ExpressionStatement', + expression: { + type: 'ConditionalExpression', + test: { + type: 'LogicalExpression', + operator: '&&', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + consequent: { + type: 'Literal', + value: 1, + raw: '1', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + alternate: { + type: 'Literal', + value: 2, + raw: '2', + range: [13, 14], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + } + + }, + + 'Assignment Operators': { + + 'x = 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'eval = 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'eval', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [7, 9], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'arguments = 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'arguments', + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [12, 14], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + + 'x *= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '*=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x /= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '/=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x %= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '%=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x += 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '+=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x -= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '-=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x <<= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '<<=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [6, 8], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + + 'x >>= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '>>=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [6, 8], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + + 'x >>>= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '>>>=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [7, 9], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x &= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '&=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x ^= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '^=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x |= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '|=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + } + + }, + + 'Block': { + + '{ foo }': { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'foo', + range: [2, 5], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 5 } + } + }, + range: [2, 6], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 6 } + } + }], + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + '{ doThis(); doThat(); }': { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'doThis', + range: [2, 8], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 8 } + } + }, + 'arguments': [], + range: [2, 10], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 10 } + } + }, + range: [2, 11], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 11 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'doThat', + range: [12, 18], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 18 } + } + }, + 'arguments': [], + range: [12, 20], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 20 } + } + }, + range: [12, 21], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 21 } + } + }], + range: [0, 23], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 23 } + } + }, + + '{}': { + type: 'BlockStatement', + body: [], + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + } + + }, + + 'Variable Statement': { + + 'var x': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: null, + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }], + kind: 'var', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + 'var x, y;': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: null, + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'y', + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }, + init: null, + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }], + kind: 'var', + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'var x = 42': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: 42, + raw: '42', + range: [8, 10], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 10 } + } + }, + range: [4, 10], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 10 } + } + }], + kind: 'var', + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + }, + + 'var eval = 42, arguments = 42': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'eval', + range: [4, 8], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 8 } + } + }, + init: { + type: 'Literal', + value: 42, + raw: '42', + range: [11, 13], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 13 } + } + }, + range: [4, 13], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 13 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'arguments', + range: [15, 24], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 24 } + } + }, + init: { + type: 'Literal', + value: 42, + raw: '42', + range: [27, 29], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 29 } + } + }, + range: [15, 29], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 29 } + } + }], + kind: 'var', + range: [0, 29], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 29 } + } + }, + + 'var x = 14, y = 3, z = 1977': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: 14, + raw: '14', + range: [8, 10], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 10 } + } + }, + range: [4, 10], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 10 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'y', + range: [12, 13], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 13 } + } + }, + init: { + type: 'Literal', + value: 3, + raw: '3', + range: [16, 17], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 17 } + } + }, + range: [12, 17], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 17 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'z', + range: [19, 20], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 20 } + } + }, + init: { + type: 'Literal', + value: 1977, + raw: '1977', + range: [23, 27], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 27 } + } + }, + range: [19, 27], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 27 } + } + }], + kind: 'var', + range: [0, 27], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 27 } + } + }, + + 'var implements, interface, package': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'implements', + range: [4, 14], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 14 } + } + }, + init: null, + range: [4, 14], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 14 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'interface', + range: [16, 25], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 25 } + } + }, + init: null, + range: [16, 25], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 25 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'package', + range: [27, 34], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 34 } + } + }, + init: null, + range: [27, 34], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 34 } + } + }], + kind: 'var', + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + } + }, + + 'var private, protected, public, static': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'private', + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + init: null, + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'protected', + range: [13, 22], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 22 } + } + }, + init: null, + range: [13, 22], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 22 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'public', + range: [24, 30], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 30 } + } + }, + init: null, + range: [24, 30], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 30 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'static', + range: [32, 38], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 38 } + } + }, + init: null, + range: [32, 38], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 38 } + } + }], + kind: 'var', + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + } + } + + }, + + 'Let Statement': { + + 'let x': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: null, + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }], + kind: 'let', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + '{ let x }': { + type: 'BlockStatement', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + init: null, + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }], + kind: 'let', + range: [2, 8], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 8 } + } + }], + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + '{ let x = 42 }': { + type: 'BlockStatement', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + init: { + type: 'Literal', + value: 42, + raw: '42', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + range: [6, 12], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 12 } + } + }], + kind: 'let', + range: [2, 13], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 13 } + } + }], + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + + '{ let x = 14, y = 3, z = 1977 }': { + type: 'BlockStatement', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + init: { + type: 'Literal', + value: 14, + raw: '14', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + range: [6, 12], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 12 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'y', + range: [14, 15], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 15 } + } + }, + init: { + type: 'Literal', + value: 3, + raw: '3', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }, + range: [14, 19], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 19 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'z', + range: [21, 22], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 22 } + } + }, + init: { + type: 'Literal', + value: 1977, + raw: '1977', + range: [25, 29], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 29 } + } + }, + range: [21, 29], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 29 } + } + }], + kind: 'let', + range: [2, 30], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 30 } + } + }], + range: [0, 31], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 31 } + } + } + + }, + + 'Const Statement': { + + 'const x = 42': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + init: { + type: 'Literal', + value: 42, + raw: '42', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + range: [6, 12], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 12 } + } + }], + kind: 'const', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + + '{ const x = 42 }': { + type: 'BlockStatement', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + init: { + type: 'Literal', + value: 42, + raw: '42', + range: [12, 14], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 14 } + } + }, + range: [8, 14], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 14 } + } + }], + kind: 'const', + range: [2, 15], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 15 } + } + }], + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + '{ const x = 14, y = 3, z = 1977 }': { + type: 'BlockStatement', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + init: { + type: 'Literal', + value: 14, + raw: '14', + range: [12, 14], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 14 } + } + }, + range: [8, 14], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 14 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'y', + range: [16, 17], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 17 } + } + }, + init: { + type: 'Literal', + value: 3, + raw: '3', + range: [20, 21], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 21 } + } + }, + range: [16, 21], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 21 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'z', + range: [23, 24], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 24 } + } + }, + init: { + type: 'Literal', + value: 1977, + raw: '1977', + range: [27, 31], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 31 } + } + }, + range: [23, 31], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 31 } + } + }], + kind: 'const', + range: [2, 32], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 32 } + } + }], + range: [0, 33], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 33 } + } + } + + }, + + 'Empty Statement': { + + ';': { + type: 'EmptyStatement', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + } + + }, + + 'Expression Statement': { + + 'x': { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + + 'x, y': { + type: 'ExpressionStatement', + expression: { + type: 'SequenceExpression', + expressions: [{ + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, { + type: 'Identifier', + name: 'y', + range: [3, 4], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 4 } + } + }], + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + + '\\u0061': { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'a', + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'a\\u0061': { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'aa', + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + '\\ua': { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'ua', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + + 'a\\u': { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'au', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + } + + }, + + 'If Statement': { + + 'if (morning) goodMorning()': { + type: 'IfStatement', + test: { + type: 'Identifier', + name: 'morning', + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + consequent: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'goodMorning', + range: [13, 24], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 24 } + } + }, + 'arguments': [], + range: [13, 26], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 26 } + } + }, + range: [13, 26], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 26 } + } + }, + alternate: null, + range: [0, 26], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 26 } + } + }, + + 'if (morning) (function(){})': { + type: 'IfStatement', + test: { + type: 'Identifier', + name: 'morning', + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + consequent: { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [24, 26], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 26 } + } + }, + rest: null, + generator: false, + expression: false, + range: [14, 26], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 26 } + } + }, + range: [13, 27], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 27 } + } + }, + alternate: null, + range: [0, 27], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 27 } + } + }, + + 'if (morning) var x = 0;': { + type: 'IfStatement', + test: { + type: 'Identifier', + name: 'morning', + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + consequent: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [17, 18], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 18 } + } + }, + init: { + type: 'Literal', + value: 0, + raw: '0', + range: [21, 22], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 22 } + } + }, + range: [17, 22], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 22 } + } + }], + kind: 'var', + range: [13, 23], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 23 } + } + }, + alternate: null, + range: [0, 23], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 23 } + } + }, + + 'if (morning) function a(){}': { + type: 'IfStatement', + test: { + type: 'Identifier', + name: 'morning', + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + consequent: { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'a', + range: [22, 23], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 23 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [25, 27], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 27 } + } + }, + rest: null, + generator: false, + expression: false, + range: [13, 27], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 27 } + } + }, + alternate: null, + range: [0, 27], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 27 } + } + }, + + 'if (morning) goodMorning(); else goodDay()': { + type: 'IfStatement', + test: { + type: 'Identifier', + name: 'morning', + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + consequent: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'goodMorning', + range: [13, 24], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 24 } + } + }, + 'arguments': [], + range: [13, 26], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 26 } + } + }, + range: [13, 27], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 27 } + } + }, + alternate: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'goodDay', + range: [33, 40], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 40 } + } + }, + 'arguments': [], + range: [33, 42], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 42 } + } + }, + range: [33, 42], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 42 } + } + }, + range: [0, 42], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 42 } + } + } + + }, + + 'Iteration Statements': { + + 'do keep(); while (true)': { + type: 'DoWhileStatement', + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'keep', + range: [3, 7], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 7 } + } + }, + 'arguments': [], + range: [3, 9], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 9 } + } + }, + range: [3, 10], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 10 } + } + }, + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [18, 22], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 23], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 23 } + } + }, + + 'do keep(); while (true);': { + type: 'DoWhileStatement', + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'keep', + range: [3, 7], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 7 } + } + }, + 'arguments': [], + range: [3, 9], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 9 } + } + }, + range: [3, 10], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 10 } + } + }, + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [18, 22], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + } + }, + + 'do { x++; y--; } while (x < 10)': { + type: 'DoWhileStatement', + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'x', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + prefix: false, + range: [5, 8], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 8 } + } + }, + range: [5, 9], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 9 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'y', + range: [10, 11], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 11 } + } + }, + prefix: false, + range: [10, 13], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 13 } + } + }, + range: [10, 14], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 14 } + } + }], + range: [3, 16], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 16 } + } + }, + test: { + type: 'BinaryExpression', + operator: '<', + left: { + type: 'Identifier', + name: 'x', + range: [24, 25], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 25 } + } + }, + right: { + type: 'Literal', + value: 10, + raw: '10', + range: [28, 30], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 30 } + } + }, + range: [24, 30], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 30 } + } + }, + range: [0, 31], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 31 } + } + }, + + '{ do { } while (false) false }': { + type: 'BlockStatement', + body: [{ + type: 'DoWhileStatement', + body: { + type: 'BlockStatement', + body: [], + range: [5, 8], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 8 } + } + }, + test: { + type: 'Literal', + value: false, + raw: 'false', + range: [16, 21], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 21 } + } + }, + range: [2, 22], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 22 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: false, + raw: 'false', + range: [23, 28], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 28 } + } + }, + range: [23, 29], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 29 } + } + }], + range: [0, 30], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 30 } + } + }, + + 'while (true) doSomething()': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'doSomething', + range: [13, 24], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 24 } + } + }, + 'arguments': [], + range: [13, 26], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 26 } + } + }, + range: [13, 26], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 26 } + } + }, + range: [0, 26], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 26 } + } + }, + + 'while (x < 10) { x++; y--; }': { + type: 'WhileStatement', + test: { + type: 'BinaryExpression', + operator: '<', + left: { + type: 'Identifier', + name: 'x', + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }, + right: { + type: 'Literal', + value: 10, + raw: '10', + range: [11, 13], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 13 } + } + }, + range: [7, 13], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 13 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'x', + range: [17, 18], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 18 } + } + }, + prefix: false, + range: [17, 20], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 20 } + } + }, + range: [17, 21], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 21 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'y', + range: [22, 23], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 23 } + } + }, + prefix: false, + range: [22, 25], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 25 } + } + }, + range: [22, 26], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 26 } + } + }], + range: [15, 28], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 28 } + } + }, + range: [0, 28], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 28 } + } + }, + + 'for(;;);': { + type: 'ForStatement', + init: null, + test: null, + update: null, + body: { + type: 'EmptyStatement', + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + + 'for(;;){}': { + type: 'ForStatement', + init: null, + test: null, + update: null, + body: { + type: 'BlockStatement', + body: [], + range: [7, 9], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'for(x = 0;;);': { + type: 'ForStatement', + init: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Literal', + value: 0, + raw: '0', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + test: null, + update: null, + body: { + type: 'EmptyStatement', + range: [12, 13], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + + 'for(var x = 0;;);': { + type: 'ForStatement', + init: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + init: { + type: 'Literal', + value: 0, + raw: '0', + range: [12, 13], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 13 } + } + }, + range: [8, 13], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 13 } + } + }], + kind: 'var', + range: [4, 13], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 13 } + } + }, + test: null, + update: null, + body: { + type: 'EmptyStatement', + range: [16, 17], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + + 'for(let x = 0;;);': { + type: 'ForStatement', + init: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + init: { + type: 'Literal', + value: 0, + raw: '0', + range: [12, 13], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 13 } + } + }, + range: [8, 13], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 13 } + } + }], + kind: 'let', + range: [4, 13], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 13 } + } + }, + test: null, + update: null, + body: { + type: 'EmptyStatement', + range: [16, 17], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + + 'for(var x = 0, y = 1;;);': { + type: 'ForStatement', + init: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + init: { + type: 'Literal', + value: 0, + raw: '0', + range: [12, 13], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 13 } + } + }, + range: [8, 13], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 13 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'y', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }, + init: { + type: 'Literal', + value: 1, + raw: '1', + range: [19, 20], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 20 } + } + }, + range: [15, 20], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 20 } + } + }], + kind: 'var', + range: [4, 20], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 20 } + } + }, + test: null, + update: null, + body: { + type: 'EmptyStatement', + range: [23, 24], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 24 } + } + }, + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + } + }, + + 'for(x = 0; x < 42;);': { + type: 'ForStatement', + init: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Literal', + value: 0, + raw: '0', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + test: { + type: 'BinaryExpression', + operator: '<', + left: { + type: 'Identifier', + name: 'x', + range: [11, 12], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 12 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [15, 17], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 17 } + } + }, + range: [11, 17], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 17 } + } + }, + update: null, + body: { + type: 'EmptyStatement', + range: [19, 20], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 20 } + } + }, + range: [0, 20], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 20 } + } + }, + + 'for(x = 0; x < 42; x++);': { + type: 'ForStatement', + init: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Literal', + value: 0, + raw: '0', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + test: { + type: 'BinaryExpression', + operator: '<', + left: { + type: 'Identifier', + name: 'x', + range: [11, 12], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 12 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [15, 17], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 17 } + } + }, + range: [11, 17], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 17 } + } + }, + update: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'x', + range: [19, 20], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 20 } + } + }, + prefix: false, + range: [19, 22], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 22 } + } + }, + body: { + type: 'EmptyStatement', + range: [23, 24], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 24 } + } + }, + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + } + }, + + 'for(x = 0; x < 42; x++) process(x);': { + type: 'ForStatement', + init: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Literal', + value: 0, + raw: '0', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + test: { + type: 'BinaryExpression', + operator: '<', + left: { + type: 'Identifier', + name: 'x', + range: [11, 12], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 12 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [15, 17], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 17 } + } + }, + range: [11, 17], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 17 } + } + }, + update: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'x', + range: [19, 20], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 20 } + } + }, + prefix: false, + range: [19, 22], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 22 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'process', + range: [24, 31], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 31 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'x', + range: [32, 33], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 33 } + } + }], + range: [24, 34], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 34 } + } + }, + range: [24, 35], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 35 } + } + }, + range: [0, 35], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 35 } + } + }, + + 'for(x in list) process(x);': { + type: 'ForInStatement', + left: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'list', + range: [9, 13], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 13 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'process', + range: [15, 22], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 22 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'x', + range: [23, 24], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 24 } + } + }], + range: [15, 25], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 25 } + } + }, + range: [15, 26], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 26 } + } + }, + each: false, + range: [0, 26], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 26 } + } + }, + + 'for (var x in list) process(x);': { + type: 'ForInStatement', + left: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + init: null, + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }], + kind: 'var', + range: [5, 10], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 10 } + } + }, + right: { + type: 'Identifier', + name: 'list', + range: [14, 18], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 18 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'process', + range: [20, 27], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 27 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'x', + range: [28, 29], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 29 } + } + }], + range: [20, 30], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 30 } + } + }, + range: [20, 31], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 31 } + } + }, + each: false, + range: [0, 31], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 31 } + } + }, + + 'for (var x = 42 in list) process(x);': { + type: 'ForInStatement', + left: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + init: { + type: 'Literal', + value: 42, + raw: '42', + range: [13, 15], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 15 } + } + }, + range: [9, 15], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 15 } + } + }], + kind: 'var', + range: [5, 15], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 15 } + } + }, + right: { + type: 'Identifier', + name: 'list', + range: [19, 23], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 23 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'process', + range: [25, 32], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 32 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'x', + range: [33, 34], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 34 } + } + }], + range: [25, 35], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 35 } + } + }, + range: [25, 36], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 36 } + } + }, + each: false, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + + 'for (let x in list) process(x);': { + type: 'ForInStatement', + left: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + init: null, + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }], + kind: 'let', + range: [5, 10], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 10 } + } + }, + right: { + type: 'Identifier', + name: 'list', + range: [14, 18], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 18 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'process', + range: [20, 27], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 27 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'x', + range: [28, 29], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 29 } + } + }], + range: [20, 30], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 30 } + } + }, + range: [20, 31], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 31 } + } + }, + each: false, + range: [0, 31], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 31 } + } + }, + + 'for (let x = 42 in list) process(x);': { + type: 'ForInStatement', + left: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + init: { + type: 'Literal', + value: 42, + raw: '42', + range: [13, 15], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 15 } + } + }, + range: [9, 15], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 15 } + } + }], + kind: 'let', + range: [5, 15], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 15 } + } + }, + right: { + type: 'Identifier', + name: 'list', + range: [19, 23], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 23 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'process', + range: [25, 32], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 32 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'x', + range: [33, 34], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 34 } + } + }], + range: [25, 35], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 35 } + } + }, + range: [25, 36], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 36 } + } + }, + each: false, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + + 'for (var i = function() { return 10 in [] } in list) process(x);': { + type: 'ForInStatement', + left: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'i', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + init: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ReturnStatement', + argument: { + type: 'BinaryExpression', + operator: 'in', + left: { + type: 'Literal', + value: 10, + raw: '10', + range: [33, 35], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 35 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [39, 41], + loc: { + start: { line: 1, column: 39 }, + end: { line: 1, column: 41 } + } + }, + range: [33, 41], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 41 } + } + }, + range: [26, 42], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 42 } + } + }], + range: [24, 43], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 43 } + } + }, + rest: null, + generator: false, + expression: false, + range: [13, 43], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 43 } + } + }, + range: [9, 43], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 43 } + } + }], + kind: 'var', + range: [5, 43], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 43 } + } + }, + right: { + type: 'Identifier', + name: 'list', + range: [47, 51], + loc: { + start: { line: 1, column: 47 }, + end: { line: 1, column: 51 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'process', + range: [53, 60], + loc: { + start: { line: 1, column: 53 }, + end: { line: 1, column: 60 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'x', + range: [61, 62], + loc: { + start: { line: 1, column: 61 }, + end: { line: 1, column: 62 } + } + }], + range: [53, 63], + loc: { + start: { line: 1, column: 53 }, + end: { line: 1, column: 63 } + } + }, + range: [53, 64], + loc: { + start: { line: 1, column: 53 }, + end: { line: 1, column: 64 } + } + }, + each: false, + range: [0, 64], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 64 } + } + } + + }, + + 'continue statement': { + + 'while (true) { continue; }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [ + { + type: 'ContinueStatement', + label: null, + range: [15, 24], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 24 } + } + } + ], + range: [13, 26], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 26 } + } + }, + range: [0, 26], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 26 } + } + }, + + 'while (true) { continue }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [ + { + type: 'ContinueStatement', + label: null, + range: [15, 24], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 24 } + } + } + ], + range: [13, 25], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 25 } + } + }, + range: [0, 25], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 25 } + } + }, + + 'done: while (true) { continue done }': { + type: 'LabeledStatement', + label: { + type: 'Identifier', + name: 'done', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + body: { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [13, 17], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 17 } + } + }, + body: { + type: 'BlockStatement', + body: [ + { + type: 'ContinueStatement', + label: { + type: 'Identifier', + name: 'done', + range: [30, 34], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 34 } + } + }, + range: [21, 35], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 35 } + } + } + ], + range: [19, 36], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 36 } + } + }, + range: [6, 36], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 36 } + } + }, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + + 'done: while (true) { continue done; }': { + type: 'LabeledStatement', + label: { + type: 'Identifier', + name: 'done', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + body: { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [13, 17], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 17 } + } + }, + body: { + type: 'BlockStatement', + body: [ + { + type: 'ContinueStatement', + label: { + type: 'Identifier', + name: 'done', + range: [30, 34], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 34 } + } + }, + range: [21, 35], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 35 } + } + } + ], + range: [19, 37], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 37 } + } + }, + range: [6, 37], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 37 } + } + }, + range: [0, 37], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 37 } + } + } + + }, + + 'break statement': { + + 'while (true) { break }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [ + { + type: 'BreakStatement', + label: null, + range: [15, 21], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 21 } + } + } + ], + range: [13, 22], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }, + + 'done: while (true) { break done }': { + type: 'LabeledStatement', + label: { + type: 'Identifier', + name: 'done', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + body: { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [13, 17], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 17 } + } + }, + body: { + type: 'BlockStatement', + body: [ + { + type: 'BreakStatement', + label: { + type: 'Identifier', + name: 'done', + range: [27, 31], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 31 } + } + }, + range: [21, 32], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 32 } + } + } + ], + range: [19, 33], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 33 } + } + }, + range: [6, 33], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 33 } + } + }, + range: [0, 33], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 33 } + } + }, + + 'done: while (true) { break done; }': { + type: 'LabeledStatement', + label: { + type: 'Identifier', + name: 'done', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + body: { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [13, 17], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 17 } + } + }, + body: { + type: 'BlockStatement', + body: [ + { + type: 'BreakStatement', + label: { + type: 'Identifier', + name: 'done', + range: [27, 31], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 31 } + } + }, + range: [21, 32], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 32 } + } + } + ], + range: [19, 34], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 34 } + } + }, + range: [6, 34], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 34 } + } + }, + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + } + } + + }, + + 'return statement': { + + '(function(){ return })': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: null, + range: [13, 20], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 20 } + } + } + ], + range: [11, 21], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 21 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 21], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }, + + '(function(){ return; })': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: null, + range: [13, 20], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 20 } + } + } + ], + range: [11, 22], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 22 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 22], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 23], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 23 } + } + }, + + '(function(){ return x; })': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: { + type: 'Identifier', + name: 'x', + range: [20, 21], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 21 } + } + }, + range: [13, 22], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 22 } + } + } + ], + range: [11, 24], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 24 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 24], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 24 } + } + }, + range: [0, 25], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 25 } + } + }, + + '(function(){ return x * y })': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'Identifier', + name: 'x', + range: [20, 21], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 21 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [24, 25], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 25 } + } + }, + range: [20, 25], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 25 } + } + }, + range: [13, 26], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 26 } + } + } + ], + range: [11, 27], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 27 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 27], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 27 } + } + }, + range: [0, 28], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 28 } + } + } + }, + + 'with statement': { + + 'with (x) foo = bar': { + type: 'WithStatement', + object: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'foo', + range: [9, 12], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 12 } + } + }, + right: { + type: 'Identifier', + name: 'bar', + range: [15, 18], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 18 } + } + }, + range: [9, 18], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 18 } + } + }, + range: [9, 18], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 18 } + } + }, + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + } + }, + + 'with (x) foo = bar;': { + type: 'WithStatement', + object: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'foo', + range: [9, 12], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 12 } + } + }, + right: { + type: 'Identifier', + name: 'bar', + range: [15, 18], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 18 } + } + }, + range: [9, 18], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 18 } + } + }, + range: [9, 19], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 19 } + } + }, + range: [0, 19], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 19 } + } + }, + + 'with (x) { foo = bar }': { + type: 'WithStatement', + object: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'foo', + range: [11, 14], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 14 } + } + }, + right: { + type: 'Identifier', + name: 'bar', + range: [17, 20], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 20 } + } + }, + range: [11, 20], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 20 } + } + }, + range: [11, 21], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 21 } + } + }], + range: [9, 22], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + } + + }, + + 'switch statement': { + + 'switch (x) {}': { + type: 'SwitchStatement', + discriminant: { + type: 'Identifier', + name: 'x', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + cases:[], + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + + 'switch (answer) { case 42: hi(); break; }': { + type: 'SwitchStatement', + discriminant: { + type: 'Identifier', + name: 'answer', + range: [8, 14], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 14 } + } + }, + cases: [{ + type: 'SwitchCase', + test: { + type: 'Literal', + value: 42, + raw: '42', + range: [23, 25], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 25 } + } + }, + consequent: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hi', + range: [27, 29], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 29 } + } + }, + 'arguments': [], + range: [27, 31], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 31 } + } + }, + range: [27, 32], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 32 } + } + }, { + type: 'BreakStatement', + label: null, + range: [33, 39], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 39 } + } + }], + range: [18, 39], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 39 } + } + }], + range: [0, 41], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 41 } + } + }, + + 'switch (answer) { case 42: hi(); break; default: break }': { + type: 'SwitchStatement', + discriminant: { + type: 'Identifier', + name: 'answer', + range: [8, 14], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 14 } + } + }, + cases: [{ + type: 'SwitchCase', + test: { + type: 'Literal', + value: 42, + raw: '42', + range: [23, 25], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 25 } + } + }, + consequent: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hi', + range: [27, 29], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 29 } + } + }, + 'arguments': [], + range: [27, 31], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 31 } + } + }, + range: [27, 32], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 32 } + } + }, { + type: 'BreakStatement', + label: null, + range: [33, 39], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 39 } + } + }], + range: [18, 39], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 39 } + } + }, { + type: 'SwitchCase', + test: null, + consequent: [{ + type: 'BreakStatement', + label: null, + range: [49, 55], + loc: { + start: { line: 1, column: 49 }, + end: { line: 1, column: 55 } + } + }], + range: [40, 55], + loc: { + start: { line: 1, column: 40 }, + end: { line: 1, column: 55 } + } + }], + range: [0, 56], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 56 } + } + } + + }, + + 'Labelled Statements': { + + 'start: for (;;) break start': { + type: 'LabeledStatement', + label: { + type: 'Identifier', + name: 'start', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + body: { + type: 'ForStatement', + init: null, + test: null, + update: null, + body: { + type: 'BreakStatement', + label: { + type: 'Identifier', + name: 'start', + range: [22, 27], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 27 } + } + }, + range: [16, 27], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 27 } + } + }, + range: [7, 27], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 27 } + } + }, + range: [0, 27], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 27 } + } + }, + + 'start: while (true) break start': { + type: 'LabeledStatement', + label: { + type: 'Identifier', + name: 'start', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + body: { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [14, 18], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 18 } + } + }, + body: { + type: 'BreakStatement', + label: { + type: 'Identifier', + name: 'start', + range: [26, 31], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 31 } + } + }, + range: [20, 31], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 31 } + } + }, + range: [7, 31], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 31 } + } + }, + range: [0, 31], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 31 } + } + } + + }, + + 'throw statement': { + + 'throw x;': { + type: 'ThrowStatement', + argument: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + + 'throw x * y': { + type: 'ThrowStatement', + argument: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [10, 11], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 11 } + } + }, + range: [6, 11], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'throw { message: "Error" }': { + type: 'ThrowStatement', + argument: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'message', + range: [8, 15], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 15 } + } + }, + value: { + type: 'Literal', + value: 'Error', + raw: '"Error"', + range: [17, 24], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 24 } + } + }, + kind: 'init', + range: [8, 24], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 24 } + } + }], + range: [6, 26], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 26 } + } + }, + range: [0, 26], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 26 } + } + } + + }, + + 'try statement': { + + 'try { } catch (e) { }': { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [], + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + guardedHandlers: [], + handlers: [{ + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'e', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }, + body: { + type: 'BlockStatement', + body: [], + range: [18, 21], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 21 } + } + }, + range: [8, 21], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 21 } + } + }], + finalizer: null, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + + 'try { } catch (eval) { }': { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [], + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + guardedHandlers: [], + handlers: [{ + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'eval', + range: [15, 19], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 19 } + } + }, + body: { + type: 'BlockStatement', + body: [], + range: [21, 24], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 24 } + } + }, + range: [8, 24], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 24 } + } + }], + finalizer: null, + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + } + }, + + 'try { } catch (arguments) { }': { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [], + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + guardedHandlers: [], + handlers: [{ + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'arguments', + range: [15, 24], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 24 } + } + }, + body: { + type: 'BlockStatement', + body: [], + range: [26, 29], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 29 } + } + }, + range: [8, 29], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 29 } + } + }], + finalizer: null, + range: [0, 29], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 29 } + } + }, + + 'try { } catch (e) { say(e) }': { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [], + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + guardedHandlers: [], + handlers: [{ + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'e', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'say', + range: [20, 23], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 23 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'e', + range: [24, 25], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 25 } + } + }], + range: [20, 26], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 26 } + } + }, + range: [20, 27], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 27 } + } + }], + range: [18, 28], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 28 } + } + }, + range: [8, 28], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 28 } + } + }], + finalizer: null, + range: [0, 28], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 28 } + } + }, + + 'try { } finally { cleanup(stuff) }': { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [], + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + guardedHandlers: [], + handlers: [], + finalizer: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'cleanup', + range: [18, 25], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 25 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'stuff', + range: [26, 31], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 31 } + } + }], + range: [18, 32], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 32 } + } + }, + range: [18, 33], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 33 } + } + }], + range: [16, 34], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 34 } + } + }, + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + } + }, + + 'try { doThat(); } catch (e) { say(e) }': { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'doThat', + range: [6, 12], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 12 } + } + }, + 'arguments': [], + range: [6, 14], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 14 } + } + }, + range: [6, 15], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 15 } + } + }], + range: [4, 17], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 17 } + } + }, + guardedHandlers: [], + handlers: [{ + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'e', + range: [25, 26], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 26 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'say', + range: [30, 33], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 33 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'e', + range: [34, 35], + loc: { + start: { line: 1, column: 34 }, + end: { line: 1, column: 35 } + } + }], + range: [30, 36], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 36 } + } + }, + range: [30, 37], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 37 } + } + }], + range: [28, 38], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 38 } + } + }, + range: [18, 38], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 38 } + } + }], + finalizer: null, + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + } + }, + + 'try { doThat(); } catch (e) { say(e) } finally { cleanup(stuff) }': { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'doThat', + range: [6, 12], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 12 } + } + }, + 'arguments': [], + range: [6, 14], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 14 } + } + }, + range: [6, 15], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 15 } + } + }], + range: [4, 17], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 17 } + } + }, + guardedHandlers: [], + handlers: [{ + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'e', + range: [25, 26], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 26 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'say', + range: [30, 33], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 33 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'e', + range: [34, 35], + loc: { + start: { line: 1, column: 34 }, + end: { line: 1, column: 35 } + } + }], + range: [30, 36], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 36 } + } + }, + range: [30, 37], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 37 } + } + }], + range: [28, 38], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 38 } + } + }, + range: [18, 38], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 38 } + } + }], + finalizer: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'cleanup', + range: [49, 56], + loc: { + start: { line: 1, column: 49 }, + end: { line: 1, column: 56 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'stuff', + range: [57, 62], + loc: { + start: { line: 1, column: 57 }, + end: { line: 1, column: 62 } + } + }], + range: [49, 63], + loc: { + start: { line: 1, column: 49 }, + end: { line: 1, column: 63 } + } + }, + range: [49, 64], + loc: { + start: { line: 1, column: 49 }, + end: { line: 1, column: 64 } + } + }], + range: [47, 65], + loc: { + start: { line: 1, column: 47 }, + end: { line: 1, column: 65 } + } + }, + range: [0, 65], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 65 } + } + } + + }, + + 'debugger statement': { + + 'debugger;': { + type: 'DebuggerStatement', + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + } + + }, + + 'Function Definition': { + + 'function hello() { sayHi(); }': { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'hello', + range: [9, 14], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 14 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'sayHi', + range: [19, 24], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 24 } + } + }, + 'arguments': [], + range: [19, 26], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 26 } + } + }, + range: [19, 27], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 27 } + } + }], + range: [17, 29], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 29 } + } + }, + rest: null, + generator: false, + expression: false, + range: [0, 29], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 29 } + } + }, + + 'function eval() { }': { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'eval', + range: [9, 13], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 13 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [16, 19], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 19 } + } + }, + rest: null, + generator: false, + expression: false, + range: [0, 19], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 19 } + } + }, + + 'function arguments() { }': { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'arguments', + range: [9, 18], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 18 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [21, 24], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 24 } + } + }, + rest: null, + generator: false, + expression: false, + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + } + }, + + 'function test(t, t) { }': { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'test', + range: [9, 13], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 13 } + } + }, + params: [{ + type: 'Identifier', + name: 't', + range: [14, 15], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 15 } + } + }, { + type: 'Identifier', + name: 't', + range: [17, 18], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 18 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [20, 23], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 23 } + } + }, + rest: null, + generator: false, + expression: false, + range: [0, 23], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 23 } + } + }, + + '(function test(t, t) { })': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'test', + range: [10, 14], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 14 } + } + }, + params: [{ + type: 'Identifier', + name: 't', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }, { + type: 'Identifier', + name: 't', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [21, 24], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 24 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 24], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 24 } + } + }, + range: [0, 25], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 25 } + } + }, + + 'function eval() { function inner() { "use strict" } }': { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'eval', + range: [9, 13], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 13 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'inner', + range: [27, 32], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 32 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '\"use strict\"', + range: [37, 49], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 49 } + } + }, + range: [37, 50], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 50 } + } + }], + range: [35, 51], + loc: { + start: { line: 1, column: 35 }, + end: { line: 1, column: 51 } + } + }, + rest: null, + generator: false, + expression: false, + range: [18, 51], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 51 } + } + }], + range: [16, 53], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 53 } + } + }, + rest: null, + generator: false, + expression: false, + range: [0, 53], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 53 } + } + }, + + 'function hello(a) { sayHi(); }': { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'hello', + range: [9, 14], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 14 } + } + }, + params: [{ + type: 'Identifier', + name: 'a', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'sayHi', + range: [20, 25], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 25 } + } + }, + 'arguments': [], + range: [20, 27], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 27 } + } + }, + range: [20, 28], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 28 } + } + }], + range: [18, 30], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 30 } + } + }, + rest: null, + generator: false, + expression: false, + range: [0, 30], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 30 } + } + }, + + 'function hello(a, b) { sayHi(); }': { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'hello', + range: [9, 14], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 14 } + } + }, + params: [{ + type: 'Identifier', + name: 'a', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }, { + type: 'Identifier', + name: 'b', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'sayHi', + range: [23, 28], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 28 } + } + }, + 'arguments': [], + range: [23, 30], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 30 } + } + }, + range: [23, 31], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 31 } + } + }], + range: [21, 33], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 33 } + } + }, + rest: null, + generator: false, + expression: false, + range: [0, 33], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 33 } + } + }, + + 'var hi = function() { sayHi() };': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'hi', + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + } + }, + init: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'sayHi', + range: [22, 27], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 27 } + } + }, + 'arguments': [], + range: [22, 29], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 29 } + } + }, + range: [22, 30], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 30 } + } + }], + range: [20, 31], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 31 } + } + }, + rest: null, + generator: false, + expression: false, + range: [9, 31], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 31 } + } + }, + range: [4, 31], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 31 } + } + }], + kind: 'var', + range: [0, 32], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 32 } + } + }, + + 'var hi = function eval() { };': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'hi', + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + } + }, + init: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'eval', + range: [18, 22], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 22 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [25, 28], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 28 } + } + }, + rest: null, + generator: false, + expression: false, + range: [9, 28], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 28 } + } + }, + range: [4, 28], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 28 } + } + }], + kind: 'var', + range: [0, 29], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 29 } + } + }, + + 'var hi = function arguments() { };': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'hi', + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + } + }, + init: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'arguments', + range: [18, 27], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 27 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [30, 33], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 33 } + } + }, + rest: null, + generator: false, + expression: false, + range: [9, 33], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 33 } + } + }, + range: [4, 33], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 33 } + } + }], + kind: 'var', + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + } + }, + + 'var hello = function hi() { sayHi() };': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'hello', + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + init: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'hi', + range: [21, 23], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 23 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'sayHi', + range: [28, 33], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 33 } + } + }, + 'arguments': [], + range: [28, 35], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 35 } + } + }, + range: [28, 36], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 36 } + } + }], + range: [26, 37], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 37 } + } + }, + rest: null, + generator: false, + expression: false, + range: [12, 37], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 37 } + } + }, + range: [4, 37], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 37 } + } + }], + kind: 'var', + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + } + }, + + '(function(){})': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [11, 13], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 13 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 13], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + } + + }, + + 'Automatic semicolon insertion': { + + '{ x\n++y }': { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'x', + range: [2, 3], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 3 } + } + }, + range: [2, 4], + loc: { + start: { line: 1, column: 2 }, + end: { line: 2, column: 0 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'y', + range: [6, 7], + loc: { + start: { line: 2, column: 2 }, + end: { line: 2, column: 3 } + } + }, + prefix: true, + range: [4, 7], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 3 } + } + }, + range: [4, 8], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 4 } + } + }], + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 5 } + } + }, + + '{ x\n--y }': { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'x', + range: [2, 3], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 3 } + } + }, + range: [2, 4], + loc: { + start: { line: 1, column: 2 }, + end: { line: 2, column: 0 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'y', + range: [6, 7], + loc: { + start: { line: 2, column: 2 }, + end: { line: 2, column: 3 } + } + }, + prefix: true, + range: [4, 7], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 3 } + } + }, + range: [4, 8], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 4 } + } + }], + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 5 } + } + }, + + 'var x /* comment */;': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: null, + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }], + kind: 'var', + range: [0, 20], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 20 } + } + }, + + '{ var x = 14, y = 3\nz; }': { + type: 'BlockStatement', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + init: { + type: 'Literal', + value: 14, + raw: '14', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + range: [6, 12], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 12 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'y', + range: [14, 15], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 15 } + } + }, + init: { + type: 'Literal', + value: 3, + raw: '3', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }, + range: [14, 19], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 19 } + } + }], + kind: 'var', + range: [2, 20], + loc: { + start: { line: 1, column: 2 }, + end: { line: 2, column: 0 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'z', + range: [20, 21], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 1 } + } + }, + range: [20, 22], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + }], + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 4 } + } + }, + + 'while (true) { continue\nthere; }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'ContinueStatement', + label: null, + range: [15, 23], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 23 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'there', + range: [24, 29], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 5 } + } + }, + range: [24, 30], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 6 } + } + }], + range: [13, 32], + loc: { + start: { line: 1, column: 13 }, + end: { line: 2, column: 8 } + } + }, + range: [0, 32], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 8 } + } + }, + + 'while (true) { continue // Comment\nthere; }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'ContinueStatement', + label: null, + range: [15, 23], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 23 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'there', + range: [35, 40], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 5 } + } + }, + range: [35, 41], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 6 } + } + }], + range: [13, 43], + loc: { + start: { line: 1, column: 13 }, + end: { line: 2, column: 8 } + } + }, + range: [0, 43], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 8 } + } + }, + + 'while (true) { continue /* Multiline\nComment */there; }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'ContinueStatement', + label: null, + range: [15, 23], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 23 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'there', + range: [47, 52], + loc: { + start: { line: 2, column: 10 }, + end: { line: 2, column: 15 } + } + }, + range: [47, 53], + loc: { + start: { line: 2, column: 10 }, + end: { line: 2, column: 16 } + } + }], + range: [13, 55], + loc: { + start: { line: 1, column: 13 }, + end: { line: 2, column: 18 } + } + }, + range: [0, 55], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 18 } + } + }, + + 'while (true) { break\nthere; }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'BreakStatement', + label: null, + range: [15, 20], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 20 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'there', + range: [21, 26], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 5 } + } + }, + range: [21, 27], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 6 } + } + }], + range: [13, 29], + loc: { + start: { line: 1, column: 13 }, + end: { line: 2, column: 8 } + } + }, + range: [0, 29], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 8 } + } + }, + + 'while (true) { break // Comment\nthere; }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'BreakStatement', + label: null, + range: [15, 20], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 20 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'there', + range: [32, 37], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 5 } + } + }, + range: [32, 38], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 6 } + } + }], + range: [13, 40], + loc: { + start: { line: 1, column: 13 }, + end: { line: 2, column: 8 } + } + }, + range: [0, 40], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 8 } + } + }, + + 'while (true) { break /* Multiline\nComment */there; }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'BreakStatement', + label: null, + range: [15, 20], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 20 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'there', + range: [44, 49], + loc: { + start: { line: 2, column: 10 }, + end: { line: 2, column: 15 } + } + }, + range: [44, 50], + loc: { + start: { line: 2, column: 10 }, + end: { line: 2, column: 16 } + } + }], + range: [13, 52], + loc: { + start: { line: 1, column: 13 }, + end: { line: 2, column: 18 } + } + }, + range: [0, 52], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 18 } + } + }, + + '(function(){ return\nx; })': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: null, + range: [13, 19], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 19 } + } + }, + { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'x', + range: [20, 21], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 1 } + } + }, + range: [20, 22], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + } + ], + range: [11, 24], + loc: { + start: { line: 1, column: 11 }, + end: { line: 2, column: 4 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 24], + loc: { + start: { line: 1, column: 1 }, + end: { line: 2, column: 4 } + } + }, + range: [0, 25], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 5 } + } + }, + + '(function(){ return // Comment\nx; })': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: null, + range: [13, 19], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 19 } + } + }, + { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'x', + range: [31, 32], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 1 } + } + }, + range: [31, 33], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + } + ], + range: [11, 35], + loc: { + start: { line: 1, column: 11 }, + end: { line: 2, column: 4 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 35], + loc: { + start: { line: 1, column: 1 }, + end: { line: 2, column: 4 } + } + }, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 5 } + } + }, + + '(function(){ return/* Multiline\nComment */x; })': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: null, + range: [13, 19], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 19 } + } + }, + { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'x', + range: [42, 43], + loc: { + start: { line: 2, column: 10 }, + end: { line: 2, column: 11 } + } + }, + range: [42, 44], + loc: { + start: { line: 2, column: 10 }, + end: { line: 2, column: 12 } + } + } + ], + range: [11, 46], + loc: { + start: { line: 1, column: 11 }, + end: { line: 2, column: 14 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 46], + loc: { + start: { line: 1, column: 1 }, + end: { line: 2, column: 14 } + } + }, + range: [0, 47], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 15 } + } + }, + + '{ throw error\nerror; }': { + type: 'BlockStatement', + body: [{ + type: 'ThrowStatement', + argument: { + type: 'Identifier', + name: 'error', + range: [8, 13], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 13 } + } + }, + range: [2, 14], + loc: { + start: { line: 1, column: 2 }, + end: { line: 2, column: 0 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'error', + range: [14, 19], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 5 } + } + }, + range: [14, 20], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 6 } + } + }], + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 8 } + } + }, + + '{ throw error// Comment\nerror; }': { + type: 'BlockStatement', + body: [{ + type: 'ThrowStatement', + argument: { + type: 'Identifier', + name: 'error', + range: [8, 13], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 13 } + } + }, + range: [2, 24], + loc: { + start: { line: 1, column: 2 }, + end: { line: 2, column: 0 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'error', + range: [24, 29], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 5 } + } + }, + range: [24, 30], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 6 } + } + }], + range: [0, 32], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 8 } + } + }, + + '{ throw error/* Multiline\nComment */error; }': { + type: 'BlockStatement', + body: [{ + type: 'ThrowStatement', + argument: { + type: 'Identifier', + name: 'error', + range: [8, 13], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 13 } + } + }, + range: [2, 36], + loc: { + start: { line: 1, column: 2 }, + end: { line: 2, column: 10 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'error', + range: [36, 41], + loc: { + start: { line: 2, column: 10 }, + end: { line: 2, column: 15 } + } + }, + range: [36, 42], + loc: { + start: { line: 2, column: 10 }, + end: { line: 2, column: 16 } + } + }], + range: [0, 44], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 18 } + } + } + + }, + + 'Source elements': { + + '': { + type: 'Program', + body: [], + range: [0, 0], + loc: { + start: { line: 0, column: 0 }, + end: { line: 0, column: 0 } + }, + tokens: [] + } + }, + + 'Invalid syntax': { + + '{': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected end of input' + }, + + '}': { + index: 0, + lineNumber: 1, + column: 1, + message: 'Error: Line 1: Unexpected token }' + }, + + '3ea': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '3in []': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '3e': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '3e+': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '3e-': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '3x': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '3x0': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '0x': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '09': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '018': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '01a': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '3in[]': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '0x3in[]': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '"Hello\nWorld"': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + 'x\\': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + 'x\\u005c': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + 'x\\u002a': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + 'var x = /(s/g': { + index: 13, + lineNumber: 1, + column: 14, + message: 'Error: Line 1: Invalid regular expression' + }, + + '/': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Invalid regular expression: missing /' + }, + + '/test': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Invalid regular expression: missing /' + }, + + 'var x = /[a-z]/\\ux': { + index: 18, + lineNumber: 1, + column: 19, + message: 'Error: Line 1: Invalid regular expression' + }, + + '3 = 4': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + 'func() = 4': { + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + '(1 + 1) = 10': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + '1++': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + '1--': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + '++1': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + '--1': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + 'for((1 + 1) in list) process(x);': { + index: 11, + lineNumber: 1, + column: 12, + message: 'Error: Line 1: Invalid left-hand side in for-in' + }, + + '[': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected end of input' + }, + + '[,': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected end of input' + }, + + '1 + {': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Unexpected end of input' + }, + + '1 + { t:t ': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Unexpected end of input' + }, + + '1 + { t:t,': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'var x = /\n/': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Invalid regular expression: missing /' + }, + + 'var x = "\n': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + 'var if = 42': { + index: 4, + lineNumber: 1, + column: 5, + message: 'Error: Line 1: Unexpected token if' + }, + + 'i + 2 = 42': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + '+i = 42': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + '1 + (': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Unexpected end of input' + }, + + '\n\n\n{': { + index: 4, + lineNumber: 4, + column: 2, + message: 'Error: Line 4: Unexpected end of input' + }, + + '\n/* Some multiline\ncomment */\n)': { + index: 30, + lineNumber: 4, + column: 1, + message: 'Error: Line 4: Unexpected token )' + }, + + '{ set 1 }': { + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Unexpected number' + }, + + '{ get 2 }': { + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Unexpected number' + }, + + '({ set: s(if) { } })': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Unexpected token if' + }, + + '({ set s(.) { } })': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token .' + }, + + '({ set s() { } })': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token )' + }, + + '({ set: s() { } })': { + index: 12, + lineNumber: 1, + column: 13, + message: 'Error: Line 1: Unexpected token {' + }, + + '({ set: s(a, b) { } })': { + index: 16, + lineNumber: 1, + column: 17, + message: 'Error: Line 1: Unexpected token {' + }, + + '({ get: g(d) { } })': { + index: 13, + lineNumber: 1, + column: 14, + message: 'Error: Line 1: Unexpected token {' + }, + + '({ get i() { }, i: 42 })': { + index: 21, + lineNumber: 1, + column: 22, + message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' + }, + + '({ i: 42, get i() { } })': { + index: 21, + lineNumber: 1, + column: 22, + message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' + }, + + '({ set i(x) { }, i: 42 })': { + index: 22, + lineNumber: 1, + column: 23, + message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' + }, + + '({ i: 42, set i(x) { } })': { + index: 22, + lineNumber: 1, + column: 23, + message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' + }, + + '({ get i() { }, get i() { } })': { + index: 27, + lineNumber: 1, + column: 28, + message: 'Error: Line 1: Object literal may not have multiple get/set accessors with the same name' + }, + + '({ set i(x) { }, set i(x) { } })': { + index: 29, + lineNumber: 1, + column: 30, + message: 'Error: Line 1: Object literal may not have multiple get/set accessors with the same name' + }, + + 'function t(if) { }': { + index: 11, + lineNumber: 1, + column: 12, + message: 'Error: Line 1: Unexpected token if' + }, + + 'function t(true) { }': { + index: 11, + lineNumber: 1, + column: 12, + message: 'Error: Line 1: Unexpected token true' + }, + + 'function t(false) { }': { + index: 11, + lineNumber: 1, + column: 12, + message: 'Error: Line 1: Unexpected token false' + }, + + 'function t(null) { }': { + index: 11, + lineNumber: 1, + column: 12, + message: 'Error: Line 1: Unexpected token null' + }, + + 'function null() { }': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token null' + }, + + 'function true() { }': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token true' + }, + + 'function false() { }': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token false' + }, + + 'function if() { }': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token if' + }, + + 'a b;': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected identifier' + }, + + 'if.a;': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token .' + }, + + 'a if;': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token if' + }, + + 'a class;': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected reserved word' + }, + + 'break\n': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Illegal break statement' + }, + + 'break 1;': { + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Unexpected number' + }, + + 'continue\n': { + index: 8, + lineNumber: 1, + column: 9, + message: 'Error: Line 1: Illegal continue statement' + }, + + 'continue 2;': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected number' + }, + + 'throw': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'throw;': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Unexpected token ;' + }, + + 'throw\n': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Illegal newline after throw' + }, + + 'for (var i, i2 in {});': { + index: 15, + lineNumber: 1, + column: 16, + message: 'Error: Line 1: Unexpected token in' + }, + + 'for ((i in {}));': { + index: 14, + lineNumber: 1, + column: 15, + message: 'Error: Line 1: Unexpected token )' + }, + + 'for (i + 1 in {});': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Invalid left-hand side in for-in' + }, + + 'for (+i in {});': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Invalid left-hand side in for-in' + }, + + 'if(false)': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'if(false) doThis(); else': { + index: 24, + lineNumber: 1, + column: 25, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'do': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'while(false)': { + index: 12, + lineNumber: 1, + column: 13, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'for(;;)': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'with(x)': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'try { }': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Missing catch or finally after try' + }, + + 'try {} catch (42) {} ': { + index: 14, + lineNumber: 1, + column: 15, + message: 'Error: Line 1: Unexpected number' + }, + + 'try {} catch (answer()) {} ': { + index: 20, + lineNumber: 1, + column: 21, + message: 'Error: Line 1: Unexpected token (' + }, + + 'try {} catch (-x) {} ': { + index: 14, + lineNumber: 1, + column: 15, + message: 'Error: Line 1: Unexpected token -' + }, + + + '\u203F = 10': { + index: 0, + lineNumber: 1, + column: 1, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + 'const x = 12, y;': { + index: 15, + lineNumber: 1, + column: 16, + message: 'Error: Line 1: Unexpected token ;' + }, + + 'const x, y = 12;': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Unexpected token ,' + }, + + 'const x;': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Unexpected token ;' + }, + + 'if(true) let a = 1;': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token let' + }, + + 'if(true) const a = 1;': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token const' + }, + + 'switch (c) { default: default: }': { + index: 30, + lineNumber: 1, + column: 31, + message: 'Error: Line 1: More than one default clause in switch statement' + }, + + 'new X()."s"': { + index: 8, + lineNumber: 1, + column: 9, + message: 'Error: Line 1: Unexpected string' + }, + + '/*': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '/*\n\n\n': { + index: 5, + lineNumber: 4, + column: 1, + message: 'Error: Line 4: Unexpected token ILLEGAL' + }, + + '/**': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '/*\n\n*': { + index: 5, + lineNumber: 3, + column: 2, + message: 'Error: Line 3: Unexpected token ILLEGAL' + }, + + '/*hello': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '/*hello *': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '\n]': { + index: 1, + lineNumber: 2, + column: 1, + message: 'Error: Line 2: Unexpected token ]' + }, + + '\r]': { + index: 1, + lineNumber: 2, + column: 1, + message: 'Error: Line 2: Unexpected token ]' + }, + + '\r\n]': { + index: 2, + lineNumber: 2, + column: 1, + message: 'Error: Line 2: Unexpected token ]' + }, + + '\n\r]': { + index: 2, + lineNumber: 3, + column: 1, + message: 'Error: Line 3: Unexpected token ]' + }, + + '//\r\n]': { + index: 4, + lineNumber: 2, + column: 1, + message: 'Error: Line 2: Unexpected token ]' + }, + + '//\n\r]': { + index: 4, + lineNumber: 3, + column: 1, + message: 'Error: Line 3: Unexpected token ]' + }, + + '/a\\\n/': { + index: 4, + lineNumber: 1, + column: 5, + message: 'Error: Line 1: Invalid regular expression: missing /' + }, + + '//\r \n]': { + index: 5, + lineNumber: 3, + column: 1, + message: 'Error: Line 3: Unexpected token ]' + }, + + '/*\r\n*/]': { + index: 6, + lineNumber: 2, + column: 3, + message: 'Error: Line 2: Unexpected token ]' + }, + + '/*\n\r*/]': { + index: 6, + lineNumber: 3, + column: 3, + message: 'Error: Line 3: Unexpected token ]' + }, + + '/*\r \n*/]': { + index: 7, + lineNumber: 3, + column: 3, + message: 'Error: Line 3: Unexpected token ]' + }, + + '\\\\': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '\\u005c': { + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + + '\\x': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '\\u0000': { + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '\u200C = []': { + index: 0, + lineNumber: 1, + column: 1, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '\u200D = []': { + index: 0, + lineNumber: 1, + column: 1, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '"\\': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '"\\u': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + 'try { } catch() {}': { + index: 14, + lineNumber: 1, + column: 15, + message: 'Error: Line 1: Unexpected token )' + }, + + 'return': { + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Illegal return statement' + }, + + 'break': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Illegal break statement' + }, + + 'continue': { + index: 8, + lineNumber: 1, + column: 9, + message: 'Error: Line 1: Illegal continue statement' + }, + + 'switch (x) { default: continue; }': { + index: 31, + lineNumber: 1, + column: 32, + message: 'Error: Line 1: Illegal continue statement' + }, + + 'do { x } *': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token *' + }, + + 'while (true) { break x; }': { + index: 22, + lineNumber: 1, + column: 23, + message: 'Error: Line 1: Undefined label \'x\'' + }, + + 'while (true) { continue x; }': { + index: 25, + lineNumber: 1, + column: 26, + message: 'Error: Line 1: Undefined label \'x\'' + }, + + 'x: while (true) { (function () { break x; }); }': { + index: 40, + lineNumber: 1, + column: 41, + message: 'Error: Line 1: Undefined label \'x\'' + }, + + 'x: while (true) { (function () { continue x; }); }': { + index: 43, + lineNumber: 1, + column: 44, + message: 'Error: Line 1: Undefined label \'x\'' + }, + + 'x: while (true) { (function () { break; }); }': { + index: 39, + lineNumber: 1, + column: 40, + message: 'Error: Line 1: Illegal break statement' + }, + + 'x: while (true) { (function () { continue; }); }': { + index: 42, + lineNumber: 1, + column: 43, + message: 'Error: Line 1: Illegal continue statement' + }, + + 'x: while (true) { x: while (true) { } }': { + index: 20, + lineNumber: 1, + column: 21, + message: 'Error: Line 1: Label \'x\' has already been declared' + }, + + '(function () { \'use strict\'; delete i; }())': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Delete of an unqualified identifier in strict mode.' + }, + + '(function () { \'use strict\'; with (i); }())': { + index: 28, + lineNumber: 1, + column: 29, + message: 'Error: Line 1: Strict mode code may not include a with statement' + }, + + 'function hello() {\'use strict\'; ({ i: 42, i: 42 }) }': { + index: 47, + lineNumber: 1, + column: 48, + message: 'Error: Line 1: Duplicate data property in object literal not allowed in strict mode' + }, + + 'function hello() {\'use strict\'; ({ hasOwnProperty: 42, hasOwnProperty: 42 }) }': { + index: 73, + lineNumber: 1, + column: 74, + message: 'Error: Line 1: Duplicate data property in object literal not allowed in strict mode' + }, + + 'function hello() {\'use strict\'; var eval = 10; }': { + index: 40, + lineNumber: 1, + column: 41, + message: 'Error: Line 1: Variable name may not be eval or arguments in strict mode' + }, + + 'function hello() {\'use strict\'; var arguments = 10; }': { + index: 45, + lineNumber: 1, + column: 46, + message: 'Error: Line 1: Variable name may not be eval or arguments in strict mode' + }, + + 'function hello() {\'use strict\'; try { } catch (eval) { } }': { + index: 51, + lineNumber: 1, + column: 52, + message: 'Error: Line 1: Catch variable may not be eval or arguments in strict mode' + }, + + 'function hello() {\'use strict\'; try { } catch (arguments) { } }': { + index: 56, + lineNumber: 1, + column: 57, + message: 'Error: Line 1: Catch variable may not be eval or arguments in strict mode' + }, + + 'function hello() {\'use strict\'; eval = 10; }': { + index: 32, + lineNumber: 1, + column: 33, + message: 'Error: Line 1: Assignment to eval or arguments is not allowed in strict mode' + }, + + 'function hello() {\'use strict\'; arguments = 10; }': { + index: 32, + lineNumber: 1, + column: 33, + message: 'Error: Line 1: Assignment to eval or arguments is not allowed in strict mode' + }, + + 'function hello() {\'use strict\'; ++eval; }': { + index: 38, + lineNumber: 1, + column: 39, + message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' + }, + + 'function hello() {\'use strict\'; --eval; }': { + index: 38, + lineNumber: 1, + column: 39, + message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' + }, + + 'function hello() {\'use strict\'; ++arguments; }': { + index: 43, + lineNumber: 1, + column: 44, + message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' + }, + + 'function hello() {\'use strict\'; --arguments; }': { + index: 43, + lineNumber: 1, + column: 44, + message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' + }, + + 'function hello() {\'use strict\'; eval++; }': { + index: 36, + lineNumber: 1, + column: 37, + message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' + }, + + 'function hello() {\'use strict\'; eval--; }': { + index: 36, + lineNumber: 1, + column: 37, + message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' + }, + + 'function hello() {\'use strict\'; arguments++; }': { + index: 41, + lineNumber: 1, + column: 42, + message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' + }, + + 'function hello() {\'use strict\'; arguments--; }': { + index: 41, + lineNumber: 1, + column: 42, + message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' + }, + + 'function hello() {\'use strict\'; function eval() { } }': { + index: 41, + lineNumber: 1, + column: 42, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + 'function hello() {\'use strict\'; function arguments() { } }': { + index: 41, + lineNumber: 1, + column: 42, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + 'function eval() {\'use strict\'; }': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + 'function arguments() {\'use strict\'; }': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + 'function hello() {\'use strict\'; (function eval() { }()) }': { + index: 42, + lineNumber: 1, + column: 43, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + 'function hello() {\'use strict\'; (function arguments() { }()) }': { + index: 42, + lineNumber: 1, + column: 43, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + '(function eval() {\'use strict\'; })()': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + '(function arguments() {\'use strict\'; })()': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + 'function hello() {\'use strict\'; ({ s: function eval() { } }); }': { + index: 47, + lineNumber: 1, + column: 48, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + '(function package() {\'use strict\'; })()': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() {\'use strict\'; ({ i: 10, set s(eval) { } }); }': { + index: 48, + lineNumber: 1, + column: 49, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + 'function hello() {\'use strict\'; ({ set s(eval) { } }); }': { + index: 41, + lineNumber: 1, + column: 42, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + 'function hello() {\'use strict\'; ({ s: function s(eval) { } }); }': { + index: 49, + lineNumber: 1, + column: 50, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + 'function hello(eval) {\'use strict\';}': { + index: 15, + lineNumber: 1, + column: 16, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + 'function hello(arguments) {\'use strict\';}': { + index: 15, + lineNumber: 1, + column: 16, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + 'function hello() { \'use strict\'; function inner(eval) {} }': { + index: 48, + lineNumber: 1, + column: 49, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + 'function hello() { \'use strict\'; function inner(arguments) {} }': { + index: 48, + lineNumber: 1, + column: 49, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + ' "\\1"; \'use strict\';': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }, + + 'function hello() { \'use strict\'; "\\1"; }': { + index: 33, + lineNumber: 1, + column: 34, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }, + + 'function hello() { \'use strict\'; 021; }': { + index: 33, + lineNumber: 1, + column: 34, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }, + + 'function hello() { \'use strict\'; ({ "\\1": 42 }); }': { + index: 36, + lineNumber: 1, + column: 37, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }, + + 'function hello() { \'use strict\'; ({ 021: 42 }); }': { + index: 36, + lineNumber: 1, + column: 37, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }, + + 'function hello() { "octal directive\\1"; "use strict"; }': { + index: 19, + lineNumber: 1, + column: 20, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }, + + 'function hello() { "octal directive\\1"; "octal directive\\2"; "use strict"; }': { + index: 19, + lineNumber: 1, + column: 20, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }, + + 'function hello() { "use strict"; function inner() { "octal directive\\1"; } }': { + index: 52, + lineNumber: 1, + column: 53, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }, + + 'function hello() { "use strict"; var implements; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() { "use strict"; var interface; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() { "use strict"; var package; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() { "use strict"; var private; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() { "use strict"; var protected; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() { "use strict"; var public; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() { "use strict"; var static; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() { "use strict"; var yield; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() { "use strict"; var let; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello(static) { "use strict"; }': { + index: 15, + lineNumber: 1, + column: 16, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function static() { "use strict"; }': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'var yield': { + index: 4, + lineNumber: 1, + column: 5, + message: 'Error: Line 1: Unexpected token yield' + }, + + 'var let': { + index: 4, + lineNumber: 1, + column: 5, + message: 'Error: Line 1: Unexpected token let' + }, + + '"use strict"; function static() { }': { + index: 23, + lineNumber: 1, + column: 24, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function a(t, t) { "use strict"; }': { + index: 14, + lineNumber: 1, + column: 15, + message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' + }, + + 'function a(eval) { "use strict"; }': { + index: 11, + lineNumber: 1, + column: 12, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + 'function a(package) { "use strict"; }': { + index: 11, + lineNumber: 1, + column: 12, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function a() { "use strict"; function b(t, t) { }; }': { + index: 43, + lineNumber: 1, + column: 44, + message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' + }, + + '(function a(t, t) { "use strict"; })': { + index: 15, + lineNumber: 1, + column: 16, + message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' + }, + + 'function a() { "use strict"; (function b(t, t) { }); }': { + index: 44, + lineNumber: 1, + column: 45, + message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' + }, + + '(function a(eval) { "use strict"; })': { + index: 12, + lineNumber: 1, + column: 13, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + '(function a(package) { "use strict"; })': { + index: 12, + lineNumber: 1, + column: 13, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'var': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'let': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'const': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Unexpected end of input' + } + + }, + + 'API': { + 'parse()': { + call: 'parse', + args: [], + result: { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'undefined' + } + }] + } + }, + + 'parse(null)': { + call: 'parse', + args: [null], + result: { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: null + } + }] + } + }, + + 'parse(42)': { + call: 'parse', + args: [42], + result: { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42 + } + }] + } + }, + + 'parse(true)': { + call: 'parse', + args: [true], + result: { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: true + } + }] + } + }, + + 'parse(undefined)': { + call: 'parse', + args: [void 0], + result: { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'undefined' + } + }] + } + }, + + 'parse(new String("test"))': { + call: 'parse', + args: [new String('test')], + result: { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'test' + } + }] + } + }, + + 'parse(new Number(42))': { + call: 'parse', + args: [new Number(42)], + result: { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42 + } + }] + } + }, + + 'parse(new Boolean(true))': { + call: 'parse', + args: [new Boolean(true)], + result: { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: true + } + }] + } + }, + + 'Syntax': { + property: 'Syntax', + result: { + AssignmentExpression: 'AssignmentExpression', + ArrayExpression: 'ArrayExpression', + BlockStatement: 'BlockStatement', + BinaryExpression: 'BinaryExpression', + BreakStatement: 'BreakStatement', + CallExpression: 'CallExpression', + CatchClause: 'CatchClause', + ConditionalExpression: 'ConditionalExpression', + ContinueStatement: 'ContinueStatement', + DoWhileStatement: 'DoWhileStatement', + DebuggerStatement: 'DebuggerStatement', + EmptyStatement: 'EmptyStatement', + ExpressionStatement: 'ExpressionStatement', + ForStatement: 'ForStatement', + ForInStatement: 'ForInStatement', + FunctionDeclaration: 'FunctionDeclaration', + FunctionExpression: 'FunctionExpression', + Identifier: 'Identifier', + IfStatement: 'IfStatement', + Literal: 'Literal', + LabeledStatement: 'LabeledStatement', + LogicalExpression: 'LogicalExpression', + MemberExpression: 'MemberExpression', + NewExpression: 'NewExpression', + ObjectExpression: 'ObjectExpression', + Program: 'Program', + Property: 'Property', + ReturnStatement: 'ReturnStatement', + SequenceExpression: 'SequenceExpression', + SwitchStatement: 'SwitchStatement', + SwitchCase: 'SwitchCase', + ThisExpression: 'ThisExpression', + ThrowStatement: 'ThrowStatement', + TryStatement: 'TryStatement', + UnaryExpression: 'UnaryExpression', + UpdateExpression: 'UpdateExpression', + VariableDeclaration: 'VariableDeclaration', + VariableDeclarator: 'VariableDeclarator', + WhileStatement: 'WhileStatement', + WithStatement: 'WithStatement' + } + } + + }, + + 'Tolerant parse': { + 'return': { + type: 'Program', + body: [{ + type: 'ReturnStatement', + 'argument': null, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }], + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + }, + errors: [{ + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Illegal return statement' + }] + }, + + '(function () { \'use strict\'; with (i); }())': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '\'use strict\'', + range: [15, 27], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 27 } + } + }, + range: [15, 28], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 28 } + } + }, { + type: 'WithStatement', + object: { + type: 'Identifier', + name: 'i', + range: [35, 36], + loc: { + start: { line: 1, column: 35 }, + end: { line: 1, column: 36 } + } + }, + body: { + type: 'EmptyStatement', + range: [37, 38], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 38 } + } + }, + range: [29, 38], + loc: { + start: { line: 1, column: 29 }, + end: { line: 1, column: 38 } + } + }], + range: [13, 40], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 40 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 40], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 40 } + } + }, + 'arguments': [], + range: [1, 42], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 42 } + } + }, + range: [0, 43], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 43 } + } + }], + range: [0, 43], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 43 } + }, + errors: [{ + index: 29, + lineNumber: 1, + column: 30, + message: 'Error: Line 1: Strict mode code may not include a with statement' + }] + }, + + '(function () { \'use strict\'; 021 }())': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '\'use strict\'', + range: [15, 27], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 27 } + } + }, + range: [15, 28], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 28 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 17, + raw: "021", + range: [29, 32], + loc: { + start: { line: 1, column: 29 }, + end: { line: 1, column: 32 } + } + }, + range: [29, 33], + loc: { + start: { line: 1, column: 29 }, + end: { line: 1, column: 33 } + } + }], + range: [13, 34], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 34 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 34], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 34 } + } + }, + 'arguments': [], + range: [1, 36], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 36 } + } + }, + range: [0, 37], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 37 } + } + }], + range: [0, 37], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 37 } + }, + errors: [{ + index: 29, + lineNumber: 1, + column: 30, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }] + }, + + '"use strict"; delete x': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UnaryExpression', + operator: 'delete', + argument: { + type: 'Identifier', + name: 'x', + range: [21, 22], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 22 } + } + }, + prefix: true, + range: [14, 22], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 22 } + } + }, + range: [14, 22], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 22 } + } + }], + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + }, + errors: [{ + index: 22, + lineNumber: 1, + column: 23, + message: 'Error: Line 1: Delete of an unqualified identifier in strict mode.' + }] + }, + + '"use strict"; try {} catch (eval) {}': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [], + range: [18, 20], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 20 } + } + }, + guardedHandlers: [], + handlers: [{ + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'eval', + range: [28, 32], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 32 } + } + }, + body: { + type: 'BlockStatement', + body: [], + range: [34, 36], + loc: { + start: { line: 1, column: 34 }, + end: { line: 1, column: 36 } + } + }, + range: [21, 36], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 36 } + } + }], + finalizer: null, + range: [14, 36], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 36 } + } + }], + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + }, + errors: [{ + index: 32, + lineNumber: 1, + column: 33, + message: 'Error: Line 1: Catch variable may not be eval or arguments in strict mode' + }] + }, + + '"use strict"; try {} catch (arguments) {}': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [], + range: [18, 20], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 20 } + } + }, + guardedHandlers: [], + handlers: [{ + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'arguments', + range: [28, 37], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 37 } + } + }, + body: { + type: 'BlockStatement', + body: [], + range: [39, 41], + loc: { + start: { line: 1, column: 39 }, + end: { line: 1, column: 41 } + } + }, + range: [21, 41], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 41 } + } + }], + finalizer: null, + range: [14, 41], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 41 } + } + }], + range: [0, 41], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 41 } + }, + errors: [{ + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Catch variable may not be eval or arguments in strict mode' + }] + }, + + '"use strict"; var eval;': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'eval', + range: [18, 22], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 22 } + } + }, + init: null, + range: [18, 22], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 22 } + } + }], + kind: 'var', + range: [14, 23], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 23 } + } + }], + range: [0, 23], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 23 } + }, + errors: [{ + index: 22, + lineNumber: 1, + column: 23, + message: 'Error: Line 1: Variable name may not be eval or arguments in strict mode' + }] + }, + + '"use strict"; var arguments;': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'arguments', + range: [18, 27], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 27 } + } + }, + init: null, + range: [18, 27], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 27 } + } + }], + kind: 'var', + range: [14, 28], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 28 } + } + }], + range: [0, 28], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 28 } + }, + errors: [{ + index: 27, + lineNumber: 1, + column: 28, + message: 'Error: Line 1: Variable name may not be eval or arguments in strict mode' + }] + }, + + '"use strict"; eval = 0;': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'eval', + range: [14, 18], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 18 } + } + }, + right: { + type: 'Literal', + value: 0, + raw: '0', + range: [21, 22], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 22 } + } + }, + range: [14, 22], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 22 } + } + }, + range: [14, 23], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 23 } + } + }], + range: [0, 23], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 23 } + }, + errors: [{ + index: 14, + lineNumber: 1, + column: 15, + message: 'Error: Line 1: Assignment to eval or arguments is not allowed in strict mode' + }] + }, + + '"use strict"; eval++;': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'eval', + range: [14, 18], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 18 } + } + }, + prefix: false, + range: [14, 20], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 20 } + } + }, + range: [14, 21], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 21 } + } + }], + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + }, + errors: [{ + index: 18, + lineNumber: 1, + column: 19, + message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' + }] + }, + + '"use strict"; --eval;': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'eval', + range: [16, 20], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 20 } + } + }, + prefix: true, + range: [14, 20], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 20 } + } + }, + range: [14, 21], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 21 } + } + }], + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + }, + errors: [{ + index: 20, + lineNumber: 1, + column: 21, + message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' + }] + }, + + '"use strict"; arguments = 0;': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'arguments', + range: [14, 23], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 23 } + } + }, + right: { + type: 'Literal', + value: 0, + raw: '0', + range: [26, 27], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 27 } + } + }, + range: [14, 27], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 27 } + } + }, + range: [14, 28], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 28 } + } + }], + range: [0, 28], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 28 } + }, + errors: [{ + index: 14, + lineNumber: 1, + column: 15, + message: 'Error: Line 1: Assignment to eval or arguments is not allowed in strict mode' + }] + }, + + '"use strict"; arguments--;': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'arguments', + range: [14, 23], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 23 } + } + }, + prefix: false, + range: [14, 25], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 25 } + } + }, + range: [14, 26], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 26 } + } + }], + range: [0, 26], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 26 } + }, + errors: [{ + index: 23, + lineNumber: 1, + column: 24, + message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' + }] + }, + + '"use strict"; ++arguments;': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'arguments', + range: [16, 25], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 25 } + } + }, + prefix: true, + range: [14, 25], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 25 } + } + }, + range: [14, 26], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 26 } + } + }], + range: [0, 26], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 26 } + }, + errors: [{ + index: 25, + lineNumber: 1, + column: 26, + message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' + }] + }, + + + '"use strict";x={y:1,y:1}': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [13, 14], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 14 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'y', + range: [16, 17], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 17 } + } + }, + value: { + type: 'Literal', + value: 1, + raw: '1', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }, + kind: 'init', + range: [16, 19], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 19 } + } + }, { + type: 'Property', + key: { + type: 'Identifier', + name: 'y', + range: [20, 21], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 21 } + } + }, + value: { + type: 'Literal', + value: 1, + raw: '1', + range: [22, 23], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 23 } + } + }, + kind: 'init', + range: [20, 23], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 23 } + } + }], + range: [15, 24], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 24 } + } + }, + range: [13, 24], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 24 } + } + }, + range: [13, 24], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 24 } + } + }], + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + }, + errors: [{ + index: 23, + lineNumber: 1, + column: 24, + message: 'Error: Line 1: Duplicate data property in object literal not allowed in strict mode' + }] + }, + + '"use strict"; function eval() {};': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'eval', + range: [23, 27], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 27 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [30, 32], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 32 } + } + }, + rest: null, + generator: false, + expression: false, + range: [14, 32], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 32 } + } + }, { + type: 'EmptyStatement', + range: [32, 33], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 33 } + } + }], + range: [0, 33], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 33 } + }, + errors: [{ + index: 23, + lineNumber: 1, + column: 24, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }] + }, + + '"use strict"; function arguments() {};': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'arguments', + range: [23, 32], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 32 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [35, 37], + loc: { + start: { line: 1, column: 35 }, + end: { line: 1, column: 37 } + } + }, + rest: null, + generator: false, + expression: false, + range: [14, 37], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 37 } + } + }, { + type: 'EmptyStatement', + range: [37, 38], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 38 } + } + }], + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + }, + errors: [{ + index: 23, + lineNumber: 1, + column: 24, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }] + }, + + '"use strict"; function interface() {};': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'interface', + range: [23, 32], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 32 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [35, 37], + loc: { + start: { line: 1, column: 35 }, + end: { line: 1, column: 37 } + } + }, + rest: null, + generator: false, + expression: false, + range: [14, 37], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 37 } + } + }, { + type: 'EmptyStatement', + range: [37, 38], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 38 } + } + }], + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + }, + errors: [{ + index: 23, + lineNumber: 1, + column: 24, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }] + }, + + '"use strict"; (function eval() {});': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'eval', + range: [24, 28], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 28 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [31, 33], + loc: { + start: { line: 1, column: 31 }, + end: { line: 1, column: 33 } + } + }, + rest: null, + generator: false, + expression: false, + range: [15, 33], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 33 } + } + }, + range: [14, 35], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 35 } + } + }], + range: [0, 35], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 35 } + }, + errors: [{ + index: 24, + lineNumber: 1, + column: 25, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }] + }, + + '"use strict"; (function arguments() {});': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'arguments', + range: [24, 33], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 33 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [36, 38], + loc: { + start: { line: 1, column: 36 }, + end: { line: 1, column: 38 } + } + }, + rest: null, + generator: false, + expression: false, + range: [15, 38], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 38 } + } + }, + range: [14, 40], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 40 } + } + }], + range: [0, 40], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 40 } + }, + errors: [{ + index: 24, + lineNumber: 1, + column: 25, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }] + }, + + '"use strict"; (function interface() {});': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'interface', + range: [24, 33], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 33 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [36, 38], + loc: { + start: { line: 1, column: 36 }, + end: { line: 1, column: 38 } + } + }, + rest: null, + generator: false, + expression: false, + range: [15, 38], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 38 } + } + }, + range: [14, 40], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 40 } + } + }], + range: [0, 40], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 40 } + }, + errors: [{ + index: 24, + lineNumber: 1, + column: 25, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }] + }, + + '"use strict"; function f(eval) {};': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'f', + range: [23, 24], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 24 } + } + }, + params: [{ + type: 'Identifier', + name: 'eval', + range: [25, 29], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 29 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [31, 33], + loc: { + start: { line: 1, column: 31 }, + end: { line: 1, column: 33 } + } + }, + rest: null, + generator: false, + expression: false, + range: [14, 33], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 33 } + } + }, { + type: 'EmptyStatement', + range: [33, 34], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 34 } + } + }], + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + }, + errors: [{ + index: 25, + lineNumber: 1, + column: 26, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }] + }, + + '"use strict"; function f(arguments) {};': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'f', + range: [23, 24], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 24 } + } + }, + params: [{ + type: 'Identifier', + name: 'arguments', + range: [25, 34], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 34 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [36, 38], + loc: { + start: { line: 1, column: 36 }, + end: { line: 1, column: 38 } + } + }, + rest: null, + generator: false, + expression: false, + range: [14, 38], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 38 } + } + }, { + type: 'EmptyStatement', + range: [38, 39], + loc: { + start: { line: 1, column: 38 }, + end: { line: 1, column: 39 } + } + }], + range: [0, 39], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 39 } + }, + errors: [{ + index: 25, + lineNumber: 1, + column: 26, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }] + }, + + '"use strict"; function f(foo, foo) {};': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'f', + range: [23, 24], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 24 } + } + }, + params: [{ + type: 'Identifier', + name: 'foo', + range: [25, 28], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 28 } + } + }, { + type: 'Identifier', + name: 'foo', + range: [31, 34], + loc: { + start: { line: 1, column: 31 }, + end: { line: 1, column: 34 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [36, 38], + loc: { + start: { line: 1, column: 36 }, + end: { line: 1, column: 38 } + } + }, + rest: null, + generator: false, + expression: false, + range: [14, 38], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 38 } + } + }, { + type: 'EmptyStatement', + range: [38, 39], + loc: { + start: { line: 1, column: 38 }, + end: { line: 1, column: 39 } + } + }], + range: [0, 39], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 39 } + }, + errors: [{ + index: 31, + lineNumber: 1, + column: 32, + message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' + }] + }, + + '"use strict"; (function f(eval) {});': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'f', + range: [24, 25], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 25 } + } + }, + params: [{ + type: 'Identifier', + name: 'eval', + range: [26, 30], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 30 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [32, 34], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 34 } + } + }, + rest: null, + generator: false, + expression: false, + range: [15, 34], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 34 } + } + }, + range: [14, 36], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 36 } + } + }], + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + }, + errors: [{ + index: 26, + lineNumber: 1, + column: 27, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }] + }, + + + '"use strict"; (function f(arguments) {});': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'f', + range: [24, 25], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 25 } + } + }, + params: [{ + type: 'Identifier', + name: 'arguments', + range: [26, 35], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 35 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [37, 39], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 39 } + } + }, + rest: null, + generator: false, + expression: false, + range: [15, 39], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 39 } + } + }, + range: [14, 41], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 41 } + } + }], + range: [0, 41], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 41 } + }, + errors: [{ + index: 26, + lineNumber: 1, + column: 27, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }] + }, + + '"use strict"; (function f(foo, foo) {});': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'f', + range: [24, 25], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 25 } + } + }, + params: [{ + type: 'Identifier', + name: 'foo', + range: [26, 29], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 29 } + } + }, { + type: 'Identifier', + name: 'foo', + range: [32, 35], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 35 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [37, 39], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 39 } + } + }, + rest: null, + generator: false, + expression: false, + range: [15, 39], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 39 } + } + }, + range: [14, 41], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 41 } + } + }], + range: [0, 41], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 41 } + }, + errors: [{ + index: 32, + lineNumber: 1, + column: 33, + message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' + }] + }, + + '"use strict"; x = { set f(eval) {} }' : { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [14, 15], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 15 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'f', + range: [24, 25], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 25 } + } + }, + value : { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'eval', + range: [26, 30], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 30 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [32, 34], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 34 } + } + }, + rest: null, + generator: false, + expression: false, + range: [32, 34], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 34 } + } + }, + kind: 'set', + range: [20, 34], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 34 } + } + }], + range: [18, 36], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 36 } + } + }, + range: [14, 36], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 36 } + } + }, + range: [14, 36], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 36 } + } + }], + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + }, + errors: [{ + index: 26, + lineNumber: 1, + column: 27, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }] + }, + + 'function hello() { "octal directive\\1"; "use strict"; }': { + type: 'Program', + body: [{ + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'hello', + range: [9, 14], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 14 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'octal directive\u0001', + raw: '"octal directive\\1"', + range: [19, 38], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 38 } + } + }, + range: [19, 39], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 39 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [40, 52], + loc: { + start: { line: 1, column: 40 }, + end: { line: 1, column: 52 } + } + }, + range: [40, 53], + loc: { + start: { line: 1, column: 40 }, + end: { line: 1, column: 53 } + } + }], + range: [17, 55], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 55 } + } + }, + rest: null, + generator: false, + expression: false, + range: [0, 55], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 55 } + } + }], + range: [0, 55], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 55 } + }, + errors: [{ + index: 19, + lineNumber: 1, + column: 20, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }] + }, + + '"\\1"; \'use strict\';': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: '\u0001', + raw: '"\\1"', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '\'use strict\'', + range: [6, 18], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 18 } + } + }, + range: [6, 19], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 19 } + } + }], + range: [0, 19], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 19 } + }, + errors: [{ + index: 0, + lineNumber: 1, + column: 1, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }] + }, + + '"use strict"; var x = { 014: 3}': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }, + init: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Literal', + value: 12, + raw: '014', + range: [24, 27], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 27 } + } + }, + value: { + type: 'Literal', + value: 3, + raw: '3', + range: [29, 30], + loc: { + start: { line: 1, column: 29 }, + end: { line: 1, column: 30 } + } + }, + kind: 'init', + range: [24, 30], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 30 } + } + }], + range: [22, 31], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 31 } + } + }, + range: [18, 31], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 31 } + } + }], + kind: 'var', + range: [14, 31], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 31 } + } + }], + range: [0, 31], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 31 } + }, + errors: [{ + index: 24, + lineNumber: 1, + column: 25, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }] + }, + + '"use strict"; var x = { get i() {}, get i() {} }': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }, + init: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'i', + range: [28, 29], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 29 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [32, 34], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 34 } + } + }, + rest: null, + generator: false, + expression: false, + range: [32, 34], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 34 } + } + }, + kind: 'get', + range: [24, 34], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 34 } + } + }, { + type: 'Property', + key: { + type: 'Identifier', + name: 'i', + range: [40, 41], + loc: { + start: { line: 1, column: 40 }, + end: { line: 1, column: 41 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [44, 46], + loc: { + start: { line: 1, column: 44 }, + end: { line: 1, column: 46 } + } + }, + rest: null, + generator: false, + expression: false, + range: [44, 46], + loc: { + start: { line: 1, column: 44 }, + end: { line: 1, column: 46 } + } + }, + kind: 'get', + range: [36, 46], + loc: { + start: { line: 1, column: 36 }, + end: { line: 1, column: 46 } + } + }], + range: [22, 48], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 48 } + } + }, + range: [18, 48], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 48 } + } + }], + kind: 'var', + range: [14, 48], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 48 } + } + }], + range: [0, 48], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 48 } + }, + errors: [{ + index: 46, + lineNumber: 1, + column: 47, + message: 'Error: Line 1: Object literal may not have multiple get/set accessors with the same name' + }] + }, + + '"use strict"; var x = { i: 42, get i() {} }': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }, + init: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'i', + range: [24, 25], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 25 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [27, 29], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 29 } + } + }, + kind: 'init', + range: [24, 29], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 29 } + } + }, { + type: 'Property', + key: { + type: 'Identifier', + name: 'i', + range: [35, 36], + loc: { + start: { line: 1, column: 35 }, + end: { line: 1, column: 36 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [39, 41], + loc: { + start: { line: 1, column: 39 }, + end: { line: 1, column: 41 } + } + }, + rest: null, + generator: false, + expression: false, + range: [39, 41], + loc: { + start: { line: 1, column: 39 }, + end: { line: 1, column: 41 } + } + }, + kind: 'get', + range: [31, 41], + loc: { + start: { line: 1, column: 31 }, + end: { line: 1, column: 41 } + } + }], + range: [22, 43], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 43 } + } + }, + range: [18, 43], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 43 } + } + }], + kind: 'var', + range: [14, 43], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 43 } + } + }], + range: [0, 43], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 43 } + }, + errors: [{ + index: 41, + lineNumber: 1, + column: 42, + message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' + }] + }, + + '"use strict"; var x = { set i(x) {}, i: 42 }': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }, + init: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'i', + range: [28, 29], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 29 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'x', + range: [30, 31], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 31 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [33, 35], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 35 } + } + }, + rest: null, + generator: false, + expression: false, + range: [33, 35], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 35 } + } + }, + kind: 'set', + range: [24, 35], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 35 } + } + }, { + type: 'Property', + key: { + type: 'Identifier', + name: 'i', + range: [37, 38], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 38 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [40, 42], + loc: { + start: { line: 1, column: 40 }, + end: { line: 1, column: 42 } + } + }, + kind: 'init', + range: [37, 42], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 42 } + } + }], + range: [22, 44], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 44 } + } + }, + range: [18, 44], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 44 } + } + }], + kind: 'var', + range: [14, 44], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 44 } + } + }], + range: [0, 44], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 44 } + }, + errors: [{ + index: 42, + lineNumber: 1, + column: 43, + message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' + }] + + + }, + + '({ set s() { } })': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 's', + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [11, 14], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 14 } + } + }, + rest: null, + generator: false, + expression: false, + range: [11, 14], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 14 } + } + }, + kind: 'set', + range: [3, 14], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 14 } + } + }], + range: [1, 16], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }], + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + }, + errors: [{ + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token )' + }] + }, + + 'foo("bar") = baz': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'foo', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + 'arguments': [{ + type: 'Literal', + value: 'bar', + raw: '"bar"', + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }], + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + }, + right: { + type: 'Identifier', + name: 'baz', + range: [13, 16], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }], + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + }, + errors: [{ + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }] + }, + + '1 = 2': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Literal', + value: 1, + raw: '1', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 2, + raw: '2', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }], + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + }, + errors: [{ + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }] + }, + + '3++': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Literal', + value: 3, + raw: '3', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + prefix: false, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }], + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + }, + errors: [{ + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }] + }, + + '--4': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Literal', + value: 4, + raw: '4', + range: [2, 3], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 3 } + } + }, + prefix: true, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }], + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + }, + errors: [{ + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }] + }, + + 'for (5 in []) {}': { + type: 'Program', + body: [{ + type: 'ForInStatement', + left: { + type: 'Literal', + value: 5, + raw: '5', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + body: { + type: 'BlockStatement', + body: [], + range: [14, 16], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 16 } + } + }, + each: false, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }], + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + }, + errors: [{ + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Invalid left-hand side in for-in' + }] + } + + + } +}; + diff --git a/node_modules/eventemitter2/README.md b/node_modules/eventemitter2/README.md new file mode 100644 index 0000000..e1f6edd --- /dev/null +++ b/node_modules/eventemitter2/README.md @@ -0,0 +1,248 @@ +[![build-status](https://www.codeship.io/projects/3ad58940-4c7d-0131-15d5-5a8cd3f550f8/status)](https://www.codeship.io/projects/11259) + +# SYNOPSIS + +EventEmitter2 is an implementation of the EventEmitter found in Node.js + +# DESCRIPTION + +### FEATURES + - Namespaces/Wildcards. + - Times To Listen (TTL), extends the `once` concept with `many`. + - Browser environment compatibility. + - Demonstrates good performance in benchmarks + +``` +EventEmitterHeatUp x 3,728,965 ops/sec \302\2610.68% (60 runs sampled) +EventEmitter x 2,822,904 ops/sec \302\2610.74% (63 runs sampled) +EventEmitter2 x 7,251,227 ops/sec \302\2610.55% (58 runs sampled) +EventEmitter2 (wild) x 3,220,268 ops/sec \302\2610.44% (65 runs sampled) +Fastest is EventEmitter2 +``` + +### Differences (Non breaking, compatible with existing EventEmitter) + + - The constructor takes a configuration object. + +```javascript + var EventEmitter2 = require('eventemitter2').EventEmitter2; + var server = new EventEmitter2({ + + // + // use wildcards. + // + wildcard: true, + + // + // the delimiter used to segment namespaces, defaults to `.`. + // + delimiter: '::', + + // + // if you want to emit the newListener event set to true. + // + newListener: false, + + // + // max listeners that can be assigned to an event, default 10. + // + maxListeners: 20 + }); +``` + + - Getting the actual event that fired. + +```javascript + server.on('foo.*', function(value1, value2) { + console.log(this.event, value1, value2); + }); +``` + + - Fire an event N times and then remove it, an extension of the `once` concept. + +```javascript + server.many('foo', 4, function() { + console.log('hello'); + }); +``` + + - Pass in a namespaced event as an array rather than a delimited string. + +```javascript + server.many(['foo', 'bar', 'bazz'], function() { + console.log('hello'); + }); +``` + + +# API + +When an `EventEmitter` instance experiences an error, the typical action is +to emit an `error` event. Error events are treated as a special case. +If there is no listener for it, then the default action is to print a stack +trace and exit the program. + +All EventEmitters emit the event `newListener` when new listeners are +added. + + +**Namespaces** with **Wildcards** +To use namespaces/wildcards, pass the `wildcard` option into the EventEmitter +constructor. When namespaces/wildcards are enabled, events can either be +strings (`foo.bar`) separated by a delimiter or arrays (`['foo', 'bar']`). The +delimiter is also configurable as a constructor option. + +An event name passed to any event emitter method can contain a wild card (the +`*` character). If the event name is a string, a wildcard may appear as `foo.*`. +If the event name is an array, the wildcard may appear as `['foo', '*']`. + +If either of the above described events were passed to the `on` method, +subsequent emits such as the following would be observed... + +```javascript + emitter.emit('foo.bazz'); + emitter.emit(['foo', 'bar']); +``` + + +### emitter.addListener(event, listener) +### emitter.on(event, listener) + +Adds a listener to the end of the listeners array for the specified event. + +```javascript + server.on('data', function(value1, value2, value3, ...) { + console.log('The event was raised!'); + }); +``` + +```javascript + server.on('data', function(value) { + console.log('The event was raised!'); + }); +``` + +### emitter.onAny(listener) + +Adds a listener that will be fired when any event is emitted. + +```javascript + server.onAny(function(value) { + console.log('All events trigger this.'); + }); +``` + +### emitter.offAny(listener) + +Removes the listener that will be fired when any event is emitted. + +```javascript + server.offAny(function(value) { + console.log('The event was raised!'); + }); +``` + +#### emitter.once(event, listener) + +Adds a **one time** listener for the event. The listener is invoked +only the first time the event is fired, after which it is removed. + +```javascript + server.once('get', function (value) { + console.log('Ah, we have our first value!'); + }); +``` + +### emitter.many(event, timesToListen, listener) + +Adds a listener that will execute **n times** for the event before being +removed. The listener is invoked only the first **n times** the event is +fired, after which it is removed. + +```javascript + server.many('get', 4, function (value) { + console.log('This event will be listened to exactly four times.'); + }); +``` + + +### emitter.removeListener(event, listener) +### emitter.off(event, listener) + +Remove a listener from the listener array for the specified event. +**Caution**: changes array indices in the listener array behind the listener. + +```javascript + var callback = function(value) { + console.log('someone connected!'); + }; + server.on('get', callback); + // ... + server.removeListener('get', callback); +``` + + +### emitter.removeAllListeners([event]) + +Removes all listeners, or those of the specified event. + + +### emitter.setMaxListeners(n) + +By default EventEmitters will print a warning if more than 10 listeners +are added to it. This is a useful default which helps finding memory leaks. +Obviously not all Emitters should be limited to 10. This function allows +that to be increased. Set to zero for unlimited. + + +### emitter.listeners(event) + +Returns an array of listeners for the specified event. This array can be +manipulated, e.g. to remove listeners. + +```javascript + server.on('get', function(value) { + console.log('someone connected!'); + }); + console.log(server.listeners('get')); // [ [Function] ] +``` + +### emitter.listenersAny() + +Returns an array of listeners that are listening for any event that is +specified. This array can be manipulated, e.g. to remove listeners. + +```javascript + server.onAny(function(value) { + console.log('someone connected!'); + }); + console.log(server.listenersAny()[0]); // [ [Function] ] +``` + +### emitter.emit(event, [arg1], [arg2], [...]) + +Execute each of the listeners that may be listening for the specified event +name in order with the list of arguments. + +# LICENSE + +(The MIT License) + +Copyright (c) 2011 hij1nx + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/eventemitter2/index.js b/node_modules/eventemitter2/index.js new file mode 100644 index 0000000..6f583b5 --- /dev/null +++ b/node_modules/eventemitter2/index.js @@ -0,0 +1 @@ +module.exports = require('./lib/eventemitter2'); diff --git a/node_modules/eventemitter2/lib/eventemitter2.js b/node_modules/eventemitter2/lib/eventemitter2.js new file mode 100644 index 0000000..bde69e8 --- /dev/null +++ b/node_modules/eventemitter2/lib/eventemitter2.js @@ -0,0 +1,573 @@ +/*! + * EventEmitter2 + * https://github.com/hij1nx/EventEmitter2 + * + * Copyright (c) 2013 hij1nx + * Licensed under the MIT license. + */ +;!function(undefined) { + + var isArray = Array.isArray ? Array.isArray : function _isArray(obj) { + return Object.prototype.toString.call(obj) === "[object Array]"; + }; + var defaultMaxListeners = 10; + + function init() { + this._events = {}; + if (this._conf) { + configure.call(this, this._conf); + } + } + + function configure(conf) { + if (conf) { + + this._conf = conf; + + conf.delimiter && (this.delimiter = conf.delimiter); + conf.maxListeners && (this._events.maxListeners = conf.maxListeners); + conf.wildcard && (this.wildcard = conf.wildcard); + conf.newListener && (this.newListener = conf.newListener); + + if (this.wildcard) { + this.listenerTree = {}; + } + } + } + + function EventEmitter(conf) { + this._events = {}; + this.newListener = false; + configure.call(this, conf); + } + + // + // Attention, function return type now is array, always ! + // It has zero elements if no any matches found and one or more + // elements (leafs) if there are matches + // + function searchListenerTree(handlers, type, tree, i) { + if (!tree) { + return []; + } + var listeners=[], leaf, len, branch, xTree, xxTree, isolatedBranch, endReached, + typeLength = type.length, currentType = type[i], nextType = type[i+1]; + if (i === typeLength && tree._listeners) { + // + // If at the end of the event(s) list and the tree has listeners + // invoke those listeners. + // + if (typeof tree._listeners === 'function') { + handlers && handlers.push(tree._listeners); + return [tree]; + } else { + for (leaf = 0, len = tree._listeners.length; leaf < len; leaf++) { + handlers && handlers.push(tree._listeners[leaf]); + } + return [tree]; + } + } + + if ((currentType === '*' || currentType === '**') || tree[currentType]) { + // + // If the event emitted is '*' at this part + // or there is a concrete match at this patch + // + if (currentType === '*') { + for (branch in tree) { + if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+1)); + } + } + return listeners; + } else if(currentType === '**') { + endReached = (i+1 === typeLength || (i+2 === typeLength && nextType === '*')); + if(endReached && tree._listeners) { + // The next element has a _listeners, add it to the handlers. + listeners = listeners.concat(searchListenerTree(handlers, type, tree, typeLength)); + } + + for (branch in tree) { + if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { + if(branch === '*' || branch === '**') { + if(tree[branch]._listeners && !endReached) { + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], typeLength)); + } + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); + } else if(branch === nextType) { + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+2)); + } else { + // No match on this one, shift into the tree but not in the type array. + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); + } + } + } + return listeners; + } + + listeners = listeners.concat(searchListenerTree(handlers, type, tree[currentType], i+1)); + } + + xTree = tree['*']; + if (xTree) { + // + // If the listener tree will allow any match for this part, + // then recursively explore all branches of the tree + // + searchListenerTree(handlers, type, xTree, i+1); + } + + xxTree = tree['**']; + if(xxTree) { + if(i < typeLength) { + if(xxTree._listeners) { + // If we have a listener on a '**', it will catch all, so add its handler. + searchListenerTree(handlers, type, xxTree, typeLength); + } + + // Build arrays of matching next branches and others. + for(branch in xxTree) { + if(branch !== '_listeners' && xxTree.hasOwnProperty(branch)) { + if(branch === nextType) { + // We know the next element will match, so jump twice. + searchListenerTree(handlers, type, xxTree[branch], i+2); + } else if(branch === currentType) { + // Current node matches, move into the tree. + searchListenerTree(handlers, type, xxTree[branch], i+1); + } else { + isolatedBranch = {}; + isolatedBranch[branch] = xxTree[branch]; + searchListenerTree(handlers, type, { '**': isolatedBranch }, i+1); + } + } + } + } else if(xxTree._listeners) { + // We have reached the end and still on a '**' + searchListenerTree(handlers, type, xxTree, typeLength); + } else if(xxTree['*'] && xxTree['*']._listeners) { + searchListenerTree(handlers, type, xxTree['*'], typeLength); + } + } + + return listeners; + } + + function growListenerTree(type, listener) { + + type = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + + // + // Looks for two consecutive '**', if so, don't add the event at all. + // + for(var i = 0, len = type.length; i+1 < len; i++) { + if(type[i] === '**' && type[i+1] === '**') { + return; + } + } + + var tree = this.listenerTree; + var name = type.shift(); + + while (name) { + + if (!tree[name]) { + tree[name] = {}; + } + + tree = tree[name]; + + if (type.length === 0) { + + if (!tree._listeners) { + tree._listeners = listener; + } + else if(typeof tree._listeners === 'function') { + tree._listeners = [tree._listeners, listener]; + } + else if (isArray(tree._listeners)) { + + tree._listeners.push(listener); + + if (!tree._listeners.warned) { + + var m = defaultMaxListeners; + + if (typeof this._events.maxListeners !== 'undefined') { + m = this._events.maxListeners; + } + + if (m > 0 && tree._listeners.length > m) { + + tree._listeners.warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + tree._listeners.length); + console.trace(); + } + } + } + return true; + } + name = type.shift(); + } + return true; + } + + // By default EventEmitters will print a warning if more than + // 10 listeners are added to it. This is a useful default which + // helps finding memory leaks. + // + // Obviously not all Emitters should be limited to 10. This function allows + // that to be increased. Set to zero for unlimited. + + EventEmitter.prototype.delimiter = '.'; + + EventEmitter.prototype.setMaxListeners = function(n) { + this._events || init.call(this); + this._events.maxListeners = n; + if (!this._conf) this._conf = {}; + this._conf.maxListeners = n; + }; + + EventEmitter.prototype.event = ''; + + EventEmitter.prototype.once = function(event, fn) { + this.many(event, 1, fn); + return this; + }; + + EventEmitter.prototype.many = function(event, ttl, fn) { + var self = this; + + if (typeof fn !== 'function') { + throw new Error('many only accepts instances of Function'); + } + + function listener() { + if (--ttl === 0) { + self.off(event, listener); + } + fn.apply(this, arguments); + } + + listener._origin = fn; + + this.on(event, listener); + + return self; + }; + + EventEmitter.prototype.emit = function() { + + this._events || init.call(this); + + var type = arguments[0]; + + if (type === 'newListener' && !this.newListener) { + if (!this._events.newListener) { return false; } + } + + // Loop through the *_all* functions and invoke them. + if (this._all) { + var l = arguments.length; + var args = new Array(l - 1); + for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; + for (i = 0, l = this._all.length; i < l; i++) { + this.event = type; + this._all[i].apply(this, args); + } + } + + // If there is no 'error' event listener then throw. + if (type === 'error') { + + if (!this._all && + !this._events.error && + !(this.wildcard && this.listenerTree.error)) { + + if (arguments[1] instanceof Error) { + throw arguments[1]; // Unhandled 'error' event + } else { + throw new Error("Uncaught, unspecified 'error' event."); + } + return false; + } + } + + var handler; + + if(this.wildcard) { + handler = []; + var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + searchListenerTree.call(this, handler, ns, this.listenerTree, 0); + } + else { + handler = this._events[type]; + } + + if (typeof handler === 'function') { + this.event = type; + if (arguments.length === 1) { + handler.call(this); + } + else if (arguments.length > 1) + switch (arguments.length) { + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + var l = arguments.length; + var args = new Array(l - 1); + for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; + handler.apply(this, args); + } + return true; + } + else if (handler) { + var l = arguments.length; + var args = new Array(l - 1); + for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; + + var listeners = handler.slice(); + for (var i = 0, l = listeners.length; i < l; i++) { + this.event = type; + listeners[i].apply(this, args); + } + return (listeners.length > 0) || !!this._all; + } + else { + return !!this._all; + } + + }; + + EventEmitter.prototype.on = function(type, listener) { + + if (typeof type === 'function') { + this.onAny(type); + return this; + } + + if (typeof listener !== 'function') { + throw new Error('on only accepts instances of Function'); + } + this._events || init.call(this); + + // To avoid recursion in the case that type == "newListeners"! Before + // adding it to the listeners, first emit "newListeners". + this.emit('newListener', type, listener); + + if(this.wildcard) { + growListenerTree.call(this, type, listener); + return this; + } + + if (!this._events[type]) { + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + } + else if(typeof this._events[type] === 'function') { + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + } + else if (isArray(this._events[type])) { + // If we've already got an array, just append. + this._events[type].push(listener); + + // Check for listener leak + if (!this._events[type].warned) { + + var m = defaultMaxListeners; + + if (typeof this._events.maxListeners !== 'undefined') { + m = this._events.maxListeners; + } + + if (m > 0 && this._events[type].length > m) { + + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + console.trace(); + } + } + } + return this; + }; + + EventEmitter.prototype.onAny = function(fn) { + + if (typeof fn !== 'function') { + throw new Error('onAny only accepts instances of Function'); + } + + if(!this._all) { + this._all = []; + } + + // Add the function to the event listener collection. + this._all.push(fn); + return this; + }; + + EventEmitter.prototype.addListener = EventEmitter.prototype.on; + + EventEmitter.prototype.off = function(type, listener) { + if (typeof listener !== 'function') { + throw new Error('removeListener only takes instances of Function'); + } + + var handlers,leafs=[]; + + if(this.wildcard) { + var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); + } + else { + // does not use listeners(), so no side effect of creating _events[type] + if (!this._events[type]) return this; + handlers = this._events[type]; + leafs.push({_listeners:handlers}); + } + + for (var iLeaf=0; iLeaf 0) { + fns = this._all; + for(i = 0, l = fns.length; i < l; i++) { + if(fn === fns[i]) { + fns.splice(i, 1); + return this; + } + } + } else { + this._all = []; + } + return this; + }; + + EventEmitter.prototype.removeListener = EventEmitter.prototype.off; + + EventEmitter.prototype.removeAllListeners = function(type) { + if (arguments.length === 0) { + !this._events || init.call(this); + return this; + } + + if(this.wildcard) { + var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + var leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); + + for (var iLeaf=0; iLeaf=0.4.13 <0.5.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt" + ] + ], + "_from": "eventemitter2@>=0.4.13 <0.5.0", + "_id": "eventemitter2@0.4.14", + "_inCache": true, + "_location": "/eventemitter2", + "_npmUser": { + "name": "jasonkuhrt", + "email": "jasonkuhrt@me.com" + }, + "_npmVersion": "1.4.7", + "_phantomChildren": {}, + "_requested": { + "raw": "eventemitter2@~0.4.13", + "scope": null, + "escapedName": "eventemitter2", + "name": "eventemitter2", + "rawSpec": "~0.4.13", + "spec": ">=0.4.13 <0.5.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt", + "/grunt-sftp-deploy/grunt" + ], + "_resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "_shasum": "8f61b75cde012b2e9eb284d4545583b5643b61ab", + "_shrinkwrap": null, + "_spec": "eventemitter2@~0.4.13", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt", + "author": { + "name": "hij1nx", + "email": "paolo@async.ly" + }, + "bugs": { + "url": "https://github.com/hij1nx/EventEmitter2/issues" + }, + "contributors": [ + { + "name": "Eric Elliott" + }, + { + "name": "Charlie Robbins", + "email": "charlie@nodejitsu.com" + }, + { + "name": "Jameson Lee", + "email": "jameson@nodejitsu.com" + }, + { + "name": "Jeroen van Duffelen", + "email": "jvduf@nodejitsu.com" + }, + { + "name": "Fedor Indutny", + "email": "fedor.indutny@gmail.com" + } + ], + "dependencies": {}, + "description": "A Node.js event emitter implementation with namespaces, wildcards, TTL and browser support.", + "devDependencies": { + "benchmark": ">= 0.2.2", + "nodeunit": "*" + }, + "directories": {}, + "dist": { + "shasum": "8f61b75cde012b2e9eb284d4545583b5643b61ab", + "tarball": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz" + }, + "files": [ + "lib/eventemitter2.js", + "index.js" + ], + "homepage": "https://github.com/hij1nx/EventEmitter2", + "keywords": [ + "event", + "events", + "emitter", + "eventemitter" + ], + "license": "MIT", + "main": "./lib/eventemitter2.js", + "maintainers": [ + { + "name": "hij1nx", + "email": "hij1nx@me.com" + }, + { + "name": "jasonkuhrt", + "email": "jasonkuhrt@me.com" + } + ], + "name": "eventemitter2", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/hij1nx/EventEmitter2.git" + }, + "scripts": { + "benchmark": "node test/perf/benchmark.js", + "test": "nodeunit test/simple/ && nodeunit test/wildcardEvents/" + }, + "version": "0.4.14" +} diff --git a/node_modules/exit/.jshintrc b/node_modules/exit/.jshintrc new file mode 100644 index 0000000..2b7e39b --- /dev/null +++ b/node_modules/exit/.jshintrc @@ -0,0 +1,14 @@ +{ + "curly": true, + "eqeqeq": true, + "immed": true, + "latedef": "nofunc", + "newcap": true, + "noarg": true, + "sub": true, + "undef": true, + "unused": true, + "boss": true, + "eqnull": true, + "node": true +} diff --git a/node_modules/exit/.npmignore b/node_modules/exit/.npmignore new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/exit/.travis.yml b/node_modules/exit/.travis.yml new file mode 100644 index 0000000..42d4302 --- /dev/null +++ b/node_modules/exit/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - 0.8 + - '0.10' +before_script: + - npm install -g grunt-cli diff --git a/node_modules/exit/Gruntfile.js b/node_modules/exit/Gruntfile.js new file mode 100644 index 0000000..ff37751 --- /dev/null +++ b/node_modules/exit/Gruntfile.js @@ -0,0 +1,48 @@ +'use strict'; + +module.exports = function(grunt) { + + // Project configuration. + grunt.initConfig({ + nodeunit: { + files: ['test/**/*_test.js'], + }, + jshint: { + options: { + jshintrc: '.jshintrc' + }, + gruntfile: { + src: 'Gruntfile.js' + }, + lib: { + src: ['lib/**/*.js'] + }, + test: { + src: ['test/**/*.js'] + }, + }, + watch: { + gruntfile: { + files: '<%= jshint.gruntfile.src %>', + tasks: ['jshint:gruntfile'] + }, + lib: { + files: '<%= jshint.lib.src %>', + tasks: ['jshint:lib', 'nodeunit'] + }, + test: { + files: '<%= jshint.test.src %>', + tasks: ['jshint:test', 'nodeunit'] + }, + }, + }); + + // These plugins provide necessary tasks. + grunt.loadNpmTasks('grunt-contrib-nodeunit'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-watch'); + + // Default task. + grunt.registerTask('default', ['jshint', 'nodeunit']); + +}; diff --git a/node_modules/exit/LICENSE-MIT b/node_modules/exit/LICENSE-MIT new file mode 100644 index 0000000..bb2aad6 --- /dev/null +++ b/node_modules/exit/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) 2013 "Cowboy" Ben Alman + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/exit/README.md b/node_modules/exit/README.md new file mode 100644 index 0000000..20c364e --- /dev/null +++ b/node_modules/exit/README.md @@ -0,0 +1,75 @@ +# exit [![Build Status](https://secure.travis-ci.org/cowboy/node-exit.png?branch=master)](http://travis-ci.org/cowboy/node-exit) + +A replacement for process.exit that ensures stdio are fully drained before exiting. + +To make a long story short, if `process.exit` is called on Windows, script output is often truncated when pipe-redirecting `stdout` or `stderr`. This module attempts to work around this issue by waiting until those streams have been completely drained before actually calling `process.exit`. + +See [Node.js issue #3584](https://github.com/joyent/node/issues/3584) for further reference. + +Tested in OS X 10.8, Windows 7 on Node.js 0.8.25 and 0.10.18. + +Based on some code by [@vladikoff](https://github.com/vladikoff). + +## Getting Started +Install the module with: `npm install exit` + +```javascript +var exit = require('exit'); + +// These lines should appear in the output, EVEN ON WINDOWS. +console.log("omg"); +console.error("yay"); + +// process.exit(5); +exit(5); + +// These lines shouldn't appear in the output. +console.log("wtf"); +console.error("bro"); +``` + +## Don't believe me? Try it for yourself. + +In Windows, clone the repo and cd to the `test\fixtures` directory. The only difference between [log.js](test/fixtures/log.js) and [log-broken.js](test/fixtures/log-broken.js) is that the former uses `exit` while the latter calls `process.exit` directly. + +This test was done using cmd.exe, but you can see the same results using `| grep "std"` in either PowerShell or git-bash. + +``` +C:\node-exit\test\fixtures>node log.js 0 10 stdout stderr 2>&1 | find "std" +stdout 0 +stderr 0 +stdout 1 +stderr 1 +stdout 2 +stderr 2 +stdout 3 +stderr 3 +stdout 4 +stderr 4 +stdout 5 +stderr 5 +stdout 6 +stderr 6 +stdout 7 +stderr 7 +stdout 8 +stderr 8 +stdout 9 +stderr 9 + +C:\node-exit\test\fixtures>node log-broken.js 0 10 stdout stderr 2>&1 | find "std" + +C:\node-exit\test\fixtures> +``` + +## Contributing +In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/). + +## Release History +2013-11-26 - v0.1.2 - Fixed a bug with hanging processes. +2013-09-26 - v0.1.1 - Fixed some bugs. It seems to actually work now! +2013-09-20 - v0.1.0 - Initial release. + +## License +Copyright (c) 2013 "Cowboy" Ben Alman +Licensed under the MIT license. diff --git a/node_modules/exit/lib/exit.js b/node_modules/exit/lib/exit.js new file mode 100644 index 0000000..2883e05 --- /dev/null +++ b/node_modules/exit/lib/exit.js @@ -0,0 +1,41 @@ +/* + * exit + * https://github.com/cowboy/node-exit + * + * Copyright (c) 2013 "Cowboy" Ben Alman + * Licensed under the MIT license. + */ + +'use strict'; + +module.exports = function exit(exitCode, streams) { + if (!streams) { streams = [process.stdout, process.stderr]; } + var drainCount = 0; + // Actually exit if all streams are drained. + function tryToExit() { + if (drainCount === streams.length) { + process.exit(exitCode); + } + } + streams.forEach(function(stream) { + // Count drained streams now, but monitor non-drained streams. + if (stream.bufferSize === 0) { + drainCount++; + } else { + stream.write('', 'utf-8', function() { + drainCount++; + tryToExit(); + }); + } + // Prevent further writing. + stream.write = function() {}; + }); + // If all streams were already drained, exit now. + tryToExit(); + // In Windows, when run as a Node.js child process, a script utilizing + // this library might just exit with a 0 exit code, regardless. This code, + // despite the fact that it looks a bit crazy, appears to fix that. + process.on('exit', function() { + process.exit(exitCode); + }); +}; diff --git a/node_modules/exit/package.json b/node_modules/exit/package.json new file mode 100644 index 0000000..7193849 --- /dev/null +++ b/node_modules/exit/package.json @@ -0,0 +1,108 @@ +{ + "_args": [ + [ + { + "raw": "exit@~0.1.1", + "scope": null, + "escapedName": "exit", + "name": "exit", + "rawSpec": "~0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt" + ] + ], + "_from": "exit@>=0.1.1 <0.2.0", + "_id": "exit@0.1.2", + "_inCache": true, + "_location": "/exit", + "_npmUser": { + "name": "cowboy", + "email": "cowboy@rj3.net" + }, + "_npmVersion": "1.3.11", + "_phantomChildren": {}, + "_requested": { + "raw": "exit@~0.1.1", + "scope": null, + "escapedName": "exit", + "name": "exit", + "rawSpec": "~0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/cli", + "/grunt", + "/grunt-legacy-util", + "/grunt-sftp-deploy/grunt", + "/grunt-sftp-deploy/grunt-legacy-util", + "/jshint" + ], + "_resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "_shasum": "0632638f8d877cc82107d30a0fff1a17cba1cd0c", + "_shrinkwrap": null, + "_spec": "exit@~0.1.1", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt", + "author": { + "name": "\"Cowboy\" Ben Alman", + "url": "http://benalman.com/" + }, + "bugs": { + "url": "https://github.com/cowboy/node-exit/issues" + }, + "dependencies": {}, + "description": "A replacement for process.exit that ensures stdio are fully drained before exiting.", + "devDependencies": { + "grunt": "~0.4.1", + "grunt-contrib-jshint": "~0.6.4", + "grunt-contrib-nodeunit": "~0.2.0", + "grunt-contrib-watch": "~0.5.3", + "which": "~1.0.5" + }, + "directories": {}, + "dist": { + "shasum": "0632638f8d877cc82107d30a0fff1a17cba1cd0c", + "tarball": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz" + }, + "engines": { + "node": ">= 0.8.0" + }, + "homepage": "https://github.com/cowboy/node-exit", + "keywords": [ + "exit", + "process", + "stdio", + "stdout", + "stderr", + "drain", + "flush", + "3584" + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/cowboy/node-exit/blob/master/LICENSE-MIT" + } + ], + "main": "lib/exit", + "maintainers": [ + { + "name": "cowboy", + "email": "cowboy@rj3.net" + } + ], + "name": "exit", + "optionalDependencies": {}, + "readme": "# exit [![Build Status](https://secure.travis-ci.org/cowboy/node-exit.png?branch=master)](http://travis-ci.org/cowboy/node-exit)\n\nA replacement for process.exit that ensures stdio are fully drained before exiting.\n\nTo make a long story short, if `process.exit` is called on Windows, script output is often truncated when pipe-redirecting `stdout` or `stderr`. This module attempts to work around this issue by waiting until those streams have been completely drained before actually calling `process.exit`.\n\nSee [Node.js issue #3584](https://github.com/joyent/node/issues/3584) for further reference.\n\nTested in OS X 10.8, Windows 7 on Node.js 0.8.25 and 0.10.18.\n\nBased on some code by [@vladikoff](https://github.com/vladikoff).\n\n## Getting Started\nInstall the module with: `npm install exit`\n\n```javascript\nvar exit = require('exit');\n\n// These lines should appear in the output, EVEN ON WINDOWS.\nconsole.log(\"omg\");\nconsole.error(\"yay\");\n\n// process.exit(5);\nexit(5);\n\n// These lines shouldn't appear in the output.\nconsole.log(\"wtf\");\nconsole.error(\"bro\");\n```\n\n## Don't believe me? Try it for yourself.\n\nIn Windows, clone the repo and cd to the `test\\fixtures` directory. The only difference between [log.js](test/fixtures/log.js) and [log-broken.js](test/fixtures/log-broken.js) is that the former uses `exit` while the latter calls `process.exit` directly.\n\nThis test was done using cmd.exe, but you can see the same results using `| grep \"std\"` in either PowerShell or git-bash.\n\n```\nC:\\node-exit\\test\\fixtures>node log.js 0 10 stdout stderr 2>&1 | find \"std\"\nstdout 0\nstderr 0\nstdout 1\nstderr 1\nstdout 2\nstderr 2\nstdout 3\nstderr 3\nstdout 4\nstderr 4\nstdout 5\nstderr 5\nstdout 6\nstderr 6\nstdout 7\nstderr 7\nstdout 8\nstderr 8\nstdout 9\nstderr 9\n\nC:\\node-exit\\test\\fixtures>node log-broken.js 0 10 stdout stderr 2>&1 | find \"std\"\n\nC:\\node-exit\\test\\fixtures>\n```\n\n## Contributing\nIn lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/).\n\n## Release History\n2013-11-26 - v0.1.2 - Fixed a bug with hanging processes. \n2013-09-26 - v0.1.1 - Fixed some bugs. It seems to actually work now! \n2013-09-20 - v0.1.0 - Initial release.\n\n## License\nCopyright (c) 2013 \"Cowboy\" Ben Alman \nLicensed under the MIT license.\n", + "readmeFilename": "README.md", + "repository": { + "type": "git", + "url": "git://github.com/cowboy/node-exit.git" + }, + "scripts": { + "test": "grunt nodeunit" + }, + "version": "0.1.2" +} diff --git a/node_modules/exit/test/exit_test.js b/node_modules/exit/test/exit_test.js new file mode 100644 index 0000000..a91afb9 --- /dev/null +++ b/node_modules/exit/test/exit_test.js @@ -0,0 +1,121 @@ +'use strict'; + +/* + ======== A Handy Little Nodeunit Reference ======== + https://github.com/caolan/nodeunit + + Test methods: + test.expect(numAssertions) + test.done() + Test assertions: + test.ok(value, [message]) + test.equal(actual, expected, [message]) + test.notEqual(actual, expected, [message]) + test.deepEqual(actual, expected, [message]) + test.notDeepEqual(actual, expected, [message]) + test.strictEqual(actual, expected, [message]) + test.notStrictEqual(actual, expected, [message]) + test.throws(block, [error], [message]) + test.doesNotThrow(block, [error], [message]) + test.ifError(value) +*/ + +var fs = require('fs'); +var exec = require('child_process').exec; + +var _which = require('which').sync; +function which(command) { + try { + _which(command); + return command; + } catch (err) { + return false; + } +} + +// Look for grep first (any OS). If not found (but on Windows) look for find, +// which is Windows' horribly crippled grep alternative. +var grep = which('grep') || process.platform === 'win32' && which('find'); + +exports['exit'] = { + setUp: function(done) { + this.origCwd = process.cwd(); + process.chdir('test/fixtures'); + done(); + }, + tearDown: function(done) { + process.chdir(this.origCwd); + done(); + }, + 'grep': function(test) { + test.expect(1); + // Many unit tests depend on this. + test.ok(grep, 'A suitable "grep" or "find" program was not found in the PATH.'); + test.done(); + }, + // The rest of the tests are built dynamically, to keep things sane. +}; + +// A few helper functions. +function normalizeLineEndings(s) { + return s.replace(/\r?\n/g, '\n'); +} + +// Capture command output, normalizing captured stdout to unix file endings. +function run(command, callback) { + exec(command, function(error, stdout) { + callback(error ? error.code : 0, normalizeLineEndings(stdout)); + }); +} + +// Read a fixture file, normalizing file contents to unix file endings. +function fixture(filename) { + return normalizeLineEndings(String(fs.readFileSync(filename))); +} + +function buildTests() { + // Build individual unit tests for command output. + var counts = [10, 100, 1000]; + var outputs = [' stdout stderr', ' stdout', ' stderr']; + var pipes = ['', ' | ' + grep + ' "std"']; + counts.forEach(function(count) { + outputs.forEach(function(output) { + pipes.forEach(function(pipe) { + var command = 'node log.js 0 ' + count + output + ' 2>&1' + pipe; + exports['exit']['output (' + command + ')'] = function(test) { + test.expect(2); + run(command, function(code, actual) { + var expected = fixture(count + output.replace(/ /g, '-') + '.txt'); + // Sometimes, the actual file lines are out of order on Windows. + // But since the point of this lib is to drain the buffer and not + // guarantee output order, we only test the length. + test.equal(actual.length, expected.length, 'should be the same length.'); + // The "fail" lines in log.js should NOT be output! + test.ok(actual.indexOf('fail') === -1, 'should not output after exit is called.'); + test.done(); + }); + }; + }); + }); + }); + + // Build individual unit tests for exit codes. + var codes = [0, 1, 123]; + codes.forEach(function(code) { + var command = 'node log.js ' + code + ' 10 stdout stderr'; + exports['exit']['exit code (' + command + ')'] = function(test) { + test.expect(1); + run(command, function(actual) { + // The specified exit code should be passed through. + test.equal(actual, code, 'should exit with ' + code + ' error code.'); + test.done(); + }); + }; + }); +} + +// Don't bother building tests if grep wasn't found, otherwise everything will +// fail and the error will get lost. +if (grep) { + buildTests(); +} diff --git a/node_modules/exit/test/fixtures/10-stderr.txt b/node_modules/exit/test/fixtures/10-stderr.txt new file mode 100644 index 0000000..2859200 --- /dev/null +++ b/node_modules/exit/test/fixtures/10-stderr.txt @@ -0,0 +1,10 @@ +stderr 0 +stderr 1 +stderr 2 +stderr 3 +stderr 4 +stderr 5 +stderr 6 +stderr 7 +stderr 8 +stderr 9 diff --git a/node_modules/exit/test/fixtures/10-stdout-stderr.txt b/node_modules/exit/test/fixtures/10-stdout-stderr.txt new file mode 100644 index 0000000..9de8616 --- /dev/null +++ b/node_modules/exit/test/fixtures/10-stdout-stderr.txt @@ -0,0 +1,20 @@ +stdout 0 +stderr 0 +stdout 1 +stdout 2 +stderr 1 +stdout 3 +stderr 2 +stderr 3 +stdout 4 +stderr 4 +stdout 5 +stderr 5 +stdout 6 +stderr 6 +stdout 7 +stderr 7 +stdout 8 +stderr 8 +stdout 9 +stderr 9 diff --git a/node_modules/exit/test/fixtures/10-stdout.txt b/node_modules/exit/test/fixtures/10-stdout.txt new file mode 100644 index 0000000..1ce90dc --- /dev/null +++ b/node_modules/exit/test/fixtures/10-stdout.txt @@ -0,0 +1,10 @@ +stdout 0 +stdout 1 +stdout 2 +stdout 3 +stdout 4 +stdout 5 +stdout 6 +stdout 7 +stdout 8 +stdout 9 diff --git a/node_modules/exit/test/fixtures/100-stderr.txt b/node_modules/exit/test/fixtures/100-stderr.txt new file mode 100644 index 0000000..3a78c85 --- /dev/null +++ b/node_modules/exit/test/fixtures/100-stderr.txt @@ -0,0 +1,100 @@ +stderr 0 +stderr 1 +stderr 2 +stderr 3 +stderr 4 +stderr 5 +stderr 6 +stderr 7 +stderr 8 +stderr 9 +stderr 10 +stderr 11 +stderr 12 +stderr 13 +stderr 14 +stderr 15 +stderr 16 +stderr 17 +stderr 18 +stderr 19 +stderr 20 +stderr 21 +stderr 22 +stderr 23 +stderr 24 +stderr 25 +stderr 26 +stderr 27 +stderr 28 +stderr 29 +stderr 30 +stderr 31 +stderr 32 +stderr 33 +stderr 34 +stderr 35 +stderr 36 +stderr 37 +stderr 38 +stderr 39 +stderr 40 +stderr 41 +stderr 42 +stderr 43 +stderr 44 +stderr 45 +stderr 46 +stderr 47 +stderr 48 +stderr 49 +stderr 50 +stderr 51 +stderr 52 +stderr 53 +stderr 54 +stderr 55 +stderr 56 +stderr 57 +stderr 58 +stderr 59 +stderr 60 +stderr 61 +stderr 62 +stderr 63 +stderr 64 +stderr 65 +stderr 66 +stderr 67 +stderr 68 +stderr 69 +stderr 70 +stderr 71 +stderr 72 +stderr 73 +stderr 74 +stderr 75 +stderr 76 +stderr 77 +stderr 78 +stderr 79 +stderr 80 +stderr 81 +stderr 82 +stderr 83 +stderr 84 +stderr 85 +stderr 86 +stderr 87 +stderr 88 +stderr 89 +stderr 90 +stderr 91 +stderr 92 +stderr 93 +stderr 94 +stderr 95 +stderr 96 +stderr 97 +stderr 98 +stderr 99 diff --git a/node_modules/exit/test/fixtures/100-stdout-stderr.txt b/node_modules/exit/test/fixtures/100-stdout-stderr.txt new file mode 100644 index 0000000..65f35f4 --- /dev/null +++ b/node_modules/exit/test/fixtures/100-stdout-stderr.txt @@ -0,0 +1,200 @@ +stdout 0 +stderr 0 +stdout 1 +stderr 1 +stdout 2 +stderr 2 +stdout 3 +stderr 3 +stdout 4 +stderr 4 +stdout 5 +stderr 5 +stdout 6 +stderr 6 +stdout 7 +stderr 7 +stdout 8 +stderr 8 +stdout 9 +stderr 9 +stdout 10 +stderr 10 +stdout 11 +stderr 11 +stdout 12 +stderr 12 +stdout 13 +stderr 13 +stdout 14 +stderr 14 +stdout 15 +stderr 15 +stdout 16 +stderr 16 +stdout 17 +stderr 17 +stdout 18 +stderr 18 +stdout 19 +stderr 19 +stdout 20 +stderr 20 +stdout 21 +stderr 21 +stdout 22 +stderr 22 +stdout 23 +stderr 23 +stdout 24 +stderr 24 +stdout 25 +stderr 25 +stdout 26 +stderr 26 +stdout 27 +stderr 27 +stdout 28 +stderr 28 +stdout 29 +stderr 29 +stdout 30 +stderr 30 +stdout 31 +stderr 31 +stdout 32 +stderr 32 +stdout 33 +stderr 33 +stdout 34 +stderr 34 +stdout 35 +stderr 35 +stdout 36 +stderr 36 +stdout 37 +stderr 37 +stdout 38 +stderr 38 +stdout 39 +stderr 39 +stdout 40 +stderr 40 +stdout 41 +stderr 41 +stdout 42 +stderr 42 +stdout 43 +stderr 43 +stdout 44 +stderr 44 +stdout 45 +stderr 45 +stdout 46 +stderr 46 +stdout 47 +stderr 47 +stdout 48 +stderr 48 +stdout 49 +stderr 49 +stdout 50 +stderr 50 +stdout 51 +stderr 51 +stdout 52 +stderr 52 +stdout 53 +stderr 53 +stdout 54 +stderr 54 +stdout 55 +stderr 55 +stdout 56 +stderr 56 +stdout 57 +stderr 57 +stdout 58 +stderr 58 +stdout 59 +stderr 59 +stdout 60 +stderr 60 +stdout 61 +stderr 61 +stdout 62 +stderr 62 +stdout 63 +stderr 63 +stdout 64 +stderr 64 +stdout 65 +stderr 65 +stdout 66 +stderr 66 +stdout 67 +stderr 67 +stdout 68 +stderr 68 +stdout 69 +stderr 69 +stdout 70 +stderr 70 +stdout 71 +stderr 71 +stdout 72 +stderr 72 +stdout 73 +stderr 73 +stdout 74 +stderr 74 +stdout 75 +stderr 75 +stdout 76 +stderr 76 +stdout 77 +stderr 77 +stdout 78 +stderr 78 +stdout 79 +stderr 79 +stdout 80 +stderr 80 +stdout 81 +stderr 81 +stdout 82 +stderr 82 +stdout 83 +stderr 83 +stdout 84 +stderr 84 +stdout 85 +stderr 85 +stdout 86 +stderr 86 +stdout 87 +stderr 87 +stdout 88 +stderr 88 +stdout 89 +stderr 89 +stdout 90 +stderr 90 +stdout 91 +stderr 91 +stdout 92 +stderr 92 +stdout 93 +stderr 93 +stdout 94 +stderr 94 +stdout 95 +stderr 95 +stdout 96 +stderr 96 +stdout 97 +stderr 97 +stdout 98 +stderr 98 +stdout 99 +stderr 99 diff --git a/node_modules/exit/test/fixtures/100-stdout.txt b/node_modules/exit/test/fixtures/100-stdout.txt new file mode 100644 index 0000000..5d9cac2 --- /dev/null +++ b/node_modules/exit/test/fixtures/100-stdout.txt @@ -0,0 +1,100 @@ +stdout 0 +stdout 1 +stdout 2 +stdout 3 +stdout 4 +stdout 5 +stdout 6 +stdout 7 +stdout 8 +stdout 9 +stdout 10 +stdout 11 +stdout 12 +stdout 13 +stdout 14 +stdout 15 +stdout 16 +stdout 17 +stdout 18 +stdout 19 +stdout 20 +stdout 21 +stdout 22 +stdout 23 +stdout 24 +stdout 25 +stdout 26 +stdout 27 +stdout 28 +stdout 29 +stdout 30 +stdout 31 +stdout 32 +stdout 33 +stdout 34 +stdout 35 +stdout 36 +stdout 37 +stdout 38 +stdout 39 +stdout 40 +stdout 41 +stdout 42 +stdout 43 +stdout 44 +stdout 45 +stdout 46 +stdout 47 +stdout 48 +stdout 49 +stdout 50 +stdout 51 +stdout 52 +stdout 53 +stdout 54 +stdout 55 +stdout 56 +stdout 57 +stdout 58 +stdout 59 +stdout 60 +stdout 61 +stdout 62 +stdout 63 +stdout 64 +stdout 65 +stdout 66 +stdout 67 +stdout 68 +stdout 69 +stdout 70 +stdout 71 +stdout 72 +stdout 73 +stdout 74 +stdout 75 +stdout 76 +stdout 77 +stdout 78 +stdout 79 +stdout 80 +stdout 81 +stdout 82 +stdout 83 +stdout 84 +stdout 85 +stdout 86 +stdout 87 +stdout 88 +stdout 89 +stdout 90 +stdout 91 +stdout 92 +stdout 93 +stdout 94 +stdout 95 +stdout 96 +stdout 97 +stdout 98 +stdout 99 diff --git a/node_modules/exit/test/fixtures/1000-stderr.txt b/node_modules/exit/test/fixtures/1000-stderr.txt new file mode 100644 index 0000000..d637510 --- /dev/null +++ b/node_modules/exit/test/fixtures/1000-stderr.txt @@ -0,0 +1,1000 @@ +stderr 0 +stderr 1 +stderr 2 +stderr 3 +stderr 4 +stderr 5 +stderr 6 +stderr 7 +stderr 8 +stderr 9 +stderr 10 +stderr 11 +stderr 12 +stderr 13 +stderr 14 +stderr 15 +stderr 16 +stderr 17 +stderr 18 +stderr 19 +stderr 20 +stderr 21 +stderr 22 +stderr 23 +stderr 24 +stderr 25 +stderr 26 +stderr 27 +stderr 28 +stderr 29 +stderr 30 +stderr 31 +stderr 32 +stderr 33 +stderr 34 +stderr 35 +stderr 36 +stderr 37 +stderr 38 +stderr 39 +stderr 40 +stderr 41 +stderr 42 +stderr 43 +stderr 44 +stderr 45 +stderr 46 +stderr 47 +stderr 48 +stderr 49 +stderr 50 +stderr 51 +stderr 52 +stderr 53 +stderr 54 +stderr 55 +stderr 56 +stderr 57 +stderr 58 +stderr 59 +stderr 60 +stderr 61 +stderr 62 +stderr 63 +stderr 64 +stderr 65 +stderr 66 +stderr 67 +stderr 68 +stderr 69 +stderr 70 +stderr 71 +stderr 72 +stderr 73 +stderr 74 +stderr 75 +stderr 76 +stderr 77 +stderr 78 +stderr 79 +stderr 80 +stderr 81 +stderr 82 +stderr 83 +stderr 84 +stderr 85 +stderr 86 +stderr 87 +stderr 88 +stderr 89 +stderr 90 +stderr 91 +stderr 92 +stderr 93 +stderr 94 +stderr 95 +stderr 96 +stderr 97 +stderr 98 +stderr 99 +stderr 100 +stderr 101 +stderr 102 +stderr 103 +stderr 104 +stderr 105 +stderr 106 +stderr 107 +stderr 108 +stderr 109 +stderr 110 +stderr 111 +stderr 112 +stderr 113 +stderr 114 +stderr 115 +stderr 116 +stderr 117 +stderr 118 +stderr 119 +stderr 120 +stderr 121 +stderr 122 +stderr 123 +stderr 124 +stderr 125 +stderr 126 +stderr 127 +stderr 128 +stderr 129 +stderr 130 +stderr 131 +stderr 132 +stderr 133 +stderr 134 +stderr 135 +stderr 136 +stderr 137 +stderr 138 +stderr 139 +stderr 140 +stderr 141 +stderr 142 +stderr 143 +stderr 144 +stderr 145 +stderr 146 +stderr 147 +stderr 148 +stderr 149 +stderr 150 +stderr 151 +stderr 152 +stderr 153 +stderr 154 +stderr 155 +stderr 156 +stderr 157 +stderr 158 +stderr 159 +stderr 160 +stderr 161 +stderr 162 +stderr 163 +stderr 164 +stderr 165 +stderr 166 +stderr 167 +stderr 168 +stderr 169 +stderr 170 +stderr 171 +stderr 172 +stderr 173 +stderr 174 +stderr 175 +stderr 176 +stderr 177 +stderr 178 +stderr 179 +stderr 180 +stderr 181 +stderr 182 +stderr 183 +stderr 184 +stderr 185 +stderr 186 +stderr 187 +stderr 188 +stderr 189 +stderr 190 +stderr 191 +stderr 192 +stderr 193 +stderr 194 +stderr 195 +stderr 196 +stderr 197 +stderr 198 +stderr 199 +stderr 200 +stderr 201 +stderr 202 +stderr 203 +stderr 204 +stderr 205 +stderr 206 +stderr 207 +stderr 208 +stderr 209 +stderr 210 +stderr 211 +stderr 212 +stderr 213 +stderr 214 +stderr 215 +stderr 216 +stderr 217 +stderr 218 +stderr 219 +stderr 220 +stderr 221 +stderr 222 +stderr 223 +stderr 224 +stderr 225 +stderr 226 +stderr 227 +stderr 228 +stderr 229 +stderr 230 +stderr 231 +stderr 232 +stderr 233 +stderr 234 +stderr 235 +stderr 236 +stderr 237 +stderr 238 +stderr 239 +stderr 240 +stderr 241 +stderr 242 +stderr 243 +stderr 244 +stderr 245 +stderr 246 +stderr 247 +stderr 248 +stderr 249 +stderr 250 +stderr 251 +stderr 252 +stderr 253 +stderr 254 +stderr 255 +stderr 256 +stderr 257 +stderr 258 +stderr 259 +stderr 260 +stderr 261 +stderr 262 +stderr 263 +stderr 264 +stderr 265 +stderr 266 +stderr 267 +stderr 268 +stderr 269 +stderr 270 +stderr 271 +stderr 272 +stderr 273 +stderr 274 +stderr 275 +stderr 276 +stderr 277 +stderr 278 +stderr 279 +stderr 280 +stderr 281 +stderr 282 +stderr 283 +stderr 284 +stderr 285 +stderr 286 +stderr 287 +stderr 288 +stderr 289 +stderr 290 +stderr 291 +stderr 292 +stderr 293 +stderr 294 +stderr 295 +stderr 296 +stderr 297 +stderr 298 +stderr 299 +stderr 300 +stderr 301 +stderr 302 +stderr 303 +stderr 304 +stderr 305 +stderr 306 +stderr 307 +stderr 308 +stderr 309 +stderr 310 +stderr 311 +stderr 312 +stderr 313 +stderr 314 +stderr 315 +stderr 316 +stderr 317 +stderr 318 +stderr 319 +stderr 320 +stderr 321 +stderr 322 +stderr 323 +stderr 324 +stderr 325 +stderr 326 +stderr 327 +stderr 328 +stderr 329 +stderr 330 +stderr 331 +stderr 332 +stderr 333 +stderr 334 +stderr 335 +stderr 336 +stderr 337 +stderr 338 +stderr 339 +stderr 340 +stderr 341 +stderr 342 +stderr 343 +stderr 344 +stderr 345 +stderr 346 +stderr 347 +stderr 348 +stderr 349 +stderr 350 +stderr 351 +stderr 352 +stderr 353 +stderr 354 +stderr 355 +stderr 356 +stderr 357 +stderr 358 +stderr 359 +stderr 360 +stderr 361 +stderr 362 +stderr 363 +stderr 364 +stderr 365 +stderr 366 +stderr 367 +stderr 368 +stderr 369 +stderr 370 +stderr 371 +stderr 372 +stderr 373 +stderr 374 +stderr 375 +stderr 376 +stderr 377 +stderr 378 +stderr 379 +stderr 380 +stderr 381 +stderr 382 +stderr 383 +stderr 384 +stderr 385 +stderr 386 +stderr 387 +stderr 388 +stderr 389 +stderr 390 +stderr 391 +stderr 392 +stderr 393 +stderr 394 +stderr 395 +stderr 396 +stderr 397 +stderr 398 +stderr 399 +stderr 400 +stderr 401 +stderr 402 +stderr 403 +stderr 404 +stderr 405 +stderr 406 +stderr 407 +stderr 408 +stderr 409 +stderr 410 +stderr 411 +stderr 412 +stderr 413 +stderr 414 +stderr 415 +stderr 416 +stderr 417 +stderr 418 +stderr 419 +stderr 420 +stderr 421 +stderr 422 +stderr 423 +stderr 424 +stderr 425 +stderr 426 +stderr 427 +stderr 428 +stderr 429 +stderr 430 +stderr 431 +stderr 432 +stderr 433 +stderr 434 +stderr 435 +stderr 436 +stderr 437 +stderr 438 +stderr 439 +stderr 440 +stderr 441 +stderr 442 +stderr 443 +stderr 444 +stderr 445 +stderr 446 +stderr 447 +stderr 448 +stderr 449 +stderr 450 +stderr 451 +stderr 452 +stderr 453 +stderr 454 +stderr 455 +stderr 456 +stderr 457 +stderr 458 +stderr 459 +stderr 460 +stderr 461 +stderr 462 +stderr 463 +stderr 464 +stderr 465 +stderr 466 +stderr 467 +stderr 468 +stderr 469 +stderr 470 +stderr 471 +stderr 472 +stderr 473 +stderr 474 +stderr 475 +stderr 476 +stderr 477 +stderr 478 +stderr 479 +stderr 480 +stderr 481 +stderr 482 +stderr 483 +stderr 484 +stderr 485 +stderr 486 +stderr 487 +stderr 488 +stderr 489 +stderr 490 +stderr 491 +stderr 492 +stderr 493 +stderr 494 +stderr 495 +stderr 496 +stderr 497 +stderr 498 +stderr 499 +stderr 500 +stderr 501 +stderr 502 +stderr 503 +stderr 504 +stderr 505 +stderr 506 +stderr 507 +stderr 508 +stderr 509 +stderr 510 +stderr 511 +stderr 512 +stderr 513 +stderr 514 +stderr 515 +stderr 516 +stderr 517 +stderr 518 +stderr 519 +stderr 520 +stderr 521 +stderr 522 +stderr 523 +stderr 524 +stderr 525 +stderr 526 +stderr 527 +stderr 528 +stderr 529 +stderr 530 +stderr 531 +stderr 532 +stderr 533 +stderr 534 +stderr 535 +stderr 536 +stderr 537 +stderr 538 +stderr 539 +stderr 540 +stderr 541 +stderr 542 +stderr 543 +stderr 544 +stderr 545 +stderr 546 +stderr 547 +stderr 548 +stderr 549 +stderr 550 +stderr 551 +stderr 552 +stderr 553 +stderr 554 +stderr 555 +stderr 556 +stderr 557 +stderr 558 +stderr 559 +stderr 560 +stderr 561 +stderr 562 +stderr 563 +stderr 564 +stderr 565 +stderr 566 +stderr 567 +stderr 568 +stderr 569 +stderr 570 +stderr 571 +stderr 572 +stderr 573 +stderr 574 +stderr 575 +stderr 576 +stderr 577 +stderr 578 +stderr 579 +stderr 580 +stderr 581 +stderr 582 +stderr 583 +stderr 584 +stderr 585 +stderr 586 +stderr 587 +stderr 588 +stderr 589 +stderr 590 +stderr 591 +stderr 592 +stderr 593 +stderr 594 +stderr 595 +stderr 596 +stderr 597 +stderr 598 +stderr 599 +stderr 600 +stderr 601 +stderr 602 +stderr 603 +stderr 604 +stderr 605 +stderr 606 +stderr 607 +stderr 608 +stderr 609 +stderr 610 +stderr 611 +stderr 612 +stderr 613 +stderr 614 +stderr 615 +stderr 616 +stderr 617 +stderr 618 +stderr 619 +stderr 620 +stderr 621 +stderr 622 +stderr 623 +stderr 624 +stderr 625 +stderr 626 +stderr 627 +stderr 628 +stderr 629 +stderr 630 +stderr 631 +stderr 632 +stderr 633 +stderr 634 +stderr 635 +stderr 636 +stderr 637 +stderr 638 +stderr 639 +stderr 640 +stderr 641 +stderr 642 +stderr 643 +stderr 644 +stderr 645 +stderr 646 +stderr 647 +stderr 648 +stderr 649 +stderr 650 +stderr 651 +stderr 652 +stderr 653 +stderr 654 +stderr 655 +stderr 656 +stderr 657 +stderr 658 +stderr 659 +stderr 660 +stderr 661 +stderr 662 +stderr 663 +stderr 664 +stderr 665 +stderr 666 +stderr 667 +stderr 668 +stderr 669 +stderr 670 +stderr 671 +stderr 672 +stderr 673 +stderr 674 +stderr 675 +stderr 676 +stderr 677 +stderr 678 +stderr 679 +stderr 680 +stderr 681 +stderr 682 +stderr 683 +stderr 684 +stderr 685 +stderr 686 +stderr 687 +stderr 688 +stderr 689 +stderr 690 +stderr 691 +stderr 692 +stderr 693 +stderr 694 +stderr 695 +stderr 696 +stderr 697 +stderr 698 +stderr 699 +stderr 700 +stderr 701 +stderr 702 +stderr 703 +stderr 704 +stderr 705 +stderr 706 +stderr 707 +stderr 708 +stderr 709 +stderr 710 +stderr 711 +stderr 712 +stderr 713 +stderr 714 +stderr 715 +stderr 716 +stderr 717 +stderr 718 +stderr 719 +stderr 720 +stderr 721 +stderr 722 +stderr 723 +stderr 724 +stderr 725 +stderr 726 +stderr 727 +stderr 728 +stderr 729 +stderr 730 +stderr 731 +stderr 732 +stderr 733 +stderr 734 +stderr 735 +stderr 736 +stderr 737 +stderr 738 +stderr 739 +stderr 740 +stderr 741 +stderr 742 +stderr 743 +stderr 744 +stderr 745 +stderr 746 +stderr 747 +stderr 748 +stderr 749 +stderr 750 +stderr 751 +stderr 752 +stderr 753 +stderr 754 +stderr 755 +stderr 756 +stderr 757 +stderr 758 +stderr 759 +stderr 760 +stderr 761 +stderr 762 +stderr 763 +stderr 764 +stderr 765 +stderr 766 +stderr 767 +stderr 768 +stderr 769 +stderr 770 +stderr 771 +stderr 772 +stderr 773 +stderr 774 +stderr 775 +stderr 776 +stderr 777 +stderr 778 +stderr 779 +stderr 780 +stderr 781 +stderr 782 +stderr 783 +stderr 784 +stderr 785 +stderr 786 +stderr 787 +stderr 788 +stderr 789 +stderr 790 +stderr 791 +stderr 792 +stderr 793 +stderr 794 +stderr 795 +stderr 796 +stderr 797 +stderr 798 +stderr 799 +stderr 800 +stderr 801 +stderr 802 +stderr 803 +stderr 804 +stderr 805 +stderr 806 +stderr 807 +stderr 808 +stderr 809 +stderr 810 +stderr 811 +stderr 812 +stderr 813 +stderr 814 +stderr 815 +stderr 816 +stderr 817 +stderr 818 +stderr 819 +stderr 820 +stderr 821 +stderr 822 +stderr 823 +stderr 824 +stderr 825 +stderr 826 +stderr 827 +stderr 828 +stderr 829 +stderr 830 +stderr 831 +stderr 832 +stderr 833 +stderr 834 +stderr 835 +stderr 836 +stderr 837 +stderr 838 +stderr 839 +stderr 840 +stderr 841 +stderr 842 +stderr 843 +stderr 844 +stderr 845 +stderr 846 +stderr 847 +stderr 848 +stderr 849 +stderr 850 +stderr 851 +stderr 852 +stderr 853 +stderr 854 +stderr 855 +stderr 856 +stderr 857 +stderr 858 +stderr 859 +stderr 860 +stderr 861 +stderr 862 +stderr 863 +stderr 864 +stderr 865 +stderr 866 +stderr 867 +stderr 868 +stderr 869 +stderr 870 +stderr 871 +stderr 872 +stderr 873 +stderr 874 +stderr 875 +stderr 876 +stderr 877 +stderr 878 +stderr 879 +stderr 880 +stderr 881 +stderr 882 +stderr 883 +stderr 884 +stderr 885 +stderr 886 +stderr 887 +stderr 888 +stderr 889 +stderr 890 +stderr 891 +stderr 892 +stderr 893 +stderr 894 +stderr 895 +stderr 896 +stderr 897 +stderr 898 +stderr 899 +stderr 900 +stderr 901 +stderr 902 +stderr 903 +stderr 904 +stderr 905 +stderr 906 +stderr 907 +stderr 908 +stderr 909 +stderr 910 +stderr 911 +stderr 912 +stderr 913 +stderr 914 +stderr 915 +stderr 916 +stderr 917 +stderr 918 +stderr 919 +stderr 920 +stderr 921 +stderr 922 +stderr 923 +stderr 924 +stderr 925 +stderr 926 +stderr 927 +stderr 928 +stderr 929 +stderr 930 +stderr 931 +stderr 932 +stderr 933 +stderr 934 +stderr 935 +stderr 936 +stderr 937 +stderr 938 +stderr 939 +stderr 940 +stderr 941 +stderr 942 +stderr 943 +stderr 944 +stderr 945 +stderr 946 +stderr 947 +stderr 948 +stderr 949 +stderr 950 +stderr 951 +stderr 952 +stderr 953 +stderr 954 +stderr 955 +stderr 956 +stderr 957 +stderr 958 +stderr 959 +stderr 960 +stderr 961 +stderr 962 +stderr 963 +stderr 964 +stderr 965 +stderr 966 +stderr 967 +stderr 968 +stderr 969 +stderr 970 +stderr 971 +stderr 972 +stderr 973 +stderr 974 +stderr 975 +stderr 976 +stderr 977 +stderr 978 +stderr 979 +stderr 980 +stderr 981 +stderr 982 +stderr 983 +stderr 984 +stderr 985 +stderr 986 +stderr 987 +stderr 988 +stderr 989 +stderr 990 +stderr 991 +stderr 992 +stderr 993 +stderr 994 +stderr 995 +stderr 996 +stderr 997 +stderr 998 +stderr 999 diff --git a/node_modules/exit/test/fixtures/1000-stdout-stderr.txt b/node_modules/exit/test/fixtures/1000-stdout-stderr.txt new file mode 100644 index 0000000..4fde2b4 --- /dev/null +++ b/node_modules/exit/test/fixtures/1000-stdout-stderr.txt @@ -0,0 +1,2000 @@ +stdout 0 +stderr 0 +stdout 1 +stderr 1 +stdout 2 +stderr 2 +stdout 3 +stderr 3 +stdout 4 +stderr 4 +stdout 5 +stderr 5 +stdout 6 +stderr 6 +stdout 7 +stderr 7 +stdout 8 +stderr 8 +stdout 9 +stderr 9 +stdout 10 +stderr 10 +stdout 11 +stderr 11 +stdout 12 +stderr 12 +stdout 13 +stderr 13 +stdout 14 +stderr 14 +stdout 15 +stderr 15 +stdout 16 +stderr 16 +stdout 17 +stderr 17 +stdout 18 +stderr 18 +stdout 19 +stderr 19 +stdout 20 +stderr 20 +stdout 21 +stderr 21 +stdout 22 +stderr 22 +stdout 23 +stderr 23 +stdout 24 +stderr 24 +stdout 25 +stderr 25 +stdout 26 +stderr 26 +stdout 27 +stderr 27 +stdout 28 +stderr 28 +stdout 29 +stderr 29 +stdout 30 +stderr 30 +stdout 31 +stderr 31 +stdout 32 +stderr 32 +stdout 33 +stderr 33 +stdout 34 +stderr 34 +stdout 35 +stderr 35 +stdout 36 +stderr 36 +stdout 37 +stderr 37 +stdout 38 +stderr 38 +stdout 39 +stderr 39 +stdout 40 +stderr 40 +stdout 41 +stderr 41 +stdout 42 +stderr 42 +stdout 43 +stderr 43 +stdout 44 +stderr 44 +stdout 45 +stderr 45 +stdout 46 +stderr 46 +stdout 47 +stderr 47 +stdout 48 +stderr 48 +stdout 49 +stderr 49 +stdout 50 +stderr 50 +stdout 51 +stderr 51 +stdout 52 +stderr 52 +stdout 53 +stderr 53 +stdout 54 +stderr 54 +stdout 55 +stderr 55 +stdout 56 +stderr 56 +stdout 57 +stderr 57 +stdout 58 +stderr 58 +stdout 59 +stderr 59 +stdout 60 +stderr 60 +stdout 61 +stderr 61 +stdout 62 +stderr 62 +stdout 63 +stderr 63 +stdout 64 +stderr 64 +stdout 65 +stderr 65 +stdout 66 +stderr 66 +stdout 67 +stderr 67 +stdout 68 +stderr 68 +stdout 69 +stderr 69 +stdout 70 +stderr 70 +stdout 71 +stderr 71 +stdout 72 +stderr 72 +stdout 73 +stderr 73 +stdout 74 +stderr 74 +stdout 75 +stderr 75 +stdout 76 +stderr 76 +stdout 77 +stderr 77 +stdout 78 +stderr 78 +stdout 79 +stderr 79 +stdout 80 +stderr 80 +stdout 81 +stderr 81 +stdout 82 +stderr 82 +stdout 83 +stderr 83 +stdout 84 +stderr 84 +stdout 85 +stderr 85 +stdout 86 +stderr 86 +stdout 87 +stderr 87 +stdout 88 +stderr 88 +stdout 89 +stderr 89 +stdout 90 +stderr 90 +stdout 91 +stderr 91 +stdout 92 +stderr 92 +stdout 93 +stderr 93 +stdout 94 +stderr 94 +stdout 95 +stderr 95 +stdout 96 +stderr 96 +stdout 97 +stderr 97 +stdout 98 +stderr 98 +stdout 99 +stderr 99 +stdout 100 +stderr 100 +stdout 101 +stderr 101 +stdout 102 +stderr 102 +stdout 103 +stderr 103 +stdout 104 +stderr 104 +stdout 105 +stderr 105 +stdout 106 +stderr 106 +stdout 107 +stderr 107 +stdout 108 +stderr 108 +stdout 109 +stderr 109 +stdout 110 +stderr 110 +stdout 111 +stderr 111 +stdout 112 +stderr 112 +stdout 113 +stderr 113 +stdout 114 +stderr 114 +stdout 115 +stderr 115 +stdout 116 +stderr 116 +stdout 117 +stderr 117 +stdout 118 +stderr 118 +stdout 119 +stderr 119 +stdout 120 +stderr 120 +stdout 121 +stderr 121 +stdout 122 +stderr 122 +stdout 123 +stderr 123 +stdout 124 +stderr 124 +stdout 125 +stderr 125 +stdout 126 +stderr 126 +stdout 127 +stderr 127 +stdout 128 +stderr 128 +stdout 129 +stderr 129 +stdout 130 +stderr 130 +stdout 131 +stderr 131 +stdout 132 +stderr 132 +stdout 133 +stderr 133 +stdout 134 +stderr 134 +stdout 135 +stderr 135 +stdout 136 +stderr 136 +stdout 137 +stderr 137 +stdout 138 +stderr 138 +stdout 139 +stderr 139 +stdout 140 +stderr 140 +stdout 141 +stderr 141 +stdout 142 +stderr 142 +stdout 143 +stderr 143 +stdout 144 +stderr 144 +stdout 145 +stderr 145 +stdout 146 +stderr 146 +stdout 147 +stderr 147 +stdout 148 +stderr 148 +stdout 149 +stderr 149 +stdout 150 +stderr 150 +stdout 151 +stderr 151 +stdout 152 +stderr 152 +stdout 153 +stderr 153 +stdout 154 +stderr 154 +stdout 155 +stderr 155 +stdout 156 +stderr 156 +stdout 157 +stderr 157 +stdout 158 +stderr 158 +stdout 159 +stderr 159 +stdout 160 +stderr 160 +stdout 161 +stderr 161 +stdout 162 +stderr 162 +stdout 163 +stderr 163 +stdout 164 +stderr 164 +stdout 165 +stderr 165 +stdout 166 +stderr 166 +stdout 167 +stderr 167 +stdout 168 +stderr 168 +stdout 169 +stderr 169 +stdout 170 +stderr 170 +stdout 171 +stderr 171 +stdout 172 +stderr 172 +stdout 173 +stderr 173 +stdout 174 +stderr 174 +stdout 175 +stderr 175 +stdout 176 +stderr 176 +stdout 177 +stderr 177 +stdout 178 +stderr 178 +stdout 179 +stderr 179 +stdout 180 +stderr 180 +stdout 181 +stderr 181 +stdout 182 +stderr 182 +stdout 183 +stderr 183 +stdout 184 +stderr 184 +stdout 185 +stderr 185 +stdout 186 +stderr 186 +stdout 187 +stderr 187 +stdout 188 +stderr 188 +stdout 189 +stderr 189 +stdout 190 +stderr 190 +stdout 191 +stderr 191 +stdout 192 +stderr 192 +stdout 193 +stderr 193 +stdout 194 +stderr 194 +stdout 195 +stderr 195 +stdout 196 +stderr 196 +stdout 197 +stderr 197 +stdout 198 +stderr 198 +stdout 199 +stderr 199 +stdout 200 +stderr 200 +stdout 201 +stderr 201 +stdout 202 +stderr 202 +stdout 203 +stderr 203 +stdout 204 +stderr 204 +stdout 205 +stderr 205 +stdout 206 +stderr 206 +stdout 207 +stderr 207 +stdout 208 +stderr 208 +stdout 209 +stderr 209 +stdout 210 +stderr 210 +stdout 211 +stderr 211 +stdout 212 +stderr 212 +stdout 213 +stderr 213 +stdout 214 +stderr 214 +stdout 215 +stderr 215 +stdout 216 +stderr 216 +stdout 217 +stderr 217 +stdout 218 +stderr 218 +stdout 219 +stderr 219 +stdout 220 +stderr 220 +stdout 221 +stderr 221 +stdout 222 +stderr 222 +stdout 223 +stderr 223 +stdout 224 +stderr 224 +stdout 225 +stderr 225 +stdout 226 +stderr 226 +stdout 227 +stderr 227 +stdout 228 +stderr 228 +stdout 229 +stderr 229 +stdout 230 +stderr 230 +stdout 231 +stderr 231 +stdout 232 +stderr 232 +stdout 233 +stderr 233 +stdout 234 +stderr 234 +stdout 235 +stderr 235 +stdout 236 +stderr 236 +stdout 237 +stderr 237 +stdout 238 +stderr 238 +stdout 239 +stderr 239 +stdout 240 +stderr 240 +stdout 241 +stderr 241 +stdout 242 +stderr 242 +stdout 243 +stderr 243 +stdout 244 +stderr 244 +stdout 245 +stderr 245 +stdout 246 +stderr 246 +stdout 247 +stderr 247 +stdout 248 +stderr 248 +stdout 249 +stderr 249 +stdout 250 +stderr 250 +stdout 251 +stderr 251 +stdout 252 +stderr 252 +stdout 253 +stderr 253 +stdout 254 +stderr 254 +stdout 255 +stderr 255 +stdout 256 +stderr 256 +stdout 257 +stderr 257 +stdout 258 +stderr 258 +stdout 259 +stderr 259 +stdout 260 +stderr 260 +stdout 261 +stderr 261 +stdout 262 +stderr 262 +stdout 263 +stderr 263 +stdout 264 +stderr 264 +stdout 265 +stderr 265 +stdout 266 +stderr 266 +stdout 267 +stderr 267 +stdout 268 +stderr 268 +stdout 269 +stderr 269 +stdout 270 +stderr 270 +stdout 271 +stderr 271 +stdout 272 +stderr 272 +stdout 273 +stderr 273 +stdout 274 +stderr 274 +stdout 275 +stderr 275 +stdout 276 +stderr 276 +stdout 277 +stderr 277 +stdout 278 +stderr 278 +stdout 279 +stderr 279 +stdout 280 +stderr 280 +stdout 281 +stderr 281 +stdout 282 +stderr 282 +stdout 283 +stderr 283 +stdout 284 +stderr 284 +stdout 285 +stderr 285 +stdout 286 +stderr 286 +stdout 287 +stderr 287 +stdout 288 +stderr 288 +stdout 289 +stderr 289 +stdout 290 +stderr 290 +stdout 291 +stderr 291 +stdout 292 +stderr 292 +stdout 293 +stderr 293 +stdout 294 +stderr 294 +stdout 295 +stderr 295 +stdout 296 +stderr 296 +stdout 297 +stderr 297 +stdout 298 +stderr 298 +stdout 299 +stderr 299 +stdout 300 +stderr 300 +stdout 301 +stderr 301 +stdout 302 +stderr 302 +stdout 303 +stderr 303 +stdout 304 +stderr 304 +stdout 305 +stderr 305 +stdout 306 +stderr 306 +stdout 307 +stderr 307 +stdout 308 +stderr 308 +stdout 309 +stderr 309 +stdout 310 +stderr 310 +stdout 311 +stderr 311 +stdout 312 +stderr 312 +stdout 313 +stderr 313 +stdout 314 +stderr 314 +stdout 315 +stderr 315 +stdout 316 +stderr 316 +stdout 317 +stderr 317 +stdout 318 +stderr 318 +stdout 319 +stderr 319 +stdout 320 +stderr 320 +stdout 321 +stderr 321 +stdout 322 +stderr 322 +stdout 323 +stderr 323 +stdout 324 +stderr 324 +stdout 325 +stderr 325 +stdout 326 +stderr 326 +stdout 327 +stderr 327 +stdout 328 +stderr 328 +stdout 329 +stderr 329 +stdout 330 +stderr 330 +stdout 331 +stderr 331 +stdout 332 +stderr 332 +stdout 333 +stderr 333 +stdout 334 +stderr 334 +stdout 335 +stderr 335 +stdout 336 +stderr 336 +stdout 337 +stderr 337 +stdout 338 +stderr 338 +stdout 339 +stderr 339 +stdout 340 +stderr 340 +stdout 341 +stderr 341 +stdout 342 +stderr 342 +stdout 343 +stderr 343 +stdout 344 +stderr 344 +stdout 345 +stderr 345 +stdout 346 +stderr 346 +stdout 347 +stderr 347 +stdout 348 +stderr 348 +stdout 349 +stderr 349 +stdout 350 +stderr 350 +stdout 351 +stderr 351 +stdout 352 +stderr 352 +stdout 353 +stderr 353 +stdout 354 +stderr 354 +stdout 355 +stderr 355 +stdout 356 +stderr 356 +stdout 357 +stderr 357 +stdout 358 +stderr 358 +stdout 359 +stderr 359 +stdout 360 +stderr 360 +stdout 361 +stderr 361 +stdout 362 +stderr 362 +stdout 363 +stderr 363 +stdout 364 +stderr 364 +stdout 365 +stderr 365 +stdout 366 +stderr 366 +stdout 367 +stderr 367 +stdout 368 +stderr 368 +stdout 369 +stderr 369 +stdout 370 +stderr 370 +stdout 371 +stderr 371 +stdout 372 +stderr 372 +stdout 373 +stderr 373 +stdout 374 +stderr 374 +stdout 375 +stderr 375 +stdout 376 +stderr 376 +stdout 377 +stderr 377 +stdout 378 +stderr 378 +stdout 379 +stderr 379 +stdout 380 +stderr 380 +stdout 381 +stderr 381 +stdout 382 +stderr 382 +stdout 383 +stderr 383 +stdout 384 +stderr 384 +stdout 385 +stderr 385 +stdout 386 +stderr 386 +stdout 387 +stderr 387 +stdout 388 +stderr 388 +stdout 389 +stderr 389 +stdout 390 +stderr 390 +stdout 391 +stderr 391 +stdout 392 +stderr 392 +stdout 393 +stderr 393 +stdout 394 +stderr 394 +stdout 395 +stderr 395 +stdout 396 +stderr 396 +stdout 397 +stderr 397 +stdout 398 +stderr 398 +stdout 399 +stderr 399 +stdout 400 +stderr 400 +stdout 401 +stderr 401 +stdout 402 +stderr 402 +stdout 403 +stderr 403 +stdout 404 +stderr 404 +stdout 405 +stderr 405 +stdout 406 +stderr 406 +stdout 407 +stderr 407 +stdout 408 +stderr 408 +stdout 409 +stderr 409 +stdout 410 +stderr 410 +stdout 411 +stderr 411 +stdout 412 +stderr 412 +stdout 413 +stderr 413 +stdout 414 +stderr 414 +stdout 415 +stderr 415 +stdout 416 +stderr 416 +stdout 417 +stderr 417 +stdout 418 +stderr 418 +stdout 419 +stderr 419 +stdout 420 +stderr 420 +stdout 421 +stderr 421 +stdout 422 +stderr 422 +stdout 423 +stderr 423 +stdout 424 +stderr 424 +stdout 425 +stderr 425 +stdout 426 +stderr 426 +stdout 427 +stderr 427 +stdout 428 +stderr 428 +stdout 429 +stderr 429 +stdout 430 +stderr 430 +stdout 431 +stderr 431 +stdout 432 +stderr 432 +stdout 433 +stderr 433 +stdout 434 +stderr 434 +stdout 435 +stderr 435 +stdout 436 +stderr 436 +stdout 437 +stderr 437 +stdout 438 +stderr 438 +stdout 439 +stderr 439 +stdout 440 +stderr 440 +stdout 441 +stderr 441 +stdout 442 +stderr 442 +stdout 443 +stderr 443 +stdout 444 +stderr 444 +stdout 445 +stderr 445 +stdout 446 +stderr 446 +stdout 447 +stderr 447 +stdout 448 +stderr 448 +stdout 449 +stderr 449 +stdout 450 +stderr 450 +stdout 451 +stderr 451 +stdout 452 +stderr 452 +stdout 453 +stderr 453 +stdout 454 +stderr 454 +stdout 455 +stderr 455 +stdout 456 +stderr 456 +stdout 457 +stderr 457 +stdout 458 +stderr 458 +stdout 459 +stderr 459 +stdout 460 +stderr 460 +stdout 461 +stderr 461 +stdout 462 +stderr 462 +stdout 463 +stderr 463 +stdout 464 +stderr 464 +stdout 465 +stderr 465 +stdout 466 +stderr 466 +stdout 467 +stderr 467 +stdout 468 +stderr 468 +stdout 469 +stderr 469 +stdout 470 +stderr 470 +stdout 471 +stderr 471 +stdout 472 +stderr 472 +stdout 473 +stderr 473 +stdout 474 +stderr 474 +stdout 475 +stderr 475 +stdout 476 +stderr 476 +stdout 477 +stderr 477 +stdout 478 +stderr 478 +stdout 479 +stderr 479 +stdout 480 +stderr 480 +stdout 481 +stderr 481 +stdout 482 +stderr 482 +stdout 483 +stderr 483 +stdout 484 +stderr 484 +stdout 485 +stderr 485 +stdout 486 +stderr 486 +stdout 487 +stderr 487 +stdout 488 +stderr 488 +stdout 489 +stderr 489 +stdout 490 +stderr 490 +stdout 491 +stderr 491 +stdout 492 +stderr 492 +stdout 493 +stderr 493 +stdout 494 +stderr 494 +stdout 495 +stderr 495 +stdout 496 +stderr 496 +stdout 497 +stderr 497 +stdout 498 +stderr 498 +stdout 499 +stderr 499 +stdout 500 +stderr 500 +stdout 501 +stderr 501 +stdout 502 +stderr 502 +stdout 503 +stderr 503 +stdout 504 +stderr 504 +stdout 505 +stderr 505 +stdout 506 +stderr 506 +stdout 507 +stderr 507 +stdout 508 +stderr 508 +stdout 509 +stderr 509 +stdout 510 +stderr 510 +stdout 511 +stderr 511 +stdout 512 +stderr 512 +stdout 513 +stderr 513 +stdout 514 +stderr 514 +stdout 515 +stderr 515 +stdout 516 +stderr 516 +stdout 517 +stderr 517 +stdout 518 +stderr 518 +stdout 519 +stderr 519 +stdout 520 +stderr 520 +stdout 521 +stderr 521 +stdout 522 +stderr 522 +stdout 523 +stderr 523 +stdout 524 +stderr 524 +stdout 525 +stderr 525 +stdout 526 +stderr 526 +stdout 527 +stderr 527 +stdout 528 +stderr 528 +stdout 529 +stderr 529 +stdout 530 +stderr 530 +stdout 531 +stderr 531 +stdout 532 +stderr 532 +stdout 533 +stderr 533 +stdout 534 +stderr 534 +stdout 535 +stderr 535 +stdout 536 +stderr 536 +stdout 537 +stderr 537 +stdout 538 +stderr 538 +stdout 539 +stderr 539 +stdout 540 +stderr 540 +stdout 541 +stderr 541 +stdout 542 +stderr 542 +stdout 543 +stderr 543 +stdout 544 +stderr 544 +stdout 545 +stderr 545 +stdout 546 +stderr 546 +stdout 547 +stderr 547 +stdout 548 +stderr 548 +stdout 549 +stderr 549 +stdout 550 +stderr 550 +stdout 551 +stderr 551 +stdout 552 +stderr 552 +stdout 553 +stderr 553 +stdout 554 +stderr 554 +stdout 555 +stderr 555 +stdout 556 +stderr 556 +stdout 557 +stderr 557 +stdout 558 +stderr 558 +stdout 559 +stderr 559 +stdout 560 +stderr 560 +stdout 561 +stderr 561 +stdout 562 +stderr 562 +stdout 563 +stderr 563 +stdout 564 +stderr 564 +stdout 565 +stderr 565 +stdout 566 +stderr 566 +stdout 567 +stderr 567 +stdout 568 +stderr 568 +stdout 569 +stderr 569 +stdout 570 +stderr 570 +stdout 571 +stderr 571 +stdout 572 +stderr 572 +stdout 573 +stderr 573 +stdout 574 +stderr 574 +stdout 575 +stderr 575 +stdout 576 +stderr 576 +stdout 577 +stderr 577 +stdout 578 +stderr 578 +stdout 579 +stderr 579 +stdout 580 +stderr 580 +stdout 581 +stderr 581 +stdout 582 +stderr 582 +stdout 583 +stderr 583 +stdout 584 +stderr 584 +stdout 585 +stderr 585 +stdout 586 +stderr 586 +stdout 587 +stderr 587 +stdout 588 +stderr 588 +stdout 589 +stderr 589 +stdout 590 +stderr 590 +stdout 591 +stderr 591 +stdout 592 +stderr 592 +stdout 593 +stderr 593 +stdout 594 +stderr 594 +stdout 595 +stderr 595 +stdout 596 +stderr 596 +stdout 597 +stderr 597 +stdout 598 +stderr 598 +stdout 599 +stderr 599 +stdout 600 +stderr 600 +stdout 601 +stderr 601 +stdout 602 +stderr 602 +stdout 603 +stderr 603 +stdout 604 +stderr 604 +stdout 605 +stderr 605 +stdout 606 +stderr 606 +stdout 607 +stderr 607 +stdout 608 +stderr 608 +stdout 609 +stderr 609 +stdout 610 +stderr 610 +stdout 611 +stderr 611 +stdout 612 +stderr 612 +stdout 613 +stderr 613 +stdout 614 +stderr 614 +stdout 615 +stderr 615 +stdout 616 +stderr 616 +stdout 617 +stderr 617 +stdout 618 +stderr 618 +stdout 619 +stderr 619 +stdout 620 +stderr 620 +stdout 621 +stderr 621 +stdout 622 +stderr 622 +stdout 623 +stderr 623 +stdout 624 +stderr 624 +stdout 625 +stderr 625 +stdout 626 +stderr 626 +stdout 627 +stderr 627 +stdout 628 +stderr 628 +stdout 629 +stderr 629 +stdout 630 +stderr 630 +stdout 631 +stderr 631 +stdout 632 +stderr 632 +stdout 633 +stderr 633 +stdout 634 +stderr 634 +stdout 635 +stderr 635 +stdout 636 +stderr 636 +stdout 637 +stderr 637 +stdout 638 +stderr 638 +stdout 639 +stderr 639 +stdout 640 +stderr 640 +stdout 641 +stderr 641 +stdout 642 +stderr 642 +stdout 643 +stderr 643 +stdout 644 +stderr 644 +stdout 645 +stderr 645 +stdout 646 +stderr 646 +stdout 647 +stderr 647 +stdout 648 +stderr 648 +stdout 649 +stderr 649 +stdout 650 +stderr 650 +stdout 651 +stderr 651 +stdout 652 +stderr 652 +stdout 653 +stderr 653 +stdout 654 +stderr 654 +stdout 655 +stderr 655 +stdout 656 +stderr 656 +stdout 657 +stderr 657 +stdout 658 +stderr 658 +stdout 659 +stderr 659 +stdout 660 +stderr 660 +stdout 661 +stderr 661 +stdout 662 +stderr 662 +stdout 663 +stderr 663 +stdout 664 +stderr 664 +stdout 665 +stderr 665 +stdout 666 +stderr 666 +stdout 667 +stderr 667 +stdout 668 +stderr 668 +stdout 669 +stderr 669 +stdout 670 +stderr 670 +stdout 671 +stderr 671 +stdout 672 +stderr 672 +stdout 673 +stderr 673 +stdout 674 +stderr 674 +stdout 675 +stderr 675 +stdout 676 +stderr 676 +stdout 677 +stderr 677 +stdout 678 +stderr 678 +stdout 679 +stderr 679 +stdout 680 +stderr 680 +stdout 681 +stderr 681 +stdout 682 +stderr 682 +stdout 683 +stderr 683 +stdout 684 +stderr 684 +stdout 685 +stderr 685 +stdout 686 +stderr 686 +stdout 687 +stderr 687 +stdout 688 +stderr 688 +stdout 689 +stderr 689 +stdout 690 +stderr 690 +stdout 691 +stderr 691 +stdout 692 +stderr 692 +stdout 693 +stderr 693 +stdout 694 +stderr 694 +stdout 695 +stderr 695 +stdout 696 +stderr 696 +stdout 697 +stderr 697 +stdout 698 +stderr 698 +stdout 699 +stderr 699 +stdout 700 +stderr 700 +stdout 701 +stderr 701 +stdout 702 +stderr 702 +stdout 703 +stderr 703 +stdout 704 +stderr 704 +stdout 705 +stderr 705 +stdout 706 +stderr 706 +stdout 707 +stderr 707 +stdout 708 +stderr 708 +stdout 709 +stderr 709 +stdout 710 +stderr 710 +stdout 711 +stderr 711 +stdout 712 +stderr 712 +stdout 713 +stderr 713 +stdout 714 +stderr 714 +stdout 715 +stderr 715 +stdout 716 +stderr 716 +stdout 717 +stderr 717 +stdout 718 +stderr 718 +stdout 719 +stderr 719 +stdout 720 +stderr 720 +stdout 721 +stderr 721 +stdout 722 +stderr 722 +stdout 723 +stderr 723 +stdout 724 +stderr 724 +stdout 725 +stderr 725 +stdout 726 +stderr 726 +stdout 727 +stderr 727 +stdout 728 +stderr 728 +stdout 729 +stderr 729 +stdout 730 +stderr 730 +stdout 731 +stderr 731 +stdout 732 +stderr 732 +stdout 733 +stderr 733 +stdout 734 +stderr 734 +stdout 735 +stderr 735 +stdout 736 +stderr 736 +stdout 737 +stderr 737 +stdout 738 +stderr 738 +stdout 739 +stderr 739 +stdout 740 +stderr 740 +stdout 741 +stderr 741 +stdout 742 +stderr 742 +stdout 743 +stderr 743 +stdout 744 +stderr 744 +stdout 745 +stderr 745 +stdout 746 +stderr 746 +stdout 747 +stderr 747 +stdout 748 +stderr 748 +stdout 749 +stderr 749 +stdout 750 +stderr 750 +stdout 751 +stderr 751 +stdout 752 +stderr 752 +stdout 753 +stderr 753 +stdout 754 +stderr 754 +stdout 755 +stderr 755 +stdout 756 +stderr 756 +stdout 757 +stderr 757 +stdout 758 +stderr 758 +stdout 759 +stderr 759 +stdout 760 +stderr 760 +stdout 761 +stderr 761 +stdout 762 +stderr 762 +stdout 763 +stderr 763 +stdout 764 +stderr 764 +stdout 765 +stderr 765 +stdout 766 +stderr 766 +stdout 767 +stderr 767 +stdout 768 +stderr 768 +stdout 769 +stderr 769 +stdout 770 +stderr 770 +stdout 771 +stderr 771 +stdout 772 +stderr 772 +stdout 773 +stderr 773 +stdout 774 +stderr 774 +stdout 775 +stderr 775 +stdout 776 +stderr 776 +stdout 777 +stderr 777 +stdout 778 +stderr 778 +stdout 779 +stderr 779 +stdout 780 +stderr 780 +stdout 781 +stderr 781 +stdout 782 +stderr 782 +stdout 783 +stderr 783 +stdout 784 +stderr 784 +stdout 785 +stderr 785 +stdout 786 +stderr 786 +stdout 787 +stderr 787 +stdout 788 +stderr 788 +stdout 789 +stderr 789 +stdout 790 +stderr 790 +stdout 791 +stderr 791 +stdout 792 +stderr 792 +stdout 793 +stderr 793 +stdout 794 +stderr 794 +stdout 795 +stderr 795 +stdout 796 +stderr 796 +stdout 797 +stderr 797 +stdout 798 +stderr 798 +stdout 799 +stderr 799 +stdout 800 +stderr 800 +stdout 801 +stderr 801 +stdout 802 +stderr 802 +stdout 803 +stderr 803 +stdout 804 +stderr 804 +stdout 805 +stderr 805 +stdout 806 +stderr 806 +stdout 807 +stderr 807 +stdout 808 +stderr 808 +stdout 809 +stderr 809 +stdout 810 +stderr 810 +stdout 811 +stderr 811 +stdout 812 +stderr 812 +stdout 813 +stderr 813 +stdout 814 +stderr 814 +stdout 815 +stderr 815 +stdout 816 +stderr 816 +stdout 817 +stderr 817 +stdout 818 +stderr 818 +stdout 819 +stderr 819 +stdout 820 +stderr 820 +stdout 821 +stderr 821 +stdout 822 +stderr 822 +stdout 823 +stderr 823 +stdout 824 +stderr 824 +stdout 825 +stderr 825 +stdout 826 +stderr 826 +stdout 827 +stderr 827 +stdout 828 +stderr 828 +stdout 829 +stderr 829 +stdout 830 +stderr 830 +stdout 831 +stderr 831 +stdout 832 +stderr 832 +stdout 833 +stderr 833 +stdout 834 +stderr 834 +stdout 835 +stderr 835 +stdout 836 +stderr 836 +stdout 837 +stderr 837 +stdout 838 +stderr 838 +stdout 839 +stderr 839 +stdout 840 +stderr 840 +stdout 841 +stderr 841 +stdout 842 +stderr 842 +stdout 843 +stderr 843 +stdout 844 +stderr 844 +stdout 845 +stderr 845 +stdout 846 +stderr 846 +stdout 847 +stderr 847 +stdout 848 +stderr 848 +stdout 849 +stderr 849 +stdout 850 +stderr 850 +stdout 851 +stderr 851 +stdout 852 +stderr 852 +stdout 853 +stderr 853 +stdout 854 +stderr 854 +stdout 855 +stderr 855 +stdout 856 +stderr 856 +stdout 857 +stderr 857 +stdout 858 +stderr 858 +stdout 859 +stderr 859 +stdout 860 +stderr 860 +stdout 861 +stderr 861 +stdout 862 +stderr 862 +stdout 863 +stderr 863 +stdout 864 +stderr 864 +stdout 865 +stderr 865 +stdout 866 +stderr 866 +stdout 867 +stderr 867 +stdout 868 +stderr 868 +stdout 869 +stderr 869 +stdout 870 +stderr 870 +stdout 871 +stderr 871 +stdout 872 +stderr 872 +stdout 873 +stderr 873 +stdout 874 +stderr 874 +stdout 875 +stderr 875 +stdout 876 +stderr 876 +stdout 877 +stderr 877 +stdout 878 +stderr 878 +stdout 879 +stderr 879 +stdout 880 +stderr 880 +stdout 881 +stderr 881 +stdout 882 +stderr 882 +stdout 883 +stderr 883 +stdout 884 +stderr 884 +stdout 885 +stderr 885 +stdout 886 +stderr 886 +stdout 887 +stderr 887 +stdout 888 +stderr 888 +stdout 889 +stderr 889 +stdout 890 +stderr 890 +stdout 891 +stderr 891 +stdout 892 +stderr 892 +stdout 893 +stderr 893 +stdout 894 +stderr 894 +stdout 895 +stderr 895 +stdout 896 +stderr 896 +stdout 897 +stderr 897 +stdout 898 +stderr 898 +stdout 899 +stderr 899 +stdout 900 +stderr 900 +stdout 901 +stderr 901 +stdout 902 +stderr 902 +stdout 903 +stderr 903 +stdout 904 +stderr 904 +stdout 905 +stderr 905 +stdout 906 +stderr 906 +stdout 907 +stderr 907 +stdout 908 +stderr 908 +stdout 909 +stderr 909 +stdout 910 +stderr 910 +stdout 911 +stderr 911 +stdout 912 +stderr 912 +stdout 913 +stderr 913 +stdout 914 +stderr 914 +stdout 915 +stderr 915 +stdout 916 +stderr 916 +stdout 917 +stderr 917 +stdout 918 +stderr 918 +stdout 919 +stderr 919 +stdout 920 +stderr 920 +stdout 921 +stderr 921 +stdout 922 +stderr 922 +stdout 923 +stderr 923 +stdout 924 +stderr 924 +stdout 925 +stderr 925 +stdout 926 +stderr 926 +stdout 927 +stderr 927 +stdout 928 +stderr 928 +stdout 929 +stderr 929 +stdout 930 +stderr 930 +stdout 931 +stderr 931 +stdout 932 +stderr 932 +stdout 933 +stderr 933 +stdout 934 +stderr 934 +stdout 935 +stderr 935 +stdout 936 +stderr 936 +stdout 937 +stderr 937 +stdout 938 +stderr 938 +stdout 939 +stderr 939 +stdout 940 +stderr 940 +stdout 941 +stderr 941 +stdout 942 +stderr 942 +stdout 943 +stderr 943 +stdout 944 +stderr 944 +stdout 945 +stderr 945 +stdout 946 +stderr 946 +stdout 947 +stderr 947 +stdout 948 +stderr 948 +stdout 949 +stderr 949 +stdout 950 +stderr 950 +stdout 951 +stderr 951 +stdout 952 +stderr 952 +stdout 953 +stderr 953 +stdout 954 +stderr 954 +stdout 955 +stderr 955 +stdout 956 +stderr 956 +stdout 957 +stderr 957 +stdout 958 +stderr 958 +stdout 959 +stderr 959 +stdout 960 +stderr 960 +stdout 961 +stderr 961 +stdout 962 +stderr 962 +stdout 963 +stderr 963 +stdout 964 +stderr 964 +stdout 965 +stderr 965 +stdout 966 +stderr 966 +stdout 967 +stderr 967 +stdout 968 +stderr 968 +stdout 969 +stderr 969 +stdout 970 +stderr 970 +stdout 971 +stderr 971 +stdout 972 +stderr 972 +stdout 973 +stderr 973 +stdout 974 +stderr 974 +stdout 975 +stderr 975 +stdout 976 +stderr 976 +stdout 977 +stderr 977 +stdout 978 +stderr 978 +stdout 979 +stderr 979 +stdout 980 +stderr 980 +stdout 981 +stderr 981 +stdout 982 +stderr 982 +stdout 983 +stderr 983 +stdout 984 +stderr 984 +stdout 985 +stderr 985 +stdout 986 +stderr 986 +stdout 987 +stderr 987 +stdout 988 +stderr 988 +stdout 989 +stderr 989 +stdout 990 +stderr 990 +stdout 991 +stderr 991 +stdout 992 +stderr 992 +stdout 993 +stderr 993 +stdout 994 +stderr 994 +stdout 995 +stderr 995 +stdout 996 +stderr 996 +stdout 997 +stderr 997 +stdout 998 +stderr 998 +stdout 999 +stderr 999 diff --git a/node_modules/exit/test/fixtures/1000-stdout.txt b/node_modules/exit/test/fixtures/1000-stdout.txt new file mode 100644 index 0000000..d3649d0 --- /dev/null +++ b/node_modules/exit/test/fixtures/1000-stdout.txt @@ -0,0 +1,1000 @@ +stdout 0 +stdout 1 +stdout 2 +stdout 3 +stdout 4 +stdout 5 +stdout 6 +stdout 7 +stdout 8 +stdout 9 +stdout 10 +stdout 11 +stdout 12 +stdout 13 +stdout 14 +stdout 15 +stdout 16 +stdout 17 +stdout 18 +stdout 19 +stdout 20 +stdout 21 +stdout 22 +stdout 23 +stdout 24 +stdout 25 +stdout 26 +stdout 27 +stdout 28 +stdout 29 +stdout 30 +stdout 31 +stdout 32 +stdout 33 +stdout 34 +stdout 35 +stdout 36 +stdout 37 +stdout 38 +stdout 39 +stdout 40 +stdout 41 +stdout 42 +stdout 43 +stdout 44 +stdout 45 +stdout 46 +stdout 47 +stdout 48 +stdout 49 +stdout 50 +stdout 51 +stdout 52 +stdout 53 +stdout 54 +stdout 55 +stdout 56 +stdout 57 +stdout 58 +stdout 59 +stdout 60 +stdout 61 +stdout 62 +stdout 63 +stdout 64 +stdout 65 +stdout 66 +stdout 67 +stdout 68 +stdout 69 +stdout 70 +stdout 71 +stdout 72 +stdout 73 +stdout 74 +stdout 75 +stdout 76 +stdout 77 +stdout 78 +stdout 79 +stdout 80 +stdout 81 +stdout 82 +stdout 83 +stdout 84 +stdout 85 +stdout 86 +stdout 87 +stdout 88 +stdout 89 +stdout 90 +stdout 91 +stdout 92 +stdout 93 +stdout 94 +stdout 95 +stdout 96 +stdout 97 +stdout 98 +stdout 99 +stdout 100 +stdout 101 +stdout 102 +stdout 103 +stdout 104 +stdout 105 +stdout 106 +stdout 107 +stdout 108 +stdout 109 +stdout 110 +stdout 111 +stdout 112 +stdout 113 +stdout 114 +stdout 115 +stdout 116 +stdout 117 +stdout 118 +stdout 119 +stdout 120 +stdout 121 +stdout 122 +stdout 123 +stdout 124 +stdout 125 +stdout 126 +stdout 127 +stdout 128 +stdout 129 +stdout 130 +stdout 131 +stdout 132 +stdout 133 +stdout 134 +stdout 135 +stdout 136 +stdout 137 +stdout 138 +stdout 139 +stdout 140 +stdout 141 +stdout 142 +stdout 143 +stdout 144 +stdout 145 +stdout 146 +stdout 147 +stdout 148 +stdout 149 +stdout 150 +stdout 151 +stdout 152 +stdout 153 +stdout 154 +stdout 155 +stdout 156 +stdout 157 +stdout 158 +stdout 159 +stdout 160 +stdout 161 +stdout 162 +stdout 163 +stdout 164 +stdout 165 +stdout 166 +stdout 167 +stdout 168 +stdout 169 +stdout 170 +stdout 171 +stdout 172 +stdout 173 +stdout 174 +stdout 175 +stdout 176 +stdout 177 +stdout 178 +stdout 179 +stdout 180 +stdout 181 +stdout 182 +stdout 183 +stdout 184 +stdout 185 +stdout 186 +stdout 187 +stdout 188 +stdout 189 +stdout 190 +stdout 191 +stdout 192 +stdout 193 +stdout 194 +stdout 195 +stdout 196 +stdout 197 +stdout 198 +stdout 199 +stdout 200 +stdout 201 +stdout 202 +stdout 203 +stdout 204 +stdout 205 +stdout 206 +stdout 207 +stdout 208 +stdout 209 +stdout 210 +stdout 211 +stdout 212 +stdout 213 +stdout 214 +stdout 215 +stdout 216 +stdout 217 +stdout 218 +stdout 219 +stdout 220 +stdout 221 +stdout 222 +stdout 223 +stdout 224 +stdout 225 +stdout 226 +stdout 227 +stdout 228 +stdout 229 +stdout 230 +stdout 231 +stdout 232 +stdout 233 +stdout 234 +stdout 235 +stdout 236 +stdout 237 +stdout 238 +stdout 239 +stdout 240 +stdout 241 +stdout 242 +stdout 243 +stdout 244 +stdout 245 +stdout 246 +stdout 247 +stdout 248 +stdout 249 +stdout 250 +stdout 251 +stdout 252 +stdout 253 +stdout 254 +stdout 255 +stdout 256 +stdout 257 +stdout 258 +stdout 259 +stdout 260 +stdout 261 +stdout 262 +stdout 263 +stdout 264 +stdout 265 +stdout 266 +stdout 267 +stdout 268 +stdout 269 +stdout 270 +stdout 271 +stdout 272 +stdout 273 +stdout 274 +stdout 275 +stdout 276 +stdout 277 +stdout 278 +stdout 279 +stdout 280 +stdout 281 +stdout 282 +stdout 283 +stdout 284 +stdout 285 +stdout 286 +stdout 287 +stdout 288 +stdout 289 +stdout 290 +stdout 291 +stdout 292 +stdout 293 +stdout 294 +stdout 295 +stdout 296 +stdout 297 +stdout 298 +stdout 299 +stdout 300 +stdout 301 +stdout 302 +stdout 303 +stdout 304 +stdout 305 +stdout 306 +stdout 307 +stdout 308 +stdout 309 +stdout 310 +stdout 311 +stdout 312 +stdout 313 +stdout 314 +stdout 315 +stdout 316 +stdout 317 +stdout 318 +stdout 319 +stdout 320 +stdout 321 +stdout 322 +stdout 323 +stdout 324 +stdout 325 +stdout 326 +stdout 327 +stdout 328 +stdout 329 +stdout 330 +stdout 331 +stdout 332 +stdout 333 +stdout 334 +stdout 335 +stdout 336 +stdout 337 +stdout 338 +stdout 339 +stdout 340 +stdout 341 +stdout 342 +stdout 343 +stdout 344 +stdout 345 +stdout 346 +stdout 347 +stdout 348 +stdout 349 +stdout 350 +stdout 351 +stdout 352 +stdout 353 +stdout 354 +stdout 355 +stdout 356 +stdout 357 +stdout 358 +stdout 359 +stdout 360 +stdout 361 +stdout 362 +stdout 363 +stdout 364 +stdout 365 +stdout 366 +stdout 367 +stdout 368 +stdout 369 +stdout 370 +stdout 371 +stdout 372 +stdout 373 +stdout 374 +stdout 375 +stdout 376 +stdout 377 +stdout 378 +stdout 379 +stdout 380 +stdout 381 +stdout 382 +stdout 383 +stdout 384 +stdout 385 +stdout 386 +stdout 387 +stdout 388 +stdout 389 +stdout 390 +stdout 391 +stdout 392 +stdout 393 +stdout 394 +stdout 395 +stdout 396 +stdout 397 +stdout 398 +stdout 399 +stdout 400 +stdout 401 +stdout 402 +stdout 403 +stdout 404 +stdout 405 +stdout 406 +stdout 407 +stdout 408 +stdout 409 +stdout 410 +stdout 411 +stdout 412 +stdout 413 +stdout 414 +stdout 415 +stdout 416 +stdout 417 +stdout 418 +stdout 419 +stdout 420 +stdout 421 +stdout 422 +stdout 423 +stdout 424 +stdout 425 +stdout 426 +stdout 427 +stdout 428 +stdout 429 +stdout 430 +stdout 431 +stdout 432 +stdout 433 +stdout 434 +stdout 435 +stdout 436 +stdout 437 +stdout 438 +stdout 439 +stdout 440 +stdout 441 +stdout 442 +stdout 443 +stdout 444 +stdout 445 +stdout 446 +stdout 447 +stdout 448 +stdout 449 +stdout 450 +stdout 451 +stdout 452 +stdout 453 +stdout 454 +stdout 455 +stdout 456 +stdout 457 +stdout 458 +stdout 459 +stdout 460 +stdout 461 +stdout 462 +stdout 463 +stdout 464 +stdout 465 +stdout 466 +stdout 467 +stdout 468 +stdout 469 +stdout 470 +stdout 471 +stdout 472 +stdout 473 +stdout 474 +stdout 475 +stdout 476 +stdout 477 +stdout 478 +stdout 479 +stdout 480 +stdout 481 +stdout 482 +stdout 483 +stdout 484 +stdout 485 +stdout 486 +stdout 487 +stdout 488 +stdout 489 +stdout 490 +stdout 491 +stdout 492 +stdout 493 +stdout 494 +stdout 495 +stdout 496 +stdout 497 +stdout 498 +stdout 499 +stdout 500 +stdout 501 +stdout 502 +stdout 503 +stdout 504 +stdout 505 +stdout 506 +stdout 507 +stdout 508 +stdout 509 +stdout 510 +stdout 511 +stdout 512 +stdout 513 +stdout 514 +stdout 515 +stdout 516 +stdout 517 +stdout 518 +stdout 519 +stdout 520 +stdout 521 +stdout 522 +stdout 523 +stdout 524 +stdout 525 +stdout 526 +stdout 527 +stdout 528 +stdout 529 +stdout 530 +stdout 531 +stdout 532 +stdout 533 +stdout 534 +stdout 535 +stdout 536 +stdout 537 +stdout 538 +stdout 539 +stdout 540 +stdout 541 +stdout 542 +stdout 543 +stdout 544 +stdout 545 +stdout 546 +stdout 547 +stdout 548 +stdout 549 +stdout 550 +stdout 551 +stdout 552 +stdout 553 +stdout 554 +stdout 555 +stdout 556 +stdout 557 +stdout 558 +stdout 559 +stdout 560 +stdout 561 +stdout 562 +stdout 563 +stdout 564 +stdout 565 +stdout 566 +stdout 567 +stdout 568 +stdout 569 +stdout 570 +stdout 571 +stdout 572 +stdout 573 +stdout 574 +stdout 575 +stdout 576 +stdout 577 +stdout 578 +stdout 579 +stdout 580 +stdout 581 +stdout 582 +stdout 583 +stdout 584 +stdout 585 +stdout 586 +stdout 587 +stdout 588 +stdout 589 +stdout 590 +stdout 591 +stdout 592 +stdout 593 +stdout 594 +stdout 595 +stdout 596 +stdout 597 +stdout 598 +stdout 599 +stdout 600 +stdout 601 +stdout 602 +stdout 603 +stdout 604 +stdout 605 +stdout 606 +stdout 607 +stdout 608 +stdout 609 +stdout 610 +stdout 611 +stdout 612 +stdout 613 +stdout 614 +stdout 615 +stdout 616 +stdout 617 +stdout 618 +stdout 619 +stdout 620 +stdout 621 +stdout 622 +stdout 623 +stdout 624 +stdout 625 +stdout 626 +stdout 627 +stdout 628 +stdout 629 +stdout 630 +stdout 631 +stdout 632 +stdout 633 +stdout 634 +stdout 635 +stdout 636 +stdout 637 +stdout 638 +stdout 639 +stdout 640 +stdout 641 +stdout 642 +stdout 643 +stdout 644 +stdout 645 +stdout 646 +stdout 647 +stdout 648 +stdout 649 +stdout 650 +stdout 651 +stdout 652 +stdout 653 +stdout 654 +stdout 655 +stdout 656 +stdout 657 +stdout 658 +stdout 659 +stdout 660 +stdout 661 +stdout 662 +stdout 663 +stdout 664 +stdout 665 +stdout 666 +stdout 667 +stdout 668 +stdout 669 +stdout 670 +stdout 671 +stdout 672 +stdout 673 +stdout 674 +stdout 675 +stdout 676 +stdout 677 +stdout 678 +stdout 679 +stdout 680 +stdout 681 +stdout 682 +stdout 683 +stdout 684 +stdout 685 +stdout 686 +stdout 687 +stdout 688 +stdout 689 +stdout 690 +stdout 691 +stdout 692 +stdout 693 +stdout 694 +stdout 695 +stdout 696 +stdout 697 +stdout 698 +stdout 699 +stdout 700 +stdout 701 +stdout 702 +stdout 703 +stdout 704 +stdout 705 +stdout 706 +stdout 707 +stdout 708 +stdout 709 +stdout 710 +stdout 711 +stdout 712 +stdout 713 +stdout 714 +stdout 715 +stdout 716 +stdout 717 +stdout 718 +stdout 719 +stdout 720 +stdout 721 +stdout 722 +stdout 723 +stdout 724 +stdout 725 +stdout 726 +stdout 727 +stdout 728 +stdout 729 +stdout 730 +stdout 731 +stdout 732 +stdout 733 +stdout 734 +stdout 735 +stdout 736 +stdout 737 +stdout 738 +stdout 739 +stdout 740 +stdout 741 +stdout 742 +stdout 743 +stdout 744 +stdout 745 +stdout 746 +stdout 747 +stdout 748 +stdout 749 +stdout 750 +stdout 751 +stdout 752 +stdout 753 +stdout 754 +stdout 755 +stdout 756 +stdout 757 +stdout 758 +stdout 759 +stdout 760 +stdout 761 +stdout 762 +stdout 763 +stdout 764 +stdout 765 +stdout 766 +stdout 767 +stdout 768 +stdout 769 +stdout 770 +stdout 771 +stdout 772 +stdout 773 +stdout 774 +stdout 775 +stdout 776 +stdout 777 +stdout 778 +stdout 779 +stdout 780 +stdout 781 +stdout 782 +stdout 783 +stdout 784 +stdout 785 +stdout 786 +stdout 787 +stdout 788 +stdout 789 +stdout 790 +stdout 791 +stdout 792 +stdout 793 +stdout 794 +stdout 795 +stdout 796 +stdout 797 +stdout 798 +stdout 799 +stdout 800 +stdout 801 +stdout 802 +stdout 803 +stdout 804 +stdout 805 +stdout 806 +stdout 807 +stdout 808 +stdout 809 +stdout 810 +stdout 811 +stdout 812 +stdout 813 +stdout 814 +stdout 815 +stdout 816 +stdout 817 +stdout 818 +stdout 819 +stdout 820 +stdout 821 +stdout 822 +stdout 823 +stdout 824 +stdout 825 +stdout 826 +stdout 827 +stdout 828 +stdout 829 +stdout 830 +stdout 831 +stdout 832 +stdout 833 +stdout 834 +stdout 835 +stdout 836 +stdout 837 +stdout 838 +stdout 839 +stdout 840 +stdout 841 +stdout 842 +stdout 843 +stdout 844 +stdout 845 +stdout 846 +stdout 847 +stdout 848 +stdout 849 +stdout 850 +stdout 851 +stdout 852 +stdout 853 +stdout 854 +stdout 855 +stdout 856 +stdout 857 +stdout 858 +stdout 859 +stdout 860 +stdout 861 +stdout 862 +stdout 863 +stdout 864 +stdout 865 +stdout 866 +stdout 867 +stdout 868 +stdout 869 +stdout 870 +stdout 871 +stdout 872 +stdout 873 +stdout 874 +stdout 875 +stdout 876 +stdout 877 +stdout 878 +stdout 879 +stdout 880 +stdout 881 +stdout 882 +stdout 883 +stdout 884 +stdout 885 +stdout 886 +stdout 887 +stdout 888 +stdout 889 +stdout 890 +stdout 891 +stdout 892 +stdout 893 +stdout 894 +stdout 895 +stdout 896 +stdout 897 +stdout 898 +stdout 899 +stdout 900 +stdout 901 +stdout 902 +stdout 903 +stdout 904 +stdout 905 +stdout 906 +stdout 907 +stdout 908 +stdout 909 +stdout 910 +stdout 911 +stdout 912 +stdout 913 +stdout 914 +stdout 915 +stdout 916 +stdout 917 +stdout 918 +stdout 919 +stdout 920 +stdout 921 +stdout 922 +stdout 923 +stdout 924 +stdout 925 +stdout 926 +stdout 927 +stdout 928 +stdout 929 +stdout 930 +stdout 931 +stdout 932 +stdout 933 +stdout 934 +stdout 935 +stdout 936 +stdout 937 +stdout 938 +stdout 939 +stdout 940 +stdout 941 +stdout 942 +stdout 943 +stdout 944 +stdout 945 +stdout 946 +stdout 947 +stdout 948 +stdout 949 +stdout 950 +stdout 951 +stdout 952 +stdout 953 +stdout 954 +stdout 955 +stdout 956 +stdout 957 +stdout 958 +stdout 959 +stdout 960 +stdout 961 +stdout 962 +stdout 963 +stdout 964 +stdout 965 +stdout 966 +stdout 967 +stdout 968 +stdout 969 +stdout 970 +stdout 971 +stdout 972 +stdout 973 +stdout 974 +stdout 975 +stdout 976 +stdout 977 +stdout 978 +stdout 979 +stdout 980 +stdout 981 +stdout 982 +stdout 983 +stdout 984 +stdout 985 +stdout 986 +stdout 987 +stdout 988 +stdout 989 +stdout 990 +stdout 991 +stdout 992 +stdout 993 +stdout 994 +stdout 995 +stdout 996 +stdout 997 +stdout 998 +stdout 999 diff --git a/node_modules/exit/test/fixtures/create-files.sh b/node_modules/exit/test/fixtures/create-files.sh new file mode 100644 index 0000000..6a526de --- /dev/null +++ b/node_modules/exit/test/fixtures/create-files.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +rm 10*.txt +for n in 10 100 1000; do + node log.js 0 $n stdout stderr &> $n-stdout-stderr.txt + node log.js 0 $n stdout &> $n-stdout.txt + node log.js 0 $n stderr &> $n-stderr.txt +done diff --git a/node_modules/exit/test/fixtures/log-broken.js b/node_modules/exit/test/fixtures/log-broken.js new file mode 100644 index 0000000..74c8f12 --- /dev/null +++ b/node_modules/exit/test/fixtures/log-broken.js @@ -0,0 +1,23 @@ +var errorCode = process.argv[2]; +var max = process.argv[3]; +var modes = process.argv.slice(4); + +function stdout(message) { + if (modes.indexOf('stdout') === -1) { return; } + process.stdout.write('stdout ' + message + '\n'); +} + +function stderr(message) { + if (modes.indexOf('stderr') === -1) { return; } + process.stderr.write('stderr ' + message + '\n'); +} + +for (var i = 0; i < max; i++) { + stdout(i); + stderr(i); +} + +process.exit(errorCode); + +stdout('fail'); +stderr('fail'); diff --git a/node_modules/exit/test/fixtures/log.js b/node_modules/exit/test/fixtures/log.js new file mode 100644 index 0000000..8a9ed9a --- /dev/null +++ b/node_modules/exit/test/fixtures/log.js @@ -0,0 +1,25 @@ +var exit = require('../../lib/exit'); + +var errorCode = process.argv[2]; +var max = process.argv[3]; +var modes = process.argv.slice(4); + +function stdout(message) { + if (modes.indexOf('stdout') === -1) { return; } + process.stdout.write('stdout ' + message + '\n'); +} + +function stderr(message) { + if (modes.indexOf('stderr') === -1) { return; } + process.stderr.write('stderr ' + message + '\n'); +} + +for (var i = 0; i < max; i++) { + stdout(i); + stderr(i); +} + +exit(errorCode); + +stdout('fail'); +stderr('fail'); diff --git a/node_modules/eyes/LICENSE b/node_modules/eyes/LICENSE new file mode 100644 index 0000000..a1edd93 --- /dev/null +++ b/node_modules/eyes/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2009 cloudhead + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/eyes/Makefile b/node_modules/eyes/Makefile new file mode 100644 index 0000000..a121dea --- /dev/null +++ b/node_modules/eyes/Makefile @@ -0,0 +1,4 @@ +test: + @@node test/eyes-test.js + +.PHONY: test diff --git a/node_modules/eyes/README.md b/node_modules/eyes/README.md new file mode 100644 index 0000000..c4f6f76 --- /dev/null +++ b/node_modules/eyes/README.md @@ -0,0 +1,73 @@ +eyes +==== + +a customizable value inspector for Node.js + +synopsis +-------- + +I was tired of looking at cluttered output in the console -- something needed to be done, +`sys.inspect()` didn't display regexps correctly, and was too verbose, and I had an hour or two to spare. +So I decided to have some fun. _eyes_ were born. + +![eyes-ss](http://dl.dropbox.com/u/251849/eyes-js-ss.gif) + +_example of the output of a user-customized eyes.js inspector_ + +*eyes* also deals with circular objects in an intelligent way, and can pretty-print object literals. + +usage +----- + + var inspect = require('eyes').inspector({styles: {all: 'magenta'}}); + + inspect(something); // inspect with the settings passed to `inspector` + +or + + var eyes = require('eyes'); + + eyes.inspect(something); // inspect with the default settings + +you can pass a _label_ to `inspect()`, to keep track of your inspections: + + eyes.inspect(something, "a random value"); + +If you want to return the output of eyes without printing it, you can set it up this way: + + var inspect = require('eyes').inspector({ stream: null }); + + sys.puts(inspect({ something: 42 })); + +customization +------------- + +These are the default styles and settings used by _eyes_. + + styles: { // Styles applied to stdout + all: 'cyan', // Overall style applied to everything + label: 'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]` + other: 'inverted', // Objects which don't have a literal representation, such as functions + key: 'bold', // The keys in object literals, like 'a' in `{a: 1}` + special: 'grey', // null, undefined... + string: 'green', + number: 'magenta', + bool: 'blue', // true false + regexp: 'green', // /\d+/ + }, + + pretty: true, // Indent object literals + hideFunctions: false, // Don't output functions at all + stream: process.stdout, // Stream to write to, or null + maxLength: 2048 // Truncate output if longer + +You can overwrite them with your own, by passing a similar object to `inspector()` or `inspect()`. + + var inspect = require('eyes').inspector({ + styles: { + all: 'magenta', + special: 'bold' + }, + maxLength: 512 + }); + diff --git a/node_modules/eyes/lib/eyes.js b/node_modules/eyes/lib/eyes.js new file mode 100644 index 0000000..10d964b --- /dev/null +++ b/node_modules/eyes/lib/eyes.js @@ -0,0 +1,236 @@ +// +// Eyes.js - a customizable value inspector for Node.js +// +// usage: +// +// var inspect = require('eyes').inspector({styles: {all: 'magenta'}}); +// inspect(something); // inspect with the settings passed to `inspector` +// +// or +// +// var eyes = require('eyes'); +// eyes.inspect(something); // inspect with the default settings +// +var eyes = exports, + stack = []; + +eyes.defaults = { + styles: { // Styles applied to stdout + all: 'cyan', // Overall style applied to everything + label: 'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]` + other: 'inverted', // Objects which don't have a literal representation, such as functions + key: 'bold', // The keys in object literals, like 'a' in `{a: 1}` + special: 'grey', // null, undefined... + string: 'green', + number: 'magenta', + bool: 'blue', // true false + regexp: 'green', // /\d+/ + }, + pretty: true, // Indent object literals + hideFunctions: false, + showHidden: false, + stream: process.stdout, + maxLength: 2048 // Truncate output if longer +}; + +// Return a curried inspect() function, with the `options` argument filled in. +eyes.inspector = function (options) { + var that = this; + return function (obj, label, opts) { + return that.inspect.call(that, obj, label, + merge(options || {}, opts || {})); + }; +}; + +// If we have a `stream` defined, use it to print a styled string, +// if not, we just return the stringified object. +eyes.inspect = function (obj, label, options) { + options = merge(this.defaults, options || {}); + + if (options.stream) { + return this.print(stringify(obj, options), label, options); + } else { + return stringify(obj, options) + (options.styles ? '\033[39m' : ''); + } +}; + +// Output using the 'stream', and an optional label +// Loop through `str`, and truncate it after `options.maxLength` has been reached. +// Because escape sequences are, at this point embeded within +// the output string, we can't measure the length of the string +// in a useful way, without separating what is an escape sequence, +// versus a printable character (`c`). So we resort to counting the +// length manually. +eyes.print = function (str, label, options) { + for (var c = 0, i = 0; i < str.length; i++) { + if (str.charAt(i) === '\033') { i += 4 } // `4` because '\033[25m'.length + 1 == 5 + else if (c === options.maxLength) { + str = str.slice(0, i - 1) + '…'; + break; + } else { c++ } + } + return options.stream.write.call(options.stream, (label ? + this.stylize(label, options.styles.label, options.styles) + ': ' : '') + + this.stylize(str, options.styles.all, options.styles) + '\033[0m' + "\n"); +}; + +// Apply a style to a string, eventually, +// I'd like this to support passing multiple +// styles. +eyes.stylize = function (str, style, styles) { + var codes = { + 'bold' : [1, 22], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'cyan' : [36, 39], + 'magenta' : [35, 39], + 'blue' : [34, 39], + 'yellow' : [33, 39], + 'green' : [32, 39], + 'red' : [31, 39], + 'grey' : [90, 39] + }, endCode; + + if (style && codes[style]) { + endCode = (codes[style][1] === 39 && styles.all) ? codes[styles.all][0] + : codes[style][1]; + return '\033[' + codes[style][0] + 'm' + str + + '\033[' + endCode + 'm'; + } else { return str } +}; + +// Convert any object to a string, ready for output. +// When an 'array' or an 'object' are encountered, they are +// passed to specialized functions, which can then recursively call +// stringify(). +function stringify(obj, options) { + var that = this, stylize = function (str, style) { + return eyes.stylize(str, options.styles[style], options.styles) + }, index, result; + + if ((index = stack.indexOf(obj)) !== -1) { + return stylize(new(Array)(stack.length - index + 1).join('.'), 'special'); + } + stack.push(obj); + + result = (function (obj) { + switch (typeOf(obj)) { + case "string" : obj = stringifyString(obj.indexOf("'") === -1 ? "'" + obj + "'" + : '"' + obj + '"'); + return stylize(obj, 'string'); + case "regexp" : return stylize('/' + obj.source + '/', 'regexp'); + case "number" : return stylize(obj + '', 'number'); + case "function" : return options.stream ? stylize("Function", 'other') : '[Function]'; + case "null" : return stylize("null", 'special'); + case "undefined": return stylize("undefined", 'special'); + case "boolean" : return stylize(obj + '', 'bool'); + case "date" : return stylize(obj.toUTCString()); + case "array" : return stringifyArray(obj, options, stack.length); + case "object" : return stringifyObject(obj, options, stack.length); + } + })(obj); + + stack.pop(); + return result; +}; + +// Escape invisible characters in a string +function stringifyString (str, options) { + return str.replace(/\\/g, '\\\\') + .replace(/\n/g, '\\n') + .replace(/[\u0001-\u001F]/g, function (match) { + return '\\0' + match[0].charCodeAt(0).toString(8); + }); +} + +// Convert an array to a string, such as [1, 2, 3]. +// This function calls stringify() for each of the elements +// in the array. +function stringifyArray(ary, options, level) { + var out = []; + var pretty = options.pretty && (ary.length > 4 || ary.some(function (o) { + return (o !== null && typeof(o) === 'object' && Object.keys(o).length > 0) || + (Array.isArray(o) && o.length > 0); + })); + var ws = pretty ? '\n' + new(Array)(level * 4 + 1).join(' ') : ' '; + + for (var i = 0; i < ary.length; i++) { + out.push(stringify(ary[i], options)); + } + + if (out.length === 0) { + return '[]'; + } else { + return '[' + ws + + out.join(',' + (pretty ? ws : ' ')) + + (pretty ? ws.slice(0, -4) : ws) + + ']'; + } +}; + +// Convert an object to a string, such as {a: 1}. +// This function calls stringify() for each of its values, +// and does not output functions or prototype values. +function stringifyObject(obj, options, level) { + var out = []; + var pretty = options.pretty && (Object.keys(obj).length > 2 || + Object.keys(obj).some(function (k) { return typeof(obj[k]) === 'object' })); + var ws = pretty ? '\n' + new(Array)(level * 4 + 1).join(' ') : ' '; + + var keys = options.showHidden ? Object.keys(obj) : Object.getOwnPropertyNames(obj); + keys.forEach(function (k) { + if (Object.prototype.hasOwnProperty.call(obj, k) + && !(obj[k] instanceof Function && options.hideFunctions)) { + out.push(eyes.stylize(k, options.styles.key, options.styles) + ': ' + + stringify(obj[k], options)); + } + }); + + if (out.length === 0) { + return '{}'; + } else { + return "{" + ws + + out.join(',' + (pretty ? ws : ' ')) + + (pretty ? ws.slice(0, -4) : ws) + + "}"; + } +}; + +// A better `typeof` +function typeOf(value) { + var s = typeof(value), + types = [Object, Array, String, RegExp, Number, Function, Boolean, Date]; + + if (s === 'object' || s === 'function') { + if (value) { + types.forEach(function (t) { + if (value instanceof t) { s = t.name.toLowerCase() } + }); + } else { s = 'null' } + } + return s; +} + +function merge(/* variable args */) { + var objs = Array.prototype.slice.call(arguments); + var target = {}; + + objs.forEach(function (o) { + Object.keys(o).forEach(function (k) { + if (k === 'styles') { + if (! o.styles) { + target.styles = false; + } else { + target.styles = {} + for (var s in o.styles) { + target.styles[s] = o.styles[s]; + } + } + } else { + target[k] = o[k]; + } + }); + }); + return target; +} + diff --git a/node_modules/eyes/package.json b/node_modules/eyes/package.json new file mode 100644 index 0000000..0c165f9 --- /dev/null +++ b/node_modules/eyes/package.json @@ -0,0 +1,95 @@ +{ + "_args": [ + [ + { + "raw": "eyes@0.1.x", + "scope": null, + "escapedName": "eyes", + "name": "eyes", + "rawSpec": "0.1.x", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/winston" + ] + ], + "_from": "eyes@>=0.1.0 <0.2.0", + "_id": "eyes@0.1.8", + "_inCache": true, + "_location": "/eyes", + "_npmUser": { + "name": "indexzero", + "email": "charlie.robbins@gmail.com" + }, + "_npmVersion": "1.1.53", + "_phantomChildren": {}, + "_requested": { + "raw": "eyes@0.1.x", + "scope": null, + "escapedName": "eyes", + "name": "eyes", + "rawSpec": "0.1.x", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/winston" + ], + "_resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "_shasum": "62cf120234c683785d902348a800ef3e0cc20bc0", + "_shrinkwrap": null, + "_spec": "eyes@0.1.x", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/winston", + "author": { + "name": "Alexis Sellier", + "email": "self@cloudhead.net" + }, + "contributors": [ + { + "name": "Charlie Robbins", + "email": "charlie@nodejitsu.com" + } + ], + "dependencies": {}, + "description": "a customizable value inspector", + "devDependencies": {}, + "directories": { + "lib": "./lib", + "test": "./test" + }, + "dist": { + "shasum": "62cf120234c683785d902348a800ef3e0cc20bc0", + "tarball": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz" + }, + "engines": { + "node": "> 0.1.90" + }, + "keywords": [ + "inspector", + "debug", + "inspect", + "print" + ], + "licenses": [ + "MIT" + ], + "main": "./lib/eyes", + "maintainers": [ + { + "name": "cloudhead", + "email": "self@cloudhead.net" + }, + { + "name": "indexzero", + "email": "charlie.robbins@gmail.com" + } + ], + "name": "eyes", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "scripts": { + "test": "node test/*-test.js" + }, + "url": "http://github.com/cloudhead/eyes.js", + "version": "0.1.8" +} diff --git a/node_modules/eyes/test/eyes-test.js b/node_modules/eyes/test/eyes-test.js new file mode 100644 index 0000000..1f9606a --- /dev/null +++ b/node_modules/eyes/test/eyes-test.js @@ -0,0 +1,56 @@ +var util = require('util'); +var eyes = require('../lib/eyes'); + +eyes.inspect({ + number: 42, + string: "John Galt", + regexp: /[a-z]+/, + array: [99, 168, 'x', {}], + func: function () {}, + bool: false, + nil: null, + undef: undefined, + object: {attr: []} +}, "native types"); + +eyes.inspect({ + number: new(Number)(42), + string: new(String)("John Galt"), + regexp: new(RegExp)(/[a-z]+/), + array: new(Array)(99, 168, 'x', {}), + bool: new(Boolean)(false), + object: new(Object)({attr: []}), + date: new(Date) +}, "wrapped types"); + +var obj = {}; +obj.that = { self: obj }; +obj.self = obj; + +eyes.inspect(obj, "circular object"); +eyes.inspect({hello: 'moto'}, "small object"); +eyes.inspect({hello: new(Array)(6) }, "big object"); +eyes.inspect(["hello 'world'", 'hello "world"'], "quotes"); +eyes.inspect({ + recommendations: [{ + id: 'a7a6576c2c822c8e2bd81a27e41437d8', + key: [ 'spree', 3.764316258020699 ], + value: { + _id: 'a7a6576c2c822c8e2bd81a27e41437d8', + _rev: '1-2e2d2f7fd858c4a5984bcf809d22ed98', + type: 'domain', + domain: 'spree', + weight: 3.764316258020699, + product_id: 30 + } + }] +}, 'complex'); + +eyes.inspect([null], "null in array"); + +var inspect = eyes.inspector({ stream: null }); + +util.puts(inspect('something', "something")); +util.puts(inspect("something else")); + +util.puts(inspect(["no color"], null, { styles: false })); diff --git a/node_modules/figures/index.js b/node_modules/figures/index.js new file mode 100644 index 0000000..090af2a --- /dev/null +++ b/node_modules/figures/index.js @@ -0,0 +1,147 @@ +'use strict'; +var objectAssign = require('object-assign'); +var escapeStringRegexp = require('escape-string-regexp'); +var platform = process.platform; + +var main = { + tick: '✔', + cross: '✖', + star: '★', + square: '▇', + squareSmall: '◻', + squareSmallFilled: '◼', + play: '▶', + circle: '◯', + circleFilled: '◉', + circleDotted: '◌', + circleDouble: '◎', + circleCircle: 'ⓞ', + circleCross: 'ⓧ', + circlePipe: 'Ⓘ', + circleQuestionMark: '?⃝', + bullet: '●', + dot: '․', + line: '─', + ellipsis: '…', + pointer: '❯', + pointerSmall: '›', + info: 'ℹ', + warning: '⚠', + hamburger: '☰', + smiley: '㋡', + mustache: '෴', + heart: '♥', + arrowUp: '↑', + arrowDown: '↓', + arrowLeft: '←', + arrowRight: '→', + radioOn: '◉', + radioOff: '◯', + checkboxOn: '☒', + checkboxOff: '☐', + checkboxCircleOn: 'ⓧ', + checkboxCircleOff: 'Ⓘ', + questionMarkPrefix: '?⃝', + oneHalf: '½', + oneThird: '⅓', + oneQuarter: '¼', + oneFifth: '⅕', + oneSixth: '⅙', + oneSeventh: '⅐', + oneEighth: '⅛', + oneNinth: '⅑', + oneTenth: '⅒', + twoThirds: '⅔', + twoFifths: '⅖', + threeQuarters: '¾', + threeFifths: '⅗', + threeEighths: '⅜', + fourFifths: '⅘', + fiveSixths: '⅚', + fiveEighths: '⅝', + sevenEighths: '⅞' +}; + +var win = { + tick: '√', + cross: '×', + star: '*', + square: '█', + squareSmall: '[ ]', + squareSmallFilled: '[█]', + play: '►', + circle: '( )', + circleFilled: '(*)', + circleDotted: '( )', + circleDouble: '( )', + circleCircle: '(○)', + circleCross: '(×)', + circlePipe: '(│)', + circleQuestionMark: '(?)', + bullet: '*', + dot: '.', + line: '─', + ellipsis: '...', + pointer: '>', + pointerSmall: '»', + info: 'i', + warning: '‼', + hamburger: '≡', + smiley: '☺', + mustache: '┌─┐', + heart: main.heart, + arrowUp: main.arrowUp, + arrowDown: main.arrowDown, + arrowLeft: main.arrowLeft, + arrowRight: main.arrowRight, + radioOn: '(*)', + radioOff: '( )', + checkboxOn: '[×]', + checkboxOff: '[ ]', + checkboxCircleOn: '(×)', + checkboxCircleOff: '( )', + questionMarkPrefix: '?', + oneHalf: '1/2', + oneThird: '1/3', + oneQuarter: '1/4', + oneFifth: '1/5', + oneSixth: '1/6', + oneSeventh: '1/7', + oneEighth: '1/8', + oneNinth: '1/9', + oneTenth: '1/10', + twoThirds: '2/3', + twoFifths: '2/5', + threeQuarters: '3/4', + threeFifths: '3/5', + threeEighths: '3/8', + fourFifths: '4/5', + fiveSixths: '5/6', + fiveEighths: '5/8', + sevenEighths: '7/8' +}; + +if (platform === 'linux') { + // the main one doesn't look that good on Ubuntu + main.questionMarkPrefix = '?'; +} + +var figures = platform === 'win32' ? win : main; + +var fn = function (str) { + if (figures === main) { + return str; + } + + Object.keys(main).forEach(function (key) { + if (main[key] === figures[key]) { + return; + } + + str = str.replace(new RegExp(escapeStringRegexp(main[key]), 'g'), figures[key]); + }); + + return str; +}; + +module.exports = objectAssign(fn, figures); diff --git a/node_modules/figures/license b/node_modules/figures/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/figures/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/figures/package.json b/node_modules/figures/package.json new file mode 100644 index 0000000..949b828 --- /dev/null +++ b/node_modules/figures/package.json @@ -0,0 +1,112 @@ +{ + "_args": [ + [ + { + "raw": "figures@^1.0.1", + "scope": null, + "escapedName": "figures", + "name": "figures", + "rawSpec": "^1.0.1", + "spec": ">=1.0.1 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/maxmin" + ] + ], + "_from": "figures@>=1.0.1 <2.0.0", + "_id": "figures@1.7.0", + "_inCache": true, + "_location": "/figures", + "_nodeVersion": "4.4.2", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/figures-1.7.0.tgz_1463504380148_0.06917169434018433" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.15.0", + "_phantomChildren": {}, + "_requested": { + "raw": "figures@^1.0.1", + "scope": null, + "escapedName": "figures", + "name": "figures", + "rawSpec": "^1.0.1", + "spec": ">=1.0.1 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/maxmin" + ], + "_resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "_shasum": "cbe1e3affcf1cd44b80cadfed28dc793a9701d2e", + "_shrinkwrap": null, + "_spec": "figures@^1.0.1", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/maxmin", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/figures/issues" + }, + "dependencies": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + }, + "description": "Unicode symbols with Windows CMD fallbacks", + "devDependencies": { + "ava": "*", + "markdown-table": "^0.4.0", + "require-uncached": "^1.0.2", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "cbe1e3affcf1cd44b80cadfed28dc793a9701d2e", + "tarball": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "f5f4e3d6cccf84f2ca13d9e6b235def59afc15f7", + "homepage": "https://github.com/sindresorhus/figures#readme", + "keywords": [ + "unicode", + "cli", + "cmd", + "command-line", + "characters", + "char", + "symbol", + "symbols", + "figure", + "figures", + "fallback" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "figures", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/figures.git" + }, + "scripts": { + "make": "./makefile.js", + "test": "xo && ava" + }, + "version": "1.7.0" +} diff --git a/node_modules/figures/readme.md b/node_modules/figures/readme.md new file mode 100644 index 0000000..10ae286 --- /dev/null +++ b/node_modules/figures/readme.md @@ -0,0 +1,115 @@ +# figures [![Build Status: Linux](https://travis-ci.org/sindresorhus/figures.svg?branch=master)](https://travis-ci.org/sindresorhus/figures) [![Build status: Windows](https://ci.appveyor.com/api/projects/status/mb743hl70269be3r/branch/master?svg=true)](https://ci.appveyor.com/project/sindresorhus/figures/branch/master) + +> Unicode symbols with Windows CMD fallbacks + +[![](screenshot.png)](index.js) + +[*and more...*](index.js) + +Windows CMD only supports a [limited character set](http://en.wikipedia.org/wiki/Code_page_437). + + +## Install + +``` +$ npm install --save figures +``` + + +## Usage + +See the [source](index.js) for supported symbols. + +```js +const figures = require('figures'); + +console.log(figures('✔︎ check')); +// On real OSes: ✔︎ check +// On Windows: √ check + +console.log(figures.tick); +// On real OSes: ✔︎ +// On Windows: √ +``` + + +## API + +### figures(input) + +Returns the input with replaced fallback unicode symbols on Windows. + +All the below [figures](#figures) are attached to the main export as shown in the example above. + +#### input + +Type: `string` + +String where the unicode symbols will be replaced with fallback symbols depending on the OS. + + +## Figures + +| Name | Real OSes | Windows | +| ------------------ | :-------: | :-----: | +| tick | ✔ | √ | +| cross | ✖ | × | +| star | ★ | * | +| square | ▇ | █ | +| squareSmall | ◻ | [ ] | +| squareSmallFilled | ◼ | [█] | +| play | ▶ | ► | +| circle | ◯ | ( ) | +| circleFilled | ◉ | (*) | +| circleDotted | ◌ | ( ) | +| circleDouble | ◎ | ( ) | +| circleCircle | ⓞ | (○) | +| circleCross | ⓧ | (×) | +| circlePipe | Ⓘ | (│) | +| circleQuestionMark | ?⃝ | (?) | +| bullet | ● | * | +| dot | ․ | . | +| line | ─ | ─ | +| ellipsis | … | ... | +| pointer | ❯ | > | +| pointerSmall | › | » | +| info | ℹ | i | +| warning | ⚠ | ‼ | +| hamburger | ☰ | ≡ | +| smiley | ㋡ | ☺ | +| mustache | ෴ | ┌─┐ | +| heart | ♥ | ♥ | +| arrowUp | ↑ | ↑ | +| arrowDown | ↓ | ↓ | +| arrowLeft | ← | ← | +| arrowRight | → | → | +| radioOn | ◉ | (*) | +| radioOff | ◯ | ( ) | +| checkboxOn | ☒ | [×] | +| checkboxOff | ☐ | [ ] | +| checkboxCircleOn | ⓧ | (×) | +| checkboxCircleOff | Ⓘ | ( ) | +| questionMarkPrefix | ?⃝ | ? | +| oneHalf | ½ | 1/2 | +| oneThird | ⅓ | 1/3 | +| oneQuarter | ¼ | 1/4 | +| oneFifth | ⅕ | 1/5 | +| oneSixth | ⅙ | 1/6 | +| oneSeventh | ⅐ | 1/7 | +| oneEighth | ⅛ | 1/8 | +| oneNinth | ⅑ | 1/9 | +| oneTenth | ⅒ | 1/10 | +| twoThirds | ⅔ | 2/3 | +| twoFifths | ⅖ | 2/5 | +| threeQuarters | ¾ | 3/4 | +| threeFifths | ⅗ | 3/5 | +| threeEighths | ⅜ | 3/8 | +| fourFifths | ⅘ | 4/5 | +| fiveSixths | ⅚ | 5/6 | +| fiveEighths | ⅝ | 5/8 | +| sevenEighths | ⅞ | 7/8 | + + +## License + +MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/file-sync-cmp/.eslintrc b/node_modules/file-sync-cmp/.eslintrc new file mode 100644 index 0000000..1255f3d --- /dev/null +++ b/node_modules/file-sync-cmp/.eslintrc @@ -0,0 +1,33 @@ +# -*- yaml -*- +--- +env: + node: true + +rules: + quotes: + - 2 + - single + - avoid-escape + global-strict: + - 2 + - always + space-in-brackets: 2 + space-in-parens: 2 + space-after-keywords: + - 2 + - always + - { checkFunctionKeyword: true } + space-before-blocks: 2 + space-unary-ops: 2 + brace-style: 2 + comma-style: 2 + func-style: + - 2 + - declaration + no-lonely-if: 2 + no-trailing-spaces: 2 + no-multiple-empty-lines: 2 + max-len: 2 + padded-blocks: + - 2 + - never diff --git a/node_modules/file-sync-cmp/.npmignore b/node_modules/file-sync-cmp/.npmignore new file mode 100644 index 0000000..50a0c39 --- /dev/null +++ b/node_modules/file-sync-cmp/.npmignore @@ -0,0 +1,2 @@ +*~ +node_modules/ diff --git a/node_modules/file-sync-cmp/.travis.yml b/node_modules/file-sync-cmp/.travis.yml new file mode 100644 index 0000000..587bd3e --- /dev/null +++ b/node_modules/file-sync-cmp/.travis.yml @@ -0,0 +1 @@ +language: node_js diff --git a/node_modules/file-sync-cmp/LICENSE b/node_modules/file-sync-cmp/LICENSE new file mode 100644 index 0000000..dd78f7e --- /dev/null +++ b/node_modules/file-sync-cmp/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014 Martin Geisler + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/node_modules/file-sync-cmp/README.md b/node_modules/file-sync-cmp/README.md new file mode 100644 index 0000000..3ab9201 --- /dev/null +++ b/node_modules/file-sync-cmp/README.md @@ -0,0 +1,14 @@ +file-sync-cmp +============= + +[![Build Status](https://travis-ci.org/mgeisler/file-sync-cmp.svg?branch=master)](https://travis-ci.org/mgeisler/file-sync-cmp) + +Synchronous file comparison for Node.js. + + +Release History +--------------- + +* 0.1.1 (2015-02-22): Close file descriptors after comparison. + +* 0.1.0 (2014-12-14): First public release. diff --git a/node_modules/file-sync-cmp/index.js b/node_modules/file-sync-cmp/index.js new file mode 100644 index 0000000..f386657 --- /dev/null +++ b/node_modules/file-sync-cmp/index.js @@ -0,0 +1,37 @@ +'use strict'; + +var fs = require('fs'); + +var BUF_SIZE = 16 * 1024; + +/* Compare two files by content. */ +function equalFiles(pathA, pathB) { + var statA = fs.lstatSync(pathA); + var statB = fs.lstatSync(pathB); + if (statA.size !== statB.size) { + return false; + } + var fdA = fs.openSync(pathA, 'r'); + var fdB = fs.openSync(pathB, 'r'); + var bufA = new Buffer(BUF_SIZE); + var bufB = new Buffer(BUF_SIZE); + var readA = 1; + var readB = 1; + while (readA > 0) { + readA = fs.readSync(fdA, bufA, 0, bufA.length, null); + readB = fs.readSync(fdB, bufB, 0, bufB.length, null); + if (readA !== readB) { + return false; + } + for (var i = 0; i < readA; i++) { + if (bufA[i] !== bufB[i]) { + return false; + } + } + } + fs.closeSync(fdA); + fs.closeSync(fdB); + return true; +} + +module.exports.equalFiles = equalFiles; diff --git a/node_modules/file-sync-cmp/package.json b/node_modules/file-sync-cmp/package.json new file mode 100644 index 0000000..b050319 --- /dev/null +++ b/node_modules/file-sync-cmp/package.json @@ -0,0 +1,88 @@ +{ + "_args": [ + [ + { + "raw": "file-sync-cmp@^0.1.0", + "scope": null, + "escapedName": "file-sync-cmp", + "name": "file-sync-cmp", + "rawSpec": "^0.1.0", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt-contrib-copy" + ] + ], + "_from": "file-sync-cmp@>=0.1.0 <0.2.0", + "_id": "file-sync-cmp@0.1.1", + "_inCache": true, + "_location": "/file-sync-cmp", + "_npmUser": { + "name": "mgeisler", + "email": "martin@geisler.net" + }, + "_npmVersion": "1.4.21", + "_phantomChildren": {}, + "_requested": { + "raw": "file-sync-cmp@^0.1.0", + "scope": null, + "escapedName": "file-sync-cmp", + "name": "file-sync-cmp", + "rawSpec": "^0.1.0", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt-contrib-copy" + ], + "_resolved": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz", + "_shasum": "a5e7a8ffbfa493b43b923bbd4ca89a53b63b612b", + "_shrinkwrap": null, + "_spec": "file-sync-cmp@^0.1.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt-contrib-copy", + "author": { + "name": "Martin Geisler", + "email": "martin@geisler.net", + "url": "http://geisler.net/" + }, + "bugs": { + "url": "https://github.com/mgeisler/file-sync-cmp/issues" + }, + "dependencies": {}, + "description": "Synchronous file comparison", + "devDependencies": { + "eslint": "0.10.1", + "mocha": "2.0.1", + "q": "1.1.2", + "tmp": "0.0.24" + }, + "directories": {}, + "dist": { + "shasum": "a5e7a8ffbfa493b43b923bbd4ca89a53b63b612b", + "tarball": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz" + }, + "gitHead": "1cf1e51b84378e702e21330213f5bed7b1e3ab79", + "homepage": "https://github.com/mgeisler/file-sync-cmp/", + "keywords": [ + "comparison" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "mgeisler", + "email": "martin@geisler.net" + } + ], + "name": "file-sync-cmp", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/mgeisler/file-sync-cmp.git" + }, + "scripts": { + "test": "eslint . && mocha" + }, + "version": "0.1.1" +} diff --git a/node_modules/file-sync-cmp/test/.eslintrc b/node_modules/file-sync-cmp/test/.eslintrc new file mode 100644 index 0000000..efac5a1 --- /dev/null +++ b/node_modules/file-sync-cmp/test/.eslintrc @@ -0,0 +1,7 @@ +# -*- yaml -*- +--- +globals: + afterEach: false + beforeEach: false + describe: false + it: false diff --git a/node_modules/file-sync-cmp/test/test.js b/node_modules/file-sync-cmp/test/test.js new file mode 100644 index 0000000..9a71723 --- /dev/null +++ b/node_modules/file-sync-cmp/test/test.js @@ -0,0 +1,54 @@ +'use strict'; + +var fileSyncCmp = require('../'); + +var assert = require('assert'); +var fs = require('fs'); + +var tmp = require('tmp'); +tmp.setGracefulCleanup(); + +var Q = require('q'); + +var fsWrite = Q.nfbind(fs.write); +var tmpFile = Q.nfbind(tmp.file); + +function write (fd, buf) { + return fsWrite(fd, buf, 0, buf.length, null); +} + + +describe('equalFiles', function () { + var pathA, pathB; + var fdA, fdB; + + beforeEach(function () { + return Q.all([tmpFile(), tmpFile()]).spread(function (a, b) { + pathA = a[0]; + pathB = b[0]; + fdA = a[1]; + fdB = b[1]; + }); + }); + + it('should handle empty files', function () { + assert(fileSyncCmp.equalFiles(pathA, pathB)); + }); + + it('should handle equal content', function () { + var buf = new Buffer('File content\n'); + var writes = [write(fdA, buf), write(fdB, buf)]; + return Q.all(writes).then(function () { + assert(fileSyncCmp.equalFiles(pathA, pathB)); + }); + }); + + it('should handle non-equal content', function () { + var bufA = new Buffer('Some text\n'); + var bufB = new Buffer('Other text\n'); + var writes = [write(fdA, bufA), write(fdB, bufB)]; + return Q.all(writes).then(function () { + assert(!fileSyncCmp.equalFiles(pathA, pathB)); + }); + }); +}); diff --git a/node_modules/find-up/index.js b/node_modules/find-up/index.js new file mode 100644 index 0000000..7ff0e2b --- /dev/null +++ b/node_modules/find-up/index.js @@ -0,0 +1,53 @@ +'use strict'; +var path = require('path'); +var pathExists = require('path-exists'); +var Promise = require('pinkie-promise'); + +function splitPath(x) { + return path.resolve(x || '').split(path.sep); +} + +function join(parts, filename) { + return path.resolve(parts.join(path.sep) + path.sep, filename); +} + +module.exports = function (filename, opts) { + opts = opts || {}; + + var parts = splitPath(opts.cwd); + + return new Promise(function (resolve) { + (function find() { + var fp = join(parts, filename); + + pathExists(fp).then(function (exists) { + if (exists) { + resolve(fp); + } else if (parts.pop()) { + find(); + } else { + resolve(null); + } + }); + })(); + }); +}; + +module.exports.sync = function (filename, opts) { + opts = opts || {}; + + var parts = splitPath(opts.cwd); + var len = parts.length; + + while (len--) { + var fp = join(parts, filename); + + if (pathExists.sync(fp)) { + return fp; + } + + parts.pop(); + } + + return null; +}; diff --git a/node_modules/find-up/license b/node_modules/find-up/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/find-up/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/find-up/package.json b/node_modules/find-up/package.json new file mode 100644 index 0000000..42221fb --- /dev/null +++ b/node_modules/find-up/package.json @@ -0,0 +1,118 @@ +{ + "_args": [ + [ + { + "raw": "find-up@^1.0.0", + "scope": null, + "escapedName": "find-up", + "name": "find-up", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/read-pkg-up" + ] + ], + "_from": "find-up@>=1.0.0 <2.0.0", + "_id": "find-up@1.1.2", + "_inCache": true, + "_location": "/find-up", + "_nodeVersion": "4.3.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/find-up-1.1.2.tgz_1457199955637_0.3445317060686648" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.14.12", + "_phantomChildren": {}, + "_requested": { + "raw": "find-up@^1.0.0", + "scope": null, + "escapedName": "find-up", + "name": "find-up", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/read-pkg-up" + ], + "_resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "_shasum": "6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f", + "_shrinkwrap": null, + "_spec": "find-up@^1.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/read-pkg-up", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/find-up/issues" + }, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "description": "Find a file by walking up parent directories", + "devDependencies": { + "ava": "*", + "tempfile": "^1.1.1", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f", + "tarball": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "f2d7c1ff74fbac82b2cff038e311ef4b075d9184", + "homepage": "https://github.com/sindresorhus/find-up", + "keywords": [ + "find", + "up", + "find-up", + "findup", + "look-up", + "look", + "file", + "search", + "match", + "package", + "resolve", + "parent", + "parents", + "folder", + "directory", + "dir", + "walk", + "walking", + "path" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "find-up", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/find-up.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "1.1.2" +} diff --git a/node_modules/find-up/readme.md b/node_modules/find-up/readme.md new file mode 100644 index 0000000..9ea0611 --- /dev/null +++ b/node_modules/find-up/readme.md @@ -0,0 +1,72 @@ +# find-up [![Build Status](https://travis-ci.org/sindresorhus/find-up.svg?branch=master)](https://travis-ci.org/sindresorhus/find-up) + +> Find a file by walking up parent directories + + +## Install + +``` +$ npm install --save find-up +``` + + +## Usage + +``` +/ +└── Users + └── sindresorhus + ├── unicorn.png + └── foo + └── bar + ├── baz + └── example.js +``` + +```js +// example.js +const findUp = require('find-up'); + +findUp('unicorn.png').then(filepath => { + console.log(filepath); + //=> '/Users/sindresorhus/unicorn.png' +}); +``` + + +## API + +### findUp(filename, [options]) + +Returns a promise for the filepath or `null`. + +### findUp.sync(filename, [options]) + +Returns a filepath or `null`. + +#### filename + +Type: `string` + +Filename of the file to find. + +#### options + +##### cwd + +Type: `string` +Default: `process.cwd()` + +Directory to start from. + + +## Related + +- [find-up-cli](https://github.com/sindresorhus/find-up-cli) - CLI for this module +- [pkg-up](https://github.com/sindresorhus/pkg-up) - Find the closest package.json file +- [pkg-dir](https://github.com/sindresorhus/pkg-dir) - Find the root directory of an npm package + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/findup-sync/.jshintrc b/node_modules/findup-sync/.jshintrc new file mode 100644 index 0000000..8718952 --- /dev/null +++ b/node_modules/findup-sync/.jshintrc @@ -0,0 +1,15 @@ +{ + "loopfunc": true, + "curly": true, + "eqeqeq": true, + "immed": true, + "latedef": true, + "newcap": true, + "noarg": true, + "sub": true, + "undef": true, + "unused": true, + "boss": true, + "eqnull": true, + "node": true +} diff --git a/node_modules/findup-sync/.npmignore b/node_modules/findup-sync/.npmignore new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/findup-sync/.travis.yml b/node_modules/findup-sync/.travis.yml new file mode 100644 index 0000000..b30fcb7 --- /dev/null +++ b/node_modules/findup-sync/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - 0.8 +before_script: + - npm install -g grunt-cli diff --git a/node_modules/findup-sync/Gruntfile.js b/node_modules/findup-sync/Gruntfile.js new file mode 100644 index 0000000..2f964a5 --- /dev/null +++ b/node_modules/findup-sync/Gruntfile.js @@ -0,0 +1,25 @@ +'use strict'; + +module.exports = function(grunt) { + + // Project configuration. + grunt.initConfig({ + nodeunit: { + files: ['test/**/*_test.js'], + }, + jshint: { + options: { + jshintrc: '.jshintrc' + }, + all: ['Gruntfile.js', 'lib/**/*.js', 'test/**/*.js'] + } + }); + + // Load plugins. + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-nodeunit'); + + // Default task. + grunt.registerTask('default', ['jshint', 'nodeunit']); + +}; diff --git a/node_modules/findup-sync/LICENSE-MIT b/node_modules/findup-sync/LICENSE-MIT new file mode 100644 index 0000000..bb2aad6 --- /dev/null +++ b/node_modules/findup-sync/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) 2013 "Cowboy" Ben Alman + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/findup-sync/README.md b/node_modules/findup-sync/README.md new file mode 100644 index 0000000..5459b93 --- /dev/null +++ b/node_modules/findup-sync/README.md @@ -0,0 +1,45 @@ +# findup-sync [![Build Status](https://secure.travis-ci.org/cowboy/node-findup-sync.png?branch=master)](http://travis-ci.org/cowboy/node-findup-sync) + +Find the first file matching a given pattern in the current directory or the nearest ancestor directory. + +## Getting Started +Install the module with: `npm install findup-sync` + +```js +var findup = require('findup-sync'); + +// Start looking in the CWD. +var filepath1 = findup('{a,b}*.txt'); + +// Start looking somewhere else, and ignore case (probably a good idea). +var filepath2 = findup('{a,b}*.txt', {cwd: '/some/path', nocase: true}); +``` + +## Usage + +```js +findup(patternOrPatterns [, minimatchOptions]) +``` + +### patternOrPatterns +Type: `String` or `Array` +Default: none + +One or more wildcard glob patterns. Or just filenames. + +### minimatchOptions +Type: `Object` +Default: `{}` + +Options to be passed to [minimatch](https://github.com/isaacs/minimatch). + +Note that if you want to start in a different directory than the current working directory, specify a `cwd` property here. + +## Contributing +In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/). + +## Release History +2014-03-14 - v0.1.3 - Updated dependencies. +2013-03-08 - v0.1.2 - Updated dependencies. Fixed a Node 0.9.x bug. Updated unit tests to work cross-platform. +2012-11-15 - v0.1.1 - Now works without an options object. +2012-11-01 - v0.1.0 - Initial release. diff --git a/node_modules/findup-sync/lib/findup-sync.js b/node_modules/findup-sync/lib/findup-sync.js new file mode 100644 index 0000000..742a478 --- /dev/null +++ b/node_modules/findup-sync/lib/findup-sync.js @@ -0,0 +1,46 @@ +/* + * findup-sync + * https://github.com/cowboy/node-findup-sync + * + * Copyright (c) 2013 "Cowboy" Ben Alman + * Licensed under the MIT license. + */ + +'use strict'; + +// Nodejs libs. +var path = require('path'); + +// External libs. +var glob = require('glob'); +var _ = require('lodash'); + +// Search for a filename in the given directory or all parent directories. +module.exports = function(patterns, options) { + // Normalize patterns to an array. + if (!Array.isArray(patterns)) { patterns = [patterns]; } + // Create globOptions so that it can be modified without mutating the + // original object. + var globOptions = Object.create(options || {}); + globOptions.maxDepth = 1; + globOptions.cwd = path.resolve(globOptions.cwd || '.'); + + var files, lastpath; + do { + // Search for files matching patterns. + files = _(patterns).map(function(pattern) { + return glob.sync(pattern, globOptions); + }).flatten().uniq().value(); + // Return file if found. + if (files.length > 0) { + return path.resolve(path.join(globOptions.cwd, files[0])); + } + // Go up a directory. + lastpath = globOptions.cwd; + globOptions.cwd = path.resolve(globOptions.cwd, '..'); + // If parentpath is the same as basedir, we can't go any higher. + } while (globOptions.cwd !== lastpath); + + // No files were found! + return null; +}; diff --git a/node_modules/findup-sync/node_modules/glob/.npmignore b/node_modules/findup-sync/node_modules/glob/.npmignore new file mode 100644 index 0000000..2af4b71 --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/.npmignore @@ -0,0 +1,2 @@ +.*.swp +test/a/ diff --git a/node_modules/findup-sync/node_modules/glob/.travis.yml b/node_modules/findup-sync/node_modules/glob/.travis.yml new file mode 100644 index 0000000..baa0031 --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - 0.8 diff --git a/node_modules/findup-sync/node_modules/glob/LICENSE b/node_modules/findup-sync/node_modules/glob/LICENSE new file mode 100644 index 0000000..0c44ae7 --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) Isaac Z. Schlueter ("Author") +All rights reserved. + +The BSD License + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/node_modules/findup-sync/node_modules/glob/README.md b/node_modules/findup-sync/node_modules/glob/README.md new file mode 100644 index 0000000..cc69164 --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/README.md @@ -0,0 +1,250 @@ +# Glob + +Match files using the patterns the shell uses, like stars and stuff. + +This is a glob implementation in JavaScript. It uses the `minimatch` +library to do its matching. + +## Attention: node-glob users! + +The API has changed dramatically between 2.x and 3.x. This library is +now 100% JavaScript, and the integer flags have been replaced with an +options object. + +Also, there's an event emitter class, proper tests, and all the other +things you've come to expect from node modules. + +And best of all, no compilation! + +## Usage + +```javascript +var glob = require("glob") + +// options is optional +glob("**/*.js", options, function (er, files) { + // files is an array of filenames. + // If the `nonull` option is set, and nothing + // was found, then files is ["**/*.js"] + // er is an error object or null. +}) +``` + +## Features + +Please see the [minimatch +documentation](https://github.com/isaacs/minimatch) for more details. + +Supports these glob features: + +* Brace Expansion +* Extended glob matching +* "Globstar" `**` matching + +See: + +* `man sh` +* `man bash` +* `man 3 fnmatch` +* `man 5 gitignore` +* [minimatch documentation](https://github.com/isaacs/minimatch) + +## glob(pattern, [options], cb) + +* `pattern` {String} Pattern to be matched +* `options` {Object} +* `cb` {Function} + * `err` {Error | null} + * `matches` {Array} filenames found matching the pattern + +Perform an asynchronous glob search. + +## glob.sync(pattern, [options]) + +* `pattern` {String} Pattern to be matched +* `options` {Object} +* return: {Array} filenames found matching the pattern + +Perform a synchronous glob search. + +## Class: glob.Glob + +Create a Glob object by instanting the `glob.Glob` class. + +```javascript +var Glob = require("glob").Glob +var mg = new Glob(pattern, options, cb) +``` + +It's an EventEmitter, and starts walking the filesystem to find matches +immediately. + +### new glob.Glob(pattern, [options], [cb]) + +* `pattern` {String} pattern to search for +* `options` {Object} +* `cb` {Function} Called when an error occurs, or matches are found + * `err` {Error | null} + * `matches` {Array} filenames found matching the pattern + +Note that if the `sync` flag is set in the options, then matches will +be immediately available on the `g.found` member. + +### Properties + +* `minimatch` The minimatch object that the glob uses. +* `options` The options object passed in. +* `error` The error encountered. When an error is encountered, the + glob object is in an undefined state, and should be discarded. +* `aborted` Boolean which is set to true when calling `abort()`. There + is no way at this time to continue a glob search after aborting, but + you can re-use the statCache to avoid having to duplicate syscalls. +* `statCache` Collection of all the stat results the glob search + performed. +* `cache` Convenience object. Each field has the following possible + values: + * `false` - Path does not exist + * `true` - Path exists + * `1` - Path exists, and is not a directory + * `2` - Path exists, and is a directory + * `[file, entries, ...]` - Path exists, is a directory, and the + array value is the results of `fs.readdir` + +### Events + +* `end` When the matching is finished, this is emitted with all the + matches found. If the `nonull` option is set, and no match was found, + then the `matches` list contains the original pattern. The matches + are sorted, unless the `nosort` flag is set. +* `match` Every time a match is found, this is emitted with the matched. +* `error` Emitted when an unexpected error is encountered, or whenever + any fs error occurs if `options.strict` is set. +* `abort` When `abort()` is called, this event is raised. + +### Methods + +* `abort` Stop the search. + +### Options + +All the options that can be passed to Minimatch can also be passed to +Glob to change pattern matching behavior. Also, some have been added, +or have glob-specific ramifications. + +All options are false by default, unless otherwise noted. + +All options are added to the glob object, as well. + +* `cwd` The current working directory in which to search. Defaults + to `process.cwd()`. +* `root` The place where patterns starting with `/` will be mounted + onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix + systems, and `C:\` or some such on Windows.) +* `dot` Include `.dot` files in normal matches and `globstar` matches. + Note that an explicit dot in a portion of the pattern will always + match dot files. +* `nomount` By default, a pattern starting with a forward-slash will be + "mounted" onto the root setting, so that a valid filesystem path is + returned. Set this flag to disable that behavior. +* `mark` Add a `/` character to directory matches. Note that this + requires additional stat calls. +* `nosort` Don't sort the results. +* `stat` Set to true to stat *all* results. This reduces performance + somewhat, and is completely unnecessary, unless `readdir` is presumed + to be an untrustworthy indicator of file existence. It will cause + ELOOP to be triggered one level sooner in the case of cyclical + symbolic links. +* `silent` When an unusual error is encountered + when attempting to read a directory, a warning will be printed to + stderr. Set the `silent` option to true to suppress these warnings. +* `strict` When an unusual error is encountered + when attempting to read a directory, the process will just continue on + in search of other matches. Set the `strict` option to raise an error + in these cases. +* `cache` See `cache` property above. Pass in a previously generated + cache object to save some fs calls. +* `statCache` A cache of results of filesystem information, to prevent + unnecessary stat calls. While it should not normally be necessary to + set this, you may pass the statCache from one glob() call to the + options object of another, if you know that the filesystem will not + change between calls. (See "Race Conditions" below.) +* `sync` Perform a synchronous glob search. +* `nounique` In some cases, brace-expanded patterns can result in the + same file showing up multiple times in the result set. By default, + this implementation prevents duplicates in the result set. + Set this flag to disable that behavior. +* `nonull` Set to never return an empty set, instead returning a set + containing the pattern itself. This is the default in glob(3). +* `nocase` Perform a case-insensitive match. Note that case-insensitive + filesystems will sometimes result in glob returning results that are + case-insensitively matched anyway, since readdir and stat will not + raise an error. +* `debug` Set to enable debug logging in minimatch and glob. +* `globDebug` Set to enable debug logging in glob, but not minimatch. + +## Comparisons to other fnmatch/glob implementations + +While strict compliance with the existing standards is a worthwhile +goal, some discrepancies exist between node-glob and other +implementations, and are intentional. + +If the pattern starts with a `!` character, then it is negated. Set the +`nonegate` flag to suppress this behavior, and treat leading `!` +characters normally. This is perhaps relevant if you wish to start the +pattern with a negative extglob pattern like `!(a|B)`. Multiple `!` +characters at the start of a pattern will negate the pattern multiple +times. + +If a pattern starts with `#`, then it is treated as a comment, and +will not match anything. Use `\#` to match a literal `#` at the +start of a line, or set the `nocomment` flag to suppress this behavior. + +The double-star character `**` is supported by default, unless the +`noglobstar` flag is set. This is supported in the manner of bsdglob +and bash 4.1, where `**` only has special significance if it is the only +thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but +`a/**b` will not. + +If an escaped pattern has no matches, and the `nonull` flag is set, +then glob returns the pattern as-provided, rather than +interpreting the character escapes. For example, +`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than +`"*a?"`. This is akin to setting the `nullglob` option in bash, except +that it does not resolve escaped pattern characters. + +If brace expansion is not disabled, then it is performed before any +other interpretation of the glob pattern. Thus, a pattern like +`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded +**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are +checked for validity. Since those two are valid, matching proceeds. + +## Windows + +**Please only use forward-slashes in glob expressions.** + +Though windows uses either `/` or `\` as its path separator, only `/` +characters are used by this glob implementation. You must use +forward-slashes **only** in glob expressions. Back-slashes will always +be interpreted as escape characters, not path separators. + +Results from absolute patterns such as `/foo/*` are mounted onto the +root setting using `path.join`. On windows, this will by default result +in `/foo/*` matching `C:\foo\bar.txt`. + +## Race Conditions + +Glob searching, by its very nature, is susceptible to race conditions, +since it relies on directory walking and such. + +As a result, it is possible that a file that exists when glob looks for +it may have been deleted or modified by the time it returns the result. + +As part of its internal implementation, this program caches all stat +and readdir calls that it makes, in order to cut down on system +overhead. However, this also makes it even more susceptible to races, +especially if the cache or statCache objects are reused between glob +calls. + +Users are thus advised not to use a glob result as a guarantee of +filesystem state in the face of rapid changes. For the vast majority +of operations, this is never a problem. diff --git a/node_modules/findup-sync/node_modules/glob/examples/g.js b/node_modules/findup-sync/node_modules/glob/examples/g.js new file mode 100644 index 0000000..be122df --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/examples/g.js @@ -0,0 +1,9 @@ +var Glob = require("../").Glob + +var pattern = "test/a/**/[cg]/../[cg]" +console.log(pattern) + +var mg = new Glob(pattern, {mark: true, sync:true}, function (er, matches) { + console.log("matches", matches) +}) +console.log("after") diff --git a/node_modules/findup-sync/node_modules/glob/examples/usr-local.js b/node_modules/findup-sync/node_modules/glob/examples/usr-local.js new file mode 100644 index 0000000..327a425 --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/examples/usr-local.js @@ -0,0 +1,9 @@ +var Glob = require("../").Glob + +var pattern = "{./*/*,/*,/usr/local/*}" +console.log(pattern) + +var mg = new Glob(pattern, {mark: true}, function (er, matches) { + console.log("matches", matches) +}) +console.log("after") diff --git a/node_modules/findup-sync/node_modules/glob/glob.js b/node_modules/findup-sync/node_modules/glob/glob.js new file mode 100644 index 0000000..f646c44 --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/glob.js @@ -0,0 +1,728 @@ +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// readdir(PREFIX) as ENTRIES +// If fails, END +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $]) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $]) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + + + +module.exports = glob + +var fs = require("fs") +, minimatch = require("minimatch") +, Minimatch = minimatch.Minimatch +, inherits = require("inherits") +, EE = require("events").EventEmitter +, path = require("path") +, isDir = {} +, assert = require("assert").ok + +function glob (pattern, options, cb) { + if (typeof options === "function") cb = options, options = {} + if (!options) options = {} + + if (typeof options === "number") { + deprecated() + return + } + + var g = new Glob(pattern, options, cb) + return g.sync ? g.found : g +} + +glob.fnmatch = deprecated + +function deprecated () { + throw new Error("glob's interface has changed. Please see the docs.") +} + +glob.sync = globSync +function globSync (pattern, options) { + if (typeof options === "number") { + deprecated() + return + } + + options = options || {} + options.sync = true + return glob(pattern, options) +} + +this._processingEmitQueue = false + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (!(this instanceof Glob)) { + return new Glob(pattern, options, cb) + } + + if (typeof options === "function") { + cb = options + options = null + } + + if (typeof cb === "function") { + this.on("error", cb) + this.on("end", function (matches) { + cb(null, matches) + }) + } + + options = options || {} + + this._endEmitted = false + this.EOF = {} + this._emitQueue = [] + + this.paused = false + this._processingEmitQueue = false + + this.maxDepth = options.maxDepth || 1000 + this.maxLength = options.maxLength || Infinity + this.cache = options.cache || {} + this.statCache = options.statCache || {} + + this.changedCwd = false + var cwd = process.cwd() + if (!options.hasOwnProperty("cwd")) this.cwd = cwd + else { + this.cwd = options.cwd + this.changedCwd = path.resolve(options.cwd) !== cwd + } + + this.root = options.root || path.resolve(this.cwd, "/") + this.root = path.resolve(this.root) + if (process.platform === "win32") + this.root = this.root.replace(/\\/g, "/") + + this.nomount = !!options.nomount + + if (!pattern) { + throw new Error("must provide pattern") + } + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + this.strict = options.strict !== false + this.dot = !!options.dot + this.mark = !!options.mark + this.sync = !!options.sync + this.nounique = !!options.nounique + this.nonull = !!options.nonull + this.nosort = !!options.nosort + this.nocase = !!options.nocase + this.stat = !!options.stat + + this.debug = !!options.debug || !!options.globDebug + if (this.debug) + this.log = console.error + + this.silent = !!options.silent + + var mm = this.minimatch = new Minimatch(pattern, options) + this.options = mm.options + pattern = this.pattern = mm.pattern + + this.error = null + this.aborted = false + + // list of all the patterns that ** has resolved do, so + // we can avoid visiting multiple times. + this._globstars = {} + + EE.call(this) + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + this.minimatch.set.forEach(iterator.bind(this)) + function iterator (pattern, i, set) { + this._process(pattern, 0, i, function (er) { + if (er) this.emit("error", er) + if (-- n <= 0) this._finish() + }) + } +} + +Glob.prototype.log = function () {} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + + var nou = this.nounique + , all = nou ? [] : {} + + for (var i = 0, l = this.matches.length; i < l; i ++) { + var matches = this.matches[i] + this.log("matches[%d] =", i, matches) + // do like the shell, and spit out the literal glob + if (!matches) { + if (this.nonull) { + var literal = this.minimatch.globSet[i] + if (nou) all.push(literal) + else all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) all.push.apply(all, m) + else m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) all = Object.keys(all) + + if (!this.nosort) { + all = all.sort(this.nocase ? alphasorti : alphasort) + } + + if (this.mark) { + // at *some* point we statted all of these + all = all.map(this._mark, this) + } + + this.log("emitting end", all) + + this.EOF = this.found = all + this.emitMatch(this.EOF) +} + +function alphasorti (a, b) { + a = a.toLowerCase() + b = b.toLowerCase() + return alphasort(a, b) +} + +function alphasort (a, b) { + return a > b ? 1 : a < b ? -1 : 0 +} + +Glob.prototype._mark = function (p) { + var c = this.cache[p] + var m = p + if (c) { + var isDir = c === 2 || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + this.statCache[m] = this.statCache[p] + this.cache[m] = this.cache[p] + } + } + + return m +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit("abort") +} + +Glob.prototype.pause = function () { + if (this.paused) return + if (this.sync) + this.emit("error", new Error("Can't pause/resume sync glob")) + this.paused = true + this.emit("pause") +} + +Glob.prototype.resume = function () { + if (!this.paused) return + if (this.sync) + this.emit("error", new Error("Can't pause/resume sync glob")) + this.paused = false + this.emit("resume") + this._processEmitQueue() + //process.nextTick(this.emit.bind(this, "resume")) +} + +Glob.prototype.emitMatch = function (m) { + this.log('emitMatch', m) + this._emitQueue.push(m) + this._processEmitQueue() +} + +Glob.prototype._processEmitQueue = function (m) { + this.log("pEQ paused=%j processing=%j m=%j", this.paused, + this._processingEmitQueue, m) + var done = false + while (!this._processingEmitQueue && + !this.paused) { + this._processingEmitQueue = true + var m = this._emitQueue.shift() + this.log(">processEmitQueue", m === this.EOF ? ":EOF:" : m) + if (!m) { + this.log(">processEmitQueue, falsey m") + this._processingEmitQueue = false + break + } + + if (m === this.EOF || !(this.mark && !this.stat)) { + this.log("peq: unmarked, or eof") + next.call(this, 0, false) + } else if (this.statCache[m]) { + var sc = this.statCache[m] + var exists + if (sc) + exists = sc.isDirectory() ? 2 : 1 + this.log("peq: stat cached") + next.call(this, exists, exists === 2) + } else { + this.log("peq: _stat, then next") + this._stat(m, next) + } + + function next(exists, isDir) { + this.log("next", m, exists, isDir) + var ev = m === this.EOF ? "end" : "match" + + // "end" can only happen once. + assert(!this._endEmitted) + if (ev === "end") + this._endEmitted = true + + if (exists) { + // Doesn't mean it necessarily doesn't exist, it's possible + // we just didn't check because we don't care that much, or + // this is EOF anyway. + if (isDir && !m.match(/\/$/)) { + m = m + "/" + } else if (!isDir && m.match(/\/$/)) { + m = m.replace(/\/+$/, "") + } + } + this.log("emit", ev, m) + this.emit(ev, m) + this._processingEmitQueue = false + if (done && m !== this.EOF && !this.paused) + this._processEmitQueue() + } + } + done = true +} + +Glob.prototype._process = function (pattern, depth, index, cb_) { + assert(this instanceof Glob) + + var cb = function cb (er, res) { + assert(this instanceof Glob) + if (this.paused) { + if (!this._processQueue) { + this._processQueue = [] + this.once("resume", function () { + var q = this._processQueue + this._processQueue = null + q.forEach(function (cb) { cb() }) + }) + } + this._processQueue.push(cb_.bind(this, er, res)) + } else { + cb_.call(this, er, res) + } + }.bind(this) + + if (this.aborted) return cb() + + if (depth > this.maxDepth) return cb() + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === "string") { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + prefix = pattern.join("/") + this._stat(prefix, function (exists, isDir) { + // either it's there, or it isn't. + // nothing more to do, either way. + if (exists) { + if (prefix && isAbsolute(prefix) && !this.nomount) { + if (prefix.charAt(0) === "/") { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + } + } + + if (process.platform === "win32") + prefix = prefix.replace(/\\/g, "/") + + this.matches[index] = this.matches[index] || {} + this.matches[index][prefix] = true + this.emitMatch(prefix) + } + return cb() + }) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's "absolute" like /foo/bar, + // or "relative" like "../baz" + prefix = pattern.slice(0, n) + prefix = prefix.join("/") + break + } + + // get the list of entries. + var read + if (prefix === null) read = "." + else if (isAbsolute(prefix) || isAbsolute(pattern.join("/"))) { + if (!prefix || !isAbsolute(prefix)) { + prefix = path.join("/", prefix) + } + read = prefix = path.resolve(prefix) + + // if (process.platform === "win32") + // read = prefix = prefix.replace(/^[a-zA-Z]:|\\/g, "/") + + this.log('absolute: ', prefix, this.root, pattern, read) + } else { + read = prefix + } + + this.log('readdir(%j)', read, this.cwd, this.root) + + return this._readdir(read, function (er, entries) { + if (er) { + // not a directory! + // this means that, whatever else comes after this, it can never match + return cb() + } + + // globstar is special + if (pattern[n] === minimatch.GLOBSTAR) { + // test without the globstar, and with every child both below + // and replacing the globstar. + var s = [ pattern.slice(0, n).concat(pattern.slice(n + 1)) ] + entries.forEach(function (e) { + if (e.charAt(0) === "." && !this.dot) return + // instead of the globstar + s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1))) + // below the globstar + s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n))) + }, this) + + s = s.filter(function (pattern) { + var key = gsKey(pattern) + var seen = !this._globstars[key] + this._globstars[key] = true + return seen + }, this) + + if (!s.length) + return cb() + + // now asyncForEach over this + var l = s.length + , errState = null + s.forEach(function (gsPattern) { + this._process(gsPattern, depth + 1, index, function (er) { + if (errState) return + if (er) return cb(errState = er) + if (--l <= 0) return cb() + }) + }, this) + + return + } + + // not a globstar + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = pattern[n] + var rawGlob = pattern[n]._glob + , dotOk = this.dot || rawGlob.charAt(0) === "." + + entries = entries.filter(function (e) { + return (e.charAt(0) !== "." || dotOk) && + e.match(pattern[n]) + }) + + // If n === pattern.length - 1, then there's no need for the extra stat + // *unless* the user has specified "mark" or "stat" explicitly. + // We know that they exist, since the readdir returned them. + if (n === pattern.length - 1 && + !this.mark && + !this.stat) { + entries.forEach(function (e) { + if (prefix) { + if (prefix !== "/") e = prefix + "/" + e + else e = prefix + e + } + if (e.charAt(0) === "/" && !this.nomount) { + e = path.join(this.root, e) + } + + if (process.platform === "win32") + e = e.replace(/\\/g, "/") + + this.matches[index] = this.matches[index] || {} + this.matches[index][e] = true + this.emitMatch(e) + }, this) + return cb.call(this) + } + + + // now test all the remaining entries as stand-ins for that part + // of the pattern. + var l = entries.length + , errState = null + if (l === 0) return cb() // no matches possible + entries.forEach(function (e) { + var p = pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1)) + this._process(p, depth + 1, index, function (er) { + if (errState) return + if (er) return cb(errState = er) + if (--l === 0) return cb.call(this) + }) + }, this) + }) + +} + +function gsKey (pattern) { + return '**' + pattern.map(function (p) { + return (p === minimatch.GLOBSTAR) ? '**' : (''+p) + }).join('/') +} + +Glob.prototype._stat = function (f, cb) { + assert(this instanceof Glob) + var abs = f + if (f.charAt(0) === "/") { + abs = path.join(this.root, f) + } else if (this.changedCwd) { + abs = path.resolve(this.cwd, f) + } + + if (f.length > this.maxLength) { + var er = new Error("Path name too long") + er.code = "ENAMETOOLONG" + er.path = f + return this._afterStat(f, abs, cb, er) + } + + this.log('stat', [this.cwd, f, '=', abs]) + + if (!this.stat && this.cache.hasOwnProperty(f)) { + var exists = this.cache[f] + , isDir = exists && (Array.isArray(exists) || exists === 2) + if (this.sync) return cb.call(this, !!exists, isDir) + return process.nextTick(cb.bind(this, !!exists, isDir)) + } + + var stat = this.statCache[abs] + if (this.sync || stat) { + var er + try { + stat = fs.statSync(abs) + } catch (e) { + er = e + } + this._afterStat(f, abs, cb, er, stat) + } else { + fs.stat(abs, this._afterStat.bind(this, f, abs, cb)) + } +} + +Glob.prototype._afterStat = function (f, abs, cb, er, stat) { + var exists + assert(this instanceof Glob) + + if (abs.slice(-1) === "/" && stat && !stat.isDirectory()) { + this.log("should be ENOTDIR, fake it") + + er = new Error("ENOTDIR, not a directory '" + abs + "'") + er.path = abs + er.code = "ENOTDIR" + stat = null + } + + var emit = !this.statCache[abs] + this.statCache[abs] = stat + + if (er || !stat) { + exists = false + } else { + exists = stat.isDirectory() ? 2 : 1 + if (emit) + this.emit('stat', f, stat) + } + this.cache[f] = this.cache[f] || exists + cb.call(this, !!exists, exists === 2) +} + +Glob.prototype._readdir = function (f, cb) { + assert(this instanceof Glob) + var abs = f + if (f.charAt(0) === "/") { + abs = path.join(this.root, f) + } else if (isAbsolute(f)) { + abs = f + } else if (this.changedCwd) { + abs = path.resolve(this.cwd, f) + } + + if (f.length > this.maxLength) { + var er = new Error("Path name too long") + er.code = "ENAMETOOLONG" + er.path = f + return this._afterReaddir(f, abs, cb, er) + } + + this.log('readdir', [this.cwd, f, abs]) + if (this.cache.hasOwnProperty(f)) { + var c = this.cache[f] + if (Array.isArray(c)) { + if (this.sync) return cb.call(this, null, c) + return process.nextTick(cb.bind(this, null, c)) + } + + if (!c || c === 1) { + // either ENOENT or ENOTDIR + var code = c ? "ENOTDIR" : "ENOENT" + , er = new Error((c ? "Not a directory" : "Not found") + ": " + f) + er.path = f + er.code = code + this.log(f, er) + if (this.sync) return cb.call(this, er) + return process.nextTick(cb.bind(this, er)) + } + + // at this point, c === 2, meaning it's a dir, but we haven't + // had to read it yet, or c === true, meaning it's *something* + // but we don't have any idea what. Need to read it, either way. + } + + if (this.sync) { + var er, entries + try { + entries = fs.readdirSync(abs) + } catch (e) { + er = e + } + return this._afterReaddir(f, abs, cb, er, entries) + } + + fs.readdir(abs, this._afterReaddir.bind(this, f, abs, cb)) +} + +Glob.prototype._afterReaddir = function (f, abs, cb, er, entries) { + assert(this instanceof Glob) + if (entries && !er) { + this.cache[f] = entries + // if we haven't asked to stat everything for suresies, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. This also gets us one step + // further into ELOOP territory. + if (!this.mark && !this.stat) { + entries.forEach(function (e) { + if (f === "/") e = f + e + else e = f + "/" + e + this.cache[e] = true + }, this) + } + + return cb.call(this, er, entries) + } + + // now handle errors, and cache the information + if (er) switch (er.code) { + case "ENOTDIR": // totally normal. means it *does* exist. + this.cache[f] = 1 + return cb.call(this, er) + case "ENOENT": // not terribly unusual + case "ELOOP": + case "ENAMETOOLONG": + case "UNKNOWN": + this.cache[f] = false + return cb.call(this, er) + default: // some unusual error. Treat as failure. + this.cache[f] = false + if (this.strict) this.emit("error", er) + if (!this.silent) console.error("glob error", er) + return cb.call(this, er) + } +} + +var isAbsolute = process.platform === "win32" ? absWin : absUnix + +function absWin (p) { + if (absUnix(p)) return true + // pull off the device/UNC bit from a windows path. + // from node's lib/path.js + var splitDeviceRe = + /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/ + , result = splitDeviceRe.exec(p) + , device = result[1] || '' + , isUnc = device && device.charAt(1) !== ':' + , isAbsolute = !!result[2] || isUnc // UNC paths are always absolute + + return isAbsolute +} + +function absUnix (p) { + return p.charAt(0) === "/" || p === "" +} diff --git a/node_modules/findup-sync/node_modules/glob/package.json b/node_modules/findup-sync/node_modules/glob/package.json new file mode 100644 index 0000000..84a9cd1 --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/package.json @@ -0,0 +1,91 @@ +{ + "_args": [ + [ + { + "raw": "glob@~3.2.9", + "scope": null, + "escapedName": "glob", + "name": "glob", + "rawSpec": "~3.2.9", + "spec": ">=3.2.9 <3.3.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/findup-sync" + ] + ], + "_from": "glob@>=3.2.9 <3.3.0", + "_id": "glob@3.2.11", + "_inCache": true, + "_location": "/findup-sync/glob", + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "1.4.10", + "_phantomChildren": {}, + "_requested": { + "raw": "glob@~3.2.9", + "scope": null, + "escapedName": "glob", + "name": "glob", + "rawSpec": "~3.2.9", + "spec": ">=3.2.9 <3.3.0", + "type": "range" + }, + "_requiredBy": [ + "/findup-sync" + ], + "_resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "_shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d", + "_shrinkwrap": null, + "_spec": "glob@~3.2.9", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/findup-sync", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/node-glob/issues" + }, + "dependencies": { + "inherits": "2", + "minimatch": "0.3" + }, + "description": "a little globber", + "devDependencies": { + "mkdirp": "0", + "rimraf": "1", + "tap": "~0.4.0" + }, + "directories": {}, + "dist": { + "shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d", + "tarball": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz" + }, + "engines": { + "node": "*" + }, + "gitHead": "73f57e99510582b2024b762305970ebcf9b70aa2", + "homepage": "https://github.com/isaacs/node-glob", + "license": "BSD", + "main": "glob.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "glob", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/node-glob.git" + }, + "scripts": { + "test": "tap test/*.js", + "test-regen": "TEST_REGEN=1 node test/00-setup.js" + }, + "version": "3.2.11" +} diff --git a/node_modules/findup-sync/node_modules/glob/test/00-setup.js b/node_modules/findup-sync/node_modules/glob/test/00-setup.js new file mode 100644 index 0000000..245afaf --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/test/00-setup.js @@ -0,0 +1,176 @@ +// just a little pre-run script to set up the fixtures. +// zz-finish cleans it up + +var mkdirp = require("mkdirp") +var path = require("path") +var i = 0 +var tap = require("tap") +var fs = require("fs") +var rimraf = require("rimraf") + +var files = +[ "a/.abcdef/x/y/z/a" +, "a/abcdef/g/h" +, "a/abcfed/g/h" +, "a/b/c/d" +, "a/bc/e/f" +, "a/c/d/c/b" +, "a/cb/e/f" +] + +var symlinkTo = path.resolve(__dirname, "a/symlink/a/b/c") +var symlinkFrom = "../.." + +files = files.map(function (f) { + return path.resolve(__dirname, f) +}) + +tap.test("remove fixtures", function (t) { + rimraf(path.resolve(__dirname, "a"), function (er) { + t.ifError(er, "remove fixtures") + t.end() + }) +}) + +files.forEach(function (f) { + tap.test(f, function (t) { + var d = path.dirname(f) + mkdirp(d, 0755, function (er) { + if (er) { + t.fail(er) + return t.bailout() + } + fs.writeFile(f, "i like tests", function (er) { + t.ifError(er, "make file") + t.end() + }) + }) + }) +}) + +if (process.platform !== "win32") { + tap.test("symlinky", function (t) { + var d = path.dirname(symlinkTo) + console.error("mkdirp", d) + mkdirp(d, 0755, function (er) { + t.ifError(er) + fs.symlink(symlinkFrom, symlinkTo, "dir", function (er) { + t.ifError(er, "make symlink") + t.end() + }) + }) + }) +} + +;["foo","bar","baz","asdf","quux","qwer","rewq"].forEach(function (w) { + w = "/tmp/glob-test/" + w + tap.test("create " + w, function (t) { + mkdirp(w, function (er) { + if (er) + throw er + t.pass(w) + t.end() + }) + }) +}) + + +// generate the bash pattern test-fixtures if possible +if (process.platform === "win32" || !process.env.TEST_REGEN) { + console.error("Windows, or TEST_REGEN unset. Using cached fixtures.") + return +} + +var spawn = require("child_process").spawn; +var globs = + // put more patterns here. + // anything that would be directly in / should be in /tmp/glob-test + ["test/a/*/+(c|g)/./d" + ,"test/a/**/[cg]/../[cg]" + ,"test/a/{b,c,d,e,f}/**/g" + ,"test/a/b/**" + ,"test/**/g" + ,"test/a/abc{fed,def}/g/h" + ,"test/a/abc{fed/g,def}/**/" + ,"test/a/abc{fed/g,def}/**///**/" + ,"test/**/a/**/" + ,"test/+(a|b|c)/a{/,bc*}/**" + ,"test/*/*/*/f" + ,"test/**/f" + ,"test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**" + ,"{./*/*,/tmp/glob-test/*}" + ,"{/tmp/glob-test/*,*}" // evil owl face! how you taunt me! + ,"test/a/!(symlink)/**" + ] +var bashOutput = {} +var fs = require("fs") + +globs.forEach(function (pattern) { + tap.test("generate fixture " + pattern, function (t) { + var cmd = "shopt -s globstar && " + + "shopt -s extglob && " + + "shopt -s nullglob && " + + // "shopt >&2; " + + "eval \'for i in " + pattern + "; do echo $i; done\'" + var cp = spawn("bash", ["-c", cmd], { cwd: path.dirname(__dirname) }) + var out = [] + cp.stdout.on("data", function (c) { + out.push(c) + }) + cp.stderr.pipe(process.stderr) + cp.on("close", function (code) { + out = flatten(out) + if (!out) + out = [] + else + out = cleanResults(out.split(/\r*\n/)) + + bashOutput[pattern] = out + t.notOk(code, "bash test should finish nicely") + t.end() + }) + }) +}) + +tap.test("save fixtures", function (t) { + var fname = path.resolve(__dirname, "bash-results.json") + var data = JSON.stringify(bashOutput, null, 2) + "\n" + fs.writeFile(fname, data, function (er) { + t.ifError(er) + t.end() + }) +}) + +function cleanResults (m) { + // normalize discrepancies in ordering, duplication, + // and ending slashes. + return m.map(function (m) { + return m.replace(/\/+/g, "/").replace(/\/$/, "") + }).sort(alphasort).reduce(function (set, f) { + if (f !== set[set.length - 1]) set.push(f) + return set + }, []).sort(alphasort).map(function (f) { + // de-windows + return (process.platform !== 'win32') ? f + : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/') + }) +} + +function flatten (chunks) { + var s = 0 + chunks.forEach(function (c) { s += c.length }) + var out = new Buffer(s) + s = 0 + chunks.forEach(function (c) { + c.copy(out, s) + s += c.length + }) + + return out.toString().trim() +} + +function alphasort (a, b) { + a = a.toLowerCase() + b = b.toLowerCase() + return a > b ? 1 : a < b ? -1 : 0 +} diff --git a/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js b/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js new file mode 100644 index 0000000..239ed1a --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js @@ -0,0 +1,63 @@ +// basic test +// show that it does the same thing by default as the shell. +var tap = require("tap") +, child_process = require("child_process") +, bashResults = require("./bash-results.json") +, globs = Object.keys(bashResults) +, glob = require("../") +, path = require("path") + +// run from the root of the project +// this is usually where you're at anyway, but be sure. +process.chdir(path.resolve(__dirname, "..")) + +function alphasort (a, b) { + a = a.toLowerCase() + b = b.toLowerCase() + return a > b ? 1 : a < b ? -1 : 0 +} + +globs.forEach(function (pattern) { + var expect = bashResults[pattern] + // anything regarding the symlink thing will fail on windows, so just skip it + if (process.platform === "win32" && + expect.some(function (m) { + return /\/symlink\//.test(m) + })) + return + + tap.test(pattern, function (t) { + glob(pattern, function (er, matches) { + if (er) + throw er + + // sort and unmark, just to match the shell results + matches = cleanResults(matches) + + t.deepEqual(matches, expect, pattern) + t.end() + }) + }) + + tap.test(pattern + " sync", function (t) { + var matches = cleanResults(glob.sync(pattern)) + + t.deepEqual(matches, expect, "should match shell") + t.end() + }) +}) + +function cleanResults (m) { + // normalize discrepancies in ordering, duplication, + // and ending slashes. + return m.map(function (m) { + return m.replace(/\/+/g, "/").replace(/\/$/, "") + }).sort(alphasort).reduce(function (set, f) { + if (f !== set[set.length - 1]) set.push(f) + return set + }, []).sort(alphasort).map(function (f) { + // de-windows + return (process.platform !== 'win32') ? f + : f.replace(/^[a-zA-Z]:[\/\\]+/, '/').replace(/[\\\/]+/g, '/') + }) +} diff --git a/node_modules/findup-sync/node_modules/glob/test/bash-results.json b/node_modules/findup-sync/node_modules/glob/test/bash-results.json new file mode 100644 index 0000000..8051c72 --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/test/bash-results.json @@ -0,0 +1,351 @@ +{ + "test/a/*/+(c|g)/./d": [ + "test/a/b/c/./d" + ], + "test/a/**/[cg]/../[cg]": [ + "test/a/abcdef/g/../g", + "test/a/abcfed/g/../g", + "test/a/b/c/../c", + "test/a/c/../c", + "test/a/c/d/c/../c", + "test/a/symlink/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c" + ], + "test/a/{b,c,d,e,f}/**/g": [], + "test/a/b/**": [ + "test/a/b", + "test/a/b/c", + "test/a/b/c/d" + ], + "test/**/g": [ + "test/a/abcdef/g", + "test/a/abcfed/g" + ], + "test/a/abc{fed,def}/g/h": [ + "test/a/abcdef/g/h", + "test/a/abcfed/g/h" + ], + "test/a/abc{fed/g,def}/**/": [ + "test/a/abcdef", + "test/a/abcdef/g", + "test/a/abcfed/g" + ], + "test/a/abc{fed/g,def}/**///**/": [ + "test/a/abcdef", + "test/a/abcdef/g", + "test/a/abcfed/g" + ], + "test/**/a/**/": [ + "test/a", + "test/a/abcdef", + "test/a/abcdef/g", + "test/a/abcfed", + "test/a/abcfed/g", + "test/a/b", + "test/a/b/c", + "test/a/bc", + "test/a/bc/e", + "test/a/c", + "test/a/c/d", + "test/a/c/d/c", + "test/a/cb", + "test/a/cb/e", + "test/a/symlink", + "test/a/symlink/a", + "test/a/symlink/a/b", + "test/a/symlink/a/b/c", + "test/a/symlink/a/b/c/a", + "test/a/symlink/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b" + ], + "test/+(a|b|c)/a{/,bc*}/**": [ + "test/a/abcdef", + "test/a/abcdef/g", + "test/a/abcdef/g/h", + "test/a/abcfed", + "test/a/abcfed/g", + "test/a/abcfed/g/h" + ], + "test/*/*/*/f": [ + "test/a/bc/e/f", + "test/a/cb/e/f" + ], + "test/**/f": [ + "test/a/bc/e/f", + "test/a/cb/e/f" + ], + "test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**": [ + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c" + ], + "{./*/*,/tmp/glob-test/*}": [ + "./examples/g.js", + "./examples/usr-local.js", + "./node_modules/inherits", + "./node_modules/minimatch", + "./node_modules/mkdirp", + "./node_modules/rimraf", + "./node_modules/tap", + "./test/00-setup.js", + "./test/a", + "./test/bash-comparison.js", + "./test/bash-results.json", + "./test/cwd-test.js", + "./test/globstar-match.js", + "./test/mark.js", + "./test/new-glob-optional-options.js", + "./test/nocase-nomagic.js", + "./test/pause-resume.js", + "./test/readme-issue.js", + "./test/root-nomount.js", + "./test/root.js", + "./test/stat.js", + "./test/zz-cleanup.js", + "/tmp/glob-test/asdf", + "/tmp/glob-test/bar", + "/tmp/glob-test/baz", + "/tmp/glob-test/foo", + "/tmp/glob-test/quux", + "/tmp/glob-test/qwer", + "/tmp/glob-test/rewq" + ], + "{/tmp/glob-test/*,*}": [ + "/tmp/glob-test/asdf", + "/tmp/glob-test/bar", + "/tmp/glob-test/baz", + "/tmp/glob-test/foo", + "/tmp/glob-test/quux", + "/tmp/glob-test/qwer", + "/tmp/glob-test/rewq", + "examples", + "glob.js", + "LICENSE", + "node_modules", + "package.json", + "README.md", + "test" + ], + "test/a/!(symlink)/**": [ + "test/a/abcdef", + "test/a/abcdef/g", + "test/a/abcdef/g/h", + "test/a/abcfed", + "test/a/abcfed/g", + "test/a/abcfed/g/h", + "test/a/b", + "test/a/b/c", + "test/a/b/c/d", + "test/a/bc", + "test/a/bc/e", + "test/a/bc/e/f", + "test/a/c", + "test/a/c/d", + "test/a/c/d/c", + "test/a/c/d/c/b", + "test/a/cb", + "test/a/cb/e", + "test/a/cb/e/f" + ] +} diff --git a/node_modules/findup-sync/node_modules/glob/test/cwd-test.js b/node_modules/findup-sync/node_modules/glob/test/cwd-test.js new file mode 100644 index 0000000..352c27e --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/test/cwd-test.js @@ -0,0 +1,55 @@ +var tap = require("tap") + +var origCwd = process.cwd() +process.chdir(__dirname) + +tap.test("changing cwd and searching for **/d", function (t) { + var glob = require('../') + var path = require('path') + t.test('.', function (t) { + glob('**/d', function (er, matches) { + t.ifError(er) + t.like(matches, [ 'a/b/c/d', 'a/c/d' ]) + t.end() + }) + }) + + t.test('a', function (t) { + glob('**/d', {cwd:path.resolve('a')}, function (er, matches) { + t.ifError(er) + t.like(matches, [ 'b/c/d', 'c/d' ]) + t.end() + }) + }) + + t.test('a/b', function (t) { + glob('**/d', {cwd:path.resolve('a/b')}, function (er, matches) { + t.ifError(er) + t.like(matches, [ 'c/d' ]) + t.end() + }) + }) + + t.test('a/b/', function (t) { + glob('**/d', {cwd:path.resolve('a/b/')}, function (er, matches) { + t.ifError(er) + t.like(matches, [ 'c/d' ]) + t.end() + }) + }) + + t.test('.', function (t) { + glob('**/d', {cwd: process.cwd()}, function (er, matches) { + t.ifError(er) + t.like(matches, [ 'a/b/c/d', 'a/c/d' ]) + t.end() + }) + }) + + t.test('cd -', function (t) { + process.chdir(origCwd) + t.end() + }) + + t.end() +}) diff --git a/node_modules/findup-sync/node_modules/glob/test/globstar-match.js b/node_modules/findup-sync/node_modules/glob/test/globstar-match.js new file mode 100644 index 0000000..9b234fa --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/test/globstar-match.js @@ -0,0 +1,19 @@ +var Glob = require("../glob.js").Glob +var test = require('tap').test + +test('globstar should not have dupe matches', function(t) { + var pattern = 'a/**/[gh]' + var g = new Glob(pattern, { cwd: __dirname }) + var matches = [] + g.on('match', function(m) { + console.error('match %j', m) + matches.push(m) + }) + g.on('end', function(set) { + console.error('set', set) + matches = matches.sort() + set = set.sort() + t.same(matches, set, 'should have same set of matches') + t.end() + }) +}) diff --git a/node_modules/findup-sync/node_modules/glob/test/mark.js b/node_modules/findup-sync/node_modules/glob/test/mark.js new file mode 100644 index 0000000..bf411c0 --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/test/mark.js @@ -0,0 +1,118 @@ +var test = require("tap").test +var glob = require('../') +process.chdir(__dirname) + +// expose timing issues +var lag = 5 +glob.Glob.prototype._stat = function(o) { return function(f, cb) { + var args = arguments + setTimeout(function() { + o.call(this, f, cb) + }.bind(this), lag += 5) +}}(glob.Glob.prototype._stat) + + +test("mark, with **", function (t) { + glob("a/*b*/**", {mark: true}, function (er, results) { + if (er) + throw er + var expect = + [ 'a/abcdef/', + 'a/abcdef/g/', + 'a/abcdef/g/h', + 'a/abcfed/', + 'a/abcfed/g/', + 'a/abcfed/g/h', + 'a/b/', + 'a/b/c/', + 'a/b/c/d', + 'a/bc/', + 'a/bc/e/', + 'a/bc/e/f', + 'a/cb/', + 'a/cb/e/', + 'a/cb/e/f' ] + + t.same(results, expect) + t.end() + }) +}) + +test("mark, no / on pattern", function (t) { + glob("a/*", {mark: true}, function (er, results) { + if (er) + throw er + var expect = [ 'a/abcdef/', + 'a/abcfed/', + 'a/b/', + 'a/bc/', + 'a/c/', + 'a/cb/' ] + + if (process.platform !== "win32") + expect.push('a/symlink/') + + t.same(results, expect) + t.end() + }).on('match', function(m) { + t.similar(m, /\/$/) + }) +}) + +test("mark=false, no / on pattern", function (t) { + glob("a/*", function (er, results) { + if (er) + throw er + var expect = [ 'a/abcdef', + 'a/abcfed', + 'a/b', + 'a/bc', + 'a/c', + 'a/cb' ] + + if (process.platform !== "win32") + expect.push('a/symlink') + t.same(results, expect) + t.end() + }).on('match', function(m) { + t.similar(m, /[^\/]$/) + }) +}) + +test("mark=true, / on pattern", function (t) { + glob("a/*/", {mark: true}, function (er, results) { + if (er) + throw er + var expect = [ 'a/abcdef/', + 'a/abcfed/', + 'a/b/', + 'a/bc/', + 'a/c/', + 'a/cb/' ] + if (process.platform !== "win32") + expect.push('a/symlink/') + t.same(results, expect) + t.end() + }).on('match', function(m) { + t.similar(m, /\/$/) + }) +}) + +test("mark=false, / on pattern", function (t) { + glob("a/*/", function (er, results) { + if (er) + throw er + var expect = [ 'a/abcdef/', + 'a/abcfed/', + 'a/b/', + 'a/bc/', + 'a/c/', + 'a/cb/' ] + if (process.platform !== "win32") + expect.push('a/symlink/') + t.same(results, expect) + t.end() + }).on('match', function(m) { + t.similar(m, /\/$/) + }) +}) diff --git a/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js b/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js new file mode 100644 index 0000000..3e7dc5a --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js @@ -0,0 +1,10 @@ +var Glob = require('../glob.js').Glob; +var test = require('tap').test; + +test('new glob, with cb, and no options', function (t) { + new Glob(__filename, function(er, results) { + if (er) throw er; + t.same(results, [__filename]); + t.end(); + }); +}); diff --git a/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js b/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js new file mode 100644 index 0000000..2503f23 --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js @@ -0,0 +1,113 @@ +var fs = require('fs'); +var test = require('tap').test; +var glob = require('../'); + +test('mock fs', function(t) { + var stat = fs.stat + var statSync = fs.statSync + var readdir = fs.readdir + var readdirSync = fs.readdirSync + + function fakeStat(path) { + var ret + switch (path.toLowerCase()) { + case '/tmp': case '/tmp/': + ret = { isDirectory: function() { return true } } + break + case '/tmp/a': + ret = { isDirectory: function() { return false } } + break + } + return ret + } + + fs.stat = function(path, cb) { + var f = fakeStat(path); + if (f) { + process.nextTick(function() { + cb(null, f) + }) + } else { + stat.call(fs, path, cb) + } + } + + fs.statSync = function(path) { + return fakeStat(path) || statSync.call(fs, path) + } + + function fakeReaddir(path) { + var ret + switch (path.toLowerCase()) { + case '/tmp': case '/tmp/': + ret = [ 'a', 'A' ] + break + case '/': + ret = ['tmp', 'tMp', 'tMP', 'TMP'] + } + return ret + } + + fs.readdir = function(path, cb) { + var f = fakeReaddir(path) + if (f) + process.nextTick(function() { + cb(null, f) + }) + else + readdir.call(fs, path, cb) + } + + fs.readdirSync = function(path) { + return fakeReaddir(path) || readdirSync.call(fs, path) + } + + t.pass('mocked') + t.end() +}) + +test('nocase, nomagic', function(t) { + var n = 2 + var want = [ '/TMP/A', + '/TMP/a', + '/tMP/A', + '/tMP/a', + '/tMp/A', + '/tMp/a', + '/tmp/A', + '/tmp/a' ] + glob('/tmp/a', { nocase: true }, function(er, res) { + if (er) + throw er + t.same(res.sort(), want) + if (--n === 0) t.end() + }) + glob('/tmp/A', { nocase: true }, function(er, res) { + if (er) + throw er + t.same(res.sort(), want) + if (--n === 0) t.end() + }) +}) + +test('nocase, with some magic', function(t) { + t.plan(2) + var want = [ '/TMP/A', + '/TMP/a', + '/tMP/A', + '/tMP/a', + '/tMp/A', + '/tMp/a', + '/tmp/A', + '/tmp/a' ] + glob('/tmp/*', { nocase: true }, function(er, res) { + if (er) + throw er + t.same(res.sort(), want) + }) + glob('/tmp/*', { nocase: true }, function(er, res) { + if (er) + throw er + t.same(res.sort(), want) + }) +}) diff --git a/node_modules/findup-sync/node_modules/glob/test/pause-resume.js b/node_modules/findup-sync/node_modules/glob/test/pause-resume.js new file mode 100644 index 0000000..e1ffbab --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/test/pause-resume.js @@ -0,0 +1,73 @@ +// show that no match events happen while paused. +var tap = require("tap") +, child_process = require("child_process") +// just some gnarly pattern with lots of matches +, pattern = "test/a/!(symlink)/**" +, bashResults = require("./bash-results.json") +, patterns = Object.keys(bashResults) +, glob = require("../") +, Glob = glob.Glob +, path = require("path") + +// run from the root of the project +// this is usually where you're at anyway, but be sure. +process.chdir(path.resolve(__dirname, "..")) + +function alphasort (a, b) { + a = a.toLowerCase() + b = b.toLowerCase() + return a > b ? 1 : a < b ? -1 : 0 +} + +function cleanResults (m) { + // normalize discrepancies in ordering, duplication, + // and ending slashes. + return m.map(function (m) { + return m.replace(/\/+/g, "/").replace(/\/$/, "") + }).sort(alphasort).reduce(function (set, f) { + if (f !== set[set.length - 1]) set.push(f) + return set + }, []).sort(alphasort).map(function (f) { + // de-windows + return (process.platform !== 'win32') ? f + : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/') + }) +} + +var globResults = [] +tap.test("use a Glob object, and pause/resume it", function (t) { + var g = new Glob(pattern) + , paused = false + , res = [] + , expect = bashResults[pattern] + + g.on("pause", function () { + console.error("pause") + }) + + g.on("resume", function () { + console.error("resume") + }) + + g.on("match", function (m) { + t.notOk(g.paused, "must not be paused") + globResults.push(m) + g.pause() + t.ok(g.paused, "must be paused") + setTimeout(g.resume.bind(g), 10) + }) + + g.on("end", function (matches) { + t.pass("reached glob end") + globResults = cleanResults(globResults) + matches = cleanResults(matches) + t.deepEqual(matches, globResults, + "end event matches should be the same as match events") + + t.deepEqual(matches, expect, + "glob matches should be the same as bash results") + + t.end() + }) +}) + diff --git a/node_modules/findup-sync/node_modules/glob/test/readme-issue.js b/node_modules/findup-sync/node_modules/glob/test/readme-issue.js new file mode 100644 index 0000000..0b4e0be --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/test/readme-issue.js @@ -0,0 +1,36 @@ +var test = require("tap").test +var glob = require("../") + +var mkdirp = require("mkdirp") +var fs = require("fs") +var rimraf = require("rimraf") +var dir = __dirname + "/package" + +test("setup", function (t) { + mkdirp.sync(dir) + fs.writeFileSync(dir + "/package.json", "{}", "ascii") + fs.writeFileSync(dir + "/README", "x", "ascii") + t.pass("setup done") + t.end() +}) + +test("glob", function (t) { + var opt = { + cwd: dir, + nocase: true, + mark: true + } + + glob("README?(.*)", opt, function (er, files) { + if (er) + throw er + t.same(files, ["README"]) + t.end() + }) +}) + +test("cleanup", function (t) { + rimraf.sync(dir) + t.pass("clean") + t.end() +}) diff --git a/node_modules/findup-sync/node_modules/glob/test/root-nomount.js b/node_modules/findup-sync/node_modules/glob/test/root-nomount.js new file mode 100644 index 0000000..3ac5979 --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/test/root-nomount.js @@ -0,0 +1,39 @@ +var tap = require("tap") + +var origCwd = process.cwd() +process.chdir(__dirname) + +tap.test("changing root and searching for /b*/**", function (t) { + var glob = require('../') + var path = require('path') + t.test('.', function (t) { + glob('/b*/**', { globDebug: true, root: '.', nomount: true }, function (er, matches) { + t.ifError(er) + t.like(matches, []) + t.end() + }) + }) + + t.test('a', function (t) { + glob('/b*/**', { globDebug: true, root: path.resolve('a'), nomount: true }, function (er, matches) { + t.ifError(er) + t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) + t.end() + }) + }) + + t.test('root=a, cwd=a/b', function (t) { + glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b'), nomount: true }, function (er, matches) { + t.ifError(er) + t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) + t.end() + }) + }) + + t.test('cd -', function (t) { + process.chdir(origCwd) + t.end() + }) + + t.end() +}) diff --git a/node_modules/findup-sync/node_modules/glob/test/root.js b/node_modules/findup-sync/node_modules/glob/test/root.js new file mode 100644 index 0000000..95c23f9 --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/test/root.js @@ -0,0 +1,46 @@ +var t = require("tap") + +var origCwd = process.cwd() +process.chdir(__dirname) + +var glob = require('../') +var path = require('path') + +t.test('.', function (t) { + glob('/b*/**', { globDebug: true, root: '.' }, function (er, matches) { + t.ifError(er) + t.like(matches, []) + t.end() + }) +}) + + +t.test('a', function (t) { + console.error("root=" + path.resolve('a')) + glob('/b*/**', { globDebug: true, root: path.resolve('a') }, function (er, matches) { + t.ifError(er) + var wanted = [ + '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' + ].map(function (m) { + return path.join(path.resolve('a'), m).replace(/\\/g, '/') + }) + + t.like(matches, wanted) + t.end() + }) +}) + +t.test('root=a, cwd=a/b', function (t) { + glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b') }, function (er, matches) { + t.ifError(er) + t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) { + return path.join(path.resolve('a'), m).replace(/\\/g, '/') + })) + t.end() + }) +}) + +t.test('cd -', function (t) { + process.chdir(origCwd) + t.end() +}) diff --git a/node_modules/findup-sync/node_modules/glob/test/stat.js b/node_modules/findup-sync/node_modules/glob/test/stat.js new file mode 100644 index 0000000..6291711 --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/test/stat.js @@ -0,0 +1,32 @@ +var glob = require('../') +var test = require('tap').test +var path = require('path') + +test('stat all the things', function(t) { + var g = new glob.Glob('a/*abc*/**', { stat: true, cwd: __dirname }) + var matches = [] + g.on('match', function(m) { + matches.push(m) + }) + var stats = [] + g.on('stat', function(m) { + stats.push(m) + }) + g.on('end', function(eof) { + stats = stats.sort() + matches = matches.sort() + eof = eof.sort() + t.same(stats, matches) + t.same(eof, matches) + var cache = Object.keys(this.statCache) + t.same(cache.map(function (f) { + return path.relative(__dirname, f) + }).sort(), matches) + + cache.forEach(function(c) { + t.equal(typeof this.statCache[c], 'object') + }, this) + + t.end() + }) +}) diff --git a/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js b/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js new file mode 100644 index 0000000..e085f0f --- /dev/null +++ b/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js @@ -0,0 +1,11 @@ +// remove the fixtures +var tap = require("tap") +, rimraf = require("rimraf") +, path = require("path") + +tap.test("cleanup fixtures", function (t) { + rimraf(path.resolve(__dirname, "a"), function (er) { + t.ifError(er, "removed") + t.end() + }) +}) diff --git a/node_modules/findup-sync/node_modules/lodash/LICENSE.txt b/node_modules/findup-sync/node_modules/lodash/LICENSE.txt new file mode 100644 index 0000000..49869bb --- /dev/null +++ b/node_modules/findup-sync/node_modules/lodash/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright 2012-2013 The Dojo Foundation +Based on Underscore.js 1.5.2, copyright 2009-2013 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/findup-sync/node_modules/lodash/README.md b/node_modules/findup-sync/node_modules/lodash/README.md new file mode 100644 index 0000000..86b0636 --- /dev/null +++ b/node_modules/findup-sync/node_modules/lodash/README.md @@ -0,0 +1,145 @@ +# Lo-Dash v2.4.2 +A utility library delivering consistency, [customization](https://lodash.com/custom-builds), [performance](https://lodash.com/benchmarks), & [extras](https://lodash.com/#features). + +## Download + +Check out our [wiki]([https://github.com/lodash/lodash/wiki/build-differences]) for details over the differences between builds. + +* Modern builds perfect for newer browsers/environments:
+[Development](https://raw.github.com/lodash/lodash/2.4.2/dist/lodash.js) & +[Production](https://raw.github.com/lodash/lodash/2.4.2/dist/lodash.min.js) + +* Compatibility builds for older environment support too:
+[Development](https://raw.github.com/lodash/lodash/2.4.2/dist/lodash.compat.js) & +[Production](https://raw.github.com/lodash/lodash/2.4.2/dist/lodash.compat.min.js) + +* Underscore builds to use as a drop-in replacement:
+[Development](https://raw.github.com/lodash/lodash/2.4.2/dist/lodash.underscore.js) & +[Production](https://raw.github.com/lodash/lodash/2.4.2/dist/lodash.underscore.min.js) + +CDN copies are available on [cdnjs](http://cdnjs.com/libraries/lodash.js/) & [jsDelivr](http://www.jsdelivr.com/#!lodash). For smaller file sizes, create [custom builds](https://lodash.com/custom-builds) with only the features needed. + +Love modules? We’ve got you covered with [lodash-amd](https://npmjs.org/package/lodash-amd), [lodash-es6](https://github.com/lodash/lodash-es6), [lodash-node](https://npmjs.org/package/lodash-node), & [npm packages](https://npmjs.org/browse/keyword/lodash-modularized) per method. + +## Dive in + +There’s plenty of **[documentation](https://lodash.com/docs)**, [unit tests](https://lodash.com/tests), & [benchmarks](https://lodash.com/benchmarks).
+Check out DevDocs as a fast, organized, & searchable interface for our documentation. + +The full changelog for this release is available on our [wiki](https://github.com/lodash/lodash/wiki/Changelog).
+A list of upcoming features is available on our [roadmap](https://github.com/lodash/lodash/wiki/Roadmap). + +## Installation & usage + +In browsers: + +```html + +``` + +Using [`npm`](http://npmjs.org/): + +```bash +npm i --save lodash + +{sudo} npm i -g lodash +npm ln lodash +``` + +In [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/): + +```js +var _ = require('lodash'); +// or as Underscore +var _ = require('lodash/dist/lodash.underscore'); +``` + +**Notes:** + * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL + * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it + +In [Rhino](http://www.mozilla.org/rhino/): + +```js +load('lodash.js'); +``` + +In an AMD loader: + +```js +require({ + 'packages': [ + { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' } + ] +}, +['lodash'], function(_) { + console.log(_.VERSION); +}); +``` + +## Resources + + * Podcasts + - [JavaScript Jabber](http://javascriptjabber.com/079-jsj-lo-dash-with-john-david-dalton/) + + * Posts + - [Say “Hello” to Lo-Dash](http://kitcambridge.be/blog/say-hello-to-lo-dash/) + - [Custom builds in Lo-Dash 2.0](http://kitcambridge.be/blog/custom-builds-in-lo-dash-2-dot-0/) + + * Videos + - [Introduction](https://vimeo.com/44154599) + - [Origins](https://vimeo.com/44154600) + - [Optimizations & builds](https://vimeo.com/44154601) + - [Native method use](https://vimeo.com/48576012) + - [Testing](https://vimeo.com/45865290) + - [CascadiaJS ’12](http://www.youtube.com/watch?v=dpPy4f_SeEk) + + A list of other community created podcasts, posts, & videos is available on our [wiki](https://github.com/lodash/lodash/wiki/Resources). + +## Features + + * AMD loader support ([curl](https://github.com/cujojs/curl), [dojo](http://dojotoolkit.org/), [requirejs](http://requirejs.org/), etc.) + * [_(…)](https://lodash.com/docs#_) supports intuitive chaining + * [_.at](https://lodash.com/docs#at) for cherry-picking collection values + * [_.bindKey](https://lodash.com/docs#bindKey) for binding [*“lazy”*](http://michaux.ca/articles/lazy-function-definition-pattern) defined methods + * [_.clone](https://lodash.com/docs#clone) supports shallow cloning of `Date` & `RegExp` objects + * [_.cloneDeep](https://lodash.com/docs#cloneDeep) for deep cloning arrays & objects + * [_.constant](https://lodash.com/docs#constant) & [_.property](https://lodash.com/docs#property) function generators for composing functions + * [_.contains](https://lodash.com/docs#contains) accepts a `fromIndex` + * [_.create](https://lodash.com/docs#create) for easier object inheritance + * [_.createCallback](https://lodash.com/docs#createCallback) for extending callbacks in methods & mixins + * [_.curry](https://lodash.com/docs#curry) for creating [curried](http://hughfdjackson.com/javascript/2013/07/06/why-curry-helps/) functions + * [_.debounce](https://lodash.com/docs#debounce) & [_.throttle](https://lodash.com/docs#throttle) accept additional `options` for more control + * [_.findIndex](https://lodash.com/docs#findIndex) & [_.findKey](https://lodash.com/docs#findKey) for finding indexes & keys + * [_.forEach](https://lodash.com/docs#forEach) is chainable & supports exiting early + * [_.forIn](https://lodash.com/docs#forIn) for iterating own & inherited properties + * [_.forOwn](https://lodash.com/docs#forOwn) for iterating own properties + * [_.isPlainObject](https://lodash.com/docs#isPlainObject) for checking if values are created by `Object` + * [_.mapValues](https://lodash.com/docs#mapValues) for [mapping](https://lodash.com/docs#map) values to an object + * [_.memoize](https://lodash.com/docs#memoize) exposes the `cache` of memoized functions + * [_.merge](https://lodash.com/docs#merge) for a deep [_.extend](https://lodash.com/docs#extend) + * [_.noop](https://lodash.com/docs#noop) for function placeholders + * [_.now](https://lodash.com/docs#now) as a cross-browser `Date.now` alternative + * [_.parseInt](https://lodash.com/docs#parseInt) for consistent behavior + * [_.pull](https://lodash.com/docs#pull) & [_.remove](https://lodash.com/docs#remove) for mutating arrays + * [_.random](https://lodash.com/docs#random) supports returning floating-point numbers + * [_.runInContext](https://lodash.com/docs#runInContext) for easier mocking + * [_.sortBy](https://lodash.com/docs#sortBy) supports sorting by multiple properties + * [_.support](https://lodash.com/docs#support) for flagging environment features + * [_.template](https://lodash.com/docs#template) supports [*“imports”*](https://lodash.com/docs#templateSettings_imports) options & [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals) + * [_.transform](https://lodash.com/docs#transform) as a powerful alternative to [_.reduce](https://lodash.com/docs#reduce) for transforming objects + * [_.where](https://lodash.com/docs#where) supports deep object comparisons + * [_.xor](https://lodash.com/docs#xor) as a companion to [_.difference](https://lodash.com/docs#difference), [_.intersection](https://lodash.com/docs#intersection), & [_.union](https://lodash.com/docs#union) + * [_.zip](https://lodash.com/docs#zip) is capable of unzipping values + * [_.omit](https://lodash.com/docs#omit), [_.pick](https://lodash.com/docs#pick), & + [more](https://lodash.com/docs "_.assign, _.clone, _.cloneDeep, _.first, _.initial, _.isEqual, _.last, _.merge, _.rest") accept callbacks + * [_.contains](https://lodash.com/docs#contains), [_.toArray](https://lodash.com/docs#toArray), & + [more](https://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.forEach, _.forEachRight, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.size, _.some, _.sortBy, _.where") accept strings + * [_.filter](https://lodash.com/docs#filter), [_.map](https://lodash.com/docs#map), & + [more](https://lodash.com/docs "_.countBy, _.every, _.find, _.findKey, _.findLast, _.findLastIndex, _.findLastKey, _.first, _.groupBy, _.initial, _.last, _.max, _.min, _.reject, _.rest, _.some, _.sortBy, _.sortedIndex, _.uniq") support *“_.pluck”* & *“_.where”* shorthands + * [_.findLast](https://lodash.com/docs#findLast), [_.findLastIndex](https://lodash.com/docs#findLastIndex), & + [more](https://lodash.com/docs "_.findLastKey, _.forEachRight, _.forInRight, _.forOwnRight, _.partialRight") right-associative methods + +## Support + +Tested in Chrome 5~31, Firefox 2~25, IE 6-11, Opera 9.25-17, Safari 3-7, Node.js 0.6.21-0.10.22, Narwhal 0.3.2, PhantomJS 1.9.2, RingoJS 0.9, & Rhino 1.7RC5. diff --git a/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js b/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js new file mode 100644 index 0000000..4d35185 --- /dev/null +++ b/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js @@ -0,0 +1,7158 @@ +/** + * @license + * Lo-Dash 2.4.2 (Custom Build) + * Build: `lodash -o ./dist/lodash.compat.js` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre ES5 environments */ + var undefined; + + /** Used to pool arrays and objects used internally */ + var arrayPool = [], + objectPool = []; + + /** Used to generate unique IDs */ + var idCounter = 0; + + /** Used internally to indicate various things */ + var indicatorObject = {}; + + /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */ + var keyPrefix = +new Date + ''; + + /** Used as the size when optimizations are enabled for large arrays */ + var largeArraySize = 75; + + /** Used as the max size of the `arrayPool` and `objectPool` */ + var maxPoolSize = 40; + + /** Used to detect and test whitespace */ + var whitespace = ( + // whitespace + ' \t\x0B\f\xA0\ufeff' + + + // line terminators + '\n\r\u2028\u2029' + + + // unicode category "Zs" space separators + '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' + ); + + /** Used to match empty string literals in compiled template source */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** + * Used to match ES6 template delimiters + * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals + */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match regexp flags from their coerced string values */ + var reFlags = /\w*$/; + + /** Used to detected named functions */ + var reFuncName = /^\s*function[ \n\r\t]+\w/; + + /** Used to match "interpolate" template delimiters */ + var reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match leading whitespace and zeros to be removed */ + var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)'); + + /** Used to ensure capturing order of template delimiters */ + var reNoMatch = /($^)/; + + /** Used to detect functions containing a `this` reference */ + var reThis = /\bthis\b/; + + /** Used to match unescaped characters in compiled string literals */ + var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; + + /** Used to assign default `context` object properties */ + var contextProps = [ + 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object', + 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', + 'parseInt', 'setTimeout' + ]; + + /** Used to fix the JScript [[DontEnum]] bug */ + var shadowedProps = [ + 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', + 'toLocaleString', 'toString', 'valueOf' + ]; + + /** Used to make template sourceURLs easier to identify */ + var templateCounter = 0; + + /** `Object#toString` result shortcuts */ + var argsClass = '[object Arguments]', + arrayClass = '[object Array]', + boolClass = '[object Boolean]', + dateClass = '[object Date]', + errorClass = '[object Error]', + funcClass = '[object Function]', + numberClass = '[object Number]', + objectClass = '[object Object]', + regexpClass = '[object RegExp]', + stringClass = '[object String]'; + + /** Used to identify object classifications that `_.clone` supports */ + var cloneableClasses = {}; + cloneableClasses[funcClass] = false; + cloneableClasses[argsClass] = cloneableClasses[arrayClass] = + cloneableClasses[boolClass] = cloneableClasses[dateClass] = + cloneableClasses[numberClass] = cloneableClasses[objectClass] = + cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; + + /** Used as an internal `_.debounce` options object */ + var debounceOptions = { + 'leading': false, + 'maxWait': 0, + 'trailing': false + }; + + /** Used as the property descriptor for `__bindData__` */ + var descriptor = { + 'configurable': false, + 'enumerable': false, + 'value': null, + 'writable': false + }; + + /** Used as the data object for `iteratorTemplate` */ + var iteratorData = { + 'args': '', + 'array': null, + 'bottom': '', + 'firstArg': '', + 'init': '', + 'keys': null, + 'loop': '', + 'shadowedProps': null, + 'support': null, + 'top': '', + 'useHas': false + }; + + /** Used to determine if values are of the language type Object */ + var objectTypes = { + 'boolean': false, + 'function': true, + 'object': true, + 'number': false, + 'string': false, + 'undefined': false + }; + + /** Used to escape characters for inclusion in compiled string literals */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\t': 't', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Used as a reference to the global object */ + var root = (objectTypes[typeof window] && window) || this; + + /** Detect free variable `exports` */ + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + + /** Detect free variable `module` */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports` */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + + /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ + var freeGlobal = objectTypes[typeof global] && global; + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { + root = freeGlobal; + } + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.indexOf` without support for binary searches + * or `fromIndex` constraints. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * An implementation of `_.contains` for cache objects that mimics the return + * signature of `_.indexOf` by returning `0` if the value is found, else `-1`. + * + * @private + * @param {Object} cache The cache object to inspect. + * @param {*} value The value to search for. + * @returns {number} Returns `0` if `value` is found, else `-1`. + */ + function cacheIndexOf(cache, value) { + var type = typeof value; + cache = cache.cache; + + if (type == 'boolean' || value == null) { + return cache[value] ? 0 : -1; + } + if (type != 'number' && type != 'string') { + type = 'object'; + } + var key = type == 'number' ? value : keyPrefix + value; + cache = (cache = cache[type]) && cache[key]; + + return type == 'object' + ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1) + : (cache ? 0 : -1); + } + + /** + * Adds a given value to the corresponding cache object. + * + * @private + * @param {*} value The value to add to the cache. + */ + function cachePush(value) { + var cache = this.cache, + type = typeof value; + + if (type == 'boolean' || value == null) { + cache[value] = true; + } else { + if (type != 'number' && type != 'string') { + type = 'object'; + } + var key = type == 'number' ? value : keyPrefix + value, + typeCache = cache[type] || (cache[type] = {}); + + if (type == 'object') { + (typeCache[key] || (typeCache[key] = [])).push(value); + } else { + typeCache[key] = true; + } + } + } + + /** + * Used by `_.max` and `_.min` as the default callback when a given + * collection is a string value. + * + * @private + * @param {string} value The character to inspect. + * @returns {number} Returns the code unit of given character. + */ + function charAtCallback(value) { + return value.charCodeAt(0); + } + + /** + * Used by `sortBy` to compare transformed `collection` elements, stable sorting + * them in ascending order. + * + * @private + * @param {Object} a The object to compare to `b`. + * @param {Object} b The object to compare to `a`. + * @returns {number} Returns the sort order indicator of `1` or `-1`. + */ + function compareAscending(a, b) { + var ac = a.criteria, + bc = b.criteria, + index = -1, + length = ac.length; + + while (++index < length) { + var value = ac[index], + other = bc[index]; + + if (value !== other) { + if (value > other || typeof value == 'undefined') { + return 1; + } + if (value < other || typeof other == 'undefined') { + return -1; + } + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to return the same value for + // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247 + // + // This also ensures a stable sort in V8 and other engines. + // See http://code.google.com/p/v8/issues/detail?id=90 + return a.index - b.index; + } + + /** + * Creates a cache object to optimize linear searches of large arrays. + * + * @private + * @param {Array} [array=[]] The array to search. + * @returns {null|Object} Returns the cache object or `null` if caching should not be used. + */ + function createCache(array) { + var index = -1, + length = array.length, + first = array[0], + mid = array[(length / 2) | 0], + last = array[length - 1]; + + if (first && typeof first == 'object' && + mid && typeof mid == 'object' && last && typeof last == 'object') { + return false; + } + var cache = getObject(); + cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false; + + var result = getObject(); + result.array = array; + result.cache = cache; + result.push = cachePush; + + while (++index < length) { + result.push(array[index]); + } + return result; + } + + /** + * Used by `template` to escape characters for inclusion in compiled + * string literals. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(match) { + return '\\' + stringEscapes[match]; + } + + /** + * Gets an array from the array pool or creates a new one if the pool is empty. + * + * @private + * @returns {Array} The array from the pool. + */ + function getArray() { + return arrayPool.pop() || []; + } + + /** + * Gets an object from the object pool or creates a new one if the pool is empty. + * + * @private + * @returns {Object} The object from the pool. + */ + function getObject() { + return objectPool.pop() || { + 'array': null, + 'cache': null, + 'criteria': null, + 'false': false, + 'index': 0, + 'null': false, + 'number': null, + 'object': null, + 'push': null, + 'string': null, + 'true': false, + 'undefined': false, + 'value': null + }; + } + + /** + * Checks if `value` is a DOM node in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`. + */ + function isNode(value) { + // IE < 9 presents DOM nodes as `Object` objects except they have `toString` + // methods that are `typeof` "string" and still can coerce nodes to strings + return typeof value.toString != 'function' && typeof (value + '') == 'string'; + } + + /** + * Releases the given array back to the array pool. + * + * @private + * @param {Array} [array] The array to release. + */ + function releaseArray(array) { + array.length = 0; + if (arrayPool.length < maxPoolSize) { + arrayPool.push(array); + } + } + + /** + * Releases the given object back to the object pool. + * + * @private + * @param {Object} [object] The object to release. + */ + function releaseObject(object) { + var cache = object.cache; + if (cache) { + releaseObject(cache); + } + object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null; + if (objectPool.length < maxPoolSize) { + objectPool.push(object); + } + } + + /** + * Slices the `collection` from the `start` index up to, but not including, + * the `end` index. + * + * Note: This function is used instead of `Array#slice` to support node lists + * in IE < 9 and to ensure dense arrays are returned. + * + * @private + * @param {Array|Object|string} collection The collection to slice. + * @param {number} start The start index. + * @param {number} end The end index. + * @returns {Array} Returns the new array. + */ + function slice(array, start, end) { + start || (start = 0); + if (typeof end == 'undefined') { + end = array ? array.length : 0; + } + var index = -1, + length = end - start || 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = array[start + index]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new `lodash` function using the given context object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} [context=root] The context object. + * @returns {Function} Returns the `lodash` function. + */ + function runInContext(context) { + // Avoid issues with some ES3 environments that attempt to use values, named + // after built-in constructors like `Object`, for the creation of literals. + // ES5 clears this up by stating that literals must use built-in constructors. + // See http://es5.github.io/#x11.1.5. + context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; + + /** Native constructor references */ + var Array = context.Array, + Boolean = context.Boolean, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Number = context.Number, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** + * Used for `Array` method references. + * + * Normally `Array.prototype` would suffice, however, using an array literal + * avoids issues in Narwhal. + */ + var arrayRef = []; + + /** Used for native method references */ + var errorProto = Error.prototype, + objectProto = Object.prototype, + stringProto = String.prototype; + + /** Used to restore the original `_` reference in `noConflict` */ + var oldDash = context._; + + /** Used to resolve the internal [[Class]] of values */ + var toString = objectProto.toString; + + /** Used to detect if a method is native */ + var reNative = RegExp('^' + + String(toString) + .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + .replace(/toString| for [^\]]+/g, '.*?') + '$' + ); + + /** Native method shortcuts */ + var ceil = Math.ceil, + clearTimeout = context.clearTimeout, + floor = Math.floor, + fnToString = Function.prototype.toString, + getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, + hasOwnProperty = objectProto.hasOwnProperty, + push = arrayRef.push, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + setTimeout = context.setTimeout, + splice = arrayRef.splice, + unshift = arrayRef.unshift; + + /** Used to set meta data on functions */ + var defineProperty = (function() { + // IE 8 only accepts DOM elements + try { + var o = {}, + func = isNative(func = Object.defineProperty) && func, + result = func(o, o, o) && func; + } catch(e) { } + return result; + }()); + + /* Native method shortcuts for methods with the same name as other `lodash` methods */ + var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, + nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, + nativeIsFinite = context.isFinite, + nativeIsNaN = context.isNaN, + nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, + nativeMax = Math.max, + nativeMin = Math.min, + nativeParseInt = context.parseInt, + nativeRandom = Math.random; + + /** Used to lookup a built-in constructor by [[Class]] */ + var ctorByClass = {}; + ctorByClass[arrayClass] = Array; + ctorByClass[boolClass] = Boolean; + ctorByClass[dateClass] = Date; + ctorByClass[funcClass] = Function; + ctorByClass[objectClass] = Object; + ctorByClass[numberClass] = Number; + ctorByClass[regexpClass] = RegExp; + ctorByClass[stringClass] = String; + + /** Used to avoid iterating non-enumerable properties in IE < 9 */ + var nonEnumProps = {}; + nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; + nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true }; + nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true }; + nonEnumProps[objectClass] = { 'constructor': true }; + + (function() { + var length = shadowedProps.length; + while (length--) { + var key = shadowedProps[length]; + for (var className in nonEnumProps) { + if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) { + nonEnumProps[className][key] = false; + } + } + } + }()); + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps the given value to enable intuitive + * method chaining. + * + * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, + * and `unshift` + * + * Chaining is supported in custom builds as long as the `value` method is + * implicitly or explicitly included in the build. + * + * The chainable wrapper functions are: + * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, + * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, + * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, + * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, + * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, + * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, + * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, + * and `zip` + * + * The non-chainable wrapper functions are: + * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`, + * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, + * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, + * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`, + * `template`, `unescape`, `uniqueId`, and `value` + * + * The wrapper functions `first` and `last` return wrapped values when `n` is + * provided, otherwise they return unwrapped values. + * + * Explicit chaining can be enabled by using the `_.chain` method. + * + * @name _ + * @constructor + * @category Chaining + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns a `lodash` instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(num) { + * return num * num; + * }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor + return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__')) + ? value + : new lodashWrapper(value); + } + + /** + * A fast path for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap in a `lodash` instance. + * @param {boolean} chainAll A flag to enable chaining for all methods + * @returns {Object} Returns a `lodash` instance. + */ + function lodashWrapper(value, chainAll) { + this.__chain__ = !!chainAll; + this.__wrapped__ = value; + } + // ensure `new lodashWrapper` is an instance of `lodash` + lodashWrapper.prototype = lodash.prototype; + + /** + * An object used to flag environments features. + * + * @static + * @memberOf _ + * @type Object + */ + var support = lodash.support = {}; + + (function() { + var ctor = function() { this.x = 1; }, + object = { '0': 1, 'length': 1 }, + props = []; + + ctor.prototype = { 'valueOf': 1, 'y': 1 }; + for (var key in new ctor) { props.push(key); } + for (key in arguments) { } + + /** + * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9). + * + * @memberOf _.support + * @type boolean + */ + support.argsClass = toString.call(arguments) == argsClass; + + /** + * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5). + * + * @memberOf _.support + * @type boolean + */ + support.argsObject = arguments.constructor == Object && !(arguments instanceof Array); + + /** + * Detect if `name` or `message` properties of `Error.prototype` are + * enumerable by default. (IE < 9, Safari < 5.1) + * + * @memberOf _.support + * @type boolean + */ + support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name'); + + /** + * Detect if `prototype` properties are enumerable by default. + * + * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 + * (if the prototype or a property on the prototype has been set) + * incorrectly sets a function's `prototype` property [[Enumerable]] + * value to `true`. + * + * @memberOf _.support + * @type boolean + */ + support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype'); + + /** + * Detect if functions can be decompiled by `Function#toString` + * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). + * + * @memberOf _.support + * @type boolean + */ + support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); + + /** + * Detect if `Function#name` is supported (all but IE). + * + * @memberOf _.support + * @type boolean + */ + support.funcNames = typeof Function.name == 'string'; + + /** + * Detect if `arguments` object indexes are non-enumerable + * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1). + * + * @memberOf _.support + * @type boolean + */ + support.nonEnumArgs = key != 0; + + /** + * Detect if properties shadowing those on `Object.prototype` are non-enumerable. + * + * In IE < 9 an objects own properties, shadowing non-enumerable ones, are + * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug). + * + * @memberOf _.support + * @type boolean + */ + support.nonEnumShadows = !/valueOf/.test(props); + + /** + * Detect if own properties are iterated after inherited properties (all but IE < 9). + * + * @memberOf _.support + * @type boolean + */ + support.ownLast = props[0] != 'x'; + + /** + * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly. + * + * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` + * and `splice()` functions that fail to remove the last element, `value[0]`, + * of array-like objects even though the `length` property is set to `0`. + * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` + * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. + * + * @memberOf _.support + * @type boolean + */ + support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]); + + /** + * Detect lack of support for accessing string characters by index. + * + * IE < 8 can't access characters by index and IE 8 can only access + * characters by index on string literals. + * + * @memberOf _.support + * @type boolean + */ + support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; + + /** + * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9) + * and that the JS engine errors when attempting to coerce an object to + * a string without a `toString` function. + * + * @memberOf _.support + * @type boolean + */ + try { + support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + '')); + } catch(e) { + support.nodeClass = true; + } + }(1)); + + /** + * By default, the template delimiters used by Lo-Dash are similar to those in + * embedded Ruby (ERB). Change the following template settings to use alternative + * delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': /<%-([\s\S]+?)%>/g, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': /<%([\s\S]+?)%>/g, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type Object + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type Function + */ + '_': lodash + } + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The template used to create iterator functions. + * + * @private + * @param {Object} data The data object used to populate the text. + * @returns {string} Returns the interpolated text. + */ + var iteratorTemplate = function(obj) { + + var __p = 'var index, iterable = ' + + (obj.firstArg) + + ', result = ' + + (obj.init) + + ';\nif (!iterable) return result;\n' + + (obj.top) + + ';'; + if (obj.array) { + __p += '\nvar length = iterable.length; index = -1;\nif (' + + (obj.array) + + ') { '; + if (support.unindexedChars) { + __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } '; + } + __p += '\n while (++index < length) {\n ' + + (obj.loop) + + ';\n }\n}\nelse { '; + } else if (support.nonEnumArgs) { + __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' + + (obj.loop) + + ';\n }\n } else { '; + } + + if (support.enumPrototypes) { + __p += '\n var skipProto = typeof iterable == \'function\';\n '; + } + + if (support.enumErrorProps) { + __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n '; + } + + var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); } + + if (obj.useHas && obj.keys) { + __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n'; + if (conditions.length) { + __p += ' if (' + + (conditions.join(' && ')) + + ') {\n '; + } + __p += + (obj.loop) + + '; '; + if (conditions.length) { + __p += '\n }'; + } + __p += '\n } '; + } else { + __p += '\n for (index in iterable) {\n'; + if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) { + __p += ' if (' + + (conditions.join(' && ')) + + ') {\n '; + } + __p += + (obj.loop) + + '; '; + if (conditions.length) { + __p += '\n }'; + } + __p += '\n } '; + if (support.nonEnumShadows) { + __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n '; + for (k = 0; k < 7; k++) { + __p += '\n index = \'' + + (obj.shadowedProps[k]) + + '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))'; + if (!obj.useHas) { + __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])'; + } + __p += ') {\n ' + + (obj.loop) + + ';\n } '; + } + __p += '\n } '; + } + + } + + if (obj.array || support.nonEnumArgs) { + __p += '\n}'; + } + __p += + (obj.bottom) + + ';\nreturn result'; + + return __p + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.bind` that creates the bound function and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new bound function. + */ + function baseBind(bindData) { + var func = bindData[0], + partialArgs = bindData[2], + thisArg = bindData[4]; + + function bound() { + // `Function#bind` spec + // http://es5.github.io/#x15.3.4.5 + if (partialArgs) { + // avoid `arguments` object deoptimizations by using `slice` instead + // of `Array.prototype.slice.call` and not assigning `arguments` to a + // variable as a ternary expression + var args = slice(partialArgs); + push.apply(args, arguments); + } + // mimic the constructor's `return` behavior + // http://es5.github.io/#x13.2.2 + if (this instanceof bound) { + // ensure `new bound` is an instance of `func` + var thisBinding = baseCreate(func.prototype), + result = func.apply(thisBinding, args || arguments); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisArg, args || arguments); + } + setBindData(bound, bindData); + return bound; + } + + /** + * The base implementation of `_.clone` without argument juggling or support + * for `thisArg` binding. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep=false] Specify a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates clones with source counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, callback, stackA, stackB) { + if (callback) { + var result = callback(value); + if (typeof result != 'undefined') { + return result; + } + } + // inspect [[Class]] + var isObj = isObject(value); + if (isObj) { + var className = toString.call(value); + if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) { + return value; + } + var ctor = ctorByClass[className]; + switch (className) { + case boolClass: + case dateClass: + return new ctor(+value); + + case numberClass: + case stringClass: + return new ctor(value); + + case regexpClass: + result = ctor(value.source, reFlags.exec(value)); + result.lastIndex = value.lastIndex; + return result; + } + } else { + return value; + } + var isArr = isArray(value); + if (isDeep) { + // check for circular references and return corresponding clone + var initedStack = !stackA; + stackA || (stackA = getArray()); + stackB || (stackB = getArray()); + + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + result = isArr ? ctor(value.length) : {}; + } + else { + result = isArr ? slice(value) : assign({}, value); + } + // add array properties assigned by `RegExp#exec` + if (isArr) { + if (hasOwnProperty.call(value, 'index')) { + result.index = value.index; + } + if (hasOwnProperty.call(value, 'input')) { + result.input = value.input; + } + } + // exit for shallow clone + if (!isDeep) { + return result; + } + // add the source value to the stack of traversed objects + // and associate it with its clone + stackA.push(value); + stackB.push(result); + + // recursively populate clone (susceptible to call stack limits) + (isArr ? baseEach : forOwn)(value, function(objValue, key) { + result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); + }); + + if (initedStack) { + releaseArray(stackA); + releaseArray(stackB); + } + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(prototype, properties) { + return isObject(prototype) ? nativeCreate(prototype) : {}; + } + // fallback for browsers without `Object.create` + if (!nativeCreate) { + baseCreate = (function() { + function Object() {} + return function(prototype) { + if (isObject(prototype)) { + Object.prototype = prototype; + var result = new Object; + Object.prototype = null; + } + return result || context.Object(); + }; + }()); + } + + /** + * The base implementation of `_.createCallback` without support for creating + * "_.pluck" or "_.where" style callbacks. + * + * @private + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + */ + function baseCreateCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + // exit early for no `thisArg` or already bound by `Function#bind` + if (typeof thisArg == 'undefined' || !('prototype' in func)) { + return func; + } + var bindData = func.__bindData__; + if (typeof bindData == 'undefined') { + if (support.funcNames) { + bindData = !func.name; + } + bindData = bindData || !support.funcDecomp; + if (!bindData) { + var source = fnToString.call(func); + if (!support.funcNames) { + bindData = !reFuncName.test(source); + } + if (!bindData) { + // checks if `func` references the `this` keyword and stores the result + bindData = reThis.test(source); + setBindData(func, bindData); + } + } + } + // exit early if there are no `this` references or `func` is bound + if (bindData === false || (bindData !== true && bindData[1] & 1)) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 2: return function(a, b) { + return func.call(thisArg, a, b); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + } + return bind(func, thisArg); + } + + /** + * The base implementation of `createWrapper` that creates the wrapper and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new function. + */ + function baseCreateWrapper(bindData) { + var func = bindData[0], + bitmask = bindData[1], + partialArgs = bindData[2], + partialRightArgs = bindData[3], + thisArg = bindData[4], + arity = bindData[5]; + + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + key = func; + + function bound() { + var thisBinding = isBind ? thisArg : this; + if (partialArgs) { + var args = slice(partialArgs); + push.apply(args, arguments); + } + if (partialRightArgs || isCurry) { + args || (args = slice(arguments)); + if (partialRightArgs) { + push.apply(args, partialRightArgs); + } + if (isCurry && args.length < arity) { + bitmask |= 16 & ~32; + return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); + } + } + args || (args = arguments); + if (isBindKey) { + func = thisBinding[key]; + } + if (this instanceof bound) { + thisBinding = baseCreate(func.prototype); + var result = func.apply(thisBinding, args); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisBinding, args); + } + setBindData(bound, bindData); + return bound; + } + + /** + * The base implementation of `_.difference` that accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to process. + * @param {Array} [values] The array of values to exclude. + * @returns {Array} Returns a new array of filtered values. + */ + function baseDifference(array, values) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + isLarge = length >= largeArraySize && indexOf === baseIndexOf, + result = []; + + if (isLarge) { + var cache = createCache(values); + if (cache) { + indexOf = cacheIndexOf; + values = cache; + } else { + isLarge = false; + } + } + while (++index < length) { + var value = array[index]; + if (indexOf(values, value) < 0) { + result.push(value); + } + } + if (isLarge) { + releaseObject(values); + } + return result; + } + + /** + * The base implementation of `_.flatten` without support for callback + * shorthands or `thisArg` binding. + * + * @private + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. + * @param {number} [fromIndex=0] The index to start from. + * @returns {Array} Returns a new flattened array. + */ + function baseFlatten(array, isShallow, isStrict, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + + if (value && typeof value == 'object' && typeof value.length == 'number' + && (isArray(value) || isArguments(value))) { + // recursively flatten arrays (susceptible to call stack limits) + if (!isShallow) { + value = baseFlatten(value, isShallow, isStrict); + } + var valIndex = -1, + valLength = value.length, + resIndex = result.length; + + result.length += valLength; + while (++valIndex < valLength) { + result[resIndex++] = value[valIndex]; + } + } else if (!isStrict) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.isEqual`, without support for `thisArg` binding, + * that allows partial "_.where" style comparisons. + * + * @private + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `a` objects. + * @param {Array} [stackB=[]] Tracks traversed `b` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { + // used to indicate that when comparing objects, `a` has at least the properties of `b` + if (callback) { + var result = callback(a, b); + if (typeof result != 'undefined') { + return !!result; + } + } + // exit early for identical values + if (a === b) { + // treat `+0` vs. `-0` as not equal + return a !== 0 || (1 / a == 1 / b); + } + var type = typeof a, + otherType = typeof b; + + // exit early for unlike primitive values + if (a === a && + !(a && objectTypes[type]) && + !(b && objectTypes[otherType])) { + return false; + } + // exit early for `null` and `undefined` avoiding ES3's Function#call behavior + // http://es5.github.io/#x15.3.4.4 + if (a == null || b == null) { + return a === b; + } + // compare [[Class]] names + var className = toString.call(a), + otherClass = toString.call(b); + + if (className == argsClass) { + className = objectClass; + } + if (otherClass == argsClass) { + otherClass = objectClass; + } + if (className != otherClass) { + return false; + } + switch (className) { + case boolClass: + case dateClass: + // coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal + return +a == +b; + + case numberClass: + // treat `NaN` vs. `NaN` as equal + return (a != +a) + ? b != +b + // but treat `+0` vs. `-0` as not equal + : (a == 0 ? (1 / a == 1 / b) : a == +b); + + case regexpClass: + case stringClass: + // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) + // treat string primitives and their corresponding object instances as equal + return a == String(b); + } + var isArr = className == arrayClass; + if (!isArr) { + // unwrap any `lodash` wrapped values + var aWrapped = hasOwnProperty.call(a, '__wrapped__'), + bWrapped = hasOwnProperty.call(b, '__wrapped__'); + + if (aWrapped || bWrapped) { + return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); + } + // exit for functions and DOM nodes + if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) { + return false; + } + // in older versions of Opera, `arguments` objects have `Array` constructors + var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor, + ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor; + + // non `Object` object instances with different constructors are not equal + if (ctorA != ctorB && + !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && + ('constructor' in a && 'constructor' in b) + ) { + return false; + } + } + // assume cyclic structures are equal + // the algorithm for detecting cyclic structures is adapted from ES 5.1 + // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) + var initedStack = !stackA; + stackA || (stackA = getArray()); + stackB || (stackB = getArray()); + + var length = stackA.length; + while (length--) { + if (stackA[length] == a) { + return stackB[length] == b; + } + } + var size = 0; + result = true; + + // add `a` and `b` to the stack of traversed objects + stackA.push(a); + stackB.push(b); + + // recursively compare objects and arrays (susceptible to call stack limits) + if (isArr) { + // compare lengths to determine if a deep comparison is necessary + length = a.length; + size = b.length; + result = size == length; + + if (result || isWhere) { + // deep compare the contents, ignoring non-numeric properties + while (size--) { + var index = length, + value = b[size]; + + if (isWhere) { + while (index--) { + if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } + } + else { + // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` + // which, in this case, is more costly + forIn(b, function(value, key, b) { + if (hasOwnProperty.call(b, key)) { + // count the number of properties. + size++; + // deep compare each property value. + return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); + } + }); + + if (result && !isWhere) { + // ensure both objects have the same number of properties + forIn(a, function(value, key, a) { + if (hasOwnProperty.call(a, key)) { + // `size` will be `-1` if `a` has more properties than `b` + return (result = --size > -1); + } + }); + } + } + stackA.pop(); + stackB.pop(); + + if (initedStack) { + releaseArray(stackA); + releaseArray(stackB); + } + return result; + } + + /** + * The base implementation of `_.merge` without argument juggling or support + * for `thisArg` binding. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} [callback] The function to customize merging properties. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + */ + function baseMerge(object, source, callback, stackA, stackB) { + (isArray(source) ? forEach : forOwn)(source, function(source, key) { + var found, + isArr, + result = source, + value = object[key]; + + if (source && ((isArr = isArray(source)) || isPlainObject(source))) { + // avoid merging previously merged cyclic sources + var stackLength = stackA.length; + while (stackLength--) { + if ((found = stackA[stackLength] == source)) { + value = stackB[stackLength]; + break; + } + } + if (!found) { + var isShallow; + if (callback) { + result = callback(value, source); + if ((isShallow = typeof result != 'undefined')) { + value = result; + } + } + if (!isShallow) { + value = isArr + ? (isArray(value) ? value : []) + : (isPlainObject(value) ? value : {}); + } + // add `source` and associated `value` to the stack of traversed objects + stackA.push(source); + stackB.push(value); + + // recursively merge objects and arrays (susceptible to call stack limits) + if (!isShallow) { + baseMerge(value, source, callback, stackA, stackB); + } + } + } + else { + if (callback) { + result = callback(value, source); + if (typeof result == 'undefined') { + result = source; + } + } + if (typeof result != 'undefined') { + value = result; + } + } + object[key] = value; + }); + } + + /** + * The base implementation of `_.random` without argument juggling or support + * for returning floating-point numbers. + * + * @private + * @param {number} min The minimum possible value. + * @param {number} max The maximum possible value. + * @returns {number} Returns a random number. + */ + function baseRandom(min, max) { + return min + floor(nativeRandom() * (max - min + 1)); + } + + /** + * The base implementation of `_.uniq` without support for callback shorthands + * or `thisArg` binding. + * + * @private + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function} [callback] The function called per iteration. + * @returns {Array} Returns a duplicate-value-free array. + */ + function baseUniq(array, isSorted, callback) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + result = []; + + var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf, + seen = (callback || isLarge) ? getArray() : result; + + if (isLarge) { + var cache = createCache(seen); + indexOf = cacheIndexOf; + seen = cache; + } + while (++index < length) { + var value = array[index], + computed = callback ? callback(value, index, array) : value; + + if (isSorted + ? !index || seen[seen.length - 1] !== computed + : indexOf(seen, computed) < 0 + ) { + if (callback || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + if (isLarge) { + releaseArray(seen.array); + releaseObject(seen); + } else if (callback) { + releaseArray(seen); + } + return result; + } + + /** + * Creates a function that aggregates a collection, creating an object composed + * of keys generated from the results of running each element of the collection + * through a callback. The given `setter` function sets the keys and values + * of the composed object. + * + * @private + * @param {Function} setter The setter function. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter) { + return function(collection, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + setter(result, value, callback(value, index, collection), collection); + } + } else { + baseEach(collection, function(value, key, collection) { + setter(result, value, callback(value, key, collection), collection); + }); + } + return result; + }; + } + + /** + * Creates a function that, when called, either curries or invokes `func` + * with an optional `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of method flags to compose. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` + * 8 - `_.curry` (bound) + * 16 - `_.partial` + * 32 - `_.partialRight` + * @param {Array} [partialArgs] An array of arguments to prepend to those + * provided to the new function. + * @param {Array} [partialRightArgs] An array of arguments to append to those + * provided to the new function. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new function. + */ + function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + isPartial = bitmask & 16, + isPartialRight = bitmask & 32; + + if (!isBindKey && !isFunction(func)) { + throw new TypeError; + } + if (isPartial && !partialArgs.length) { + bitmask &= ~16; + isPartial = partialArgs = false; + } + if (isPartialRight && !partialRightArgs.length) { + bitmask &= ~32; + isPartialRight = partialRightArgs = false; + } + var bindData = func && func.__bindData__; + if (bindData && bindData !== true) { + // clone `bindData` + bindData = slice(bindData); + if (bindData[2]) { + bindData[2] = slice(bindData[2]); + } + if (bindData[3]) { + bindData[3] = slice(bindData[3]); + } + // set `thisBinding` is not previously bound + if (isBind && !(bindData[1] & 1)) { + bindData[4] = thisArg; + } + // set if previously bound but not currently (subsequent curried functions) + if (!isBind && bindData[1] & 1) { + bitmask |= 8; + } + // set curried arity if not yet set + if (isCurry && !(bindData[1] & 4)) { + bindData[5] = arity; + } + // append partial left arguments + if (isPartial) { + push.apply(bindData[2] || (bindData[2] = []), partialArgs); + } + // append partial right arguments + if (isPartialRight) { + unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); + } + // merge flags + bindData[1] |= bitmask; + return createWrapper.apply(null, bindData); + } + // fast path for `_.bind` + var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; + return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); + } + + /** + * Creates compiled iteration functions. + * + * @private + * @param {...Object} [options] The compile options object(s). + * @param {string} [options.array] Code to determine if the iterable is an array or array-like. + * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop. + * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration. + * @param {string} [options.args] A comma separated string of iteration function arguments. + * @param {string} [options.top] Code to execute before the iteration branches. + * @param {string} [options.loop] Code to execute in the object loop. + * @param {string} [options.bottom] Code to execute after the iteration branches. + * @returns {Function} Returns the compiled function. + */ + function createIterator() { + // data properties + iteratorData.shadowedProps = shadowedProps; + + // iterator options + iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = ''; + iteratorData.init = 'iterable'; + iteratorData.useHas = true; + + // merge options into a template data object + for (var object, index = 0; object = arguments[index]; index++) { + for (var key in object) { + iteratorData[key] = object[key]; + } + } + var args = iteratorData.args; + iteratorData.firstArg = /^[^,]+/.exec(args)[0]; + + // create the function factory + var factory = Function( + 'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' + + 'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' + + 'objectTypes, nonEnumProps, stringClass, stringProto, toString', + 'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}' + ); + + // return the compiled function + return factory( + baseCreateCallback, errorClass, errorProto, hasOwnProperty, + indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto, + objectTypes, nonEnumProps, stringClass, stringProto, toString + ); + } + + /** + * Used by `escape` to convert characters to HTML entities. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(match) { + return htmlEscapes[match]; + } + + /** + * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * customized, this method returns the custom method, otherwise it returns + * the `baseIndexOf` function. + * + * @private + * @returns {Function} Returns the "indexOf" function. + */ + function getIndexOf() { + var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; + return result; + } + + /** + * Checks if `value` is a native function. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. + */ + function isNative(value) { + return typeof value == 'function' && reNative.test(value); + } + + /** + * Sets `this` binding data on a given function. + * + * @private + * @param {Function} func The function to set data on. + * @param {Array} value The data array to set. + */ + var setBindData = !defineProperty ? noop : function(func, value) { + descriptor.value = value; + defineProperty(func, '__bindData__', descriptor); + descriptor.value = null; + }; + + /** + * A fallback implementation of `isPlainObject` which checks if a given value + * is an object created by the `Object` constructor, assuming objects created + * by the `Object` constructor have no inherited enumerable properties and that + * there are no `Object.prototype` extensions. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + */ + function shimIsPlainObject(value) { + var ctor, + result; + + // avoid non Object objects, `arguments` objects, and DOM elements + if (!(value && toString.call(value) == objectClass) || + (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) || + (!support.argsClass && isArguments(value)) || + (!support.nodeClass && isNode(value))) { + return false; + } + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + if (support.ownLast) { + forIn(value, function(value, key, object) { + result = hasOwnProperty.call(object, key); + return false; + }); + return result !== false; + } + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + forIn(value, function(value, key) { + result = key; + }); + return typeof result == 'undefined' || hasOwnProperty.call(value, result); + } + + /** + * Used by `unescape` to convert HTML entities to characters. + * + * @private + * @param {string} match The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(match) { + return htmlUnescapes[match]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Checks if `value` is an `arguments` object. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. + * @example + * + * (function() { return _.isArguments(arguments); })(1, 2, 3); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == argsClass || false; + } + // fallback for browsers that can't detect `arguments` objects by [[Class]] + if (!support.argsClass) { + isArguments = function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false; + }; + } + + /** + * Checks if `value` is an array. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an array, else `false`. + * @example + * + * (function() { return _.isArray(arguments); })(); + * // => false + * + * _.isArray([1, 2, 3]); + * // => true + */ + var isArray = nativeIsArray || function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == arrayClass || false; + }; + + /** + * A fallback implementation of `Object.keys` which produces an array of the + * given object's own enumerable property names. + * + * @private + * @type Function + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + */ + var shimKeys = createIterator({ + 'args': 'object', + 'init': '[]', + 'top': 'if (!(objectTypes[typeof object])) return result', + 'loop': 'result.push(index)' + }); + + /** + * Creates an array composed of the own enumerable property names of an object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + * @example + * + * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); + * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) + */ + var keys = !nativeKeys ? shimKeys : function(object) { + if (!isObject(object)) { + return []; + } + if ((support.enumPrototypes && typeof object == 'function') || + (support.nonEnumArgs && object.length && isArguments(object))) { + return shimKeys(object); + } + return nativeKeys(object); + }; + + /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */ + var eachIteratorOptions = { + 'args': 'collection, callback, thisArg', + 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)", + 'array': "typeof length == 'number'", + 'keys': keys, + 'loop': 'if (callback(iterable[index], index, collection) === false) return result' + }; + + /** Reusable iterator options for `assign` and `defaults` */ + var defaultsIteratorOptions = { + 'args': 'object, source, guard', + 'top': + 'var args = arguments,\n' + + ' argsIndex = 0,\n' + + " argsLength = typeof guard == 'number' ? 2 : args.length;\n" + + 'while (++argsIndex < argsLength) {\n' + + ' iterable = args[argsIndex];\n' + + ' if (iterable && objectTypes[typeof iterable]) {', + 'keys': keys, + 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]", + 'bottom': ' }\n}' + }; + + /** Reusable iterator options for `forIn` and `forOwn` */ + var forOwnIteratorOptions = { + 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top, + 'array': false + }; + + /** + * Used to convert characters to HTML entities: + * + * Though the `>` character is escaped for symmetry, characters like `>` and `/` + * don't require escaping in HTML and have no special meaning unless they're part + * of a tag or an unquoted attribute value. + * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") + */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + /** Used to convert HTML entities to characters */ + var htmlUnescapes = invert(htmlEscapes); + + /** Used to match HTML entities and HTML characters */ + var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), + reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); + + /** + * A function compiled to iterate `arguments` objects, arrays, objects, and + * strings consistenly across environments, executing the callback for each + * element in the collection. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index|key, collection). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @private + * @type Function + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEach = createIterator(eachIteratorOptions); + + /*--------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources will overwrite property assignments of previous + * sources. If a callback is provided it will be executed to produce the + * assigned values. The callback is bound to `thisArg` and invoked with two + * arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @type Function + * @alias extend + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param {Function} [callback] The function to customize assigning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); + * // => { 'name': 'fred', 'employer': 'slate' } + * + * var defaults = _.partialRight(_.assign, function(a, b) { + * return typeof a == 'undefined' ? b : a; + * }); + * + * var object = { 'name': 'barney' }; + * defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + var assign = createIterator(defaultsIteratorOptions, { + 'top': + defaultsIteratorOptions.top.replace(';', + ';\n' + + "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" + + ' var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' + + "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" + + ' callback = args[--argsLength];\n' + + '}' + ), + 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]' + }); + + /** + * Creates a clone of `value`. If `isDeep` is `true` nested objects will also + * be cloned, otherwise they will be assigned by reference. If a callback + * is provided it will be executed to produce the cloned values. If the + * callback returns `undefined` cloning will be handled by the method instead. + * The callback is bound to `thisArg` and invoked with one argument; (value). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to clone. + * @param {boolean} [isDeep=false] Specify a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the cloned value. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * var shallow = _.clone(characters); + * shallow[0] === characters[0]; + * // => true + * + * var deep = _.clone(characters, true); + * deep[0] === characters[0]; + * // => false + * + * _.mixin({ + * 'clone': _.partialRight(_.clone, function(value) { + * return _.isElement(value) ? value.cloneNode(false) : undefined; + * }) + * }); + * + * var clone = _.clone(document.body); + * clone.childNodes.length; + * // => 0 + */ + function clone(value, isDeep, callback, thisArg) { + // allows working with "Collections" methods without using their `index` + // and `collection` arguments for `isDeep` and `callback` + if (typeof isDeep != 'boolean' && isDeep != null) { + thisArg = callback; + callback = isDeep; + isDeep = false; + } + return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + } + + /** + * Creates a deep clone of `value`. If a callback is provided it will be + * executed to produce the cloned values. If the callback returns `undefined` + * cloning will be handled by the method instead. The callback is bound to + * `thisArg` and invoked with one argument; (value). + * + * Note: This method is loosely based on the structured clone algorithm. Functions + * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and + * objects created by constructors other than `Object` are cloned to plain `Object` objects. + * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the deep cloned value. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * var deep = _.cloneDeep(characters); + * deep[0] === characters[0]; + * // => false + * + * var view = { + * 'label': 'docs', + * 'node': element + * }; + * + * var clone = _.cloneDeep(view, function(value) { + * return _.isElement(value) ? value.cloneNode(true) : undefined; + * }); + * + * clone.node == view.node; + * // => false + */ + function cloneDeep(value, callback, thisArg) { + return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + } + + /** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties ? assign(result, properties) : result; + } + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional defaults of the same property will be ignored. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param- {Object} [guard] Allows working with `_.reduce` without using its + * `key` and `object` arguments as sources. + * @returns {Object} Returns the destination object. + * @example + * + * var object = { 'name': 'barney' }; + * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + var defaults = createIterator(defaultsIteratorOptions); + + /** + * This method is like `_.findIndex` except that it returns the key of the + * first element that passes the callback check, instead of the element itself. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to search. + * @param {Function|Object|string} [callback=identity] The function called per + * iteration. If a property name or object is provided it will be used to + * create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @example + * + * var characters = { + * 'barney': { 'age': 36, 'blocked': false }, + * 'fred': { 'age': 40, 'blocked': true }, + * 'pebbles': { 'age': 1, 'blocked': false } + * }; + * + * _.findKey(characters, function(chr) { + * return chr.age < 40; + * }); + * // => 'barney' (property order is not guaranteed across environments) + * + * // using "_.where" callback shorthand + * _.findKey(characters, { 'age': 1 }); + * // => 'pebbles' + * + * // using "_.pluck" callback shorthand + * _.findKey(characters, 'blocked'); + * // => 'fred' + */ + function findKey(object, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forOwn(object, function(value, key, object) { + if (callback(value, key, object)) { + result = key; + return false; + } + }); + return result; + } + + /** + * This method is like `_.findKey` except that it iterates over elements + * of a `collection` in the opposite order. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to search. + * @param {Function|Object|string} [callback=identity] The function called per + * iteration. If a property name or object is provided it will be used to + * create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @example + * + * var characters = { + * 'barney': { 'age': 36, 'blocked': true }, + * 'fred': { 'age': 40, 'blocked': false }, + * 'pebbles': { 'age': 1, 'blocked': true } + * }; + * + * _.findLastKey(characters, function(chr) { + * return chr.age < 40; + * }); + * // => returns `pebbles`, assuming `_.findKey` returns `barney` + * + * // using "_.where" callback shorthand + * _.findLastKey(characters, { 'age': 40 }); + * // => 'fred' + * + * // using "_.pluck" callback shorthand + * _.findLastKey(characters, 'blocked'); + * // => 'pebbles' + */ + function findLastKey(object, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forOwnRight(object, function(value, key, object) { + if (callback(value, key, object)) { + result = key; + return false; + } + }); + return result; + } + + /** + * Iterates over own and inherited enumerable properties of an object, + * executing the callback for each property. The callback is bound to `thisArg` + * and invoked with three arguments; (value, key, object). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forIn(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) + */ + var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, { + 'useHas': false + }); + + /** + * This method is like `_.forIn` except that it iterates over elements + * of a `collection` in the opposite order. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forInRight(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' + */ + function forInRight(object, callback, thisArg) { + var pairs = []; + + forIn(object, function(value, key) { + pairs.push(key, value); + }); + + var length = pairs.length; + callback = baseCreateCallback(callback, thisArg, 3); + while (length--) { + if (callback(pairs[length--], pairs[length], object) === false) { + break; + } + } + return object; + } + + /** + * Iterates over own enumerable properties of an object, executing the callback + * for each property. The callback is bound to `thisArg` and invoked with three + * arguments; (value, key, object). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) + */ + var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions); + + /** + * This method is like `_.forOwn` except that it iterates over elements + * of a `collection` in the opposite order. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' + */ + function forOwnRight(object, callback, thisArg) { + var props = keys(object), + length = props.length; + + callback = baseCreateCallback(callback, thisArg, 3); + while (length--) { + var key = props[length]; + if (callback(object[key], key, object) === false) { + break; + } + } + return object; + } + + /** + * Creates a sorted array of property names of all enumerable properties, + * own and inherited, of `object` that have function values. + * + * @static + * @memberOf _ + * @alias methods + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names that have function values. + * @example + * + * _.functions(_); + * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] + */ + function functions(object) { + var result = []; + forIn(object, function(value, key) { + if (isFunction(value)) { + result.push(key); + } + }); + return result.sort(); + } + + /** + * Checks if the specified property name exists as a direct property of `object`, + * instead of an inherited property. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to check. + * @returns {boolean} Returns `true` if key is a direct property, else `false`. + * @example + * + * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); + * // => true + */ + function has(object, key) { + return object ? hasOwnProperty.call(object, key) : false; + } + + /** + * Creates an object composed of the inverted keys and values of the given object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to invert. + * @returns {Object} Returns the created inverted object. + * @example + * + * _.invert({ 'first': 'fred', 'second': 'barney' }); + * // => { 'fred': 'first', 'barney': 'second' } + */ + function invert(object) { + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + result[object[key]] = key; + } + return result; + } + + /** + * Checks if `value` is a boolean value. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. + * @example + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + value && typeof value == 'object' && toString.call(value) == boolClass || false; + } + + /** + * Checks if `value` is a date. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a date, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + */ + function isDate(value) { + return value && typeof value == 'object' && toString.call(value) == dateClass || false; + } + + /** + * Checks if `value` is a DOM element. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + */ + function isElement(value) { + return value && value.nodeType === 1 || false; + } + + /** + * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a + * length of `0` and objects with no own enumerable properties are considered + * "empty". + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if the `value` is empty, else `false`. + * @example + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({}); + * // => true + * + * _.isEmpty(''); + * // => true + */ + function isEmpty(value) { + var result = true; + if (!value) { + return result; + } + var className = toString.call(value), + length = value.length; + + if ((className == arrayClass || className == stringClass || + (support.argsClass ? className == argsClass : isArguments(value))) || + (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { + return !length; + } + forOwn(value, function() { + return (result = false); + }); + return result; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent to each other. If a callback is provided it will be executed + * to compare values. If the callback returns `undefined` comparisons will + * be handled by the method instead. The callback is bound to `thisArg` and + * invoked with two arguments; (a, b). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'name': 'fred' }; + * var copy = { 'name': 'fred' }; + * + * object == copy; + * // => false + * + * _.isEqual(object, copy); + * // => true + * + * var words = ['hello', 'goodbye']; + * var otherWords = ['hi', 'goodbye']; + * + * _.isEqual(words, otherWords, function(a, b) { + * var reGreet = /^(?:hello|hi)$/i, + * aGreet = _.isString(a) && reGreet.test(a), + * bGreet = _.isString(b) && reGreet.test(b); + * + * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; + * }); + * // => true + */ + function isEqual(a, b, callback, thisArg) { + return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2)); + } + + /** + * Checks if `value` is, or can be coerced to, a finite number. + * + * Note: This is not the same as native `isFinite` which will return true for + * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is finite, else `false`. + * @example + * + * _.isFinite(-101); + * // => true + * + * _.isFinite('10'); + * // => true + * + * _.isFinite(true); + * // => false + * + * _.isFinite(''); + * // => false + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); + } + + /** + * Checks if `value` is a function. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + */ + function isFunction(value) { + return typeof value == 'function'; + } + // fallback for older versions of Chrome and Safari + if (isFunction(/x/)) { + isFunction = function(value) { + return typeof value == 'function' && toString.call(value) == funcClass; + }; + } + + /** + * Checks if `value` is the language type of Object. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ + function isObject(value) { + // check if the value is the ECMAScript language type of Object + // http://es5.github.io/#x8 + // and avoid a V8 bug + // http://code.google.com/p/v8/issues/detail?id=2291 + return !!(value && objectTypes[typeof value]); + } + + /** + * Checks if `value` is `NaN`. + * + * Note: This is not the same as native `isNaN` which will return `true` for + * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // `NaN` as a primitive is the only value that is not equal to itself + // (perform the [[Class]] check first to avoid errors with some host objects in IE) + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(undefined); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is a number. + * + * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a number, else `false`. + * @example + * + * _.isNumber(8.4 * 5); + * // => true + */ + function isNumber(value) { + return typeof value == 'number' || + value && typeof value == 'object' && toString.call(value) == numberClass || false; + } + + /** + * Checks if `value` is an object created by the `Object` constructor. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * _.isPlainObject(new Shape); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + */ + var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { + if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) { + return false; + } + var valueOf = value.valueOf, + objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); + + return objProto + ? (value == objProto || getPrototypeOf(value) == objProto) + : shimIsPlainObject(value); + }; + + /** + * Checks if `value` is a regular expression. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. + * @example + * + * _.isRegExp(/fred/); + * // => true + */ + function isRegExp(value) { + return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false; + } + + /** + * Checks if `value` is a string. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a string, else `false`. + * @example + * + * _.isString('fred'); + * // => true + */ + function isString(value) { + return typeof value == 'string' || + value && typeof value == 'object' && toString.call(value) == stringClass || false; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + */ + function isUndefined(value) { + return typeof value == 'undefined'; + } + + /** + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through the callback. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new object with values of the results of each `callback` execution. + * @example + * + * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + * + * var characters = { + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * }; + * + * // using "_.pluck" callback shorthand + * _.mapValues(characters, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } + */ + function mapValues(object, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + + forOwn(object, function(value, key, object) { + result[key] = callback(value, key, object); + }); + return result; + } + + /** + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * will overwrite property assignments of previous sources. If a callback is + * provided it will be executed to produce the merged values of the destination + * and source properties. If the callback returns `undefined` merging will + * be handled by the method instead. The callback is bound to `thisArg` and + * invoked with two arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param {Function} [callback] The function to customize merging properties. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * var names = { + * 'characters': [ + * { 'name': 'barney' }, + * { 'name': 'fred' } + * ] + * }; + * + * var ages = { + * 'characters': [ + * { 'age': 36 }, + * { 'age': 40 } + * ] + * }; + * + * _.merge(names, ages); + * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } + * + * var food = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var otherFood = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(food, otherFood, function(a, b) { + * return _.isArray(a) ? a.concat(b) : undefined; + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } + */ + function merge(object) { + var args = arguments, + length = 2; + + if (!isObject(object)) { + return object; + } + // allows working with `_.reduce` and `_.reduceRight` without using + // their `index` and `collection` arguments + if (typeof args[2] != 'number') { + length = args.length; + } + if (length > 3 && typeof args[length - 2] == 'function') { + var callback = baseCreateCallback(args[--length - 1], args[length--], 2); + } else if (length > 2 && typeof args[length - 1] == 'function') { + callback = args[--length]; + } + var sources = slice(arguments, 1, length), + index = -1, + stackA = getArray(), + stackB = getArray(); + + while (++index < length) { + baseMerge(object, sources[index], callback, stackA, stackB); + } + releaseArray(stackA); + releaseArray(stackB); + return object; + } + + /** + * Creates a shallow clone of `object` excluding the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` omitting the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The properties to omit or the + * function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object without the omitted properties. + * @example + * + * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); + * // => { 'name': 'fred' } + * + * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { + * return typeof value == 'number'; + * }); + * // => { 'name': 'fred' } + */ + function omit(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var props = []; + forIn(object, function(value, key) { + props.push(key); + }); + props = baseDifference(props, baseFlatten(arguments, true, false, 1)); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + result[key] = object[key]; + } + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (!callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * Creates a two dimensional array of an object's key-value pairs, + * i.e. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns new array of key-value pairs. + * @example + * + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) + */ + function pairs(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; + } + + /** + * Creates a shallow clone of `object` composed of the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` picking the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The function called per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object composed of the picked properties. + * @example + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); + * // => { 'name': 'fred' } + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { + * return key.charAt(0) != '_'; + * }); + * // => { 'name': 'fred' } + */ + function pick(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var index = -1, + props = baseFlatten(arguments, true, false, 1), + length = isObject(object) ? props.length : 0; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * An alternative to `_.reduce` this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own + * enumerable properties through a callback, with each callback execution + * potentially mutating the `accumulator` object. The callback is bound to + * `thisArg` and invoked with four arguments; (accumulator, value, key, object). + * Callbacks may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) { + * num *= num; + * if (num % 2) { + * return result.push(num) < 3; + * } + * }); + * // => [1, 9, 25] + * + * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function transform(object, callback, accumulator, thisArg) { + var isArr = isArray(object); + if (accumulator == null) { + if (isArr) { + accumulator = []; + } else { + var ctor = object && object.constructor, + proto = ctor && ctor.prototype; + + accumulator = baseCreate(proto); + } + } + if (callback) { + callback = lodash.createCallback(callback, thisArg, 4); + (isArr ? baseEach : forOwn)(object, function(value, index, object) { + return callback(accumulator, value, index, object); + }); + } + return accumulator; + } + + /** + * Creates an array composed of the own enumerable property values of `object`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property values. + * @example + * + * _.values({ 'one': 1, 'two': 2, 'three': 3 }); + * // => [1, 2, 3] (property order is not guaranteed across environments) + */ + function values(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array of elements from the specified indexes, or keys, of the + * `collection`. Indexes may be specified as individual arguments or as arrays + * of indexes. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [index] The indexes of `collection` + * to retrieve, specified as individual indexes or arrays of indexes. + * @returns {Array} Returns a new array of elements corresponding to the + * provided indexes. + * @example + * + * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); + * // => ['a', 'c', 'e'] + * + * _.at(['fred', 'barney', 'pebbles'], 0, 2); + * // => ['fred', 'pebbles'] + */ + function at(collection) { + var args = arguments, + index = -1, + props = baseFlatten(args, true, false, 1), + length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length, + result = Array(length); + + if (support.unindexedChars && isString(collection)) { + collection = collection.split(''); + } + while(++index < length) { + result[index] = collection[props[index]]; + } + return result; + } + + /** + * Checks if a given value is present in a collection using strict equality + * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the + * offset from the end of the collection. + * + * @static + * @memberOf _ + * @alias include + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {*} target The value to check for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {boolean} Returns `true` if the `target` element is found, else `false`. + * @example + * + * _.contains([1, 2, 3], 1); + * // => true + * + * _.contains([1, 2, 3], 1, 2); + * // => false + * + * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.contains('pebbles', 'eb'); + * // => true + */ + function contains(collection, target, fromIndex) { + var index = -1, + indexOf = getIndexOf(), + length = collection ? collection.length : 0, + result = false; + + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; + if (isArray(collection)) { + result = indexOf(collection, target, fromIndex) > -1; + } else if (typeof length == 'number') { + result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1; + } else { + baseEach(collection, function(value) { + if (++index >= fromIndex) { + return !(result = value === target); + } + }); + } + return result; + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through the callback. The corresponding value + * of each key is the number of times the key was returned by the callback. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); + }); + + /** + * Checks if the given callback returns truey value for **all** elements of + * a collection. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if all elements passed the callback check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes']); + * // => false + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.every(characters, 'age'); + * // => true + * + * // using "_.where" callback shorthand + * _.every(characters, { 'age': 36 }); + * // => false + */ + function every(collection, callback, thisArg) { + var result = true; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (!(result = !!callback(collection[index], index, collection))) { + break; + } + } + } else { + baseEach(collection, function(value, index, collection) { + return (result = !!callback(value, index, collection)); + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning an array of all elements + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that passed the callback check. + * @example + * + * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [2, 4, 6] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.filter(characters, 'blocked'); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + * + * // using "_.where" callback shorthand + * _.filter(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + */ + function filter(collection, callback, thisArg) { + var result = []; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + result.push(value); + } + } + } else { + baseEach(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result.push(value); + } + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning the first element that + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias detect, findWhere + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.find(characters, function(chr) { + * return chr.age < 40; + * }); + * // => { 'name': 'barney', 'age': 36, 'blocked': false } + * + * // using "_.where" callback shorthand + * _.find(characters, { 'age': 1 }); + * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } + * + * // using "_.pluck" callback shorthand + * _.find(characters, 'blocked'); + * // => { 'name': 'fred', 'age': 40, 'blocked': true } + */ + function find(collection, callback, thisArg) { + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + return value; + } + } + } else { + var result; + baseEach(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + } + + /** + * This method is like `_.find` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(num) { + * return num % 2 == 1; + * }); + * // => 3 + */ + function findLast(collection, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forEachRight(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + + /** + * Iterates over elements of a collection, executing the callback for each + * element. The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * Note: As with other "Collections" methods, objects with a `length` property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); + * // => logs each number and returns '1,2,3' + * + * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); + * // => logs each number and returns the object (property order is not guaranteed across environments) + */ + function forEach(collection, callback, thisArg) { + if (callback && typeof thisArg == 'undefined' && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (callback(collection[index], index, collection) === false) { + break; + } + } + } else { + baseEach(collection, callback, thisArg); + } + return collection; + } + + /** + * This method is like `_.forEach` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); + * // => logs each number from right to left and returns '3,2,1' + */ + function forEachRight(collection, callback, thisArg) { + var iterable = collection, + length = collection ? collection.length : 0; + + callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); + if (isArray(collection)) { + while (length--) { + if (callback(collection[length], length, collection) === false) { + break; + } + } + } else { + if (typeof length != 'number') { + var props = keys(collection); + length = props.length; + } else if (support.unindexedChars && isString(collection)) { + iterable = collection.split(''); + } + baseEach(collection, function(value, key, collection) { + key = props ? props[--length] : --length; + return callback(iterable[key], key, collection); + }); + } + return collection; + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of a collection through the callback. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false` + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using "_.pluck" callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of the collection through the given callback. The corresponding + * value of each key is the last element responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keys = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keys, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Invokes the method named by `methodName` on each element in the `collection` + * returning an array of the results of each invoked method. Additional arguments + * will be provided to each invoked method. If `methodName` is a function it + * will be invoked for, and `this` bound to, each element in the `collection`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|string} methodName The name of the method to invoke or + * the function invoked per iteration. + * @param {...*} [arg] Arguments to invoke the method with. + * @returns {Array} Returns a new array of the results of each invoked method. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + function invoke(collection, methodName) { + var args = slice(arguments, 2), + index = -1, + isFunc = typeof methodName == 'function', + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); + }); + return result; + } + + /** + * Creates an array of values by running each element in the collection + * through the callback. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias collect + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of the results of each `callback` execution. + * @example + * + * _.map([1, 2, 3], function(num) { return num * 3; }); + * // => [3, 6, 9] + * + * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); + * // => [3, 6, 9] (property order is not guaranteed across environments) + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(characters, 'name'); + * // => ['barney', 'fred'] + */ + function map(collection, callback, thisArg) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + callback = lodash.createCallback(callback, thisArg, 3); + if (isArray(collection)) { + while (++index < length) { + result[index] = callback(collection[index], index, collection); + } + } else { + baseEach(collection, function(value, key, collection) { + result[++index] = callback(value, key, collection); + }); + } + return result; + } + + /** + * Retrieves the maximum value of a collection. If the collection is empty or + * falsey `-Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.max(characters, function(chr) { return chr.age; }); + * // => { 'name': 'fred', 'age': 40 }; + * + * // using "_.pluck" callback shorthand + * _.max(characters, 'age'); + * // => { 'name': 'fred', 'age': 40 }; + */ + function max(collection, callback, thisArg) { + var computed = -Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value > result) { + result = value; + } + } + } else { + callback = (callback == null && isString(collection)) + ? charAtCallback + : lodash.createCallback(callback, thisArg, 3); + + baseEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current > computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the minimum value of a collection. If the collection is empty or + * falsey `Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.min(characters, function(chr) { return chr.age; }); + * // => { 'name': 'barney', 'age': 36 }; + * + * // using "_.pluck" callback shorthand + * _.min(characters, 'age'); + * // => { 'name': 'barney', 'age': 36 }; + */ + function min(collection, callback, thisArg) { + var computed = Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value < result) { + result = value; + } + } + } else { + callback = (callback == null && isString(collection)) + ? charAtCallback + : lodash.createCallback(callback, thisArg, 3); + + baseEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current < computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the value of a specified property from all elements in the collection. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {string} property The name of the property to pluck. + * @returns {Array} Returns a new array of property values. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.pluck(characters, 'name'); + * // => ['barney', 'fred'] + */ + var pluck = map; + + /** + * Reduces a collection to a value which is the accumulated result of running + * each element in the collection through the callback, where each successive + * callback execution consumes the return value of the previous execution. If + * `accumulator` is not provided the first element of the collection will be + * used as the initial `accumulator` value. The callback is bound to `thisArg` + * and invoked with four arguments; (accumulator, value, index|key, collection). + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var sum = _.reduce([1, 2, 3], function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function reduce(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = lodash.createCallback(callback, thisArg, 4); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + if (noaccum) { + accumulator = collection[++index]; + } + while (++index < length) { + accumulator = callback(accumulator, collection[index], index, collection); + } + } else { + baseEach(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection) + }); + } + return accumulator; + } + + /** + * This method is like `_.reduce` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var list = [[0, 1], [2, 3], [4, 5]]; + * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + function reduceRight(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = lodash.createCallback(callback, thisArg, 4); + forEachRight(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The opposite of `_.filter` this method returns the elements of a + * collection that the callback does **not** return truey for. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that failed the callback check. + * @example + * + * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [1, 3, 5] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.reject(characters, 'blocked'); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + * + * // using "_.where" callback shorthand + * _.reject(characters, { 'age': 36 }); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + */ + function reject(collection, callback, thisArg) { + callback = lodash.createCallback(callback, thisArg, 3); + return filter(collection, function(value, index, collection) { + return !callback(value, index, collection); + }); + } + + /** + * Retrieves a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Allows working with functions like `_.map` + * without using their `index` arguments as `n`. + * @returns {Array} Returns the random sample(s) of `collection`. + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ + function sample(collection, n, guard) { + if (collection && typeof collection.length != 'number') { + collection = values(collection); + } else if (support.unindexedChars && isString(collection)) { + collection = collection.split(''); + } + if (n == null || guard) { + return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; + } + var result = shuffle(collection); + result.length = nativeMin(nativeMax(0, n), result.length); + return result; + } + + /** + * Creates an array of shuffled values, using a version of the Fisher-Yates + * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns a new shuffled collection. + * @example + * + * _.shuffle([1, 2, 3, 4, 5, 6]); + * // => [4, 1, 6, 3, 5, 2] + */ + function shuffle(collection) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + var rand = baseRandom(0, ++index); + result[index] = result[rand]; + result[rand] = value; + }); + return result; + } + + /** + * Gets the size of the `collection` by returning `collection.length` for arrays + * and array-like objects or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns `collection.length` or number of own enumerable properties. + * @example + * + * _.size([1, 2]); + * // => 2 + * + * _.size({ 'one': 1, 'two': 2, 'three': 3 }); + * // => 3 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + var length = collection ? collection.length : 0; + return typeof length == 'number' ? length : keys(collection).length; + } + + /** + * Checks if the callback returns a truey value for **any** element of a + * collection. The function returns as soon as it finds a passing value and + * does not iterate over the entire collection. The callback is bound to + * `thisArg` and invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if any element passed the callback check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.some(characters, 'blocked'); + * // => true + * + * // using "_.where" callback shorthand + * _.some(characters, { 'age': 1 }); + * // => false + */ + function some(collection, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if ((result = callback(collection[index], index, collection))) { + break; + } + } + } else { + baseEach(collection, function(value, index, collection) { + return !(result = callback(value, index, collection)); + }); + } + return !!result; + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through the callback. This method + * performs a stable sort, that is, it will preserve the original sort order + * of equal elements. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an array of property names is provided for `callback` the collection + * will be sorted by each property value. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of sorted elements. + * @example + * + * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); + * // => [3, 1, 2] + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 26 }, + * { 'name': 'fred', 'age': 30 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(_.sortBy(characters, 'age'), _.values); + * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] + * + * // sorting by multiple properties + * _.map(_.sortBy(characters, ['name', 'age']), _.values); + * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] + */ + function sortBy(collection, callback, thisArg) { + var index = -1, + isArr = isArray(callback), + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + if (!isArr) { + callback = lodash.createCallback(callback, thisArg, 3); + } + forEach(collection, function(value, key, collection) { + var object = result[++index] = getObject(); + if (isArr) { + object.criteria = map(callback, function(key) { return value[key]; }); + } else { + (object.criteria = getArray())[0] = callback(value, key, collection); + } + object.index = index; + object.value = value; + }); + + length = result.length; + result.sort(compareAscending); + while (length--) { + var object = result[length]; + result[length] = object.value; + if (!isArr) { + releaseArray(object.criteria); + } + releaseObject(object); + } + return result; + } + + /** + * Converts the `collection` to an array. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to convert. + * @returns {Array} Returns the new converted array. + * @example + * + * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); + * // => [2, 3, 4] + */ + function toArray(collection) { + if (collection && typeof collection.length == 'number') { + return (support.unindexedChars && isString(collection)) + ? collection.split('') + : slice(collection); + } + return values(collection); + } + + /** + * Performs a deep comparison of each element in a `collection` to the given + * `properties` object, returning an array of all elements that have equivalent + * property values. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Object} props The object of property values to filter by. + * @returns {Array} Returns a new array of elements that have the given properties. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.where(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] + * + * _.where(characters, { 'pets': ['dino'] }); + * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] + */ + var where = filter; + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are all falsey. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to compact. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result.push(value); + } + } + return result; + } + + /** + * Creates an array excluding all values of the provided arrays using strict + * equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to process. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); + * // => [1, 3, 4] + */ + function difference(array) { + return baseDifference(array, baseFlatten(arguments, true, true, 1)); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element that passes the callback check, instead of the element itself. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.findIndex(characters, function(chr) { + * return chr.age < 20; + * }); + * // => 2 + * + * // using "_.where" callback shorthand + * _.findIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findIndex(characters, 'blocked'); + * // => 1 + */ + function findIndex(array, callback, thisArg) { + var index = -1, + length = array ? array.length : 0; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length) { + if (callback(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of a `collection` from right to left. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': true }, + * { 'name': 'fred', 'age': 40, 'blocked': false }, + * { 'name': 'pebbles', 'age': 1, 'blocked': true } + * ]; + * + * _.findLastIndex(characters, function(chr) { + * return chr.age > 30; + * }); + * // => 1 + * + * // using "_.where" callback shorthand + * _.findLastIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findLastIndex(characters, 'blocked'); + * // => 2 + */ + function findLastIndex(array, callback, thisArg) { + var length = array ? array.length : 0; + callback = lodash.createCallback(callback, thisArg, 3); + while (length--) { + if (callback(array[length], length, array)) { + return length; + } + } + return -1; + } + + /** + * Gets the first element or first `n` elements of an array. If a callback + * is provided elements at the beginning of the array are returned as long + * as the callback returns truey. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias head, take + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the first element(s) of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([1, 2, 3], 2); + * // => [1, 2] + * + * _.first([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [1, 2] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.first(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); + * // => ['barney', 'fred'] + */ + function first(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = -1; + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[0] : undefined; + } + } + return slice(array, 0, nativeMin(nativeMax(0, n), length)); + } + + /** + * Flattens a nested array (the nesting can be to any depth). If `isShallow` + * is truey, the array will only be flattened a single level. If a callback + * is provided each element of the array is passed through the callback before + * flattening. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new flattened array. + * @example + * + * _.flatten([1, [2], [3, [[4]]]]); + * // => [1, 2, 3, 4]; + * + * _.flatten([1, [2], [3, [[4]]]], true); + * // => [1, 2, 3, [[4]]]; + * + * var characters = [ + * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * // using "_.pluck" callback shorthand + * _.flatten(characters, 'pets'); + * // => ['hoppy', 'baby puss', 'dino'] + */ + function flatten(array, isShallow, callback, thisArg) { + // juggle arguments + if (typeof isShallow != 'boolean' && isShallow != null) { + thisArg = callback; + callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; + isShallow = false; + } + if (callback != null) { + array = map(array, callback, thisArg); + } + return baseFlatten(array, isShallow); + } + + /** + * Gets the index at which the first occurrence of `value` is found using + * strict equality for comparisons, i.e. `===`. If the array is already sorted + * providing `true` for `fromIndex` will run a faster binary search. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2); + * // => 1 + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 4 + * + * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + if (typeof fromIndex == 'number') { + var length = array ? array.length : 0; + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); + } else if (fromIndex) { + var index = sortedIndex(array, value); + return array[index] === value ? index : -1; + } + return baseIndexOf(array, value, fromIndex); + } + + /** + * Gets all but the last element or last `n` elements of an array. If a + * callback is provided elements at the end of the array are excluded from + * the result as long as the callback returns truey. The callback is bound + * to `thisArg` and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + * + * _.initial([1, 2, 3], 2); + * // => [1] + * + * _.initial([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [1] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.initial(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); + * // => ['barney', 'fred'] + */ + function initial(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = lodash.createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : callback || n; + } + return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); + } + + /** + * Creates an array of unique values present in all provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of shared values. + * @example + * + * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2] + */ + function intersection() { + var args = [], + argsIndex = -1, + argsLength = arguments.length, + caches = getArray(), + indexOf = getIndexOf(), + trustIndexOf = indexOf === baseIndexOf, + seen = getArray(); + + while (++argsIndex < argsLength) { + var value = arguments[argsIndex]; + if (isArray(value) || isArguments(value)) { + args.push(value); + caches.push(trustIndexOf && value.length >= largeArraySize && + createCache(argsIndex ? args[argsIndex] : seen)); + } + } + var array = args[0], + index = -1, + length = array ? array.length : 0, + result = []; + + outer: + while (++index < length) { + var cache = caches[0]; + value = array[index]; + + if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) { + argsIndex = argsLength; + (cache || seen).push(value); + while (--argsIndex) { + cache = caches[argsIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { + continue outer; + } + } + result.push(value); + } + } + while (argsLength--) { + cache = caches[argsLength]; + if (cache) { + releaseObject(cache); + } + } + releaseArray(caches); + releaseArray(seen); + return result; + } + + /** + * Gets the last element or last `n` elements of an array. If a callback is + * provided elements at the end of the array are returned as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the last element(s) of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + * + * _.last([1, 2, 3], 2); + * // => [2, 3] + * + * _.last([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [2, 3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.last(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.last(characters, { 'employer': 'na' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function last(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = lodash.createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[length - 1] : undefined; + } + } + return slice(array, nativeMax(0, length - n)); + } + + /** + * Gets the index at which the last occurrence of `value` is found using strict + * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used + * as the offset from the end of the collection. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); + * // => 4 + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 1 + */ + function lastIndexOf(array, value, fromIndex) { + var index = array ? array.length : 0; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Removes all provided values from the given array using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to modify. + * @param {...*} [value] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ + function pull(array) { + var args = arguments, + argsIndex = 0, + argsLength = args.length, + length = array ? array.length : 0; + + while (++argsIndex < argsLength) { + var index = -1, + value = args[argsIndex]; + while (++index < length) { + if (array[index] === value) { + splice.call(array, index--, 1); + length--; + } + } + } + return array; + } + + /** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to but not including `end`. If `start` is less than `stop` a + * zero-length range is created unless a negative `step` is specified. + * + * @static + * @memberOf _ + * @category Arrays + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns a new range array. + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ + function range(start, end, step) { + start = +start || 0; + step = typeof step == 'number' ? step : (+step || 1); + + if (end == null) { + end = start; + start = 0; + } + // use `Array(length)` so engines like Chakra and V8 avoid slower modes + // http://youtu.be/XAqIpGU8ZZk#t=17m25s + var index = -1, + length = nativeMax(0, ceil((end - start) / (step || 1))), + result = Array(length); + + while (++index < length) { + result[index] = start; + start += step; + } + return result; + } + + /** + * Removes all elements from an array that the callback returns truey for + * and returns an array of removed elements. The callback is bound to `thisArg` + * and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to modify. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4, 5, 6]; + * var evens = _.remove(array, function(num) { return num % 2 == 0; }); + * + * console.log(array); + * // => [1, 3, 5] + * + * console.log(evens); + * // => [2, 4, 6] + */ + function remove(array, callback, thisArg) { + var index = -1, + length = array ? array.length : 0, + result = []; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (callback(value, index, array)) { + result.push(value); + splice.call(array, index--, 1); + length--; + } + } + return result; + } + + /** + * The opposite of `_.initial` this method gets all but the first element or + * first `n` elements of an array. If a callback function is provided elements + * at the beginning of the array are excluded from the result as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias drop, tail + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + * + * _.rest([1, 2, 3], 2); + * // => [3] + * + * _.rest([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.rest(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.rest(characters, { 'employer': 'slate' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function rest(array, callback, thisArg) { + if (typeof callback != 'number' && callback != null) { + var n = 0, + index = -1, + length = array ? array.length : 0; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); + } + return slice(array, n); + } + + /** + * Uses a binary search to determine the smallest index at which a value + * should be inserted into a given sorted array in order to maintain the sort + * order of the array. If a callback is provided it will be executed for + * `value` and each element of `array` to compute their sort ranking. The + * callback is bound to `thisArg` and invoked with one argument; (value). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([20, 30, 50], 40); + * // => 2 + * + * // using "_.pluck" callback shorthand + * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 2 + * + * var dict = { + * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } + * }; + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return dict.wordToNumber[word]; + * }); + * // => 2 + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return this.wordToNumber[word]; + * }, dict); + * // => 2 + */ + function sortedIndex(array, value, callback, thisArg) { + var low = 0, + high = array ? array.length : low; + + // explicitly reference `identity` for better inlining in Firefox + callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; + value = callback(value); + + while (low < high) { + var mid = (low + high) >>> 1; + (callback(array[mid]) < value) + ? low = mid + 1 + : high = mid; + } + return low; + } + + /** + * Creates an array of unique values, in order, of the provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of combined values. + * @example + * + * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2, 3, 5, 4] + */ + function union() { + return baseUniq(baseFlatten(arguments, true, true)); + } + + /** + * Creates a duplicate-value-free version of an array using strict equality + * for comparisons, i.e. `===`. If the array is sorted, providing + * `true` for `isSorted` will use a faster algorithm. If a callback is provided + * each element of `array` is passed through the callback before uniqueness + * is computed. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Arrays + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a duplicate-value-free array. + * @example + * + * _.uniq([1, 2, 1, 3, 1]); + * // => [1, 2, 3] + * + * _.uniq([1, 1, 2, 2, 3], true); + * // => [1, 2, 3] + * + * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); + * // => ['A', 'b', 'C'] + * + * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); + * // => [1, 2.5, 3] + * + * // using "_.pluck" callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniq(array, isSorted, callback, thisArg) { + // juggle arguments + if (typeof isSorted != 'boolean' && isSorted != null) { + thisArg = callback; + callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; + isSorted = false; + } + if (callback != null) { + callback = lodash.createCallback(callback, thisArg, 3); + } + return baseUniq(array, isSorted, callback); + } + + /** + * Creates an array excluding all provided values using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to filter. + * @param {...*} [value] The values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); + * // => [2, 3, 4] + */ + function without(array) { + return baseDifference(array, slice(arguments, 1)); + } + + /** + * Creates an array that is the symmetric difference of the provided arrays. + * See http://en.wikipedia.org/wiki/Symmetric_difference. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of values. + * @example + * + * _.xor([1, 2, 3], [5, 2, 1, 4]); + * // => [3, 5, 4] + * + * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); + * // => [1, 4, 5] + */ + function xor() { + var index = -1, + length = arguments.length; + + while (++index < length) { + var array = arguments[index]; + if (isArray(array) || isArguments(array)) { + var result = result + ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result))) + : array; + } + } + return result || []; + } + + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second + * elements of the given arrays, and so on. + * + * @static + * @memberOf _ + * @alias unzip + * @category Arrays + * @param {...Array} [array] Arrays to process. + * @returns {Array} Returns a new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + function zip() { + var array = arguments.length > 1 ? arguments : arguments[0], + index = -1, + length = array ? max(pluck(array, 'length')) : 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = pluck(array, index); + } + return result; + } + + /** + * Creates an object composed from arrays of `keys` and `values`. Provide + * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` + * or two arrays, one of `keys` and one of corresponding `values`. + * + * @static + * @memberOf _ + * @alias object + * @category Arrays + * @param {Array} keys The array of keys. + * @param {Array} [values=[]] The array of values. + * @returns {Object} Returns an object composed of the given keys and + * corresponding values. + * @example + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ + function zipObject(keys, values) { + var index = -1, + length = keys ? keys.length : 0, + result = {}; + + if (!values && length && !isArray(keys[0])) { + values = []; + } + while (++index < length) { + var key = keys[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that executes `func`, with the `this` binding and + * arguments of the created function, only after being called `n` times. + * + * @static + * @memberOf _ + * @category Functions + * @param {number} n The number of times the function must be called before + * `func` is executed. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('Done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'Done saving!', after all saves have completed + */ + function after(n, func) { + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that, when called, invokes `func` with the `this` + * binding of `thisArg` and prepends any additional `bind` arguments to those + * provided to the bound function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var func = function(greeting) { + * return greeting + ' ' + this.name; + * }; + * + * func = _.bind(func, { 'name': 'fred' }, 'hi'); + * func(); + * // => 'hi fred' + */ + function bind(func, thisArg) { + return arguments.length > 2 + ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) + : createWrapper(func, 1, null, null, thisArg); + } + + /** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all the function properties + * of `object` will be bound. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...string} [methodName] The object method names to + * bind, specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { console.log('clicked ' + this.label); } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs', when the button is clicked + */ + function bindAll(object) { + var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), + index = -1, + length = funcs.length; + + while (++index < length) { + var key = funcs[index]; + object[key] = createWrapper(object[key], 1, null, null, object); + } + return object; + } + + /** + * Creates a function that, when called, invokes the method at `object[key]` + * and prepends any additional `bindKey` arguments to those provided to the bound + * function. This method differs from `_.bind` by allowing bound functions to + * reference methods that will be redefined or don't yet exist. + * See http://michaux.ca/articles/lazy-function-definition-pattern. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'name': 'fred', + * 'greet': function(greeting) { + * return greeting + ' ' + this.name; + * } + * }; + * + * var func = _.bindKey(object, 'greet', 'hi'); + * func(); + * // => 'hi fred' + * + * object.greet = function(greeting) { + * return greeting + 'ya ' + this.name + '!'; + * }; + * + * func(); + * // => 'hiya fred!' + */ + function bindKey(object, key) { + return arguments.length > 2 + ? createWrapper(key, 19, slice(arguments, 2), null, object) + : createWrapper(key, 3, null, null, object); + } + + /** + * Creates a function that is the composition of the provided functions, + * where each function consumes the return value of the function that follows. + * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. + * Each function is executed with the `this` binding of the composed function. + * + * @static + * @memberOf _ + * @category Functions + * @param {...Function} [func] Functions to compose. + * @returns {Function} Returns the new composed function. + * @example + * + * var realNameMap = { + * 'pebbles': 'penelope' + * }; + * + * var format = function(name) { + * name = realNameMap[name.toLowerCase()] || name; + * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); + * }; + * + * var greet = function(formatted) { + * return 'Hiya ' + formatted + '!'; + * }; + * + * var welcome = _.compose(greet, format); + * welcome('pebbles'); + * // => 'Hiya Penelope!' + */ + function compose() { + var funcs = arguments, + length = funcs.length; + + while (length--) { + if (!isFunction(funcs[length])) { + throw new TypeError; + } + } + return function() { + var args = arguments, + length = funcs.length; + + while (length--) { + args = [funcs[length].apply(this, args)]; + } + return args[0]; + }; + } + + /** + * Creates a function which accepts one or more arguments of `func` that when + * invoked either executes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` can be specified + * if `func.length` is not sufficient. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @returns {Function} Returns the new curried function. + * @example + * + * var curried = _.curry(function(a, b, c) { + * console.log(a + b + c); + * }); + * + * curried(1)(2)(3); + * // => 6 + * + * curried(1, 2)(3); + * // => 6 + * + * curried(1, 2, 3); + * // => 6 + */ + function curry(func, arity) { + arity = typeof arity == 'number' ? arity : (+arity || func.length); + return createWrapper(func, 4, null, null, null, arity); + } + + /** + * Creates a function that will delay the execution of `func` until after + * `wait` milliseconds have elapsed since the last time it was invoked. + * Provide an options object to indicate that `func` should be invoked on + * the leading and/or trailing edge of the `wait` timeout. Subsequent calls + * to the debounced function will return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to debounce. + * @param {number} wait The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * var lazyLayout = _.debounce(calculateLayout, 150); + * jQuery(window).on('resize', lazyLayout); + * + * // execute `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * }); + * + * // ensure `batchLog` is executed once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * source.addEventListener('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * }, false); + */ + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + wait = nativeMax(0, wait) || 0; + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = options.leading; + maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0); + trailing = 'trailing' in options ? options.trailing : trailing; + } + var delayed = function() { + var remaining = wait - (now() - stamp); + if (remaining <= 0) { + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + var isCalled = trailingCall; + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + } else { + timeoutId = setTimeout(delayed, remaining); + } + }; + + var maxDelayed = function() { + if (timeoutId) { + clearTimeout(timeoutId); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (trailing || (maxWait !== wait)) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + }; + + return function() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + return result; + }; + } + + /** + * Defers executing the `func` function until the current call stack has cleared. + * Additional arguments will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to defer. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { console.log(text); }, 'deferred'); + * // logs 'deferred' after one or more milliseconds + */ + function defer(func) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 1); + return setTimeout(function() { func.apply(undefined, args); }, 1); + } + + /** + * Executes the `func` function after `wait` milliseconds. Additional arguments + * will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay execution. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { console.log(text); }, 1000, 'later'); + * // => logs 'later' after one second + */ + function delay(func, wait) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 2); + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it will be used to determine the cache key for storing the result + * based on the arguments provided to the memoized function. By default, the + * first argument provided to the memoized function is used as the cache key. + * The `func` is executed with the `this` binding of the memoized function. + * The result cache is exposed as the `cache` property on the memoized function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] A function used to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var fibonacci = _.memoize(function(n) { + * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); + * }); + * + * fibonacci(9) + * // => 34 + * + * var data = { + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * }; + * + * // modifying the result cache + * var get = _.memoize(function(name) { return data[name]; }, _.identity); + * get('pebbles'); + * // => { 'name': 'pebbles', 'age': 1 } + * + * get.cache.pebbles.name = 'penelope'; + * get('pebbles'); + * // => { 'name': 'penelope', 'age': 1 } + */ + function memoize(func, resolver) { + if (!isFunction(func)) { + throw new TypeError; + } + var memoized = function() { + var cache = memoized.cache, + key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0]; + + return hasOwnProperty.call(cache, key) + ? cache[key] + : (cache[key] = func.apply(this, arguments)); + } + memoized.cache = {}; + return memoized; + } + + /** + * Creates a function that is restricted to execute `func` once. Repeat calls to + * the function will return the value of the first call. The `func` is executed + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` executes `createApplication` once + */ + function once(func) { + var ran, + result; + + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (ran) { + return result; + } + ran = true; + result = func.apply(this, arguments); + + // clear the `func` variable so the function may be garbage collected + func = null; + return result; + }; + } + + /** + * Creates a function that, when called, invokes `func` with any additional + * `partial` arguments prepended to those provided to the new function. This + * method is similar to `_.bind` except it does **not** alter the `this` binding. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { return greeting + ' ' + name; }; + * var hi = _.partial(greet, 'hi'); + * hi('fred'); + * // => 'hi fred' + */ + function partial(func) { + return createWrapper(func, 16, slice(arguments, 1)); + } + + /** + * This method is like `_.partial` except that `partial` arguments are + * appended to those provided to the new function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var defaultsDeep = _.partialRight(_.merge, _.defaults); + * + * var options = { + * 'variable': 'data', + * 'imports': { 'jq': $ } + * }; + * + * defaultsDeep(options, _.templateSettings); + * + * options.variable + * // => 'data' + * + * options.imports + * // => { '_': _, 'jq': $ } + */ + function partialRight(func) { + return createWrapper(func, 32, null, slice(arguments, 1)); + } + + /** + * Creates a function that, when executed, will only call the `func` function + * at most once per every `wait` milliseconds. Provide an options object to + * indicate that `func` should be invoked on the leading and/or trailing edge + * of the `wait` timeout. Subsequent calls to the throttled function will + * return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to throttle. + * @param {number} wait The number of milliseconds to throttle executions to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // avoid excessively updating the position while scrolling + * var throttled = _.throttle(updatePosition, 100); + * jQuery(window).on('scroll', throttled); + * + * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? options.leading : leading; + trailing = 'trailing' in options ? options.trailing : trailing; + } + debounceOptions.leading = leading; + debounceOptions.maxWait = wait; + debounceOptions.trailing = trailing; + + return debounce(func, wait, debounceOptions); + } + + /** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Additional arguments provided to the function are appended + * to those provided to the wrapper function. The wrapper is executed with + * the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

' + func(text) + '

'; + * }); + * + * p('Fred, Wilma, & Pebbles'); + * // => '

Fred, Wilma, & Pebbles

' + */ + function wrap(value, wrapper) { + return createWrapper(wrapper, 16, [value]); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new function. + * @example + * + * var object = { 'name': 'fred' }; + * var getter = _.constant(object); + * getter() === object; + * // => true + */ + function constant(value) { + return function() { + return value; + }; + } + + /** + * Produces a callback bound to an optional `thisArg`. If `func` is a property + * name the created callback will return the property value for a given element. + * If `func` is an object the created callback will return `true` for elements + * that contain the equivalent object properties, otherwise it will return `false`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // wrap to create custom callback shorthands + * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { + * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); + * return !match ? func(callback, thisArg) : function(object) { + * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; + * }; + * }); + * + * _.filter(characters, 'age__gt38'); + * // => [{ 'name': 'fred', 'age': 40 }] + */ + function createCallback(func, thisArg, argCount) { + var type = typeof func; + if (func == null || type == 'function') { + return baseCreateCallback(func, thisArg, argCount); + } + // handle "_.pluck" style callback shorthands + if (type != 'object') { + return property(func); + } + var props = keys(func), + key = props[0], + a = func[key]; + + // handle "_.where" style callback shorthands + if (props.length == 1 && a === a && !isObject(a)) { + // fast path the common case of providing an object with a single + // property containing a primitive value + return function(object) { + var b = object[key]; + return a === b && (a !== 0 || (1 / a == 1 / b)); + }; + } + return function(object) { + var length = props.length, + result = false; + + while (length--) { + if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { + break; + } + } + return result; + }; + } + + /** + * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their + * corresponding HTML entities. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} string The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('Fred, Wilma, & Pebbles'); + * // => 'Fred, Wilma, & Pebbles' + */ + function escape(string) { + return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); + } + + /** + * This method returns the first argument provided to it. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'name': 'fred' }; + * _.identity(object) === object; + * // => true + */ + function identity(value) { + return value; + } + + /** + * Adds function properties of a source object to the destination object. + * If `object` is a function methods will be added to its prototype as well. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Function|Object} [object=lodash] object The destination object. + * @param {Object} source The object of functions to add. + * @param {Object} [options] The options object. + * @param {boolean} [options.chain=true] Specify whether the functions added are chainable. + * @example + * + * function capitalize(string) { + * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); + * } + * + * _.mixin({ 'capitalize': capitalize }); + * _.capitalize('fred'); + * // => 'Fred' + * + * _('fred').capitalize().value(); + * // => 'Fred' + * + * _.mixin({ 'capitalize': capitalize }, { 'chain': false }); + * _('fred').capitalize(); + * // => 'Fred' + */ + function mixin(object, source, options) { + var chain = true, + methodNames = source && functions(source); + + if (!source || (!options && !methodNames.length)) { + if (options == null) { + options = source; + } + ctor = lodashWrapper; + source = object; + object = lodash; + methodNames = functions(source); + } + if (options === false) { + chain = false; + } else if (isObject(options) && 'chain' in options) { + chain = options.chain; + } + var ctor = object, + isFunc = isFunction(ctor); + + forEach(methodNames, function(methodName) { + var func = object[methodName] = source[methodName]; + if (isFunc) { + ctor.prototype[methodName] = function() { + var chainAll = this.__chain__, + value = this.__wrapped__, + args = [value]; + + push.apply(args, arguments); + var result = func.apply(object, args); + if (chain || chainAll) { + if (value === result && isObject(result)) { + return this; + } + result = new ctor(result); + result.__chain__ = chainAll; + } + return result; + }; + } + }); + } + + /** + * Reverts the '_' variable to its previous value and returns a reference to + * the `lodash` function. + * + * @static + * @memberOf _ + * @category Utilities + * @returns {Function} Returns the `lodash` function. + * @example + * + * var lodash = _.noConflict(); + */ + function noConflict() { + context._ = oldDash; + return this; + } + + /** + * A no-operation function. + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var object = { 'name': 'fred' }; + * _.noop(object) === undefined; + * // => true + */ + function noop() { + // no operation performed + } + + /** + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var stamp = _.now(); + * _.defer(function() { console.log(_.now() - stamp); }); + * // => logs the number of milliseconds it took for the deferred function to be called + */ + var now = isNative(now = Date.now) && now || function() { + return new Date().getTime(); + }; + + /** + * Converts the given value into an integer of the specified radix. + * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the + * `value` is a hexadecimal, in which case a `radix` of `16` is used. + * + * Note: This method avoids differences in native ES3 and ES5 `parseInt` + * implementations. See http://es5.github.io/#E. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} value The value to parse. + * @param {number} [radix] The radix used to interpret the value to parse. + * @returns {number} Returns the new integer value. + * @example + * + * _.parseInt('08'); + * // => 8 + */ + var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) { + // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt` + return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0); + }; + + /** + * Creates a "_.pluck" style function, which returns the `key` value of a + * given object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} key The name of the property to retrieve. + * @returns {Function} Returns the new function. + * @example + * + * var characters = [ + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 36 } + * ]; + * + * var getName = _.property('name'); + * + * _.map(characters, getName); + * // => ['barney', 'fred'] + * + * _.sortBy(characters, getName); + * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] + */ + function property(key) { + return function(object) { + return object[key]; + }; + } + + /** + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is provided a number between `0` and the given number will be + * returned. If `floating` is truey or either `min` or `max` are floats a + * floating-point number will be returned instead of an integer. + * + * @static + * @memberOf _ + * @category Utilities + * @param {number} [min=0] The minimum possible value. + * @param {number} [max=1] The maximum possible value. + * @param {boolean} [floating=false] Specify returning a floating-point number. + * @returns {number} Returns a random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(min, max, floating) { + var noMin = min == null, + noMax = max == null; + + if (floating == null) { + if (typeof min == 'boolean' && noMax) { + floating = min; + min = 1; + } + else if (!noMax && typeof max == 'boolean') { + floating = max; + noMax = true; + } + } + if (noMin && noMax) { + max = 1; + } + min = +min || 0; + if (noMax) { + max = min; + min = 0; + } else { + max = +max || 0; + } + if (floating || min % 1 || max % 1) { + var rand = nativeRandom(); + return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max); + } + return baseRandom(min, max); + } + + /** + * Resolves the value of property `key` on `object`. If `key` is a function + * it will be invoked with the `this` binding of `object` and its result returned, + * else the property value is returned. If `object` is falsey then `undefined` + * is returned. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to resolve. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { + * 'cheese': 'crumpets', + * 'stuff': function() { + * return 'nonsense'; + * } + * }; + * + * _.result(object, 'cheese'); + * // => 'crumpets' + * + * _.result(object, 'stuff'); + * // => 'nonsense' + */ + function result(object, key) { + if (object) { + var value = object[key]; + return isFunction(value) ? object[key]() : value; + } + } + + /** + * A micro-templating method that handles arbitrary delimiters, preserves + * whitespace, and correctly escapes quotes within interpolated code. + * + * Note: In the development build, `_.template` utilizes sourceURLs for easier + * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl + * + * For more information on precompiling templates see: + * https://lodash.com/custom-builds + * + * For more information on Chrome extension sandboxes see: + * http://developer.chrome.com/stable/extensions/sandboxingEval.html + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} text The template text. + * @param {Object} data The data object used to populate the text. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as local variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [sourceURL] The sourceURL of the template's compiled source. + * @param {string} [variable] The data object variable name. + * @returns {Function|string} Returns a compiled function when no `data` object + * is given, else it returns the interpolated text. + * @example + * + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= name %>'); + * compiled({ 'name': 'fred' }); + * // => 'hello fred' + * + * // using the "escape" delimiter to escape HTML in data property values + * _.template('<%- value %>', { 'value': ' + +``` + +## Documentation + +Some functions are also available in the following forms: +* `Series` - the same as `` but runs only a single async operation at a time +* `Limit` - the same as `` but runs a maximum of `limit` async operations at a time + +### Collections + +* [`each`](#each), `eachSeries`, `eachLimit` +* [`forEachOf`](#forEachOf), `forEachOfSeries`, `forEachOfLimit` +* [`map`](#map), `mapSeries`, `mapLimit` +* [`filter`](#filter), `filterSeries`, `filterLimit` +* [`reject`](#reject), `rejectSeries`, `rejectLimit` +* [`reduce`](#reduce), [`reduceRight`](#reduceRight) +* [`detect`](#detect), `detectSeries`, `detectLimit` +* [`sortBy`](#sortBy) +* [`some`](#some), `someLimit` +* [`every`](#every), `everyLimit` +* [`concat`](#concat), `concatSeries` + +### Control Flow + +* [`series`](#seriestasks-callback) +* [`parallel`](#parallel), `parallelLimit` +* [`whilst`](#whilst), [`doWhilst`](#doWhilst) +* [`until`](#until), [`doUntil`](#doUntil) +* [`during`](#during), [`doDuring`](#doDuring) +* [`forever`](#forever) +* [`waterfall`](#waterfall) +* [`compose`](#compose) +* [`seq`](#seq) +* [`applyEach`](#applyEach), `applyEachSeries` +* [`queue`](#queue), [`priorityQueue`](#priorityQueue) +* [`cargo`](#cargo) +* [`auto`](#auto) +* [`retry`](#retry) +* [`iterator`](#iterator) +* [`times`](#times), `timesSeries`, `timesLimit` + +### Utils + +* [`apply`](#apply) +* [`nextTick`](#nextTick) +* [`memoize`](#memoize) +* [`unmemoize`](#unmemoize) +* [`ensureAsync`](#ensureAsync) +* [`constant`](#constant) +* [`asyncify`](#asyncify) +* [`wrapSync`](#wrapSync) +* [`log`](#log) +* [`dir`](#dir) +* [`noConflict`](#noConflict) + +## Collections + + + +### each(arr, iterator, [callback]) + +Applies the function `iterator` to each item in `arr`, in parallel. +The `iterator` is called with an item from the list, and a callback for when it +has finished. If the `iterator` passes an error to its `callback`, the main +`callback` (for the `each` function) is immediately called with the error. + +Note, that since this function applies `iterator` to each item in parallel, +there is no guarantee that the iterator functions will complete in order. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err)` which must be called once it has + completed. If no error has occurred, the `callback` should be run without + arguments or with an explicit `null` argument. The array index is not passed + to the iterator. If you need the index, use [`forEachOf`](#forEachOf). +* `callback(err)` - *Optional* A callback which is called when all `iterator` functions + have finished, or an error occurs. + +__Examples__ + + +```js +// assuming openFiles is an array of file names and saveFile is a function +// to save the modified contents of that file: + +async.each(openFiles, saveFile, function(err){ + // if any of the saves produced an error, err would equal that error +}); +``` + +```js +// assuming openFiles is an array of file names + +async.each(openFiles, function(file, callback) { + + // Perform operation on file here. + console.log('Processing file ' + file); + + if( file.length > 32 ) { + console.log('This file name is too long'); + callback('File name too long'); + } else { + // Do work to process file here + console.log('File processed'); + callback(); + } +}, function(err){ + // if any of the file processing produced an error, err would equal that error + if( err ) { + // One of the iterations produced an error. + // All processing will now stop. + console.log('A file failed to process'); + } else { + console.log('All files have been processed successfully'); + } +}); +``` + +__Related__ + +* eachSeries(arr, iterator, [callback]) +* eachLimit(arr, limit, iterator, [callback]) + +--------------------------------------- + + + + +### forEachOf(obj, iterator, [callback]) + +Like `each`, except that it iterates over objects, and passes the key as the second argument to the iterator. + +__Arguments__ + +* `obj` - An object or array to iterate over. +* `iterator(item, key, callback)` - A function to apply to each item in `obj`. +The `key` is the item's key, or index in the case of an array. The iterator is +passed a `callback(err)` which must be called once it has completed. If no +error has occurred, the callback should be run without arguments or with an +explicit `null` argument. +* `callback(err)` - *Optional* A callback which is called when all `iterator` functions have finished, or an error occurs. + +__Example__ + +```js +var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"}; +var configs = {}; + +async.forEachOf(obj, function (value, key, callback) { + fs.readFile(__dirname + value, "utf8", function (err, data) { + if (err) return callback(err); + try { + configs[key] = JSON.parse(data); + } catch (e) { + return callback(e); + } + callback(); + }) +}, function (err) { + if (err) console.error(err.message); + // configs is now a map of JSON data + doSomethingWith(configs); +}) +``` + +__Related__ + +* forEachOfSeries(obj, iterator, [callback]) +* forEachOfLimit(obj, limit, iterator, [callback]) + +--------------------------------------- + + +### map(arr, iterator, [callback]) + +Produces a new array of values by mapping each value in `arr` through +the `iterator` function. The `iterator` is called with an item from `arr` and a +callback for when it has finished processing. Each of these callback takes 2 arguments: +an `error`, and the transformed item from `arr`. If `iterator` passes an error to its +callback, the main `callback` (for the `map` function) is immediately called with the error. + +Note, that since this function applies the `iterator` to each item in parallel, +there is no guarantee that the `iterator` functions will complete in order. +However, the results array will be in the same order as the original `arr`. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err, transformed)` which must be called once + it has completed with an error (which can be `null`) and a transformed item. +* `callback(err, results)` - *Optional* A callback which is called when all `iterator` + functions have finished, or an error occurs. Results is an array of the + transformed items from the `arr`. + +__Example__ + +```js +async.map(['file1','file2','file3'], fs.stat, function(err, results){ + // results is now an array of stats for each file +}); +``` + +__Related__ +* mapSeries(arr, iterator, [callback]) +* mapLimit(arr, limit, iterator, [callback]) + +--------------------------------------- + + + +### filter(arr, iterator, [callback]) + +__Alias:__ `select` + +Returns a new array of all the values in `arr` which pass an async truth test. +_The callback for each `iterator` call only accepts a single argument of `true` or +`false`; it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like `fs.exists`. This operation is +performed in parallel, but the results array will be in the same order as the +original. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in `arr`. + The `iterator` is passed a `callback(truthValue)`, which must be called with a + boolean argument once it has completed. +* `callback(results)` - *Optional* A callback which is called after all the `iterator` + functions have finished. + +__Example__ + +```js +async.filter(['file1','file2','file3'], fs.exists, function(results){ + // results now equals an array of the existing files +}); +``` + +__Related__ + +* filterSeries(arr, iterator, [callback]) +* filterLimit(arr, limit, iterator, [callback]) + +--------------------------------------- + + +### reject(arr, iterator, [callback]) + +The opposite of [`filter`](#filter). Removes values that pass an `async` truth test. + +__Related__ + +* rejectSeries(arr, iterator, [callback]) +* rejectLimit(arr, limit, iterator, [callback]) + +--------------------------------------- + + +### reduce(arr, memo, iterator, [callback]) + +__Aliases:__ `inject`, `foldl` + +Reduces `arr` into a single value using an async `iterator` to return +each successive step. `memo` is the initial state of the reduction. +This function only operates in series. + +For performance reasons, it may make sense to split a call to this function into +a parallel map, and then use the normal `Array.prototype.reduce` on the results. +This function is for situations where each step in the reduction needs to be async; +if you can get the data before reducing it, then it's probably a good idea to do so. + +__Arguments__ + +* `arr` - An array to iterate over. +* `memo` - The initial state of the reduction. +* `iterator(memo, item, callback)` - A function applied to each item in the + array to produce the next step in the reduction. The `iterator` is passed a + `callback(err, reduction)` which accepts an optional error as its first + argument, and the state of the reduction as the second. If an error is + passed to the callback, the reduction is stopped and the main `callback` is + immediately called with the error. +* `callback(err, result)` - *Optional* A callback which is called after all the `iterator` + functions have finished. Result is the reduced value. + +__Example__ + +```js +async.reduce([1,2,3], 0, function(memo, item, callback){ + // pointless async: + process.nextTick(function(){ + callback(null, memo + item) + }); +}, function(err, result){ + // result is now equal to the last value of memo, which is 6 +}); +``` + +--------------------------------------- + + +### reduceRight(arr, memo, iterator, [callback]) + +__Alias:__ `foldr` + +Same as [`reduce`](#reduce), only operates on `arr` in reverse order. + + +--------------------------------------- + + +### detect(arr, iterator, [callback]) + +Returns the first value in `arr` that passes an async truth test. The +`iterator` is applied in parallel, meaning the first iterator to return `true` will +fire the detect `callback` with that result. That means the result might not be +the first item in the original `arr` (in terms of order) that passes the test. + +If order within the original `arr` is important, then look at [`detectSeries`](#detectSeries). + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in `arr`. + The iterator is passed a `callback(truthValue)` which must be called with a + boolean argument once it has completed. **Note: this callback does not take an error as its first argument.** +* `callback(result)` - *Optional* A callback which is called as soon as any iterator returns + `true`, or after all the `iterator` functions have finished. Result will be + the first item in the array that passes the truth test (iterator) or the + value `undefined` if none passed. **Note: this callback does not take an error as its first argument.** + +__Example__ + +```js +async.detect(['file1','file2','file3'], fs.exists, function(result){ + // result now equals the first file in the list that exists +}); +``` + +__Related__ + +* detectSeries(arr, iterator, [callback]) +* detectLimit(arr, limit, iterator, [callback]) + +--------------------------------------- + + +### sortBy(arr, iterator, [callback]) + +Sorts a list by the results of running each `arr` value through an async `iterator`. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err, sortValue)` which must be called once it + has completed with an error (which can be `null`) and a value to use as the sort + criteria. +* `callback(err, results)` - *Optional* A callback which is called after all the `iterator` + functions have finished, or an error occurs. Results is the items from + the original `arr` sorted by the values returned by the `iterator` calls. + +__Example__ + +```js +async.sortBy(['file1','file2','file3'], function(file, callback){ + fs.stat(file, function(err, stats){ + callback(err, stats.mtime); + }); +}, function(err, results){ + // results is now the original array of files sorted by + // modified date +}); +``` + +__Sort Order__ + +By modifying the callback parameter the sorting order can be influenced: + +```js +//ascending order +async.sortBy([1,9,3,5], function(x, callback){ + callback(null, x); +}, function(err,result){ + //result callback +} ); + +//descending order +async.sortBy([1,9,3,5], function(x, callback){ + callback(null, x*-1); //<- x*-1 instead of x, turns the order around +}, function(err,result){ + //result callback +} ); +``` + +--------------------------------------- + + +### some(arr, iterator, [callback]) + +__Alias:__ `any` + +Returns `true` if at least one element in the `arr` satisfies an async test. +_The callback for each iterator call only accepts a single argument of `true` or +`false`; it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like `fs.exists`. Once any iterator +call returns `true`, the main `callback` is immediately called. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in the array + in parallel. The iterator is passed a `callback(truthValue)`` which must be + called with a boolean argument once it has completed. +* `callback(result)` - *Optional* A callback which is called as soon as any iterator returns + `true`, or after all the iterator functions have finished. Result will be + either `true` or `false` depending on the values of the async tests. + + **Note: the callbacks do not take an error as their first argument.** +__Example__ + +```js +async.some(['file1','file2','file3'], fs.exists, function(result){ + // if result is true then at least one of the files exists +}); +``` + +__Related__ + +* someLimit(arr, limit, iterator, callback) + +--------------------------------------- + + +### every(arr, iterator, [callback]) + +__Alias:__ `all` + +Returns `true` if every element in `arr` satisfies an async test. +_The callback for each `iterator` call only accepts a single argument of `true` or +`false`; it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like `fs.exists`. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in the array + in parallel. The iterator is passed a `callback(truthValue)` which must be + called with a boolean argument once it has completed. +* `callback(result)` - *Optional* A callback which is called as soon as any iterator returns + `false`, or after all the iterator functions have finished. Result will be + either `true` or `false` depending on the values of the async tests. + + **Note: the callbacks do not take an error as their first argument.** + +__Example__ + +```js +async.every(['file1','file2','file3'], fs.exists, function(result){ + // if result is true then every file exists +}); +``` + +__Related__ + +* everyLimit(arr, limit, iterator, callback) + +--------------------------------------- + + +### concat(arr, iterator, [callback]) + +Applies `iterator` to each item in `arr`, concatenating the results. Returns the +concatenated list. The `iterator`s are called in parallel, and the results are +concatenated as they return. There is no guarantee that the results array will +be returned in the original order of `arr` passed to the `iterator` function. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err, results)` which must be called once it + has completed with an error (which can be `null`) and an array of results. +* `callback(err, results)` - *Optional* A callback which is called after all the `iterator` + functions have finished, or an error occurs. Results is an array containing + the concatenated results of the `iterator` function. + +__Example__ + +```js +async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){ + // files is now a list of filenames that exist in the 3 directories +}); +``` + +__Related__ + +* concatSeries(arr, iterator, [callback]) + + +## Control Flow + + +### series(tasks, [callback]) + +Run the functions in the `tasks` array in series, each one running once the previous +function has completed. If any functions in the series pass an error to its +callback, no more functions are run, and `callback` is immediately called with the value of the error. +Otherwise, `callback` receives an array of results when `tasks` have completed. + +It is also possible to use an object instead of an array. Each property will be +run as a function, and the results will be passed to the final `callback` as an object +instead of an array. This can be a more readable way of handling results from +[`series`](#series). + +**Note** that while many implementations preserve the order of object properties, the +[ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) +explicitly states that + +> The mechanics and order of enumerating the properties is not specified. + +So if you rely on the order in which your series of functions are executed, and want +this to work on all platforms, consider using an array. + +__Arguments__ + +* `tasks` - An array or object containing functions to run, each function is passed + a `callback(err, result)` it must call on completion with an error `err` (which can + be `null`) and an optional `result` value. +* `callback(err, results)` - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the `task` callbacks. + +__Example__ + +```js +async.series([ + function(callback){ + // do some stuff ... + callback(null, 'one'); + }, + function(callback){ + // do some more stuff ... + callback(null, 'two'); + } +], +// optional callback +function(err, results){ + // results is now equal to ['one', 'two'] +}); + + +// an example using an object instead of an array +async.series({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + } +}, +function(err, results) { + // results is now equal to: {one: 1, two: 2} +}); +``` + +--------------------------------------- + + +### parallel(tasks, [callback]) + +Run the `tasks` array of functions in parallel, without waiting until the previous +function has completed. If any of the functions pass an error to its +callback, the main `callback` is immediately called with the value of the error. +Once the `tasks` have completed, the results are passed to the final `callback` as an +array. + +**Note:** `parallel` is about kicking-off I/O tasks in parallel, not about parallel execution of code. If your tasks do not use any timers or perform any I/O, they will actually be executed in series. Any synchronous setup sections for each task will happen one after the other. JavaScript remains single-threaded. + +It is also possible to use an object instead of an array. Each property will be +run as a function and the results will be passed to the final `callback` as an object +instead of an array. This can be a more readable way of handling results from +[`parallel`](#parallel). + + +__Arguments__ + +* `tasks` - An array or object containing functions to run. Each function is passed + a `callback(err, result)` which it must call on completion with an error `err` + (which can be `null`) and an optional `result` value. +* `callback(err, results)` - An optional callback to run once all the functions + have completed successfully. This function gets a results array (or object) containing all + the result arguments passed to the task callbacks. + +__Example__ + +```js +async.parallel([ + function(callback){ + setTimeout(function(){ + callback(null, 'one'); + }, 200); + }, + function(callback){ + setTimeout(function(){ + callback(null, 'two'); + }, 100); + } +], +// optional callback +function(err, results){ + // the results array will equal ['one','two'] even though + // the second function had a shorter timeout. +}); + + +// an example using an object instead of an array +async.parallel({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + } +}, +function(err, results) { + // results is now equals to: {one: 1, two: 2} +}); +``` + +__Related__ + +* parallelLimit(tasks, limit, [callback]) + +--------------------------------------- + + +### whilst(test, fn, callback) + +Repeatedly call `fn`, while `test` returns `true`. Calls `callback` when stopped, +or an error occurs. + +__Arguments__ + +* `test()` - synchronous truth test to perform before each execution of `fn`. +* `fn(callback)` - A function which is called each time `test` passes. The function is + passed a `callback(err)`, which must be called once it has completed with an + optional `err` argument. +* `callback(err, [results])` - A callback which is called after the test + function has failed and repeated execution of `fn` has stopped. `callback` + will be passed an error and any arguments passed to the final `fn`'s callback. + +__Example__ + +```js +var count = 0; + +async.whilst( + function () { return count < 5; }, + function (callback) { + count++; + setTimeout(function () { + callback(null, count); + }, 1000); + }, + function (err, n) { + // 5 seconds have passed, n = 5 + } +); +``` + +--------------------------------------- + + +### doWhilst(fn, test, callback) + +The post-check version of [`whilst`](#whilst). To reflect the difference in +the order of operations, the arguments `test` and `fn` are switched. + +`doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. + +--------------------------------------- + + +### until(test, fn, callback) + +Repeatedly call `fn` until `test` returns `true`. Calls `callback` when stopped, +or an error occurs. `callback` will be passed an error and any arguments passed +to the final `fn`'s callback. + +The inverse of [`whilst`](#whilst). + +--------------------------------------- + + +### doUntil(fn, test, callback) + +Like [`doWhilst`](#doWhilst), except the `test` is inverted. Note the argument ordering differs from `until`. + +--------------------------------------- + + +### during(test, fn, callback) + +Like [`whilst`](#whilst), except the `test` is an asynchronous function that is passed a callback in the form of `function (err, truth)`. If error is passed to `test` or `fn`, the main callback is immediately called with the value of the error. + +__Example__ + +```js +var count = 0; + +async.during( + function (callback) { + return callback(null, count < 5); + }, + function (callback) { + count++; + setTimeout(callback, 1000); + }, + function (err) { + // 5 seconds have passed + } +); +``` + +--------------------------------------- + + +### doDuring(fn, test, callback) + +The post-check version of [`during`](#during). To reflect the difference in +the order of operations, the arguments `test` and `fn` are switched. + +Also a version of [`doWhilst`](#doWhilst) with asynchronous `test` function. + +--------------------------------------- + + +### forever(fn, [errback]) + +Calls the asynchronous function `fn` with a callback parameter that allows it to +call itself again, in series, indefinitely. + +If an error is passed to the callback then `errback` is called with the +error, and execution stops, otherwise it will never be called. + +```js +async.forever( + function(next) { + // next is suitable for passing to things that need a callback(err [, whatever]); + // it will result in this function being called again. + }, + function(err) { + // if next is called with a value in its first parameter, it will appear + // in here as 'err', and execution will stop. + } +); +``` + +--------------------------------------- + + +### waterfall(tasks, [callback]) + +Runs the `tasks` array of functions in series, each passing their results to the next in +the array. However, if any of the `tasks` pass an error to their own callback, the +next function is not executed, and the main `callback` is immediately called with +the error. + +__Arguments__ + +* `tasks` - An array of functions to run, each function is passed a + `callback(err, result1, result2, ...)` it must call on completion. The first + argument is an error (which can be `null`) and any further arguments will be + passed as arguments in order to the next task. +* `callback(err, [results])` - An optional callback to run once all the functions + have completed. This will be passed the results of the last task's callback. + + + +__Example__ + +```js +async.waterfall([ + function(callback) { + callback(null, 'one', 'two'); + }, + function(arg1, arg2, callback) { + // arg1 now equals 'one' and arg2 now equals 'two' + callback(null, 'three'); + }, + function(arg1, callback) { + // arg1 now equals 'three' + callback(null, 'done'); + } +], function (err, result) { + // result now equals 'done' +}); +``` +Or, with named functions: + +```js +async.waterfall([ + myFirstFunction, + mySecondFunction, + myLastFunction, +], function (err, result) { + // result now equals 'done' +}); +function myFirstFunction(callback) { + callback(null, 'one', 'two'); +} +function mySecondFunction(arg1, arg2, callback) { + // arg1 now equals 'one' and arg2 now equals 'two' + callback(null, 'three'); +} +function myLastFunction(arg1, callback) { + // arg1 now equals 'three' + callback(null, 'done'); +} +``` + +Or, if you need to pass any argument to the first function: + +```js +async.waterfall([ + async.apply(myFirstFunction, 'zero'), + mySecondFunction, + myLastFunction, +], function (err, result) { + // result now equals 'done' +}); +function myFirstFunction(arg1, callback) { + // arg1 now equals 'zero' + callback(null, 'one', 'two'); +} +function mySecondFunction(arg1, arg2, callback) { + // arg1 now equals 'one' and arg2 now equals 'two' + callback(null, 'three'); +} +function myLastFunction(arg1, callback) { + // arg1 now equals 'three' + callback(null, 'done'); +} +``` + +--------------------------------------- + +### compose(fn1, fn2...) + +Creates a function which is a composition of the passed asynchronous +functions. Each function consumes the return value of the function that +follows. Composing functions `f()`, `g()`, and `h()` would produce the result of +`f(g(h()))`, only this version uses callbacks to obtain the return values. + +Each function is executed with the `this` binding of the composed function. + +__Arguments__ + +* `functions...` - the asynchronous functions to compose + + +__Example__ + +```js +function add1(n, callback) { + setTimeout(function () { + callback(null, n + 1); + }, 10); +} + +function mul3(n, callback) { + setTimeout(function () { + callback(null, n * 3); + }, 10); +} + +var add1mul3 = async.compose(mul3, add1); + +add1mul3(4, function (err, result) { + // result now equals 15 +}); +``` + +--------------------------------------- + +### seq(fn1, fn2...) + +Version of the compose function that is more natural to read. +Each function consumes the return value of the previous function. +It is the equivalent of [`compose`](#compose) with the arguments reversed. + +Each function is executed with the `this` binding of the composed function. + +__Arguments__ + +* `functions...` - the asynchronous functions to compose + + +__Example__ + +```js +// Requires lodash (or underscore), express3 and dresende's orm2. +// Part of an app, that fetches cats of the logged user. +// This example uses `seq` function to avoid overnesting and error +// handling clutter. +app.get('/cats', function(request, response) { + var User = request.models.User; + async.seq( + _.bind(User.get, User), // 'User.get' has signature (id, callback(err, data)) + function(user, fn) { + user.getCats(fn); // 'getCats' has signature (callback(err, data)) + } + )(req.session.user_id, function (err, cats) { + if (err) { + console.error(err); + response.json({ status: 'error', message: err.message }); + } else { + response.json({ status: 'ok', message: 'Cats found', data: cats }); + } + }); +}); +``` + +--------------------------------------- + +### applyEach(fns, args..., callback) + +Applies the provided arguments to each function in the array, calling +`callback` after all functions have completed. If you only provide the first +argument, then it will return a function which lets you pass in the +arguments as if it were a single function call. + +__Arguments__ + +* `fns` - the asynchronous functions to all call with the same arguments +* `args...` - any number of separate arguments to pass to the function +* `callback` - the final argument should be the callback, called when all + functions have completed processing + + +__Example__ + +```js +async.applyEach([enableSearch, updateSchema], 'bucket', callback); + +// partial application example: +async.each( + buckets, + async.applyEach([enableSearch, updateSchema]), + callback +); +``` + +__Related__ + +* applyEachSeries(tasks, args..., [callback]) + +--------------------------------------- + + +### queue(worker, [concurrency]) + +Creates a `queue` object with the specified `concurrency`. Tasks added to the +`queue` are processed in parallel (up to the `concurrency` limit). If all +`worker`s are in progress, the task is queued until one becomes available. +Once a `worker` completes a `task`, that `task`'s callback is called. + +__Arguments__ + +* `worker(task, callback)` - An asynchronous function for processing a queued + task, which must call its `callback(err)` argument when finished, with an + optional `error` as an argument. If you want to handle errors from an individual task, pass a callback to `q.push()`. +* `concurrency` - An `integer` for determining how many `worker` functions should be + run in parallel. If omitted, the concurrency defaults to `1`. If the concurrency is `0`, an error is thrown. + +__Queue objects__ + +The `queue` object returned by this function has the following properties and +methods: + +* `length()` - a function returning the number of items waiting to be processed. +* `started` - a function returning whether or not any items have been pushed and processed by the queue +* `running()` - a function returning the number of items currently being processed. +* `workersList()` - a function returning the array of items currently being processed. +* `idle()` - a function returning false if there are items waiting or being processed, or true if not. +* `concurrency` - an integer for determining how many `worker` functions should be + run in parallel. This property can be changed after a `queue` is created to + alter the concurrency on-the-fly. +* `push(task, [callback])` - add a new task to the `queue`. Calls `callback` once + the `worker` has finished processing the task. Instead of a single task, a `tasks` array + can be submitted. The respective callback is used for every task in the list. +* `unshift(task, [callback])` - add a new task to the front of the `queue`. +* `saturated` - a callback that is called when the `queue` length hits the `concurrency` limit, + and further tasks will be queued. +* `empty` - a callback that is called when the last item from the `queue` is given to a `worker`. +* `drain` - a callback that is called when the last item from the `queue` has returned from the `worker`. +* `paused` - a boolean for determining whether the queue is in a paused state +* `pause()` - a function that pauses the processing of tasks until `resume()` is called. +* `resume()` - a function that resumes the processing of queued tasks when the queue is paused. +* `kill()` - a function that removes the `drain` callback and empties remaining tasks from the queue forcing it to go idle. + +__Example__ + +```js +// create a queue object with concurrency 2 + +var q = async.queue(function (task, callback) { + console.log('hello ' + task.name); + callback(); +}, 2); + + +// assign a callback +q.drain = function() { + console.log('all items have been processed'); +} + +// add some items to the queue + +q.push({name: 'foo'}, function (err) { + console.log('finished processing foo'); +}); +q.push({name: 'bar'}, function (err) { + console.log('finished processing bar'); +}); + +// add some items to the queue (batch-wise) + +q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) { + console.log('finished processing item'); +}); + +// add some items to the front of the queue + +q.unshift({name: 'bar'}, function (err) { + console.log('finished processing bar'); +}); +``` + + +--------------------------------------- + + +### priorityQueue(worker, concurrency) + +The same as [`queue`](#queue) only tasks are assigned a priority and completed in ascending priority order. There are two differences between `queue` and `priorityQueue` objects: + +* `push(task, priority, [callback])` - `priority` should be a number. If an array of + `tasks` is given, all tasks will be assigned the same priority. +* The `unshift` method was removed. + +--------------------------------------- + + +### cargo(worker, [payload]) + +Creates a `cargo` object with the specified payload. Tasks added to the +cargo will be processed altogether (up to the `payload` limit). If the +`worker` is in progress, the task is queued until it becomes available. Once +the `worker` has completed some tasks, each callback of those tasks is called. +Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966) for how `cargo` and `queue` work. + +While [queue](#queue) passes only one task to one of a group of workers +at a time, cargo passes an array of tasks to a single worker, repeating +when the worker is finished. + +__Arguments__ + +* `worker(tasks, callback)` - An asynchronous function for processing an array of + queued tasks, which must call its `callback(err)` argument when finished, with + an optional `err` argument. +* `payload` - An optional `integer` for determining how many tasks should be + processed per round; if omitted, the default is unlimited. + +__Cargo objects__ + +The `cargo` object returned by this function has the following properties and +methods: + +* `length()` - A function returning the number of items waiting to be processed. +* `payload` - An `integer` for determining how many tasks should be + process per round. This property can be changed after a `cargo` is created to + alter the payload on-the-fly. +* `push(task, [callback])` - Adds `task` to the `queue`. The callback is called + once the `worker` has finished processing the task. Instead of a single task, an array of `tasks` + can be submitted. The respective callback is used for every task in the list. +* `saturated` - A callback that is called when the `queue.length()` hits the concurrency and further tasks will be queued. +* `empty` - A callback that is called when the last item from the `queue` is given to a `worker`. +* `drain` - A callback that is called when the last item from the `queue` has returned from the `worker`. +* `idle()`, `pause()`, `resume()`, `kill()` - cargo inherits all of the same methods and event calbacks as [`queue`](#queue) + +__Example__ + +```js +// create a cargo object with payload 2 + +var cargo = async.cargo(function (tasks, callback) { + for(var i=0; i +### auto(tasks, [concurrency], [callback]) + +Determines the best order for running the functions in `tasks`, based on their requirements. Each function can optionally depend on other functions being completed first, and each function is run as soon as its requirements are satisfied. + +If any of the functions pass an error to their callback, the `auto` sequence will stop. Further tasks will not execute (so any other functions depending on it will not run), and the main `callback` is immediately called with the error. Functions also receive an object containing the results of functions which have completed so far. + +Note, all functions are called with a `results` object as a second argument, +so it is unsafe to pass functions in the `tasks` object which cannot handle the +extra argument. + +For example, this snippet of code: + +```js +async.auto({ + readData: async.apply(fs.readFile, 'data.txt', 'utf-8') +}, callback); +``` + +will have the effect of calling `readFile` with the results object as the last +argument, which will fail: + +```js +fs.readFile('data.txt', 'utf-8', cb, {}); +``` + +Instead, wrap the call to `readFile` in a function which does not forward the +`results` object: + +```js +async.auto({ + readData: function(cb, results){ + fs.readFile('data.txt', 'utf-8', cb); + } +}, callback); +``` + +__Arguments__ + +* `tasks` - An object. Each of its properties is either a function or an array of + requirements, with the function itself the last item in the array. The object's key + of a property serves as the name of the task defined by that property, + i.e. can be used when specifying requirements for other tasks. + The function receives two arguments: (1) a `callback(err, result)` which must be + called when finished, passing an `error` (which can be `null`) and the result of + the function's execution, and (2) a `results` object, containing the results of + the previously executed functions. +* `concurrency` - An optional `integer` for determining the maximum number of tasks that can be run in parallel. By default, as many as possible. +* `callback(err, results)` - An optional callback which is called when all the + tasks have been completed. It receives the `err` argument if any `tasks` + pass an error to their callback. Results are always returned; however, if + an error occurs, no further `tasks` will be performed, and the results + object will only contain partial results. + + +__Example__ + +```js +async.auto({ + get_data: function(callback){ + console.log('in get_data'); + // async code to get some data + callback(null, 'data', 'converted to array'); + }, + make_folder: function(callback){ + console.log('in make_folder'); + // async code to create a directory to store a file in + // this is run at the same time as getting the data + callback(null, 'folder'); + }, + write_file: ['get_data', 'make_folder', function(callback, results){ + console.log('in write_file', JSON.stringify(results)); + // once there is some data and the directory exists, + // write the data to a file in the directory + callback(null, 'filename'); + }], + email_link: ['write_file', function(callback, results){ + console.log('in email_link', JSON.stringify(results)); + // once the file is written let's email a link to it... + // results.write_file contains the filename returned by write_file. + callback(null, {'file':results.write_file, 'email':'user@example.com'}); + }] +}, function(err, results) { + console.log('err = ', err); + console.log('results = ', results); +}); +``` + +This is a fairly trivial example, but to do this using the basic parallel and +series functions would look like this: + +```js +async.parallel([ + function(callback){ + console.log('in get_data'); + // async code to get some data + callback(null, 'data', 'converted to array'); + }, + function(callback){ + console.log('in make_folder'); + // async code to create a directory to store a file in + // this is run at the same time as getting the data + callback(null, 'folder'); + } +], +function(err, results){ + async.series([ + function(callback){ + console.log('in write_file', JSON.stringify(results)); + // once there is some data and the directory exists, + // write the data to a file in the directory + results.push('filename'); + callback(null); + }, + function(callback){ + console.log('in email_link', JSON.stringify(results)); + // once the file is written let's email a link to it... + callback(null, {'file':results.pop(), 'email':'user@example.com'}); + } + ]); +}); +``` + +For a complicated series of `async` tasks, using the [`auto`](#auto) function makes adding +new tasks much easier (and the code more readable). + + +--------------------------------------- + + +### retry([opts = {times: 5, interval: 0}| 5], task, [callback]) + +Attempts to get a successful response from `task` no more than `times` times before +returning an error. If the task is successful, the `callback` will be passed the result +of the successful task. If all attempts fail, the callback will be passed the error and +result (if any) of the final attempt. + +__Arguments__ + +* `opts` - Can be either an object with `times` and `interval` or a number. + * `times` - The number of attempts to make before giving up. The default is `5`. + * `interval` - The time to wait between retries, in milliseconds. The default is `0`. + * If `opts` is a number, the number specifies the number of times to retry, with the default interval of `0`. +* `task(callback, results)` - A function which receives two arguments: (1) a `callback(err, result)` + which must be called when finished, passing `err` (which can be `null`) and the `result` of + the function's execution, and (2) a `results` object, containing the results of + the previously executed functions (if nested inside another control flow). +* `callback(err, results)` - An optional callback which is called when the + task has succeeded, or after the final failed attempt. It receives the `err` and `result` arguments of the last attempt at completing the `task`. + +The [`retry`](#retry) function can be used as a stand-alone control flow by passing a callback, as shown below: + +```js +// try calling apiMethod 3 times +async.retry(3, apiMethod, function(err, result) { + // do something with the result +}); +``` + +```js +// try calling apiMethod 3 times, waiting 200 ms between each retry +async.retry({times: 3, interval: 200}, apiMethod, function(err, result) { + // do something with the result +}); +``` + +```js +// try calling apiMethod the default 5 times no delay between each retry +async.retry(apiMethod, function(err, result) { + // do something with the result +}); +``` + +It can also be embedded within other control flow functions to retry individual methods +that are not as reliable, like this: + +```js +async.auto({ + users: api.getUsers.bind(api), + payments: async.retry(3, api.getPayments.bind(api)) +}, function(err, results) { + // do something with the results +}); +``` + + +--------------------------------------- + + +### iterator(tasks) + +Creates an iterator function which calls the next function in the `tasks` array, +returning a continuation to call the next one after that. It's also possible to +“peek” at the next iterator with `iterator.next()`. + +This function is used internally by the `async` module, but can be useful when +you want to manually control the flow of functions in series. + +__Arguments__ + +* `tasks` - An array of functions to run. + +__Example__ + +```js +var iterator = async.iterator([ + function(){ sys.p('one'); }, + function(){ sys.p('two'); }, + function(){ sys.p('three'); } +]); + +node> var iterator2 = iterator(); +'one' +node> var iterator3 = iterator2(); +'two' +node> iterator3(); +'three' +node> var nextfn = iterator2.next(); +node> nextfn(); +'three' +``` + +--------------------------------------- + + +### apply(function, arguments..) + +Creates a continuation function with some arguments already applied. + +Useful as a shorthand when combined with other control flow functions. Any arguments +passed to the returned function are added to the arguments originally passed +to apply. + +__Arguments__ + +* `function` - The function you want to eventually apply all arguments to. +* `arguments...` - Any number of arguments to automatically apply when the + continuation is called. + +__Example__ + +```js +// using apply + +async.parallel([ + async.apply(fs.writeFile, 'testfile1', 'test1'), + async.apply(fs.writeFile, 'testfile2', 'test2'), +]); + + +// the same process without using apply + +async.parallel([ + function(callback){ + fs.writeFile('testfile1', 'test1', callback); + }, + function(callback){ + fs.writeFile('testfile2', 'test2', callback); + } +]); +``` + +It's possible to pass any number of additional arguments when calling the +continuation: + +```js +node> var fn = async.apply(sys.puts, 'one'); +node> fn('two', 'three'); +one +two +three +``` + +--------------------------------------- + + +### nextTick(callback), setImmediate(callback) + +Calls `callback` on a later loop around the event loop. In Node.js this just +calls `process.nextTick`; in the browser it falls back to `setImmediate(callback)` +if available, otherwise `setTimeout(callback, 0)`, which means other higher priority +events may precede the execution of `callback`. + +This is used internally for browser-compatibility purposes. + +__Arguments__ + +* `callback` - The function to call on a later loop around the event loop. + +__Example__ + +```js +var call_order = []; +async.nextTick(function(){ + call_order.push('two'); + // call_order now equals ['one','two'] +}); +call_order.push('one') +``` + + +### times(n, iterator, [callback]) + +Calls the `iterator` function `n` times, and accumulates results in the same manner +you would use with [`map`](#map). + +__Arguments__ + +* `n` - The number of times to run the function. +* `iterator` - The function to call `n` times. +* `callback` - see [`map`](#map) + +__Example__ + +```js +// Pretend this is some complicated async factory +var createUser = function(id, callback) { + callback(null, { + id: 'user' + id + }) +} +// generate 5 users +async.times(5, function(n, next){ + createUser(n, function(err, user) { + next(err, user) + }) +}, function(err, users) { + // we should now have 5 users +}); +``` + +__Related__ + +* timesSeries(n, iterator, [callback]) +* timesLimit(n, limit, iterator, [callback]) + + +## Utils + + +### memoize(fn, [hasher]) + +Caches the results of an `async` function. When creating a hash to store function +results against, the callback is omitted from the hash and an optional hash +function can be used. + +If no hash function is specified, the first argument is used as a hash key, which may work reasonably if it is a string or a data type that converts to a distinct string. Note that objects and arrays will not behave reasonably. Neither will cases where the other arguments are significant. In such cases, specify your own hash function. + +The cache of results is exposed as the `memo` property of the function returned +by `memoize`. + +__Arguments__ + +* `fn` - The function to proxy and cache results from. +* `hasher` - An optional function for generating a custom hash for storing + results. It has all the arguments applied to it apart from the callback, and + must be synchronous. + +__Example__ + +```js +var slow_fn = function (name, callback) { + // do something + callback(null, result); +}; +var fn = async.memoize(slow_fn); + +// fn can now be used as if it were slow_fn +fn('some name', function () { + // callback +}); +``` + + +### unmemoize(fn) + +Undoes a [`memoize`](#memoize)d function, reverting it to the original, unmemoized +form. Handy for testing. + +__Arguments__ + +* `fn` - the memoized function + +--------------------------------------- + + +### ensureAsync(fn) + +Wrap an async function and ensure it calls its callback on a later tick of the event loop. If the function already calls its callback on a next tick, no extra deferral is added. This is useful for preventing stack overflows (`RangeError: Maximum call stack size exceeded`) and generally keeping [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony) contained. + +__Arguments__ + +* `fn` - an async function, one that expects a node-style callback as its last argument + +Returns a wrapped function with the exact same call signature as the function passed in. + +__Example__ + +```js +function sometimesAsync(arg, callback) { + if (cache[arg]) { + return callback(null, cache[arg]); // this would be synchronous!! + } else { + doSomeIO(arg, callback); // this IO would be asynchronous + } +} + +// this has a risk of stack overflows if many results are cached in a row +async.mapSeries(args, sometimesAsync, done); + +// this will defer sometimesAsync's callback if necessary, +// preventing stack overflows +async.mapSeries(args, async.ensureAsync(sometimesAsync), done); + +``` + +--------------------------------------- + + +### constant(values...) + +Returns a function that when called, calls-back with the values provided. Useful as the first function in a `waterfall`, or for plugging values in to `auto`. + +__Example__ + +```js +async.waterfall([ + async.constant(42), + function (value, next) { + // value === 42 + }, + //... +], callback); + +async.waterfall([ + async.constant(filename, "utf8"), + fs.readFile, + function (fileData, next) { + //... + } + //... +], callback); + +async.auto({ + hostname: async.constant("https://server.net/"), + port: findFreePort, + launchServer: ["hostname", "port", function (cb, options) { + startServer(options, cb); + }], + //... +}, callback); + +``` + +--------------------------------------- + + + +### asyncify(func) + +__Alias:__ `wrapSync` + +Take a sync function and make it async, passing its return value to a callback. This is useful for plugging sync functions into a waterfall, series, or other async functions. Any arguments passed to the generated function will be passed to the wrapped function (except for the final callback argument). Errors thrown will be passed to the callback. + +__Example__ + +```js +async.waterfall([ + async.apply(fs.readFile, filename, "utf8"), + async.asyncify(JSON.parse), + function (data, next) { + // data is the result of parsing the text. + // If there was a parsing error, it would have been caught. + } +], callback) +``` + +If the function passed to `asyncify` returns a Promise, that promises's resolved/rejected state will be used to call the callback, rather than simply the synchronous return value. Example: + +```js +async.waterfall([ + async.apply(fs.readFile, filename, "utf8"), + async.asyncify(function (contents) { + return db.model.create(contents); + }), + function (model, next) { + // `model` is the instantiated model object. + // If there was an error, this function would be skipped. + } +], callback) +``` + +This also means you can asyncify ES2016 `async` functions. + +```js +var q = async.queue(async.asyncify(async function (file) { + var intermediateStep = await processFile(file); + return await somePromise(intermediateStep) +})); + +q.push(files); +``` + +--------------------------------------- + + +### log(function, arguments) + +Logs the result of an `async` function to the `console`. Only works in Node.js or +in browsers that support `console.log` and `console.error` (such as FF and Chrome). +If multiple arguments are returned from the async function, `console.log` is +called on each argument in order. + +__Arguments__ + +* `function` - The function you want to eventually apply all arguments to. +* `arguments...` - Any number of arguments to apply to the function. + +__Example__ + +```js +var hello = function(name, callback){ + setTimeout(function(){ + callback(null, 'hello ' + name); + }, 1000); +}; +``` +```js +node> async.log(hello, 'world'); +'hello world' +``` + +--------------------------------------- + + +### dir(function, arguments) + +Logs the result of an `async` function to the `console` using `console.dir` to +display the properties of the resulting object. Only works in Node.js or +in browsers that support `console.dir` and `console.error` (such as FF and Chrome). +If multiple arguments are returned from the async function, `console.dir` is +called on each argument in order. + +__Arguments__ + +* `function` - The function you want to eventually apply all arguments to. +* `arguments...` - Any number of arguments to apply to the function. + +__Example__ + +```js +var hello = function(name, callback){ + setTimeout(function(){ + callback(null, {hello: name}); + }, 1000); +}; +``` +```js +node> async.dir(hello, 'world'); +{hello: 'world'} +``` + +--------------------------------------- + + +### noConflict() + +Changes the value of `async` back to its original value, returning a reference to the +`async` object. diff --git a/node_modules/grunt-contrib-clean/node_modules/async/dist/async.js b/node_modules/grunt-contrib-clean/node_modules/async/dist/async.js new file mode 100644 index 0000000..31e7620 --- /dev/null +++ b/node_modules/grunt-contrib-clean/node_modules/async/dist/async.js @@ -0,0 +1,1265 @@ +/*! + * async + * https://github.com/caolan/async + * + * Copyright 2010-2014 Caolan McMahon + * Released under the MIT license + */ +(function () { + + var async = {}; + function noop() {} + function identity(v) { + return v; + } + function toBool(v) { + return !!v; + } + function notId(v) { + return !v; + } + + // global on the server, window in the browser + var previous_async; + + // Establish the root object, `window` (`self`) in the browser, `global` + // on the server, or `this` in some virtual machines. We use `self` + // instead of `window` for `WebWorker` support. + var root = typeof self === 'object' && self.self === self && self || + typeof global === 'object' && global.global === global && global || + this; + + if (root != null) { + previous_async = root.async; + } + + async.noConflict = function () { + root.async = previous_async; + return async; + }; + + function only_once(fn) { + return function() { + if (fn === null) throw new Error("Callback was already called."); + fn.apply(this, arguments); + fn = null; + }; + } + + function _once(fn) { + return function() { + if (fn === null) return; + fn.apply(this, arguments); + fn = null; + }; + } + + //// cross-browser compatiblity functions //// + + var _toString = Object.prototype.toString; + + var _isArray = Array.isArray || function (obj) { + return _toString.call(obj) === '[object Array]'; + }; + + // Ported from underscore.js isObject + var _isObject = function(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + }; + + function _isArrayLike(arr) { + return _isArray(arr) || ( + // has a positive integer length property + typeof arr.length === "number" && + arr.length >= 0 && + arr.length % 1 === 0 + ); + } + + function _arrayEach(arr, iterator) { + var index = -1, + length = arr.length; + + while (++index < length) { + iterator(arr[index], index, arr); + } + } + + function _map(arr, iterator) { + var index = -1, + length = arr.length, + result = Array(length); + + while (++index < length) { + result[index] = iterator(arr[index], index, arr); + } + return result; + } + + function _range(count) { + return _map(Array(count), function (v, i) { return i; }); + } + + function _reduce(arr, iterator, memo) { + _arrayEach(arr, function (x, i, a) { + memo = iterator(memo, x, i, a); + }); + return memo; + } + + function _forEachOf(object, iterator) { + _arrayEach(_keys(object), function (key) { + iterator(object[key], key); + }); + } + + function _indexOf(arr, item) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] === item) return i; + } + return -1; + } + + var _keys = Object.keys || function (obj) { + var keys = []; + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + keys.push(k); + } + } + return keys; + }; + + function _keyIterator(coll) { + var i = -1; + var len; + var keys; + if (_isArrayLike(coll)) { + len = coll.length; + return function next() { + i++; + return i < len ? i : null; + }; + } else { + keys = _keys(coll); + len = keys.length; + return function next() { + i++; + return i < len ? keys[i] : null; + }; + } + } + + // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html) + // This accumulates the arguments passed into an array, after a given index. + // From underscore.js (https://github.com/jashkenas/underscore/pull/2140). + function _restParam(func, startIndex) { + startIndex = startIndex == null ? func.length - 1 : +startIndex; + return function() { + var length = Math.max(arguments.length - startIndex, 0); + var rest = Array(length); + for (var index = 0; index < length; index++) { + rest[index] = arguments[index + startIndex]; + } + switch (startIndex) { + case 0: return func.call(this, rest); + case 1: return func.call(this, arguments[0], rest); + } + // Currently unused but handle cases outside of the switch statement: + // var args = Array(startIndex + 1); + // for (index = 0; index < startIndex; index++) { + // args[index] = arguments[index]; + // } + // args[startIndex] = rest; + // return func.apply(this, args); + }; + } + + function _withoutIndex(iterator) { + return function (value, index, callback) { + return iterator(value, callback); + }; + } + + //// exported async module functions //// + + //// nextTick implementation with browser-compatible fallback //// + + // capture the global reference to guard against fakeTimer mocks + var _setImmediate = typeof setImmediate === 'function' && setImmediate; + + var _delay = _setImmediate ? function(fn) { + // not a direct alias for IE10 compatibility + _setImmediate(fn); + } : function(fn) { + setTimeout(fn, 0); + }; + + if (typeof process === 'object' && typeof process.nextTick === 'function') { + async.nextTick = process.nextTick; + } else { + async.nextTick = _delay; + } + async.setImmediate = _setImmediate ? _delay : async.nextTick; + + + async.forEach = + async.each = function (arr, iterator, callback) { + return async.eachOf(arr, _withoutIndex(iterator), callback); + }; + + async.forEachSeries = + async.eachSeries = function (arr, iterator, callback) { + return async.eachOfSeries(arr, _withoutIndex(iterator), callback); + }; + + + async.forEachLimit = + async.eachLimit = function (arr, limit, iterator, callback) { + return _eachOfLimit(limit)(arr, _withoutIndex(iterator), callback); + }; + + async.forEachOf = + async.eachOf = function (object, iterator, callback) { + callback = _once(callback || noop); + object = object || []; + + var iter = _keyIterator(object); + var key, completed = 0; + + while ((key = iter()) != null) { + completed += 1; + iterator(object[key], key, only_once(done)); + } + + if (completed === 0) callback(null); + + function done(err) { + completed--; + if (err) { + callback(err); + } + // Check key is null in case iterator isn't exhausted + // and done resolved synchronously. + else if (key === null && completed <= 0) { + callback(null); + } + } + }; + + async.forEachOfSeries = + async.eachOfSeries = function (obj, iterator, callback) { + callback = _once(callback || noop); + obj = obj || []; + var nextKey = _keyIterator(obj); + var key = nextKey(); + function iterate() { + var sync = true; + if (key === null) { + return callback(null); + } + iterator(obj[key], key, only_once(function (err) { + if (err) { + callback(err); + } + else { + key = nextKey(); + if (key === null) { + return callback(null); + } else { + if (sync) { + async.setImmediate(iterate); + } else { + iterate(); + } + } + } + })); + sync = false; + } + iterate(); + }; + + + + async.forEachOfLimit = + async.eachOfLimit = function (obj, limit, iterator, callback) { + _eachOfLimit(limit)(obj, iterator, callback); + }; + + function _eachOfLimit(limit) { + + return function (obj, iterator, callback) { + callback = _once(callback || noop); + obj = obj || []; + var nextKey = _keyIterator(obj); + if (limit <= 0) { + return callback(null); + } + var done = false; + var running = 0; + var errored = false; + + (function replenish () { + if (done && running <= 0) { + return callback(null); + } + + while (running < limit && !errored) { + var key = nextKey(); + if (key === null) { + done = true; + if (running <= 0) { + callback(null); + } + return; + } + running += 1; + iterator(obj[key], key, only_once(function (err) { + running -= 1; + if (err) { + callback(err); + errored = true; + } + else { + replenish(); + } + })); + } + })(); + }; + } + + + function doParallel(fn) { + return function (obj, iterator, callback) { + return fn(async.eachOf, obj, iterator, callback); + }; + } + function doParallelLimit(fn) { + return function (obj, limit, iterator, callback) { + return fn(_eachOfLimit(limit), obj, iterator, callback); + }; + } + function doSeries(fn) { + return function (obj, iterator, callback) { + return fn(async.eachOfSeries, obj, iterator, callback); + }; + } + + function _asyncMap(eachfn, arr, iterator, callback) { + callback = _once(callback || noop); + arr = arr || []; + var results = _isArrayLike(arr) ? [] : {}; + eachfn(arr, function (value, index, callback) { + iterator(value, function (err, v) { + results[index] = v; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + + async.map = doParallel(_asyncMap); + async.mapSeries = doSeries(_asyncMap); + async.mapLimit = doParallelLimit(_asyncMap); + + // reduce only has a series version, as doing reduce in parallel won't + // work in many situations. + async.inject = + async.foldl = + async.reduce = function (arr, memo, iterator, callback) { + async.eachOfSeries(arr, function (x, i, callback) { + iterator(memo, x, function (err, v) { + memo = v; + callback(err); + }); + }, function (err) { + callback(err, memo); + }); + }; + + async.foldr = + async.reduceRight = function (arr, memo, iterator, callback) { + var reversed = _map(arr, identity).reverse(); + async.reduce(reversed, memo, iterator, callback); + }; + + async.transform = function (arr, memo, iterator, callback) { + if (arguments.length === 3) { + callback = iterator; + iterator = memo; + memo = _isArray(arr) ? [] : {}; + } + + async.eachOf(arr, function(v, k, cb) { + iterator(memo, v, k, cb); + }, function(err) { + callback(err, memo); + }); + }; + + function _filter(eachfn, arr, iterator, callback) { + var results = []; + eachfn(arr, function (x, index, callback) { + iterator(x, function (v) { + if (v) { + results.push({index: index, value: x}); + } + callback(); + }); + }, function () { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + } + + async.select = + async.filter = doParallel(_filter); + + async.selectLimit = + async.filterLimit = doParallelLimit(_filter); + + async.selectSeries = + async.filterSeries = doSeries(_filter); + + function _reject(eachfn, arr, iterator, callback) { + _filter(eachfn, arr, function(value, cb) { + iterator(value, function(v) { + cb(!v); + }); + }, callback); + } + async.reject = doParallel(_reject); + async.rejectLimit = doParallelLimit(_reject); + async.rejectSeries = doSeries(_reject); + + function _createTester(eachfn, check, getResult) { + return function(arr, limit, iterator, cb) { + function done() { + if (cb) cb(getResult(false, void 0)); + } + function iteratee(x, _, callback) { + if (!cb) return callback(); + iterator(x, function (v) { + if (cb && check(v)) { + cb(getResult(true, x)); + cb = iterator = false; + } + callback(); + }); + } + if (arguments.length > 3) { + eachfn(arr, limit, iteratee, done); + } else { + cb = iterator; + iterator = limit; + eachfn(arr, iteratee, done); + } + }; + } + + async.any = + async.some = _createTester(async.eachOf, toBool, identity); + + async.someLimit = _createTester(async.eachOfLimit, toBool, identity); + + async.all = + async.every = _createTester(async.eachOf, notId, notId); + + async.everyLimit = _createTester(async.eachOfLimit, notId, notId); + + function _findGetResult(v, x) { + return x; + } + async.detect = _createTester(async.eachOf, identity, _findGetResult); + async.detectSeries = _createTester(async.eachOfSeries, identity, _findGetResult); + async.detectLimit = _createTester(async.eachOfLimit, identity, _findGetResult); + + async.sortBy = function (arr, iterator, callback) { + async.map(arr, function (x, callback) { + iterator(x, function (err, criteria) { + if (err) { + callback(err); + } + else { + callback(null, {value: x, criteria: criteria}); + } + }); + }, function (err, results) { + if (err) { + return callback(err); + } + else { + callback(null, _map(results.sort(comparator), function (x) { + return x.value; + })); + } + + }); + + function comparator(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + } + }; + + async.auto = function (tasks, concurrency, callback) { + if (typeof arguments[1] === 'function') { + // concurrency is optional, shift the args. + callback = concurrency; + concurrency = null; + } + callback = _once(callback || noop); + var keys = _keys(tasks); + var remainingTasks = keys.length; + if (!remainingTasks) { + return callback(null); + } + if (!concurrency) { + concurrency = remainingTasks; + } + + var results = {}; + var runningTasks = 0; + + var hasError = false; + + var listeners = []; + function addListener(fn) { + listeners.unshift(fn); + } + function removeListener(fn) { + var idx = _indexOf(listeners, fn); + if (idx >= 0) listeners.splice(idx, 1); + } + function taskComplete() { + remainingTasks--; + _arrayEach(listeners.slice(0), function (fn) { + fn(); + }); + } + + addListener(function () { + if (!remainingTasks) { + callback(null, results); + } + }); + + _arrayEach(keys, function (k) { + if (hasError) return; + var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]]; + var taskCallback = _restParam(function(err, args) { + runningTasks--; + if (args.length <= 1) { + args = args[0]; + } + if (err) { + var safeResults = {}; + _forEachOf(results, function(val, rkey) { + safeResults[rkey] = val; + }); + safeResults[k] = args; + hasError = true; + + callback(err, safeResults); + } + else { + results[k] = args; + async.setImmediate(taskComplete); + } + }); + var requires = task.slice(0, task.length - 1); + // prevent dead-locks + var len = requires.length; + var dep; + while (len--) { + if (!(dep = tasks[requires[len]])) { + throw new Error('Has nonexistent dependency in ' + requires.join(', ')); + } + if (_isArray(dep) && _indexOf(dep, k) >= 0) { + throw new Error('Has cyclic dependencies'); + } + } + function ready() { + return runningTasks < concurrency && _reduce(requires, function (a, x) { + return (a && results.hasOwnProperty(x)); + }, true) && !results.hasOwnProperty(k); + } + if (ready()) { + runningTasks++; + task[task.length - 1](taskCallback, results); + } + else { + addListener(listener); + } + function listener() { + if (ready()) { + runningTasks++; + removeListener(listener); + task[task.length - 1](taskCallback, results); + } + } + }); + }; + + + + async.retry = function(times, task, callback) { + var DEFAULT_TIMES = 5; + var DEFAULT_INTERVAL = 0; + + var attempts = []; + + var opts = { + times: DEFAULT_TIMES, + interval: DEFAULT_INTERVAL + }; + + function parseTimes(acc, t){ + if(typeof t === 'number'){ + acc.times = parseInt(t, 10) || DEFAULT_TIMES; + } else if(typeof t === 'object'){ + acc.times = parseInt(t.times, 10) || DEFAULT_TIMES; + acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL; + } else { + throw new Error('Unsupported argument type for \'times\': ' + typeof t); + } + } + + var length = arguments.length; + if (length < 1 || length > 3) { + throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)'); + } else if (length <= 2 && typeof times === 'function') { + callback = task; + task = times; + } + if (typeof times !== 'function') { + parseTimes(opts, times); + } + opts.callback = callback; + opts.task = task; + + function wrappedTask(wrappedCallback, wrappedResults) { + function retryAttempt(task, finalAttempt) { + return function(seriesCallback) { + task(function(err, result){ + seriesCallback(!err || finalAttempt, {err: err, result: result}); + }, wrappedResults); + }; + } + + function retryInterval(interval){ + return function(seriesCallback){ + setTimeout(function(){ + seriesCallback(null); + }, interval); + }; + } + + while (opts.times) { + + var finalAttempt = !(opts.times-=1); + attempts.push(retryAttempt(opts.task, finalAttempt)); + if(!finalAttempt && opts.interval > 0){ + attempts.push(retryInterval(opts.interval)); + } + } + + async.series(attempts, function(done, data){ + data = data[data.length - 1]; + (wrappedCallback || opts.callback)(data.err, data.result); + }); + } + + // If a callback is passed, run this as a controll flow + return opts.callback ? wrappedTask() : wrappedTask; + }; + + async.waterfall = function (tasks, callback) { + callback = _once(callback || noop); + if (!_isArray(tasks)) { + var err = new Error('First argument to waterfall must be an array of functions'); + return callback(err); + } + if (!tasks.length) { + return callback(); + } + function wrapIterator(iterator) { + return _restParam(function (err, args) { + if (err) { + callback.apply(null, [err].concat(args)); + } + else { + var next = iterator.next(); + if (next) { + args.push(wrapIterator(next)); + } + else { + args.push(callback); + } + ensureAsync(iterator).apply(null, args); + } + }); + } + wrapIterator(async.iterator(tasks))(); + }; + + function _parallel(eachfn, tasks, callback) { + callback = callback || noop; + var results = _isArrayLike(tasks) ? [] : {}; + + eachfn(tasks, function (task, key, callback) { + task(_restParam(function (err, args) { + if (args.length <= 1) { + args = args[0]; + } + results[key] = args; + callback(err); + })); + }, function (err) { + callback(err, results); + }); + } + + async.parallel = function (tasks, callback) { + _parallel(async.eachOf, tasks, callback); + }; + + async.parallelLimit = function(tasks, limit, callback) { + _parallel(_eachOfLimit(limit), tasks, callback); + }; + + async.series = function(tasks, callback) { + _parallel(async.eachOfSeries, tasks, callback); + }; + + async.iterator = function (tasks) { + function makeCallback(index) { + function fn() { + if (tasks.length) { + tasks[index].apply(null, arguments); + } + return fn.next(); + } + fn.next = function () { + return (index < tasks.length - 1) ? makeCallback(index + 1): null; + }; + return fn; + } + return makeCallback(0); + }; + + async.apply = _restParam(function (fn, args) { + return _restParam(function (callArgs) { + return fn.apply( + null, args.concat(callArgs) + ); + }); + }); + + function _concat(eachfn, arr, fn, callback) { + var result = []; + eachfn(arr, function (x, index, cb) { + fn(x, function (err, y) { + result = result.concat(y || []); + cb(err); + }); + }, function (err) { + callback(err, result); + }); + } + async.concat = doParallel(_concat); + async.concatSeries = doSeries(_concat); + + async.whilst = function (test, iterator, callback) { + callback = callback || noop; + if (test()) { + var next = _restParam(function(err, args) { + if (err) { + callback(err); + } else if (test.apply(this, args)) { + iterator(next); + } else { + callback.apply(null, [null].concat(args)); + } + }); + iterator(next); + } else { + callback(null); + } + }; + + async.doWhilst = function (iterator, test, callback) { + var calls = 0; + return async.whilst(function() { + return ++calls <= 1 || test.apply(this, arguments); + }, iterator, callback); + }; + + async.until = function (test, iterator, callback) { + return async.whilst(function() { + return !test.apply(this, arguments); + }, iterator, callback); + }; + + async.doUntil = function (iterator, test, callback) { + return async.doWhilst(iterator, function() { + return !test.apply(this, arguments); + }, callback); + }; + + async.during = function (test, iterator, callback) { + callback = callback || noop; + + var next = _restParam(function(err, args) { + if (err) { + callback(err); + } else { + args.push(check); + test.apply(this, args); + } + }); + + var check = function(err, truth) { + if (err) { + callback(err); + } else if (truth) { + iterator(next); + } else { + callback(null); + } + }; + + test(check); + }; + + async.doDuring = function (iterator, test, callback) { + var calls = 0; + async.during(function(next) { + if (calls++ < 1) { + next(null, true); + } else { + test.apply(this, arguments); + } + }, iterator, callback); + }; + + function _queue(worker, concurrency, payload) { + if (concurrency == null) { + concurrency = 1; + } + else if(concurrency === 0) { + throw new Error('Concurrency must not be zero'); + } + function _insert(q, data, pos, callback) { + if (callback != null && typeof callback !== "function") { + throw new Error("task callback must be a function"); + } + q.started = true; + if (!_isArray(data)) { + data = [data]; + } + if(data.length === 0 && q.idle()) { + // call drain immediately if there are no tasks + return async.setImmediate(function() { + q.drain(); + }); + } + _arrayEach(data, function(task) { + var item = { + data: task, + callback: callback || noop + }; + + if (pos) { + q.tasks.unshift(item); + } else { + q.tasks.push(item); + } + + if (q.tasks.length === q.concurrency) { + q.saturated(); + } + }); + async.setImmediate(q.process); + } + function _next(q, tasks) { + return function(){ + workers -= 1; + + var removed = false; + var args = arguments; + _arrayEach(tasks, function (task) { + _arrayEach(workersList, function (worker, index) { + if (worker === task && !removed) { + workersList.splice(index, 1); + removed = true; + } + }); + + task.callback.apply(task, args); + }); + if (q.tasks.length + workers === 0) { + q.drain(); + } + q.process(); + }; + } + + var workers = 0; + var workersList = []; + var q = { + tasks: [], + concurrency: concurrency, + payload: payload, + saturated: noop, + empty: noop, + drain: noop, + started: false, + paused: false, + push: function (data, callback) { + _insert(q, data, false, callback); + }, + kill: function () { + q.drain = noop; + q.tasks = []; + }, + unshift: function (data, callback) { + _insert(q, data, true, callback); + }, + process: function () { + while(!q.paused && workers < q.concurrency && q.tasks.length){ + + var tasks = q.payload ? + q.tasks.splice(0, q.payload) : + q.tasks.splice(0, q.tasks.length); + + var data = _map(tasks, function (task) { + return task.data; + }); + + if (q.tasks.length === 0) { + q.empty(); + } + workers += 1; + workersList.push(tasks[0]); + var cb = only_once(_next(q, tasks)); + worker(data, cb); + } + }, + length: function () { + return q.tasks.length; + }, + running: function () { + return workers; + }, + workersList: function () { + return workersList; + }, + idle: function() { + return q.tasks.length + workers === 0; + }, + pause: function () { + q.paused = true; + }, + resume: function () { + if (q.paused === false) { return; } + q.paused = false; + var resumeCount = Math.min(q.concurrency, q.tasks.length); + // Need to call q.process once per concurrent + // worker to preserve full concurrency after pause + for (var w = 1; w <= resumeCount; w++) { + async.setImmediate(q.process); + } + } + }; + return q; + } + + async.queue = function (worker, concurrency) { + var q = _queue(function (items, cb) { + worker(items[0], cb); + }, concurrency, 1); + + return q; + }; + + async.priorityQueue = function (worker, concurrency) { + + function _compareTasks(a, b){ + return a.priority - b.priority; + } + + function _binarySearch(sequence, item, compare) { + var beg = -1, + end = sequence.length - 1; + while (beg < end) { + var mid = beg + ((end - beg + 1) >>> 1); + if (compare(item, sequence[mid]) >= 0) { + beg = mid; + } else { + end = mid - 1; + } + } + return beg; + } + + function _insert(q, data, priority, callback) { + if (callback != null && typeof callback !== "function") { + throw new Error("task callback must be a function"); + } + q.started = true; + if (!_isArray(data)) { + data = [data]; + } + if(data.length === 0) { + // call drain immediately if there are no tasks + return async.setImmediate(function() { + q.drain(); + }); + } + _arrayEach(data, function(task) { + var item = { + data: task, + priority: priority, + callback: typeof callback === 'function' ? callback : noop + }; + + q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item); + + if (q.tasks.length === q.concurrency) { + q.saturated(); + } + async.setImmediate(q.process); + }); + } + + // Start with a normal queue + var q = async.queue(worker, concurrency); + + // Override push to accept second parameter representing priority + q.push = function (data, priority, callback) { + _insert(q, data, priority, callback); + }; + + // Remove unshift function + delete q.unshift; + + return q; + }; + + async.cargo = function (worker, payload) { + return _queue(worker, 1, payload); + }; + + function _console_fn(name) { + return _restParam(function (fn, args) { + fn.apply(null, args.concat([_restParam(function (err, args) { + if (typeof console === 'object') { + if (err) { + if (console.error) { + console.error(err); + } + } + else if (console[name]) { + _arrayEach(args, function (x) { + console[name](x); + }); + } + } + })])); + }); + } + async.log = _console_fn('log'); + async.dir = _console_fn('dir'); + /*async.info = _console_fn('info'); + async.warn = _console_fn('warn'); + async.error = _console_fn('error');*/ + + async.memoize = function (fn, hasher) { + var memo = {}; + var queues = {}; + var has = Object.prototype.hasOwnProperty; + hasher = hasher || identity; + var memoized = _restParam(function memoized(args) { + var callback = args.pop(); + var key = hasher.apply(null, args); + if (has.call(memo, key)) { + async.setImmediate(function () { + callback.apply(null, memo[key]); + }); + } + else if (has.call(queues, key)) { + queues[key].push(callback); + } + else { + queues[key] = [callback]; + fn.apply(null, args.concat([_restParam(function (args) { + memo[key] = args; + var q = queues[key]; + delete queues[key]; + for (var i = 0, l = q.length; i < l; i++) { + q[i].apply(null, args); + } + })])); + } + }); + memoized.memo = memo; + memoized.unmemoized = fn; + return memoized; + }; + + async.unmemoize = function (fn) { + return function () { + return (fn.unmemoized || fn).apply(null, arguments); + }; + }; + + function _times(mapper) { + return function (count, iterator, callback) { + mapper(_range(count), iterator, callback); + }; + } + + async.times = _times(async.map); + async.timesSeries = _times(async.mapSeries); + async.timesLimit = function (count, limit, iterator, callback) { + return async.mapLimit(_range(count), limit, iterator, callback); + }; + + async.seq = function (/* functions... */) { + var fns = arguments; + return _restParam(function (args) { + var that = this; + + var callback = args[args.length - 1]; + if (typeof callback == 'function') { + args.pop(); + } else { + callback = noop; + } + + async.reduce(fns, args, function (newargs, fn, cb) { + fn.apply(that, newargs.concat([_restParam(function (err, nextargs) { + cb(err, nextargs); + })])); + }, + function (err, results) { + callback.apply(that, [err].concat(results)); + }); + }); + }; + + async.compose = function (/* functions... */) { + return async.seq.apply(null, Array.prototype.reverse.call(arguments)); + }; + + + function _applyEach(eachfn) { + return _restParam(function(fns, args) { + var go = _restParam(function(args) { + var that = this; + var callback = args.pop(); + return eachfn(fns, function (fn, _, cb) { + fn.apply(that, args.concat([cb])); + }, + callback); + }); + if (args.length) { + return go.apply(this, args); + } + else { + return go; + } + }); + } + + async.applyEach = _applyEach(async.eachOf); + async.applyEachSeries = _applyEach(async.eachOfSeries); + + + async.forever = function (fn, callback) { + var done = only_once(callback || noop); + var task = ensureAsync(fn); + function next(err) { + if (err) { + return done(err); + } + task(next); + } + next(); + }; + + function ensureAsync(fn) { + return _restParam(function (args) { + var callback = args.pop(); + args.push(function () { + var innerArgs = arguments; + if (sync) { + async.setImmediate(function () { + callback.apply(null, innerArgs); + }); + } else { + callback.apply(null, innerArgs); + } + }); + var sync = true; + fn.apply(this, args); + sync = false; + }); + } + + async.ensureAsync = ensureAsync; + + async.constant = _restParam(function(values) { + var args = [null].concat(values); + return function (callback) { + return callback.apply(this, args); + }; + }); + + async.wrapSync = + async.asyncify = function asyncify(func) { + return _restParam(function (args) { + var callback = args.pop(); + var result; + try { + result = func.apply(this, args); + } catch (e) { + return callback(e); + } + // if result is Promise object + if (_isObject(result) && typeof result.then === "function") { + result.then(function(value) { + callback(null, value); + })["catch"](function(err) { + callback(err.message ? err : new Error(err)); + }); + } else { + callback(null, result); + } + }); + }; + + // Node.js + if (typeof module === 'object' && module.exports) { + module.exports = async; + } + // AMD / RequireJS + else if (typeof define === 'function' && define.amd) { + define([], function () { + return async; + }); + } + // included directly via +``` + +Using [`npm`](http://npmjs.org/): + +```bash +npm i --save lodash + +{sudo} npm i -g lodash +npm ln lodash +``` + +In [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/): + +```js +var _ = require('lodash'); +// or as Underscore +var _ = require('lodash/dist/lodash.underscore'); +``` + +**Notes:** + * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL + * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it + +In [Rhino](http://www.mozilla.org/rhino/): + +```js +load('lodash.js'); +``` + +In an AMD loader: + +```js +require({ + 'packages': [ + { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' } + ] +}, +['lodash'], function(_) { + console.log(_.VERSION); +}); +``` + +## Resources + + * Podcasts + - [JavaScript Jabber](http://javascriptjabber.com/079-jsj-lo-dash-with-john-david-dalton/) + + * Posts + - [Say “Hello” to Lo-Dash](http://kitcambridge.be/blog/say-hello-to-lo-dash/) + - [Custom builds in Lo-Dash 2.0](http://kitcambridge.be/blog/custom-builds-in-lo-dash-2-dot-0/) + + * Videos + - [Introduction](https://vimeo.com/44154599) + - [Origins](https://vimeo.com/44154600) + - [Optimizations & builds](https://vimeo.com/44154601) + - [Native method use](https://vimeo.com/48576012) + - [Testing](https://vimeo.com/45865290) + - [CascadiaJS ’12](http://www.youtube.com/watch?v=dpPy4f_SeEk) + + A list of other community created podcasts, posts, & videos is available on our [wiki](https://github.com/lodash/lodash/wiki/Resources). + +## Features + + * AMD loader support ([curl](https://github.com/cujojs/curl), [dojo](http://dojotoolkit.org/), [requirejs](http://requirejs.org/), etc.) + * [_(…)](https://lodash.com/docs#_) supports intuitive chaining + * [_.at](https://lodash.com/docs#at) for cherry-picking collection values + * [_.bindKey](https://lodash.com/docs#bindKey) for binding [*“lazy”*](http://michaux.ca/articles/lazy-function-definition-pattern) defined methods + * [_.clone](https://lodash.com/docs#clone) supports shallow cloning of `Date` & `RegExp` objects + * [_.cloneDeep](https://lodash.com/docs#cloneDeep) for deep cloning arrays & objects + * [_.constant](https://lodash.com/docs#constant) & [_.property](https://lodash.com/docs#property) function generators for composing functions + * [_.contains](https://lodash.com/docs#contains) accepts a `fromIndex` + * [_.create](https://lodash.com/docs#create) for easier object inheritance + * [_.createCallback](https://lodash.com/docs#createCallback) for extending callbacks in methods & mixins + * [_.curry](https://lodash.com/docs#curry) for creating [curried](http://hughfdjackson.com/javascript/2013/07/06/why-curry-helps/) functions + * [_.debounce](https://lodash.com/docs#debounce) & [_.throttle](https://lodash.com/docs#throttle) accept additional `options` for more control + * [_.findIndex](https://lodash.com/docs#findIndex) & [_.findKey](https://lodash.com/docs#findKey) for finding indexes & keys + * [_.forEach](https://lodash.com/docs#forEach) is chainable & supports exiting early + * [_.forIn](https://lodash.com/docs#forIn) for iterating own & inherited properties + * [_.forOwn](https://lodash.com/docs#forOwn) for iterating own properties + * [_.isPlainObject](https://lodash.com/docs#isPlainObject) for checking if values are created by `Object` + * [_.mapValues](https://lodash.com/docs#mapValues) for [mapping](https://lodash.com/docs#map) values to an object + * [_.memoize](https://lodash.com/docs#memoize) exposes the `cache` of memoized functions + * [_.merge](https://lodash.com/docs#merge) for a deep [_.extend](https://lodash.com/docs#extend) + * [_.noop](https://lodash.com/docs#noop) for function placeholders + * [_.now](https://lodash.com/docs#now) as a cross-browser `Date.now` alternative + * [_.parseInt](https://lodash.com/docs#parseInt) for consistent behavior + * [_.pull](https://lodash.com/docs#pull) & [_.remove](https://lodash.com/docs#remove) for mutating arrays + * [_.random](https://lodash.com/docs#random) supports returning floating-point numbers + * [_.runInContext](https://lodash.com/docs#runInContext) for easier mocking + * [_.sortBy](https://lodash.com/docs#sortBy) supports sorting by multiple properties + * [_.support](https://lodash.com/docs#support) for flagging environment features + * [_.template](https://lodash.com/docs#template) supports [*“imports”*](https://lodash.com/docs#templateSettings_imports) options & [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals) + * [_.transform](https://lodash.com/docs#transform) as a powerful alternative to [_.reduce](https://lodash.com/docs#reduce) for transforming objects + * [_.where](https://lodash.com/docs#where) supports deep object comparisons + * [_.xor](https://lodash.com/docs#xor) as a companion to [_.difference](https://lodash.com/docs#difference), [_.intersection](https://lodash.com/docs#intersection), & [_.union](https://lodash.com/docs#union) + * [_.zip](https://lodash.com/docs#zip) is capable of unzipping values + * [_.omit](https://lodash.com/docs#omit), [_.pick](https://lodash.com/docs#pick), & + [more](https://lodash.com/docs "_.assign, _.clone, _.cloneDeep, _.first, _.initial, _.isEqual, _.last, _.merge, _.rest") accept callbacks + * [_.contains](https://lodash.com/docs#contains), [_.toArray](https://lodash.com/docs#toArray), & + [more](https://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.forEach, _.forEachRight, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.size, _.some, _.sortBy, _.where") accept strings + * [_.filter](https://lodash.com/docs#filter), [_.map](https://lodash.com/docs#map), & + [more](https://lodash.com/docs "_.countBy, _.every, _.find, _.findKey, _.findLast, _.findLastIndex, _.findLastKey, _.first, _.groupBy, _.initial, _.last, _.max, _.min, _.reject, _.rest, _.some, _.sortBy, _.sortedIndex, _.uniq") support *“_.pluck”* & *“_.where”* shorthands + * [_.findLast](https://lodash.com/docs#findLast), [_.findLastIndex](https://lodash.com/docs#findLastIndex), & + [more](https://lodash.com/docs "_.findLastKey, _.forEachRight, _.forInRight, _.forOwnRight, _.partialRight") right-associative methods + +## Support + +Tested in Chrome 5~31, Firefox 2~25, IE 6-11, Opera 9.25-17, Safari 3-7, Node.js 0.6.21-0.10.22, Narwhal 0.3.2, PhantomJS 1.9.2, RingoJS 0.9, & Rhino 1.7RC5. diff --git a/node_modules/grunt-contrib-jst/node_modules/lodash/dist/lodash.compat.js b/node_modules/grunt-contrib-jst/node_modules/lodash/dist/lodash.compat.js new file mode 100644 index 0000000..4d35185 --- /dev/null +++ b/node_modules/grunt-contrib-jst/node_modules/lodash/dist/lodash.compat.js @@ -0,0 +1,7158 @@ +/** + * @license + * Lo-Dash 2.4.2 (Custom Build) + * Build: `lodash -o ./dist/lodash.compat.js` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre ES5 environments */ + var undefined; + + /** Used to pool arrays and objects used internally */ + var arrayPool = [], + objectPool = []; + + /** Used to generate unique IDs */ + var idCounter = 0; + + /** Used internally to indicate various things */ + var indicatorObject = {}; + + /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */ + var keyPrefix = +new Date + ''; + + /** Used as the size when optimizations are enabled for large arrays */ + var largeArraySize = 75; + + /** Used as the max size of the `arrayPool` and `objectPool` */ + var maxPoolSize = 40; + + /** Used to detect and test whitespace */ + var whitespace = ( + // whitespace + ' \t\x0B\f\xA0\ufeff' + + + // line terminators + '\n\r\u2028\u2029' + + + // unicode category "Zs" space separators + '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' + ); + + /** Used to match empty string literals in compiled template source */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** + * Used to match ES6 template delimiters + * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals + */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match regexp flags from their coerced string values */ + var reFlags = /\w*$/; + + /** Used to detected named functions */ + var reFuncName = /^\s*function[ \n\r\t]+\w/; + + /** Used to match "interpolate" template delimiters */ + var reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match leading whitespace and zeros to be removed */ + var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)'); + + /** Used to ensure capturing order of template delimiters */ + var reNoMatch = /($^)/; + + /** Used to detect functions containing a `this` reference */ + var reThis = /\bthis\b/; + + /** Used to match unescaped characters in compiled string literals */ + var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; + + /** Used to assign default `context` object properties */ + var contextProps = [ + 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object', + 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', + 'parseInt', 'setTimeout' + ]; + + /** Used to fix the JScript [[DontEnum]] bug */ + var shadowedProps = [ + 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', + 'toLocaleString', 'toString', 'valueOf' + ]; + + /** Used to make template sourceURLs easier to identify */ + var templateCounter = 0; + + /** `Object#toString` result shortcuts */ + var argsClass = '[object Arguments]', + arrayClass = '[object Array]', + boolClass = '[object Boolean]', + dateClass = '[object Date]', + errorClass = '[object Error]', + funcClass = '[object Function]', + numberClass = '[object Number]', + objectClass = '[object Object]', + regexpClass = '[object RegExp]', + stringClass = '[object String]'; + + /** Used to identify object classifications that `_.clone` supports */ + var cloneableClasses = {}; + cloneableClasses[funcClass] = false; + cloneableClasses[argsClass] = cloneableClasses[arrayClass] = + cloneableClasses[boolClass] = cloneableClasses[dateClass] = + cloneableClasses[numberClass] = cloneableClasses[objectClass] = + cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; + + /** Used as an internal `_.debounce` options object */ + var debounceOptions = { + 'leading': false, + 'maxWait': 0, + 'trailing': false + }; + + /** Used as the property descriptor for `__bindData__` */ + var descriptor = { + 'configurable': false, + 'enumerable': false, + 'value': null, + 'writable': false + }; + + /** Used as the data object for `iteratorTemplate` */ + var iteratorData = { + 'args': '', + 'array': null, + 'bottom': '', + 'firstArg': '', + 'init': '', + 'keys': null, + 'loop': '', + 'shadowedProps': null, + 'support': null, + 'top': '', + 'useHas': false + }; + + /** Used to determine if values are of the language type Object */ + var objectTypes = { + 'boolean': false, + 'function': true, + 'object': true, + 'number': false, + 'string': false, + 'undefined': false + }; + + /** Used to escape characters for inclusion in compiled string literals */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\t': 't', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Used as a reference to the global object */ + var root = (objectTypes[typeof window] && window) || this; + + /** Detect free variable `exports` */ + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + + /** Detect free variable `module` */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports` */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + + /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ + var freeGlobal = objectTypes[typeof global] && global; + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { + root = freeGlobal; + } + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.indexOf` without support for binary searches + * or `fromIndex` constraints. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * An implementation of `_.contains` for cache objects that mimics the return + * signature of `_.indexOf` by returning `0` if the value is found, else `-1`. + * + * @private + * @param {Object} cache The cache object to inspect. + * @param {*} value The value to search for. + * @returns {number} Returns `0` if `value` is found, else `-1`. + */ + function cacheIndexOf(cache, value) { + var type = typeof value; + cache = cache.cache; + + if (type == 'boolean' || value == null) { + return cache[value] ? 0 : -1; + } + if (type != 'number' && type != 'string') { + type = 'object'; + } + var key = type == 'number' ? value : keyPrefix + value; + cache = (cache = cache[type]) && cache[key]; + + return type == 'object' + ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1) + : (cache ? 0 : -1); + } + + /** + * Adds a given value to the corresponding cache object. + * + * @private + * @param {*} value The value to add to the cache. + */ + function cachePush(value) { + var cache = this.cache, + type = typeof value; + + if (type == 'boolean' || value == null) { + cache[value] = true; + } else { + if (type != 'number' && type != 'string') { + type = 'object'; + } + var key = type == 'number' ? value : keyPrefix + value, + typeCache = cache[type] || (cache[type] = {}); + + if (type == 'object') { + (typeCache[key] || (typeCache[key] = [])).push(value); + } else { + typeCache[key] = true; + } + } + } + + /** + * Used by `_.max` and `_.min` as the default callback when a given + * collection is a string value. + * + * @private + * @param {string} value The character to inspect. + * @returns {number} Returns the code unit of given character. + */ + function charAtCallback(value) { + return value.charCodeAt(0); + } + + /** + * Used by `sortBy` to compare transformed `collection` elements, stable sorting + * them in ascending order. + * + * @private + * @param {Object} a The object to compare to `b`. + * @param {Object} b The object to compare to `a`. + * @returns {number} Returns the sort order indicator of `1` or `-1`. + */ + function compareAscending(a, b) { + var ac = a.criteria, + bc = b.criteria, + index = -1, + length = ac.length; + + while (++index < length) { + var value = ac[index], + other = bc[index]; + + if (value !== other) { + if (value > other || typeof value == 'undefined') { + return 1; + } + if (value < other || typeof other == 'undefined') { + return -1; + } + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to return the same value for + // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247 + // + // This also ensures a stable sort in V8 and other engines. + // See http://code.google.com/p/v8/issues/detail?id=90 + return a.index - b.index; + } + + /** + * Creates a cache object to optimize linear searches of large arrays. + * + * @private + * @param {Array} [array=[]] The array to search. + * @returns {null|Object} Returns the cache object or `null` if caching should not be used. + */ + function createCache(array) { + var index = -1, + length = array.length, + first = array[0], + mid = array[(length / 2) | 0], + last = array[length - 1]; + + if (first && typeof first == 'object' && + mid && typeof mid == 'object' && last && typeof last == 'object') { + return false; + } + var cache = getObject(); + cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false; + + var result = getObject(); + result.array = array; + result.cache = cache; + result.push = cachePush; + + while (++index < length) { + result.push(array[index]); + } + return result; + } + + /** + * Used by `template` to escape characters for inclusion in compiled + * string literals. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(match) { + return '\\' + stringEscapes[match]; + } + + /** + * Gets an array from the array pool or creates a new one if the pool is empty. + * + * @private + * @returns {Array} The array from the pool. + */ + function getArray() { + return arrayPool.pop() || []; + } + + /** + * Gets an object from the object pool or creates a new one if the pool is empty. + * + * @private + * @returns {Object} The object from the pool. + */ + function getObject() { + return objectPool.pop() || { + 'array': null, + 'cache': null, + 'criteria': null, + 'false': false, + 'index': 0, + 'null': false, + 'number': null, + 'object': null, + 'push': null, + 'string': null, + 'true': false, + 'undefined': false, + 'value': null + }; + } + + /** + * Checks if `value` is a DOM node in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`. + */ + function isNode(value) { + // IE < 9 presents DOM nodes as `Object` objects except they have `toString` + // methods that are `typeof` "string" and still can coerce nodes to strings + return typeof value.toString != 'function' && typeof (value + '') == 'string'; + } + + /** + * Releases the given array back to the array pool. + * + * @private + * @param {Array} [array] The array to release. + */ + function releaseArray(array) { + array.length = 0; + if (arrayPool.length < maxPoolSize) { + arrayPool.push(array); + } + } + + /** + * Releases the given object back to the object pool. + * + * @private + * @param {Object} [object] The object to release. + */ + function releaseObject(object) { + var cache = object.cache; + if (cache) { + releaseObject(cache); + } + object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null; + if (objectPool.length < maxPoolSize) { + objectPool.push(object); + } + } + + /** + * Slices the `collection` from the `start` index up to, but not including, + * the `end` index. + * + * Note: This function is used instead of `Array#slice` to support node lists + * in IE < 9 and to ensure dense arrays are returned. + * + * @private + * @param {Array|Object|string} collection The collection to slice. + * @param {number} start The start index. + * @param {number} end The end index. + * @returns {Array} Returns the new array. + */ + function slice(array, start, end) { + start || (start = 0); + if (typeof end == 'undefined') { + end = array ? array.length : 0; + } + var index = -1, + length = end - start || 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = array[start + index]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new `lodash` function using the given context object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} [context=root] The context object. + * @returns {Function} Returns the `lodash` function. + */ + function runInContext(context) { + // Avoid issues with some ES3 environments that attempt to use values, named + // after built-in constructors like `Object`, for the creation of literals. + // ES5 clears this up by stating that literals must use built-in constructors. + // See http://es5.github.io/#x11.1.5. + context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; + + /** Native constructor references */ + var Array = context.Array, + Boolean = context.Boolean, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Number = context.Number, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** + * Used for `Array` method references. + * + * Normally `Array.prototype` would suffice, however, using an array literal + * avoids issues in Narwhal. + */ + var arrayRef = []; + + /** Used for native method references */ + var errorProto = Error.prototype, + objectProto = Object.prototype, + stringProto = String.prototype; + + /** Used to restore the original `_` reference in `noConflict` */ + var oldDash = context._; + + /** Used to resolve the internal [[Class]] of values */ + var toString = objectProto.toString; + + /** Used to detect if a method is native */ + var reNative = RegExp('^' + + String(toString) + .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + .replace(/toString| for [^\]]+/g, '.*?') + '$' + ); + + /** Native method shortcuts */ + var ceil = Math.ceil, + clearTimeout = context.clearTimeout, + floor = Math.floor, + fnToString = Function.prototype.toString, + getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, + hasOwnProperty = objectProto.hasOwnProperty, + push = arrayRef.push, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + setTimeout = context.setTimeout, + splice = arrayRef.splice, + unshift = arrayRef.unshift; + + /** Used to set meta data on functions */ + var defineProperty = (function() { + // IE 8 only accepts DOM elements + try { + var o = {}, + func = isNative(func = Object.defineProperty) && func, + result = func(o, o, o) && func; + } catch(e) { } + return result; + }()); + + /* Native method shortcuts for methods with the same name as other `lodash` methods */ + var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, + nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, + nativeIsFinite = context.isFinite, + nativeIsNaN = context.isNaN, + nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, + nativeMax = Math.max, + nativeMin = Math.min, + nativeParseInt = context.parseInt, + nativeRandom = Math.random; + + /** Used to lookup a built-in constructor by [[Class]] */ + var ctorByClass = {}; + ctorByClass[arrayClass] = Array; + ctorByClass[boolClass] = Boolean; + ctorByClass[dateClass] = Date; + ctorByClass[funcClass] = Function; + ctorByClass[objectClass] = Object; + ctorByClass[numberClass] = Number; + ctorByClass[regexpClass] = RegExp; + ctorByClass[stringClass] = String; + + /** Used to avoid iterating non-enumerable properties in IE < 9 */ + var nonEnumProps = {}; + nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; + nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true }; + nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true }; + nonEnumProps[objectClass] = { 'constructor': true }; + + (function() { + var length = shadowedProps.length; + while (length--) { + var key = shadowedProps[length]; + for (var className in nonEnumProps) { + if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) { + nonEnumProps[className][key] = false; + } + } + } + }()); + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps the given value to enable intuitive + * method chaining. + * + * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, + * and `unshift` + * + * Chaining is supported in custom builds as long as the `value` method is + * implicitly or explicitly included in the build. + * + * The chainable wrapper functions are: + * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, + * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, + * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, + * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, + * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, + * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, + * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, + * and `zip` + * + * The non-chainable wrapper functions are: + * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`, + * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, + * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, + * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`, + * `template`, `unescape`, `uniqueId`, and `value` + * + * The wrapper functions `first` and `last` return wrapped values when `n` is + * provided, otherwise they return unwrapped values. + * + * Explicit chaining can be enabled by using the `_.chain` method. + * + * @name _ + * @constructor + * @category Chaining + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns a `lodash` instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(num) { + * return num * num; + * }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor + return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__')) + ? value + : new lodashWrapper(value); + } + + /** + * A fast path for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap in a `lodash` instance. + * @param {boolean} chainAll A flag to enable chaining for all methods + * @returns {Object} Returns a `lodash` instance. + */ + function lodashWrapper(value, chainAll) { + this.__chain__ = !!chainAll; + this.__wrapped__ = value; + } + // ensure `new lodashWrapper` is an instance of `lodash` + lodashWrapper.prototype = lodash.prototype; + + /** + * An object used to flag environments features. + * + * @static + * @memberOf _ + * @type Object + */ + var support = lodash.support = {}; + + (function() { + var ctor = function() { this.x = 1; }, + object = { '0': 1, 'length': 1 }, + props = []; + + ctor.prototype = { 'valueOf': 1, 'y': 1 }; + for (var key in new ctor) { props.push(key); } + for (key in arguments) { } + + /** + * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9). + * + * @memberOf _.support + * @type boolean + */ + support.argsClass = toString.call(arguments) == argsClass; + + /** + * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5). + * + * @memberOf _.support + * @type boolean + */ + support.argsObject = arguments.constructor == Object && !(arguments instanceof Array); + + /** + * Detect if `name` or `message` properties of `Error.prototype` are + * enumerable by default. (IE < 9, Safari < 5.1) + * + * @memberOf _.support + * @type boolean + */ + support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name'); + + /** + * Detect if `prototype` properties are enumerable by default. + * + * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 + * (if the prototype or a property on the prototype has been set) + * incorrectly sets a function's `prototype` property [[Enumerable]] + * value to `true`. + * + * @memberOf _.support + * @type boolean + */ + support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype'); + + /** + * Detect if functions can be decompiled by `Function#toString` + * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). + * + * @memberOf _.support + * @type boolean + */ + support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); + + /** + * Detect if `Function#name` is supported (all but IE). + * + * @memberOf _.support + * @type boolean + */ + support.funcNames = typeof Function.name == 'string'; + + /** + * Detect if `arguments` object indexes are non-enumerable + * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1). + * + * @memberOf _.support + * @type boolean + */ + support.nonEnumArgs = key != 0; + + /** + * Detect if properties shadowing those on `Object.prototype` are non-enumerable. + * + * In IE < 9 an objects own properties, shadowing non-enumerable ones, are + * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug). + * + * @memberOf _.support + * @type boolean + */ + support.nonEnumShadows = !/valueOf/.test(props); + + /** + * Detect if own properties are iterated after inherited properties (all but IE < 9). + * + * @memberOf _.support + * @type boolean + */ + support.ownLast = props[0] != 'x'; + + /** + * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly. + * + * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` + * and `splice()` functions that fail to remove the last element, `value[0]`, + * of array-like objects even though the `length` property is set to `0`. + * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` + * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. + * + * @memberOf _.support + * @type boolean + */ + support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]); + + /** + * Detect lack of support for accessing string characters by index. + * + * IE < 8 can't access characters by index and IE 8 can only access + * characters by index on string literals. + * + * @memberOf _.support + * @type boolean + */ + support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; + + /** + * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9) + * and that the JS engine errors when attempting to coerce an object to + * a string without a `toString` function. + * + * @memberOf _.support + * @type boolean + */ + try { + support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + '')); + } catch(e) { + support.nodeClass = true; + } + }(1)); + + /** + * By default, the template delimiters used by Lo-Dash are similar to those in + * embedded Ruby (ERB). Change the following template settings to use alternative + * delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': /<%-([\s\S]+?)%>/g, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': /<%([\s\S]+?)%>/g, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type Object + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type Function + */ + '_': lodash + } + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The template used to create iterator functions. + * + * @private + * @param {Object} data The data object used to populate the text. + * @returns {string} Returns the interpolated text. + */ + var iteratorTemplate = function(obj) { + + var __p = 'var index, iterable = ' + + (obj.firstArg) + + ', result = ' + + (obj.init) + + ';\nif (!iterable) return result;\n' + + (obj.top) + + ';'; + if (obj.array) { + __p += '\nvar length = iterable.length; index = -1;\nif (' + + (obj.array) + + ') { '; + if (support.unindexedChars) { + __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } '; + } + __p += '\n while (++index < length) {\n ' + + (obj.loop) + + ';\n }\n}\nelse { '; + } else if (support.nonEnumArgs) { + __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' + + (obj.loop) + + ';\n }\n } else { '; + } + + if (support.enumPrototypes) { + __p += '\n var skipProto = typeof iterable == \'function\';\n '; + } + + if (support.enumErrorProps) { + __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n '; + } + + var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); } + + if (obj.useHas && obj.keys) { + __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n'; + if (conditions.length) { + __p += ' if (' + + (conditions.join(' && ')) + + ') {\n '; + } + __p += + (obj.loop) + + '; '; + if (conditions.length) { + __p += '\n }'; + } + __p += '\n } '; + } else { + __p += '\n for (index in iterable) {\n'; + if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) { + __p += ' if (' + + (conditions.join(' && ')) + + ') {\n '; + } + __p += + (obj.loop) + + '; '; + if (conditions.length) { + __p += '\n }'; + } + __p += '\n } '; + if (support.nonEnumShadows) { + __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n '; + for (k = 0; k < 7; k++) { + __p += '\n index = \'' + + (obj.shadowedProps[k]) + + '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))'; + if (!obj.useHas) { + __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])'; + } + __p += ') {\n ' + + (obj.loop) + + ';\n } '; + } + __p += '\n } '; + } + + } + + if (obj.array || support.nonEnumArgs) { + __p += '\n}'; + } + __p += + (obj.bottom) + + ';\nreturn result'; + + return __p + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.bind` that creates the bound function and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new bound function. + */ + function baseBind(bindData) { + var func = bindData[0], + partialArgs = bindData[2], + thisArg = bindData[4]; + + function bound() { + // `Function#bind` spec + // http://es5.github.io/#x15.3.4.5 + if (partialArgs) { + // avoid `arguments` object deoptimizations by using `slice` instead + // of `Array.prototype.slice.call` and not assigning `arguments` to a + // variable as a ternary expression + var args = slice(partialArgs); + push.apply(args, arguments); + } + // mimic the constructor's `return` behavior + // http://es5.github.io/#x13.2.2 + if (this instanceof bound) { + // ensure `new bound` is an instance of `func` + var thisBinding = baseCreate(func.prototype), + result = func.apply(thisBinding, args || arguments); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisArg, args || arguments); + } + setBindData(bound, bindData); + return bound; + } + + /** + * The base implementation of `_.clone` without argument juggling or support + * for `thisArg` binding. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep=false] Specify a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates clones with source counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, callback, stackA, stackB) { + if (callback) { + var result = callback(value); + if (typeof result != 'undefined') { + return result; + } + } + // inspect [[Class]] + var isObj = isObject(value); + if (isObj) { + var className = toString.call(value); + if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) { + return value; + } + var ctor = ctorByClass[className]; + switch (className) { + case boolClass: + case dateClass: + return new ctor(+value); + + case numberClass: + case stringClass: + return new ctor(value); + + case regexpClass: + result = ctor(value.source, reFlags.exec(value)); + result.lastIndex = value.lastIndex; + return result; + } + } else { + return value; + } + var isArr = isArray(value); + if (isDeep) { + // check for circular references and return corresponding clone + var initedStack = !stackA; + stackA || (stackA = getArray()); + stackB || (stackB = getArray()); + + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + result = isArr ? ctor(value.length) : {}; + } + else { + result = isArr ? slice(value) : assign({}, value); + } + // add array properties assigned by `RegExp#exec` + if (isArr) { + if (hasOwnProperty.call(value, 'index')) { + result.index = value.index; + } + if (hasOwnProperty.call(value, 'input')) { + result.input = value.input; + } + } + // exit for shallow clone + if (!isDeep) { + return result; + } + // add the source value to the stack of traversed objects + // and associate it with its clone + stackA.push(value); + stackB.push(result); + + // recursively populate clone (susceptible to call stack limits) + (isArr ? baseEach : forOwn)(value, function(objValue, key) { + result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); + }); + + if (initedStack) { + releaseArray(stackA); + releaseArray(stackB); + } + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(prototype, properties) { + return isObject(prototype) ? nativeCreate(prototype) : {}; + } + // fallback for browsers without `Object.create` + if (!nativeCreate) { + baseCreate = (function() { + function Object() {} + return function(prototype) { + if (isObject(prototype)) { + Object.prototype = prototype; + var result = new Object; + Object.prototype = null; + } + return result || context.Object(); + }; + }()); + } + + /** + * The base implementation of `_.createCallback` without support for creating + * "_.pluck" or "_.where" style callbacks. + * + * @private + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + */ + function baseCreateCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + // exit early for no `thisArg` or already bound by `Function#bind` + if (typeof thisArg == 'undefined' || !('prototype' in func)) { + return func; + } + var bindData = func.__bindData__; + if (typeof bindData == 'undefined') { + if (support.funcNames) { + bindData = !func.name; + } + bindData = bindData || !support.funcDecomp; + if (!bindData) { + var source = fnToString.call(func); + if (!support.funcNames) { + bindData = !reFuncName.test(source); + } + if (!bindData) { + // checks if `func` references the `this` keyword and stores the result + bindData = reThis.test(source); + setBindData(func, bindData); + } + } + } + // exit early if there are no `this` references or `func` is bound + if (bindData === false || (bindData !== true && bindData[1] & 1)) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 2: return function(a, b) { + return func.call(thisArg, a, b); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + } + return bind(func, thisArg); + } + + /** + * The base implementation of `createWrapper` that creates the wrapper and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new function. + */ + function baseCreateWrapper(bindData) { + var func = bindData[0], + bitmask = bindData[1], + partialArgs = bindData[2], + partialRightArgs = bindData[3], + thisArg = bindData[4], + arity = bindData[5]; + + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + key = func; + + function bound() { + var thisBinding = isBind ? thisArg : this; + if (partialArgs) { + var args = slice(partialArgs); + push.apply(args, arguments); + } + if (partialRightArgs || isCurry) { + args || (args = slice(arguments)); + if (partialRightArgs) { + push.apply(args, partialRightArgs); + } + if (isCurry && args.length < arity) { + bitmask |= 16 & ~32; + return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); + } + } + args || (args = arguments); + if (isBindKey) { + func = thisBinding[key]; + } + if (this instanceof bound) { + thisBinding = baseCreate(func.prototype); + var result = func.apply(thisBinding, args); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisBinding, args); + } + setBindData(bound, bindData); + return bound; + } + + /** + * The base implementation of `_.difference` that accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to process. + * @param {Array} [values] The array of values to exclude. + * @returns {Array} Returns a new array of filtered values. + */ + function baseDifference(array, values) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + isLarge = length >= largeArraySize && indexOf === baseIndexOf, + result = []; + + if (isLarge) { + var cache = createCache(values); + if (cache) { + indexOf = cacheIndexOf; + values = cache; + } else { + isLarge = false; + } + } + while (++index < length) { + var value = array[index]; + if (indexOf(values, value) < 0) { + result.push(value); + } + } + if (isLarge) { + releaseObject(values); + } + return result; + } + + /** + * The base implementation of `_.flatten` without support for callback + * shorthands or `thisArg` binding. + * + * @private + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. + * @param {number} [fromIndex=0] The index to start from. + * @returns {Array} Returns a new flattened array. + */ + function baseFlatten(array, isShallow, isStrict, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + + if (value && typeof value == 'object' && typeof value.length == 'number' + && (isArray(value) || isArguments(value))) { + // recursively flatten arrays (susceptible to call stack limits) + if (!isShallow) { + value = baseFlatten(value, isShallow, isStrict); + } + var valIndex = -1, + valLength = value.length, + resIndex = result.length; + + result.length += valLength; + while (++valIndex < valLength) { + result[resIndex++] = value[valIndex]; + } + } else if (!isStrict) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.isEqual`, without support for `thisArg` binding, + * that allows partial "_.where" style comparisons. + * + * @private + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `a` objects. + * @param {Array} [stackB=[]] Tracks traversed `b` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { + // used to indicate that when comparing objects, `a` has at least the properties of `b` + if (callback) { + var result = callback(a, b); + if (typeof result != 'undefined') { + return !!result; + } + } + // exit early for identical values + if (a === b) { + // treat `+0` vs. `-0` as not equal + return a !== 0 || (1 / a == 1 / b); + } + var type = typeof a, + otherType = typeof b; + + // exit early for unlike primitive values + if (a === a && + !(a && objectTypes[type]) && + !(b && objectTypes[otherType])) { + return false; + } + // exit early for `null` and `undefined` avoiding ES3's Function#call behavior + // http://es5.github.io/#x15.3.4.4 + if (a == null || b == null) { + return a === b; + } + // compare [[Class]] names + var className = toString.call(a), + otherClass = toString.call(b); + + if (className == argsClass) { + className = objectClass; + } + if (otherClass == argsClass) { + otherClass = objectClass; + } + if (className != otherClass) { + return false; + } + switch (className) { + case boolClass: + case dateClass: + // coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal + return +a == +b; + + case numberClass: + // treat `NaN` vs. `NaN` as equal + return (a != +a) + ? b != +b + // but treat `+0` vs. `-0` as not equal + : (a == 0 ? (1 / a == 1 / b) : a == +b); + + case regexpClass: + case stringClass: + // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) + // treat string primitives and their corresponding object instances as equal + return a == String(b); + } + var isArr = className == arrayClass; + if (!isArr) { + // unwrap any `lodash` wrapped values + var aWrapped = hasOwnProperty.call(a, '__wrapped__'), + bWrapped = hasOwnProperty.call(b, '__wrapped__'); + + if (aWrapped || bWrapped) { + return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); + } + // exit for functions and DOM nodes + if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) { + return false; + } + // in older versions of Opera, `arguments` objects have `Array` constructors + var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor, + ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor; + + // non `Object` object instances with different constructors are not equal + if (ctorA != ctorB && + !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && + ('constructor' in a && 'constructor' in b) + ) { + return false; + } + } + // assume cyclic structures are equal + // the algorithm for detecting cyclic structures is adapted from ES 5.1 + // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) + var initedStack = !stackA; + stackA || (stackA = getArray()); + stackB || (stackB = getArray()); + + var length = stackA.length; + while (length--) { + if (stackA[length] == a) { + return stackB[length] == b; + } + } + var size = 0; + result = true; + + // add `a` and `b` to the stack of traversed objects + stackA.push(a); + stackB.push(b); + + // recursively compare objects and arrays (susceptible to call stack limits) + if (isArr) { + // compare lengths to determine if a deep comparison is necessary + length = a.length; + size = b.length; + result = size == length; + + if (result || isWhere) { + // deep compare the contents, ignoring non-numeric properties + while (size--) { + var index = length, + value = b[size]; + + if (isWhere) { + while (index--) { + if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } + } + else { + // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` + // which, in this case, is more costly + forIn(b, function(value, key, b) { + if (hasOwnProperty.call(b, key)) { + // count the number of properties. + size++; + // deep compare each property value. + return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); + } + }); + + if (result && !isWhere) { + // ensure both objects have the same number of properties + forIn(a, function(value, key, a) { + if (hasOwnProperty.call(a, key)) { + // `size` will be `-1` if `a` has more properties than `b` + return (result = --size > -1); + } + }); + } + } + stackA.pop(); + stackB.pop(); + + if (initedStack) { + releaseArray(stackA); + releaseArray(stackB); + } + return result; + } + + /** + * The base implementation of `_.merge` without argument juggling or support + * for `thisArg` binding. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} [callback] The function to customize merging properties. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + */ + function baseMerge(object, source, callback, stackA, stackB) { + (isArray(source) ? forEach : forOwn)(source, function(source, key) { + var found, + isArr, + result = source, + value = object[key]; + + if (source && ((isArr = isArray(source)) || isPlainObject(source))) { + // avoid merging previously merged cyclic sources + var stackLength = stackA.length; + while (stackLength--) { + if ((found = stackA[stackLength] == source)) { + value = stackB[stackLength]; + break; + } + } + if (!found) { + var isShallow; + if (callback) { + result = callback(value, source); + if ((isShallow = typeof result != 'undefined')) { + value = result; + } + } + if (!isShallow) { + value = isArr + ? (isArray(value) ? value : []) + : (isPlainObject(value) ? value : {}); + } + // add `source` and associated `value` to the stack of traversed objects + stackA.push(source); + stackB.push(value); + + // recursively merge objects and arrays (susceptible to call stack limits) + if (!isShallow) { + baseMerge(value, source, callback, stackA, stackB); + } + } + } + else { + if (callback) { + result = callback(value, source); + if (typeof result == 'undefined') { + result = source; + } + } + if (typeof result != 'undefined') { + value = result; + } + } + object[key] = value; + }); + } + + /** + * The base implementation of `_.random` without argument juggling or support + * for returning floating-point numbers. + * + * @private + * @param {number} min The minimum possible value. + * @param {number} max The maximum possible value. + * @returns {number} Returns a random number. + */ + function baseRandom(min, max) { + return min + floor(nativeRandom() * (max - min + 1)); + } + + /** + * The base implementation of `_.uniq` without support for callback shorthands + * or `thisArg` binding. + * + * @private + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function} [callback] The function called per iteration. + * @returns {Array} Returns a duplicate-value-free array. + */ + function baseUniq(array, isSorted, callback) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + result = []; + + var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf, + seen = (callback || isLarge) ? getArray() : result; + + if (isLarge) { + var cache = createCache(seen); + indexOf = cacheIndexOf; + seen = cache; + } + while (++index < length) { + var value = array[index], + computed = callback ? callback(value, index, array) : value; + + if (isSorted + ? !index || seen[seen.length - 1] !== computed + : indexOf(seen, computed) < 0 + ) { + if (callback || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + if (isLarge) { + releaseArray(seen.array); + releaseObject(seen); + } else if (callback) { + releaseArray(seen); + } + return result; + } + + /** + * Creates a function that aggregates a collection, creating an object composed + * of keys generated from the results of running each element of the collection + * through a callback. The given `setter` function sets the keys and values + * of the composed object. + * + * @private + * @param {Function} setter The setter function. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter) { + return function(collection, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + setter(result, value, callback(value, index, collection), collection); + } + } else { + baseEach(collection, function(value, key, collection) { + setter(result, value, callback(value, key, collection), collection); + }); + } + return result; + }; + } + + /** + * Creates a function that, when called, either curries or invokes `func` + * with an optional `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of method flags to compose. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` + * 8 - `_.curry` (bound) + * 16 - `_.partial` + * 32 - `_.partialRight` + * @param {Array} [partialArgs] An array of arguments to prepend to those + * provided to the new function. + * @param {Array} [partialRightArgs] An array of arguments to append to those + * provided to the new function. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new function. + */ + function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + isPartial = bitmask & 16, + isPartialRight = bitmask & 32; + + if (!isBindKey && !isFunction(func)) { + throw new TypeError; + } + if (isPartial && !partialArgs.length) { + bitmask &= ~16; + isPartial = partialArgs = false; + } + if (isPartialRight && !partialRightArgs.length) { + bitmask &= ~32; + isPartialRight = partialRightArgs = false; + } + var bindData = func && func.__bindData__; + if (bindData && bindData !== true) { + // clone `bindData` + bindData = slice(bindData); + if (bindData[2]) { + bindData[2] = slice(bindData[2]); + } + if (bindData[3]) { + bindData[3] = slice(bindData[3]); + } + // set `thisBinding` is not previously bound + if (isBind && !(bindData[1] & 1)) { + bindData[4] = thisArg; + } + // set if previously bound but not currently (subsequent curried functions) + if (!isBind && bindData[1] & 1) { + bitmask |= 8; + } + // set curried arity if not yet set + if (isCurry && !(bindData[1] & 4)) { + bindData[5] = arity; + } + // append partial left arguments + if (isPartial) { + push.apply(bindData[2] || (bindData[2] = []), partialArgs); + } + // append partial right arguments + if (isPartialRight) { + unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); + } + // merge flags + bindData[1] |= bitmask; + return createWrapper.apply(null, bindData); + } + // fast path for `_.bind` + var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; + return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); + } + + /** + * Creates compiled iteration functions. + * + * @private + * @param {...Object} [options] The compile options object(s). + * @param {string} [options.array] Code to determine if the iterable is an array or array-like. + * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop. + * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration. + * @param {string} [options.args] A comma separated string of iteration function arguments. + * @param {string} [options.top] Code to execute before the iteration branches. + * @param {string} [options.loop] Code to execute in the object loop. + * @param {string} [options.bottom] Code to execute after the iteration branches. + * @returns {Function} Returns the compiled function. + */ + function createIterator() { + // data properties + iteratorData.shadowedProps = shadowedProps; + + // iterator options + iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = ''; + iteratorData.init = 'iterable'; + iteratorData.useHas = true; + + // merge options into a template data object + for (var object, index = 0; object = arguments[index]; index++) { + for (var key in object) { + iteratorData[key] = object[key]; + } + } + var args = iteratorData.args; + iteratorData.firstArg = /^[^,]+/.exec(args)[0]; + + // create the function factory + var factory = Function( + 'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' + + 'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' + + 'objectTypes, nonEnumProps, stringClass, stringProto, toString', + 'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}' + ); + + // return the compiled function + return factory( + baseCreateCallback, errorClass, errorProto, hasOwnProperty, + indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto, + objectTypes, nonEnumProps, stringClass, stringProto, toString + ); + } + + /** + * Used by `escape` to convert characters to HTML entities. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(match) { + return htmlEscapes[match]; + } + + /** + * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * customized, this method returns the custom method, otherwise it returns + * the `baseIndexOf` function. + * + * @private + * @returns {Function} Returns the "indexOf" function. + */ + function getIndexOf() { + var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; + return result; + } + + /** + * Checks if `value` is a native function. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. + */ + function isNative(value) { + return typeof value == 'function' && reNative.test(value); + } + + /** + * Sets `this` binding data on a given function. + * + * @private + * @param {Function} func The function to set data on. + * @param {Array} value The data array to set. + */ + var setBindData = !defineProperty ? noop : function(func, value) { + descriptor.value = value; + defineProperty(func, '__bindData__', descriptor); + descriptor.value = null; + }; + + /** + * A fallback implementation of `isPlainObject` which checks if a given value + * is an object created by the `Object` constructor, assuming objects created + * by the `Object` constructor have no inherited enumerable properties and that + * there are no `Object.prototype` extensions. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + */ + function shimIsPlainObject(value) { + var ctor, + result; + + // avoid non Object objects, `arguments` objects, and DOM elements + if (!(value && toString.call(value) == objectClass) || + (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) || + (!support.argsClass && isArguments(value)) || + (!support.nodeClass && isNode(value))) { + return false; + } + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + if (support.ownLast) { + forIn(value, function(value, key, object) { + result = hasOwnProperty.call(object, key); + return false; + }); + return result !== false; + } + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + forIn(value, function(value, key) { + result = key; + }); + return typeof result == 'undefined' || hasOwnProperty.call(value, result); + } + + /** + * Used by `unescape` to convert HTML entities to characters. + * + * @private + * @param {string} match The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(match) { + return htmlUnescapes[match]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Checks if `value` is an `arguments` object. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. + * @example + * + * (function() { return _.isArguments(arguments); })(1, 2, 3); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == argsClass || false; + } + // fallback for browsers that can't detect `arguments` objects by [[Class]] + if (!support.argsClass) { + isArguments = function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false; + }; + } + + /** + * Checks if `value` is an array. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an array, else `false`. + * @example + * + * (function() { return _.isArray(arguments); })(); + * // => false + * + * _.isArray([1, 2, 3]); + * // => true + */ + var isArray = nativeIsArray || function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == arrayClass || false; + }; + + /** + * A fallback implementation of `Object.keys` which produces an array of the + * given object's own enumerable property names. + * + * @private + * @type Function + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + */ + var shimKeys = createIterator({ + 'args': 'object', + 'init': '[]', + 'top': 'if (!(objectTypes[typeof object])) return result', + 'loop': 'result.push(index)' + }); + + /** + * Creates an array composed of the own enumerable property names of an object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + * @example + * + * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); + * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) + */ + var keys = !nativeKeys ? shimKeys : function(object) { + if (!isObject(object)) { + return []; + } + if ((support.enumPrototypes && typeof object == 'function') || + (support.nonEnumArgs && object.length && isArguments(object))) { + return shimKeys(object); + } + return nativeKeys(object); + }; + + /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */ + var eachIteratorOptions = { + 'args': 'collection, callback, thisArg', + 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)", + 'array': "typeof length == 'number'", + 'keys': keys, + 'loop': 'if (callback(iterable[index], index, collection) === false) return result' + }; + + /** Reusable iterator options for `assign` and `defaults` */ + var defaultsIteratorOptions = { + 'args': 'object, source, guard', + 'top': + 'var args = arguments,\n' + + ' argsIndex = 0,\n' + + " argsLength = typeof guard == 'number' ? 2 : args.length;\n" + + 'while (++argsIndex < argsLength) {\n' + + ' iterable = args[argsIndex];\n' + + ' if (iterable && objectTypes[typeof iterable]) {', + 'keys': keys, + 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]", + 'bottom': ' }\n}' + }; + + /** Reusable iterator options for `forIn` and `forOwn` */ + var forOwnIteratorOptions = { + 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top, + 'array': false + }; + + /** + * Used to convert characters to HTML entities: + * + * Though the `>` character is escaped for symmetry, characters like `>` and `/` + * don't require escaping in HTML and have no special meaning unless they're part + * of a tag or an unquoted attribute value. + * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") + */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + /** Used to convert HTML entities to characters */ + var htmlUnescapes = invert(htmlEscapes); + + /** Used to match HTML entities and HTML characters */ + var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), + reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); + + /** + * A function compiled to iterate `arguments` objects, arrays, objects, and + * strings consistenly across environments, executing the callback for each + * element in the collection. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index|key, collection). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @private + * @type Function + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEach = createIterator(eachIteratorOptions); + + /*--------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources will overwrite property assignments of previous + * sources. If a callback is provided it will be executed to produce the + * assigned values. The callback is bound to `thisArg` and invoked with two + * arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @type Function + * @alias extend + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param {Function} [callback] The function to customize assigning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); + * // => { 'name': 'fred', 'employer': 'slate' } + * + * var defaults = _.partialRight(_.assign, function(a, b) { + * return typeof a == 'undefined' ? b : a; + * }); + * + * var object = { 'name': 'barney' }; + * defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + var assign = createIterator(defaultsIteratorOptions, { + 'top': + defaultsIteratorOptions.top.replace(';', + ';\n' + + "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" + + ' var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' + + "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" + + ' callback = args[--argsLength];\n' + + '}' + ), + 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]' + }); + + /** + * Creates a clone of `value`. If `isDeep` is `true` nested objects will also + * be cloned, otherwise they will be assigned by reference. If a callback + * is provided it will be executed to produce the cloned values. If the + * callback returns `undefined` cloning will be handled by the method instead. + * The callback is bound to `thisArg` and invoked with one argument; (value). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to clone. + * @param {boolean} [isDeep=false] Specify a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the cloned value. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * var shallow = _.clone(characters); + * shallow[0] === characters[0]; + * // => true + * + * var deep = _.clone(characters, true); + * deep[0] === characters[0]; + * // => false + * + * _.mixin({ + * 'clone': _.partialRight(_.clone, function(value) { + * return _.isElement(value) ? value.cloneNode(false) : undefined; + * }) + * }); + * + * var clone = _.clone(document.body); + * clone.childNodes.length; + * // => 0 + */ + function clone(value, isDeep, callback, thisArg) { + // allows working with "Collections" methods without using their `index` + // and `collection` arguments for `isDeep` and `callback` + if (typeof isDeep != 'boolean' && isDeep != null) { + thisArg = callback; + callback = isDeep; + isDeep = false; + } + return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + } + + /** + * Creates a deep clone of `value`. If a callback is provided it will be + * executed to produce the cloned values. If the callback returns `undefined` + * cloning will be handled by the method instead. The callback is bound to + * `thisArg` and invoked with one argument; (value). + * + * Note: This method is loosely based on the structured clone algorithm. Functions + * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and + * objects created by constructors other than `Object` are cloned to plain `Object` objects. + * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the deep cloned value. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * var deep = _.cloneDeep(characters); + * deep[0] === characters[0]; + * // => false + * + * var view = { + * 'label': 'docs', + * 'node': element + * }; + * + * var clone = _.cloneDeep(view, function(value) { + * return _.isElement(value) ? value.cloneNode(true) : undefined; + * }); + * + * clone.node == view.node; + * // => false + */ + function cloneDeep(value, callback, thisArg) { + return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + } + + /** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties ? assign(result, properties) : result; + } + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional defaults of the same property will be ignored. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param- {Object} [guard] Allows working with `_.reduce` without using its + * `key` and `object` arguments as sources. + * @returns {Object} Returns the destination object. + * @example + * + * var object = { 'name': 'barney' }; + * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + var defaults = createIterator(defaultsIteratorOptions); + + /** + * This method is like `_.findIndex` except that it returns the key of the + * first element that passes the callback check, instead of the element itself. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to search. + * @param {Function|Object|string} [callback=identity] The function called per + * iteration. If a property name or object is provided it will be used to + * create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @example + * + * var characters = { + * 'barney': { 'age': 36, 'blocked': false }, + * 'fred': { 'age': 40, 'blocked': true }, + * 'pebbles': { 'age': 1, 'blocked': false } + * }; + * + * _.findKey(characters, function(chr) { + * return chr.age < 40; + * }); + * // => 'barney' (property order is not guaranteed across environments) + * + * // using "_.where" callback shorthand + * _.findKey(characters, { 'age': 1 }); + * // => 'pebbles' + * + * // using "_.pluck" callback shorthand + * _.findKey(characters, 'blocked'); + * // => 'fred' + */ + function findKey(object, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forOwn(object, function(value, key, object) { + if (callback(value, key, object)) { + result = key; + return false; + } + }); + return result; + } + + /** + * This method is like `_.findKey` except that it iterates over elements + * of a `collection` in the opposite order. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to search. + * @param {Function|Object|string} [callback=identity] The function called per + * iteration. If a property name or object is provided it will be used to + * create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @example + * + * var characters = { + * 'barney': { 'age': 36, 'blocked': true }, + * 'fred': { 'age': 40, 'blocked': false }, + * 'pebbles': { 'age': 1, 'blocked': true } + * }; + * + * _.findLastKey(characters, function(chr) { + * return chr.age < 40; + * }); + * // => returns `pebbles`, assuming `_.findKey` returns `barney` + * + * // using "_.where" callback shorthand + * _.findLastKey(characters, { 'age': 40 }); + * // => 'fred' + * + * // using "_.pluck" callback shorthand + * _.findLastKey(characters, 'blocked'); + * // => 'pebbles' + */ + function findLastKey(object, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forOwnRight(object, function(value, key, object) { + if (callback(value, key, object)) { + result = key; + return false; + } + }); + return result; + } + + /** + * Iterates over own and inherited enumerable properties of an object, + * executing the callback for each property. The callback is bound to `thisArg` + * and invoked with three arguments; (value, key, object). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forIn(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) + */ + var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, { + 'useHas': false + }); + + /** + * This method is like `_.forIn` except that it iterates over elements + * of a `collection` in the opposite order. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forInRight(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' + */ + function forInRight(object, callback, thisArg) { + var pairs = []; + + forIn(object, function(value, key) { + pairs.push(key, value); + }); + + var length = pairs.length; + callback = baseCreateCallback(callback, thisArg, 3); + while (length--) { + if (callback(pairs[length--], pairs[length], object) === false) { + break; + } + } + return object; + } + + /** + * Iterates over own enumerable properties of an object, executing the callback + * for each property. The callback is bound to `thisArg` and invoked with three + * arguments; (value, key, object). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) + */ + var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions); + + /** + * This method is like `_.forOwn` except that it iterates over elements + * of a `collection` in the opposite order. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' + */ + function forOwnRight(object, callback, thisArg) { + var props = keys(object), + length = props.length; + + callback = baseCreateCallback(callback, thisArg, 3); + while (length--) { + var key = props[length]; + if (callback(object[key], key, object) === false) { + break; + } + } + return object; + } + + /** + * Creates a sorted array of property names of all enumerable properties, + * own and inherited, of `object` that have function values. + * + * @static + * @memberOf _ + * @alias methods + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names that have function values. + * @example + * + * _.functions(_); + * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] + */ + function functions(object) { + var result = []; + forIn(object, function(value, key) { + if (isFunction(value)) { + result.push(key); + } + }); + return result.sort(); + } + + /** + * Checks if the specified property name exists as a direct property of `object`, + * instead of an inherited property. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to check. + * @returns {boolean} Returns `true` if key is a direct property, else `false`. + * @example + * + * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); + * // => true + */ + function has(object, key) { + return object ? hasOwnProperty.call(object, key) : false; + } + + /** + * Creates an object composed of the inverted keys and values of the given object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to invert. + * @returns {Object} Returns the created inverted object. + * @example + * + * _.invert({ 'first': 'fred', 'second': 'barney' }); + * // => { 'fred': 'first', 'barney': 'second' } + */ + function invert(object) { + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + result[object[key]] = key; + } + return result; + } + + /** + * Checks if `value` is a boolean value. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. + * @example + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + value && typeof value == 'object' && toString.call(value) == boolClass || false; + } + + /** + * Checks if `value` is a date. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a date, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + */ + function isDate(value) { + return value && typeof value == 'object' && toString.call(value) == dateClass || false; + } + + /** + * Checks if `value` is a DOM element. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + */ + function isElement(value) { + return value && value.nodeType === 1 || false; + } + + /** + * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a + * length of `0` and objects with no own enumerable properties are considered + * "empty". + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if the `value` is empty, else `false`. + * @example + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({}); + * // => true + * + * _.isEmpty(''); + * // => true + */ + function isEmpty(value) { + var result = true; + if (!value) { + return result; + } + var className = toString.call(value), + length = value.length; + + if ((className == arrayClass || className == stringClass || + (support.argsClass ? className == argsClass : isArguments(value))) || + (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { + return !length; + } + forOwn(value, function() { + return (result = false); + }); + return result; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent to each other. If a callback is provided it will be executed + * to compare values. If the callback returns `undefined` comparisons will + * be handled by the method instead. The callback is bound to `thisArg` and + * invoked with two arguments; (a, b). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'name': 'fred' }; + * var copy = { 'name': 'fred' }; + * + * object == copy; + * // => false + * + * _.isEqual(object, copy); + * // => true + * + * var words = ['hello', 'goodbye']; + * var otherWords = ['hi', 'goodbye']; + * + * _.isEqual(words, otherWords, function(a, b) { + * var reGreet = /^(?:hello|hi)$/i, + * aGreet = _.isString(a) && reGreet.test(a), + * bGreet = _.isString(b) && reGreet.test(b); + * + * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; + * }); + * // => true + */ + function isEqual(a, b, callback, thisArg) { + return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2)); + } + + /** + * Checks if `value` is, or can be coerced to, a finite number. + * + * Note: This is not the same as native `isFinite` which will return true for + * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is finite, else `false`. + * @example + * + * _.isFinite(-101); + * // => true + * + * _.isFinite('10'); + * // => true + * + * _.isFinite(true); + * // => false + * + * _.isFinite(''); + * // => false + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); + } + + /** + * Checks if `value` is a function. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + */ + function isFunction(value) { + return typeof value == 'function'; + } + // fallback for older versions of Chrome and Safari + if (isFunction(/x/)) { + isFunction = function(value) { + return typeof value == 'function' && toString.call(value) == funcClass; + }; + } + + /** + * Checks if `value` is the language type of Object. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ + function isObject(value) { + // check if the value is the ECMAScript language type of Object + // http://es5.github.io/#x8 + // and avoid a V8 bug + // http://code.google.com/p/v8/issues/detail?id=2291 + return !!(value && objectTypes[typeof value]); + } + + /** + * Checks if `value` is `NaN`. + * + * Note: This is not the same as native `isNaN` which will return `true` for + * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // `NaN` as a primitive is the only value that is not equal to itself + // (perform the [[Class]] check first to avoid errors with some host objects in IE) + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(undefined); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is a number. + * + * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a number, else `false`. + * @example + * + * _.isNumber(8.4 * 5); + * // => true + */ + function isNumber(value) { + return typeof value == 'number' || + value && typeof value == 'object' && toString.call(value) == numberClass || false; + } + + /** + * Checks if `value` is an object created by the `Object` constructor. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * _.isPlainObject(new Shape); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + */ + var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { + if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) { + return false; + } + var valueOf = value.valueOf, + objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); + + return objProto + ? (value == objProto || getPrototypeOf(value) == objProto) + : shimIsPlainObject(value); + }; + + /** + * Checks if `value` is a regular expression. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. + * @example + * + * _.isRegExp(/fred/); + * // => true + */ + function isRegExp(value) { + return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false; + } + + /** + * Checks if `value` is a string. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a string, else `false`. + * @example + * + * _.isString('fred'); + * // => true + */ + function isString(value) { + return typeof value == 'string' || + value && typeof value == 'object' && toString.call(value) == stringClass || false; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + */ + function isUndefined(value) { + return typeof value == 'undefined'; + } + + /** + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through the callback. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new object with values of the results of each `callback` execution. + * @example + * + * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + * + * var characters = { + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * }; + * + * // using "_.pluck" callback shorthand + * _.mapValues(characters, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } + */ + function mapValues(object, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + + forOwn(object, function(value, key, object) { + result[key] = callback(value, key, object); + }); + return result; + } + + /** + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * will overwrite property assignments of previous sources. If a callback is + * provided it will be executed to produce the merged values of the destination + * and source properties. If the callback returns `undefined` merging will + * be handled by the method instead. The callback is bound to `thisArg` and + * invoked with two arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param {Function} [callback] The function to customize merging properties. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * var names = { + * 'characters': [ + * { 'name': 'barney' }, + * { 'name': 'fred' } + * ] + * }; + * + * var ages = { + * 'characters': [ + * { 'age': 36 }, + * { 'age': 40 } + * ] + * }; + * + * _.merge(names, ages); + * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } + * + * var food = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var otherFood = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(food, otherFood, function(a, b) { + * return _.isArray(a) ? a.concat(b) : undefined; + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } + */ + function merge(object) { + var args = arguments, + length = 2; + + if (!isObject(object)) { + return object; + } + // allows working with `_.reduce` and `_.reduceRight` without using + // their `index` and `collection` arguments + if (typeof args[2] != 'number') { + length = args.length; + } + if (length > 3 && typeof args[length - 2] == 'function') { + var callback = baseCreateCallback(args[--length - 1], args[length--], 2); + } else if (length > 2 && typeof args[length - 1] == 'function') { + callback = args[--length]; + } + var sources = slice(arguments, 1, length), + index = -1, + stackA = getArray(), + stackB = getArray(); + + while (++index < length) { + baseMerge(object, sources[index], callback, stackA, stackB); + } + releaseArray(stackA); + releaseArray(stackB); + return object; + } + + /** + * Creates a shallow clone of `object` excluding the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` omitting the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The properties to omit or the + * function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object without the omitted properties. + * @example + * + * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); + * // => { 'name': 'fred' } + * + * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { + * return typeof value == 'number'; + * }); + * // => { 'name': 'fred' } + */ + function omit(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var props = []; + forIn(object, function(value, key) { + props.push(key); + }); + props = baseDifference(props, baseFlatten(arguments, true, false, 1)); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + result[key] = object[key]; + } + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (!callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * Creates a two dimensional array of an object's key-value pairs, + * i.e. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns new array of key-value pairs. + * @example + * + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) + */ + function pairs(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; + } + + /** + * Creates a shallow clone of `object` composed of the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` picking the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The function called per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object composed of the picked properties. + * @example + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); + * // => { 'name': 'fred' } + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { + * return key.charAt(0) != '_'; + * }); + * // => { 'name': 'fred' } + */ + function pick(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var index = -1, + props = baseFlatten(arguments, true, false, 1), + length = isObject(object) ? props.length : 0; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * An alternative to `_.reduce` this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own + * enumerable properties through a callback, with each callback execution + * potentially mutating the `accumulator` object. The callback is bound to + * `thisArg` and invoked with four arguments; (accumulator, value, key, object). + * Callbacks may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) { + * num *= num; + * if (num % 2) { + * return result.push(num) < 3; + * } + * }); + * // => [1, 9, 25] + * + * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function transform(object, callback, accumulator, thisArg) { + var isArr = isArray(object); + if (accumulator == null) { + if (isArr) { + accumulator = []; + } else { + var ctor = object && object.constructor, + proto = ctor && ctor.prototype; + + accumulator = baseCreate(proto); + } + } + if (callback) { + callback = lodash.createCallback(callback, thisArg, 4); + (isArr ? baseEach : forOwn)(object, function(value, index, object) { + return callback(accumulator, value, index, object); + }); + } + return accumulator; + } + + /** + * Creates an array composed of the own enumerable property values of `object`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property values. + * @example + * + * _.values({ 'one': 1, 'two': 2, 'three': 3 }); + * // => [1, 2, 3] (property order is not guaranteed across environments) + */ + function values(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array of elements from the specified indexes, or keys, of the + * `collection`. Indexes may be specified as individual arguments or as arrays + * of indexes. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [index] The indexes of `collection` + * to retrieve, specified as individual indexes or arrays of indexes. + * @returns {Array} Returns a new array of elements corresponding to the + * provided indexes. + * @example + * + * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); + * // => ['a', 'c', 'e'] + * + * _.at(['fred', 'barney', 'pebbles'], 0, 2); + * // => ['fred', 'pebbles'] + */ + function at(collection) { + var args = arguments, + index = -1, + props = baseFlatten(args, true, false, 1), + length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length, + result = Array(length); + + if (support.unindexedChars && isString(collection)) { + collection = collection.split(''); + } + while(++index < length) { + result[index] = collection[props[index]]; + } + return result; + } + + /** + * Checks if a given value is present in a collection using strict equality + * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the + * offset from the end of the collection. + * + * @static + * @memberOf _ + * @alias include + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {*} target The value to check for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {boolean} Returns `true` if the `target` element is found, else `false`. + * @example + * + * _.contains([1, 2, 3], 1); + * // => true + * + * _.contains([1, 2, 3], 1, 2); + * // => false + * + * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.contains('pebbles', 'eb'); + * // => true + */ + function contains(collection, target, fromIndex) { + var index = -1, + indexOf = getIndexOf(), + length = collection ? collection.length : 0, + result = false; + + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; + if (isArray(collection)) { + result = indexOf(collection, target, fromIndex) > -1; + } else if (typeof length == 'number') { + result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1; + } else { + baseEach(collection, function(value) { + if (++index >= fromIndex) { + return !(result = value === target); + } + }); + } + return result; + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through the callback. The corresponding value + * of each key is the number of times the key was returned by the callback. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); + }); + + /** + * Checks if the given callback returns truey value for **all** elements of + * a collection. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if all elements passed the callback check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes']); + * // => false + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.every(characters, 'age'); + * // => true + * + * // using "_.where" callback shorthand + * _.every(characters, { 'age': 36 }); + * // => false + */ + function every(collection, callback, thisArg) { + var result = true; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (!(result = !!callback(collection[index], index, collection))) { + break; + } + } + } else { + baseEach(collection, function(value, index, collection) { + return (result = !!callback(value, index, collection)); + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning an array of all elements + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that passed the callback check. + * @example + * + * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [2, 4, 6] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.filter(characters, 'blocked'); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + * + * // using "_.where" callback shorthand + * _.filter(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + */ + function filter(collection, callback, thisArg) { + var result = []; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + result.push(value); + } + } + } else { + baseEach(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result.push(value); + } + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning the first element that + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias detect, findWhere + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.find(characters, function(chr) { + * return chr.age < 40; + * }); + * // => { 'name': 'barney', 'age': 36, 'blocked': false } + * + * // using "_.where" callback shorthand + * _.find(characters, { 'age': 1 }); + * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } + * + * // using "_.pluck" callback shorthand + * _.find(characters, 'blocked'); + * // => { 'name': 'fred', 'age': 40, 'blocked': true } + */ + function find(collection, callback, thisArg) { + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + return value; + } + } + } else { + var result; + baseEach(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + } + + /** + * This method is like `_.find` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(num) { + * return num % 2 == 1; + * }); + * // => 3 + */ + function findLast(collection, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forEachRight(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + + /** + * Iterates over elements of a collection, executing the callback for each + * element. The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * Note: As with other "Collections" methods, objects with a `length` property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); + * // => logs each number and returns '1,2,3' + * + * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); + * // => logs each number and returns the object (property order is not guaranteed across environments) + */ + function forEach(collection, callback, thisArg) { + if (callback && typeof thisArg == 'undefined' && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (callback(collection[index], index, collection) === false) { + break; + } + } + } else { + baseEach(collection, callback, thisArg); + } + return collection; + } + + /** + * This method is like `_.forEach` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); + * // => logs each number from right to left and returns '3,2,1' + */ + function forEachRight(collection, callback, thisArg) { + var iterable = collection, + length = collection ? collection.length : 0; + + callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); + if (isArray(collection)) { + while (length--) { + if (callback(collection[length], length, collection) === false) { + break; + } + } + } else { + if (typeof length != 'number') { + var props = keys(collection); + length = props.length; + } else if (support.unindexedChars && isString(collection)) { + iterable = collection.split(''); + } + baseEach(collection, function(value, key, collection) { + key = props ? props[--length] : --length; + return callback(iterable[key], key, collection); + }); + } + return collection; + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of a collection through the callback. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false` + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using "_.pluck" callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of the collection through the given callback. The corresponding + * value of each key is the last element responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keys = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keys, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Invokes the method named by `methodName` on each element in the `collection` + * returning an array of the results of each invoked method. Additional arguments + * will be provided to each invoked method. If `methodName` is a function it + * will be invoked for, and `this` bound to, each element in the `collection`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|string} methodName The name of the method to invoke or + * the function invoked per iteration. + * @param {...*} [arg] Arguments to invoke the method with. + * @returns {Array} Returns a new array of the results of each invoked method. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + function invoke(collection, methodName) { + var args = slice(arguments, 2), + index = -1, + isFunc = typeof methodName == 'function', + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); + }); + return result; + } + + /** + * Creates an array of values by running each element in the collection + * through the callback. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias collect + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of the results of each `callback` execution. + * @example + * + * _.map([1, 2, 3], function(num) { return num * 3; }); + * // => [3, 6, 9] + * + * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); + * // => [3, 6, 9] (property order is not guaranteed across environments) + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(characters, 'name'); + * // => ['barney', 'fred'] + */ + function map(collection, callback, thisArg) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + callback = lodash.createCallback(callback, thisArg, 3); + if (isArray(collection)) { + while (++index < length) { + result[index] = callback(collection[index], index, collection); + } + } else { + baseEach(collection, function(value, key, collection) { + result[++index] = callback(value, key, collection); + }); + } + return result; + } + + /** + * Retrieves the maximum value of a collection. If the collection is empty or + * falsey `-Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.max(characters, function(chr) { return chr.age; }); + * // => { 'name': 'fred', 'age': 40 }; + * + * // using "_.pluck" callback shorthand + * _.max(characters, 'age'); + * // => { 'name': 'fred', 'age': 40 }; + */ + function max(collection, callback, thisArg) { + var computed = -Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value > result) { + result = value; + } + } + } else { + callback = (callback == null && isString(collection)) + ? charAtCallback + : lodash.createCallback(callback, thisArg, 3); + + baseEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current > computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the minimum value of a collection. If the collection is empty or + * falsey `Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.min(characters, function(chr) { return chr.age; }); + * // => { 'name': 'barney', 'age': 36 }; + * + * // using "_.pluck" callback shorthand + * _.min(characters, 'age'); + * // => { 'name': 'barney', 'age': 36 }; + */ + function min(collection, callback, thisArg) { + var computed = Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value < result) { + result = value; + } + } + } else { + callback = (callback == null && isString(collection)) + ? charAtCallback + : lodash.createCallback(callback, thisArg, 3); + + baseEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current < computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the value of a specified property from all elements in the collection. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {string} property The name of the property to pluck. + * @returns {Array} Returns a new array of property values. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.pluck(characters, 'name'); + * // => ['barney', 'fred'] + */ + var pluck = map; + + /** + * Reduces a collection to a value which is the accumulated result of running + * each element in the collection through the callback, where each successive + * callback execution consumes the return value of the previous execution. If + * `accumulator` is not provided the first element of the collection will be + * used as the initial `accumulator` value. The callback is bound to `thisArg` + * and invoked with four arguments; (accumulator, value, index|key, collection). + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var sum = _.reduce([1, 2, 3], function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function reduce(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = lodash.createCallback(callback, thisArg, 4); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + if (noaccum) { + accumulator = collection[++index]; + } + while (++index < length) { + accumulator = callback(accumulator, collection[index], index, collection); + } + } else { + baseEach(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection) + }); + } + return accumulator; + } + + /** + * This method is like `_.reduce` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var list = [[0, 1], [2, 3], [4, 5]]; + * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + function reduceRight(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = lodash.createCallback(callback, thisArg, 4); + forEachRight(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The opposite of `_.filter` this method returns the elements of a + * collection that the callback does **not** return truey for. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that failed the callback check. + * @example + * + * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [1, 3, 5] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.reject(characters, 'blocked'); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + * + * // using "_.where" callback shorthand + * _.reject(characters, { 'age': 36 }); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + */ + function reject(collection, callback, thisArg) { + callback = lodash.createCallback(callback, thisArg, 3); + return filter(collection, function(value, index, collection) { + return !callback(value, index, collection); + }); + } + + /** + * Retrieves a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Allows working with functions like `_.map` + * without using their `index` arguments as `n`. + * @returns {Array} Returns the random sample(s) of `collection`. + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ + function sample(collection, n, guard) { + if (collection && typeof collection.length != 'number') { + collection = values(collection); + } else if (support.unindexedChars && isString(collection)) { + collection = collection.split(''); + } + if (n == null || guard) { + return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; + } + var result = shuffle(collection); + result.length = nativeMin(nativeMax(0, n), result.length); + return result; + } + + /** + * Creates an array of shuffled values, using a version of the Fisher-Yates + * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns a new shuffled collection. + * @example + * + * _.shuffle([1, 2, 3, 4, 5, 6]); + * // => [4, 1, 6, 3, 5, 2] + */ + function shuffle(collection) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + var rand = baseRandom(0, ++index); + result[index] = result[rand]; + result[rand] = value; + }); + return result; + } + + /** + * Gets the size of the `collection` by returning `collection.length` for arrays + * and array-like objects or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns `collection.length` or number of own enumerable properties. + * @example + * + * _.size([1, 2]); + * // => 2 + * + * _.size({ 'one': 1, 'two': 2, 'three': 3 }); + * // => 3 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + var length = collection ? collection.length : 0; + return typeof length == 'number' ? length : keys(collection).length; + } + + /** + * Checks if the callback returns a truey value for **any** element of a + * collection. The function returns as soon as it finds a passing value and + * does not iterate over the entire collection. The callback is bound to + * `thisArg` and invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if any element passed the callback check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.some(characters, 'blocked'); + * // => true + * + * // using "_.where" callback shorthand + * _.some(characters, { 'age': 1 }); + * // => false + */ + function some(collection, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if ((result = callback(collection[index], index, collection))) { + break; + } + } + } else { + baseEach(collection, function(value, index, collection) { + return !(result = callback(value, index, collection)); + }); + } + return !!result; + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through the callback. This method + * performs a stable sort, that is, it will preserve the original sort order + * of equal elements. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an array of property names is provided for `callback` the collection + * will be sorted by each property value. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of sorted elements. + * @example + * + * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); + * // => [3, 1, 2] + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 26 }, + * { 'name': 'fred', 'age': 30 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(_.sortBy(characters, 'age'), _.values); + * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] + * + * // sorting by multiple properties + * _.map(_.sortBy(characters, ['name', 'age']), _.values); + * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] + */ + function sortBy(collection, callback, thisArg) { + var index = -1, + isArr = isArray(callback), + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + if (!isArr) { + callback = lodash.createCallback(callback, thisArg, 3); + } + forEach(collection, function(value, key, collection) { + var object = result[++index] = getObject(); + if (isArr) { + object.criteria = map(callback, function(key) { return value[key]; }); + } else { + (object.criteria = getArray())[0] = callback(value, key, collection); + } + object.index = index; + object.value = value; + }); + + length = result.length; + result.sort(compareAscending); + while (length--) { + var object = result[length]; + result[length] = object.value; + if (!isArr) { + releaseArray(object.criteria); + } + releaseObject(object); + } + return result; + } + + /** + * Converts the `collection` to an array. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to convert. + * @returns {Array} Returns the new converted array. + * @example + * + * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); + * // => [2, 3, 4] + */ + function toArray(collection) { + if (collection && typeof collection.length == 'number') { + return (support.unindexedChars && isString(collection)) + ? collection.split('') + : slice(collection); + } + return values(collection); + } + + /** + * Performs a deep comparison of each element in a `collection` to the given + * `properties` object, returning an array of all elements that have equivalent + * property values. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Object} props The object of property values to filter by. + * @returns {Array} Returns a new array of elements that have the given properties. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.where(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] + * + * _.where(characters, { 'pets': ['dino'] }); + * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] + */ + var where = filter; + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are all falsey. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to compact. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result.push(value); + } + } + return result; + } + + /** + * Creates an array excluding all values of the provided arrays using strict + * equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to process. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); + * // => [1, 3, 4] + */ + function difference(array) { + return baseDifference(array, baseFlatten(arguments, true, true, 1)); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element that passes the callback check, instead of the element itself. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.findIndex(characters, function(chr) { + * return chr.age < 20; + * }); + * // => 2 + * + * // using "_.where" callback shorthand + * _.findIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findIndex(characters, 'blocked'); + * // => 1 + */ + function findIndex(array, callback, thisArg) { + var index = -1, + length = array ? array.length : 0; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length) { + if (callback(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of a `collection` from right to left. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': true }, + * { 'name': 'fred', 'age': 40, 'blocked': false }, + * { 'name': 'pebbles', 'age': 1, 'blocked': true } + * ]; + * + * _.findLastIndex(characters, function(chr) { + * return chr.age > 30; + * }); + * // => 1 + * + * // using "_.where" callback shorthand + * _.findLastIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findLastIndex(characters, 'blocked'); + * // => 2 + */ + function findLastIndex(array, callback, thisArg) { + var length = array ? array.length : 0; + callback = lodash.createCallback(callback, thisArg, 3); + while (length--) { + if (callback(array[length], length, array)) { + return length; + } + } + return -1; + } + + /** + * Gets the first element or first `n` elements of an array. If a callback + * is provided elements at the beginning of the array are returned as long + * as the callback returns truey. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias head, take + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the first element(s) of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([1, 2, 3], 2); + * // => [1, 2] + * + * _.first([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [1, 2] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.first(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); + * // => ['barney', 'fred'] + */ + function first(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = -1; + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[0] : undefined; + } + } + return slice(array, 0, nativeMin(nativeMax(0, n), length)); + } + + /** + * Flattens a nested array (the nesting can be to any depth). If `isShallow` + * is truey, the array will only be flattened a single level. If a callback + * is provided each element of the array is passed through the callback before + * flattening. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new flattened array. + * @example + * + * _.flatten([1, [2], [3, [[4]]]]); + * // => [1, 2, 3, 4]; + * + * _.flatten([1, [2], [3, [[4]]]], true); + * // => [1, 2, 3, [[4]]]; + * + * var characters = [ + * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * // using "_.pluck" callback shorthand + * _.flatten(characters, 'pets'); + * // => ['hoppy', 'baby puss', 'dino'] + */ + function flatten(array, isShallow, callback, thisArg) { + // juggle arguments + if (typeof isShallow != 'boolean' && isShallow != null) { + thisArg = callback; + callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; + isShallow = false; + } + if (callback != null) { + array = map(array, callback, thisArg); + } + return baseFlatten(array, isShallow); + } + + /** + * Gets the index at which the first occurrence of `value` is found using + * strict equality for comparisons, i.e. `===`. If the array is already sorted + * providing `true` for `fromIndex` will run a faster binary search. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2); + * // => 1 + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 4 + * + * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + if (typeof fromIndex == 'number') { + var length = array ? array.length : 0; + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); + } else if (fromIndex) { + var index = sortedIndex(array, value); + return array[index] === value ? index : -1; + } + return baseIndexOf(array, value, fromIndex); + } + + /** + * Gets all but the last element or last `n` elements of an array. If a + * callback is provided elements at the end of the array are excluded from + * the result as long as the callback returns truey. The callback is bound + * to `thisArg` and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + * + * _.initial([1, 2, 3], 2); + * // => [1] + * + * _.initial([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [1] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.initial(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); + * // => ['barney', 'fred'] + */ + function initial(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = lodash.createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : callback || n; + } + return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); + } + + /** + * Creates an array of unique values present in all provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of shared values. + * @example + * + * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2] + */ + function intersection() { + var args = [], + argsIndex = -1, + argsLength = arguments.length, + caches = getArray(), + indexOf = getIndexOf(), + trustIndexOf = indexOf === baseIndexOf, + seen = getArray(); + + while (++argsIndex < argsLength) { + var value = arguments[argsIndex]; + if (isArray(value) || isArguments(value)) { + args.push(value); + caches.push(trustIndexOf && value.length >= largeArraySize && + createCache(argsIndex ? args[argsIndex] : seen)); + } + } + var array = args[0], + index = -1, + length = array ? array.length : 0, + result = []; + + outer: + while (++index < length) { + var cache = caches[0]; + value = array[index]; + + if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) { + argsIndex = argsLength; + (cache || seen).push(value); + while (--argsIndex) { + cache = caches[argsIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { + continue outer; + } + } + result.push(value); + } + } + while (argsLength--) { + cache = caches[argsLength]; + if (cache) { + releaseObject(cache); + } + } + releaseArray(caches); + releaseArray(seen); + return result; + } + + /** + * Gets the last element or last `n` elements of an array. If a callback is + * provided elements at the end of the array are returned as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the last element(s) of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + * + * _.last([1, 2, 3], 2); + * // => [2, 3] + * + * _.last([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [2, 3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.last(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.last(characters, { 'employer': 'na' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function last(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = lodash.createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[length - 1] : undefined; + } + } + return slice(array, nativeMax(0, length - n)); + } + + /** + * Gets the index at which the last occurrence of `value` is found using strict + * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used + * as the offset from the end of the collection. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); + * // => 4 + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 1 + */ + function lastIndexOf(array, value, fromIndex) { + var index = array ? array.length : 0; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Removes all provided values from the given array using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to modify. + * @param {...*} [value] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ + function pull(array) { + var args = arguments, + argsIndex = 0, + argsLength = args.length, + length = array ? array.length : 0; + + while (++argsIndex < argsLength) { + var index = -1, + value = args[argsIndex]; + while (++index < length) { + if (array[index] === value) { + splice.call(array, index--, 1); + length--; + } + } + } + return array; + } + + /** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to but not including `end`. If `start` is less than `stop` a + * zero-length range is created unless a negative `step` is specified. + * + * @static + * @memberOf _ + * @category Arrays + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns a new range array. + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ + function range(start, end, step) { + start = +start || 0; + step = typeof step == 'number' ? step : (+step || 1); + + if (end == null) { + end = start; + start = 0; + } + // use `Array(length)` so engines like Chakra and V8 avoid slower modes + // http://youtu.be/XAqIpGU8ZZk#t=17m25s + var index = -1, + length = nativeMax(0, ceil((end - start) / (step || 1))), + result = Array(length); + + while (++index < length) { + result[index] = start; + start += step; + } + return result; + } + + /** + * Removes all elements from an array that the callback returns truey for + * and returns an array of removed elements. The callback is bound to `thisArg` + * and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to modify. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4, 5, 6]; + * var evens = _.remove(array, function(num) { return num % 2 == 0; }); + * + * console.log(array); + * // => [1, 3, 5] + * + * console.log(evens); + * // => [2, 4, 6] + */ + function remove(array, callback, thisArg) { + var index = -1, + length = array ? array.length : 0, + result = []; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (callback(value, index, array)) { + result.push(value); + splice.call(array, index--, 1); + length--; + } + } + return result; + } + + /** + * The opposite of `_.initial` this method gets all but the first element or + * first `n` elements of an array. If a callback function is provided elements + * at the beginning of the array are excluded from the result as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias drop, tail + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + * + * _.rest([1, 2, 3], 2); + * // => [3] + * + * _.rest([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.rest(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.rest(characters, { 'employer': 'slate' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function rest(array, callback, thisArg) { + if (typeof callback != 'number' && callback != null) { + var n = 0, + index = -1, + length = array ? array.length : 0; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); + } + return slice(array, n); + } + + /** + * Uses a binary search to determine the smallest index at which a value + * should be inserted into a given sorted array in order to maintain the sort + * order of the array. If a callback is provided it will be executed for + * `value` and each element of `array` to compute their sort ranking. The + * callback is bound to `thisArg` and invoked with one argument; (value). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([20, 30, 50], 40); + * // => 2 + * + * // using "_.pluck" callback shorthand + * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 2 + * + * var dict = { + * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } + * }; + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return dict.wordToNumber[word]; + * }); + * // => 2 + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return this.wordToNumber[word]; + * }, dict); + * // => 2 + */ + function sortedIndex(array, value, callback, thisArg) { + var low = 0, + high = array ? array.length : low; + + // explicitly reference `identity` for better inlining in Firefox + callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; + value = callback(value); + + while (low < high) { + var mid = (low + high) >>> 1; + (callback(array[mid]) < value) + ? low = mid + 1 + : high = mid; + } + return low; + } + + /** + * Creates an array of unique values, in order, of the provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of combined values. + * @example + * + * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2, 3, 5, 4] + */ + function union() { + return baseUniq(baseFlatten(arguments, true, true)); + } + + /** + * Creates a duplicate-value-free version of an array using strict equality + * for comparisons, i.e. `===`. If the array is sorted, providing + * `true` for `isSorted` will use a faster algorithm. If a callback is provided + * each element of `array` is passed through the callback before uniqueness + * is computed. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Arrays + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a duplicate-value-free array. + * @example + * + * _.uniq([1, 2, 1, 3, 1]); + * // => [1, 2, 3] + * + * _.uniq([1, 1, 2, 2, 3], true); + * // => [1, 2, 3] + * + * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); + * // => ['A', 'b', 'C'] + * + * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); + * // => [1, 2.5, 3] + * + * // using "_.pluck" callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniq(array, isSorted, callback, thisArg) { + // juggle arguments + if (typeof isSorted != 'boolean' && isSorted != null) { + thisArg = callback; + callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; + isSorted = false; + } + if (callback != null) { + callback = lodash.createCallback(callback, thisArg, 3); + } + return baseUniq(array, isSorted, callback); + } + + /** + * Creates an array excluding all provided values using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to filter. + * @param {...*} [value] The values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); + * // => [2, 3, 4] + */ + function without(array) { + return baseDifference(array, slice(arguments, 1)); + } + + /** + * Creates an array that is the symmetric difference of the provided arrays. + * See http://en.wikipedia.org/wiki/Symmetric_difference. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of values. + * @example + * + * _.xor([1, 2, 3], [5, 2, 1, 4]); + * // => [3, 5, 4] + * + * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); + * // => [1, 4, 5] + */ + function xor() { + var index = -1, + length = arguments.length; + + while (++index < length) { + var array = arguments[index]; + if (isArray(array) || isArguments(array)) { + var result = result + ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result))) + : array; + } + } + return result || []; + } + + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second + * elements of the given arrays, and so on. + * + * @static + * @memberOf _ + * @alias unzip + * @category Arrays + * @param {...Array} [array] Arrays to process. + * @returns {Array} Returns a new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + function zip() { + var array = arguments.length > 1 ? arguments : arguments[0], + index = -1, + length = array ? max(pluck(array, 'length')) : 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = pluck(array, index); + } + return result; + } + + /** + * Creates an object composed from arrays of `keys` and `values`. Provide + * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` + * or two arrays, one of `keys` and one of corresponding `values`. + * + * @static + * @memberOf _ + * @alias object + * @category Arrays + * @param {Array} keys The array of keys. + * @param {Array} [values=[]] The array of values. + * @returns {Object} Returns an object composed of the given keys and + * corresponding values. + * @example + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ + function zipObject(keys, values) { + var index = -1, + length = keys ? keys.length : 0, + result = {}; + + if (!values && length && !isArray(keys[0])) { + values = []; + } + while (++index < length) { + var key = keys[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that executes `func`, with the `this` binding and + * arguments of the created function, only after being called `n` times. + * + * @static + * @memberOf _ + * @category Functions + * @param {number} n The number of times the function must be called before + * `func` is executed. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('Done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'Done saving!', after all saves have completed + */ + function after(n, func) { + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that, when called, invokes `func` with the `this` + * binding of `thisArg` and prepends any additional `bind` arguments to those + * provided to the bound function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var func = function(greeting) { + * return greeting + ' ' + this.name; + * }; + * + * func = _.bind(func, { 'name': 'fred' }, 'hi'); + * func(); + * // => 'hi fred' + */ + function bind(func, thisArg) { + return arguments.length > 2 + ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) + : createWrapper(func, 1, null, null, thisArg); + } + + /** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all the function properties + * of `object` will be bound. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...string} [methodName] The object method names to + * bind, specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { console.log('clicked ' + this.label); } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs', when the button is clicked + */ + function bindAll(object) { + var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), + index = -1, + length = funcs.length; + + while (++index < length) { + var key = funcs[index]; + object[key] = createWrapper(object[key], 1, null, null, object); + } + return object; + } + + /** + * Creates a function that, when called, invokes the method at `object[key]` + * and prepends any additional `bindKey` arguments to those provided to the bound + * function. This method differs from `_.bind` by allowing bound functions to + * reference methods that will be redefined or don't yet exist. + * See http://michaux.ca/articles/lazy-function-definition-pattern. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'name': 'fred', + * 'greet': function(greeting) { + * return greeting + ' ' + this.name; + * } + * }; + * + * var func = _.bindKey(object, 'greet', 'hi'); + * func(); + * // => 'hi fred' + * + * object.greet = function(greeting) { + * return greeting + 'ya ' + this.name + '!'; + * }; + * + * func(); + * // => 'hiya fred!' + */ + function bindKey(object, key) { + return arguments.length > 2 + ? createWrapper(key, 19, slice(arguments, 2), null, object) + : createWrapper(key, 3, null, null, object); + } + + /** + * Creates a function that is the composition of the provided functions, + * where each function consumes the return value of the function that follows. + * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. + * Each function is executed with the `this` binding of the composed function. + * + * @static + * @memberOf _ + * @category Functions + * @param {...Function} [func] Functions to compose. + * @returns {Function} Returns the new composed function. + * @example + * + * var realNameMap = { + * 'pebbles': 'penelope' + * }; + * + * var format = function(name) { + * name = realNameMap[name.toLowerCase()] || name; + * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); + * }; + * + * var greet = function(formatted) { + * return 'Hiya ' + formatted + '!'; + * }; + * + * var welcome = _.compose(greet, format); + * welcome('pebbles'); + * // => 'Hiya Penelope!' + */ + function compose() { + var funcs = arguments, + length = funcs.length; + + while (length--) { + if (!isFunction(funcs[length])) { + throw new TypeError; + } + } + return function() { + var args = arguments, + length = funcs.length; + + while (length--) { + args = [funcs[length].apply(this, args)]; + } + return args[0]; + }; + } + + /** + * Creates a function which accepts one or more arguments of `func` that when + * invoked either executes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` can be specified + * if `func.length` is not sufficient. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @returns {Function} Returns the new curried function. + * @example + * + * var curried = _.curry(function(a, b, c) { + * console.log(a + b + c); + * }); + * + * curried(1)(2)(3); + * // => 6 + * + * curried(1, 2)(3); + * // => 6 + * + * curried(1, 2, 3); + * // => 6 + */ + function curry(func, arity) { + arity = typeof arity == 'number' ? arity : (+arity || func.length); + return createWrapper(func, 4, null, null, null, arity); + } + + /** + * Creates a function that will delay the execution of `func` until after + * `wait` milliseconds have elapsed since the last time it was invoked. + * Provide an options object to indicate that `func` should be invoked on + * the leading and/or trailing edge of the `wait` timeout. Subsequent calls + * to the debounced function will return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to debounce. + * @param {number} wait The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * var lazyLayout = _.debounce(calculateLayout, 150); + * jQuery(window).on('resize', lazyLayout); + * + * // execute `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * }); + * + * // ensure `batchLog` is executed once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * source.addEventListener('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * }, false); + */ + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + wait = nativeMax(0, wait) || 0; + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = options.leading; + maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0); + trailing = 'trailing' in options ? options.trailing : trailing; + } + var delayed = function() { + var remaining = wait - (now() - stamp); + if (remaining <= 0) { + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + var isCalled = trailingCall; + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + } else { + timeoutId = setTimeout(delayed, remaining); + } + }; + + var maxDelayed = function() { + if (timeoutId) { + clearTimeout(timeoutId); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (trailing || (maxWait !== wait)) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + }; + + return function() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + return result; + }; + } + + /** + * Defers executing the `func` function until the current call stack has cleared. + * Additional arguments will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to defer. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { console.log(text); }, 'deferred'); + * // logs 'deferred' after one or more milliseconds + */ + function defer(func) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 1); + return setTimeout(function() { func.apply(undefined, args); }, 1); + } + + /** + * Executes the `func` function after `wait` milliseconds. Additional arguments + * will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay execution. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { console.log(text); }, 1000, 'later'); + * // => logs 'later' after one second + */ + function delay(func, wait) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 2); + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it will be used to determine the cache key for storing the result + * based on the arguments provided to the memoized function. By default, the + * first argument provided to the memoized function is used as the cache key. + * The `func` is executed with the `this` binding of the memoized function. + * The result cache is exposed as the `cache` property on the memoized function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] A function used to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var fibonacci = _.memoize(function(n) { + * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); + * }); + * + * fibonacci(9) + * // => 34 + * + * var data = { + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * }; + * + * // modifying the result cache + * var get = _.memoize(function(name) { return data[name]; }, _.identity); + * get('pebbles'); + * // => { 'name': 'pebbles', 'age': 1 } + * + * get.cache.pebbles.name = 'penelope'; + * get('pebbles'); + * // => { 'name': 'penelope', 'age': 1 } + */ + function memoize(func, resolver) { + if (!isFunction(func)) { + throw new TypeError; + } + var memoized = function() { + var cache = memoized.cache, + key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0]; + + return hasOwnProperty.call(cache, key) + ? cache[key] + : (cache[key] = func.apply(this, arguments)); + } + memoized.cache = {}; + return memoized; + } + + /** + * Creates a function that is restricted to execute `func` once. Repeat calls to + * the function will return the value of the first call. The `func` is executed + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` executes `createApplication` once + */ + function once(func) { + var ran, + result; + + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (ran) { + return result; + } + ran = true; + result = func.apply(this, arguments); + + // clear the `func` variable so the function may be garbage collected + func = null; + return result; + }; + } + + /** + * Creates a function that, when called, invokes `func` with any additional + * `partial` arguments prepended to those provided to the new function. This + * method is similar to `_.bind` except it does **not** alter the `this` binding. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { return greeting + ' ' + name; }; + * var hi = _.partial(greet, 'hi'); + * hi('fred'); + * // => 'hi fred' + */ + function partial(func) { + return createWrapper(func, 16, slice(arguments, 1)); + } + + /** + * This method is like `_.partial` except that `partial` arguments are + * appended to those provided to the new function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var defaultsDeep = _.partialRight(_.merge, _.defaults); + * + * var options = { + * 'variable': 'data', + * 'imports': { 'jq': $ } + * }; + * + * defaultsDeep(options, _.templateSettings); + * + * options.variable + * // => 'data' + * + * options.imports + * // => { '_': _, 'jq': $ } + */ + function partialRight(func) { + return createWrapper(func, 32, null, slice(arguments, 1)); + } + + /** + * Creates a function that, when executed, will only call the `func` function + * at most once per every `wait` milliseconds. Provide an options object to + * indicate that `func` should be invoked on the leading and/or trailing edge + * of the `wait` timeout. Subsequent calls to the throttled function will + * return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to throttle. + * @param {number} wait The number of milliseconds to throttle executions to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // avoid excessively updating the position while scrolling + * var throttled = _.throttle(updatePosition, 100); + * jQuery(window).on('scroll', throttled); + * + * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? options.leading : leading; + trailing = 'trailing' in options ? options.trailing : trailing; + } + debounceOptions.leading = leading; + debounceOptions.maxWait = wait; + debounceOptions.trailing = trailing; + + return debounce(func, wait, debounceOptions); + } + + /** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Additional arguments provided to the function are appended + * to those provided to the wrapper function. The wrapper is executed with + * the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

' + func(text) + '

'; + * }); + * + * p('Fred, Wilma, & Pebbles'); + * // => '

Fred, Wilma, & Pebbles

' + */ + function wrap(value, wrapper) { + return createWrapper(wrapper, 16, [value]); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new function. + * @example + * + * var object = { 'name': 'fred' }; + * var getter = _.constant(object); + * getter() === object; + * // => true + */ + function constant(value) { + return function() { + return value; + }; + } + + /** + * Produces a callback bound to an optional `thisArg`. If `func` is a property + * name the created callback will return the property value for a given element. + * If `func` is an object the created callback will return `true` for elements + * that contain the equivalent object properties, otherwise it will return `false`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // wrap to create custom callback shorthands + * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { + * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); + * return !match ? func(callback, thisArg) : function(object) { + * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; + * }; + * }); + * + * _.filter(characters, 'age__gt38'); + * // => [{ 'name': 'fred', 'age': 40 }] + */ + function createCallback(func, thisArg, argCount) { + var type = typeof func; + if (func == null || type == 'function') { + return baseCreateCallback(func, thisArg, argCount); + } + // handle "_.pluck" style callback shorthands + if (type != 'object') { + return property(func); + } + var props = keys(func), + key = props[0], + a = func[key]; + + // handle "_.where" style callback shorthands + if (props.length == 1 && a === a && !isObject(a)) { + // fast path the common case of providing an object with a single + // property containing a primitive value + return function(object) { + var b = object[key]; + return a === b && (a !== 0 || (1 / a == 1 / b)); + }; + } + return function(object) { + var length = props.length, + result = false; + + while (length--) { + if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { + break; + } + } + return result; + }; + } + + /** + * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their + * corresponding HTML entities. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} string The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('Fred, Wilma, & Pebbles'); + * // => 'Fred, Wilma, & Pebbles' + */ + function escape(string) { + return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); + } + + /** + * This method returns the first argument provided to it. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'name': 'fred' }; + * _.identity(object) === object; + * // => true + */ + function identity(value) { + return value; + } + + /** + * Adds function properties of a source object to the destination object. + * If `object` is a function methods will be added to its prototype as well. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Function|Object} [object=lodash] object The destination object. + * @param {Object} source The object of functions to add. + * @param {Object} [options] The options object. + * @param {boolean} [options.chain=true] Specify whether the functions added are chainable. + * @example + * + * function capitalize(string) { + * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); + * } + * + * _.mixin({ 'capitalize': capitalize }); + * _.capitalize('fred'); + * // => 'Fred' + * + * _('fred').capitalize().value(); + * // => 'Fred' + * + * _.mixin({ 'capitalize': capitalize }, { 'chain': false }); + * _('fred').capitalize(); + * // => 'Fred' + */ + function mixin(object, source, options) { + var chain = true, + methodNames = source && functions(source); + + if (!source || (!options && !methodNames.length)) { + if (options == null) { + options = source; + } + ctor = lodashWrapper; + source = object; + object = lodash; + methodNames = functions(source); + } + if (options === false) { + chain = false; + } else if (isObject(options) && 'chain' in options) { + chain = options.chain; + } + var ctor = object, + isFunc = isFunction(ctor); + + forEach(methodNames, function(methodName) { + var func = object[methodName] = source[methodName]; + if (isFunc) { + ctor.prototype[methodName] = function() { + var chainAll = this.__chain__, + value = this.__wrapped__, + args = [value]; + + push.apply(args, arguments); + var result = func.apply(object, args); + if (chain || chainAll) { + if (value === result && isObject(result)) { + return this; + } + result = new ctor(result); + result.__chain__ = chainAll; + } + return result; + }; + } + }); + } + + /** + * Reverts the '_' variable to its previous value and returns a reference to + * the `lodash` function. + * + * @static + * @memberOf _ + * @category Utilities + * @returns {Function} Returns the `lodash` function. + * @example + * + * var lodash = _.noConflict(); + */ + function noConflict() { + context._ = oldDash; + return this; + } + + /** + * A no-operation function. + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var object = { 'name': 'fred' }; + * _.noop(object) === undefined; + * // => true + */ + function noop() { + // no operation performed + } + + /** + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var stamp = _.now(); + * _.defer(function() { console.log(_.now() - stamp); }); + * // => logs the number of milliseconds it took for the deferred function to be called + */ + var now = isNative(now = Date.now) && now || function() { + return new Date().getTime(); + }; + + /** + * Converts the given value into an integer of the specified radix. + * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the + * `value` is a hexadecimal, in which case a `radix` of `16` is used. + * + * Note: This method avoids differences in native ES3 and ES5 `parseInt` + * implementations. See http://es5.github.io/#E. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} value The value to parse. + * @param {number} [radix] The radix used to interpret the value to parse. + * @returns {number} Returns the new integer value. + * @example + * + * _.parseInt('08'); + * // => 8 + */ + var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) { + // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt` + return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0); + }; + + /** + * Creates a "_.pluck" style function, which returns the `key` value of a + * given object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} key The name of the property to retrieve. + * @returns {Function} Returns the new function. + * @example + * + * var characters = [ + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 36 } + * ]; + * + * var getName = _.property('name'); + * + * _.map(characters, getName); + * // => ['barney', 'fred'] + * + * _.sortBy(characters, getName); + * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] + */ + function property(key) { + return function(object) { + return object[key]; + }; + } + + /** + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is provided a number between `0` and the given number will be + * returned. If `floating` is truey or either `min` or `max` are floats a + * floating-point number will be returned instead of an integer. + * + * @static + * @memberOf _ + * @category Utilities + * @param {number} [min=0] The minimum possible value. + * @param {number} [max=1] The maximum possible value. + * @param {boolean} [floating=false] Specify returning a floating-point number. + * @returns {number} Returns a random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(min, max, floating) { + var noMin = min == null, + noMax = max == null; + + if (floating == null) { + if (typeof min == 'boolean' && noMax) { + floating = min; + min = 1; + } + else if (!noMax && typeof max == 'boolean') { + floating = max; + noMax = true; + } + } + if (noMin && noMax) { + max = 1; + } + min = +min || 0; + if (noMax) { + max = min; + min = 0; + } else { + max = +max || 0; + } + if (floating || min % 1 || max % 1) { + var rand = nativeRandom(); + return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max); + } + return baseRandom(min, max); + } + + /** + * Resolves the value of property `key` on `object`. If `key` is a function + * it will be invoked with the `this` binding of `object` and its result returned, + * else the property value is returned. If `object` is falsey then `undefined` + * is returned. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to resolve. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { + * 'cheese': 'crumpets', + * 'stuff': function() { + * return 'nonsense'; + * } + * }; + * + * _.result(object, 'cheese'); + * // => 'crumpets' + * + * _.result(object, 'stuff'); + * // => 'nonsense' + */ + function result(object, key) { + if (object) { + var value = object[key]; + return isFunction(value) ? object[key]() : value; + } + } + + /** + * A micro-templating method that handles arbitrary delimiters, preserves + * whitespace, and correctly escapes quotes within interpolated code. + * + * Note: In the development build, `_.template` utilizes sourceURLs for easier + * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl + * + * For more information on precompiling templates see: + * https://lodash.com/custom-builds + * + * For more information on Chrome extension sandboxes see: + * http://developer.chrome.com/stable/extensions/sandboxingEval.html + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} text The template text. + * @param {Object} data The data object used to populate the text. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as local variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [sourceURL] The sourceURL of the template's compiled source. + * @param {string} [variable] The data object variable name. + * @returns {Function|string} Returns a compiled function when no `data` object + * is given, else it returns the interpolated text. + * @example + * + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= name %>'); + * compiled({ 'name': 'fred' }); + * // => 'hello fred' + * + * // using the "escape" delimiter to escape HTML in data property values + * _.template('<%- value %>', { 'value': ' + +``` + +## Documentation + +### Collections + +* [`each`](#each) +* [`eachSeries`](#eachSeries) +* [`eachLimit`](#eachLimit) +* [`map`](#map) +* [`mapSeries`](#mapSeries) +* [`mapLimit`](#mapLimit) +* [`filter`](#filter) +* [`filterSeries`](#filterSeries) +* [`reject`](#reject) +* [`rejectSeries`](#rejectSeries) +* [`reduce`](#reduce) +* [`reduceRight`](#reduceRight) +* [`detect`](#detect) +* [`detectSeries`](#detectSeries) +* [`sortBy`](#sortBy) +* [`some`](#some) +* [`every`](#every) +* [`concat`](#concat) +* [`concatSeries`](#concatSeries) + +### Control Flow + +* [`series`](#seriestasks-callback) +* [`parallel`](#parallel) +* [`parallelLimit`](#parallellimittasks-limit-callback) +* [`whilst`](#whilst) +* [`doWhilst`](#doWhilst) +* [`until`](#until) +* [`doUntil`](#doUntil) +* [`forever`](#forever) +* [`waterfall`](#waterfall) +* [`compose`](#compose) +* [`seq`](#seq) +* [`applyEach`](#applyEach) +* [`applyEachSeries`](#applyEachSeries) +* [`queue`](#queue) +* [`priorityQueue`](#priorityQueue) +* [`cargo`](#cargo) +* [`auto`](#auto) +* [`retry`](#retry) +* [`iterator`](#iterator) +* [`apply`](#apply) +* [`nextTick`](#nextTick) +* [`times`](#times) +* [`timesSeries`](#timesSeries) + +### Utils + +* [`memoize`](#memoize) +* [`unmemoize`](#unmemoize) +* [`log`](#log) +* [`dir`](#dir) +* [`noConflict`](#noConflict) + + +## Collections + +
+ +### each(arr, iterator, callback) + +Applies the function `iterator` to each item in `arr`, in parallel. +The `iterator` is called with an item from the list, and a callback for when it +has finished. If the `iterator` passes an error to its `callback`, the main +`callback` (for the `each` function) is immediately called with the error. + +Note, that since this function applies `iterator` to each item in parallel, +there is no guarantee that the iterator functions will complete in order. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err)` which must be called once it has + completed. If no error has occurred, the `callback` should be run without + arguments or with an explicit `null` argument. +* `callback(err)` - A callback which is called when all `iterator` functions + have finished, or an error occurs. + +__Examples__ + + +```js +// assuming openFiles is an array of file names and saveFile is a function +// to save the modified contents of that file: + +async.each(openFiles, saveFile, function(err){ + // if any of the saves produced an error, err would equal that error +}); +``` + +```js +// assuming openFiles is an array of file names + +async.each(openFiles, function(file, callback) { + + // Perform operation on file here. + console.log('Processing file ' + file); + + if( file.length > 32 ) { + console.log('This file name is too long'); + callback('File name too long'); + } else { + // Do work to process file here + console.log('File processed'); + callback(); + } +}, function(err){ + // if any of the file processing produced an error, err would equal that error + if( err ) { + // One of the iterations produced an error. + // All processing will now stop. + console.log('A file failed to process'); + } else { + console.log('All files have been processed successfully'); + } +}); +``` + +--------------------------------------- + + + +### eachSeries(arr, iterator, callback) + +The same as [`each`](#each), only `iterator` is applied to each item in `arr` in +series. The next `iterator` is only called once the current one has completed. +This means the `iterator` functions will complete in order. + + +--------------------------------------- + + + +### eachLimit(arr, limit, iterator, callback) + +The same as [`each`](#each), only no more than `limit` `iterator`s will be simultaneously +running at any time. + +Note that the items in `arr` are not processed in batches, so there is no guarantee that +the first `limit` `iterator` functions will complete before any others are started. + +__Arguments__ + +* `arr` - An array to iterate over. +* `limit` - The maximum number of `iterator`s to run at any time. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err)` which must be called once it has + completed. If no error has occurred, the callback should be run without + arguments or with an explicit `null` argument. +* `callback(err)` - A callback which is called when all `iterator` functions + have finished, or an error occurs. + +__Example__ + +```js +// Assume documents is an array of JSON objects and requestApi is a +// function that interacts with a rate-limited REST api. + +async.eachLimit(documents, 20, requestApi, function(err){ + // if any of the saves produced an error, err would equal that error +}); +``` + +--------------------------------------- + + +### map(arr, iterator, callback) + +Produces a new array of values by mapping each value in `arr` through +the `iterator` function. The `iterator` is called with an item from `arr` and a +callback for when it has finished processing. Each of these callback takes 2 arguments: +an `error`, and the transformed item from `arr`. If `iterator` passes an error to his +callback, the main `callback` (for the `map` function) is immediately called with the error. + +Note, that since this function applies the `iterator` to each item in parallel, +there is no guarantee that the `iterator` functions will complete in order. +However, the results array will be in the same order as the original `arr`. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err, transformed)` which must be called once + it has completed with an error (which can be `null`) and a transformed item. +* `callback(err, results)` - A callback which is called when all `iterator` + functions have finished, or an error occurs. Results is an array of the + transformed items from the `arr`. + +__Example__ + +```js +async.map(['file1','file2','file3'], fs.stat, function(err, results){ + // results is now an array of stats for each file +}); +``` + +--------------------------------------- + + +### mapSeries(arr, iterator, callback) + +The same as [`map`](#map), only the `iterator` is applied to each item in `arr` in +series. The next `iterator` is only called once the current one has completed. +The results array will be in the same order as the original. + + +--------------------------------------- + + +### mapLimit(arr, limit, iterator, callback) + +The same as [`map`](#map), only no more than `limit` `iterator`s will be simultaneously +running at any time. + +Note that the items are not processed in batches, so there is no guarantee that +the first `limit` `iterator` functions will complete before any others are started. + +__Arguments__ + +* `arr` - An array to iterate over. +* `limit` - The maximum number of `iterator`s to run at any time. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err, transformed)` which must be called once + it has completed with an error (which can be `null`) and a transformed item. +* `callback(err, results)` - A callback which is called when all `iterator` + calls have finished, or an error occurs. The result is an array of the + transformed items from the original `arr`. + +__Example__ + +```js +async.mapLimit(['file1','file2','file3'], 1, fs.stat, function(err, results){ + // results is now an array of stats for each file +}); +``` + +--------------------------------------- + + + +### filter(arr, iterator, callback) + +__Alias:__ `select` + +Returns a new array of all the values in `arr` which pass an async truth test. +_The callback for each `iterator` call only accepts a single argument of `true` or +`false`; it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like `fs.exists`. This operation is +performed in parallel, but the results array will be in the same order as the +original. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in `arr`. + The `iterator` is passed a `callback(truthValue)`, which must be called with a + boolean argument once it has completed. +* `callback(results)` - A callback which is called after all the `iterator` + functions have finished. + +__Example__ + +```js +async.filter(['file1','file2','file3'], fs.exists, function(results){ + // results now equals an array of the existing files +}); +``` + +--------------------------------------- + + + +### filterSeries(arr, iterator, callback) + +__Alias:__ `selectSeries` + +The same as [`filter`](#filter) only the `iterator` is applied to each item in `arr` in +series. The next `iterator` is only called once the current one has completed. +The results array will be in the same order as the original. + +--------------------------------------- + + +### reject(arr, iterator, callback) + +The opposite of [`filter`](#filter). Removes values that pass an `async` truth test. + +--------------------------------------- + + +### rejectSeries(arr, iterator, callback) + +The same as [`reject`](#reject), only the `iterator` is applied to each item in `arr` +in series. + + +--------------------------------------- + + +### reduce(arr, memo, iterator, callback) + +__Aliases:__ `inject`, `foldl` + +Reduces `arr` into a single value using an async `iterator` to return +each successive step. `memo` is the initial state of the reduction. +This function only operates in series. + +For performance reasons, it may make sense to split a call to this function into +a parallel map, and then use the normal `Array.prototype.reduce` on the results. +This function is for situations where each step in the reduction needs to be async; +if you can get the data before reducing it, then it's probably a good idea to do so. + +__Arguments__ + +* `arr` - An array to iterate over. +* `memo` - The initial state of the reduction. +* `iterator(memo, item, callback)` - A function applied to each item in the + array to produce the next step in the reduction. The `iterator` is passed a + `callback(err, reduction)` which accepts an optional error as its first + argument, and the state of the reduction as the second. If an error is + passed to the callback, the reduction is stopped and the main `callback` is + immediately called with the error. +* `callback(err, result)` - A callback which is called after all the `iterator` + functions have finished. Result is the reduced value. + +__Example__ + +```js +async.reduce([1,2,3], 0, function(memo, item, callback){ + // pointless async: + process.nextTick(function(){ + callback(null, memo + item) + }); +}, function(err, result){ + // result is now equal to the last value of memo, which is 6 +}); +``` + +--------------------------------------- + + +### reduceRight(arr, memo, iterator, callback) + +__Alias:__ `foldr` + +Same as [`reduce`](#reduce), only operates on `arr` in reverse order. + + +--------------------------------------- + + +### detect(arr, iterator, callback) + +Returns the first value in `arr` that passes an async truth test. The +`iterator` is applied in parallel, meaning the first iterator to return `true` will +fire the detect `callback` with that result. That means the result might not be +the first item in the original `arr` (in terms of order) that passes the test. + +If order within the original `arr` is important, then look at [`detectSeries`](#detectSeries). + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in `arr`. + The iterator is passed a `callback(truthValue)` which must be called with a + boolean argument once it has completed. +* `callback(result)` - A callback which is called as soon as any iterator returns + `true`, or after all the `iterator` functions have finished. Result will be + the first item in the array that passes the truth test (iterator) or the + value `undefined` if none passed. + +__Example__ + +```js +async.detect(['file1','file2','file3'], fs.exists, function(result){ + // result now equals the first file in the list that exists +}); +``` + +--------------------------------------- + + +### detectSeries(arr, iterator, callback) + +The same as [`detect`](#detect), only the `iterator` is applied to each item in `arr` +in series. This means the result is always the first in the original `arr` (in +terms of array order) that passes the truth test. + + +--------------------------------------- + + +### sortBy(arr, iterator, callback) + +Sorts a list by the results of running each `arr` value through an async `iterator`. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err, sortValue)` which must be called once it + has completed with an error (which can be `null`) and a value to use as the sort + criteria. +* `callback(err, results)` - A callback which is called after all the `iterator` + functions have finished, or an error occurs. Results is the items from + the original `arr` sorted by the values returned by the `iterator` calls. + +__Example__ + +```js +async.sortBy(['file1','file2','file3'], function(file, callback){ + fs.stat(file, function(err, stats){ + callback(err, stats.mtime); + }); +}, function(err, results){ + // results is now the original array of files sorted by + // modified date +}); +``` + +__Sort Order__ + +By modifying the callback parameter the sorting order can be influenced: + +```js +//ascending order +async.sortBy([1,9,3,5], function(x, callback){ + callback(null, x); +}, function(err,result){ + //result callback +} ); + +//descending order +async.sortBy([1,9,3,5], function(x, callback){ + callback(null, x*-1); //<- x*-1 instead of x, turns the order around +}, function(err,result){ + //result callback +} ); +``` + +--------------------------------------- + + +### some(arr, iterator, callback) + +__Alias:__ `any` + +Returns `true` if at least one element in the `arr` satisfies an async test. +_The callback for each iterator call only accepts a single argument of `true` or +`false`; it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like `fs.exists`. Once any iterator +call returns `true`, the main `callback` is immediately called. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in the array + in parallel. The iterator is passed a callback(truthValue) which must be + called with a boolean argument once it has completed. +* `callback(result)` - A callback which is called as soon as any iterator returns + `true`, or after all the iterator functions have finished. Result will be + either `true` or `false` depending on the values of the async tests. + +__Example__ + +```js +async.some(['file1','file2','file3'], fs.exists, function(result){ + // if result is true then at least one of the files exists +}); +``` + +--------------------------------------- + + +### every(arr, iterator, callback) + +__Alias:__ `all` + +Returns `true` if every element in `arr` satisfies an async test. +_The callback for each `iterator` call only accepts a single argument of `true` or +`false`; it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like `fs.exists`. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in the array + in parallel. The iterator is passed a callback(truthValue) which must be + called with a boolean argument once it has completed. +* `callback(result)` - A callback which is called after all the `iterator` + functions have finished. Result will be either `true` or `false` depending on + the values of the async tests. + +__Example__ + +```js +async.every(['file1','file2','file3'], fs.exists, function(result){ + // if result is true then every file exists +}); +``` + +--------------------------------------- + + +### concat(arr, iterator, callback) + +Applies `iterator` to each item in `arr`, concatenating the results. Returns the +concatenated list. The `iterator`s are called in parallel, and the results are +concatenated as they return. There is no guarantee that the results array will +be returned in the original order of `arr` passed to the `iterator` function. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err, results)` which must be called once it + has completed with an error (which can be `null`) and an array of results. +* `callback(err, results)` - A callback which is called after all the `iterator` + functions have finished, or an error occurs. Results is an array containing + the concatenated results of the `iterator` function. + +__Example__ + +```js +async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){ + // files is now a list of filenames that exist in the 3 directories +}); +``` + +--------------------------------------- + + +### concatSeries(arr, iterator, callback) + +Same as [`concat`](#concat), but executes in series instead of parallel. + + +## Control Flow + + +### series(tasks, [callback]) + +Run the functions in the `tasks` array in series, each one running once the previous +function has completed. If any functions in the series pass an error to its +callback, no more functions are run, and `callback` is immediately called with the value of the error. +Otherwise, `callback` receives an array of results when `tasks` have completed. + +It is also possible to use an object instead of an array. Each property will be +run as a function, and the results will be passed to the final `callback` as an object +instead of an array. This can be a more readable way of handling results from +[`series`](#series). + +**Note** that while many implementations preserve the order of object properties, the +[ECMAScript Language Specifcation](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) +explicitly states that + +> The mechanics and order of enumerating the properties is not specified. + +So if you rely on the order in which your series of functions are executed, and want +this to work on all platforms, consider using an array. + +__Arguments__ + +* `tasks` - An array or object containing functions to run, each function is passed + a `callback(err, result)` it must call on completion with an error `err` (which can + be `null`) and an optional `result` value. +* `callback(err, results)` - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the `task` callbacks. + +__Example__ + +```js +async.series([ + function(callback){ + // do some stuff ... + callback(null, 'one'); + }, + function(callback){ + // do some more stuff ... + callback(null, 'two'); + } +], +// optional callback +function(err, results){ + // results is now equal to ['one', 'two'] +}); + + +// an example using an object instead of an array +async.series({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + } +}, +function(err, results) { + // results is now equal to: {one: 1, two: 2} +}); +``` + +--------------------------------------- + + +### parallel(tasks, [callback]) + +Run the `tasks` array of functions in parallel, without waiting until the previous +function has completed. If any of the functions pass an error to its +callback, the main `callback` is immediately called with the value of the error. +Once the `tasks` have completed, the results are passed to the final `callback` as an +array. + +It is also possible to use an object instead of an array. Each property will be +run as a function and the results will be passed to the final `callback` as an object +instead of an array. This can be a more readable way of handling results from +[`parallel`](#parallel). + + +__Arguments__ + +* `tasks` - An array or object containing functions to run. Each function is passed + a `callback(err, result)` which it must call on completion with an error `err` + (which can be `null`) and an optional `result` value. +* `callback(err, results)` - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the task callbacks. + +__Example__ + +```js +async.parallel([ + function(callback){ + setTimeout(function(){ + callback(null, 'one'); + }, 200); + }, + function(callback){ + setTimeout(function(){ + callback(null, 'two'); + }, 100); + } +], +// optional callback +function(err, results){ + // the results array will equal ['one','two'] even though + // the second function had a shorter timeout. +}); + + +// an example using an object instead of an array +async.parallel({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + } +}, +function(err, results) { + // results is now equals to: {one: 1, two: 2} +}); +``` + +--------------------------------------- + + +### parallelLimit(tasks, limit, [callback]) + +The same as [`parallel`](#parallel), only `tasks` are executed in parallel +with a maximum of `limit` tasks executing at any time. + +Note that the `tasks` are not executed in batches, so there is no guarantee that +the first `limit` tasks will complete before any others are started. + +__Arguments__ + +* `tasks` - An array or object containing functions to run, each function is passed + a `callback(err, result)` it must call on completion with an error `err` (which can + be `null`) and an optional `result` value. +* `limit` - The maximum number of `tasks` to run at any time. +* `callback(err, results)` - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the `task` callbacks. + +--------------------------------------- + + +### whilst(test, fn, callback) + +Repeatedly call `fn`, while `test` returns `true`. Calls `callback` when stopped, +or an error occurs. + +__Arguments__ + +* `test()` - synchronous truth test to perform before each execution of `fn`. +* `fn(callback)` - A function which is called each time `test` passes. The function is + passed a `callback(err)`, which must be called once it has completed with an + optional `err` argument. +* `callback(err)` - A callback which is called after the test fails and repeated + execution of `fn` has stopped. + +__Example__ + +```js +var count = 0; + +async.whilst( + function () { return count < 5; }, + function (callback) { + count++; + setTimeout(callback, 1000); + }, + function (err) { + // 5 seconds have passed + } +); +``` + +--------------------------------------- + + +### doWhilst(fn, test, callback) + +The post-check version of [`whilst`](#whilst). To reflect the difference in +the order of operations, the arguments `test` and `fn` are switched. + +`doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. + +--------------------------------------- + + +### until(test, fn, callback) + +Repeatedly call `fn` until `test` returns `true`. Calls `callback` when stopped, +or an error occurs. + +The inverse of [`whilst`](#whilst). + +--------------------------------------- + + +### doUntil(fn, test, callback) + +Like [`doWhilst`](#doWhilst), except the `test` is inverted. Note the argument ordering differs from `until`. + +--------------------------------------- + + +### forever(fn, errback) + +Calls the asynchronous function `fn` with a callback parameter that allows it to +call itself again, in series, indefinitely. + +If an error is passed to the callback then `errback` is called with the +error, and execution stops, otherwise it will never be called. + +```js +async.forever( + function(next) { + // next is suitable for passing to things that need a callback(err [, whatever]); + // it will result in this function being called again. + }, + function(err) { + // if next is called with a value in its first parameter, it will appear + // in here as 'err', and execution will stop. + } +); +``` + +--------------------------------------- + + +### waterfall(tasks, [callback]) + +Runs the `tasks` array of functions in series, each passing their results to the next in +the array. However, if any of the `tasks` pass an error to their own callback, the +next function is not executed, and the main `callback` is immediately called with +the error. + +__Arguments__ + +* `tasks` - An array of functions to run, each function is passed a + `callback(err, result1, result2, ...)` it must call on completion. The first + argument is an error (which can be `null`) and any further arguments will be + passed as arguments in order to the next task. +* `callback(err, [results])` - An optional callback to run once all the functions + have completed. This will be passed the results of the last task's callback. + + + +__Example__ + +```js +async.waterfall([ + function(callback) { + callback(null, 'one', 'two'); + }, + function(arg1, arg2, callback) { + // arg1 now equals 'one' and arg2 now equals 'two' + callback(null, 'three'); + }, + function(arg1, callback) { + // arg1 now equals 'three' + callback(null, 'done'); + } +], function (err, result) { + // result now equals 'done' +}); +``` + +--------------------------------------- + +### compose(fn1, fn2...) + +Creates a function which is a composition of the passed asynchronous +functions. Each function consumes the return value of the function that +follows. Composing functions `f()`, `g()`, and `h()` would produce the result of +`f(g(h()))`, only this version uses callbacks to obtain the return values. + +Each function is executed with the `this` binding of the composed function. + +__Arguments__ + +* `functions...` - the asynchronous functions to compose + + +__Example__ + +```js +function add1(n, callback) { + setTimeout(function () { + callback(null, n + 1); + }, 10); +} + +function mul3(n, callback) { + setTimeout(function () { + callback(null, n * 3); + }, 10); +} + +var add1mul3 = async.compose(mul3, add1); + +add1mul3(4, function (err, result) { + // result now equals 15 +}); +``` + +--------------------------------------- + +### seq(fn1, fn2...) + +Version of the compose function that is more natural to read. +Each function consumes the return value of the previous function. +It is the equivalent of [`compose`](#compose) with the arguments reversed. + +Each function is executed with the `this` binding of the composed function. + +__Arguments__ + +* functions... - the asynchronous functions to compose + + +__Example__ + +```js +// Requires lodash (or underscore), express3 and dresende's orm2. +// Part of an app, that fetches cats of the logged user. +// This example uses `seq` function to avoid overnesting and error +// handling clutter. +app.get('/cats', function(request, response) { + var User = request.models.User; + async.seq( + _.bind(User.get, User), // 'User.get' has signature (id, callback(err, data)) + function(user, fn) { + user.getCats(fn); // 'getCats' has signature (callback(err, data)) + } + )(req.session.user_id, function (err, cats) { + if (err) { + console.error(err); + response.json({ status: 'error', message: err.message }); + } else { + response.json({ status: 'ok', message: 'Cats found', data: cats }); + } + }); +}); +``` + +--------------------------------------- + +### applyEach(fns, args..., callback) + +Applies the provided arguments to each function in the array, calling +`callback` after all functions have completed. If you only provide the first +argument, then it will return a function which lets you pass in the +arguments as if it were a single function call. + +__Arguments__ + +* `fns` - the asynchronous functions to all call with the same arguments +* `args...` - any number of separate arguments to pass to the function +* `callback` - the final argument should be the callback, called when all + functions have completed processing + + +__Example__ + +```js +async.applyEach([enableSearch, updateSchema], 'bucket', callback); + +// partial application example: +async.each( + buckets, + async.applyEach([enableSearch, updateSchema]), + callback +); +``` + +--------------------------------------- + + +### applyEachSeries(arr, iterator, callback) + +The same as [`applyEach`](#applyEach) only the functions are applied in series. + +--------------------------------------- + + +### queue(worker, concurrency) + +Creates a `queue` object with the specified `concurrency`. Tasks added to the +`queue` are processed in parallel (up to the `concurrency` limit). If all +`worker`s are in progress, the task is queued until one becomes available. +Once a `worker` completes a `task`, that `task`'s callback is called. + +__Arguments__ + +* `worker(task, callback)` - An asynchronous function for processing a queued + task, which must call its `callback(err)` argument when finished, with an + optional `error` as an argument. +* `concurrency` - An `integer` for determining how many `worker` functions should be + run in parallel. + +__Queue objects__ + +The `queue` object returned by this function has the following properties and +methods: + +* `length()` - a function returning the number of items waiting to be processed. +* `started` - a function returning whether or not any items have been pushed and processed by the queue +* `running()` - a function returning the number of items currently being processed. +* `idle()` - a function returning false if there are items waiting or being processed, or true if not. +* `concurrency` - an integer for determining how many `worker` functions should be + run in parallel. This property can be changed after a `queue` is created to + alter the concurrency on-the-fly. +* `push(task, [callback])` - add a new task to the `queue`. Calls `callback` once + the `worker` has finished processing the task. Instead of a single task, a `tasks` array + can be submitted. The respective callback is used for every task in the list. +* `unshift(task, [callback])` - add a new task to the front of the `queue`. +* `saturated` - a callback that is called when the `queue` length hits the `concurrency` limit, + and further tasks will be queued. +* `empty` - a callback that is called when the last item from the `queue` is given to a `worker`. +* `drain` - a callback that is called when the last item from the `queue` has returned from the `worker`. +* `paused` - a boolean for determining whether the queue is in a paused state +* `pause()` - a function that pauses the processing of tasks until `resume()` is called. +* `resume()` - a function that resumes the processing of queued tasks when the queue is paused. +* `kill()` - a function that removes the `drain` callback and empties remaining tasks from the queue forcing it to go idle. + +__Example__ + +```js +// create a queue object with concurrency 2 + +var q = async.queue(function (task, callback) { + console.log('hello ' + task.name); + callback(); +}, 2); + + +// assign a callback +q.drain = function() { + console.log('all items have been processed'); +} + +// add some items to the queue + +q.push({name: 'foo'}, function (err) { + console.log('finished processing foo'); +}); +q.push({name: 'bar'}, function (err) { + console.log('finished processing bar'); +}); + +// add some items to the queue (batch-wise) + +q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) { + console.log('finished processing item'); +}); + +// add some items to the front of the queue + +q.unshift({name: 'bar'}, function (err) { + console.log('finished processing bar'); +}); +``` + + +--------------------------------------- + + +### priorityQueue(worker, concurrency) + +The same as [`queue`](#queue) only tasks are assigned a priority and completed in ascending priority order. There are two differences between `queue` and `priorityQueue` objects: + +* `push(task, priority, [callback])` - `priority` should be a number. If an array of + `tasks` is given, all tasks will be assigned the same priority. +* The `unshift` method was removed. + +--------------------------------------- + + +### cargo(worker, [payload]) + +Creates a `cargo` object with the specified payload. Tasks added to the +cargo will be processed altogether (up to the `payload` limit). If the +`worker` is in progress, the task is queued until it becomes available. Once +the `worker` has completed some tasks, each callback of those tasks is called. +Check out [this animation](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) for how `cargo` and `queue` work. + +While [queue](#queue) passes only one task to one of a group of workers +at a time, cargo passes an array of tasks to a single worker, repeating +when the worker is finished. + +__Arguments__ + +* `worker(tasks, callback)` - An asynchronous function for processing an array of + queued tasks, which must call its `callback(err)` argument when finished, with + an optional `err` argument. +* `payload` - An optional `integer` for determining how many tasks should be + processed per round; if omitted, the default is unlimited. + +__Cargo objects__ + +The `cargo` object returned by this function has the following properties and +methods: + +* `length()` - A function returning the number of items waiting to be processed. +* `payload` - An `integer` for determining how many tasks should be + process per round. This property can be changed after a `cargo` is created to + alter the payload on-the-fly. +* `push(task, [callback])` - Adds `task` to the `queue`. The callback is called + once the `worker` has finished processing the task. Instead of a single task, an array of `tasks` + can be submitted. The respective callback is used for every task in the list. +* `saturated` - A callback that is called when the `queue.length()` hits the concurrency and further tasks will be queued. +* `empty` - A callback that is called when the last item from the `queue` is given to a `worker`. +* `drain` - A callback that is called when the last item from the `queue` has returned from the `worker`. + +__Example__ + +```js +// create a cargo object with payload 2 + +var cargo = async.cargo(function (tasks, callback) { + for(var i=0; i +### auto(tasks, [callback]) + +Determines the best order for running the functions in `tasks`, based on their +requirements. Each function can optionally depend on other functions being completed +first, and each function is run as soon as its requirements are satisfied. + +If any of the functions pass an error to their callback, it will not +complete (so any other functions depending on it will not run), and the main +`callback` is immediately called with the error. Functions also receive an +object containing the results of functions which have completed so far. + +Note, all functions are called with a `results` object as a second argument, +so it is unsafe to pass functions in the `tasks` object which cannot handle the +extra argument. + +For example, this snippet of code: + +```js +async.auto({ + readData: async.apply(fs.readFile, 'data.txt', 'utf-8') +}, callback); +``` + +will have the effect of calling `readFile` with the results object as the last +argument, which will fail: + +```js +fs.readFile('data.txt', 'utf-8', cb, {}); +``` + +Instead, wrap the call to `readFile` in a function which does not forward the +`results` object: + +```js +async.auto({ + readData: function(cb, results){ + fs.readFile('data.txt', 'utf-8', cb); + } +}, callback); +``` + +__Arguments__ + +* `tasks` - An object. Each of its properties is either a function or an array of + requirements, with the function itself the last item in the array. The object's key + of a property serves as the name of the task defined by that property, + i.e. can be used when specifying requirements for other tasks. + The function receives two arguments: (1) a `callback(err, result)` which must be + called when finished, passing an `error` (which can be `null`) and the result of + the function's execution, and (2) a `results` object, containing the results of + the previously executed functions. +* `callback(err, results)` - An optional callback which is called when all the + tasks have been completed. It receives the `err` argument if any `tasks` + pass an error to their callback. Results are always returned; however, if + an error occurs, no further `tasks` will be performed, and the results + object will only contain partial results. + + +__Example__ + +```js +async.auto({ + get_data: function(callback){ + console.log('in get_data'); + // async code to get some data + callback(null, 'data', 'converted to array'); + }, + make_folder: function(callback){ + console.log('in make_folder'); + // async code to create a directory to store a file in + // this is run at the same time as getting the data + callback(null, 'folder'); + }, + write_file: ['get_data', 'make_folder', function(callback, results){ + console.log('in write_file', JSON.stringify(results)); + // once there is some data and the directory exists, + // write the data to a file in the directory + callback(null, 'filename'); + }], + email_link: ['write_file', function(callback, results){ + console.log('in email_link', JSON.stringify(results)); + // once the file is written let's email a link to it... + // results.write_file contains the filename returned by write_file. + callback(null, {'file':results.write_file, 'email':'user@example.com'}); + }] +}, function(err, results) { + console.log('err = ', err); + console.log('results = ', results); +}); +``` + +This is a fairly trivial example, but to do this using the basic parallel and +series functions would look like this: + +```js +async.parallel([ + function(callback){ + console.log('in get_data'); + // async code to get some data + callback(null, 'data', 'converted to array'); + }, + function(callback){ + console.log('in make_folder'); + // async code to create a directory to store a file in + // this is run at the same time as getting the data + callback(null, 'folder'); + } +], +function(err, results){ + async.series([ + function(callback){ + console.log('in write_file', JSON.stringify(results)); + // once there is some data and the directory exists, + // write the data to a file in the directory + results.push('filename'); + callback(null); + }, + function(callback){ + console.log('in email_link', JSON.stringify(results)); + // once the file is written let's email a link to it... + callback(null, {'file':results.pop(), 'email':'user@example.com'}); + } + ]); +}); +``` + +For a complicated series of `async` tasks, using the [`auto`](#auto) function makes adding +new tasks much easier (and the code more readable). + + +--------------------------------------- + + +### retry([times = 5], task, [callback]) + +Attempts to get a successful response from `task` no more than `times` times before +returning an error. If the task is successful, the `callback` will be passed the result +of the successful task. If all attempts fail, the callback will be passed the error and +result (if any) of the final attempt. + +__Arguments__ + +* `times` - An integer indicating how many times to attempt the `task` before giving up. Defaults to 5. +* `task(callback, results)` - A function which receives two arguments: (1) a `callback(err, result)` + which must be called when finished, passing `err` (which can be `null`) and the `result` of + the function's execution, and (2) a `results` object, containing the results of + the previously executed functions (if nested inside another control flow). +* `callback(err, results)` - An optional callback which is called when the + task has succeeded, or after the final failed attempt. It receives the `err` and `result` arguments of the last attempt at completing the `task`. + +The [`retry`](#retry) function can be used as a stand-alone control flow by passing a +callback, as shown below: + +```js +async.retry(3, apiMethod, function(err, result) { + // do something with the result +}); +``` + +It can also be embeded within other control flow functions to retry individual methods +that are not as reliable, like this: + +```js +async.auto({ + users: api.getUsers.bind(api), + payments: async.retry(3, api.getPayments.bind(api)) +}, function(err, results) { + // do something with the results +}); +``` + + +--------------------------------------- + + +### iterator(tasks) + +Creates an iterator function which calls the next function in the `tasks` array, +returning a continuation to call the next one after that. It's also possible to +“peek” at the next iterator with `iterator.next()`. + +This function is used internally by the `async` module, but can be useful when +you want to manually control the flow of functions in series. + +__Arguments__ + +* `tasks` - An array of functions to run. + +__Example__ + +```js +var iterator = async.iterator([ + function(){ sys.p('one'); }, + function(){ sys.p('two'); }, + function(){ sys.p('three'); } +]); + +node> var iterator2 = iterator(); +'one' +node> var iterator3 = iterator2(); +'two' +node> iterator3(); +'three' +node> var nextfn = iterator2.next(); +node> nextfn(); +'three' +``` + +--------------------------------------- + + +### apply(function, arguments..) + +Creates a continuation function with some arguments already applied. + +Useful as a shorthand when combined with other control flow functions. Any arguments +passed to the returned function are added to the arguments originally passed +to apply. + +__Arguments__ + +* `function` - The function you want to eventually apply all arguments to. +* `arguments...` - Any number of arguments to automatically apply when the + continuation is called. + +__Example__ + +```js +// using apply + +async.parallel([ + async.apply(fs.writeFile, 'testfile1', 'test1'), + async.apply(fs.writeFile, 'testfile2', 'test2'), +]); + + +// the same process without using apply + +async.parallel([ + function(callback){ + fs.writeFile('testfile1', 'test1', callback); + }, + function(callback){ + fs.writeFile('testfile2', 'test2', callback); + } +]); +``` + +It's possible to pass any number of additional arguments when calling the +continuation: + +```js +node> var fn = async.apply(sys.puts, 'one'); +node> fn('two', 'three'); +one +two +three +``` + +--------------------------------------- + + +### nextTick(callback), setImmediate(callback) + +Calls `callback` on a later loop around the event loop. In Node.js this just +calls `process.nextTick`; in the browser it falls back to `setImmediate(callback)` +if available, otherwise `setTimeout(callback, 0)`, which means other higher priority +events may precede the execution of `callback`. + +This is used internally for browser-compatibility purposes. + +__Arguments__ + +* `callback` - The function to call on a later loop around the event loop. + +__Example__ + +```js +var call_order = []; +async.nextTick(function(){ + call_order.push('two'); + // call_order now equals ['one','two'] +}); +call_order.push('one') +``` + + +### times(n, callback) + +Calls the `callback` function `n` times, and accumulates results in the same manner +you would use with [`map`](#map). + +__Arguments__ + +* `n` - The number of times to run the function. +* `callback` - The function to call `n` times. + +__Example__ + +```js +// Pretend this is some complicated async factory +var createUser = function(id, callback) { + callback(null, { + id: 'user' + id + }) +} +// generate 5 users +async.times(5, function(n, next){ + createUser(n, function(err, user) { + next(err, user) + }) +}, function(err, users) { + // we should now have 5 users +}); +``` + + +### timesSeries(n, callback) + +The same as [`times`](#times), only the iterator is applied to each item in `arr` in +series. The next `iterator` is only called once the current one has completed. +The results array will be in the same order as the original. + + +## Utils + + +### memoize(fn, [hasher]) + +Caches the results of an `async` function. When creating a hash to store function +results against, the callback is omitted from the hash and an optional hash +function can be used. + +The cache of results is exposed as the `memo` property of the function returned +by `memoize`. + +__Arguments__ + +* `fn` - The function to proxy and cache results from. +* `hasher` - Tn optional function for generating a custom hash for storing + results. It has all the arguments applied to it apart from the callback, and + must be synchronous. + +__Example__ + +```js +var slow_fn = function (name, callback) { + // do something + callback(null, result); +}; +var fn = async.memoize(slow_fn); + +// fn can now be used as if it were slow_fn +fn('some name', function () { + // callback +}); +``` + + +### unmemoize(fn) + +Undoes a [`memoize`](#memoize)d function, reverting it to the original, unmemoized +form. Handy for testing. + +__Arguments__ + +* `fn` - the memoized function + + +### log(function, arguments) + +Logs the result of an `async` function to the `console`. Only works in Node.js or +in browsers that support `console.log` and `console.error` (such as FF and Chrome). +If multiple arguments are returned from the async function, `console.log` is +called on each argument in order. + +__Arguments__ + +* `function` - The function you want to eventually apply all arguments to. +* `arguments...` - Any number of arguments to apply to the function. + +__Example__ + +```js +var hello = function(name, callback){ + setTimeout(function(){ + callback(null, 'hello ' + name); + }, 1000); +}; +``` +```js +node> async.log(hello, 'world'); +'hello world' +``` + +--------------------------------------- + + +### dir(function, arguments) + +Logs the result of an `async` function to the `console` using `console.dir` to +display the properties of the resulting object. Only works in Node.js or +in browsers that support `console.dir` and `console.error` (such as FF and Chrome). +If multiple arguments are returned from the async function, `console.dir` is +called on each argument in order. + +__Arguments__ + +* `function` - The function you want to eventually apply all arguments to. +* `arguments...` - Any number of arguments to apply to the function. + +__Example__ + +```js +var hello = function(name, callback){ + setTimeout(function(){ + callback(null, {hello: name}); + }, 1000); +}; +``` +```js +node> async.dir(hello, 'world'); +{hello: 'world'} +``` + +--------------------------------------- + + +### noConflict() + +Changes the value of `async` back to its original value, returning a reference to the +`async` object. diff --git a/node_modules/grunt-ftp-deploy/node_modules/async/bower.json b/node_modules/grunt-ftp-deploy/node_modules/async/bower.json new file mode 100644 index 0000000..1817688 --- /dev/null +++ b/node_modules/grunt-ftp-deploy/node_modules/async/bower.json @@ -0,0 +1,38 @@ +{ + "name": "async", + "description": "Higher-order functions and common patterns for asynchronous code", + "version": "0.9.2", + "main": "lib/async.js", + "keywords": [ + "async", + "callback", + "utility", + "module" + ], + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/caolan/async.git" + }, + "devDependencies": { + "nodeunit": ">0.0.0", + "uglify-js": "1.2.x", + "nodelint": ">0.0.0", + "lodash": ">=2.4.1" + }, + "moduleType": [ + "amd", + "globals", + "node" + ], + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "authors": [ + "Caolan McMahon" + ] +} \ No newline at end of file diff --git a/node_modules/grunt-ftp-deploy/node_modules/async/component.json b/node_modules/grunt-ftp-deploy/node_modules/async/component.json new file mode 100644 index 0000000..5003a7c --- /dev/null +++ b/node_modules/grunt-ftp-deploy/node_modules/async/component.json @@ -0,0 +1,16 @@ +{ + "name": "async", + "description": "Higher-order functions and common patterns for asynchronous code", + "version": "0.9.2", + "keywords": [ + "async", + "callback", + "utility", + "module" + ], + "license": "MIT", + "repository": "caolan/async", + "scripts": [ + "lib/async.js" + ] +} \ No newline at end of file diff --git a/node_modules/grunt-ftp-deploy/node_modules/async/lib/async.js b/node_modules/grunt-ftp-deploy/node_modules/async/lib/async.js new file mode 100644 index 0000000..394c41c --- /dev/null +++ b/node_modules/grunt-ftp-deploy/node_modules/async/lib/async.js @@ -0,0 +1,1123 @@ +/*! + * async + * https://github.com/caolan/async + * + * Copyright 2010-2014 Caolan McMahon + * Released under the MIT license + */ +/*jshint onevar: false, indent:4 */ +/*global setImmediate: false, setTimeout: false, console: false */ +(function () { + + var async = {}; + + // global on the server, window in the browser + var root, previous_async; + + root = this; + if (root != null) { + previous_async = root.async; + } + + async.noConflict = function () { + root.async = previous_async; + return async; + }; + + function only_once(fn) { + var called = false; + return function() { + if (called) throw new Error("Callback was already called."); + called = true; + fn.apply(root, arguments); + } + } + + //// cross-browser compatiblity functions //// + + var _toString = Object.prototype.toString; + + var _isArray = Array.isArray || function (obj) { + return _toString.call(obj) === '[object Array]'; + }; + + var _each = function (arr, iterator) { + for (var i = 0; i < arr.length; i += 1) { + iterator(arr[i], i, arr); + } + }; + + var _map = function (arr, iterator) { + if (arr.map) { + return arr.map(iterator); + } + var results = []; + _each(arr, function (x, i, a) { + results.push(iterator(x, i, a)); + }); + return results; + }; + + var _reduce = function (arr, iterator, memo) { + if (arr.reduce) { + return arr.reduce(iterator, memo); + } + _each(arr, function (x, i, a) { + memo = iterator(memo, x, i, a); + }); + return memo; + }; + + var _keys = function (obj) { + if (Object.keys) { + return Object.keys(obj); + } + var keys = []; + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + keys.push(k); + } + } + return keys; + }; + + //// exported async module functions //// + + //// nextTick implementation with browser-compatible fallback //// + if (typeof process === 'undefined' || !(process.nextTick)) { + if (typeof setImmediate === 'function') { + async.nextTick = function (fn) { + // not a direct alias for IE10 compatibility + setImmediate(fn); + }; + async.setImmediate = async.nextTick; + } + else { + async.nextTick = function (fn) { + setTimeout(fn, 0); + }; + async.setImmediate = async.nextTick; + } + } + else { + async.nextTick = process.nextTick; + if (typeof setImmediate !== 'undefined') { + async.setImmediate = function (fn) { + // not a direct alias for IE10 compatibility + setImmediate(fn); + }; + } + else { + async.setImmediate = async.nextTick; + } + } + + async.each = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); + } + var completed = 0; + _each(arr, function (x) { + iterator(x, only_once(done) ); + }); + function done(err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed >= arr.length) { + callback(); + } + } + } + }; + async.forEach = async.each; + + async.eachSeries = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); + } + var completed = 0; + var iterate = function () { + iterator(arr[completed], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed >= arr.length) { + callback(); + } + else { + iterate(); + } + } + }); + }; + iterate(); + }; + async.forEachSeries = async.eachSeries; + + async.eachLimit = function (arr, limit, iterator, callback) { + var fn = _eachLimit(limit); + fn.apply(null, [arr, iterator, callback]); + }; + async.forEachLimit = async.eachLimit; + + var _eachLimit = function (limit) { + + return function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length || limit <= 0) { + return callback(); + } + var completed = 0; + var started = 0; + var running = 0; + + (function replenish () { + if (completed >= arr.length) { + return callback(); + } + + while (running < limit && started < arr.length) { + started += 1; + running += 1; + iterator(arr[started - 1], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + running -= 1; + if (completed >= arr.length) { + callback(); + } + else { + replenish(); + } + } + }); + } + })(); + }; + }; + + + var doParallel = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.each].concat(args)); + }; + }; + var doParallelLimit = function(limit, fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [_eachLimit(limit)].concat(args)); + }; + }; + var doSeries = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.eachSeries].concat(args)); + }; + }; + + + var _asyncMap = function (eachfn, arr, iterator, callback) { + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + if (!callback) { + eachfn(arr, function (x, callback) { + iterator(x.value, function (err) { + callback(err); + }); + }); + } else { + var results = []; + eachfn(arr, function (x, callback) { + iterator(x.value, function (err, v) { + results[x.index] = v; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + async.map = doParallel(_asyncMap); + async.mapSeries = doSeries(_asyncMap); + async.mapLimit = function (arr, limit, iterator, callback) { + return _mapLimit(limit)(arr, iterator, callback); + }; + + var _mapLimit = function(limit) { + return doParallelLimit(limit, _asyncMap); + }; + + // reduce only has a series version, as doing reduce in parallel won't + // work in many situations. + async.reduce = function (arr, memo, iterator, callback) { + async.eachSeries(arr, function (x, callback) { + iterator(memo, x, function (err, v) { + memo = v; + callback(err); + }); + }, function (err) { + callback(err, memo); + }); + }; + // inject alias + async.inject = async.reduce; + // foldl alias + async.foldl = async.reduce; + + async.reduceRight = function (arr, memo, iterator, callback) { + var reversed = _map(arr, function (x) { + return x; + }).reverse(); + async.reduce(reversed, memo, iterator, callback); + }; + // foldr alias + async.foldr = async.reduceRight; + + var _filter = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.filter = doParallel(_filter); + async.filterSeries = doSeries(_filter); + // select alias + async.select = async.filter; + async.selectSeries = async.filterSeries; + + var _reject = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (!v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.reject = doParallel(_reject); + async.rejectSeries = doSeries(_reject); + + var _detect = function (eachfn, arr, iterator, main_callback) { + eachfn(arr, function (x, callback) { + iterator(x, function (result) { + if (result) { + main_callback(x); + main_callback = function () {}; + } + else { + callback(); + } + }); + }, function (err) { + main_callback(); + }); + }; + async.detect = doParallel(_detect); + async.detectSeries = doSeries(_detect); + + async.some = function (arr, iterator, main_callback) { + async.each(arr, function (x, callback) { + iterator(x, function (v) { + if (v) { + main_callback(true); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(false); + }); + }; + // any alias + async.any = async.some; + + async.every = function (arr, iterator, main_callback) { + async.each(arr, function (x, callback) { + iterator(x, function (v) { + if (!v) { + main_callback(false); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(true); + }); + }; + // all alias + async.all = async.every; + + async.sortBy = function (arr, iterator, callback) { + async.map(arr, function (x, callback) { + iterator(x, function (err, criteria) { + if (err) { + callback(err); + } + else { + callback(null, {value: x, criteria: criteria}); + } + }); + }, function (err, results) { + if (err) { + return callback(err); + } + else { + var fn = function (left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }; + callback(null, _map(results.sort(fn), function (x) { + return x.value; + })); + } + }); + }; + + async.auto = function (tasks, callback) { + callback = callback || function () {}; + var keys = _keys(tasks); + var remainingTasks = keys.length + if (!remainingTasks) { + return callback(); + } + + var results = {}; + + var listeners = []; + var addListener = function (fn) { + listeners.unshift(fn); + }; + var removeListener = function (fn) { + for (var i = 0; i < listeners.length; i += 1) { + if (listeners[i] === fn) { + listeners.splice(i, 1); + return; + } + } + }; + var taskComplete = function () { + remainingTasks-- + _each(listeners.slice(0), function (fn) { + fn(); + }); + }; + + addListener(function () { + if (!remainingTasks) { + var theCallback = callback; + // prevent final callback from calling itself if it errors + callback = function () {}; + + theCallback(null, results); + } + }); + + _each(keys, function (k) { + var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]]; + var taskCallback = function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + if (err) { + var safeResults = {}; + _each(_keys(results), function(rkey) { + safeResults[rkey] = results[rkey]; + }); + safeResults[k] = args; + callback(err, safeResults); + // stop subsequent errors hitting callback multiple times + callback = function () {}; + } + else { + results[k] = args; + async.setImmediate(taskComplete); + } + }; + var requires = task.slice(0, Math.abs(task.length - 1)) || []; + var ready = function () { + return _reduce(requires, function (a, x) { + return (a && results.hasOwnProperty(x)); + }, true) && !results.hasOwnProperty(k); + }; + if (ready()) { + task[task.length - 1](taskCallback, results); + } + else { + var listener = function () { + if (ready()) { + removeListener(listener); + task[task.length - 1](taskCallback, results); + } + }; + addListener(listener); + } + }); + }; + + async.retry = function(times, task, callback) { + var DEFAULT_TIMES = 5; + var attempts = []; + // Use defaults if times not passed + if (typeof times === 'function') { + callback = task; + task = times; + times = DEFAULT_TIMES; + } + // Make sure times is a number + times = parseInt(times, 10) || DEFAULT_TIMES; + var wrappedTask = function(wrappedCallback, wrappedResults) { + var retryAttempt = function(task, finalAttempt) { + return function(seriesCallback) { + task(function(err, result){ + seriesCallback(!err || finalAttempt, {err: err, result: result}); + }, wrappedResults); + }; + }; + while (times) { + attempts.push(retryAttempt(task, !(times-=1))); + } + async.series(attempts, function(done, data){ + data = data[data.length - 1]; + (wrappedCallback || callback)(data.err, data.result); + }); + } + // If a callback is passed, run this as a controll flow + return callback ? wrappedTask() : wrappedTask + }; + + async.waterfall = function (tasks, callback) { + callback = callback || function () {}; + if (!_isArray(tasks)) { + var err = new Error('First argument to waterfall must be an array of functions'); + return callback(err); + } + if (!tasks.length) { + return callback(); + } + var wrapIterator = function (iterator) { + return function (err) { + if (err) { + callback.apply(null, arguments); + callback = function () {}; + } + else { + var args = Array.prototype.slice.call(arguments, 1); + var next = iterator.next(); + if (next) { + args.push(wrapIterator(next)); + } + else { + args.push(callback); + } + async.setImmediate(function () { + iterator.apply(null, args); + }); + } + }; + }; + wrapIterator(async.iterator(tasks))(); + }; + + var _parallel = function(eachfn, tasks, callback) { + callback = callback || function () {}; + if (_isArray(tasks)) { + eachfn.map(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + eachfn.each(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.parallel = function (tasks, callback) { + _parallel({ map: async.map, each: async.each }, tasks, callback); + }; + + async.parallelLimit = function(tasks, limit, callback) { + _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback); + }; + + async.series = function (tasks, callback) { + callback = callback || function () {}; + if (_isArray(tasks)) { + async.mapSeries(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + async.eachSeries(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.iterator = function (tasks) { + var makeCallback = function (index) { + var fn = function () { + if (tasks.length) { + tasks[index].apply(null, arguments); + } + return fn.next(); + }; + fn.next = function () { + return (index < tasks.length - 1) ? makeCallback(index + 1): null; + }; + return fn; + }; + return makeCallback(0); + }; + + async.apply = function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + return function () { + return fn.apply( + null, args.concat(Array.prototype.slice.call(arguments)) + ); + }; + }; + + var _concat = function (eachfn, arr, fn, callback) { + var r = []; + eachfn(arr, function (x, cb) { + fn(x, function (err, y) { + r = r.concat(y || []); + cb(err); + }); + }, function (err) { + callback(err, r); + }); + }; + async.concat = doParallel(_concat); + async.concatSeries = doSeries(_concat); + + async.whilst = function (test, iterator, callback) { + if (test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.whilst(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.doWhilst = function (iterator, test, callback) { + iterator(function (err) { + if (err) { + return callback(err); + } + var args = Array.prototype.slice.call(arguments, 1); + if (test.apply(null, args)) { + async.doWhilst(iterator, test, callback); + } + else { + callback(); + } + }); + }; + + async.until = function (test, iterator, callback) { + if (!test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.until(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.doUntil = function (iterator, test, callback) { + iterator(function (err) { + if (err) { + return callback(err); + } + var args = Array.prototype.slice.call(arguments, 1); + if (!test.apply(null, args)) { + async.doUntil(iterator, test, callback); + } + else { + callback(); + } + }); + }; + + async.queue = function (worker, concurrency) { + if (concurrency === undefined) { + concurrency = 1; + } + function _insert(q, data, pos, callback) { + if (!q.started){ + q.started = true; + } + if (!_isArray(data)) { + data = [data]; + } + if(data.length == 0) { + // call drain immediately if there are no tasks + return async.setImmediate(function() { + if (q.drain) { + q.drain(); + } + }); + } + _each(data, function(task) { + var item = { + data: task, + callback: typeof callback === 'function' ? callback : null + }; + + if (pos) { + q.tasks.unshift(item); + } else { + q.tasks.push(item); + } + + if (q.saturated && q.tasks.length === q.concurrency) { + q.saturated(); + } + async.setImmediate(q.process); + }); + } + + var workers = 0; + var q = { + tasks: [], + concurrency: concurrency, + saturated: null, + empty: null, + drain: null, + started: false, + paused: false, + push: function (data, callback) { + _insert(q, data, false, callback); + }, + kill: function () { + q.drain = null; + q.tasks = []; + }, + unshift: function (data, callback) { + _insert(q, data, true, callback); + }, + process: function () { + if (!q.paused && workers < q.concurrency && q.tasks.length) { + var task = q.tasks.shift(); + if (q.empty && q.tasks.length === 0) { + q.empty(); + } + workers += 1; + var next = function () { + workers -= 1; + if (task.callback) { + task.callback.apply(task, arguments); + } + if (q.drain && q.tasks.length + workers === 0) { + q.drain(); + } + q.process(); + }; + var cb = only_once(next); + worker(task.data, cb); + } + }, + length: function () { + return q.tasks.length; + }, + running: function () { + return workers; + }, + idle: function() { + return q.tasks.length + workers === 0; + }, + pause: function () { + if (q.paused === true) { return; } + q.paused = true; + }, + resume: function () { + if (q.paused === false) { return; } + q.paused = false; + // Need to call q.process once per concurrent + // worker to preserve full concurrency after pause + for (var w = 1; w <= q.concurrency; w++) { + async.setImmediate(q.process); + } + } + }; + return q; + }; + + async.priorityQueue = function (worker, concurrency) { + + function _compareTasks(a, b){ + return a.priority - b.priority; + }; + + function _binarySearch(sequence, item, compare) { + var beg = -1, + end = sequence.length - 1; + while (beg < end) { + var mid = beg + ((end - beg + 1) >>> 1); + if (compare(item, sequence[mid]) >= 0) { + beg = mid; + } else { + end = mid - 1; + } + } + return beg; + } + + function _insert(q, data, priority, callback) { + if (!q.started){ + q.started = true; + } + if (!_isArray(data)) { + data = [data]; + } + if(data.length == 0) { + // call drain immediately if there are no tasks + return async.setImmediate(function() { + if (q.drain) { + q.drain(); + } + }); + } + _each(data, function(task) { + var item = { + data: task, + priority: priority, + callback: typeof callback === 'function' ? callback : null + }; + + q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item); + + if (q.saturated && q.tasks.length === q.concurrency) { + q.saturated(); + } + async.setImmediate(q.process); + }); + } + + // Start with a normal queue + var q = async.queue(worker, concurrency); + + // Override push to accept second parameter representing priority + q.push = function (data, priority, callback) { + _insert(q, data, priority, callback); + }; + + // Remove unshift function + delete q.unshift; + + return q; + }; + + async.cargo = function (worker, payload) { + var working = false, + tasks = []; + + var cargo = { + tasks: tasks, + payload: payload, + saturated: null, + empty: null, + drain: null, + drained: true, + push: function (data, callback) { + if (!_isArray(data)) { + data = [data]; + } + _each(data, function(task) { + tasks.push({ + data: task, + callback: typeof callback === 'function' ? callback : null + }); + cargo.drained = false; + if (cargo.saturated && tasks.length === payload) { + cargo.saturated(); + } + }); + async.setImmediate(cargo.process); + }, + process: function process() { + if (working) return; + if (tasks.length === 0) { + if(cargo.drain && !cargo.drained) cargo.drain(); + cargo.drained = true; + return; + } + + var ts = typeof payload === 'number' + ? tasks.splice(0, payload) + : tasks.splice(0, tasks.length); + + var ds = _map(ts, function (task) { + return task.data; + }); + + if(cargo.empty) cargo.empty(); + working = true; + worker(ds, function () { + working = false; + + var args = arguments; + _each(ts, function (data) { + if (data.callback) { + data.callback.apply(null, args); + } + }); + + process(); + }); + }, + length: function () { + return tasks.length; + }, + running: function () { + return working; + } + }; + return cargo; + }; + + var _console_fn = function (name) { + return function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + fn.apply(null, args.concat([function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (typeof console !== 'undefined') { + if (err) { + if (console.error) { + console.error(err); + } + } + else if (console[name]) { + _each(args, function (x) { + console[name](x); + }); + } + } + }])); + }; + }; + async.log = _console_fn('log'); + async.dir = _console_fn('dir'); + /*async.info = _console_fn('info'); + async.warn = _console_fn('warn'); + async.error = _console_fn('error');*/ + + async.memoize = function (fn, hasher) { + var memo = {}; + var queues = {}; + hasher = hasher || function (x) { + return x; + }; + var memoized = function () { + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + var key = hasher.apply(null, args); + if (key in memo) { + async.nextTick(function () { + callback.apply(null, memo[key]); + }); + } + else if (key in queues) { + queues[key].push(callback); + } + else { + queues[key] = [callback]; + fn.apply(null, args.concat([function () { + memo[key] = arguments; + var q = queues[key]; + delete queues[key]; + for (var i = 0, l = q.length; i < l; i++) { + q[i].apply(null, arguments); + } + }])); + } + }; + memoized.memo = memo; + memoized.unmemoized = fn; + return memoized; + }; + + async.unmemoize = function (fn) { + return function () { + return (fn.unmemoized || fn).apply(null, arguments); + }; + }; + + async.times = function (count, iterator, callback) { + var counter = []; + for (var i = 0; i < count; i++) { + counter.push(i); + } + return async.map(counter, iterator, callback); + }; + + async.timesSeries = function (count, iterator, callback) { + var counter = []; + for (var i = 0; i < count; i++) { + counter.push(i); + } + return async.mapSeries(counter, iterator, callback); + }; + + async.seq = function (/* functions... */) { + var fns = arguments; + return function () { + var that = this; + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + async.reduce(fns, args, function (newargs, fn, cb) { + fn.apply(that, newargs.concat([function () { + var err = arguments[0]; + var nextargs = Array.prototype.slice.call(arguments, 1); + cb(err, nextargs); + }])) + }, + function (err, results) { + callback.apply(that, [err].concat(results)); + }); + }; + }; + + async.compose = function (/* functions... */) { + return async.seq.apply(null, Array.prototype.reverse.call(arguments)); + }; + + var _applyEach = function (eachfn, fns /*args...*/) { + var go = function () { + var that = this; + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + return eachfn(fns, function (fn, cb) { + fn.apply(that, args.concat([cb])); + }, + callback); + }; + if (arguments.length > 2) { + var args = Array.prototype.slice.call(arguments, 2); + return go.apply(this, args); + } + else { + return go; + } + }; + async.applyEach = doParallel(_applyEach); + async.applyEachSeries = doSeries(_applyEach); + + async.forever = function (fn, callback) { + function next(err) { + if (err) { + if (callback) { + return callback(err); + } + throw err; + } + fn(next); + } + next(); + }; + + // Node.js + if (typeof module !== 'undefined' && module.exports) { + module.exports = async; + } + // AMD / RequireJS + else if (typeof define !== 'undefined' && define.amd) { + define([], function () { + return async; + }); + } + // included directly via +``` + +Using [`npm`](http://npmjs.org/): + +```bash +npm i --save lodash + +{sudo} npm i -g lodash +npm ln lodash +``` + +In [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/): + +```js +var _ = require('lodash'); +// or as Underscore +var _ = require('lodash/dist/lodash.underscore'); +``` + +**Notes:** + * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL + * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it + +In [Rhino](http://www.mozilla.org/rhino/): + +```js +load('lodash.js'); +``` + +In an AMD loader: + +```js +require({ + 'packages': [ + { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' } + ] +}, +['lodash'], function(_) { + console.log(_.VERSION); +}); +``` + +## Resources + + * Podcasts + - [JavaScript Jabber](http://javascriptjabber.com/079-jsj-lo-dash-with-john-david-dalton/) + + * Posts + - [Say “Hello” to Lo-Dash](http://kitcambridge.be/blog/say-hello-to-lo-dash/) + - [Custom builds in Lo-Dash 2.0](http://kitcambridge.be/blog/custom-builds-in-lo-dash-2-dot-0/) + + * Videos + - [Introduction](https://vimeo.com/44154599) + - [Origins](https://vimeo.com/44154600) + - [Optimizations & builds](https://vimeo.com/44154601) + - [Native method use](https://vimeo.com/48576012) + - [Testing](https://vimeo.com/45865290) + - [CascadiaJS ’12](http://www.youtube.com/watch?v=dpPy4f_SeEk) + + A list of other community created podcasts, posts, & videos is available on our [wiki](https://github.com/lodash/lodash/wiki/Resources). + +## Features + + * AMD loader support ([curl](https://github.com/cujojs/curl), [dojo](http://dojotoolkit.org/), [requirejs](http://requirejs.org/), etc.) + * [_(…)](https://lodash.com/docs#_) supports intuitive chaining + * [_.at](https://lodash.com/docs#at) for cherry-picking collection values + * [_.bindKey](https://lodash.com/docs#bindKey) for binding [*“lazy”*](http://michaux.ca/articles/lazy-function-definition-pattern) defined methods + * [_.clone](https://lodash.com/docs#clone) supports shallow cloning of `Date` & `RegExp` objects + * [_.cloneDeep](https://lodash.com/docs#cloneDeep) for deep cloning arrays & objects + * [_.constant](https://lodash.com/docs#constant) & [_.property](https://lodash.com/docs#property) function generators for composing functions + * [_.contains](https://lodash.com/docs#contains) accepts a `fromIndex` + * [_.create](https://lodash.com/docs#create) for easier object inheritance + * [_.createCallback](https://lodash.com/docs#createCallback) for extending callbacks in methods & mixins + * [_.curry](https://lodash.com/docs#curry) for creating [curried](http://hughfdjackson.com/javascript/2013/07/06/why-curry-helps/) functions + * [_.debounce](https://lodash.com/docs#debounce) & [_.throttle](https://lodash.com/docs#throttle) accept additional `options` for more control + * [_.findIndex](https://lodash.com/docs#findIndex) & [_.findKey](https://lodash.com/docs#findKey) for finding indexes & keys + * [_.forEach](https://lodash.com/docs#forEach) is chainable & supports exiting early + * [_.forIn](https://lodash.com/docs#forIn) for iterating own & inherited properties + * [_.forOwn](https://lodash.com/docs#forOwn) for iterating own properties + * [_.isPlainObject](https://lodash.com/docs#isPlainObject) for checking if values are created by `Object` + * [_.mapValues](https://lodash.com/docs#mapValues) for [mapping](https://lodash.com/docs#map) values to an object + * [_.memoize](https://lodash.com/docs#memoize) exposes the `cache` of memoized functions + * [_.merge](https://lodash.com/docs#merge) for a deep [_.extend](https://lodash.com/docs#extend) + * [_.noop](https://lodash.com/docs#noop) for function placeholders + * [_.now](https://lodash.com/docs#now) as a cross-browser `Date.now` alternative + * [_.parseInt](https://lodash.com/docs#parseInt) for consistent behavior + * [_.pull](https://lodash.com/docs#pull) & [_.remove](https://lodash.com/docs#remove) for mutating arrays + * [_.random](https://lodash.com/docs#random) supports returning floating-point numbers + * [_.runInContext](https://lodash.com/docs#runInContext) for easier mocking + * [_.sortBy](https://lodash.com/docs#sortBy) supports sorting by multiple properties + * [_.support](https://lodash.com/docs#support) for flagging environment features + * [_.template](https://lodash.com/docs#template) supports [*“imports”*](https://lodash.com/docs#templateSettings_imports) options & [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals) + * [_.transform](https://lodash.com/docs#transform) as a powerful alternative to [_.reduce](https://lodash.com/docs#reduce) for transforming objects + * [_.where](https://lodash.com/docs#where) supports deep object comparisons + * [_.xor](https://lodash.com/docs#xor) as a companion to [_.difference](https://lodash.com/docs#difference), [_.intersection](https://lodash.com/docs#intersection), & [_.union](https://lodash.com/docs#union) + * [_.zip](https://lodash.com/docs#zip) is capable of unzipping values + * [_.omit](https://lodash.com/docs#omit), [_.pick](https://lodash.com/docs#pick), & + [more](https://lodash.com/docs "_.assign, _.clone, _.cloneDeep, _.first, _.initial, _.isEqual, _.last, _.merge, _.rest") accept callbacks + * [_.contains](https://lodash.com/docs#contains), [_.toArray](https://lodash.com/docs#toArray), & + [more](https://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.forEach, _.forEachRight, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.size, _.some, _.sortBy, _.where") accept strings + * [_.filter](https://lodash.com/docs#filter), [_.map](https://lodash.com/docs#map), & + [more](https://lodash.com/docs "_.countBy, _.every, _.find, _.findKey, _.findLast, _.findLastIndex, _.findLastKey, _.first, _.groupBy, _.initial, _.last, _.max, _.min, _.reject, _.rest, _.some, _.sortBy, _.sortedIndex, _.uniq") support *“_.pluck”* & *“_.where”* shorthands + * [_.findLast](https://lodash.com/docs#findLast), [_.findLastIndex](https://lodash.com/docs#findLastIndex), & + [more](https://lodash.com/docs "_.findLastKey, _.forEachRight, _.forInRight, _.forOwnRight, _.partialRight") right-associative methods + +## Support + +Tested in Chrome 5~31, Firefox 2~25, IE 6-11, Opera 9.25-17, Safari 3-7, Node.js 0.6.21-0.10.22, Narwhal 0.3.2, PhantomJS 1.9.2, RingoJS 0.9, & Rhino 1.7RC5. diff --git a/node_modules/grunt-ftp-deploy/node_modules/lodash/dist/lodash.compat.js b/node_modules/grunt-ftp-deploy/node_modules/lodash/dist/lodash.compat.js new file mode 100644 index 0000000..4d35185 --- /dev/null +++ b/node_modules/grunt-ftp-deploy/node_modules/lodash/dist/lodash.compat.js @@ -0,0 +1,7158 @@ +/** + * @license + * Lo-Dash 2.4.2 (Custom Build) + * Build: `lodash -o ./dist/lodash.compat.js` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre ES5 environments */ + var undefined; + + /** Used to pool arrays and objects used internally */ + var arrayPool = [], + objectPool = []; + + /** Used to generate unique IDs */ + var idCounter = 0; + + /** Used internally to indicate various things */ + var indicatorObject = {}; + + /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */ + var keyPrefix = +new Date + ''; + + /** Used as the size when optimizations are enabled for large arrays */ + var largeArraySize = 75; + + /** Used as the max size of the `arrayPool` and `objectPool` */ + var maxPoolSize = 40; + + /** Used to detect and test whitespace */ + var whitespace = ( + // whitespace + ' \t\x0B\f\xA0\ufeff' + + + // line terminators + '\n\r\u2028\u2029' + + + // unicode category "Zs" space separators + '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' + ); + + /** Used to match empty string literals in compiled template source */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** + * Used to match ES6 template delimiters + * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals + */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match regexp flags from their coerced string values */ + var reFlags = /\w*$/; + + /** Used to detected named functions */ + var reFuncName = /^\s*function[ \n\r\t]+\w/; + + /** Used to match "interpolate" template delimiters */ + var reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match leading whitespace and zeros to be removed */ + var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)'); + + /** Used to ensure capturing order of template delimiters */ + var reNoMatch = /($^)/; + + /** Used to detect functions containing a `this` reference */ + var reThis = /\bthis\b/; + + /** Used to match unescaped characters in compiled string literals */ + var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; + + /** Used to assign default `context` object properties */ + var contextProps = [ + 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object', + 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', + 'parseInt', 'setTimeout' + ]; + + /** Used to fix the JScript [[DontEnum]] bug */ + var shadowedProps = [ + 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', + 'toLocaleString', 'toString', 'valueOf' + ]; + + /** Used to make template sourceURLs easier to identify */ + var templateCounter = 0; + + /** `Object#toString` result shortcuts */ + var argsClass = '[object Arguments]', + arrayClass = '[object Array]', + boolClass = '[object Boolean]', + dateClass = '[object Date]', + errorClass = '[object Error]', + funcClass = '[object Function]', + numberClass = '[object Number]', + objectClass = '[object Object]', + regexpClass = '[object RegExp]', + stringClass = '[object String]'; + + /** Used to identify object classifications that `_.clone` supports */ + var cloneableClasses = {}; + cloneableClasses[funcClass] = false; + cloneableClasses[argsClass] = cloneableClasses[arrayClass] = + cloneableClasses[boolClass] = cloneableClasses[dateClass] = + cloneableClasses[numberClass] = cloneableClasses[objectClass] = + cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; + + /** Used as an internal `_.debounce` options object */ + var debounceOptions = { + 'leading': false, + 'maxWait': 0, + 'trailing': false + }; + + /** Used as the property descriptor for `__bindData__` */ + var descriptor = { + 'configurable': false, + 'enumerable': false, + 'value': null, + 'writable': false + }; + + /** Used as the data object for `iteratorTemplate` */ + var iteratorData = { + 'args': '', + 'array': null, + 'bottom': '', + 'firstArg': '', + 'init': '', + 'keys': null, + 'loop': '', + 'shadowedProps': null, + 'support': null, + 'top': '', + 'useHas': false + }; + + /** Used to determine if values are of the language type Object */ + var objectTypes = { + 'boolean': false, + 'function': true, + 'object': true, + 'number': false, + 'string': false, + 'undefined': false + }; + + /** Used to escape characters for inclusion in compiled string literals */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\t': 't', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Used as a reference to the global object */ + var root = (objectTypes[typeof window] && window) || this; + + /** Detect free variable `exports` */ + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + + /** Detect free variable `module` */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports` */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + + /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ + var freeGlobal = objectTypes[typeof global] && global; + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { + root = freeGlobal; + } + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.indexOf` without support for binary searches + * or `fromIndex` constraints. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * An implementation of `_.contains` for cache objects that mimics the return + * signature of `_.indexOf` by returning `0` if the value is found, else `-1`. + * + * @private + * @param {Object} cache The cache object to inspect. + * @param {*} value The value to search for. + * @returns {number} Returns `0` if `value` is found, else `-1`. + */ + function cacheIndexOf(cache, value) { + var type = typeof value; + cache = cache.cache; + + if (type == 'boolean' || value == null) { + return cache[value] ? 0 : -1; + } + if (type != 'number' && type != 'string') { + type = 'object'; + } + var key = type == 'number' ? value : keyPrefix + value; + cache = (cache = cache[type]) && cache[key]; + + return type == 'object' + ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1) + : (cache ? 0 : -1); + } + + /** + * Adds a given value to the corresponding cache object. + * + * @private + * @param {*} value The value to add to the cache. + */ + function cachePush(value) { + var cache = this.cache, + type = typeof value; + + if (type == 'boolean' || value == null) { + cache[value] = true; + } else { + if (type != 'number' && type != 'string') { + type = 'object'; + } + var key = type == 'number' ? value : keyPrefix + value, + typeCache = cache[type] || (cache[type] = {}); + + if (type == 'object') { + (typeCache[key] || (typeCache[key] = [])).push(value); + } else { + typeCache[key] = true; + } + } + } + + /** + * Used by `_.max` and `_.min` as the default callback when a given + * collection is a string value. + * + * @private + * @param {string} value The character to inspect. + * @returns {number} Returns the code unit of given character. + */ + function charAtCallback(value) { + return value.charCodeAt(0); + } + + /** + * Used by `sortBy` to compare transformed `collection` elements, stable sorting + * them in ascending order. + * + * @private + * @param {Object} a The object to compare to `b`. + * @param {Object} b The object to compare to `a`. + * @returns {number} Returns the sort order indicator of `1` or `-1`. + */ + function compareAscending(a, b) { + var ac = a.criteria, + bc = b.criteria, + index = -1, + length = ac.length; + + while (++index < length) { + var value = ac[index], + other = bc[index]; + + if (value !== other) { + if (value > other || typeof value == 'undefined') { + return 1; + } + if (value < other || typeof other == 'undefined') { + return -1; + } + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to return the same value for + // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247 + // + // This also ensures a stable sort in V8 and other engines. + // See http://code.google.com/p/v8/issues/detail?id=90 + return a.index - b.index; + } + + /** + * Creates a cache object to optimize linear searches of large arrays. + * + * @private + * @param {Array} [array=[]] The array to search. + * @returns {null|Object} Returns the cache object or `null` if caching should not be used. + */ + function createCache(array) { + var index = -1, + length = array.length, + first = array[0], + mid = array[(length / 2) | 0], + last = array[length - 1]; + + if (first && typeof first == 'object' && + mid && typeof mid == 'object' && last && typeof last == 'object') { + return false; + } + var cache = getObject(); + cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false; + + var result = getObject(); + result.array = array; + result.cache = cache; + result.push = cachePush; + + while (++index < length) { + result.push(array[index]); + } + return result; + } + + /** + * Used by `template` to escape characters for inclusion in compiled + * string literals. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(match) { + return '\\' + stringEscapes[match]; + } + + /** + * Gets an array from the array pool or creates a new one if the pool is empty. + * + * @private + * @returns {Array} The array from the pool. + */ + function getArray() { + return arrayPool.pop() || []; + } + + /** + * Gets an object from the object pool or creates a new one if the pool is empty. + * + * @private + * @returns {Object} The object from the pool. + */ + function getObject() { + return objectPool.pop() || { + 'array': null, + 'cache': null, + 'criteria': null, + 'false': false, + 'index': 0, + 'null': false, + 'number': null, + 'object': null, + 'push': null, + 'string': null, + 'true': false, + 'undefined': false, + 'value': null + }; + } + + /** + * Checks if `value` is a DOM node in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`. + */ + function isNode(value) { + // IE < 9 presents DOM nodes as `Object` objects except they have `toString` + // methods that are `typeof` "string" and still can coerce nodes to strings + return typeof value.toString != 'function' && typeof (value + '') == 'string'; + } + + /** + * Releases the given array back to the array pool. + * + * @private + * @param {Array} [array] The array to release. + */ + function releaseArray(array) { + array.length = 0; + if (arrayPool.length < maxPoolSize) { + arrayPool.push(array); + } + } + + /** + * Releases the given object back to the object pool. + * + * @private + * @param {Object} [object] The object to release. + */ + function releaseObject(object) { + var cache = object.cache; + if (cache) { + releaseObject(cache); + } + object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null; + if (objectPool.length < maxPoolSize) { + objectPool.push(object); + } + } + + /** + * Slices the `collection` from the `start` index up to, but not including, + * the `end` index. + * + * Note: This function is used instead of `Array#slice` to support node lists + * in IE < 9 and to ensure dense arrays are returned. + * + * @private + * @param {Array|Object|string} collection The collection to slice. + * @param {number} start The start index. + * @param {number} end The end index. + * @returns {Array} Returns the new array. + */ + function slice(array, start, end) { + start || (start = 0); + if (typeof end == 'undefined') { + end = array ? array.length : 0; + } + var index = -1, + length = end - start || 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = array[start + index]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new `lodash` function using the given context object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} [context=root] The context object. + * @returns {Function} Returns the `lodash` function. + */ + function runInContext(context) { + // Avoid issues with some ES3 environments that attempt to use values, named + // after built-in constructors like `Object`, for the creation of literals. + // ES5 clears this up by stating that literals must use built-in constructors. + // See http://es5.github.io/#x11.1.5. + context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; + + /** Native constructor references */ + var Array = context.Array, + Boolean = context.Boolean, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Number = context.Number, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** + * Used for `Array` method references. + * + * Normally `Array.prototype` would suffice, however, using an array literal + * avoids issues in Narwhal. + */ + var arrayRef = []; + + /** Used for native method references */ + var errorProto = Error.prototype, + objectProto = Object.prototype, + stringProto = String.prototype; + + /** Used to restore the original `_` reference in `noConflict` */ + var oldDash = context._; + + /** Used to resolve the internal [[Class]] of values */ + var toString = objectProto.toString; + + /** Used to detect if a method is native */ + var reNative = RegExp('^' + + String(toString) + .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + .replace(/toString| for [^\]]+/g, '.*?') + '$' + ); + + /** Native method shortcuts */ + var ceil = Math.ceil, + clearTimeout = context.clearTimeout, + floor = Math.floor, + fnToString = Function.prototype.toString, + getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, + hasOwnProperty = objectProto.hasOwnProperty, + push = arrayRef.push, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + setTimeout = context.setTimeout, + splice = arrayRef.splice, + unshift = arrayRef.unshift; + + /** Used to set meta data on functions */ + var defineProperty = (function() { + // IE 8 only accepts DOM elements + try { + var o = {}, + func = isNative(func = Object.defineProperty) && func, + result = func(o, o, o) && func; + } catch(e) { } + return result; + }()); + + /* Native method shortcuts for methods with the same name as other `lodash` methods */ + var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, + nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, + nativeIsFinite = context.isFinite, + nativeIsNaN = context.isNaN, + nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, + nativeMax = Math.max, + nativeMin = Math.min, + nativeParseInt = context.parseInt, + nativeRandom = Math.random; + + /** Used to lookup a built-in constructor by [[Class]] */ + var ctorByClass = {}; + ctorByClass[arrayClass] = Array; + ctorByClass[boolClass] = Boolean; + ctorByClass[dateClass] = Date; + ctorByClass[funcClass] = Function; + ctorByClass[objectClass] = Object; + ctorByClass[numberClass] = Number; + ctorByClass[regexpClass] = RegExp; + ctorByClass[stringClass] = String; + + /** Used to avoid iterating non-enumerable properties in IE < 9 */ + var nonEnumProps = {}; + nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; + nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true }; + nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true }; + nonEnumProps[objectClass] = { 'constructor': true }; + + (function() { + var length = shadowedProps.length; + while (length--) { + var key = shadowedProps[length]; + for (var className in nonEnumProps) { + if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) { + nonEnumProps[className][key] = false; + } + } + } + }()); + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps the given value to enable intuitive + * method chaining. + * + * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, + * and `unshift` + * + * Chaining is supported in custom builds as long as the `value` method is + * implicitly or explicitly included in the build. + * + * The chainable wrapper functions are: + * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, + * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, + * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, + * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, + * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, + * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, + * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, + * and `zip` + * + * The non-chainable wrapper functions are: + * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`, + * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, + * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, + * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`, + * `template`, `unescape`, `uniqueId`, and `value` + * + * The wrapper functions `first` and `last` return wrapped values when `n` is + * provided, otherwise they return unwrapped values. + * + * Explicit chaining can be enabled by using the `_.chain` method. + * + * @name _ + * @constructor + * @category Chaining + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns a `lodash` instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(num) { + * return num * num; + * }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor + return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__')) + ? value + : new lodashWrapper(value); + } + + /** + * A fast path for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap in a `lodash` instance. + * @param {boolean} chainAll A flag to enable chaining for all methods + * @returns {Object} Returns a `lodash` instance. + */ + function lodashWrapper(value, chainAll) { + this.__chain__ = !!chainAll; + this.__wrapped__ = value; + } + // ensure `new lodashWrapper` is an instance of `lodash` + lodashWrapper.prototype = lodash.prototype; + + /** + * An object used to flag environments features. + * + * @static + * @memberOf _ + * @type Object + */ + var support = lodash.support = {}; + + (function() { + var ctor = function() { this.x = 1; }, + object = { '0': 1, 'length': 1 }, + props = []; + + ctor.prototype = { 'valueOf': 1, 'y': 1 }; + for (var key in new ctor) { props.push(key); } + for (key in arguments) { } + + /** + * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9). + * + * @memberOf _.support + * @type boolean + */ + support.argsClass = toString.call(arguments) == argsClass; + + /** + * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5). + * + * @memberOf _.support + * @type boolean + */ + support.argsObject = arguments.constructor == Object && !(arguments instanceof Array); + + /** + * Detect if `name` or `message` properties of `Error.prototype` are + * enumerable by default. (IE < 9, Safari < 5.1) + * + * @memberOf _.support + * @type boolean + */ + support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name'); + + /** + * Detect if `prototype` properties are enumerable by default. + * + * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 + * (if the prototype or a property on the prototype has been set) + * incorrectly sets a function's `prototype` property [[Enumerable]] + * value to `true`. + * + * @memberOf _.support + * @type boolean + */ + support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype'); + + /** + * Detect if functions can be decompiled by `Function#toString` + * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). + * + * @memberOf _.support + * @type boolean + */ + support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); + + /** + * Detect if `Function#name` is supported (all but IE). + * + * @memberOf _.support + * @type boolean + */ + support.funcNames = typeof Function.name == 'string'; + + /** + * Detect if `arguments` object indexes are non-enumerable + * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1). + * + * @memberOf _.support + * @type boolean + */ + support.nonEnumArgs = key != 0; + + /** + * Detect if properties shadowing those on `Object.prototype` are non-enumerable. + * + * In IE < 9 an objects own properties, shadowing non-enumerable ones, are + * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug). + * + * @memberOf _.support + * @type boolean + */ + support.nonEnumShadows = !/valueOf/.test(props); + + /** + * Detect if own properties are iterated after inherited properties (all but IE < 9). + * + * @memberOf _.support + * @type boolean + */ + support.ownLast = props[0] != 'x'; + + /** + * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly. + * + * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` + * and `splice()` functions that fail to remove the last element, `value[0]`, + * of array-like objects even though the `length` property is set to `0`. + * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` + * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. + * + * @memberOf _.support + * @type boolean + */ + support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]); + + /** + * Detect lack of support for accessing string characters by index. + * + * IE < 8 can't access characters by index and IE 8 can only access + * characters by index on string literals. + * + * @memberOf _.support + * @type boolean + */ + support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; + + /** + * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9) + * and that the JS engine errors when attempting to coerce an object to + * a string without a `toString` function. + * + * @memberOf _.support + * @type boolean + */ + try { + support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + '')); + } catch(e) { + support.nodeClass = true; + } + }(1)); + + /** + * By default, the template delimiters used by Lo-Dash are similar to those in + * embedded Ruby (ERB). Change the following template settings to use alternative + * delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': /<%-([\s\S]+?)%>/g, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': /<%([\s\S]+?)%>/g, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type Object + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type Function + */ + '_': lodash + } + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The template used to create iterator functions. + * + * @private + * @param {Object} data The data object used to populate the text. + * @returns {string} Returns the interpolated text. + */ + var iteratorTemplate = function(obj) { + + var __p = 'var index, iterable = ' + + (obj.firstArg) + + ', result = ' + + (obj.init) + + ';\nif (!iterable) return result;\n' + + (obj.top) + + ';'; + if (obj.array) { + __p += '\nvar length = iterable.length; index = -1;\nif (' + + (obj.array) + + ') { '; + if (support.unindexedChars) { + __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } '; + } + __p += '\n while (++index < length) {\n ' + + (obj.loop) + + ';\n }\n}\nelse { '; + } else if (support.nonEnumArgs) { + __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' + + (obj.loop) + + ';\n }\n } else { '; + } + + if (support.enumPrototypes) { + __p += '\n var skipProto = typeof iterable == \'function\';\n '; + } + + if (support.enumErrorProps) { + __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n '; + } + + var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); } + + if (obj.useHas && obj.keys) { + __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n'; + if (conditions.length) { + __p += ' if (' + + (conditions.join(' && ')) + + ') {\n '; + } + __p += + (obj.loop) + + '; '; + if (conditions.length) { + __p += '\n }'; + } + __p += '\n } '; + } else { + __p += '\n for (index in iterable) {\n'; + if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) { + __p += ' if (' + + (conditions.join(' && ')) + + ') {\n '; + } + __p += + (obj.loop) + + '; '; + if (conditions.length) { + __p += '\n }'; + } + __p += '\n } '; + if (support.nonEnumShadows) { + __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n '; + for (k = 0; k < 7; k++) { + __p += '\n index = \'' + + (obj.shadowedProps[k]) + + '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))'; + if (!obj.useHas) { + __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])'; + } + __p += ') {\n ' + + (obj.loop) + + ';\n } '; + } + __p += '\n } '; + } + + } + + if (obj.array || support.nonEnumArgs) { + __p += '\n}'; + } + __p += + (obj.bottom) + + ';\nreturn result'; + + return __p + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.bind` that creates the bound function and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new bound function. + */ + function baseBind(bindData) { + var func = bindData[0], + partialArgs = bindData[2], + thisArg = bindData[4]; + + function bound() { + // `Function#bind` spec + // http://es5.github.io/#x15.3.4.5 + if (partialArgs) { + // avoid `arguments` object deoptimizations by using `slice` instead + // of `Array.prototype.slice.call` and not assigning `arguments` to a + // variable as a ternary expression + var args = slice(partialArgs); + push.apply(args, arguments); + } + // mimic the constructor's `return` behavior + // http://es5.github.io/#x13.2.2 + if (this instanceof bound) { + // ensure `new bound` is an instance of `func` + var thisBinding = baseCreate(func.prototype), + result = func.apply(thisBinding, args || arguments); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisArg, args || arguments); + } + setBindData(bound, bindData); + return bound; + } + + /** + * The base implementation of `_.clone` without argument juggling or support + * for `thisArg` binding. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep=false] Specify a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates clones with source counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, callback, stackA, stackB) { + if (callback) { + var result = callback(value); + if (typeof result != 'undefined') { + return result; + } + } + // inspect [[Class]] + var isObj = isObject(value); + if (isObj) { + var className = toString.call(value); + if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) { + return value; + } + var ctor = ctorByClass[className]; + switch (className) { + case boolClass: + case dateClass: + return new ctor(+value); + + case numberClass: + case stringClass: + return new ctor(value); + + case regexpClass: + result = ctor(value.source, reFlags.exec(value)); + result.lastIndex = value.lastIndex; + return result; + } + } else { + return value; + } + var isArr = isArray(value); + if (isDeep) { + // check for circular references and return corresponding clone + var initedStack = !stackA; + stackA || (stackA = getArray()); + stackB || (stackB = getArray()); + + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + result = isArr ? ctor(value.length) : {}; + } + else { + result = isArr ? slice(value) : assign({}, value); + } + // add array properties assigned by `RegExp#exec` + if (isArr) { + if (hasOwnProperty.call(value, 'index')) { + result.index = value.index; + } + if (hasOwnProperty.call(value, 'input')) { + result.input = value.input; + } + } + // exit for shallow clone + if (!isDeep) { + return result; + } + // add the source value to the stack of traversed objects + // and associate it with its clone + stackA.push(value); + stackB.push(result); + + // recursively populate clone (susceptible to call stack limits) + (isArr ? baseEach : forOwn)(value, function(objValue, key) { + result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); + }); + + if (initedStack) { + releaseArray(stackA); + releaseArray(stackB); + } + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(prototype, properties) { + return isObject(prototype) ? nativeCreate(prototype) : {}; + } + // fallback for browsers without `Object.create` + if (!nativeCreate) { + baseCreate = (function() { + function Object() {} + return function(prototype) { + if (isObject(prototype)) { + Object.prototype = prototype; + var result = new Object; + Object.prototype = null; + } + return result || context.Object(); + }; + }()); + } + + /** + * The base implementation of `_.createCallback` without support for creating + * "_.pluck" or "_.where" style callbacks. + * + * @private + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + */ + function baseCreateCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + // exit early for no `thisArg` or already bound by `Function#bind` + if (typeof thisArg == 'undefined' || !('prototype' in func)) { + return func; + } + var bindData = func.__bindData__; + if (typeof bindData == 'undefined') { + if (support.funcNames) { + bindData = !func.name; + } + bindData = bindData || !support.funcDecomp; + if (!bindData) { + var source = fnToString.call(func); + if (!support.funcNames) { + bindData = !reFuncName.test(source); + } + if (!bindData) { + // checks if `func` references the `this` keyword and stores the result + bindData = reThis.test(source); + setBindData(func, bindData); + } + } + } + // exit early if there are no `this` references or `func` is bound + if (bindData === false || (bindData !== true && bindData[1] & 1)) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 2: return function(a, b) { + return func.call(thisArg, a, b); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + } + return bind(func, thisArg); + } + + /** + * The base implementation of `createWrapper` that creates the wrapper and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new function. + */ + function baseCreateWrapper(bindData) { + var func = bindData[0], + bitmask = bindData[1], + partialArgs = bindData[2], + partialRightArgs = bindData[3], + thisArg = bindData[4], + arity = bindData[5]; + + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + key = func; + + function bound() { + var thisBinding = isBind ? thisArg : this; + if (partialArgs) { + var args = slice(partialArgs); + push.apply(args, arguments); + } + if (partialRightArgs || isCurry) { + args || (args = slice(arguments)); + if (partialRightArgs) { + push.apply(args, partialRightArgs); + } + if (isCurry && args.length < arity) { + bitmask |= 16 & ~32; + return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); + } + } + args || (args = arguments); + if (isBindKey) { + func = thisBinding[key]; + } + if (this instanceof bound) { + thisBinding = baseCreate(func.prototype); + var result = func.apply(thisBinding, args); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisBinding, args); + } + setBindData(bound, bindData); + return bound; + } + + /** + * The base implementation of `_.difference` that accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to process. + * @param {Array} [values] The array of values to exclude. + * @returns {Array} Returns a new array of filtered values. + */ + function baseDifference(array, values) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + isLarge = length >= largeArraySize && indexOf === baseIndexOf, + result = []; + + if (isLarge) { + var cache = createCache(values); + if (cache) { + indexOf = cacheIndexOf; + values = cache; + } else { + isLarge = false; + } + } + while (++index < length) { + var value = array[index]; + if (indexOf(values, value) < 0) { + result.push(value); + } + } + if (isLarge) { + releaseObject(values); + } + return result; + } + + /** + * The base implementation of `_.flatten` without support for callback + * shorthands or `thisArg` binding. + * + * @private + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. + * @param {number} [fromIndex=0] The index to start from. + * @returns {Array} Returns a new flattened array. + */ + function baseFlatten(array, isShallow, isStrict, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + + if (value && typeof value == 'object' && typeof value.length == 'number' + && (isArray(value) || isArguments(value))) { + // recursively flatten arrays (susceptible to call stack limits) + if (!isShallow) { + value = baseFlatten(value, isShallow, isStrict); + } + var valIndex = -1, + valLength = value.length, + resIndex = result.length; + + result.length += valLength; + while (++valIndex < valLength) { + result[resIndex++] = value[valIndex]; + } + } else if (!isStrict) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.isEqual`, without support for `thisArg` binding, + * that allows partial "_.where" style comparisons. + * + * @private + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `a` objects. + * @param {Array} [stackB=[]] Tracks traversed `b` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { + // used to indicate that when comparing objects, `a` has at least the properties of `b` + if (callback) { + var result = callback(a, b); + if (typeof result != 'undefined') { + return !!result; + } + } + // exit early for identical values + if (a === b) { + // treat `+0` vs. `-0` as not equal + return a !== 0 || (1 / a == 1 / b); + } + var type = typeof a, + otherType = typeof b; + + // exit early for unlike primitive values + if (a === a && + !(a && objectTypes[type]) && + !(b && objectTypes[otherType])) { + return false; + } + // exit early for `null` and `undefined` avoiding ES3's Function#call behavior + // http://es5.github.io/#x15.3.4.4 + if (a == null || b == null) { + return a === b; + } + // compare [[Class]] names + var className = toString.call(a), + otherClass = toString.call(b); + + if (className == argsClass) { + className = objectClass; + } + if (otherClass == argsClass) { + otherClass = objectClass; + } + if (className != otherClass) { + return false; + } + switch (className) { + case boolClass: + case dateClass: + // coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal + return +a == +b; + + case numberClass: + // treat `NaN` vs. `NaN` as equal + return (a != +a) + ? b != +b + // but treat `+0` vs. `-0` as not equal + : (a == 0 ? (1 / a == 1 / b) : a == +b); + + case regexpClass: + case stringClass: + // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) + // treat string primitives and their corresponding object instances as equal + return a == String(b); + } + var isArr = className == arrayClass; + if (!isArr) { + // unwrap any `lodash` wrapped values + var aWrapped = hasOwnProperty.call(a, '__wrapped__'), + bWrapped = hasOwnProperty.call(b, '__wrapped__'); + + if (aWrapped || bWrapped) { + return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); + } + // exit for functions and DOM nodes + if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) { + return false; + } + // in older versions of Opera, `arguments` objects have `Array` constructors + var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor, + ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor; + + // non `Object` object instances with different constructors are not equal + if (ctorA != ctorB && + !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && + ('constructor' in a && 'constructor' in b) + ) { + return false; + } + } + // assume cyclic structures are equal + // the algorithm for detecting cyclic structures is adapted from ES 5.1 + // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) + var initedStack = !stackA; + stackA || (stackA = getArray()); + stackB || (stackB = getArray()); + + var length = stackA.length; + while (length--) { + if (stackA[length] == a) { + return stackB[length] == b; + } + } + var size = 0; + result = true; + + // add `a` and `b` to the stack of traversed objects + stackA.push(a); + stackB.push(b); + + // recursively compare objects and arrays (susceptible to call stack limits) + if (isArr) { + // compare lengths to determine if a deep comparison is necessary + length = a.length; + size = b.length; + result = size == length; + + if (result || isWhere) { + // deep compare the contents, ignoring non-numeric properties + while (size--) { + var index = length, + value = b[size]; + + if (isWhere) { + while (index--) { + if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } + } + else { + // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` + // which, in this case, is more costly + forIn(b, function(value, key, b) { + if (hasOwnProperty.call(b, key)) { + // count the number of properties. + size++; + // deep compare each property value. + return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); + } + }); + + if (result && !isWhere) { + // ensure both objects have the same number of properties + forIn(a, function(value, key, a) { + if (hasOwnProperty.call(a, key)) { + // `size` will be `-1` if `a` has more properties than `b` + return (result = --size > -1); + } + }); + } + } + stackA.pop(); + stackB.pop(); + + if (initedStack) { + releaseArray(stackA); + releaseArray(stackB); + } + return result; + } + + /** + * The base implementation of `_.merge` without argument juggling or support + * for `thisArg` binding. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} [callback] The function to customize merging properties. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + */ + function baseMerge(object, source, callback, stackA, stackB) { + (isArray(source) ? forEach : forOwn)(source, function(source, key) { + var found, + isArr, + result = source, + value = object[key]; + + if (source && ((isArr = isArray(source)) || isPlainObject(source))) { + // avoid merging previously merged cyclic sources + var stackLength = stackA.length; + while (stackLength--) { + if ((found = stackA[stackLength] == source)) { + value = stackB[stackLength]; + break; + } + } + if (!found) { + var isShallow; + if (callback) { + result = callback(value, source); + if ((isShallow = typeof result != 'undefined')) { + value = result; + } + } + if (!isShallow) { + value = isArr + ? (isArray(value) ? value : []) + : (isPlainObject(value) ? value : {}); + } + // add `source` and associated `value` to the stack of traversed objects + stackA.push(source); + stackB.push(value); + + // recursively merge objects and arrays (susceptible to call stack limits) + if (!isShallow) { + baseMerge(value, source, callback, stackA, stackB); + } + } + } + else { + if (callback) { + result = callback(value, source); + if (typeof result == 'undefined') { + result = source; + } + } + if (typeof result != 'undefined') { + value = result; + } + } + object[key] = value; + }); + } + + /** + * The base implementation of `_.random` without argument juggling or support + * for returning floating-point numbers. + * + * @private + * @param {number} min The minimum possible value. + * @param {number} max The maximum possible value. + * @returns {number} Returns a random number. + */ + function baseRandom(min, max) { + return min + floor(nativeRandom() * (max - min + 1)); + } + + /** + * The base implementation of `_.uniq` without support for callback shorthands + * or `thisArg` binding. + * + * @private + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function} [callback] The function called per iteration. + * @returns {Array} Returns a duplicate-value-free array. + */ + function baseUniq(array, isSorted, callback) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + result = []; + + var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf, + seen = (callback || isLarge) ? getArray() : result; + + if (isLarge) { + var cache = createCache(seen); + indexOf = cacheIndexOf; + seen = cache; + } + while (++index < length) { + var value = array[index], + computed = callback ? callback(value, index, array) : value; + + if (isSorted + ? !index || seen[seen.length - 1] !== computed + : indexOf(seen, computed) < 0 + ) { + if (callback || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + if (isLarge) { + releaseArray(seen.array); + releaseObject(seen); + } else if (callback) { + releaseArray(seen); + } + return result; + } + + /** + * Creates a function that aggregates a collection, creating an object composed + * of keys generated from the results of running each element of the collection + * through a callback. The given `setter` function sets the keys and values + * of the composed object. + * + * @private + * @param {Function} setter The setter function. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter) { + return function(collection, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + setter(result, value, callback(value, index, collection), collection); + } + } else { + baseEach(collection, function(value, key, collection) { + setter(result, value, callback(value, key, collection), collection); + }); + } + return result; + }; + } + + /** + * Creates a function that, when called, either curries or invokes `func` + * with an optional `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of method flags to compose. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` + * 8 - `_.curry` (bound) + * 16 - `_.partial` + * 32 - `_.partialRight` + * @param {Array} [partialArgs] An array of arguments to prepend to those + * provided to the new function. + * @param {Array} [partialRightArgs] An array of arguments to append to those + * provided to the new function. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new function. + */ + function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + isPartial = bitmask & 16, + isPartialRight = bitmask & 32; + + if (!isBindKey && !isFunction(func)) { + throw new TypeError; + } + if (isPartial && !partialArgs.length) { + bitmask &= ~16; + isPartial = partialArgs = false; + } + if (isPartialRight && !partialRightArgs.length) { + bitmask &= ~32; + isPartialRight = partialRightArgs = false; + } + var bindData = func && func.__bindData__; + if (bindData && bindData !== true) { + // clone `bindData` + bindData = slice(bindData); + if (bindData[2]) { + bindData[2] = slice(bindData[2]); + } + if (bindData[3]) { + bindData[3] = slice(bindData[3]); + } + // set `thisBinding` is not previously bound + if (isBind && !(bindData[1] & 1)) { + bindData[4] = thisArg; + } + // set if previously bound but not currently (subsequent curried functions) + if (!isBind && bindData[1] & 1) { + bitmask |= 8; + } + // set curried arity if not yet set + if (isCurry && !(bindData[1] & 4)) { + bindData[5] = arity; + } + // append partial left arguments + if (isPartial) { + push.apply(bindData[2] || (bindData[2] = []), partialArgs); + } + // append partial right arguments + if (isPartialRight) { + unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); + } + // merge flags + bindData[1] |= bitmask; + return createWrapper.apply(null, bindData); + } + // fast path for `_.bind` + var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; + return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); + } + + /** + * Creates compiled iteration functions. + * + * @private + * @param {...Object} [options] The compile options object(s). + * @param {string} [options.array] Code to determine if the iterable is an array or array-like. + * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop. + * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration. + * @param {string} [options.args] A comma separated string of iteration function arguments. + * @param {string} [options.top] Code to execute before the iteration branches. + * @param {string} [options.loop] Code to execute in the object loop. + * @param {string} [options.bottom] Code to execute after the iteration branches. + * @returns {Function} Returns the compiled function. + */ + function createIterator() { + // data properties + iteratorData.shadowedProps = shadowedProps; + + // iterator options + iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = ''; + iteratorData.init = 'iterable'; + iteratorData.useHas = true; + + // merge options into a template data object + for (var object, index = 0; object = arguments[index]; index++) { + for (var key in object) { + iteratorData[key] = object[key]; + } + } + var args = iteratorData.args; + iteratorData.firstArg = /^[^,]+/.exec(args)[0]; + + // create the function factory + var factory = Function( + 'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' + + 'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' + + 'objectTypes, nonEnumProps, stringClass, stringProto, toString', + 'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}' + ); + + // return the compiled function + return factory( + baseCreateCallback, errorClass, errorProto, hasOwnProperty, + indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto, + objectTypes, nonEnumProps, stringClass, stringProto, toString + ); + } + + /** + * Used by `escape` to convert characters to HTML entities. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(match) { + return htmlEscapes[match]; + } + + /** + * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * customized, this method returns the custom method, otherwise it returns + * the `baseIndexOf` function. + * + * @private + * @returns {Function} Returns the "indexOf" function. + */ + function getIndexOf() { + var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; + return result; + } + + /** + * Checks if `value` is a native function. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. + */ + function isNative(value) { + return typeof value == 'function' && reNative.test(value); + } + + /** + * Sets `this` binding data on a given function. + * + * @private + * @param {Function} func The function to set data on. + * @param {Array} value The data array to set. + */ + var setBindData = !defineProperty ? noop : function(func, value) { + descriptor.value = value; + defineProperty(func, '__bindData__', descriptor); + descriptor.value = null; + }; + + /** + * A fallback implementation of `isPlainObject` which checks if a given value + * is an object created by the `Object` constructor, assuming objects created + * by the `Object` constructor have no inherited enumerable properties and that + * there are no `Object.prototype` extensions. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + */ + function shimIsPlainObject(value) { + var ctor, + result; + + // avoid non Object objects, `arguments` objects, and DOM elements + if (!(value && toString.call(value) == objectClass) || + (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) || + (!support.argsClass && isArguments(value)) || + (!support.nodeClass && isNode(value))) { + return false; + } + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + if (support.ownLast) { + forIn(value, function(value, key, object) { + result = hasOwnProperty.call(object, key); + return false; + }); + return result !== false; + } + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + forIn(value, function(value, key) { + result = key; + }); + return typeof result == 'undefined' || hasOwnProperty.call(value, result); + } + + /** + * Used by `unescape` to convert HTML entities to characters. + * + * @private + * @param {string} match The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(match) { + return htmlUnescapes[match]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Checks if `value` is an `arguments` object. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. + * @example + * + * (function() { return _.isArguments(arguments); })(1, 2, 3); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == argsClass || false; + } + // fallback for browsers that can't detect `arguments` objects by [[Class]] + if (!support.argsClass) { + isArguments = function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false; + }; + } + + /** + * Checks if `value` is an array. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an array, else `false`. + * @example + * + * (function() { return _.isArray(arguments); })(); + * // => false + * + * _.isArray([1, 2, 3]); + * // => true + */ + var isArray = nativeIsArray || function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == arrayClass || false; + }; + + /** + * A fallback implementation of `Object.keys` which produces an array of the + * given object's own enumerable property names. + * + * @private + * @type Function + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + */ + var shimKeys = createIterator({ + 'args': 'object', + 'init': '[]', + 'top': 'if (!(objectTypes[typeof object])) return result', + 'loop': 'result.push(index)' + }); + + /** + * Creates an array composed of the own enumerable property names of an object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + * @example + * + * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); + * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) + */ + var keys = !nativeKeys ? shimKeys : function(object) { + if (!isObject(object)) { + return []; + } + if ((support.enumPrototypes && typeof object == 'function') || + (support.nonEnumArgs && object.length && isArguments(object))) { + return shimKeys(object); + } + return nativeKeys(object); + }; + + /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */ + var eachIteratorOptions = { + 'args': 'collection, callback, thisArg', + 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)", + 'array': "typeof length == 'number'", + 'keys': keys, + 'loop': 'if (callback(iterable[index], index, collection) === false) return result' + }; + + /** Reusable iterator options for `assign` and `defaults` */ + var defaultsIteratorOptions = { + 'args': 'object, source, guard', + 'top': + 'var args = arguments,\n' + + ' argsIndex = 0,\n' + + " argsLength = typeof guard == 'number' ? 2 : args.length;\n" + + 'while (++argsIndex < argsLength) {\n' + + ' iterable = args[argsIndex];\n' + + ' if (iterable && objectTypes[typeof iterable]) {', + 'keys': keys, + 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]", + 'bottom': ' }\n}' + }; + + /** Reusable iterator options for `forIn` and `forOwn` */ + var forOwnIteratorOptions = { + 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top, + 'array': false + }; + + /** + * Used to convert characters to HTML entities: + * + * Though the `>` character is escaped for symmetry, characters like `>` and `/` + * don't require escaping in HTML and have no special meaning unless they're part + * of a tag or an unquoted attribute value. + * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") + */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + /** Used to convert HTML entities to characters */ + var htmlUnescapes = invert(htmlEscapes); + + /** Used to match HTML entities and HTML characters */ + var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), + reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); + + /** + * A function compiled to iterate `arguments` objects, arrays, objects, and + * strings consistenly across environments, executing the callback for each + * element in the collection. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index|key, collection). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @private + * @type Function + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEach = createIterator(eachIteratorOptions); + + /*--------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources will overwrite property assignments of previous + * sources. If a callback is provided it will be executed to produce the + * assigned values. The callback is bound to `thisArg` and invoked with two + * arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @type Function + * @alias extend + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param {Function} [callback] The function to customize assigning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); + * // => { 'name': 'fred', 'employer': 'slate' } + * + * var defaults = _.partialRight(_.assign, function(a, b) { + * return typeof a == 'undefined' ? b : a; + * }); + * + * var object = { 'name': 'barney' }; + * defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + var assign = createIterator(defaultsIteratorOptions, { + 'top': + defaultsIteratorOptions.top.replace(';', + ';\n' + + "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" + + ' var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' + + "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" + + ' callback = args[--argsLength];\n' + + '}' + ), + 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]' + }); + + /** + * Creates a clone of `value`. If `isDeep` is `true` nested objects will also + * be cloned, otherwise they will be assigned by reference. If a callback + * is provided it will be executed to produce the cloned values. If the + * callback returns `undefined` cloning will be handled by the method instead. + * The callback is bound to `thisArg` and invoked with one argument; (value). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to clone. + * @param {boolean} [isDeep=false] Specify a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the cloned value. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * var shallow = _.clone(characters); + * shallow[0] === characters[0]; + * // => true + * + * var deep = _.clone(characters, true); + * deep[0] === characters[0]; + * // => false + * + * _.mixin({ + * 'clone': _.partialRight(_.clone, function(value) { + * return _.isElement(value) ? value.cloneNode(false) : undefined; + * }) + * }); + * + * var clone = _.clone(document.body); + * clone.childNodes.length; + * // => 0 + */ + function clone(value, isDeep, callback, thisArg) { + // allows working with "Collections" methods without using their `index` + // and `collection` arguments for `isDeep` and `callback` + if (typeof isDeep != 'boolean' && isDeep != null) { + thisArg = callback; + callback = isDeep; + isDeep = false; + } + return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + } + + /** + * Creates a deep clone of `value`. If a callback is provided it will be + * executed to produce the cloned values. If the callback returns `undefined` + * cloning will be handled by the method instead. The callback is bound to + * `thisArg` and invoked with one argument; (value). + * + * Note: This method is loosely based on the structured clone algorithm. Functions + * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and + * objects created by constructors other than `Object` are cloned to plain `Object` objects. + * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the deep cloned value. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * var deep = _.cloneDeep(characters); + * deep[0] === characters[0]; + * // => false + * + * var view = { + * 'label': 'docs', + * 'node': element + * }; + * + * var clone = _.cloneDeep(view, function(value) { + * return _.isElement(value) ? value.cloneNode(true) : undefined; + * }); + * + * clone.node == view.node; + * // => false + */ + function cloneDeep(value, callback, thisArg) { + return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + } + + /** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties ? assign(result, properties) : result; + } + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional defaults of the same property will be ignored. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param- {Object} [guard] Allows working with `_.reduce` without using its + * `key` and `object` arguments as sources. + * @returns {Object} Returns the destination object. + * @example + * + * var object = { 'name': 'barney' }; + * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + var defaults = createIterator(defaultsIteratorOptions); + + /** + * This method is like `_.findIndex` except that it returns the key of the + * first element that passes the callback check, instead of the element itself. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to search. + * @param {Function|Object|string} [callback=identity] The function called per + * iteration. If a property name or object is provided it will be used to + * create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @example + * + * var characters = { + * 'barney': { 'age': 36, 'blocked': false }, + * 'fred': { 'age': 40, 'blocked': true }, + * 'pebbles': { 'age': 1, 'blocked': false } + * }; + * + * _.findKey(characters, function(chr) { + * return chr.age < 40; + * }); + * // => 'barney' (property order is not guaranteed across environments) + * + * // using "_.where" callback shorthand + * _.findKey(characters, { 'age': 1 }); + * // => 'pebbles' + * + * // using "_.pluck" callback shorthand + * _.findKey(characters, 'blocked'); + * // => 'fred' + */ + function findKey(object, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forOwn(object, function(value, key, object) { + if (callback(value, key, object)) { + result = key; + return false; + } + }); + return result; + } + + /** + * This method is like `_.findKey` except that it iterates over elements + * of a `collection` in the opposite order. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to search. + * @param {Function|Object|string} [callback=identity] The function called per + * iteration. If a property name or object is provided it will be used to + * create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @example + * + * var characters = { + * 'barney': { 'age': 36, 'blocked': true }, + * 'fred': { 'age': 40, 'blocked': false }, + * 'pebbles': { 'age': 1, 'blocked': true } + * }; + * + * _.findLastKey(characters, function(chr) { + * return chr.age < 40; + * }); + * // => returns `pebbles`, assuming `_.findKey` returns `barney` + * + * // using "_.where" callback shorthand + * _.findLastKey(characters, { 'age': 40 }); + * // => 'fred' + * + * // using "_.pluck" callback shorthand + * _.findLastKey(characters, 'blocked'); + * // => 'pebbles' + */ + function findLastKey(object, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forOwnRight(object, function(value, key, object) { + if (callback(value, key, object)) { + result = key; + return false; + } + }); + return result; + } + + /** + * Iterates over own and inherited enumerable properties of an object, + * executing the callback for each property. The callback is bound to `thisArg` + * and invoked with three arguments; (value, key, object). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forIn(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) + */ + var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, { + 'useHas': false + }); + + /** + * This method is like `_.forIn` except that it iterates over elements + * of a `collection` in the opposite order. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forInRight(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' + */ + function forInRight(object, callback, thisArg) { + var pairs = []; + + forIn(object, function(value, key) { + pairs.push(key, value); + }); + + var length = pairs.length; + callback = baseCreateCallback(callback, thisArg, 3); + while (length--) { + if (callback(pairs[length--], pairs[length], object) === false) { + break; + } + } + return object; + } + + /** + * Iterates over own enumerable properties of an object, executing the callback + * for each property. The callback is bound to `thisArg` and invoked with three + * arguments; (value, key, object). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) + */ + var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions); + + /** + * This method is like `_.forOwn` except that it iterates over elements + * of a `collection` in the opposite order. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' + */ + function forOwnRight(object, callback, thisArg) { + var props = keys(object), + length = props.length; + + callback = baseCreateCallback(callback, thisArg, 3); + while (length--) { + var key = props[length]; + if (callback(object[key], key, object) === false) { + break; + } + } + return object; + } + + /** + * Creates a sorted array of property names of all enumerable properties, + * own and inherited, of `object` that have function values. + * + * @static + * @memberOf _ + * @alias methods + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names that have function values. + * @example + * + * _.functions(_); + * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] + */ + function functions(object) { + var result = []; + forIn(object, function(value, key) { + if (isFunction(value)) { + result.push(key); + } + }); + return result.sort(); + } + + /** + * Checks if the specified property name exists as a direct property of `object`, + * instead of an inherited property. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to check. + * @returns {boolean} Returns `true` if key is a direct property, else `false`. + * @example + * + * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); + * // => true + */ + function has(object, key) { + return object ? hasOwnProperty.call(object, key) : false; + } + + /** + * Creates an object composed of the inverted keys and values of the given object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to invert. + * @returns {Object} Returns the created inverted object. + * @example + * + * _.invert({ 'first': 'fred', 'second': 'barney' }); + * // => { 'fred': 'first', 'barney': 'second' } + */ + function invert(object) { + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + result[object[key]] = key; + } + return result; + } + + /** + * Checks if `value` is a boolean value. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. + * @example + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + value && typeof value == 'object' && toString.call(value) == boolClass || false; + } + + /** + * Checks if `value` is a date. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a date, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + */ + function isDate(value) { + return value && typeof value == 'object' && toString.call(value) == dateClass || false; + } + + /** + * Checks if `value` is a DOM element. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + */ + function isElement(value) { + return value && value.nodeType === 1 || false; + } + + /** + * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a + * length of `0` and objects with no own enumerable properties are considered + * "empty". + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if the `value` is empty, else `false`. + * @example + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({}); + * // => true + * + * _.isEmpty(''); + * // => true + */ + function isEmpty(value) { + var result = true; + if (!value) { + return result; + } + var className = toString.call(value), + length = value.length; + + if ((className == arrayClass || className == stringClass || + (support.argsClass ? className == argsClass : isArguments(value))) || + (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { + return !length; + } + forOwn(value, function() { + return (result = false); + }); + return result; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent to each other. If a callback is provided it will be executed + * to compare values. If the callback returns `undefined` comparisons will + * be handled by the method instead. The callback is bound to `thisArg` and + * invoked with two arguments; (a, b). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'name': 'fred' }; + * var copy = { 'name': 'fred' }; + * + * object == copy; + * // => false + * + * _.isEqual(object, copy); + * // => true + * + * var words = ['hello', 'goodbye']; + * var otherWords = ['hi', 'goodbye']; + * + * _.isEqual(words, otherWords, function(a, b) { + * var reGreet = /^(?:hello|hi)$/i, + * aGreet = _.isString(a) && reGreet.test(a), + * bGreet = _.isString(b) && reGreet.test(b); + * + * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; + * }); + * // => true + */ + function isEqual(a, b, callback, thisArg) { + return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2)); + } + + /** + * Checks if `value` is, or can be coerced to, a finite number. + * + * Note: This is not the same as native `isFinite` which will return true for + * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is finite, else `false`. + * @example + * + * _.isFinite(-101); + * // => true + * + * _.isFinite('10'); + * // => true + * + * _.isFinite(true); + * // => false + * + * _.isFinite(''); + * // => false + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); + } + + /** + * Checks if `value` is a function. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + */ + function isFunction(value) { + return typeof value == 'function'; + } + // fallback for older versions of Chrome and Safari + if (isFunction(/x/)) { + isFunction = function(value) { + return typeof value == 'function' && toString.call(value) == funcClass; + }; + } + + /** + * Checks if `value` is the language type of Object. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ + function isObject(value) { + // check if the value is the ECMAScript language type of Object + // http://es5.github.io/#x8 + // and avoid a V8 bug + // http://code.google.com/p/v8/issues/detail?id=2291 + return !!(value && objectTypes[typeof value]); + } + + /** + * Checks if `value` is `NaN`. + * + * Note: This is not the same as native `isNaN` which will return `true` for + * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // `NaN` as a primitive is the only value that is not equal to itself + // (perform the [[Class]] check first to avoid errors with some host objects in IE) + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(undefined); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is a number. + * + * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a number, else `false`. + * @example + * + * _.isNumber(8.4 * 5); + * // => true + */ + function isNumber(value) { + return typeof value == 'number' || + value && typeof value == 'object' && toString.call(value) == numberClass || false; + } + + /** + * Checks if `value` is an object created by the `Object` constructor. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * _.isPlainObject(new Shape); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + */ + var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { + if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) { + return false; + } + var valueOf = value.valueOf, + objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); + + return objProto + ? (value == objProto || getPrototypeOf(value) == objProto) + : shimIsPlainObject(value); + }; + + /** + * Checks if `value` is a regular expression. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. + * @example + * + * _.isRegExp(/fred/); + * // => true + */ + function isRegExp(value) { + return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false; + } + + /** + * Checks if `value` is a string. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a string, else `false`. + * @example + * + * _.isString('fred'); + * // => true + */ + function isString(value) { + return typeof value == 'string' || + value && typeof value == 'object' && toString.call(value) == stringClass || false; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + */ + function isUndefined(value) { + return typeof value == 'undefined'; + } + + /** + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through the callback. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new object with values of the results of each `callback` execution. + * @example + * + * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + * + * var characters = { + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * }; + * + * // using "_.pluck" callback shorthand + * _.mapValues(characters, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } + */ + function mapValues(object, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + + forOwn(object, function(value, key, object) { + result[key] = callback(value, key, object); + }); + return result; + } + + /** + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * will overwrite property assignments of previous sources. If a callback is + * provided it will be executed to produce the merged values of the destination + * and source properties. If the callback returns `undefined` merging will + * be handled by the method instead. The callback is bound to `thisArg` and + * invoked with two arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param {Function} [callback] The function to customize merging properties. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * var names = { + * 'characters': [ + * { 'name': 'barney' }, + * { 'name': 'fred' } + * ] + * }; + * + * var ages = { + * 'characters': [ + * { 'age': 36 }, + * { 'age': 40 } + * ] + * }; + * + * _.merge(names, ages); + * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } + * + * var food = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var otherFood = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(food, otherFood, function(a, b) { + * return _.isArray(a) ? a.concat(b) : undefined; + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } + */ + function merge(object) { + var args = arguments, + length = 2; + + if (!isObject(object)) { + return object; + } + // allows working with `_.reduce` and `_.reduceRight` without using + // their `index` and `collection` arguments + if (typeof args[2] != 'number') { + length = args.length; + } + if (length > 3 && typeof args[length - 2] == 'function') { + var callback = baseCreateCallback(args[--length - 1], args[length--], 2); + } else if (length > 2 && typeof args[length - 1] == 'function') { + callback = args[--length]; + } + var sources = slice(arguments, 1, length), + index = -1, + stackA = getArray(), + stackB = getArray(); + + while (++index < length) { + baseMerge(object, sources[index], callback, stackA, stackB); + } + releaseArray(stackA); + releaseArray(stackB); + return object; + } + + /** + * Creates a shallow clone of `object` excluding the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` omitting the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The properties to omit or the + * function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object without the omitted properties. + * @example + * + * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); + * // => { 'name': 'fred' } + * + * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { + * return typeof value == 'number'; + * }); + * // => { 'name': 'fred' } + */ + function omit(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var props = []; + forIn(object, function(value, key) { + props.push(key); + }); + props = baseDifference(props, baseFlatten(arguments, true, false, 1)); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + result[key] = object[key]; + } + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (!callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * Creates a two dimensional array of an object's key-value pairs, + * i.e. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns new array of key-value pairs. + * @example + * + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) + */ + function pairs(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; + } + + /** + * Creates a shallow clone of `object` composed of the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` picking the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The function called per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object composed of the picked properties. + * @example + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); + * // => { 'name': 'fred' } + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { + * return key.charAt(0) != '_'; + * }); + * // => { 'name': 'fred' } + */ + function pick(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var index = -1, + props = baseFlatten(arguments, true, false, 1), + length = isObject(object) ? props.length : 0; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * An alternative to `_.reduce` this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own + * enumerable properties through a callback, with each callback execution + * potentially mutating the `accumulator` object. The callback is bound to + * `thisArg` and invoked with four arguments; (accumulator, value, key, object). + * Callbacks may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) { + * num *= num; + * if (num % 2) { + * return result.push(num) < 3; + * } + * }); + * // => [1, 9, 25] + * + * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function transform(object, callback, accumulator, thisArg) { + var isArr = isArray(object); + if (accumulator == null) { + if (isArr) { + accumulator = []; + } else { + var ctor = object && object.constructor, + proto = ctor && ctor.prototype; + + accumulator = baseCreate(proto); + } + } + if (callback) { + callback = lodash.createCallback(callback, thisArg, 4); + (isArr ? baseEach : forOwn)(object, function(value, index, object) { + return callback(accumulator, value, index, object); + }); + } + return accumulator; + } + + /** + * Creates an array composed of the own enumerable property values of `object`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property values. + * @example + * + * _.values({ 'one': 1, 'two': 2, 'three': 3 }); + * // => [1, 2, 3] (property order is not guaranteed across environments) + */ + function values(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array of elements from the specified indexes, or keys, of the + * `collection`. Indexes may be specified as individual arguments or as arrays + * of indexes. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [index] The indexes of `collection` + * to retrieve, specified as individual indexes or arrays of indexes. + * @returns {Array} Returns a new array of elements corresponding to the + * provided indexes. + * @example + * + * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); + * // => ['a', 'c', 'e'] + * + * _.at(['fred', 'barney', 'pebbles'], 0, 2); + * // => ['fred', 'pebbles'] + */ + function at(collection) { + var args = arguments, + index = -1, + props = baseFlatten(args, true, false, 1), + length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length, + result = Array(length); + + if (support.unindexedChars && isString(collection)) { + collection = collection.split(''); + } + while(++index < length) { + result[index] = collection[props[index]]; + } + return result; + } + + /** + * Checks if a given value is present in a collection using strict equality + * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the + * offset from the end of the collection. + * + * @static + * @memberOf _ + * @alias include + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {*} target The value to check for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {boolean} Returns `true` if the `target` element is found, else `false`. + * @example + * + * _.contains([1, 2, 3], 1); + * // => true + * + * _.contains([1, 2, 3], 1, 2); + * // => false + * + * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.contains('pebbles', 'eb'); + * // => true + */ + function contains(collection, target, fromIndex) { + var index = -1, + indexOf = getIndexOf(), + length = collection ? collection.length : 0, + result = false; + + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; + if (isArray(collection)) { + result = indexOf(collection, target, fromIndex) > -1; + } else if (typeof length == 'number') { + result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1; + } else { + baseEach(collection, function(value) { + if (++index >= fromIndex) { + return !(result = value === target); + } + }); + } + return result; + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through the callback. The corresponding value + * of each key is the number of times the key was returned by the callback. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); + }); + + /** + * Checks if the given callback returns truey value for **all** elements of + * a collection. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if all elements passed the callback check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes']); + * // => false + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.every(characters, 'age'); + * // => true + * + * // using "_.where" callback shorthand + * _.every(characters, { 'age': 36 }); + * // => false + */ + function every(collection, callback, thisArg) { + var result = true; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (!(result = !!callback(collection[index], index, collection))) { + break; + } + } + } else { + baseEach(collection, function(value, index, collection) { + return (result = !!callback(value, index, collection)); + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning an array of all elements + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that passed the callback check. + * @example + * + * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [2, 4, 6] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.filter(characters, 'blocked'); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + * + * // using "_.where" callback shorthand + * _.filter(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + */ + function filter(collection, callback, thisArg) { + var result = []; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + result.push(value); + } + } + } else { + baseEach(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result.push(value); + } + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning the first element that + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias detect, findWhere + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.find(characters, function(chr) { + * return chr.age < 40; + * }); + * // => { 'name': 'barney', 'age': 36, 'blocked': false } + * + * // using "_.where" callback shorthand + * _.find(characters, { 'age': 1 }); + * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } + * + * // using "_.pluck" callback shorthand + * _.find(characters, 'blocked'); + * // => { 'name': 'fred', 'age': 40, 'blocked': true } + */ + function find(collection, callback, thisArg) { + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + return value; + } + } + } else { + var result; + baseEach(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + } + + /** + * This method is like `_.find` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(num) { + * return num % 2 == 1; + * }); + * // => 3 + */ + function findLast(collection, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forEachRight(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + + /** + * Iterates over elements of a collection, executing the callback for each + * element. The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * Note: As with other "Collections" methods, objects with a `length` property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); + * // => logs each number and returns '1,2,3' + * + * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); + * // => logs each number and returns the object (property order is not guaranteed across environments) + */ + function forEach(collection, callback, thisArg) { + if (callback && typeof thisArg == 'undefined' && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (callback(collection[index], index, collection) === false) { + break; + } + } + } else { + baseEach(collection, callback, thisArg); + } + return collection; + } + + /** + * This method is like `_.forEach` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); + * // => logs each number from right to left and returns '3,2,1' + */ + function forEachRight(collection, callback, thisArg) { + var iterable = collection, + length = collection ? collection.length : 0; + + callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); + if (isArray(collection)) { + while (length--) { + if (callback(collection[length], length, collection) === false) { + break; + } + } + } else { + if (typeof length != 'number') { + var props = keys(collection); + length = props.length; + } else if (support.unindexedChars && isString(collection)) { + iterable = collection.split(''); + } + baseEach(collection, function(value, key, collection) { + key = props ? props[--length] : --length; + return callback(iterable[key], key, collection); + }); + } + return collection; + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of a collection through the callback. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false` + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using "_.pluck" callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of the collection through the given callback. The corresponding + * value of each key is the last element responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keys = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keys, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Invokes the method named by `methodName` on each element in the `collection` + * returning an array of the results of each invoked method. Additional arguments + * will be provided to each invoked method. If `methodName` is a function it + * will be invoked for, and `this` bound to, each element in the `collection`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|string} methodName The name of the method to invoke or + * the function invoked per iteration. + * @param {...*} [arg] Arguments to invoke the method with. + * @returns {Array} Returns a new array of the results of each invoked method. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + function invoke(collection, methodName) { + var args = slice(arguments, 2), + index = -1, + isFunc = typeof methodName == 'function', + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); + }); + return result; + } + + /** + * Creates an array of values by running each element in the collection + * through the callback. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias collect + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of the results of each `callback` execution. + * @example + * + * _.map([1, 2, 3], function(num) { return num * 3; }); + * // => [3, 6, 9] + * + * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); + * // => [3, 6, 9] (property order is not guaranteed across environments) + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(characters, 'name'); + * // => ['barney', 'fred'] + */ + function map(collection, callback, thisArg) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + callback = lodash.createCallback(callback, thisArg, 3); + if (isArray(collection)) { + while (++index < length) { + result[index] = callback(collection[index], index, collection); + } + } else { + baseEach(collection, function(value, key, collection) { + result[++index] = callback(value, key, collection); + }); + } + return result; + } + + /** + * Retrieves the maximum value of a collection. If the collection is empty or + * falsey `-Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.max(characters, function(chr) { return chr.age; }); + * // => { 'name': 'fred', 'age': 40 }; + * + * // using "_.pluck" callback shorthand + * _.max(characters, 'age'); + * // => { 'name': 'fred', 'age': 40 }; + */ + function max(collection, callback, thisArg) { + var computed = -Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value > result) { + result = value; + } + } + } else { + callback = (callback == null && isString(collection)) + ? charAtCallback + : lodash.createCallback(callback, thisArg, 3); + + baseEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current > computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the minimum value of a collection. If the collection is empty or + * falsey `Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.min(characters, function(chr) { return chr.age; }); + * // => { 'name': 'barney', 'age': 36 }; + * + * // using "_.pluck" callback shorthand + * _.min(characters, 'age'); + * // => { 'name': 'barney', 'age': 36 }; + */ + function min(collection, callback, thisArg) { + var computed = Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value < result) { + result = value; + } + } + } else { + callback = (callback == null && isString(collection)) + ? charAtCallback + : lodash.createCallback(callback, thisArg, 3); + + baseEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current < computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the value of a specified property from all elements in the collection. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {string} property The name of the property to pluck. + * @returns {Array} Returns a new array of property values. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.pluck(characters, 'name'); + * // => ['barney', 'fred'] + */ + var pluck = map; + + /** + * Reduces a collection to a value which is the accumulated result of running + * each element in the collection through the callback, where each successive + * callback execution consumes the return value of the previous execution. If + * `accumulator` is not provided the first element of the collection will be + * used as the initial `accumulator` value. The callback is bound to `thisArg` + * and invoked with four arguments; (accumulator, value, index|key, collection). + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var sum = _.reduce([1, 2, 3], function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function reduce(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = lodash.createCallback(callback, thisArg, 4); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + if (noaccum) { + accumulator = collection[++index]; + } + while (++index < length) { + accumulator = callback(accumulator, collection[index], index, collection); + } + } else { + baseEach(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection) + }); + } + return accumulator; + } + + /** + * This method is like `_.reduce` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var list = [[0, 1], [2, 3], [4, 5]]; + * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + function reduceRight(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = lodash.createCallback(callback, thisArg, 4); + forEachRight(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The opposite of `_.filter` this method returns the elements of a + * collection that the callback does **not** return truey for. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that failed the callback check. + * @example + * + * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [1, 3, 5] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.reject(characters, 'blocked'); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + * + * // using "_.where" callback shorthand + * _.reject(characters, { 'age': 36 }); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + */ + function reject(collection, callback, thisArg) { + callback = lodash.createCallback(callback, thisArg, 3); + return filter(collection, function(value, index, collection) { + return !callback(value, index, collection); + }); + } + + /** + * Retrieves a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Allows working with functions like `_.map` + * without using their `index` arguments as `n`. + * @returns {Array} Returns the random sample(s) of `collection`. + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ + function sample(collection, n, guard) { + if (collection && typeof collection.length != 'number') { + collection = values(collection); + } else if (support.unindexedChars && isString(collection)) { + collection = collection.split(''); + } + if (n == null || guard) { + return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; + } + var result = shuffle(collection); + result.length = nativeMin(nativeMax(0, n), result.length); + return result; + } + + /** + * Creates an array of shuffled values, using a version of the Fisher-Yates + * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns a new shuffled collection. + * @example + * + * _.shuffle([1, 2, 3, 4, 5, 6]); + * // => [4, 1, 6, 3, 5, 2] + */ + function shuffle(collection) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + var rand = baseRandom(0, ++index); + result[index] = result[rand]; + result[rand] = value; + }); + return result; + } + + /** + * Gets the size of the `collection` by returning `collection.length` for arrays + * and array-like objects or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns `collection.length` or number of own enumerable properties. + * @example + * + * _.size([1, 2]); + * // => 2 + * + * _.size({ 'one': 1, 'two': 2, 'three': 3 }); + * // => 3 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + var length = collection ? collection.length : 0; + return typeof length == 'number' ? length : keys(collection).length; + } + + /** + * Checks if the callback returns a truey value for **any** element of a + * collection. The function returns as soon as it finds a passing value and + * does not iterate over the entire collection. The callback is bound to + * `thisArg` and invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if any element passed the callback check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.some(characters, 'blocked'); + * // => true + * + * // using "_.where" callback shorthand + * _.some(characters, { 'age': 1 }); + * // => false + */ + function some(collection, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if ((result = callback(collection[index], index, collection))) { + break; + } + } + } else { + baseEach(collection, function(value, index, collection) { + return !(result = callback(value, index, collection)); + }); + } + return !!result; + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through the callback. This method + * performs a stable sort, that is, it will preserve the original sort order + * of equal elements. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an array of property names is provided for `callback` the collection + * will be sorted by each property value. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of sorted elements. + * @example + * + * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); + * // => [3, 1, 2] + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 26 }, + * { 'name': 'fred', 'age': 30 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(_.sortBy(characters, 'age'), _.values); + * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] + * + * // sorting by multiple properties + * _.map(_.sortBy(characters, ['name', 'age']), _.values); + * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] + */ + function sortBy(collection, callback, thisArg) { + var index = -1, + isArr = isArray(callback), + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + if (!isArr) { + callback = lodash.createCallback(callback, thisArg, 3); + } + forEach(collection, function(value, key, collection) { + var object = result[++index] = getObject(); + if (isArr) { + object.criteria = map(callback, function(key) { return value[key]; }); + } else { + (object.criteria = getArray())[0] = callback(value, key, collection); + } + object.index = index; + object.value = value; + }); + + length = result.length; + result.sort(compareAscending); + while (length--) { + var object = result[length]; + result[length] = object.value; + if (!isArr) { + releaseArray(object.criteria); + } + releaseObject(object); + } + return result; + } + + /** + * Converts the `collection` to an array. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to convert. + * @returns {Array} Returns the new converted array. + * @example + * + * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); + * // => [2, 3, 4] + */ + function toArray(collection) { + if (collection && typeof collection.length == 'number') { + return (support.unindexedChars && isString(collection)) + ? collection.split('') + : slice(collection); + } + return values(collection); + } + + /** + * Performs a deep comparison of each element in a `collection` to the given + * `properties` object, returning an array of all elements that have equivalent + * property values. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Object} props The object of property values to filter by. + * @returns {Array} Returns a new array of elements that have the given properties. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.where(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] + * + * _.where(characters, { 'pets': ['dino'] }); + * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] + */ + var where = filter; + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are all falsey. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to compact. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result.push(value); + } + } + return result; + } + + /** + * Creates an array excluding all values of the provided arrays using strict + * equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to process. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); + * // => [1, 3, 4] + */ + function difference(array) { + return baseDifference(array, baseFlatten(arguments, true, true, 1)); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element that passes the callback check, instead of the element itself. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.findIndex(characters, function(chr) { + * return chr.age < 20; + * }); + * // => 2 + * + * // using "_.where" callback shorthand + * _.findIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findIndex(characters, 'blocked'); + * // => 1 + */ + function findIndex(array, callback, thisArg) { + var index = -1, + length = array ? array.length : 0; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length) { + if (callback(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of a `collection` from right to left. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': true }, + * { 'name': 'fred', 'age': 40, 'blocked': false }, + * { 'name': 'pebbles', 'age': 1, 'blocked': true } + * ]; + * + * _.findLastIndex(characters, function(chr) { + * return chr.age > 30; + * }); + * // => 1 + * + * // using "_.where" callback shorthand + * _.findLastIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findLastIndex(characters, 'blocked'); + * // => 2 + */ + function findLastIndex(array, callback, thisArg) { + var length = array ? array.length : 0; + callback = lodash.createCallback(callback, thisArg, 3); + while (length--) { + if (callback(array[length], length, array)) { + return length; + } + } + return -1; + } + + /** + * Gets the first element or first `n` elements of an array. If a callback + * is provided elements at the beginning of the array are returned as long + * as the callback returns truey. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias head, take + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the first element(s) of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([1, 2, 3], 2); + * // => [1, 2] + * + * _.first([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [1, 2] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.first(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); + * // => ['barney', 'fred'] + */ + function first(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = -1; + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[0] : undefined; + } + } + return slice(array, 0, nativeMin(nativeMax(0, n), length)); + } + + /** + * Flattens a nested array (the nesting can be to any depth). If `isShallow` + * is truey, the array will only be flattened a single level. If a callback + * is provided each element of the array is passed through the callback before + * flattening. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new flattened array. + * @example + * + * _.flatten([1, [2], [3, [[4]]]]); + * // => [1, 2, 3, 4]; + * + * _.flatten([1, [2], [3, [[4]]]], true); + * // => [1, 2, 3, [[4]]]; + * + * var characters = [ + * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * // using "_.pluck" callback shorthand + * _.flatten(characters, 'pets'); + * // => ['hoppy', 'baby puss', 'dino'] + */ + function flatten(array, isShallow, callback, thisArg) { + // juggle arguments + if (typeof isShallow != 'boolean' && isShallow != null) { + thisArg = callback; + callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; + isShallow = false; + } + if (callback != null) { + array = map(array, callback, thisArg); + } + return baseFlatten(array, isShallow); + } + + /** + * Gets the index at which the first occurrence of `value` is found using + * strict equality for comparisons, i.e. `===`. If the array is already sorted + * providing `true` for `fromIndex` will run a faster binary search. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2); + * // => 1 + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 4 + * + * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + if (typeof fromIndex == 'number') { + var length = array ? array.length : 0; + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); + } else if (fromIndex) { + var index = sortedIndex(array, value); + return array[index] === value ? index : -1; + } + return baseIndexOf(array, value, fromIndex); + } + + /** + * Gets all but the last element or last `n` elements of an array. If a + * callback is provided elements at the end of the array are excluded from + * the result as long as the callback returns truey. The callback is bound + * to `thisArg` and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + * + * _.initial([1, 2, 3], 2); + * // => [1] + * + * _.initial([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [1] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.initial(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); + * // => ['barney', 'fred'] + */ + function initial(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = lodash.createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : callback || n; + } + return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); + } + + /** + * Creates an array of unique values present in all provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of shared values. + * @example + * + * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2] + */ + function intersection() { + var args = [], + argsIndex = -1, + argsLength = arguments.length, + caches = getArray(), + indexOf = getIndexOf(), + trustIndexOf = indexOf === baseIndexOf, + seen = getArray(); + + while (++argsIndex < argsLength) { + var value = arguments[argsIndex]; + if (isArray(value) || isArguments(value)) { + args.push(value); + caches.push(trustIndexOf && value.length >= largeArraySize && + createCache(argsIndex ? args[argsIndex] : seen)); + } + } + var array = args[0], + index = -1, + length = array ? array.length : 0, + result = []; + + outer: + while (++index < length) { + var cache = caches[0]; + value = array[index]; + + if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) { + argsIndex = argsLength; + (cache || seen).push(value); + while (--argsIndex) { + cache = caches[argsIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { + continue outer; + } + } + result.push(value); + } + } + while (argsLength--) { + cache = caches[argsLength]; + if (cache) { + releaseObject(cache); + } + } + releaseArray(caches); + releaseArray(seen); + return result; + } + + /** + * Gets the last element or last `n` elements of an array. If a callback is + * provided elements at the end of the array are returned as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the last element(s) of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + * + * _.last([1, 2, 3], 2); + * // => [2, 3] + * + * _.last([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [2, 3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.last(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.last(characters, { 'employer': 'na' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function last(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = lodash.createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[length - 1] : undefined; + } + } + return slice(array, nativeMax(0, length - n)); + } + + /** + * Gets the index at which the last occurrence of `value` is found using strict + * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used + * as the offset from the end of the collection. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); + * // => 4 + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 1 + */ + function lastIndexOf(array, value, fromIndex) { + var index = array ? array.length : 0; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Removes all provided values from the given array using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to modify. + * @param {...*} [value] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ + function pull(array) { + var args = arguments, + argsIndex = 0, + argsLength = args.length, + length = array ? array.length : 0; + + while (++argsIndex < argsLength) { + var index = -1, + value = args[argsIndex]; + while (++index < length) { + if (array[index] === value) { + splice.call(array, index--, 1); + length--; + } + } + } + return array; + } + + /** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to but not including `end`. If `start` is less than `stop` a + * zero-length range is created unless a negative `step` is specified. + * + * @static + * @memberOf _ + * @category Arrays + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns a new range array. + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ + function range(start, end, step) { + start = +start || 0; + step = typeof step == 'number' ? step : (+step || 1); + + if (end == null) { + end = start; + start = 0; + } + // use `Array(length)` so engines like Chakra and V8 avoid slower modes + // http://youtu.be/XAqIpGU8ZZk#t=17m25s + var index = -1, + length = nativeMax(0, ceil((end - start) / (step || 1))), + result = Array(length); + + while (++index < length) { + result[index] = start; + start += step; + } + return result; + } + + /** + * Removes all elements from an array that the callback returns truey for + * and returns an array of removed elements. The callback is bound to `thisArg` + * and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to modify. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4, 5, 6]; + * var evens = _.remove(array, function(num) { return num % 2 == 0; }); + * + * console.log(array); + * // => [1, 3, 5] + * + * console.log(evens); + * // => [2, 4, 6] + */ + function remove(array, callback, thisArg) { + var index = -1, + length = array ? array.length : 0, + result = []; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (callback(value, index, array)) { + result.push(value); + splice.call(array, index--, 1); + length--; + } + } + return result; + } + + /** + * The opposite of `_.initial` this method gets all but the first element or + * first `n` elements of an array. If a callback function is provided elements + * at the beginning of the array are excluded from the result as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias drop, tail + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + * + * _.rest([1, 2, 3], 2); + * // => [3] + * + * _.rest([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.rest(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.rest(characters, { 'employer': 'slate' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function rest(array, callback, thisArg) { + if (typeof callback != 'number' && callback != null) { + var n = 0, + index = -1, + length = array ? array.length : 0; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); + } + return slice(array, n); + } + + /** + * Uses a binary search to determine the smallest index at which a value + * should be inserted into a given sorted array in order to maintain the sort + * order of the array. If a callback is provided it will be executed for + * `value` and each element of `array` to compute their sort ranking. The + * callback is bound to `thisArg` and invoked with one argument; (value). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([20, 30, 50], 40); + * // => 2 + * + * // using "_.pluck" callback shorthand + * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 2 + * + * var dict = { + * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } + * }; + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return dict.wordToNumber[word]; + * }); + * // => 2 + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return this.wordToNumber[word]; + * }, dict); + * // => 2 + */ + function sortedIndex(array, value, callback, thisArg) { + var low = 0, + high = array ? array.length : low; + + // explicitly reference `identity` for better inlining in Firefox + callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; + value = callback(value); + + while (low < high) { + var mid = (low + high) >>> 1; + (callback(array[mid]) < value) + ? low = mid + 1 + : high = mid; + } + return low; + } + + /** + * Creates an array of unique values, in order, of the provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of combined values. + * @example + * + * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2, 3, 5, 4] + */ + function union() { + return baseUniq(baseFlatten(arguments, true, true)); + } + + /** + * Creates a duplicate-value-free version of an array using strict equality + * for comparisons, i.e. `===`. If the array is sorted, providing + * `true` for `isSorted` will use a faster algorithm. If a callback is provided + * each element of `array` is passed through the callback before uniqueness + * is computed. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Arrays + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a duplicate-value-free array. + * @example + * + * _.uniq([1, 2, 1, 3, 1]); + * // => [1, 2, 3] + * + * _.uniq([1, 1, 2, 2, 3], true); + * // => [1, 2, 3] + * + * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); + * // => ['A', 'b', 'C'] + * + * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); + * // => [1, 2.5, 3] + * + * // using "_.pluck" callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniq(array, isSorted, callback, thisArg) { + // juggle arguments + if (typeof isSorted != 'boolean' && isSorted != null) { + thisArg = callback; + callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; + isSorted = false; + } + if (callback != null) { + callback = lodash.createCallback(callback, thisArg, 3); + } + return baseUniq(array, isSorted, callback); + } + + /** + * Creates an array excluding all provided values using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to filter. + * @param {...*} [value] The values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); + * // => [2, 3, 4] + */ + function without(array) { + return baseDifference(array, slice(arguments, 1)); + } + + /** + * Creates an array that is the symmetric difference of the provided arrays. + * See http://en.wikipedia.org/wiki/Symmetric_difference. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of values. + * @example + * + * _.xor([1, 2, 3], [5, 2, 1, 4]); + * // => [3, 5, 4] + * + * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); + * // => [1, 4, 5] + */ + function xor() { + var index = -1, + length = arguments.length; + + while (++index < length) { + var array = arguments[index]; + if (isArray(array) || isArguments(array)) { + var result = result + ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result))) + : array; + } + } + return result || []; + } + + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second + * elements of the given arrays, and so on. + * + * @static + * @memberOf _ + * @alias unzip + * @category Arrays + * @param {...Array} [array] Arrays to process. + * @returns {Array} Returns a new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + function zip() { + var array = arguments.length > 1 ? arguments : arguments[0], + index = -1, + length = array ? max(pluck(array, 'length')) : 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = pluck(array, index); + } + return result; + } + + /** + * Creates an object composed from arrays of `keys` and `values`. Provide + * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` + * or two arrays, one of `keys` and one of corresponding `values`. + * + * @static + * @memberOf _ + * @alias object + * @category Arrays + * @param {Array} keys The array of keys. + * @param {Array} [values=[]] The array of values. + * @returns {Object} Returns an object composed of the given keys and + * corresponding values. + * @example + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ + function zipObject(keys, values) { + var index = -1, + length = keys ? keys.length : 0, + result = {}; + + if (!values && length && !isArray(keys[0])) { + values = []; + } + while (++index < length) { + var key = keys[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that executes `func`, with the `this` binding and + * arguments of the created function, only after being called `n` times. + * + * @static + * @memberOf _ + * @category Functions + * @param {number} n The number of times the function must be called before + * `func` is executed. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('Done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'Done saving!', after all saves have completed + */ + function after(n, func) { + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that, when called, invokes `func` with the `this` + * binding of `thisArg` and prepends any additional `bind` arguments to those + * provided to the bound function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var func = function(greeting) { + * return greeting + ' ' + this.name; + * }; + * + * func = _.bind(func, { 'name': 'fred' }, 'hi'); + * func(); + * // => 'hi fred' + */ + function bind(func, thisArg) { + return arguments.length > 2 + ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) + : createWrapper(func, 1, null, null, thisArg); + } + + /** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all the function properties + * of `object` will be bound. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...string} [methodName] The object method names to + * bind, specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { console.log('clicked ' + this.label); } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs', when the button is clicked + */ + function bindAll(object) { + var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), + index = -1, + length = funcs.length; + + while (++index < length) { + var key = funcs[index]; + object[key] = createWrapper(object[key], 1, null, null, object); + } + return object; + } + + /** + * Creates a function that, when called, invokes the method at `object[key]` + * and prepends any additional `bindKey` arguments to those provided to the bound + * function. This method differs from `_.bind` by allowing bound functions to + * reference methods that will be redefined or don't yet exist. + * See http://michaux.ca/articles/lazy-function-definition-pattern. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'name': 'fred', + * 'greet': function(greeting) { + * return greeting + ' ' + this.name; + * } + * }; + * + * var func = _.bindKey(object, 'greet', 'hi'); + * func(); + * // => 'hi fred' + * + * object.greet = function(greeting) { + * return greeting + 'ya ' + this.name + '!'; + * }; + * + * func(); + * // => 'hiya fred!' + */ + function bindKey(object, key) { + return arguments.length > 2 + ? createWrapper(key, 19, slice(arguments, 2), null, object) + : createWrapper(key, 3, null, null, object); + } + + /** + * Creates a function that is the composition of the provided functions, + * where each function consumes the return value of the function that follows. + * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. + * Each function is executed with the `this` binding of the composed function. + * + * @static + * @memberOf _ + * @category Functions + * @param {...Function} [func] Functions to compose. + * @returns {Function} Returns the new composed function. + * @example + * + * var realNameMap = { + * 'pebbles': 'penelope' + * }; + * + * var format = function(name) { + * name = realNameMap[name.toLowerCase()] || name; + * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); + * }; + * + * var greet = function(formatted) { + * return 'Hiya ' + formatted + '!'; + * }; + * + * var welcome = _.compose(greet, format); + * welcome('pebbles'); + * // => 'Hiya Penelope!' + */ + function compose() { + var funcs = arguments, + length = funcs.length; + + while (length--) { + if (!isFunction(funcs[length])) { + throw new TypeError; + } + } + return function() { + var args = arguments, + length = funcs.length; + + while (length--) { + args = [funcs[length].apply(this, args)]; + } + return args[0]; + }; + } + + /** + * Creates a function which accepts one or more arguments of `func` that when + * invoked either executes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` can be specified + * if `func.length` is not sufficient. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @returns {Function} Returns the new curried function. + * @example + * + * var curried = _.curry(function(a, b, c) { + * console.log(a + b + c); + * }); + * + * curried(1)(2)(3); + * // => 6 + * + * curried(1, 2)(3); + * // => 6 + * + * curried(1, 2, 3); + * // => 6 + */ + function curry(func, arity) { + arity = typeof arity == 'number' ? arity : (+arity || func.length); + return createWrapper(func, 4, null, null, null, arity); + } + + /** + * Creates a function that will delay the execution of `func` until after + * `wait` milliseconds have elapsed since the last time it was invoked. + * Provide an options object to indicate that `func` should be invoked on + * the leading and/or trailing edge of the `wait` timeout. Subsequent calls + * to the debounced function will return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to debounce. + * @param {number} wait The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * var lazyLayout = _.debounce(calculateLayout, 150); + * jQuery(window).on('resize', lazyLayout); + * + * // execute `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * }); + * + * // ensure `batchLog` is executed once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * source.addEventListener('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * }, false); + */ + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + wait = nativeMax(0, wait) || 0; + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = options.leading; + maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0); + trailing = 'trailing' in options ? options.trailing : trailing; + } + var delayed = function() { + var remaining = wait - (now() - stamp); + if (remaining <= 0) { + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + var isCalled = trailingCall; + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + } else { + timeoutId = setTimeout(delayed, remaining); + } + }; + + var maxDelayed = function() { + if (timeoutId) { + clearTimeout(timeoutId); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (trailing || (maxWait !== wait)) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + }; + + return function() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + return result; + }; + } + + /** + * Defers executing the `func` function until the current call stack has cleared. + * Additional arguments will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to defer. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { console.log(text); }, 'deferred'); + * // logs 'deferred' after one or more milliseconds + */ + function defer(func) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 1); + return setTimeout(function() { func.apply(undefined, args); }, 1); + } + + /** + * Executes the `func` function after `wait` milliseconds. Additional arguments + * will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay execution. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { console.log(text); }, 1000, 'later'); + * // => logs 'later' after one second + */ + function delay(func, wait) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 2); + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it will be used to determine the cache key for storing the result + * based on the arguments provided to the memoized function. By default, the + * first argument provided to the memoized function is used as the cache key. + * The `func` is executed with the `this` binding of the memoized function. + * The result cache is exposed as the `cache` property on the memoized function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] A function used to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var fibonacci = _.memoize(function(n) { + * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); + * }); + * + * fibonacci(9) + * // => 34 + * + * var data = { + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * }; + * + * // modifying the result cache + * var get = _.memoize(function(name) { return data[name]; }, _.identity); + * get('pebbles'); + * // => { 'name': 'pebbles', 'age': 1 } + * + * get.cache.pebbles.name = 'penelope'; + * get('pebbles'); + * // => { 'name': 'penelope', 'age': 1 } + */ + function memoize(func, resolver) { + if (!isFunction(func)) { + throw new TypeError; + } + var memoized = function() { + var cache = memoized.cache, + key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0]; + + return hasOwnProperty.call(cache, key) + ? cache[key] + : (cache[key] = func.apply(this, arguments)); + } + memoized.cache = {}; + return memoized; + } + + /** + * Creates a function that is restricted to execute `func` once. Repeat calls to + * the function will return the value of the first call. The `func` is executed + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` executes `createApplication` once + */ + function once(func) { + var ran, + result; + + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (ran) { + return result; + } + ran = true; + result = func.apply(this, arguments); + + // clear the `func` variable so the function may be garbage collected + func = null; + return result; + }; + } + + /** + * Creates a function that, when called, invokes `func` with any additional + * `partial` arguments prepended to those provided to the new function. This + * method is similar to `_.bind` except it does **not** alter the `this` binding. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { return greeting + ' ' + name; }; + * var hi = _.partial(greet, 'hi'); + * hi('fred'); + * // => 'hi fred' + */ + function partial(func) { + return createWrapper(func, 16, slice(arguments, 1)); + } + + /** + * This method is like `_.partial` except that `partial` arguments are + * appended to those provided to the new function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var defaultsDeep = _.partialRight(_.merge, _.defaults); + * + * var options = { + * 'variable': 'data', + * 'imports': { 'jq': $ } + * }; + * + * defaultsDeep(options, _.templateSettings); + * + * options.variable + * // => 'data' + * + * options.imports + * // => { '_': _, 'jq': $ } + */ + function partialRight(func) { + return createWrapper(func, 32, null, slice(arguments, 1)); + } + + /** + * Creates a function that, when executed, will only call the `func` function + * at most once per every `wait` milliseconds. Provide an options object to + * indicate that `func` should be invoked on the leading and/or trailing edge + * of the `wait` timeout. Subsequent calls to the throttled function will + * return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to throttle. + * @param {number} wait The number of milliseconds to throttle executions to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // avoid excessively updating the position while scrolling + * var throttled = _.throttle(updatePosition, 100); + * jQuery(window).on('scroll', throttled); + * + * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? options.leading : leading; + trailing = 'trailing' in options ? options.trailing : trailing; + } + debounceOptions.leading = leading; + debounceOptions.maxWait = wait; + debounceOptions.trailing = trailing; + + return debounce(func, wait, debounceOptions); + } + + /** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Additional arguments provided to the function are appended + * to those provided to the wrapper function. The wrapper is executed with + * the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

' + func(text) + '

'; + * }); + * + * p('Fred, Wilma, & Pebbles'); + * // => '

Fred, Wilma, & Pebbles

' + */ + function wrap(value, wrapper) { + return createWrapper(wrapper, 16, [value]); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new function. + * @example + * + * var object = { 'name': 'fred' }; + * var getter = _.constant(object); + * getter() === object; + * // => true + */ + function constant(value) { + return function() { + return value; + }; + } + + /** + * Produces a callback bound to an optional `thisArg`. If `func` is a property + * name the created callback will return the property value for a given element. + * If `func` is an object the created callback will return `true` for elements + * that contain the equivalent object properties, otherwise it will return `false`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // wrap to create custom callback shorthands + * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { + * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); + * return !match ? func(callback, thisArg) : function(object) { + * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; + * }; + * }); + * + * _.filter(characters, 'age__gt38'); + * // => [{ 'name': 'fred', 'age': 40 }] + */ + function createCallback(func, thisArg, argCount) { + var type = typeof func; + if (func == null || type == 'function') { + return baseCreateCallback(func, thisArg, argCount); + } + // handle "_.pluck" style callback shorthands + if (type != 'object') { + return property(func); + } + var props = keys(func), + key = props[0], + a = func[key]; + + // handle "_.where" style callback shorthands + if (props.length == 1 && a === a && !isObject(a)) { + // fast path the common case of providing an object with a single + // property containing a primitive value + return function(object) { + var b = object[key]; + return a === b && (a !== 0 || (1 / a == 1 / b)); + }; + } + return function(object) { + var length = props.length, + result = false; + + while (length--) { + if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { + break; + } + } + return result; + }; + } + + /** + * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their + * corresponding HTML entities. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} string The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('Fred, Wilma, & Pebbles'); + * // => 'Fred, Wilma, & Pebbles' + */ + function escape(string) { + return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); + } + + /** + * This method returns the first argument provided to it. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'name': 'fred' }; + * _.identity(object) === object; + * // => true + */ + function identity(value) { + return value; + } + + /** + * Adds function properties of a source object to the destination object. + * If `object` is a function methods will be added to its prototype as well. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Function|Object} [object=lodash] object The destination object. + * @param {Object} source The object of functions to add. + * @param {Object} [options] The options object. + * @param {boolean} [options.chain=true] Specify whether the functions added are chainable. + * @example + * + * function capitalize(string) { + * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); + * } + * + * _.mixin({ 'capitalize': capitalize }); + * _.capitalize('fred'); + * // => 'Fred' + * + * _('fred').capitalize().value(); + * // => 'Fred' + * + * _.mixin({ 'capitalize': capitalize }, { 'chain': false }); + * _('fred').capitalize(); + * // => 'Fred' + */ + function mixin(object, source, options) { + var chain = true, + methodNames = source && functions(source); + + if (!source || (!options && !methodNames.length)) { + if (options == null) { + options = source; + } + ctor = lodashWrapper; + source = object; + object = lodash; + methodNames = functions(source); + } + if (options === false) { + chain = false; + } else if (isObject(options) && 'chain' in options) { + chain = options.chain; + } + var ctor = object, + isFunc = isFunction(ctor); + + forEach(methodNames, function(methodName) { + var func = object[methodName] = source[methodName]; + if (isFunc) { + ctor.prototype[methodName] = function() { + var chainAll = this.__chain__, + value = this.__wrapped__, + args = [value]; + + push.apply(args, arguments); + var result = func.apply(object, args); + if (chain || chainAll) { + if (value === result && isObject(result)) { + return this; + } + result = new ctor(result); + result.__chain__ = chainAll; + } + return result; + }; + } + }); + } + + /** + * Reverts the '_' variable to its previous value and returns a reference to + * the `lodash` function. + * + * @static + * @memberOf _ + * @category Utilities + * @returns {Function} Returns the `lodash` function. + * @example + * + * var lodash = _.noConflict(); + */ + function noConflict() { + context._ = oldDash; + return this; + } + + /** + * A no-operation function. + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var object = { 'name': 'fred' }; + * _.noop(object) === undefined; + * // => true + */ + function noop() { + // no operation performed + } + + /** + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var stamp = _.now(); + * _.defer(function() { console.log(_.now() - stamp); }); + * // => logs the number of milliseconds it took for the deferred function to be called + */ + var now = isNative(now = Date.now) && now || function() { + return new Date().getTime(); + }; + + /** + * Converts the given value into an integer of the specified radix. + * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the + * `value` is a hexadecimal, in which case a `radix` of `16` is used. + * + * Note: This method avoids differences in native ES3 and ES5 `parseInt` + * implementations. See http://es5.github.io/#E. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} value The value to parse. + * @param {number} [radix] The radix used to interpret the value to parse. + * @returns {number} Returns the new integer value. + * @example + * + * _.parseInt('08'); + * // => 8 + */ + var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) { + // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt` + return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0); + }; + + /** + * Creates a "_.pluck" style function, which returns the `key` value of a + * given object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} key The name of the property to retrieve. + * @returns {Function} Returns the new function. + * @example + * + * var characters = [ + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 36 } + * ]; + * + * var getName = _.property('name'); + * + * _.map(characters, getName); + * // => ['barney', 'fred'] + * + * _.sortBy(characters, getName); + * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] + */ + function property(key) { + return function(object) { + return object[key]; + }; + } + + /** + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is provided a number between `0` and the given number will be + * returned. If `floating` is truey or either `min` or `max` are floats a + * floating-point number will be returned instead of an integer. + * + * @static + * @memberOf _ + * @category Utilities + * @param {number} [min=0] The minimum possible value. + * @param {number} [max=1] The maximum possible value. + * @param {boolean} [floating=false] Specify returning a floating-point number. + * @returns {number} Returns a random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(min, max, floating) { + var noMin = min == null, + noMax = max == null; + + if (floating == null) { + if (typeof min == 'boolean' && noMax) { + floating = min; + min = 1; + } + else if (!noMax && typeof max == 'boolean') { + floating = max; + noMax = true; + } + } + if (noMin && noMax) { + max = 1; + } + min = +min || 0; + if (noMax) { + max = min; + min = 0; + } else { + max = +max || 0; + } + if (floating || min % 1 || max % 1) { + var rand = nativeRandom(); + return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max); + } + return baseRandom(min, max); + } + + /** + * Resolves the value of property `key` on `object`. If `key` is a function + * it will be invoked with the `this` binding of `object` and its result returned, + * else the property value is returned. If `object` is falsey then `undefined` + * is returned. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to resolve. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { + * 'cheese': 'crumpets', + * 'stuff': function() { + * return 'nonsense'; + * } + * }; + * + * _.result(object, 'cheese'); + * // => 'crumpets' + * + * _.result(object, 'stuff'); + * // => 'nonsense' + */ + function result(object, key) { + if (object) { + var value = object[key]; + return isFunction(value) ? object[key]() : value; + } + } + + /** + * A micro-templating method that handles arbitrary delimiters, preserves + * whitespace, and correctly escapes quotes within interpolated code. + * + * Note: In the development build, `_.template` utilizes sourceURLs for easier + * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl + * + * For more information on precompiling templates see: + * https://lodash.com/custom-builds + * + * For more information on Chrome extension sandboxes see: + * http://developer.chrome.com/stable/extensions/sandboxingEval.html + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} text The template text. + * @param {Object} data The data object used to populate the text. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as local variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [sourceURL] The sourceURL of the template's compiled source. + * @param {string} [variable] The data object variable name. + * @returns {Function|string} Returns a compiled function when no `data` object + * is given, else it returns the interpolated text. + * @example + * + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= name %>'); + * compiled({ 'name': 'fred' }); + * // => 'hello fred' + * + * // using the "escape" delimiter to escape HTML in data property values + * _.template('<%- value %>', { 'value': ' +``` + +Using [`npm`](http://npmjs.org/): + +```bash +npm i --save lodash + +{sudo} npm i -g lodash +npm ln lodash +``` + +In [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/): + +```js +var _ = require('lodash'); +// or as Underscore +var _ = require('lodash/dist/lodash.underscore'); +``` + +**Notes:** + * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL + * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it + +In [Rhino](http://www.mozilla.org/rhino/): + +```js +load('lodash.js'); +``` + +In an AMD loader: + +```js +require({ + 'packages': [ + { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' } + ] +}, +['lodash'], function(_) { + console.log(_.VERSION); +}); +``` + +## Resources + + * Podcasts + - [JavaScript Jabber](http://javascriptjabber.com/079-jsj-lo-dash-with-john-david-dalton/) + + * Posts + - [Say “Hello” to Lo-Dash](http://kitcambridge.be/blog/say-hello-to-lo-dash/) + - [Custom builds in Lo-Dash 2.0](http://kitcambridge.be/blog/custom-builds-in-lo-dash-2-dot-0/) + + * Videos + - [Introduction](https://vimeo.com/44154599) + - [Origins](https://vimeo.com/44154600) + - [Optimizations & builds](https://vimeo.com/44154601) + - [Native method use](https://vimeo.com/48576012) + - [Testing](https://vimeo.com/45865290) + - [CascadiaJS ’12](http://www.youtube.com/watch?v=dpPy4f_SeEk) + + A list of other community created podcasts, posts, & videos is available on our [wiki](https://github.com/lodash/lodash/wiki/Resources). + +## Features + + * AMD loader support ([curl](https://github.com/cujojs/curl), [dojo](http://dojotoolkit.org/), [requirejs](http://requirejs.org/), etc.) + * [_(…)](https://lodash.com/docs#_) supports intuitive chaining + * [_.at](https://lodash.com/docs#at) for cherry-picking collection values + * [_.bindKey](https://lodash.com/docs#bindKey) for binding [*“lazy”*](http://michaux.ca/articles/lazy-function-definition-pattern) defined methods + * [_.clone](https://lodash.com/docs#clone) supports shallow cloning of `Date` & `RegExp` objects + * [_.cloneDeep](https://lodash.com/docs#cloneDeep) for deep cloning arrays & objects + * [_.constant](https://lodash.com/docs#constant) & [_.property](https://lodash.com/docs#property) function generators for composing functions + * [_.contains](https://lodash.com/docs#contains) accepts a `fromIndex` + * [_.create](https://lodash.com/docs#create) for easier object inheritance + * [_.createCallback](https://lodash.com/docs#createCallback) for extending callbacks in methods & mixins + * [_.curry](https://lodash.com/docs#curry) for creating [curried](http://hughfdjackson.com/javascript/2013/07/06/why-curry-helps/) functions + * [_.debounce](https://lodash.com/docs#debounce) & [_.throttle](https://lodash.com/docs#throttle) accept additional `options` for more control + * [_.findIndex](https://lodash.com/docs#findIndex) & [_.findKey](https://lodash.com/docs#findKey) for finding indexes & keys + * [_.forEach](https://lodash.com/docs#forEach) is chainable & supports exiting early + * [_.forIn](https://lodash.com/docs#forIn) for iterating own & inherited properties + * [_.forOwn](https://lodash.com/docs#forOwn) for iterating own properties + * [_.isPlainObject](https://lodash.com/docs#isPlainObject) for checking if values are created by `Object` + * [_.mapValues](https://lodash.com/docs#mapValues) for [mapping](https://lodash.com/docs#map) values to an object + * [_.memoize](https://lodash.com/docs#memoize) exposes the `cache` of memoized functions + * [_.merge](https://lodash.com/docs#merge) for a deep [_.extend](https://lodash.com/docs#extend) + * [_.noop](https://lodash.com/docs#noop) for function placeholders + * [_.now](https://lodash.com/docs#now) as a cross-browser `Date.now` alternative + * [_.parseInt](https://lodash.com/docs#parseInt) for consistent behavior + * [_.pull](https://lodash.com/docs#pull) & [_.remove](https://lodash.com/docs#remove) for mutating arrays + * [_.random](https://lodash.com/docs#random) supports returning floating-point numbers + * [_.runInContext](https://lodash.com/docs#runInContext) for easier mocking + * [_.sortBy](https://lodash.com/docs#sortBy) supports sorting by multiple properties + * [_.support](https://lodash.com/docs#support) for flagging environment features + * [_.template](https://lodash.com/docs#template) supports [*“imports”*](https://lodash.com/docs#templateSettings_imports) options & [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals) + * [_.transform](https://lodash.com/docs#transform) as a powerful alternative to [_.reduce](https://lodash.com/docs#reduce) for transforming objects + * [_.where](https://lodash.com/docs#where) supports deep object comparisons + * [_.xor](https://lodash.com/docs#xor) as a companion to [_.difference](https://lodash.com/docs#difference), [_.intersection](https://lodash.com/docs#intersection), & [_.union](https://lodash.com/docs#union) + * [_.zip](https://lodash.com/docs#zip) is capable of unzipping values + * [_.omit](https://lodash.com/docs#omit), [_.pick](https://lodash.com/docs#pick), & + [more](https://lodash.com/docs "_.assign, _.clone, _.cloneDeep, _.first, _.initial, _.isEqual, _.last, _.merge, _.rest") accept callbacks + * [_.contains](https://lodash.com/docs#contains), [_.toArray](https://lodash.com/docs#toArray), & + [more](https://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.forEach, _.forEachRight, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.size, _.some, _.sortBy, _.where") accept strings + * [_.filter](https://lodash.com/docs#filter), [_.map](https://lodash.com/docs#map), & + [more](https://lodash.com/docs "_.countBy, _.every, _.find, _.findKey, _.findLast, _.findLastIndex, _.findLastKey, _.first, _.groupBy, _.initial, _.last, _.max, _.min, _.reject, _.rest, _.some, _.sortBy, _.sortedIndex, _.uniq") support *“_.pluck”* & *“_.where”* shorthands + * [_.findLast](https://lodash.com/docs#findLast), [_.findLastIndex](https://lodash.com/docs#findLastIndex), & + [more](https://lodash.com/docs "_.findLastKey, _.forEachRight, _.forInRight, _.forOwnRight, _.partialRight") right-associative methods + +## Support + +Tested in Chrome 5~31, Firefox 2~25, IE 6-11, Opera 9.25-17, Safari 3-7, Node.js 0.6.21-0.10.22, Narwhal 0.3.2, PhantomJS 1.9.2, RingoJS 0.9, & Rhino 1.7RC5. diff --git a/node_modules/grunt-legacy-log-utils/node_modules/lodash/dist/lodash.compat.js b/node_modules/grunt-legacy-log-utils/node_modules/lodash/dist/lodash.compat.js new file mode 100644 index 0000000..4d35185 --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/lodash/dist/lodash.compat.js @@ -0,0 +1,7158 @@ +/** + * @license + * Lo-Dash 2.4.2 (Custom Build) + * Build: `lodash -o ./dist/lodash.compat.js` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre ES5 environments */ + var undefined; + + /** Used to pool arrays and objects used internally */ + var arrayPool = [], + objectPool = []; + + /** Used to generate unique IDs */ + var idCounter = 0; + + /** Used internally to indicate various things */ + var indicatorObject = {}; + + /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */ + var keyPrefix = +new Date + ''; + + /** Used as the size when optimizations are enabled for large arrays */ + var largeArraySize = 75; + + /** Used as the max size of the `arrayPool` and `objectPool` */ + var maxPoolSize = 40; + + /** Used to detect and test whitespace */ + var whitespace = ( + // whitespace + ' \t\x0B\f\xA0\ufeff' + + + // line terminators + '\n\r\u2028\u2029' + + + // unicode category "Zs" space separators + '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' + ); + + /** Used to match empty string literals in compiled template source */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** + * Used to match ES6 template delimiters + * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals + */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match regexp flags from their coerced string values */ + var reFlags = /\w*$/; + + /** Used to detected named functions */ + var reFuncName = /^\s*function[ \n\r\t]+\w/; + + /** Used to match "interpolate" template delimiters */ + var reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match leading whitespace and zeros to be removed */ + var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)'); + + /** Used to ensure capturing order of template delimiters */ + var reNoMatch = /($^)/; + + /** Used to detect functions containing a `this` reference */ + var reThis = /\bthis\b/; + + /** Used to match unescaped characters in compiled string literals */ + var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; + + /** Used to assign default `context` object properties */ + var contextProps = [ + 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object', + 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', + 'parseInt', 'setTimeout' + ]; + + /** Used to fix the JScript [[DontEnum]] bug */ + var shadowedProps = [ + 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', + 'toLocaleString', 'toString', 'valueOf' + ]; + + /** Used to make template sourceURLs easier to identify */ + var templateCounter = 0; + + /** `Object#toString` result shortcuts */ + var argsClass = '[object Arguments]', + arrayClass = '[object Array]', + boolClass = '[object Boolean]', + dateClass = '[object Date]', + errorClass = '[object Error]', + funcClass = '[object Function]', + numberClass = '[object Number]', + objectClass = '[object Object]', + regexpClass = '[object RegExp]', + stringClass = '[object String]'; + + /** Used to identify object classifications that `_.clone` supports */ + var cloneableClasses = {}; + cloneableClasses[funcClass] = false; + cloneableClasses[argsClass] = cloneableClasses[arrayClass] = + cloneableClasses[boolClass] = cloneableClasses[dateClass] = + cloneableClasses[numberClass] = cloneableClasses[objectClass] = + cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; + + /** Used as an internal `_.debounce` options object */ + var debounceOptions = { + 'leading': false, + 'maxWait': 0, + 'trailing': false + }; + + /** Used as the property descriptor for `__bindData__` */ + var descriptor = { + 'configurable': false, + 'enumerable': false, + 'value': null, + 'writable': false + }; + + /** Used as the data object for `iteratorTemplate` */ + var iteratorData = { + 'args': '', + 'array': null, + 'bottom': '', + 'firstArg': '', + 'init': '', + 'keys': null, + 'loop': '', + 'shadowedProps': null, + 'support': null, + 'top': '', + 'useHas': false + }; + + /** Used to determine if values are of the language type Object */ + var objectTypes = { + 'boolean': false, + 'function': true, + 'object': true, + 'number': false, + 'string': false, + 'undefined': false + }; + + /** Used to escape characters for inclusion in compiled string literals */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\t': 't', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Used as a reference to the global object */ + var root = (objectTypes[typeof window] && window) || this; + + /** Detect free variable `exports` */ + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + + /** Detect free variable `module` */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports` */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + + /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ + var freeGlobal = objectTypes[typeof global] && global; + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { + root = freeGlobal; + } + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.indexOf` without support for binary searches + * or `fromIndex` constraints. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * An implementation of `_.contains` for cache objects that mimics the return + * signature of `_.indexOf` by returning `0` if the value is found, else `-1`. + * + * @private + * @param {Object} cache The cache object to inspect. + * @param {*} value The value to search for. + * @returns {number} Returns `0` if `value` is found, else `-1`. + */ + function cacheIndexOf(cache, value) { + var type = typeof value; + cache = cache.cache; + + if (type == 'boolean' || value == null) { + return cache[value] ? 0 : -1; + } + if (type != 'number' && type != 'string') { + type = 'object'; + } + var key = type == 'number' ? value : keyPrefix + value; + cache = (cache = cache[type]) && cache[key]; + + return type == 'object' + ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1) + : (cache ? 0 : -1); + } + + /** + * Adds a given value to the corresponding cache object. + * + * @private + * @param {*} value The value to add to the cache. + */ + function cachePush(value) { + var cache = this.cache, + type = typeof value; + + if (type == 'boolean' || value == null) { + cache[value] = true; + } else { + if (type != 'number' && type != 'string') { + type = 'object'; + } + var key = type == 'number' ? value : keyPrefix + value, + typeCache = cache[type] || (cache[type] = {}); + + if (type == 'object') { + (typeCache[key] || (typeCache[key] = [])).push(value); + } else { + typeCache[key] = true; + } + } + } + + /** + * Used by `_.max` and `_.min` as the default callback when a given + * collection is a string value. + * + * @private + * @param {string} value The character to inspect. + * @returns {number} Returns the code unit of given character. + */ + function charAtCallback(value) { + return value.charCodeAt(0); + } + + /** + * Used by `sortBy` to compare transformed `collection` elements, stable sorting + * them in ascending order. + * + * @private + * @param {Object} a The object to compare to `b`. + * @param {Object} b The object to compare to `a`. + * @returns {number} Returns the sort order indicator of `1` or `-1`. + */ + function compareAscending(a, b) { + var ac = a.criteria, + bc = b.criteria, + index = -1, + length = ac.length; + + while (++index < length) { + var value = ac[index], + other = bc[index]; + + if (value !== other) { + if (value > other || typeof value == 'undefined') { + return 1; + } + if (value < other || typeof other == 'undefined') { + return -1; + } + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to return the same value for + // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247 + // + // This also ensures a stable sort in V8 and other engines. + // See http://code.google.com/p/v8/issues/detail?id=90 + return a.index - b.index; + } + + /** + * Creates a cache object to optimize linear searches of large arrays. + * + * @private + * @param {Array} [array=[]] The array to search. + * @returns {null|Object} Returns the cache object or `null` if caching should not be used. + */ + function createCache(array) { + var index = -1, + length = array.length, + first = array[0], + mid = array[(length / 2) | 0], + last = array[length - 1]; + + if (first && typeof first == 'object' && + mid && typeof mid == 'object' && last && typeof last == 'object') { + return false; + } + var cache = getObject(); + cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false; + + var result = getObject(); + result.array = array; + result.cache = cache; + result.push = cachePush; + + while (++index < length) { + result.push(array[index]); + } + return result; + } + + /** + * Used by `template` to escape characters for inclusion in compiled + * string literals. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(match) { + return '\\' + stringEscapes[match]; + } + + /** + * Gets an array from the array pool or creates a new one if the pool is empty. + * + * @private + * @returns {Array} The array from the pool. + */ + function getArray() { + return arrayPool.pop() || []; + } + + /** + * Gets an object from the object pool or creates a new one if the pool is empty. + * + * @private + * @returns {Object} The object from the pool. + */ + function getObject() { + return objectPool.pop() || { + 'array': null, + 'cache': null, + 'criteria': null, + 'false': false, + 'index': 0, + 'null': false, + 'number': null, + 'object': null, + 'push': null, + 'string': null, + 'true': false, + 'undefined': false, + 'value': null + }; + } + + /** + * Checks if `value` is a DOM node in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`. + */ + function isNode(value) { + // IE < 9 presents DOM nodes as `Object` objects except they have `toString` + // methods that are `typeof` "string" and still can coerce nodes to strings + return typeof value.toString != 'function' && typeof (value + '') == 'string'; + } + + /** + * Releases the given array back to the array pool. + * + * @private + * @param {Array} [array] The array to release. + */ + function releaseArray(array) { + array.length = 0; + if (arrayPool.length < maxPoolSize) { + arrayPool.push(array); + } + } + + /** + * Releases the given object back to the object pool. + * + * @private + * @param {Object} [object] The object to release. + */ + function releaseObject(object) { + var cache = object.cache; + if (cache) { + releaseObject(cache); + } + object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null; + if (objectPool.length < maxPoolSize) { + objectPool.push(object); + } + } + + /** + * Slices the `collection` from the `start` index up to, but not including, + * the `end` index. + * + * Note: This function is used instead of `Array#slice` to support node lists + * in IE < 9 and to ensure dense arrays are returned. + * + * @private + * @param {Array|Object|string} collection The collection to slice. + * @param {number} start The start index. + * @param {number} end The end index. + * @returns {Array} Returns the new array. + */ + function slice(array, start, end) { + start || (start = 0); + if (typeof end == 'undefined') { + end = array ? array.length : 0; + } + var index = -1, + length = end - start || 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = array[start + index]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new `lodash` function using the given context object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} [context=root] The context object. + * @returns {Function} Returns the `lodash` function. + */ + function runInContext(context) { + // Avoid issues with some ES3 environments that attempt to use values, named + // after built-in constructors like `Object`, for the creation of literals. + // ES5 clears this up by stating that literals must use built-in constructors. + // See http://es5.github.io/#x11.1.5. + context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; + + /** Native constructor references */ + var Array = context.Array, + Boolean = context.Boolean, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Number = context.Number, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** + * Used for `Array` method references. + * + * Normally `Array.prototype` would suffice, however, using an array literal + * avoids issues in Narwhal. + */ + var arrayRef = []; + + /** Used for native method references */ + var errorProto = Error.prototype, + objectProto = Object.prototype, + stringProto = String.prototype; + + /** Used to restore the original `_` reference in `noConflict` */ + var oldDash = context._; + + /** Used to resolve the internal [[Class]] of values */ + var toString = objectProto.toString; + + /** Used to detect if a method is native */ + var reNative = RegExp('^' + + String(toString) + .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + .replace(/toString| for [^\]]+/g, '.*?') + '$' + ); + + /** Native method shortcuts */ + var ceil = Math.ceil, + clearTimeout = context.clearTimeout, + floor = Math.floor, + fnToString = Function.prototype.toString, + getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, + hasOwnProperty = objectProto.hasOwnProperty, + push = arrayRef.push, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + setTimeout = context.setTimeout, + splice = arrayRef.splice, + unshift = arrayRef.unshift; + + /** Used to set meta data on functions */ + var defineProperty = (function() { + // IE 8 only accepts DOM elements + try { + var o = {}, + func = isNative(func = Object.defineProperty) && func, + result = func(o, o, o) && func; + } catch(e) { } + return result; + }()); + + /* Native method shortcuts for methods with the same name as other `lodash` methods */ + var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, + nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, + nativeIsFinite = context.isFinite, + nativeIsNaN = context.isNaN, + nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, + nativeMax = Math.max, + nativeMin = Math.min, + nativeParseInt = context.parseInt, + nativeRandom = Math.random; + + /** Used to lookup a built-in constructor by [[Class]] */ + var ctorByClass = {}; + ctorByClass[arrayClass] = Array; + ctorByClass[boolClass] = Boolean; + ctorByClass[dateClass] = Date; + ctorByClass[funcClass] = Function; + ctorByClass[objectClass] = Object; + ctorByClass[numberClass] = Number; + ctorByClass[regexpClass] = RegExp; + ctorByClass[stringClass] = String; + + /** Used to avoid iterating non-enumerable properties in IE < 9 */ + var nonEnumProps = {}; + nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; + nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true }; + nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true }; + nonEnumProps[objectClass] = { 'constructor': true }; + + (function() { + var length = shadowedProps.length; + while (length--) { + var key = shadowedProps[length]; + for (var className in nonEnumProps) { + if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) { + nonEnumProps[className][key] = false; + } + } + } + }()); + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps the given value to enable intuitive + * method chaining. + * + * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, + * and `unshift` + * + * Chaining is supported in custom builds as long as the `value` method is + * implicitly or explicitly included in the build. + * + * The chainable wrapper functions are: + * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, + * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, + * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, + * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, + * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, + * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, + * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, + * and `zip` + * + * The non-chainable wrapper functions are: + * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`, + * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, + * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, + * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`, + * `template`, `unescape`, `uniqueId`, and `value` + * + * The wrapper functions `first` and `last` return wrapped values when `n` is + * provided, otherwise they return unwrapped values. + * + * Explicit chaining can be enabled by using the `_.chain` method. + * + * @name _ + * @constructor + * @category Chaining + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns a `lodash` instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(num) { + * return num * num; + * }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor + return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__')) + ? value + : new lodashWrapper(value); + } + + /** + * A fast path for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap in a `lodash` instance. + * @param {boolean} chainAll A flag to enable chaining for all methods + * @returns {Object} Returns a `lodash` instance. + */ + function lodashWrapper(value, chainAll) { + this.__chain__ = !!chainAll; + this.__wrapped__ = value; + } + // ensure `new lodashWrapper` is an instance of `lodash` + lodashWrapper.prototype = lodash.prototype; + + /** + * An object used to flag environments features. + * + * @static + * @memberOf _ + * @type Object + */ + var support = lodash.support = {}; + + (function() { + var ctor = function() { this.x = 1; }, + object = { '0': 1, 'length': 1 }, + props = []; + + ctor.prototype = { 'valueOf': 1, 'y': 1 }; + for (var key in new ctor) { props.push(key); } + for (key in arguments) { } + + /** + * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9). + * + * @memberOf _.support + * @type boolean + */ + support.argsClass = toString.call(arguments) == argsClass; + + /** + * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5). + * + * @memberOf _.support + * @type boolean + */ + support.argsObject = arguments.constructor == Object && !(arguments instanceof Array); + + /** + * Detect if `name` or `message` properties of `Error.prototype` are + * enumerable by default. (IE < 9, Safari < 5.1) + * + * @memberOf _.support + * @type boolean + */ + support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name'); + + /** + * Detect if `prototype` properties are enumerable by default. + * + * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 + * (if the prototype or a property on the prototype has been set) + * incorrectly sets a function's `prototype` property [[Enumerable]] + * value to `true`. + * + * @memberOf _.support + * @type boolean + */ + support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype'); + + /** + * Detect if functions can be decompiled by `Function#toString` + * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). + * + * @memberOf _.support + * @type boolean + */ + support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); + + /** + * Detect if `Function#name` is supported (all but IE). + * + * @memberOf _.support + * @type boolean + */ + support.funcNames = typeof Function.name == 'string'; + + /** + * Detect if `arguments` object indexes are non-enumerable + * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1). + * + * @memberOf _.support + * @type boolean + */ + support.nonEnumArgs = key != 0; + + /** + * Detect if properties shadowing those on `Object.prototype` are non-enumerable. + * + * In IE < 9 an objects own properties, shadowing non-enumerable ones, are + * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug). + * + * @memberOf _.support + * @type boolean + */ + support.nonEnumShadows = !/valueOf/.test(props); + + /** + * Detect if own properties are iterated after inherited properties (all but IE < 9). + * + * @memberOf _.support + * @type boolean + */ + support.ownLast = props[0] != 'x'; + + /** + * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly. + * + * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` + * and `splice()` functions that fail to remove the last element, `value[0]`, + * of array-like objects even though the `length` property is set to `0`. + * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` + * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. + * + * @memberOf _.support + * @type boolean + */ + support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]); + + /** + * Detect lack of support for accessing string characters by index. + * + * IE < 8 can't access characters by index and IE 8 can only access + * characters by index on string literals. + * + * @memberOf _.support + * @type boolean + */ + support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; + + /** + * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9) + * and that the JS engine errors when attempting to coerce an object to + * a string without a `toString` function. + * + * @memberOf _.support + * @type boolean + */ + try { + support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + '')); + } catch(e) { + support.nodeClass = true; + } + }(1)); + + /** + * By default, the template delimiters used by Lo-Dash are similar to those in + * embedded Ruby (ERB). Change the following template settings to use alternative + * delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': /<%-([\s\S]+?)%>/g, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': /<%([\s\S]+?)%>/g, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type Object + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type Function + */ + '_': lodash + } + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The template used to create iterator functions. + * + * @private + * @param {Object} data The data object used to populate the text. + * @returns {string} Returns the interpolated text. + */ + var iteratorTemplate = function(obj) { + + var __p = 'var index, iterable = ' + + (obj.firstArg) + + ', result = ' + + (obj.init) + + ';\nif (!iterable) return result;\n' + + (obj.top) + + ';'; + if (obj.array) { + __p += '\nvar length = iterable.length; index = -1;\nif (' + + (obj.array) + + ') { '; + if (support.unindexedChars) { + __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } '; + } + __p += '\n while (++index < length) {\n ' + + (obj.loop) + + ';\n }\n}\nelse { '; + } else if (support.nonEnumArgs) { + __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' + + (obj.loop) + + ';\n }\n } else { '; + } + + if (support.enumPrototypes) { + __p += '\n var skipProto = typeof iterable == \'function\';\n '; + } + + if (support.enumErrorProps) { + __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n '; + } + + var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); } + + if (obj.useHas && obj.keys) { + __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n'; + if (conditions.length) { + __p += ' if (' + + (conditions.join(' && ')) + + ') {\n '; + } + __p += + (obj.loop) + + '; '; + if (conditions.length) { + __p += '\n }'; + } + __p += '\n } '; + } else { + __p += '\n for (index in iterable) {\n'; + if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) { + __p += ' if (' + + (conditions.join(' && ')) + + ') {\n '; + } + __p += + (obj.loop) + + '; '; + if (conditions.length) { + __p += '\n }'; + } + __p += '\n } '; + if (support.nonEnumShadows) { + __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n '; + for (k = 0; k < 7; k++) { + __p += '\n index = \'' + + (obj.shadowedProps[k]) + + '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))'; + if (!obj.useHas) { + __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])'; + } + __p += ') {\n ' + + (obj.loop) + + ';\n } '; + } + __p += '\n } '; + } + + } + + if (obj.array || support.nonEnumArgs) { + __p += '\n}'; + } + __p += + (obj.bottom) + + ';\nreturn result'; + + return __p + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.bind` that creates the bound function and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new bound function. + */ + function baseBind(bindData) { + var func = bindData[0], + partialArgs = bindData[2], + thisArg = bindData[4]; + + function bound() { + // `Function#bind` spec + // http://es5.github.io/#x15.3.4.5 + if (partialArgs) { + // avoid `arguments` object deoptimizations by using `slice` instead + // of `Array.prototype.slice.call` and not assigning `arguments` to a + // variable as a ternary expression + var args = slice(partialArgs); + push.apply(args, arguments); + } + // mimic the constructor's `return` behavior + // http://es5.github.io/#x13.2.2 + if (this instanceof bound) { + // ensure `new bound` is an instance of `func` + var thisBinding = baseCreate(func.prototype), + result = func.apply(thisBinding, args || arguments); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisArg, args || arguments); + } + setBindData(bound, bindData); + return bound; + } + + /** + * The base implementation of `_.clone` without argument juggling or support + * for `thisArg` binding. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep=false] Specify a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates clones with source counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, callback, stackA, stackB) { + if (callback) { + var result = callback(value); + if (typeof result != 'undefined') { + return result; + } + } + // inspect [[Class]] + var isObj = isObject(value); + if (isObj) { + var className = toString.call(value); + if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) { + return value; + } + var ctor = ctorByClass[className]; + switch (className) { + case boolClass: + case dateClass: + return new ctor(+value); + + case numberClass: + case stringClass: + return new ctor(value); + + case regexpClass: + result = ctor(value.source, reFlags.exec(value)); + result.lastIndex = value.lastIndex; + return result; + } + } else { + return value; + } + var isArr = isArray(value); + if (isDeep) { + // check for circular references and return corresponding clone + var initedStack = !stackA; + stackA || (stackA = getArray()); + stackB || (stackB = getArray()); + + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + result = isArr ? ctor(value.length) : {}; + } + else { + result = isArr ? slice(value) : assign({}, value); + } + // add array properties assigned by `RegExp#exec` + if (isArr) { + if (hasOwnProperty.call(value, 'index')) { + result.index = value.index; + } + if (hasOwnProperty.call(value, 'input')) { + result.input = value.input; + } + } + // exit for shallow clone + if (!isDeep) { + return result; + } + // add the source value to the stack of traversed objects + // and associate it with its clone + stackA.push(value); + stackB.push(result); + + // recursively populate clone (susceptible to call stack limits) + (isArr ? baseEach : forOwn)(value, function(objValue, key) { + result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); + }); + + if (initedStack) { + releaseArray(stackA); + releaseArray(stackB); + } + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(prototype, properties) { + return isObject(prototype) ? nativeCreate(prototype) : {}; + } + // fallback for browsers without `Object.create` + if (!nativeCreate) { + baseCreate = (function() { + function Object() {} + return function(prototype) { + if (isObject(prototype)) { + Object.prototype = prototype; + var result = new Object; + Object.prototype = null; + } + return result || context.Object(); + }; + }()); + } + + /** + * The base implementation of `_.createCallback` without support for creating + * "_.pluck" or "_.where" style callbacks. + * + * @private + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + */ + function baseCreateCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + // exit early for no `thisArg` or already bound by `Function#bind` + if (typeof thisArg == 'undefined' || !('prototype' in func)) { + return func; + } + var bindData = func.__bindData__; + if (typeof bindData == 'undefined') { + if (support.funcNames) { + bindData = !func.name; + } + bindData = bindData || !support.funcDecomp; + if (!bindData) { + var source = fnToString.call(func); + if (!support.funcNames) { + bindData = !reFuncName.test(source); + } + if (!bindData) { + // checks if `func` references the `this` keyword and stores the result + bindData = reThis.test(source); + setBindData(func, bindData); + } + } + } + // exit early if there are no `this` references or `func` is bound + if (bindData === false || (bindData !== true && bindData[1] & 1)) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 2: return function(a, b) { + return func.call(thisArg, a, b); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + } + return bind(func, thisArg); + } + + /** + * The base implementation of `createWrapper` that creates the wrapper and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new function. + */ + function baseCreateWrapper(bindData) { + var func = bindData[0], + bitmask = bindData[1], + partialArgs = bindData[2], + partialRightArgs = bindData[3], + thisArg = bindData[4], + arity = bindData[5]; + + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + key = func; + + function bound() { + var thisBinding = isBind ? thisArg : this; + if (partialArgs) { + var args = slice(partialArgs); + push.apply(args, arguments); + } + if (partialRightArgs || isCurry) { + args || (args = slice(arguments)); + if (partialRightArgs) { + push.apply(args, partialRightArgs); + } + if (isCurry && args.length < arity) { + bitmask |= 16 & ~32; + return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); + } + } + args || (args = arguments); + if (isBindKey) { + func = thisBinding[key]; + } + if (this instanceof bound) { + thisBinding = baseCreate(func.prototype); + var result = func.apply(thisBinding, args); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisBinding, args); + } + setBindData(bound, bindData); + return bound; + } + + /** + * The base implementation of `_.difference` that accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to process. + * @param {Array} [values] The array of values to exclude. + * @returns {Array} Returns a new array of filtered values. + */ + function baseDifference(array, values) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + isLarge = length >= largeArraySize && indexOf === baseIndexOf, + result = []; + + if (isLarge) { + var cache = createCache(values); + if (cache) { + indexOf = cacheIndexOf; + values = cache; + } else { + isLarge = false; + } + } + while (++index < length) { + var value = array[index]; + if (indexOf(values, value) < 0) { + result.push(value); + } + } + if (isLarge) { + releaseObject(values); + } + return result; + } + + /** + * The base implementation of `_.flatten` without support for callback + * shorthands or `thisArg` binding. + * + * @private + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. + * @param {number} [fromIndex=0] The index to start from. + * @returns {Array} Returns a new flattened array. + */ + function baseFlatten(array, isShallow, isStrict, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + + if (value && typeof value == 'object' && typeof value.length == 'number' + && (isArray(value) || isArguments(value))) { + // recursively flatten arrays (susceptible to call stack limits) + if (!isShallow) { + value = baseFlatten(value, isShallow, isStrict); + } + var valIndex = -1, + valLength = value.length, + resIndex = result.length; + + result.length += valLength; + while (++valIndex < valLength) { + result[resIndex++] = value[valIndex]; + } + } else if (!isStrict) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.isEqual`, without support for `thisArg` binding, + * that allows partial "_.where" style comparisons. + * + * @private + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `a` objects. + * @param {Array} [stackB=[]] Tracks traversed `b` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { + // used to indicate that when comparing objects, `a` has at least the properties of `b` + if (callback) { + var result = callback(a, b); + if (typeof result != 'undefined') { + return !!result; + } + } + // exit early for identical values + if (a === b) { + // treat `+0` vs. `-0` as not equal + return a !== 0 || (1 / a == 1 / b); + } + var type = typeof a, + otherType = typeof b; + + // exit early for unlike primitive values + if (a === a && + !(a && objectTypes[type]) && + !(b && objectTypes[otherType])) { + return false; + } + // exit early for `null` and `undefined` avoiding ES3's Function#call behavior + // http://es5.github.io/#x15.3.4.4 + if (a == null || b == null) { + return a === b; + } + // compare [[Class]] names + var className = toString.call(a), + otherClass = toString.call(b); + + if (className == argsClass) { + className = objectClass; + } + if (otherClass == argsClass) { + otherClass = objectClass; + } + if (className != otherClass) { + return false; + } + switch (className) { + case boolClass: + case dateClass: + // coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal + return +a == +b; + + case numberClass: + // treat `NaN` vs. `NaN` as equal + return (a != +a) + ? b != +b + // but treat `+0` vs. `-0` as not equal + : (a == 0 ? (1 / a == 1 / b) : a == +b); + + case regexpClass: + case stringClass: + // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) + // treat string primitives and their corresponding object instances as equal + return a == String(b); + } + var isArr = className == arrayClass; + if (!isArr) { + // unwrap any `lodash` wrapped values + var aWrapped = hasOwnProperty.call(a, '__wrapped__'), + bWrapped = hasOwnProperty.call(b, '__wrapped__'); + + if (aWrapped || bWrapped) { + return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); + } + // exit for functions and DOM nodes + if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) { + return false; + } + // in older versions of Opera, `arguments` objects have `Array` constructors + var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor, + ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor; + + // non `Object` object instances with different constructors are not equal + if (ctorA != ctorB && + !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && + ('constructor' in a && 'constructor' in b) + ) { + return false; + } + } + // assume cyclic structures are equal + // the algorithm for detecting cyclic structures is adapted from ES 5.1 + // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) + var initedStack = !stackA; + stackA || (stackA = getArray()); + stackB || (stackB = getArray()); + + var length = stackA.length; + while (length--) { + if (stackA[length] == a) { + return stackB[length] == b; + } + } + var size = 0; + result = true; + + // add `a` and `b` to the stack of traversed objects + stackA.push(a); + stackB.push(b); + + // recursively compare objects and arrays (susceptible to call stack limits) + if (isArr) { + // compare lengths to determine if a deep comparison is necessary + length = a.length; + size = b.length; + result = size == length; + + if (result || isWhere) { + // deep compare the contents, ignoring non-numeric properties + while (size--) { + var index = length, + value = b[size]; + + if (isWhere) { + while (index--) { + if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } + } + else { + // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` + // which, in this case, is more costly + forIn(b, function(value, key, b) { + if (hasOwnProperty.call(b, key)) { + // count the number of properties. + size++; + // deep compare each property value. + return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); + } + }); + + if (result && !isWhere) { + // ensure both objects have the same number of properties + forIn(a, function(value, key, a) { + if (hasOwnProperty.call(a, key)) { + // `size` will be `-1` if `a` has more properties than `b` + return (result = --size > -1); + } + }); + } + } + stackA.pop(); + stackB.pop(); + + if (initedStack) { + releaseArray(stackA); + releaseArray(stackB); + } + return result; + } + + /** + * The base implementation of `_.merge` without argument juggling or support + * for `thisArg` binding. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} [callback] The function to customize merging properties. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + */ + function baseMerge(object, source, callback, stackA, stackB) { + (isArray(source) ? forEach : forOwn)(source, function(source, key) { + var found, + isArr, + result = source, + value = object[key]; + + if (source && ((isArr = isArray(source)) || isPlainObject(source))) { + // avoid merging previously merged cyclic sources + var stackLength = stackA.length; + while (stackLength--) { + if ((found = stackA[stackLength] == source)) { + value = stackB[stackLength]; + break; + } + } + if (!found) { + var isShallow; + if (callback) { + result = callback(value, source); + if ((isShallow = typeof result != 'undefined')) { + value = result; + } + } + if (!isShallow) { + value = isArr + ? (isArray(value) ? value : []) + : (isPlainObject(value) ? value : {}); + } + // add `source` and associated `value` to the stack of traversed objects + stackA.push(source); + stackB.push(value); + + // recursively merge objects and arrays (susceptible to call stack limits) + if (!isShallow) { + baseMerge(value, source, callback, stackA, stackB); + } + } + } + else { + if (callback) { + result = callback(value, source); + if (typeof result == 'undefined') { + result = source; + } + } + if (typeof result != 'undefined') { + value = result; + } + } + object[key] = value; + }); + } + + /** + * The base implementation of `_.random` without argument juggling or support + * for returning floating-point numbers. + * + * @private + * @param {number} min The minimum possible value. + * @param {number} max The maximum possible value. + * @returns {number} Returns a random number. + */ + function baseRandom(min, max) { + return min + floor(nativeRandom() * (max - min + 1)); + } + + /** + * The base implementation of `_.uniq` without support for callback shorthands + * or `thisArg` binding. + * + * @private + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function} [callback] The function called per iteration. + * @returns {Array} Returns a duplicate-value-free array. + */ + function baseUniq(array, isSorted, callback) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + result = []; + + var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf, + seen = (callback || isLarge) ? getArray() : result; + + if (isLarge) { + var cache = createCache(seen); + indexOf = cacheIndexOf; + seen = cache; + } + while (++index < length) { + var value = array[index], + computed = callback ? callback(value, index, array) : value; + + if (isSorted + ? !index || seen[seen.length - 1] !== computed + : indexOf(seen, computed) < 0 + ) { + if (callback || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + if (isLarge) { + releaseArray(seen.array); + releaseObject(seen); + } else if (callback) { + releaseArray(seen); + } + return result; + } + + /** + * Creates a function that aggregates a collection, creating an object composed + * of keys generated from the results of running each element of the collection + * through a callback. The given `setter` function sets the keys and values + * of the composed object. + * + * @private + * @param {Function} setter The setter function. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter) { + return function(collection, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + setter(result, value, callback(value, index, collection), collection); + } + } else { + baseEach(collection, function(value, key, collection) { + setter(result, value, callback(value, key, collection), collection); + }); + } + return result; + }; + } + + /** + * Creates a function that, when called, either curries or invokes `func` + * with an optional `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of method flags to compose. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` + * 8 - `_.curry` (bound) + * 16 - `_.partial` + * 32 - `_.partialRight` + * @param {Array} [partialArgs] An array of arguments to prepend to those + * provided to the new function. + * @param {Array} [partialRightArgs] An array of arguments to append to those + * provided to the new function. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new function. + */ + function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + isPartial = bitmask & 16, + isPartialRight = bitmask & 32; + + if (!isBindKey && !isFunction(func)) { + throw new TypeError; + } + if (isPartial && !partialArgs.length) { + bitmask &= ~16; + isPartial = partialArgs = false; + } + if (isPartialRight && !partialRightArgs.length) { + bitmask &= ~32; + isPartialRight = partialRightArgs = false; + } + var bindData = func && func.__bindData__; + if (bindData && bindData !== true) { + // clone `bindData` + bindData = slice(bindData); + if (bindData[2]) { + bindData[2] = slice(bindData[2]); + } + if (bindData[3]) { + bindData[3] = slice(bindData[3]); + } + // set `thisBinding` is not previously bound + if (isBind && !(bindData[1] & 1)) { + bindData[4] = thisArg; + } + // set if previously bound but not currently (subsequent curried functions) + if (!isBind && bindData[1] & 1) { + bitmask |= 8; + } + // set curried arity if not yet set + if (isCurry && !(bindData[1] & 4)) { + bindData[5] = arity; + } + // append partial left arguments + if (isPartial) { + push.apply(bindData[2] || (bindData[2] = []), partialArgs); + } + // append partial right arguments + if (isPartialRight) { + unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); + } + // merge flags + bindData[1] |= bitmask; + return createWrapper.apply(null, bindData); + } + // fast path for `_.bind` + var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; + return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); + } + + /** + * Creates compiled iteration functions. + * + * @private + * @param {...Object} [options] The compile options object(s). + * @param {string} [options.array] Code to determine if the iterable is an array or array-like. + * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop. + * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration. + * @param {string} [options.args] A comma separated string of iteration function arguments. + * @param {string} [options.top] Code to execute before the iteration branches. + * @param {string} [options.loop] Code to execute in the object loop. + * @param {string} [options.bottom] Code to execute after the iteration branches. + * @returns {Function} Returns the compiled function. + */ + function createIterator() { + // data properties + iteratorData.shadowedProps = shadowedProps; + + // iterator options + iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = ''; + iteratorData.init = 'iterable'; + iteratorData.useHas = true; + + // merge options into a template data object + for (var object, index = 0; object = arguments[index]; index++) { + for (var key in object) { + iteratorData[key] = object[key]; + } + } + var args = iteratorData.args; + iteratorData.firstArg = /^[^,]+/.exec(args)[0]; + + // create the function factory + var factory = Function( + 'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' + + 'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' + + 'objectTypes, nonEnumProps, stringClass, stringProto, toString', + 'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}' + ); + + // return the compiled function + return factory( + baseCreateCallback, errorClass, errorProto, hasOwnProperty, + indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto, + objectTypes, nonEnumProps, stringClass, stringProto, toString + ); + } + + /** + * Used by `escape` to convert characters to HTML entities. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(match) { + return htmlEscapes[match]; + } + + /** + * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * customized, this method returns the custom method, otherwise it returns + * the `baseIndexOf` function. + * + * @private + * @returns {Function} Returns the "indexOf" function. + */ + function getIndexOf() { + var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; + return result; + } + + /** + * Checks if `value` is a native function. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. + */ + function isNative(value) { + return typeof value == 'function' && reNative.test(value); + } + + /** + * Sets `this` binding data on a given function. + * + * @private + * @param {Function} func The function to set data on. + * @param {Array} value The data array to set. + */ + var setBindData = !defineProperty ? noop : function(func, value) { + descriptor.value = value; + defineProperty(func, '__bindData__', descriptor); + descriptor.value = null; + }; + + /** + * A fallback implementation of `isPlainObject` which checks if a given value + * is an object created by the `Object` constructor, assuming objects created + * by the `Object` constructor have no inherited enumerable properties and that + * there are no `Object.prototype` extensions. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + */ + function shimIsPlainObject(value) { + var ctor, + result; + + // avoid non Object objects, `arguments` objects, and DOM elements + if (!(value && toString.call(value) == objectClass) || + (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) || + (!support.argsClass && isArguments(value)) || + (!support.nodeClass && isNode(value))) { + return false; + } + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + if (support.ownLast) { + forIn(value, function(value, key, object) { + result = hasOwnProperty.call(object, key); + return false; + }); + return result !== false; + } + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + forIn(value, function(value, key) { + result = key; + }); + return typeof result == 'undefined' || hasOwnProperty.call(value, result); + } + + /** + * Used by `unescape` to convert HTML entities to characters. + * + * @private + * @param {string} match The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(match) { + return htmlUnescapes[match]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Checks if `value` is an `arguments` object. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. + * @example + * + * (function() { return _.isArguments(arguments); })(1, 2, 3); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == argsClass || false; + } + // fallback for browsers that can't detect `arguments` objects by [[Class]] + if (!support.argsClass) { + isArguments = function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false; + }; + } + + /** + * Checks if `value` is an array. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an array, else `false`. + * @example + * + * (function() { return _.isArray(arguments); })(); + * // => false + * + * _.isArray([1, 2, 3]); + * // => true + */ + var isArray = nativeIsArray || function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == arrayClass || false; + }; + + /** + * A fallback implementation of `Object.keys` which produces an array of the + * given object's own enumerable property names. + * + * @private + * @type Function + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + */ + var shimKeys = createIterator({ + 'args': 'object', + 'init': '[]', + 'top': 'if (!(objectTypes[typeof object])) return result', + 'loop': 'result.push(index)' + }); + + /** + * Creates an array composed of the own enumerable property names of an object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + * @example + * + * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); + * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) + */ + var keys = !nativeKeys ? shimKeys : function(object) { + if (!isObject(object)) { + return []; + } + if ((support.enumPrototypes && typeof object == 'function') || + (support.nonEnumArgs && object.length && isArguments(object))) { + return shimKeys(object); + } + return nativeKeys(object); + }; + + /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */ + var eachIteratorOptions = { + 'args': 'collection, callback, thisArg', + 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)", + 'array': "typeof length == 'number'", + 'keys': keys, + 'loop': 'if (callback(iterable[index], index, collection) === false) return result' + }; + + /** Reusable iterator options for `assign` and `defaults` */ + var defaultsIteratorOptions = { + 'args': 'object, source, guard', + 'top': + 'var args = arguments,\n' + + ' argsIndex = 0,\n' + + " argsLength = typeof guard == 'number' ? 2 : args.length;\n" + + 'while (++argsIndex < argsLength) {\n' + + ' iterable = args[argsIndex];\n' + + ' if (iterable && objectTypes[typeof iterable]) {', + 'keys': keys, + 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]", + 'bottom': ' }\n}' + }; + + /** Reusable iterator options for `forIn` and `forOwn` */ + var forOwnIteratorOptions = { + 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top, + 'array': false + }; + + /** + * Used to convert characters to HTML entities: + * + * Though the `>` character is escaped for symmetry, characters like `>` and `/` + * don't require escaping in HTML and have no special meaning unless they're part + * of a tag or an unquoted attribute value. + * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") + */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + /** Used to convert HTML entities to characters */ + var htmlUnescapes = invert(htmlEscapes); + + /** Used to match HTML entities and HTML characters */ + var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), + reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); + + /** + * A function compiled to iterate `arguments` objects, arrays, objects, and + * strings consistenly across environments, executing the callback for each + * element in the collection. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index|key, collection). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @private + * @type Function + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEach = createIterator(eachIteratorOptions); + + /*--------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources will overwrite property assignments of previous + * sources. If a callback is provided it will be executed to produce the + * assigned values. The callback is bound to `thisArg` and invoked with two + * arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @type Function + * @alias extend + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param {Function} [callback] The function to customize assigning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); + * // => { 'name': 'fred', 'employer': 'slate' } + * + * var defaults = _.partialRight(_.assign, function(a, b) { + * return typeof a == 'undefined' ? b : a; + * }); + * + * var object = { 'name': 'barney' }; + * defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + var assign = createIterator(defaultsIteratorOptions, { + 'top': + defaultsIteratorOptions.top.replace(';', + ';\n' + + "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" + + ' var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' + + "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" + + ' callback = args[--argsLength];\n' + + '}' + ), + 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]' + }); + + /** + * Creates a clone of `value`. If `isDeep` is `true` nested objects will also + * be cloned, otherwise they will be assigned by reference. If a callback + * is provided it will be executed to produce the cloned values. If the + * callback returns `undefined` cloning will be handled by the method instead. + * The callback is bound to `thisArg` and invoked with one argument; (value). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to clone. + * @param {boolean} [isDeep=false] Specify a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the cloned value. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * var shallow = _.clone(characters); + * shallow[0] === characters[0]; + * // => true + * + * var deep = _.clone(characters, true); + * deep[0] === characters[0]; + * // => false + * + * _.mixin({ + * 'clone': _.partialRight(_.clone, function(value) { + * return _.isElement(value) ? value.cloneNode(false) : undefined; + * }) + * }); + * + * var clone = _.clone(document.body); + * clone.childNodes.length; + * // => 0 + */ + function clone(value, isDeep, callback, thisArg) { + // allows working with "Collections" methods without using their `index` + // and `collection` arguments for `isDeep` and `callback` + if (typeof isDeep != 'boolean' && isDeep != null) { + thisArg = callback; + callback = isDeep; + isDeep = false; + } + return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + } + + /** + * Creates a deep clone of `value`. If a callback is provided it will be + * executed to produce the cloned values. If the callback returns `undefined` + * cloning will be handled by the method instead. The callback is bound to + * `thisArg` and invoked with one argument; (value). + * + * Note: This method is loosely based on the structured clone algorithm. Functions + * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and + * objects created by constructors other than `Object` are cloned to plain `Object` objects. + * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the deep cloned value. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * var deep = _.cloneDeep(characters); + * deep[0] === characters[0]; + * // => false + * + * var view = { + * 'label': 'docs', + * 'node': element + * }; + * + * var clone = _.cloneDeep(view, function(value) { + * return _.isElement(value) ? value.cloneNode(true) : undefined; + * }); + * + * clone.node == view.node; + * // => false + */ + function cloneDeep(value, callback, thisArg) { + return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + } + + /** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties ? assign(result, properties) : result; + } + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional defaults of the same property will be ignored. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param- {Object} [guard] Allows working with `_.reduce` without using its + * `key` and `object` arguments as sources. + * @returns {Object} Returns the destination object. + * @example + * + * var object = { 'name': 'barney' }; + * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + var defaults = createIterator(defaultsIteratorOptions); + + /** + * This method is like `_.findIndex` except that it returns the key of the + * first element that passes the callback check, instead of the element itself. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to search. + * @param {Function|Object|string} [callback=identity] The function called per + * iteration. If a property name or object is provided it will be used to + * create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @example + * + * var characters = { + * 'barney': { 'age': 36, 'blocked': false }, + * 'fred': { 'age': 40, 'blocked': true }, + * 'pebbles': { 'age': 1, 'blocked': false } + * }; + * + * _.findKey(characters, function(chr) { + * return chr.age < 40; + * }); + * // => 'barney' (property order is not guaranteed across environments) + * + * // using "_.where" callback shorthand + * _.findKey(characters, { 'age': 1 }); + * // => 'pebbles' + * + * // using "_.pluck" callback shorthand + * _.findKey(characters, 'blocked'); + * // => 'fred' + */ + function findKey(object, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forOwn(object, function(value, key, object) { + if (callback(value, key, object)) { + result = key; + return false; + } + }); + return result; + } + + /** + * This method is like `_.findKey` except that it iterates over elements + * of a `collection` in the opposite order. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to search. + * @param {Function|Object|string} [callback=identity] The function called per + * iteration. If a property name or object is provided it will be used to + * create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @example + * + * var characters = { + * 'barney': { 'age': 36, 'blocked': true }, + * 'fred': { 'age': 40, 'blocked': false }, + * 'pebbles': { 'age': 1, 'blocked': true } + * }; + * + * _.findLastKey(characters, function(chr) { + * return chr.age < 40; + * }); + * // => returns `pebbles`, assuming `_.findKey` returns `barney` + * + * // using "_.where" callback shorthand + * _.findLastKey(characters, { 'age': 40 }); + * // => 'fred' + * + * // using "_.pluck" callback shorthand + * _.findLastKey(characters, 'blocked'); + * // => 'pebbles' + */ + function findLastKey(object, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forOwnRight(object, function(value, key, object) { + if (callback(value, key, object)) { + result = key; + return false; + } + }); + return result; + } + + /** + * Iterates over own and inherited enumerable properties of an object, + * executing the callback for each property. The callback is bound to `thisArg` + * and invoked with three arguments; (value, key, object). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forIn(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) + */ + var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, { + 'useHas': false + }); + + /** + * This method is like `_.forIn` except that it iterates over elements + * of a `collection` in the opposite order. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forInRight(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' + */ + function forInRight(object, callback, thisArg) { + var pairs = []; + + forIn(object, function(value, key) { + pairs.push(key, value); + }); + + var length = pairs.length; + callback = baseCreateCallback(callback, thisArg, 3); + while (length--) { + if (callback(pairs[length--], pairs[length], object) === false) { + break; + } + } + return object; + } + + /** + * Iterates over own enumerable properties of an object, executing the callback + * for each property. The callback is bound to `thisArg` and invoked with three + * arguments; (value, key, object). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) + */ + var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions); + + /** + * This method is like `_.forOwn` except that it iterates over elements + * of a `collection` in the opposite order. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' + */ + function forOwnRight(object, callback, thisArg) { + var props = keys(object), + length = props.length; + + callback = baseCreateCallback(callback, thisArg, 3); + while (length--) { + var key = props[length]; + if (callback(object[key], key, object) === false) { + break; + } + } + return object; + } + + /** + * Creates a sorted array of property names of all enumerable properties, + * own and inherited, of `object` that have function values. + * + * @static + * @memberOf _ + * @alias methods + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names that have function values. + * @example + * + * _.functions(_); + * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] + */ + function functions(object) { + var result = []; + forIn(object, function(value, key) { + if (isFunction(value)) { + result.push(key); + } + }); + return result.sort(); + } + + /** + * Checks if the specified property name exists as a direct property of `object`, + * instead of an inherited property. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to check. + * @returns {boolean} Returns `true` if key is a direct property, else `false`. + * @example + * + * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); + * // => true + */ + function has(object, key) { + return object ? hasOwnProperty.call(object, key) : false; + } + + /** + * Creates an object composed of the inverted keys and values of the given object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to invert. + * @returns {Object} Returns the created inverted object. + * @example + * + * _.invert({ 'first': 'fred', 'second': 'barney' }); + * // => { 'fred': 'first', 'barney': 'second' } + */ + function invert(object) { + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + result[object[key]] = key; + } + return result; + } + + /** + * Checks if `value` is a boolean value. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. + * @example + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + value && typeof value == 'object' && toString.call(value) == boolClass || false; + } + + /** + * Checks if `value` is a date. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a date, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + */ + function isDate(value) { + return value && typeof value == 'object' && toString.call(value) == dateClass || false; + } + + /** + * Checks if `value` is a DOM element. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + */ + function isElement(value) { + return value && value.nodeType === 1 || false; + } + + /** + * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a + * length of `0` and objects with no own enumerable properties are considered + * "empty". + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if the `value` is empty, else `false`. + * @example + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({}); + * // => true + * + * _.isEmpty(''); + * // => true + */ + function isEmpty(value) { + var result = true; + if (!value) { + return result; + } + var className = toString.call(value), + length = value.length; + + if ((className == arrayClass || className == stringClass || + (support.argsClass ? className == argsClass : isArguments(value))) || + (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { + return !length; + } + forOwn(value, function() { + return (result = false); + }); + return result; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent to each other. If a callback is provided it will be executed + * to compare values. If the callback returns `undefined` comparisons will + * be handled by the method instead. The callback is bound to `thisArg` and + * invoked with two arguments; (a, b). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'name': 'fred' }; + * var copy = { 'name': 'fred' }; + * + * object == copy; + * // => false + * + * _.isEqual(object, copy); + * // => true + * + * var words = ['hello', 'goodbye']; + * var otherWords = ['hi', 'goodbye']; + * + * _.isEqual(words, otherWords, function(a, b) { + * var reGreet = /^(?:hello|hi)$/i, + * aGreet = _.isString(a) && reGreet.test(a), + * bGreet = _.isString(b) && reGreet.test(b); + * + * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; + * }); + * // => true + */ + function isEqual(a, b, callback, thisArg) { + return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2)); + } + + /** + * Checks if `value` is, or can be coerced to, a finite number. + * + * Note: This is not the same as native `isFinite` which will return true for + * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is finite, else `false`. + * @example + * + * _.isFinite(-101); + * // => true + * + * _.isFinite('10'); + * // => true + * + * _.isFinite(true); + * // => false + * + * _.isFinite(''); + * // => false + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); + } + + /** + * Checks if `value` is a function. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + */ + function isFunction(value) { + return typeof value == 'function'; + } + // fallback for older versions of Chrome and Safari + if (isFunction(/x/)) { + isFunction = function(value) { + return typeof value == 'function' && toString.call(value) == funcClass; + }; + } + + /** + * Checks if `value` is the language type of Object. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ + function isObject(value) { + // check if the value is the ECMAScript language type of Object + // http://es5.github.io/#x8 + // and avoid a V8 bug + // http://code.google.com/p/v8/issues/detail?id=2291 + return !!(value && objectTypes[typeof value]); + } + + /** + * Checks if `value` is `NaN`. + * + * Note: This is not the same as native `isNaN` which will return `true` for + * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // `NaN` as a primitive is the only value that is not equal to itself + // (perform the [[Class]] check first to avoid errors with some host objects in IE) + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(undefined); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is a number. + * + * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a number, else `false`. + * @example + * + * _.isNumber(8.4 * 5); + * // => true + */ + function isNumber(value) { + return typeof value == 'number' || + value && typeof value == 'object' && toString.call(value) == numberClass || false; + } + + /** + * Checks if `value` is an object created by the `Object` constructor. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * _.isPlainObject(new Shape); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + */ + var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { + if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) { + return false; + } + var valueOf = value.valueOf, + objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); + + return objProto + ? (value == objProto || getPrototypeOf(value) == objProto) + : shimIsPlainObject(value); + }; + + /** + * Checks if `value` is a regular expression. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. + * @example + * + * _.isRegExp(/fred/); + * // => true + */ + function isRegExp(value) { + return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false; + } + + /** + * Checks if `value` is a string. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a string, else `false`. + * @example + * + * _.isString('fred'); + * // => true + */ + function isString(value) { + return typeof value == 'string' || + value && typeof value == 'object' && toString.call(value) == stringClass || false; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + */ + function isUndefined(value) { + return typeof value == 'undefined'; + } + + /** + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through the callback. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new object with values of the results of each `callback` execution. + * @example + * + * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + * + * var characters = { + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * }; + * + * // using "_.pluck" callback shorthand + * _.mapValues(characters, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } + */ + function mapValues(object, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + + forOwn(object, function(value, key, object) { + result[key] = callback(value, key, object); + }); + return result; + } + + /** + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * will overwrite property assignments of previous sources. If a callback is + * provided it will be executed to produce the merged values of the destination + * and source properties. If the callback returns `undefined` merging will + * be handled by the method instead. The callback is bound to `thisArg` and + * invoked with two arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param {Function} [callback] The function to customize merging properties. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * var names = { + * 'characters': [ + * { 'name': 'barney' }, + * { 'name': 'fred' } + * ] + * }; + * + * var ages = { + * 'characters': [ + * { 'age': 36 }, + * { 'age': 40 } + * ] + * }; + * + * _.merge(names, ages); + * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } + * + * var food = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var otherFood = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(food, otherFood, function(a, b) { + * return _.isArray(a) ? a.concat(b) : undefined; + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } + */ + function merge(object) { + var args = arguments, + length = 2; + + if (!isObject(object)) { + return object; + } + // allows working with `_.reduce` and `_.reduceRight` without using + // their `index` and `collection` arguments + if (typeof args[2] != 'number') { + length = args.length; + } + if (length > 3 && typeof args[length - 2] == 'function') { + var callback = baseCreateCallback(args[--length - 1], args[length--], 2); + } else if (length > 2 && typeof args[length - 1] == 'function') { + callback = args[--length]; + } + var sources = slice(arguments, 1, length), + index = -1, + stackA = getArray(), + stackB = getArray(); + + while (++index < length) { + baseMerge(object, sources[index], callback, stackA, stackB); + } + releaseArray(stackA); + releaseArray(stackB); + return object; + } + + /** + * Creates a shallow clone of `object` excluding the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` omitting the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The properties to omit or the + * function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object without the omitted properties. + * @example + * + * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); + * // => { 'name': 'fred' } + * + * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { + * return typeof value == 'number'; + * }); + * // => { 'name': 'fred' } + */ + function omit(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var props = []; + forIn(object, function(value, key) { + props.push(key); + }); + props = baseDifference(props, baseFlatten(arguments, true, false, 1)); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + result[key] = object[key]; + } + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (!callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * Creates a two dimensional array of an object's key-value pairs, + * i.e. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns new array of key-value pairs. + * @example + * + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) + */ + function pairs(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; + } + + /** + * Creates a shallow clone of `object` composed of the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` picking the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The function called per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object composed of the picked properties. + * @example + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); + * // => { 'name': 'fred' } + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { + * return key.charAt(0) != '_'; + * }); + * // => { 'name': 'fred' } + */ + function pick(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var index = -1, + props = baseFlatten(arguments, true, false, 1), + length = isObject(object) ? props.length : 0; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * An alternative to `_.reduce` this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own + * enumerable properties through a callback, with each callback execution + * potentially mutating the `accumulator` object. The callback is bound to + * `thisArg` and invoked with four arguments; (accumulator, value, key, object). + * Callbacks may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) { + * num *= num; + * if (num % 2) { + * return result.push(num) < 3; + * } + * }); + * // => [1, 9, 25] + * + * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function transform(object, callback, accumulator, thisArg) { + var isArr = isArray(object); + if (accumulator == null) { + if (isArr) { + accumulator = []; + } else { + var ctor = object && object.constructor, + proto = ctor && ctor.prototype; + + accumulator = baseCreate(proto); + } + } + if (callback) { + callback = lodash.createCallback(callback, thisArg, 4); + (isArr ? baseEach : forOwn)(object, function(value, index, object) { + return callback(accumulator, value, index, object); + }); + } + return accumulator; + } + + /** + * Creates an array composed of the own enumerable property values of `object`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property values. + * @example + * + * _.values({ 'one': 1, 'two': 2, 'three': 3 }); + * // => [1, 2, 3] (property order is not guaranteed across environments) + */ + function values(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array of elements from the specified indexes, or keys, of the + * `collection`. Indexes may be specified as individual arguments or as arrays + * of indexes. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [index] The indexes of `collection` + * to retrieve, specified as individual indexes or arrays of indexes. + * @returns {Array} Returns a new array of elements corresponding to the + * provided indexes. + * @example + * + * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); + * // => ['a', 'c', 'e'] + * + * _.at(['fred', 'barney', 'pebbles'], 0, 2); + * // => ['fred', 'pebbles'] + */ + function at(collection) { + var args = arguments, + index = -1, + props = baseFlatten(args, true, false, 1), + length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length, + result = Array(length); + + if (support.unindexedChars && isString(collection)) { + collection = collection.split(''); + } + while(++index < length) { + result[index] = collection[props[index]]; + } + return result; + } + + /** + * Checks if a given value is present in a collection using strict equality + * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the + * offset from the end of the collection. + * + * @static + * @memberOf _ + * @alias include + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {*} target The value to check for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {boolean} Returns `true` if the `target` element is found, else `false`. + * @example + * + * _.contains([1, 2, 3], 1); + * // => true + * + * _.contains([1, 2, 3], 1, 2); + * // => false + * + * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.contains('pebbles', 'eb'); + * // => true + */ + function contains(collection, target, fromIndex) { + var index = -1, + indexOf = getIndexOf(), + length = collection ? collection.length : 0, + result = false; + + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; + if (isArray(collection)) { + result = indexOf(collection, target, fromIndex) > -1; + } else if (typeof length == 'number') { + result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1; + } else { + baseEach(collection, function(value) { + if (++index >= fromIndex) { + return !(result = value === target); + } + }); + } + return result; + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through the callback. The corresponding value + * of each key is the number of times the key was returned by the callback. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); + }); + + /** + * Checks if the given callback returns truey value for **all** elements of + * a collection. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if all elements passed the callback check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes']); + * // => false + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.every(characters, 'age'); + * // => true + * + * // using "_.where" callback shorthand + * _.every(characters, { 'age': 36 }); + * // => false + */ + function every(collection, callback, thisArg) { + var result = true; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (!(result = !!callback(collection[index], index, collection))) { + break; + } + } + } else { + baseEach(collection, function(value, index, collection) { + return (result = !!callback(value, index, collection)); + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning an array of all elements + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that passed the callback check. + * @example + * + * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [2, 4, 6] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.filter(characters, 'blocked'); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + * + * // using "_.where" callback shorthand + * _.filter(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + */ + function filter(collection, callback, thisArg) { + var result = []; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + result.push(value); + } + } + } else { + baseEach(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result.push(value); + } + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning the first element that + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias detect, findWhere + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.find(characters, function(chr) { + * return chr.age < 40; + * }); + * // => { 'name': 'barney', 'age': 36, 'blocked': false } + * + * // using "_.where" callback shorthand + * _.find(characters, { 'age': 1 }); + * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } + * + * // using "_.pluck" callback shorthand + * _.find(characters, 'blocked'); + * // => { 'name': 'fred', 'age': 40, 'blocked': true } + */ + function find(collection, callback, thisArg) { + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + return value; + } + } + } else { + var result; + baseEach(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + } + + /** + * This method is like `_.find` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(num) { + * return num % 2 == 1; + * }); + * // => 3 + */ + function findLast(collection, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forEachRight(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + + /** + * Iterates over elements of a collection, executing the callback for each + * element. The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * Note: As with other "Collections" methods, objects with a `length` property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); + * // => logs each number and returns '1,2,3' + * + * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); + * // => logs each number and returns the object (property order is not guaranteed across environments) + */ + function forEach(collection, callback, thisArg) { + if (callback && typeof thisArg == 'undefined' && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (callback(collection[index], index, collection) === false) { + break; + } + } + } else { + baseEach(collection, callback, thisArg); + } + return collection; + } + + /** + * This method is like `_.forEach` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); + * // => logs each number from right to left and returns '3,2,1' + */ + function forEachRight(collection, callback, thisArg) { + var iterable = collection, + length = collection ? collection.length : 0; + + callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); + if (isArray(collection)) { + while (length--) { + if (callback(collection[length], length, collection) === false) { + break; + } + } + } else { + if (typeof length != 'number') { + var props = keys(collection); + length = props.length; + } else if (support.unindexedChars && isString(collection)) { + iterable = collection.split(''); + } + baseEach(collection, function(value, key, collection) { + key = props ? props[--length] : --length; + return callback(iterable[key], key, collection); + }); + } + return collection; + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of a collection through the callback. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false` + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using "_.pluck" callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of the collection through the given callback. The corresponding + * value of each key is the last element responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keys = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keys, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Invokes the method named by `methodName` on each element in the `collection` + * returning an array of the results of each invoked method. Additional arguments + * will be provided to each invoked method. If `methodName` is a function it + * will be invoked for, and `this` bound to, each element in the `collection`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|string} methodName The name of the method to invoke or + * the function invoked per iteration. + * @param {...*} [arg] Arguments to invoke the method with. + * @returns {Array} Returns a new array of the results of each invoked method. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + function invoke(collection, methodName) { + var args = slice(arguments, 2), + index = -1, + isFunc = typeof methodName == 'function', + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); + }); + return result; + } + + /** + * Creates an array of values by running each element in the collection + * through the callback. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias collect + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of the results of each `callback` execution. + * @example + * + * _.map([1, 2, 3], function(num) { return num * 3; }); + * // => [3, 6, 9] + * + * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); + * // => [3, 6, 9] (property order is not guaranteed across environments) + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(characters, 'name'); + * // => ['barney', 'fred'] + */ + function map(collection, callback, thisArg) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + callback = lodash.createCallback(callback, thisArg, 3); + if (isArray(collection)) { + while (++index < length) { + result[index] = callback(collection[index], index, collection); + } + } else { + baseEach(collection, function(value, key, collection) { + result[++index] = callback(value, key, collection); + }); + } + return result; + } + + /** + * Retrieves the maximum value of a collection. If the collection is empty or + * falsey `-Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.max(characters, function(chr) { return chr.age; }); + * // => { 'name': 'fred', 'age': 40 }; + * + * // using "_.pluck" callback shorthand + * _.max(characters, 'age'); + * // => { 'name': 'fred', 'age': 40 }; + */ + function max(collection, callback, thisArg) { + var computed = -Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value > result) { + result = value; + } + } + } else { + callback = (callback == null && isString(collection)) + ? charAtCallback + : lodash.createCallback(callback, thisArg, 3); + + baseEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current > computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the minimum value of a collection. If the collection is empty or + * falsey `Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.min(characters, function(chr) { return chr.age; }); + * // => { 'name': 'barney', 'age': 36 }; + * + * // using "_.pluck" callback shorthand + * _.min(characters, 'age'); + * // => { 'name': 'barney', 'age': 36 }; + */ + function min(collection, callback, thisArg) { + var computed = Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value < result) { + result = value; + } + } + } else { + callback = (callback == null && isString(collection)) + ? charAtCallback + : lodash.createCallback(callback, thisArg, 3); + + baseEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current < computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the value of a specified property from all elements in the collection. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {string} property The name of the property to pluck. + * @returns {Array} Returns a new array of property values. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.pluck(characters, 'name'); + * // => ['barney', 'fred'] + */ + var pluck = map; + + /** + * Reduces a collection to a value which is the accumulated result of running + * each element in the collection through the callback, where each successive + * callback execution consumes the return value of the previous execution. If + * `accumulator` is not provided the first element of the collection will be + * used as the initial `accumulator` value. The callback is bound to `thisArg` + * and invoked with four arguments; (accumulator, value, index|key, collection). + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var sum = _.reduce([1, 2, 3], function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function reduce(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = lodash.createCallback(callback, thisArg, 4); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + if (noaccum) { + accumulator = collection[++index]; + } + while (++index < length) { + accumulator = callback(accumulator, collection[index], index, collection); + } + } else { + baseEach(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection) + }); + } + return accumulator; + } + + /** + * This method is like `_.reduce` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var list = [[0, 1], [2, 3], [4, 5]]; + * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + function reduceRight(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = lodash.createCallback(callback, thisArg, 4); + forEachRight(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The opposite of `_.filter` this method returns the elements of a + * collection that the callback does **not** return truey for. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that failed the callback check. + * @example + * + * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [1, 3, 5] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.reject(characters, 'blocked'); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + * + * // using "_.where" callback shorthand + * _.reject(characters, { 'age': 36 }); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + */ + function reject(collection, callback, thisArg) { + callback = lodash.createCallback(callback, thisArg, 3); + return filter(collection, function(value, index, collection) { + return !callback(value, index, collection); + }); + } + + /** + * Retrieves a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Allows working with functions like `_.map` + * without using their `index` arguments as `n`. + * @returns {Array} Returns the random sample(s) of `collection`. + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ + function sample(collection, n, guard) { + if (collection && typeof collection.length != 'number') { + collection = values(collection); + } else if (support.unindexedChars && isString(collection)) { + collection = collection.split(''); + } + if (n == null || guard) { + return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; + } + var result = shuffle(collection); + result.length = nativeMin(nativeMax(0, n), result.length); + return result; + } + + /** + * Creates an array of shuffled values, using a version of the Fisher-Yates + * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns a new shuffled collection. + * @example + * + * _.shuffle([1, 2, 3, 4, 5, 6]); + * // => [4, 1, 6, 3, 5, 2] + */ + function shuffle(collection) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + var rand = baseRandom(0, ++index); + result[index] = result[rand]; + result[rand] = value; + }); + return result; + } + + /** + * Gets the size of the `collection` by returning `collection.length` for arrays + * and array-like objects or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns `collection.length` or number of own enumerable properties. + * @example + * + * _.size([1, 2]); + * // => 2 + * + * _.size({ 'one': 1, 'two': 2, 'three': 3 }); + * // => 3 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + var length = collection ? collection.length : 0; + return typeof length == 'number' ? length : keys(collection).length; + } + + /** + * Checks if the callback returns a truey value for **any** element of a + * collection. The function returns as soon as it finds a passing value and + * does not iterate over the entire collection. The callback is bound to + * `thisArg` and invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if any element passed the callback check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.some(characters, 'blocked'); + * // => true + * + * // using "_.where" callback shorthand + * _.some(characters, { 'age': 1 }); + * // => false + */ + function some(collection, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if ((result = callback(collection[index], index, collection))) { + break; + } + } + } else { + baseEach(collection, function(value, index, collection) { + return !(result = callback(value, index, collection)); + }); + } + return !!result; + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through the callback. This method + * performs a stable sort, that is, it will preserve the original sort order + * of equal elements. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an array of property names is provided for `callback` the collection + * will be sorted by each property value. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of sorted elements. + * @example + * + * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); + * // => [3, 1, 2] + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 26 }, + * { 'name': 'fred', 'age': 30 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(_.sortBy(characters, 'age'), _.values); + * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] + * + * // sorting by multiple properties + * _.map(_.sortBy(characters, ['name', 'age']), _.values); + * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] + */ + function sortBy(collection, callback, thisArg) { + var index = -1, + isArr = isArray(callback), + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + if (!isArr) { + callback = lodash.createCallback(callback, thisArg, 3); + } + forEach(collection, function(value, key, collection) { + var object = result[++index] = getObject(); + if (isArr) { + object.criteria = map(callback, function(key) { return value[key]; }); + } else { + (object.criteria = getArray())[0] = callback(value, key, collection); + } + object.index = index; + object.value = value; + }); + + length = result.length; + result.sort(compareAscending); + while (length--) { + var object = result[length]; + result[length] = object.value; + if (!isArr) { + releaseArray(object.criteria); + } + releaseObject(object); + } + return result; + } + + /** + * Converts the `collection` to an array. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to convert. + * @returns {Array} Returns the new converted array. + * @example + * + * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); + * // => [2, 3, 4] + */ + function toArray(collection) { + if (collection && typeof collection.length == 'number') { + return (support.unindexedChars && isString(collection)) + ? collection.split('') + : slice(collection); + } + return values(collection); + } + + /** + * Performs a deep comparison of each element in a `collection` to the given + * `properties` object, returning an array of all elements that have equivalent + * property values. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Object} props The object of property values to filter by. + * @returns {Array} Returns a new array of elements that have the given properties. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.where(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] + * + * _.where(characters, { 'pets': ['dino'] }); + * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] + */ + var where = filter; + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are all falsey. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to compact. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result.push(value); + } + } + return result; + } + + /** + * Creates an array excluding all values of the provided arrays using strict + * equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to process. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); + * // => [1, 3, 4] + */ + function difference(array) { + return baseDifference(array, baseFlatten(arguments, true, true, 1)); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element that passes the callback check, instead of the element itself. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.findIndex(characters, function(chr) { + * return chr.age < 20; + * }); + * // => 2 + * + * // using "_.where" callback shorthand + * _.findIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findIndex(characters, 'blocked'); + * // => 1 + */ + function findIndex(array, callback, thisArg) { + var index = -1, + length = array ? array.length : 0; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length) { + if (callback(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of a `collection` from right to left. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': true }, + * { 'name': 'fred', 'age': 40, 'blocked': false }, + * { 'name': 'pebbles', 'age': 1, 'blocked': true } + * ]; + * + * _.findLastIndex(characters, function(chr) { + * return chr.age > 30; + * }); + * // => 1 + * + * // using "_.where" callback shorthand + * _.findLastIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findLastIndex(characters, 'blocked'); + * // => 2 + */ + function findLastIndex(array, callback, thisArg) { + var length = array ? array.length : 0; + callback = lodash.createCallback(callback, thisArg, 3); + while (length--) { + if (callback(array[length], length, array)) { + return length; + } + } + return -1; + } + + /** + * Gets the first element or first `n` elements of an array. If a callback + * is provided elements at the beginning of the array are returned as long + * as the callback returns truey. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias head, take + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the first element(s) of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([1, 2, 3], 2); + * // => [1, 2] + * + * _.first([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [1, 2] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.first(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); + * // => ['barney', 'fred'] + */ + function first(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = -1; + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[0] : undefined; + } + } + return slice(array, 0, nativeMin(nativeMax(0, n), length)); + } + + /** + * Flattens a nested array (the nesting can be to any depth). If `isShallow` + * is truey, the array will only be flattened a single level. If a callback + * is provided each element of the array is passed through the callback before + * flattening. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new flattened array. + * @example + * + * _.flatten([1, [2], [3, [[4]]]]); + * // => [1, 2, 3, 4]; + * + * _.flatten([1, [2], [3, [[4]]]], true); + * // => [1, 2, 3, [[4]]]; + * + * var characters = [ + * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * // using "_.pluck" callback shorthand + * _.flatten(characters, 'pets'); + * // => ['hoppy', 'baby puss', 'dino'] + */ + function flatten(array, isShallow, callback, thisArg) { + // juggle arguments + if (typeof isShallow != 'boolean' && isShallow != null) { + thisArg = callback; + callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; + isShallow = false; + } + if (callback != null) { + array = map(array, callback, thisArg); + } + return baseFlatten(array, isShallow); + } + + /** + * Gets the index at which the first occurrence of `value` is found using + * strict equality for comparisons, i.e. `===`. If the array is already sorted + * providing `true` for `fromIndex` will run a faster binary search. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2); + * // => 1 + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 4 + * + * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + if (typeof fromIndex == 'number') { + var length = array ? array.length : 0; + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); + } else if (fromIndex) { + var index = sortedIndex(array, value); + return array[index] === value ? index : -1; + } + return baseIndexOf(array, value, fromIndex); + } + + /** + * Gets all but the last element or last `n` elements of an array. If a + * callback is provided elements at the end of the array are excluded from + * the result as long as the callback returns truey. The callback is bound + * to `thisArg` and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + * + * _.initial([1, 2, 3], 2); + * // => [1] + * + * _.initial([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [1] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.initial(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); + * // => ['barney', 'fred'] + */ + function initial(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = lodash.createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : callback || n; + } + return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); + } + + /** + * Creates an array of unique values present in all provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of shared values. + * @example + * + * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2] + */ + function intersection() { + var args = [], + argsIndex = -1, + argsLength = arguments.length, + caches = getArray(), + indexOf = getIndexOf(), + trustIndexOf = indexOf === baseIndexOf, + seen = getArray(); + + while (++argsIndex < argsLength) { + var value = arguments[argsIndex]; + if (isArray(value) || isArguments(value)) { + args.push(value); + caches.push(trustIndexOf && value.length >= largeArraySize && + createCache(argsIndex ? args[argsIndex] : seen)); + } + } + var array = args[0], + index = -1, + length = array ? array.length : 0, + result = []; + + outer: + while (++index < length) { + var cache = caches[0]; + value = array[index]; + + if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) { + argsIndex = argsLength; + (cache || seen).push(value); + while (--argsIndex) { + cache = caches[argsIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { + continue outer; + } + } + result.push(value); + } + } + while (argsLength--) { + cache = caches[argsLength]; + if (cache) { + releaseObject(cache); + } + } + releaseArray(caches); + releaseArray(seen); + return result; + } + + /** + * Gets the last element or last `n` elements of an array. If a callback is + * provided elements at the end of the array are returned as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the last element(s) of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + * + * _.last([1, 2, 3], 2); + * // => [2, 3] + * + * _.last([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [2, 3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.last(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.last(characters, { 'employer': 'na' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function last(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = lodash.createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[length - 1] : undefined; + } + } + return slice(array, nativeMax(0, length - n)); + } + + /** + * Gets the index at which the last occurrence of `value` is found using strict + * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used + * as the offset from the end of the collection. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); + * // => 4 + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 1 + */ + function lastIndexOf(array, value, fromIndex) { + var index = array ? array.length : 0; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Removes all provided values from the given array using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to modify. + * @param {...*} [value] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ + function pull(array) { + var args = arguments, + argsIndex = 0, + argsLength = args.length, + length = array ? array.length : 0; + + while (++argsIndex < argsLength) { + var index = -1, + value = args[argsIndex]; + while (++index < length) { + if (array[index] === value) { + splice.call(array, index--, 1); + length--; + } + } + } + return array; + } + + /** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to but not including `end`. If `start` is less than `stop` a + * zero-length range is created unless a negative `step` is specified. + * + * @static + * @memberOf _ + * @category Arrays + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns a new range array. + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ + function range(start, end, step) { + start = +start || 0; + step = typeof step == 'number' ? step : (+step || 1); + + if (end == null) { + end = start; + start = 0; + } + // use `Array(length)` so engines like Chakra and V8 avoid slower modes + // http://youtu.be/XAqIpGU8ZZk#t=17m25s + var index = -1, + length = nativeMax(0, ceil((end - start) / (step || 1))), + result = Array(length); + + while (++index < length) { + result[index] = start; + start += step; + } + return result; + } + + /** + * Removes all elements from an array that the callback returns truey for + * and returns an array of removed elements. The callback is bound to `thisArg` + * and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to modify. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4, 5, 6]; + * var evens = _.remove(array, function(num) { return num % 2 == 0; }); + * + * console.log(array); + * // => [1, 3, 5] + * + * console.log(evens); + * // => [2, 4, 6] + */ + function remove(array, callback, thisArg) { + var index = -1, + length = array ? array.length : 0, + result = []; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (callback(value, index, array)) { + result.push(value); + splice.call(array, index--, 1); + length--; + } + } + return result; + } + + /** + * The opposite of `_.initial` this method gets all but the first element or + * first `n` elements of an array. If a callback function is provided elements + * at the beginning of the array are excluded from the result as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias drop, tail + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + * + * _.rest([1, 2, 3], 2); + * // => [3] + * + * _.rest([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.rest(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.rest(characters, { 'employer': 'slate' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function rest(array, callback, thisArg) { + if (typeof callback != 'number' && callback != null) { + var n = 0, + index = -1, + length = array ? array.length : 0; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); + } + return slice(array, n); + } + + /** + * Uses a binary search to determine the smallest index at which a value + * should be inserted into a given sorted array in order to maintain the sort + * order of the array. If a callback is provided it will be executed for + * `value` and each element of `array` to compute their sort ranking. The + * callback is bound to `thisArg` and invoked with one argument; (value). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([20, 30, 50], 40); + * // => 2 + * + * // using "_.pluck" callback shorthand + * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 2 + * + * var dict = { + * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } + * }; + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return dict.wordToNumber[word]; + * }); + * // => 2 + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return this.wordToNumber[word]; + * }, dict); + * // => 2 + */ + function sortedIndex(array, value, callback, thisArg) { + var low = 0, + high = array ? array.length : low; + + // explicitly reference `identity` for better inlining in Firefox + callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; + value = callback(value); + + while (low < high) { + var mid = (low + high) >>> 1; + (callback(array[mid]) < value) + ? low = mid + 1 + : high = mid; + } + return low; + } + + /** + * Creates an array of unique values, in order, of the provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of combined values. + * @example + * + * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2, 3, 5, 4] + */ + function union() { + return baseUniq(baseFlatten(arguments, true, true)); + } + + /** + * Creates a duplicate-value-free version of an array using strict equality + * for comparisons, i.e. `===`. If the array is sorted, providing + * `true` for `isSorted` will use a faster algorithm. If a callback is provided + * each element of `array` is passed through the callback before uniqueness + * is computed. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Arrays + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a duplicate-value-free array. + * @example + * + * _.uniq([1, 2, 1, 3, 1]); + * // => [1, 2, 3] + * + * _.uniq([1, 1, 2, 2, 3], true); + * // => [1, 2, 3] + * + * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); + * // => ['A', 'b', 'C'] + * + * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); + * // => [1, 2.5, 3] + * + * // using "_.pluck" callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniq(array, isSorted, callback, thisArg) { + // juggle arguments + if (typeof isSorted != 'boolean' && isSorted != null) { + thisArg = callback; + callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; + isSorted = false; + } + if (callback != null) { + callback = lodash.createCallback(callback, thisArg, 3); + } + return baseUniq(array, isSorted, callback); + } + + /** + * Creates an array excluding all provided values using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to filter. + * @param {...*} [value] The values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); + * // => [2, 3, 4] + */ + function without(array) { + return baseDifference(array, slice(arguments, 1)); + } + + /** + * Creates an array that is the symmetric difference of the provided arrays. + * See http://en.wikipedia.org/wiki/Symmetric_difference. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of values. + * @example + * + * _.xor([1, 2, 3], [5, 2, 1, 4]); + * // => [3, 5, 4] + * + * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); + * // => [1, 4, 5] + */ + function xor() { + var index = -1, + length = arguments.length; + + while (++index < length) { + var array = arguments[index]; + if (isArray(array) || isArguments(array)) { + var result = result + ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result))) + : array; + } + } + return result || []; + } + + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second + * elements of the given arrays, and so on. + * + * @static + * @memberOf _ + * @alias unzip + * @category Arrays + * @param {...Array} [array] Arrays to process. + * @returns {Array} Returns a new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + function zip() { + var array = arguments.length > 1 ? arguments : arguments[0], + index = -1, + length = array ? max(pluck(array, 'length')) : 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = pluck(array, index); + } + return result; + } + + /** + * Creates an object composed from arrays of `keys` and `values`. Provide + * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` + * or two arrays, one of `keys` and one of corresponding `values`. + * + * @static + * @memberOf _ + * @alias object + * @category Arrays + * @param {Array} keys The array of keys. + * @param {Array} [values=[]] The array of values. + * @returns {Object} Returns an object composed of the given keys and + * corresponding values. + * @example + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ + function zipObject(keys, values) { + var index = -1, + length = keys ? keys.length : 0, + result = {}; + + if (!values && length && !isArray(keys[0])) { + values = []; + } + while (++index < length) { + var key = keys[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that executes `func`, with the `this` binding and + * arguments of the created function, only after being called `n` times. + * + * @static + * @memberOf _ + * @category Functions + * @param {number} n The number of times the function must be called before + * `func` is executed. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('Done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'Done saving!', after all saves have completed + */ + function after(n, func) { + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that, when called, invokes `func` with the `this` + * binding of `thisArg` and prepends any additional `bind` arguments to those + * provided to the bound function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var func = function(greeting) { + * return greeting + ' ' + this.name; + * }; + * + * func = _.bind(func, { 'name': 'fred' }, 'hi'); + * func(); + * // => 'hi fred' + */ + function bind(func, thisArg) { + return arguments.length > 2 + ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) + : createWrapper(func, 1, null, null, thisArg); + } + + /** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all the function properties + * of `object` will be bound. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...string} [methodName] The object method names to + * bind, specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { console.log('clicked ' + this.label); } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs', when the button is clicked + */ + function bindAll(object) { + var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), + index = -1, + length = funcs.length; + + while (++index < length) { + var key = funcs[index]; + object[key] = createWrapper(object[key], 1, null, null, object); + } + return object; + } + + /** + * Creates a function that, when called, invokes the method at `object[key]` + * and prepends any additional `bindKey` arguments to those provided to the bound + * function. This method differs from `_.bind` by allowing bound functions to + * reference methods that will be redefined or don't yet exist. + * See http://michaux.ca/articles/lazy-function-definition-pattern. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'name': 'fred', + * 'greet': function(greeting) { + * return greeting + ' ' + this.name; + * } + * }; + * + * var func = _.bindKey(object, 'greet', 'hi'); + * func(); + * // => 'hi fred' + * + * object.greet = function(greeting) { + * return greeting + 'ya ' + this.name + '!'; + * }; + * + * func(); + * // => 'hiya fred!' + */ + function bindKey(object, key) { + return arguments.length > 2 + ? createWrapper(key, 19, slice(arguments, 2), null, object) + : createWrapper(key, 3, null, null, object); + } + + /** + * Creates a function that is the composition of the provided functions, + * where each function consumes the return value of the function that follows. + * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. + * Each function is executed with the `this` binding of the composed function. + * + * @static + * @memberOf _ + * @category Functions + * @param {...Function} [func] Functions to compose. + * @returns {Function} Returns the new composed function. + * @example + * + * var realNameMap = { + * 'pebbles': 'penelope' + * }; + * + * var format = function(name) { + * name = realNameMap[name.toLowerCase()] || name; + * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); + * }; + * + * var greet = function(formatted) { + * return 'Hiya ' + formatted + '!'; + * }; + * + * var welcome = _.compose(greet, format); + * welcome('pebbles'); + * // => 'Hiya Penelope!' + */ + function compose() { + var funcs = arguments, + length = funcs.length; + + while (length--) { + if (!isFunction(funcs[length])) { + throw new TypeError; + } + } + return function() { + var args = arguments, + length = funcs.length; + + while (length--) { + args = [funcs[length].apply(this, args)]; + } + return args[0]; + }; + } + + /** + * Creates a function which accepts one or more arguments of `func` that when + * invoked either executes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` can be specified + * if `func.length` is not sufficient. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @returns {Function} Returns the new curried function. + * @example + * + * var curried = _.curry(function(a, b, c) { + * console.log(a + b + c); + * }); + * + * curried(1)(2)(3); + * // => 6 + * + * curried(1, 2)(3); + * // => 6 + * + * curried(1, 2, 3); + * // => 6 + */ + function curry(func, arity) { + arity = typeof arity == 'number' ? arity : (+arity || func.length); + return createWrapper(func, 4, null, null, null, arity); + } + + /** + * Creates a function that will delay the execution of `func` until after + * `wait` milliseconds have elapsed since the last time it was invoked. + * Provide an options object to indicate that `func` should be invoked on + * the leading and/or trailing edge of the `wait` timeout. Subsequent calls + * to the debounced function will return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to debounce. + * @param {number} wait The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * var lazyLayout = _.debounce(calculateLayout, 150); + * jQuery(window).on('resize', lazyLayout); + * + * // execute `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * }); + * + * // ensure `batchLog` is executed once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * source.addEventListener('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * }, false); + */ + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + wait = nativeMax(0, wait) || 0; + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = options.leading; + maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0); + trailing = 'trailing' in options ? options.trailing : trailing; + } + var delayed = function() { + var remaining = wait - (now() - stamp); + if (remaining <= 0) { + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + var isCalled = trailingCall; + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + } else { + timeoutId = setTimeout(delayed, remaining); + } + }; + + var maxDelayed = function() { + if (timeoutId) { + clearTimeout(timeoutId); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (trailing || (maxWait !== wait)) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + }; + + return function() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + return result; + }; + } + + /** + * Defers executing the `func` function until the current call stack has cleared. + * Additional arguments will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to defer. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { console.log(text); }, 'deferred'); + * // logs 'deferred' after one or more milliseconds + */ + function defer(func) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 1); + return setTimeout(function() { func.apply(undefined, args); }, 1); + } + + /** + * Executes the `func` function after `wait` milliseconds. Additional arguments + * will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay execution. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { console.log(text); }, 1000, 'later'); + * // => logs 'later' after one second + */ + function delay(func, wait) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 2); + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it will be used to determine the cache key for storing the result + * based on the arguments provided to the memoized function. By default, the + * first argument provided to the memoized function is used as the cache key. + * The `func` is executed with the `this` binding of the memoized function. + * The result cache is exposed as the `cache` property on the memoized function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] A function used to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var fibonacci = _.memoize(function(n) { + * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); + * }); + * + * fibonacci(9) + * // => 34 + * + * var data = { + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * }; + * + * // modifying the result cache + * var get = _.memoize(function(name) { return data[name]; }, _.identity); + * get('pebbles'); + * // => { 'name': 'pebbles', 'age': 1 } + * + * get.cache.pebbles.name = 'penelope'; + * get('pebbles'); + * // => { 'name': 'penelope', 'age': 1 } + */ + function memoize(func, resolver) { + if (!isFunction(func)) { + throw new TypeError; + } + var memoized = function() { + var cache = memoized.cache, + key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0]; + + return hasOwnProperty.call(cache, key) + ? cache[key] + : (cache[key] = func.apply(this, arguments)); + } + memoized.cache = {}; + return memoized; + } + + /** + * Creates a function that is restricted to execute `func` once. Repeat calls to + * the function will return the value of the first call. The `func` is executed + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` executes `createApplication` once + */ + function once(func) { + var ran, + result; + + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (ran) { + return result; + } + ran = true; + result = func.apply(this, arguments); + + // clear the `func` variable so the function may be garbage collected + func = null; + return result; + }; + } + + /** + * Creates a function that, when called, invokes `func` with any additional + * `partial` arguments prepended to those provided to the new function. This + * method is similar to `_.bind` except it does **not** alter the `this` binding. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { return greeting + ' ' + name; }; + * var hi = _.partial(greet, 'hi'); + * hi('fred'); + * // => 'hi fred' + */ + function partial(func) { + return createWrapper(func, 16, slice(arguments, 1)); + } + + /** + * This method is like `_.partial` except that `partial` arguments are + * appended to those provided to the new function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var defaultsDeep = _.partialRight(_.merge, _.defaults); + * + * var options = { + * 'variable': 'data', + * 'imports': { 'jq': $ } + * }; + * + * defaultsDeep(options, _.templateSettings); + * + * options.variable + * // => 'data' + * + * options.imports + * // => { '_': _, 'jq': $ } + */ + function partialRight(func) { + return createWrapper(func, 32, null, slice(arguments, 1)); + } + + /** + * Creates a function that, when executed, will only call the `func` function + * at most once per every `wait` milliseconds. Provide an options object to + * indicate that `func` should be invoked on the leading and/or trailing edge + * of the `wait` timeout. Subsequent calls to the throttled function will + * return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to throttle. + * @param {number} wait The number of milliseconds to throttle executions to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // avoid excessively updating the position while scrolling + * var throttled = _.throttle(updatePosition, 100); + * jQuery(window).on('scroll', throttled); + * + * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? options.leading : leading; + trailing = 'trailing' in options ? options.trailing : trailing; + } + debounceOptions.leading = leading; + debounceOptions.maxWait = wait; + debounceOptions.trailing = trailing; + + return debounce(func, wait, debounceOptions); + } + + /** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Additional arguments provided to the function are appended + * to those provided to the wrapper function. The wrapper is executed with + * the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

' + func(text) + '

'; + * }); + * + * p('Fred, Wilma, & Pebbles'); + * // => '

Fred, Wilma, & Pebbles

' + */ + function wrap(value, wrapper) { + return createWrapper(wrapper, 16, [value]); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new function. + * @example + * + * var object = { 'name': 'fred' }; + * var getter = _.constant(object); + * getter() === object; + * // => true + */ + function constant(value) { + return function() { + return value; + }; + } + + /** + * Produces a callback bound to an optional `thisArg`. If `func` is a property + * name the created callback will return the property value for a given element. + * If `func` is an object the created callback will return `true` for elements + * that contain the equivalent object properties, otherwise it will return `false`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // wrap to create custom callback shorthands + * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { + * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); + * return !match ? func(callback, thisArg) : function(object) { + * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; + * }; + * }); + * + * _.filter(characters, 'age__gt38'); + * // => [{ 'name': 'fred', 'age': 40 }] + */ + function createCallback(func, thisArg, argCount) { + var type = typeof func; + if (func == null || type == 'function') { + return baseCreateCallback(func, thisArg, argCount); + } + // handle "_.pluck" style callback shorthands + if (type != 'object') { + return property(func); + } + var props = keys(func), + key = props[0], + a = func[key]; + + // handle "_.where" style callback shorthands + if (props.length == 1 && a === a && !isObject(a)) { + // fast path the common case of providing an object with a single + // property containing a primitive value + return function(object) { + var b = object[key]; + return a === b && (a !== 0 || (1 / a == 1 / b)); + }; + } + return function(object) { + var length = props.length, + result = false; + + while (length--) { + if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { + break; + } + } + return result; + }; + } + + /** + * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their + * corresponding HTML entities. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} string The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('Fred, Wilma, & Pebbles'); + * // => 'Fred, Wilma, & Pebbles' + */ + function escape(string) { + return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); + } + + /** + * This method returns the first argument provided to it. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'name': 'fred' }; + * _.identity(object) === object; + * // => true + */ + function identity(value) { + return value; + } + + /** + * Adds function properties of a source object to the destination object. + * If `object` is a function methods will be added to its prototype as well. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Function|Object} [object=lodash] object The destination object. + * @param {Object} source The object of functions to add. + * @param {Object} [options] The options object. + * @param {boolean} [options.chain=true] Specify whether the functions added are chainable. + * @example + * + * function capitalize(string) { + * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); + * } + * + * _.mixin({ 'capitalize': capitalize }); + * _.capitalize('fred'); + * // => 'Fred' + * + * _('fred').capitalize().value(); + * // => 'Fred' + * + * _.mixin({ 'capitalize': capitalize }, { 'chain': false }); + * _('fred').capitalize(); + * // => 'Fred' + */ + function mixin(object, source, options) { + var chain = true, + methodNames = source && functions(source); + + if (!source || (!options && !methodNames.length)) { + if (options == null) { + options = source; + } + ctor = lodashWrapper; + source = object; + object = lodash; + methodNames = functions(source); + } + if (options === false) { + chain = false; + } else if (isObject(options) && 'chain' in options) { + chain = options.chain; + } + var ctor = object, + isFunc = isFunction(ctor); + + forEach(methodNames, function(methodName) { + var func = object[methodName] = source[methodName]; + if (isFunc) { + ctor.prototype[methodName] = function() { + var chainAll = this.__chain__, + value = this.__wrapped__, + args = [value]; + + push.apply(args, arguments); + var result = func.apply(object, args); + if (chain || chainAll) { + if (value === result && isObject(result)) { + return this; + } + result = new ctor(result); + result.__chain__ = chainAll; + } + return result; + }; + } + }); + } + + /** + * Reverts the '_' variable to its previous value and returns a reference to + * the `lodash` function. + * + * @static + * @memberOf _ + * @category Utilities + * @returns {Function} Returns the `lodash` function. + * @example + * + * var lodash = _.noConflict(); + */ + function noConflict() { + context._ = oldDash; + return this; + } + + /** + * A no-operation function. + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var object = { 'name': 'fred' }; + * _.noop(object) === undefined; + * // => true + */ + function noop() { + // no operation performed + } + + /** + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var stamp = _.now(); + * _.defer(function() { console.log(_.now() - stamp); }); + * // => logs the number of milliseconds it took for the deferred function to be called + */ + var now = isNative(now = Date.now) && now || function() { + return new Date().getTime(); + }; + + /** + * Converts the given value into an integer of the specified radix. + * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the + * `value` is a hexadecimal, in which case a `radix` of `16` is used. + * + * Note: This method avoids differences in native ES3 and ES5 `parseInt` + * implementations. See http://es5.github.io/#E. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} value The value to parse. + * @param {number} [radix] The radix used to interpret the value to parse. + * @returns {number} Returns the new integer value. + * @example + * + * _.parseInt('08'); + * // => 8 + */ + var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) { + // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt` + return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0); + }; + + /** + * Creates a "_.pluck" style function, which returns the `key` value of a + * given object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} key The name of the property to retrieve. + * @returns {Function} Returns the new function. + * @example + * + * var characters = [ + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 36 } + * ]; + * + * var getName = _.property('name'); + * + * _.map(characters, getName); + * // => ['barney', 'fred'] + * + * _.sortBy(characters, getName); + * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] + */ + function property(key) { + return function(object) { + return object[key]; + }; + } + + /** + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is provided a number between `0` and the given number will be + * returned. If `floating` is truey or either `min` or `max` are floats a + * floating-point number will be returned instead of an integer. + * + * @static + * @memberOf _ + * @category Utilities + * @param {number} [min=0] The minimum possible value. + * @param {number} [max=1] The maximum possible value. + * @param {boolean} [floating=false] Specify returning a floating-point number. + * @returns {number} Returns a random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(min, max, floating) { + var noMin = min == null, + noMax = max == null; + + if (floating == null) { + if (typeof min == 'boolean' && noMax) { + floating = min; + min = 1; + } + else if (!noMax && typeof max == 'boolean') { + floating = max; + noMax = true; + } + } + if (noMin && noMax) { + max = 1; + } + min = +min || 0; + if (noMax) { + max = min; + min = 0; + } else { + max = +max || 0; + } + if (floating || min % 1 || max % 1) { + var rand = nativeRandom(); + return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max); + } + return baseRandom(min, max); + } + + /** + * Resolves the value of property `key` on `object`. If `key` is a function + * it will be invoked with the `this` binding of `object` and its result returned, + * else the property value is returned. If `object` is falsey then `undefined` + * is returned. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to resolve. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { + * 'cheese': 'crumpets', + * 'stuff': function() { + * return 'nonsense'; + * } + * }; + * + * _.result(object, 'cheese'); + * // => 'crumpets' + * + * _.result(object, 'stuff'); + * // => 'nonsense' + */ + function result(object, key) { + if (object) { + var value = object[key]; + return isFunction(value) ? object[key]() : value; + } + } + + /** + * A micro-templating method that handles arbitrary delimiters, preserves + * whitespace, and correctly escapes quotes within interpolated code. + * + * Note: In the development build, `_.template` utilizes sourceURLs for easier + * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl + * + * For more information on precompiling templates see: + * https://lodash.com/custom-builds + * + * For more information on Chrome extension sandboxes see: + * http://developer.chrome.com/stable/extensions/sandboxingEval.html + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} text The template text. + * @param {Object} data The data object used to populate the text. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as local variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [sourceURL] The sourceURL of the template's compiled source. + * @param {string} [variable] The data object variable name. + * @returns {Function|string} Returns a compiled function when no `data` object + * is given, else it returns the interpolated text. + * @example + * + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= name %>'); + * compiled({ 'name': 'fred' }); + * // => 'hello fred' + * + * // using the "escape" delimiter to escape HTML in data property values + * _.template('<%- value %>', { 'value': '').stripTags() +=> 'a linkalert("hello world!")' +``` + +**toSentence** _.toSentence(array, [delimiter, lastDelimiter]) + +Join an array into a human readable sentence. + +```javascript +_.toSentence(['jQuery', 'Mootools', 'Prototype']) +=> 'jQuery, Mootools and Prototype'; + +_.toSentence(['jQuery', 'Mootools', 'Prototype'], ', ', ' unt ') +=> 'jQuery, Mootools unt Prototype'; +``` + +**toSentenceSerial** _.toSentenceSerial(array, [delimiter, lastDelimiter]) + +The same as `toSentence`, but adjusts delimeters to use [Serial comma](http://en.wikipedia.org/wiki/Serial_comma). + +```javascript +_.toSentenceSerial(['jQuery', 'Mootools']) +=> 'jQuery and Mootools'; + +_.toSentenceSerial(['jQuery', 'Mootools', 'Prototype']) +=> 'jQuery, Mootools, and Prototype' + +_.toSentenceSerial(['jQuery', 'Mootools', 'Prototype'], ', ', ' unt '); +=> 'jQuery, Mootools, unt Prototype'; +``` + +**repeat** _.repeat(string, count, [separator]) + +Repeats a string count times. + +```javascript +_.repeat("foo", 3) +=> 'foofoofoo'; + +_.repeat("foo", 3, "bar") +=> 'foobarfoobarfoo' +``` + +**surround** _.surround(string, wrap) + +Surround a string with another string. + +```javascript +_.surround("foo", "ab") +=> 'abfooab'; +``` + +**quote** _.quote(string, quoteChar) or _.q(string, quoteChar) + +Quotes a string. `quoteChar` defaults to `"`. + +```javascript +_.quote('foo', quoteChar) +=> '"foo"'; +``` +**unquote** _.unquote(string, quoteChar) + +Unquotes a string. `quoteChar` defaults to `"`. + +```javascript +_.unquote('"foo"') +=> 'foo'; +_.unquote("'foo'", "'") +=> 'foo'; +``` + + +**slugify** _.slugify(string) + +Transform text into a URL slug. Replaces whitespaces, accentuated, and special characters with a dash. + +```javascript +_.slugify("Un éléphant à l'orée du bois") +=> 'un-elephant-a-loree-du-bois'; +``` + +***Caution: this function is charset dependent*** + +**naturalCmp** array.sort(_.naturalCmp) + +Naturally sort strings like humans would do. + +```javascript +['foo20', 'foo5'].sort(_.naturalCmp) +=> [ 'foo5', 'foo20' ] +``` + +**toBoolean** _.toBoolean(string) or _.toBool(string) + +Turn strings that can be commonly considered as booleas to real booleans. Such as "true", "false", "1" and "0". This function is case insensitive. + +```javascript +_.toBoolean("true") +=> true +_.toBoolean("FALSE") +=> false +_.toBoolean("random") +=> undefined +``` + +It can be customized by giving arrays of truth and falsy value matcher as parameters. Matchers can be also RegExp objects. + +```javascript +_.toBoolean("truthy", ["truthy"], ["falsy"]) +=> true +_.toBoolean("true only at start", [/^true/]) +=> true +``` + +## Roadmap ## + +Any suggestions or bug reports are welcome. Just email me or more preferably open an issue. + +#### Problems + +We lose two things for `include` and `reverse` methods from `_.string`: + +* Calls like `_('foobar').include('bar')` aren't available; +* Chaining isn't available too. + +But if you need this functionality you can create aliases for conflict functions which will be convenient for you: + +```javascript +_.mixin({ + includeString: _.str.include, + reverseString: _.str.reverse +}) + +// Now wrapper calls and chaining are available. +_('foobar').chain().reverseString().includeString('rab').value() +``` + +#### Standalone Usage + +If you are using Underscore.string without Underscore. You also have `_.string` namespace for it and `_.str` alias +But of course you can just reassign `_` variable with `_.string` + +```javascript +_ = _.string +``` + +## Changelog ## + +### 2.3.3 ### + +* Add `toBoolean` +* Add `unquote` +* Add quote char option to `quote` +* Support dash-separated words in `titleize` + +### 2.3.2 ### + +* Add `naturalCmp` +* Bug fix to `camelize` +* Add ă, ș, ț and ś to `slugify` +* Doc updates +* Add support for [component](http://component.io/) +* [Full changelog](https://github.com/epeli/underscore.string/compare/v2.3.1...v2.3.2) + +### 2.3.1 ### + +* Bug fixes to `escapeHTML`, `classify`, `substr` +* Faster `count` +* Documentation fixes +* [Full changelog](https://github.com/epeli/underscore.string/compare/v2.3.0...v2.3.1) + +### 2.3.0 ### + +* Added `numberformat` method +* Added `levenshtein` method (Levenshtein distance calculation) +* Added `swapCase` method +* Changed default behavior of `words` method +* Added `toSentenceSerial` method +* Added `surround` and `quote` methods + +### 2.2.1 ### + +* Same as 2.2.0 (2.2.0rc on npm) to fix some npm drama + +### 2.2.0 ### + +* Capitalize method behavior changed +* Various perfomance tweaks + +### 2.1.1### + +* Fixed words method bug +* Added classify method + +### 2.1.0 ### + +* AMD support +* Added toSentence method +* Added slugify method +* Lots of speed optimizations + +### 2.0.0 ### + +* Added prune, humanize functions +* Added _.string (_.str) namespace for Underscore.string library +* Removed includes function + +For upgrading to this version you need to mix in Underscore.string library to Underscore object: + +```javascript +_.mixin(_.string.exports()); +``` + +and all non-conflict Underscore.string functions will be available through Underscore object. +Also function `includes` has been removed, you should replace this function by `_.str.include` +or create alias `_.includes = _.str.include` and all your code will work fine. + +### 1.1.6 ### + +* Fixed reverse and truncate +* Added isBlank, stripTags, inlude(alias for includes) +* Added uglifier compression + +### 1.1.5 ### + +* Added strRight, strRightBack, strLeft, strLeftBack + +### 1.1.4 ### + +* Added pad, lpad, rpad, lrpad methods and aliases center, ljust, rjust +* Integration with Underscore 1.1.6 + +### 1.1.3 ### + +* Added methods: underscored, camelize, dasherize +* Support newer version of npm + +### 1.1.2 ### + +* Created functions: lines, chars, words functions + +### 1.0.2 ### + +* Created integration test suite with underscore.js 1.1.4 (now it's absolutely compatible) +* Removed 'reverse' function, because this function override underscore.js 'reverse' + +## Contribute ## + +* Fork & pull request. Don't forget about tests. +* If you planning add some feature please create issue before. + +Otherwise changes will be rejected. + +## Contributors list ## +[Can be found here](https://github.com/epeli/underscore.string/graphs/contributors). + + +## Licence ## + +The MIT License + +Copyright (c) 2011 Esa-Matti Suuronen esa-matti@suuronen.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/Rakefile b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/Rakefile new file mode 100644 index 0000000..2cd9eed --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/Rakefile @@ -0,0 +1,23 @@ +# encoding: utf-8 +task default: :test + +desc 'Use UglifyJS to compress Underscore.string' +task :build do + require 'uglifier' + source = File.read('lib/underscore.string.js', :encoding => 'utf-8') + compressed = Uglifier.compile(source, copyright: false) + File.open('dist/underscore.string.min.js', 'w'){ |f| f.write compressed } + compression_rate = compressed.length.to_f/source.length + puts "compressed dist/underscore.string.min.js: #{compressed.length}/#{source.length} #{(compression_rate * 100).round}%" +end + +desc 'Run tests' +task :test do + puts "Running underscore.string test suite." + result1 = system %{phantomjs ./test/run-qunit.js "test/test.html"} + + puts "Running Underscore test suite." + result2 = system %{phantomjs ./test/run-qunit.js "test/test_underscore/index.html"} + + exit(result1 && result2 ? 0 : 1) +end diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/component.json b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/component.json new file mode 100644 index 0000000..ae91b65 --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/component.json @@ -0,0 +1,11 @@ +{ + "name": "underscore.string", + "repo": "epeli/underscore.string", + "description": "String manipulation extensions for Underscore.js javascript library", + "version": "2.3.3", + "keywords": ["underscore", "string"], + "dependencies": {}, + "development": {}, + "main": "lib/underscore.string.js", + "scripts": ["lib/underscore.string.js"] +} diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/dist/underscore.string.min.js b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/dist/underscore.string.min.js new file mode 100644 index 0000000..4f6b2b9 --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/dist/underscore.string.min.js @@ -0,0 +1 @@ +!function(e,n){"use strict";function r(e,n){var r,t,u=e.toLowerCase();for(n=[].concat(n),r=0;n.length>r;r+=1)if(t=n[r]){if(t.test&&t.test(e))return!0;if(t.toLowerCase()===u)return!0}}var t=n.prototype.trim,u=n.prototype.trimRight,i=n.prototype.trimLeft,l=function(e){return 1*e||0},o=function(e,n){if(1>n)return"";for(var r="";n>0;)1&n&&(r+=e),n>>=1,e+=e;return r},a=[].slice,c=function(e){return null==e?"\\s":e.source?e.source:"["+g.escapeRegExp(e)+"]"},s={lt:"<",gt:">",quot:'"',amp:"&",apos:"'"},f={};for(var p in s)f[s[p]]=p;f["'"]="#39";var h=function(){function e(e){return Object.prototype.toString.call(e).slice(8,-1).toLowerCase()}var r=o,t=function(){return t.cache.hasOwnProperty(arguments[0])||(t.cache[arguments[0]]=t.parse(arguments[0])),t.format.call(null,t.cache[arguments[0]],arguments)};return t.format=function(t,u){var i,l,o,a,c,s,f,p=1,g=t.length,d="",m=[];for(l=0;g>l;l++)if(d=e(t[l]),"string"===d)m.push(t[l]);else if("array"===d){if(a=t[l],a[2])for(i=u[p],o=0;a[2].length>o;o++){if(!i.hasOwnProperty(a[2][o]))throw new Error(h('[_.sprintf] property "%s" does not exist',a[2][o]));i=i[a[2][o]]}else i=a[1]?u[a[1]]:u[p++];if(/[^s]/.test(a[8])&&"number"!=e(i))throw new Error(h("[_.sprintf] expecting number but found %s",e(i)));switch(a[8]){case"b":i=i.toString(2);break;case"c":i=n.fromCharCode(i);break;case"d":i=parseInt(i,10);break;case"e":i=a[7]?i.toExponential(a[7]):i.toExponential();break;case"f":i=a[7]?parseFloat(i).toFixed(a[7]):parseFloat(i);break;case"o":i=i.toString(8);break;case"s":i=(i=n(i))&&a[7]?i.substring(0,a[7]):i;break;case"u":i=Math.abs(i);break;case"x":i=i.toString(16);break;case"X":i=i.toString(16).toUpperCase()}i=/[def]/.test(a[8])&&a[3]&&i>=0?"+"+i:i,s=a[4]?"0"==a[4]?"0":a[4].charAt(1):" ",f=a[6]-n(i).length,c=a[6]?r(s,f):"",m.push(a[5]?i+c:c+i)}return m.join("")},t.cache={},t.parse=function(e){for(var n=e,r=[],t=[],u=0;n;){if(null!==(r=/^[^\x25]+/.exec(n)))t.push(r[0]);else if(null!==(r=/^\x25{2}/.exec(n)))t.push("%");else{if(null===(r=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(n)))throw new Error("[_.sprintf] huh?");if(r[2]){u|=1;var i=[],l=r[2],o=[];if(null===(o=/^([a-z_][a-z_\d]*)/i.exec(l)))throw new Error("[_.sprintf] huh?");for(i.push(o[1]);""!==(l=l.substring(o[0].length));)if(null!==(o=/^\.([a-z_][a-z_\d]*)/i.exec(l)))i.push(o[1]);else{if(null===(o=/^\[(\d+)\]/.exec(l)))throw new Error("[_.sprintf] huh?");i.push(o[1])}r[2]=i}else u|=2;if(3===u)throw new Error("[_.sprintf] mixing positional and named placeholders is not (yet) supported");t.push(r)}n=n.substring(r[0].length)}return t},t}(),g={VERSION:"2.3.0",isBlank:function(e){return null==e&&(e=""),/^\s*$/.test(e)},stripTags:function(e){return null==e?"":n(e).replace(/<\/?[^>]+>/g,"")},capitalize:function(e){return e=null==e?"":n(e),e.charAt(0).toUpperCase()+e.slice(1)},chop:function(e,r){return null==e?[]:(e=n(e),r=~~r,r>0?e.match(new RegExp(".{1,"+r+"}","g")):[e])},clean:function(e){return g.strip(e).replace(/\s+/g," ")},count:function(e,r){if(null==e||null==r)return 0;e=n(e),r=n(r);for(var t=0,u=0,i=r.length;;){if(u=e.indexOf(r,u),-1===u)break;t++,u+=i}return t},chars:function(e){return null==e?[]:n(e).split("")},swapCase:function(e){return null==e?"":n(e).replace(/\S/g,function(e){return e===e.toUpperCase()?e.toLowerCase():e.toUpperCase()})},escapeHTML:function(e){return null==e?"":n(e).replace(/[&<>"']/g,function(e){return"&"+f[e]+";"})},unescapeHTML:function(e){return null==e?"":n(e).replace(/\&([^;]+);/g,function(e,r){var t;return r in s?s[r]:(t=r.match(/^#x([\da-fA-F]+)$/))?n.fromCharCode(parseInt(t[1],16)):(t=r.match(/^#(\d+)$/))?n.fromCharCode(~~t[1]):e})},escapeRegExp:function(e){return null==e?"":n(e).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")},splice:function(e,n,r,t){var u=g.chars(e);return u.splice(~~n,~~r,t),u.join("")},insert:function(e,n,r){return g.splice(e,n,0,r)},include:function(e,r){return""===r?!0:null==e?!1:-1!==n(e).indexOf(r)},join:function(){var e=a.call(arguments),n=e.shift();return null==n&&(n=""),e.join(n)},lines:function(e){return null==e?[]:n(e).split("\n")},reverse:function(e){return g.chars(e).reverse().join("")},startsWith:function(e,r){return""===r?!0:null==e||null==r?!1:(e=n(e),r=n(r),e.length>=r.length&&e.slice(0,r.length)===r)},endsWith:function(e,r){return""===r?!0:null==e||null==r?!1:(e=n(e),r=n(r),e.length>=r.length&&e.slice(e.length-r.length)===r)},succ:function(e){return null==e?"":(e=n(e),e.slice(0,-1)+n.fromCharCode(e.charCodeAt(e.length-1)+1))},titleize:function(e){return null==e?"":(e=n(e).toLowerCase(),e.replace(/(?:^|\s|-)\S/g,function(e){return e.toUpperCase()}))},camelize:function(e){return g.trim(e).replace(/[-_\s]+(.)?/g,function(e,n){return n?n.toUpperCase():""})},underscored:function(e){return g.trim(e).replace(/([a-z\d])([A-Z]+)/g,"$1_$2").replace(/[-\s]+/g,"_").toLowerCase()},dasherize:function(e){return g.trim(e).replace(/([A-Z])/g,"-$1").replace(/[-_\s]+/g,"-").toLowerCase()},classify:function(e){return g.titleize(n(e).replace(/[\W_]/g," ")).replace(/\s/g,"")},humanize:function(e){return g.capitalize(g.underscored(e).replace(/_id$/,"").replace(/_/g," "))},trim:function(e,r){return null==e?"":!r&&t?t.call(e):(r=c(r),n(e).replace(new RegExp("^"+r+"+|"+r+"+$","g"),""))},ltrim:function(e,r){return null==e?"":!r&&i?i.call(e):(r=c(r),n(e).replace(new RegExp("^"+r+"+"),""))},rtrim:function(e,r){return null==e?"":!r&&u?u.call(e):(r=c(r),n(e).replace(new RegExp(r+"+$"),""))},truncate:function(e,r,t){return null==e?"":(e=n(e),t=t||"...",r=~~r,e.length>r?e.slice(0,r)+t:e)},prune:function(e,r,t){if(null==e)return"";if(e=n(e),r=~~r,t=null!=t?n(t):"...",r>=e.length)return e;var u=function(e){return e.toUpperCase()!==e.toLowerCase()?"A":" "},i=e.slice(0,r+1).replace(/.(?=\W*\w*$)/g,u);return i=i.slice(i.length-2).match(/\w\w/)?i.replace(/\s*\S+$/,""):g.rtrim(i.slice(0,i.length-1)),(i+t).length>e.length?e:e.slice(0,i.length)+t},words:function(e,n){return g.isBlank(e)?[]:g.trim(e,n).split(n||/\s+/)},pad:function(e,r,t,u){e=null==e?"":n(e),r=~~r;var i=0;switch(t?t.length>1&&(t=t.charAt(0)):t=" ",u){case"right":return i=r-e.length,e+o(t,i);case"both":return i=r-e.length,o(t,Math.ceil(i/2))+e+o(t,Math.floor(i/2));default:return i=r-e.length,o(t,i)+e}},lpad:function(e,n,r){return g.pad(e,n,r)},rpad:function(e,n,r){return g.pad(e,n,r,"right")},lrpad:function(e,n,r){return g.pad(e,n,r,"both")},sprintf:h,vsprintf:function(e,n){return n.unshift(e),h.apply(null,n)},toNumber:function(e,n){return e?(e=g.trim(e),e.match(/^-?\d+(?:\.\d+)?$/)?l(l(e).toFixed(~~n)):0/0):0},numberFormat:function(e,n,r,t){if(isNaN(e)||null==e)return"";e=e.toFixed(~~n),t="string"==typeof t?t:",";var u=e.split("."),i=u[0],l=u[1]?(r||".")+u[1]:"";return i.replace(/(\d)(?=(?:\d{3})+$)/g,"$1"+t)+l},strRight:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.indexOf(r):-1;return~t?e.slice(t+r.length,e.length):e},strRightBack:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.lastIndexOf(r):-1;return~t?e.slice(t+r.length,e.length):e},strLeft:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.indexOf(r):-1;return~t?e.slice(0,t):e},strLeftBack:function(e,n){if(null==e)return"";e+="",n=null!=n?""+n:n;var r=e.lastIndexOf(n);return~r?e.slice(0,r):e},toSentence:function(e,n,r,t){n=n||", ",r=r||" and ";var u=e.slice(),i=u.pop();return e.length>2&&t&&(r=g.rtrim(n)+r),u.length?u.join(n)+r+i:i},toSentenceSerial:function(){var e=a.call(arguments);return e[3]=!0,g.toSentence.apply(g,e)},slugify:function(e){if(null==e)return"";var r="ąàáäâãåæăćęèéëêìíïîłńòóöôõøśșțùúüûñçżź",t="aaaaaaaaaceeeeeiiiilnoooooosstuuuunczz",u=new RegExp(c(r),"g");return e=n(e).toLowerCase().replace(u,function(e){var n=r.indexOf(e);return t.charAt(n)||"-"}),g.dasherize(e.replace(/[^\w\s-]/g,""))},surround:function(e,n){return[n,e,n].join("")},quote:function(e,n){return g.surround(e,n||'"')},unquote:function(e,n){return n=n||'"',e[0]===n&&e[e.length-1]===n?e.slice(1,e.length-1):e},exports:function(){var e={};for(var n in this)this.hasOwnProperty(n)&&!n.match(/^(?:include|contains|reverse)$/)&&(e[n]=this[n]);return e},repeat:function(e,r,t){if(null==e)return"";if(r=~~r,null==t)return o(n(e),r);for(var u=[];r>0;u[--r]=e);return u.join(t)},naturalCmp:function(e,r){if(e==r)return 0;if(!e)return-1;if(!r)return 1;for(var t=/(\.\d+)|(\d+)|(\D+)/g,u=n(e).toLowerCase().match(t),i=n(r).toLowerCase().match(t),l=Math.min(u.length,i.length),o=0;l>o;o++){var a=u[o],c=i[o];if(a!==c){var s=parseInt(a,10);if(!isNaN(s)){var f=parseInt(c,10);if(!isNaN(f)&&s-f)return s-f}return c>a?-1:1}}return u.length===i.length?u.length-i.length:r>e?-1:1},levenshtein:function(e,r){if(null==e&&null==r)return 0;if(null==e)return n(r).length;if(null==r)return n(e).length;e=n(e),r=n(r);for(var t,u,i=[],l=0;r.length>=l;l++)for(var o=0;e.length>=o;o++)u=l&&o?e.charAt(o-1)===r.charAt(l-1)?t:Math.min(i[o],i[o-1],t)+1:l+o,t=i[o],i[o]=u;return i.pop()},toBoolean:function(e,n,t){return"number"==typeof e&&(e=""+e),"string"!=typeof e?!!e:(e=g.trim(e),r(e,n||["true","1"])?!0:r(e,t||["false","0"])?!1:void 0)}};g.strip=g.trim,g.lstrip=g.ltrim,g.rstrip=g.rtrim,g.center=g.lrpad,g.rjust=g.lpad,g.ljust=g.rpad,g.contains=g.include,g.q=g.quote,g.toBool=g.toBoolean,"undefined"!=typeof exports&&("undefined"!=typeof module&&module.exports&&(module.exports=g),exports._s=g),"function"==typeof define&&define.amd&&define("underscore.string",[],function(){return g}),e._=e._||{},e._.string=e._.str=g}(this,String); \ No newline at end of file diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/lib/underscore.string.js b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/lib/underscore.string.js new file mode 100644 index 0000000..8761117 --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/lib/underscore.string.js @@ -0,0 +1,673 @@ +// Underscore.string +// (c) 2010 Esa-Matti Suuronen +// Underscore.string is freely distributable under the terms of the MIT license. +// Documentation: https://github.com/epeli/underscore.string +// Some code is borrowed from MooTools and Alexandru Marasteanu. +// Version '2.3.2' + +!function(root, String){ + 'use strict'; + + // Defining helper functions. + + var nativeTrim = String.prototype.trim; + var nativeTrimRight = String.prototype.trimRight; + var nativeTrimLeft = String.prototype.trimLeft; + + var parseNumber = function(source) { return source * 1 || 0; }; + + var strRepeat = function(str, qty){ + if (qty < 1) return ''; + var result = ''; + while (qty > 0) { + if (qty & 1) result += str; + qty >>= 1, str += str; + } + return result; + }; + + var slice = [].slice; + + var defaultToWhiteSpace = function(characters) { + if (characters == null) + return '\\s'; + else if (characters.source) + return characters.source; + else + return '[' + _s.escapeRegExp(characters) + ']'; + }; + + // Helper for toBoolean + function boolMatch(s, matchers) { + var i, matcher, down = s.toLowerCase(); + matchers = [].concat(matchers); + for (i = 0; i < matchers.length; i += 1) { + matcher = matchers[i]; + if (!matcher) continue; + if (matcher.test && matcher.test(s)) return true; + if (matcher.toLowerCase() === down) return true; + } + } + + var escapeChars = { + lt: '<', + gt: '>', + quot: '"', + amp: '&', + apos: "'" + }; + + var reversedEscapeChars = {}; + for(var key in escapeChars) reversedEscapeChars[escapeChars[key]] = key; + reversedEscapeChars["'"] = '#39'; + + // sprintf() for JavaScript 0.7-beta1 + // http://www.diveintojavascript.com/projects/javascript-sprintf + // + // Copyright (c) Alexandru Marasteanu + // All rights reserved. + + var sprintf = (function() { + function get_type(variable) { + return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase(); + } + + var str_repeat = strRepeat; + + var str_format = function() { + if (!str_format.cache.hasOwnProperty(arguments[0])) { + str_format.cache[arguments[0]] = str_format.parse(arguments[0]); + } + return str_format.format.call(null, str_format.cache[arguments[0]], arguments); + }; + + str_format.format = function(parse_tree, argv) { + var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length; + for (i = 0; i < tree_length; i++) { + node_type = get_type(parse_tree[i]); + if (node_type === 'string') { + output.push(parse_tree[i]); + } + else if (node_type === 'array') { + match = parse_tree[i]; // convenience purposes only + if (match[2]) { // keyword argument + arg = argv[cursor]; + for (k = 0; k < match[2].length; k++) { + if (!arg.hasOwnProperty(match[2][k])) { + throw new Error(sprintf('[_.sprintf] property "%s" does not exist', match[2][k])); + } + arg = arg[match[2][k]]; + } + } else if (match[1]) { // positional argument (explicit) + arg = argv[match[1]]; + } + else { // positional argument (implicit) + arg = argv[cursor++]; + } + + if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) { + throw new Error(sprintf('[_.sprintf] expecting number but found %s', get_type(arg))); + } + switch (match[8]) { + case 'b': arg = arg.toString(2); break; + case 'c': arg = String.fromCharCode(arg); break; + case 'd': arg = parseInt(arg, 10); break; + case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; + case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; + case 'o': arg = arg.toString(8); break; + case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break; + case 'u': arg = Math.abs(arg); break; + case 'x': arg = arg.toString(16); break; + case 'X': arg = arg.toString(16).toUpperCase(); break; + } + arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); + pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' '; + pad_length = match[6] - String(arg).length; + pad = match[6] ? str_repeat(pad_character, pad_length) : ''; + output.push(match[5] ? arg + pad : pad + arg); + } + } + return output.join(''); + }; + + str_format.cache = {}; + + str_format.parse = function(fmt) { + var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; + while (_fmt) { + if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { + parse_tree.push(match[0]); + } + else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { + parse_tree.push('%'); + } + else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { + if (match[2]) { + arg_names |= 1; + var field_list = [], replacement_field = match[2], field_match = []; + if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { + if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + } + else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + } + else { + throw new Error('[_.sprintf] huh?'); + } + } + } + else { + throw new Error('[_.sprintf] huh?'); + } + match[2] = field_list; + } + else { + arg_names |= 2; + } + if (arg_names === 3) { + throw new Error('[_.sprintf] mixing positional and named placeholders is not (yet) supported'); + } + parse_tree.push(match); + } + else { + throw new Error('[_.sprintf] huh?'); + } + _fmt = _fmt.substring(match[0].length); + } + return parse_tree; + }; + + return str_format; + })(); + + + + // Defining underscore.string + + var _s = { + + VERSION: '2.3.0', + + isBlank: function(str){ + if (str == null) str = ''; + return (/^\s*$/).test(str); + }, + + stripTags: function(str){ + if (str == null) return ''; + return String(str).replace(/<\/?[^>]+>/g, ''); + }, + + capitalize : function(str){ + str = str == null ? '' : String(str); + return str.charAt(0).toUpperCase() + str.slice(1); + }, + + chop: function(str, step){ + if (str == null) return []; + str = String(str); + step = ~~step; + return step > 0 ? str.match(new RegExp('.{1,' + step + '}', 'g')) : [str]; + }, + + clean: function(str){ + return _s.strip(str).replace(/\s+/g, ' '); + }, + + count: function(str, substr){ + if (str == null || substr == null) return 0; + + str = String(str); + substr = String(substr); + + var count = 0, + pos = 0, + length = substr.length; + + while (true) { + pos = str.indexOf(substr, pos); + if (pos === -1) break; + count++; + pos += length; + } + + return count; + }, + + chars: function(str) { + if (str == null) return []; + return String(str).split(''); + }, + + swapCase: function(str) { + if (str == null) return ''; + return String(str).replace(/\S/g, function(c){ + return c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase(); + }); + }, + + escapeHTML: function(str) { + if (str == null) return ''; + return String(str).replace(/[&<>"']/g, function(m){ return '&' + reversedEscapeChars[m] + ';'; }); + }, + + unescapeHTML: function(str) { + if (str == null) return ''; + return String(str).replace(/\&([^;]+);/g, function(entity, entityCode){ + var match; + + if (entityCode in escapeChars) { + return escapeChars[entityCode]; + } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) { + return String.fromCharCode(parseInt(match[1], 16)); + } else if (match = entityCode.match(/^#(\d+)$/)) { + return String.fromCharCode(~~match[1]); + } else { + return entity; + } + }); + }, + + escapeRegExp: function(str){ + if (str == null) return ''; + return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); + }, + + splice: function(str, i, howmany, substr){ + var arr = _s.chars(str); + arr.splice(~~i, ~~howmany, substr); + return arr.join(''); + }, + + insert: function(str, i, substr){ + return _s.splice(str, i, 0, substr); + }, + + include: function(str, needle){ + if (needle === '') return true; + if (str == null) return false; + return String(str).indexOf(needle) !== -1; + }, + + join: function() { + var args = slice.call(arguments), + separator = args.shift(); + + if (separator == null) separator = ''; + + return args.join(separator); + }, + + lines: function(str) { + if (str == null) return []; + return String(str).split("\n"); + }, + + reverse: function(str){ + return _s.chars(str).reverse().join(''); + }, + + startsWith: function(str, starts){ + if (starts === '') return true; + if (str == null || starts == null) return false; + str = String(str); starts = String(starts); + return str.length >= starts.length && str.slice(0, starts.length) === starts; + }, + + endsWith: function(str, ends){ + if (ends === '') return true; + if (str == null || ends == null) return false; + str = String(str); ends = String(ends); + return str.length >= ends.length && str.slice(str.length - ends.length) === ends; + }, + + succ: function(str){ + if (str == null) return ''; + str = String(str); + return str.slice(0, -1) + String.fromCharCode(str.charCodeAt(str.length-1) + 1); + }, + + titleize: function(str){ + if (str == null) return ''; + str = String(str).toLowerCase(); + return str.replace(/(?:^|\s|-)\S/g, function(c){ return c.toUpperCase(); }); + }, + + camelize: function(str){ + return _s.trim(str).replace(/[-_\s]+(.)?/g, function(match, c){ return c ? c.toUpperCase() : ""; }); + }, + + underscored: function(str){ + return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase(); + }, + + dasherize: function(str){ + return _s.trim(str).replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase(); + }, + + classify: function(str){ + return _s.titleize(String(str).replace(/[\W_]/g, ' ')).replace(/\s/g, ''); + }, + + humanize: function(str){ + return _s.capitalize(_s.underscored(str).replace(/_id$/,'').replace(/_/g, ' ')); + }, + + trim: function(str, characters){ + if (str == null) return ''; + if (!characters && nativeTrim) return nativeTrim.call(str); + characters = defaultToWhiteSpace(characters); + return String(str).replace(new RegExp('\^' + characters + '+|' + characters + '+$', 'g'), ''); + }, + + ltrim: function(str, characters){ + if (str == null) return ''; + if (!characters && nativeTrimLeft) return nativeTrimLeft.call(str); + characters = defaultToWhiteSpace(characters); + return String(str).replace(new RegExp('^' + characters + '+'), ''); + }, + + rtrim: function(str, characters){ + if (str == null) return ''; + if (!characters && nativeTrimRight) return nativeTrimRight.call(str); + characters = defaultToWhiteSpace(characters); + return String(str).replace(new RegExp(characters + '+$'), ''); + }, + + truncate: function(str, length, truncateStr){ + if (str == null) return ''; + str = String(str); truncateStr = truncateStr || '...'; + length = ~~length; + return str.length > length ? str.slice(0, length) + truncateStr : str; + }, + + /** + * _s.prune: a more elegant version of truncate + * prune extra chars, never leaving a half-chopped word. + * @author github.com/rwz + */ + prune: function(str, length, pruneStr){ + if (str == null) return ''; + + str = String(str); length = ~~length; + pruneStr = pruneStr != null ? String(pruneStr) : '...'; + + if (str.length <= length) return str; + + var tmpl = function(c){ return c.toUpperCase() !== c.toLowerCase() ? 'A' : ' '; }, + template = str.slice(0, length+1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA' + + if (template.slice(template.length-2).match(/\w\w/)) + template = template.replace(/\s*\S+$/, ''); + else + template = _s.rtrim(template.slice(0, template.length-1)); + + return (template+pruneStr).length > str.length ? str : str.slice(0, template.length)+pruneStr; + }, + + words: function(str, delimiter) { + if (_s.isBlank(str)) return []; + return _s.trim(str, delimiter).split(delimiter || /\s+/); + }, + + pad: function(str, length, padStr, type) { + str = str == null ? '' : String(str); + length = ~~length; + + var padlen = 0; + + if (!padStr) + padStr = ' '; + else if (padStr.length > 1) + padStr = padStr.charAt(0); + + switch(type) { + case 'right': + padlen = length - str.length; + return str + strRepeat(padStr, padlen); + case 'both': + padlen = length - str.length; + return strRepeat(padStr, Math.ceil(padlen/2)) + str + + strRepeat(padStr, Math.floor(padlen/2)); + default: // 'left' + padlen = length - str.length; + return strRepeat(padStr, padlen) + str; + } + }, + + lpad: function(str, length, padStr) { + return _s.pad(str, length, padStr); + }, + + rpad: function(str, length, padStr) { + return _s.pad(str, length, padStr, 'right'); + }, + + lrpad: function(str, length, padStr) { + return _s.pad(str, length, padStr, 'both'); + }, + + sprintf: sprintf, + + vsprintf: function(fmt, argv){ + argv.unshift(fmt); + return sprintf.apply(null, argv); + }, + + toNumber: function(str, decimals) { + if (!str) return 0; + str = _s.trim(str); + if (!str.match(/^-?\d+(?:\.\d+)?$/)) return NaN; + return parseNumber(parseNumber(str).toFixed(~~decimals)); + }, + + numberFormat : function(number, dec, dsep, tsep) { + if (isNaN(number) || number == null) return ''; + + number = number.toFixed(~~dec); + tsep = typeof tsep == 'string' ? tsep : ','; + + var parts = number.split('.'), fnums = parts[0], + decimals = parts[1] ? (dsep || '.') + parts[1] : ''; + + return fnums.replace(/(\d)(?=(?:\d{3})+$)/g, '$1' + tsep) + decimals; + }, + + strRight: function(str, sep){ + if (str == null) return ''; + str = String(str); sep = sep != null ? String(sep) : sep; + var pos = !sep ? -1 : str.indexOf(sep); + return ~pos ? str.slice(pos+sep.length, str.length) : str; + }, + + strRightBack: function(str, sep){ + if (str == null) return ''; + str = String(str); sep = sep != null ? String(sep) : sep; + var pos = !sep ? -1 : str.lastIndexOf(sep); + return ~pos ? str.slice(pos+sep.length, str.length) : str; + }, + + strLeft: function(str, sep){ + if (str == null) return ''; + str = String(str); sep = sep != null ? String(sep) : sep; + var pos = !sep ? -1 : str.indexOf(sep); + return ~pos ? str.slice(0, pos) : str; + }, + + strLeftBack: function(str, sep){ + if (str == null) return ''; + str += ''; sep = sep != null ? ''+sep : sep; + var pos = str.lastIndexOf(sep); + return ~pos ? str.slice(0, pos) : str; + }, + + toSentence: function(array, separator, lastSeparator, serial) { + separator = separator || ', '; + lastSeparator = lastSeparator || ' and '; + var a = array.slice(), lastMember = a.pop(); + + if (array.length > 2 && serial) lastSeparator = _s.rtrim(separator) + lastSeparator; + + return a.length ? a.join(separator) + lastSeparator + lastMember : lastMember; + }, + + toSentenceSerial: function() { + var args = slice.call(arguments); + args[3] = true; + return _s.toSentence.apply(_s, args); + }, + + slugify: function(str) { + if (str == null) return ''; + + var from = "ąàáäâãåæăćęèéëêìíïîłńòóöôõøśșțùúüûñçżź", + to = "aaaaaaaaaceeeeeiiiilnoooooosstuuuunczz", + regex = new RegExp(defaultToWhiteSpace(from), 'g'); + + str = String(str).toLowerCase().replace(regex, function(c){ + var index = from.indexOf(c); + return to.charAt(index) || '-'; + }); + + return _s.dasherize(str.replace(/[^\w\s-]/g, '')); + }, + + surround: function(str, wrapper) { + return [wrapper, str, wrapper].join(''); + }, + + quote: function(str, quoteChar) { + return _s.surround(str, quoteChar || '"'); + }, + + unquote: function(str, quoteChar) { + quoteChar = quoteChar || '"'; + if (str[0] === quoteChar && str[str.length-1] === quoteChar) + return str.slice(1,str.length-1); + else return str; + }, + + exports: function() { + var result = {}; + + for (var prop in this) { + if (!this.hasOwnProperty(prop) || prop.match(/^(?:include|contains|reverse)$/)) continue; + result[prop] = this[prop]; + } + + return result; + }, + + repeat: function(str, qty, separator){ + if (str == null) return ''; + + qty = ~~qty; + + // using faster implementation if separator is not needed; + if (separator == null) return strRepeat(String(str), qty); + + // this one is about 300x slower in Google Chrome + for (var repeat = []; qty > 0; repeat[--qty] = str) {} + return repeat.join(separator); + }, + + naturalCmp: function(str1, str2){ + if (str1 == str2) return 0; + if (!str1) return -1; + if (!str2) return 1; + + var cmpRegex = /(\.\d+)|(\d+)|(\D+)/g, + tokens1 = String(str1).toLowerCase().match(cmpRegex), + tokens2 = String(str2).toLowerCase().match(cmpRegex), + count = Math.min(tokens1.length, tokens2.length); + + for(var i = 0; i < count; i++) { + var a = tokens1[i], b = tokens2[i]; + + if (a !== b){ + var num1 = parseInt(a, 10); + if (!isNaN(num1)){ + var num2 = parseInt(b, 10); + if (!isNaN(num2) && num1 - num2) + return num1 - num2; + } + return a < b ? -1 : 1; + } + } + + if (tokens1.length === tokens2.length) + return tokens1.length - tokens2.length; + + return str1 < str2 ? -1 : 1; + }, + + levenshtein: function(str1, str2) { + if (str1 == null && str2 == null) return 0; + if (str1 == null) return String(str2).length; + if (str2 == null) return String(str1).length; + + str1 = String(str1); str2 = String(str2); + + var current = [], prev, value; + + for (var i = 0; i <= str2.length; i++) + for (var j = 0; j <= str1.length; j++) { + if (i && j) + if (str1.charAt(j - 1) === str2.charAt(i - 1)) + value = prev; + else + value = Math.min(current[j], current[j - 1], prev) + 1; + else + value = i + j; + + prev = current[j]; + current[j] = value; + } + + return current.pop(); + }, + + toBoolean: function(str, trueValues, falseValues) { + if (typeof str === "number") str = "" + str; + if (typeof str !== "string") return !!str; + str = _s.trim(str); + if (boolMatch(str, trueValues || ["true", "1"])) return true; + if (boolMatch(str, falseValues || ["false", "0"])) return false; + } + }; + + // Aliases + + _s.strip = _s.trim; + _s.lstrip = _s.ltrim; + _s.rstrip = _s.rtrim; + _s.center = _s.lrpad; + _s.rjust = _s.lpad; + _s.ljust = _s.rpad; + _s.contains = _s.include; + _s.q = _s.quote; + _s.toBool = _s.toBoolean; + + // Exporting + + // CommonJS module is defined + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) + module.exports = _s; + + exports._s = _s; + } + + // Register as a named module with AMD. + if (typeof define === 'function' && define.amd) + define('underscore.string', [], function(){ return _s; }); + + + // Integrate with Underscore.js if defined + // or create our own underscore object. + root._ = root._ || {}; + root._.string = root._.str = _s; +}(this, String); diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/libpeerconnection.log b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/libpeerconnection.log new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/package.json b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/package.json new file mode 100644 index 0000000..99e39b3 --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/package.json @@ -0,0 +1,132 @@ +{ + "_args": [ + [ + { + "raw": "underscore.string@~2.3.3", + "scope": null, + "escapedName": "underscore.string", + "name": "underscore.string", + "rawSpec": "~2.3.3", + "spec": ">=2.3.3 <2.4.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt-legacy-log-utils" + ] + ], + "_from": "underscore.string@>=2.3.3 <2.4.0", + "_id": "underscore.string@2.3.3", + "_inCache": true, + "_location": "/grunt-legacy-log-utils/underscore.string", + "_npmUser": { + "name": "epeli", + "email": "esa-matti@suuronen.org" + }, + "_npmVersion": "1.2.32", + "_phantomChildren": {}, + "_requested": { + "raw": "underscore.string@~2.3.3", + "scope": null, + "escapedName": "underscore.string", + "name": "underscore.string", + "rawSpec": "~2.3.3", + "spec": ">=2.3.3 <2.4.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt-legacy-log-utils" + ], + "_resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", + "_shasum": "71c08bf6b428b1133f37e78fa3a21c82f7329b0d", + "_shrinkwrap": null, + "_spec": "underscore.string@~2.3.3", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt-legacy-log-utils", + "bugs": { + "url": "https://github.com/epeli/underscore.string/issues" + }, + "contributors": [ + { + "name": "Esa-Matti Suuronen", + "email": "esa-matti@suuronen.org", + "url": "http://esa-matti.suuronen.org/" + }, + { + "name": "Edward Tsech", + "email": "edtsech@gmail.com" + }, + { + "name": "Pavel Pravosud", + "email": "pavel@pravosud.com", + "url": "" + }, + { + "name": "Sasha Koss", + "email": "kossnocorp@gmail.com", + "url": "http://koss.nocorp.me/" + }, + { + "name": "Vladimir Dronnikov", + "email": "dronnikov@gmail.com" + }, + { + "name": "Pete Kruckenberg", + "email": "https://github.com/kruckenb", + "url": "" + }, + { + "name": "Paul Chavard", + "email": "paul@chavard.net", + "url": "" + }, + { + "name": "Ed Finkler", + "email": "coj@funkatron.com", + "url": "" + } + ], + "dependencies": {}, + "description": "String manipulation extensions for Underscore.js javascript library.", + "devDependencies": {}, + "directories": { + "lib": "./lib" + }, + "dist": { + "shasum": "71c08bf6b428b1133f37e78fa3a21c82f7329b0d", + "tarball": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz" + }, + "engines": { + "node": "*" + }, + "homepage": "http://epeli.github.com/underscore.string/", + "keywords": [ + "underscore", + "string" + ], + "licenses": [ + { + "type": "MIT" + } + ], + "main": "./lib/underscore.string", + "maintainers": [ + { + "name": "edtsech", + "email": "edtsech@gmail.com" + }, + { + "name": "rwz", + "email": "rwz@duckroll.ru" + }, + { + "name": "epeli", + "email": "esa-matti@suuronen.org" + } + ], + "name": "underscore.string", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/epeli/underscore.string.git" + }, + "version": "2.3.3" +} diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/run-qunit.js b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/run-qunit.js new file mode 100644 index 0000000..44a2167 --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/run-qunit.js @@ -0,0 +1,45 @@ +function waitFor(test, complete, timeout) { + var result, start = new Date().getTime() + setInterval(function interval() { + if ((new Date().getTime() - start < timeout) && !result) { + result = test() + } else { + if (!result) { + phantom.exit(1) + } else { + complete() + clearInterval(interval) + } + } + }, 100) +} + + +var fs = require('fs'), page = require('webpage').create(); +var url = 'file://localhost' + fs.workingDirectory + '/' + phantom.args[0]; + +page.onConsoleMessage = function(msg) { + console.log(msg) +} + +page.open(url, function(status) { + waitFor(function() { + return page.evaluate(function(){ + var el = document.getElementById('qunit-testresult') + return el && el.innerText.match('completed') + }) + }, function() { + var failures = page.evaluate(function() { + var el = document.getElementById('qunit-testresult'), + fails = document.getElementsByClassName('fail') + + for (var i = 0; i < fails.length; i++) + console.log(fails[i].innerText) + + console.log(el.innerText) + + return parseInt(el.getElementsByClassName('failed')[0].innerHTML) + }) + phantom.exit(failures > 0 ? 1 : 0) + }, 10000) +}) \ No newline at end of file diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/speed.js b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/speed.js new file mode 100644 index 0000000..9ceeea7 --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/speed.js @@ -0,0 +1,148 @@ +(function() { + + JSLitmus.test('levenshtein', function() { + return [ + _.levenshtein('pineapple', 'potato'), + _.levenshtein('seven', 'eight'), + _.levenshtein('the very same string', 'the very same string'), + _.levenshtein('very very very long string', 'something completely different') + ]; + }); + + + JSLitmus.test('trimNoNative', function() { + return _.trim(" foobar ", " "); + }); + + JSLitmus.test('trim', function() { + return _.trim(" foobar "); + }); + + JSLitmus.test('trim object-oriented', function() { + return _(" foobar ").trim(); + }); + + JSLitmus.test('trim jQuery', function() { + return jQuery.trim(" foobar "); + }); + + JSLitmus.test('ltrimp', function() { + return _.ltrim(" foobar ", " "); + }); + + JSLitmus.test('rtrimp', function() { + return _.rtrim(" foobar ", " "); + }); + + JSLitmus.test('startsWith', function() { + return _.startsWith("foobar", "foo"); + }); + + JSLitmus.test('endsWith', function() { + return _.endsWith("foobar", "xx"); + }); + + JSLitmus.test('chop', function(){ + return _('whitespace').chop(2); + }); + + JSLitmus.test('count', function(){ + return _('Hello worls').count('l'); + }); + + JSLitmus.test('insert', function() { + return _('Hello ').insert(6, 'world'); + }); + + JSLitmus.test('splice', function() { + return _('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli'); + }); + + JSLitmus.test('succ', function(){ + var let = 'a', alphabet = []; + + for (var i=0; i < 26; i++) { + alphabet.push(let); + let = _(let).succ(); + } + + return alphabet; + }); + + JSLitmus.test('titleize', function(){ + return _('the titleize string method').titleize(); + }); + + JSLitmus.test('truncate', function(){ + return _('Hello world').truncate(5); + }); + + JSLitmus.test('prune', function(){ + return _('Hello world').prune(5); + }); + + JSLitmus.test('isBlank', function(){ + return _('').isBlank(); + }); + + JSLitmus.test('escapeHTML', function(){ + _('
Blah blah blah
').escapeHTML(); + }); + + JSLitmus.test('unescapeHTML', function(){ + _('<div>Blah blah blah</div>').unescapeHTML(); + }); + + JSLitmus.test('reverse', function(){ + _('Hello World').reverse(); + }); + + JSLitmus.test('pad default', function(){ + _('foo').pad(12); + }); + + JSLitmus.test('pad hash left', function(){ + _('foo').pad(12, '#'); + }); + + JSLitmus.test('pad hash right', function(){ + _('foo').pad(12, '#', 'right'); + }); + + JSLitmus.test('pad hash both', function(){ + _('foo').pad(12, '#', 'both'); + }); + + JSLitmus.test('pad hash both longPad', function(){ + _('foo').pad(12, 'f00f00f00', 'both'); + }); + + JSLitmus.test('toNumber', function(){ + _('10.232323').toNumber(2); + }); + + JSLitmus.test('strRight', function(){ + _('aaa_bbb_ccc').strRight('_'); + }); + + JSLitmus.test('strRightBack', function(){ + _('aaa_bbb_ccc').strRightBack('_'); + }); + + JSLitmus.test('strLeft', function(){ + _('aaa_bbb_ccc').strLeft('_'); + }); + + JSLitmus.test('strLeftBack', function(){ + _('aaa_bbb_ccc').strLeftBack('_'); + }); + + JSLitmus.test('join', function(){ + _('separator').join(1, 2, 3, 4, 5, 6, 7, 8, 'foo', 'bar', 'lol', 'wut'); + }); + + JSLitmus.test('slugify', function(){ + _("Un éléphant à l'orée du bois").slugify(); + }); + +})(); diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/strings.js b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/strings.js new file mode 100644 index 0000000..77364f2 --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/strings.js @@ -0,0 +1,685 @@ +$(document).ready(function() { + + // Include Underscore.string methods to Underscore namespace + _.mixin(_.str.exports()); + + module('String extensions'); + + test('Strings: naturalSort', function() { + var arr = ['foo2', 'foo1', 'foo10', 'foo30', 'foo100', 'foo10bar'], + sorted = ['foo1', 'foo2', 'foo10', 'foo10bar', 'foo30', 'foo100']; + deepEqual(arr.sort(_.naturalCmp), sorted); + }); + + test('Strings: trim', function() { + equal(_.trim(123), '123', 'Non string'); + equal(_(' foo').trim(), 'foo'); + equal(_('foo ').trim(), 'foo'); + equal(_(' foo ').trim(), 'foo'); + equal(_(' foo ').trim(), 'foo'); + equal(_(' foo ').trim(' '), 'foo', 'Manually set whitespace'); + equal(_('\t foo \t ').trim(/\s/), 'foo', 'Manually set RegExp /\\s+/'); + + equal(_('ffoo').trim('f'), 'oo'); + equal(_('ooff').trim('f'), 'oo'); + equal(_('ffooff').trim('f'), 'oo'); + + + equal(_('_-foobar-_').trim('_-'), 'foobar'); + + equal(_('http://foo/').trim('/'), 'http://foo'); + equal(_('c:\\').trim('\\'), 'c:'); + + equal(_(123).trim(), '123'); + equal(_(123).trim(3), '12'); + equal(_('').trim(), '', 'Trim empty string should return empty string'); + equal(_(null).trim(), '', 'Trim null should return empty string'); + equal(_(undefined).trim(), '', 'Trim undefined should return empty string'); + }); + + test('String: levenshtein', function() { + equal(_.levenshtein('Godfather', 'Godfather'), 0); + equal(_.levenshtein('Godfather', 'Godfathe'), 1); + equal(_.levenshtein('Godfather', 'odfather'), 1); + equal(_.levenshtein('Godfather', 'Gdfthr'), 3); + equal(_.levenshtein('seven', 'eight'), 5); + equal(_.levenshtein('123', 123), 0); + equal(_.levenshtein(321, '321'), 0); + equal(_.levenshtein('lol', null), 3); + equal(_.levenshtein('lol'), 3); + equal(_.levenshtein(null, 'lol'), 3); + equal(_.levenshtein(undefined, 'lol'), 3); + equal(_.levenshtein(), 0); + }); + + test('Strings: ltrim', function() { + equal(_(' foo').ltrim(), 'foo'); + equal(_(' foo').ltrim(), 'foo'); + equal(_('foo ').ltrim(), 'foo '); + equal(_(' foo ').ltrim(), 'foo '); + equal(_('').ltrim(), '', 'ltrim empty string should return empty string'); + equal(_(null).ltrim(), '', 'ltrim null should return empty string'); + equal(_(undefined).ltrim(), '', 'ltrim undefined should return empty string'); + + equal(_('ffoo').ltrim('f'), 'oo'); + equal(_('ooff').ltrim('f'), 'ooff'); + equal(_('ffooff').ltrim('f'), 'ooff'); + + equal(_('_-foobar-_').ltrim('_-'), 'foobar-_'); + + equal(_(123).ltrim(1), '23'); + }); + + test('Strings: rtrim', function() { + equal(_('http://foo/').rtrim('/'), 'http://foo', 'clean trailing slash'); + equal(_(' foo').rtrim(), ' foo'); + equal(_('foo ').rtrim(), 'foo'); + equal(_('foo ').rtrim(), 'foo'); + equal(_('foo bar ').rtrim(), 'foo bar'); + equal(_(' foo ').rtrim(), ' foo'); + + equal(_('ffoo').rtrim('f'), 'ffoo'); + equal(_('ooff').rtrim('f'), 'oo'); + equal(_('ffooff').rtrim('f'), 'ffoo'); + + equal(_('_-foobar-_').rtrim('_-'), '_-foobar'); + + equal(_(123).rtrim(3), '12'); + equal(_('').rtrim(), '', 'rtrim empty string should return empty string'); + equal(_(null).rtrim(), '', 'rtrim null should return empty string'); + }); + + test('Strings: capitalize', function() { + equal(_('fabio').capitalize(), 'Fabio', 'First letter is upper case'); + equal(_.capitalize('fabio'), 'Fabio', 'First letter is upper case'); + equal(_.capitalize('FOO'), 'FOO', 'Other letters unchanged'); + equal(_(123).capitalize(), '123', 'Non string'); + equal(_.capitalize(''), '', 'Capitalizing empty string returns empty string'); + equal(_.capitalize(null), '', 'Capitalizing null returns empty string'); + equal(_.capitalize(undefined), '', 'Capitalizing undefined returns empty string'); + }); + + test('Strings: join', function() { + equal(_.join('', 'foo', 'bar'), 'foobar', 'basic join'); + equal(_.join('', 1, 'foo', 2), '1foo2', 'join numbers and strings'); + equal(_.join(' ','foo', 'bar'), 'foo bar', 'join with spaces'); + equal(_.join('1', '2', '2'), '212', 'join number strings'); + equal(_.join(1, 2, 2), '212', 'join numbers'); + equal(_.join('','foo', null), 'foo', 'join null with string returns string'); + equal(_.join(null,'foo', 'bar'), 'foobar', 'join strings with null returns string'); + equal(_(' ').join('foo', 'bar'), 'foo bar', 'join object oriented'); + }); + + test('Strings: reverse', function() { + equal(_.str.reverse('foo'), 'oof' ); + equal(_.str.reverse('foobar'), 'raboof' ); + equal(_.str.reverse('foo bar'), 'rab oof' ); + equal(_.str.reverse('saippuakauppias'), 'saippuakauppias' ); + equal(_.str.reverse(123), '321', 'Non string'); + equal(_.str.reverse(123.45), '54.321', 'Non string'); + equal(_.str.reverse(''), '', 'reversing empty string returns empty string' ); + equal(_.str.reverse(null), '', 'reversing null returns empty string' ); + equal(_.str.reverse(undefined), '', 'reversing undefined returns empty string' ); + }); + + test('Strings: clean', function() { + equal(_(' foo bar ').clean(), 'foo bar'); + equal(_(123).clean(), '123'); + equal(_('').clean(), '', 'claning empty string returns empty string'); + equal(_(null).clean(), '', 'claning null returns empty string'); + equal(_(undefined).clean(), '', 'claning undefined returns empty string'); + }); + + test('Strings: sprintf', function() { + // Should be very tested function already. Thanks to + // http://www.diveintojavascript.com/projects/sprintf-for-javascript + equal(_.sprintf('Hello %s', 'me'), 'Hello me', 'basic'); + equal(_('Hello %s').sprintf('me'), 'Hello me', 'object'); + equal(_('hello %s').chain().sprintf('me').capitalize().value(), 'Hello me', 'Chaining works'); + equal(_.sprintf('%.1f', 1.22222), '1.2', 'round'); + equal(_.sprintf('%.1f', 1.17), '1.2', 'round 2'); + equal(_.sprintf('%(id)d - %(name)s', {id: 824, name: 'Hello World'}), '824 - Hello World', 'Named replacements work'); + equal(_.sprintf('%(args[0].id)d - %(args[1].name)s', {args: [{id: 824}, {name: 'Hello World'}]}), '824 - Hello World', 'Named replacements with arrays work'); + }); + + + test('Strings: vsprintf', function() { + equal(_.vsprintf('Hello %s', ['me']), 'Hello me', 'basic'); + equal(_('Hello %s').vsprintf(['me']), 'Hello me', 'object'); + equal(_('hello %s').chain().vsprintf(['me']).capitalize().value(), 'Hello me', 'Chaining works'); + equal(_.vsprintf('%.1f', [1.22222]), '1.2', 'round'); + equal(_.vsprintf('%.1f', [1.17]), '1.2', 'round 2'); + equal(_.vsprintf('%(id)d - %(name)s', [{id: 824, name: 'Hello World'}]), '824 - Hello World', 'Named replacement works'); + equal(_.vsprintf('%(args[0].id)d - %(args[1].name)s', [{args: [{id: 824}, {name: 'Hello World'}]}]), '824 - Hello World', 'Named replacement with arrays works'); + }); + + test('Strings: startsWith', function() { + ok(_('foobar').startsWith('foo'), 'foobar starts with foo'); + ok(!_('oobar').startsWith('foo'), 'oobar does not start with foo'); + ok(_(12345).startsWith(123), '12345 starts with 123'); + ok(!_(2345).startsWith(123), '2345 does not start with 123'); + ok(_('').startsWith(''), 'empty string starts with empty string'); + ok(_(null).startsWith(''), 'null starts with empty string'); + ok(!_(null).startsWith('foo'), 'null starts with foo'); + }); + + test('Strings: endsWith', function() { + ok(_('foobar').endsWith('bar'), 'foobar ends with bar'); + ok(_.endsWith('foobar', 'bar'), 'foobar ends with bar'); + ok(_.endsWith('00018-0000062.Plone.sdh264.1a7264e6912a91aa4a81b64dc5517df7b8875994.mp4', 'mp4'), 'endsWith .mp4'); + ok(!_('fooba').endsWith('bar'), 'fooba does not end with bar'); + ok(_.endsWith(12345, 45), '12345 ends with 45'); + ok(!_.endsWith(12345, 6), '12345 does not end with 6'); + ok(_('').endsWith(''), 'empty string ends with empty string'); + ok(_(null).endsWith(''), 'null ends with empty string'); + ok(!_(null).endsWith('foo'), 'null ends with foo'); + }); + + test('Strings: include', function() { + ok(_.str.include('foobar', 'bar'), 'foobar includes bar'); + ok(!_.str.include('foobar', 'buzz'), 'foobar does not includes buzz'); + ok(_.str.include(12345, 34), '12345 includes 34'); + ok(!_.str.contains(12345, 6), '12345 does not includes 6'); + ok(!_.str.include('', 34), 'empty string includes 34'); + ok(!_.str.include(null, 34), 'null includes 34'); + ok(_.str.include(null, ''), 'null includes empty string'); + }); + + test('String: chop', function(){ + ok(_('whitespace').chop(2).length === 5, 'output [wh, it, es, pa, ce]'); + ok(_('whitespace').chop(3).length === 4, 'output [whi, tes, pac, e]'); + ok(_('whitespace').chop()[0].length === 10, 'output [whitespace]'); + ok(_(12345).chop(1).length === 5, 'output [1, 2, 3, 4, 5]'); + }); + + test('String: clean', function(){ + equal(_.clean(' foo bar '), 'foo bar'); + equal(_.clean(''), ''); + equal(_.clean(null), ''); + equal(_.clean(1), '1'); + }); + + test('String: count', function(){ + equal(_('Hello world').count('l'), 3); + equal(_('Hello world').count('Hello'), 1); + equal(_('Hello world').count('foo'), 0); + equal(_('x.xx....x.x').count('x'), 5); + equal(_('').count('x'), 0); + equal(_(null).count('x'), 0); + equal(_(undefined).count('x'), 0); + equal(_(12345).count(1), 1); + equal(_(11345).count(1), 2); + }); + + test('String: insert', function(){ + equal(_('Hello ').insert(6, 'Jessy'), 'Hello Jessy'); + equal(_('Hello ').insert(100, 'Jessy'), 'Hello Jessy'); + equal(_('').insert(100, 'Jessy'), 'Jessy'); + equal(_(null).insert(100, 'Jessy'), 'Jessy'); + equal(_(undefined).insert(100, 'Jessy'), 'Jessy'); + equal(_(12345).insert(6, 'Jessy'), '12345Jessy'); + }); + + test('String: splice', function(){ + equal(_('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli'), + 'https://edtsech@bitbucket.org/epeli/underscore.strings'); + equal(_.splice(12345, 1, 2, 321), '132145', 'Non strings'); + }); + + test('String: succ', function(){ + equal(_('a').succ(), 'b'); + equal(_('A').succ(), 'B'); + equal(_('+').succ(), ','); + equal(_(1).succ(), '2'); + }); + + test('String: titleize', function(){ + equal(_('the titleize string method').titleize(), 'The Titleize String Method'); + equal(_('the titleize string method').titleize(), 'The Titleize String Method'); + equal(_('').titleize(), '', 'Titleize empty string returns empty string'); + equal(_(null).titleize(), '', 'Titleize null returns empty string'); + equal(_(undefined).titleize(), '', 'Titleize undefined returns empty string'); + equal(_('let\'s have some fun').titleize(), 'Let\'s Have Some Fun'); + equal(_('a-dash-separated-string').titleize(), 'A-Dash-Separated-String'); + equal(_('A-DASH-SEPARATED-STRING').titleize(), 'A-Dash-Separated-String'); + equal(_(123).titleize(), '123'); + }); + + test('String: camelize', function(){ + equal(_('the_camelize_string_method').camelize(), 'theCamelizeStringMethod'); + equal(_('-the-camelize-string-method').camelize(), 'TheCamelizeStringMethod'); + equal(_('the camelize string method').camelize(), 'theCamelizeStringMethod'); + equal(_(' the camelize string method').camelize(), 'theCamelizeStringMethod'); + equal(_('the camelize string method').camelize(), 'theCamelizeStringMethod'); + equal(_('').camelize(), '', 'Camelize empty string returns empty string'); + equal(_(null).camelize(), '', 'Camelize null returns empty string'); + equal(_(undefined).camelize(), '', 'Camelize undefined returns empty string'); + equal(_(123).camelize(), '123'); + }); + + test('String: underscored', function(){ + equal(_('the-underscored-string-method').underscored(), 'the_underscored_string_method'); + equal(_('theUnderscoredStringMethod').underscored(), 'the_underscored_string_method'); + equal(_('TheUnderscoredStringMethod').underscored(), 'the_underscored_string_method'); + equal(_(' the underscored string method').underscored(), 'the_underscored_string_method'); + equal(_('').underscored(), ''); + equal(_(null).underscored(), ''); + equal(_(undefined).underscored(), ''); + equal(_(123).underscored(), '123'); + }); + + test('String: dasherize', function(){ + equal(_('the_dasherize_string_method').dasherize(), 'the-dasherize-string-method'); + equal(_('TheDasherizeStringMethod').dasherize(), '-the-dasherize-string-method'); + equal(_('thisIsATest').dasherize(), 'this-is-a-test'); + equal(_('this Is A Test').dasherize(), 'this-is-a-test'); + equal(_('thisIsATest123').dasherize(), 'this-is-a-test123'); + equal(_('123thisIsATest').dasherize(), '123this-is-a-test'); + equal(_('the dasherize string method').dasherize(), 'the-dasherize-string-method'); + equal(_('the dasherize string method ').dasherize(), 'the-dasherize-string-method'); + equal(_('téléphone').dasherize(), 'téléphone'); + equal(_('foo$bar').dasherize(), 'foo$bar'); + equal(_('').dasherize(), ''); + equal(_(null).dasherize(), ''); + equal(_(undefined).dasherize(), ''); + equal(_(123).dasherize(), '123'); + }); + + test('String: camelize', function(){ + equal(_.camelize('-moz-transform'), 'MozTransform'); + equal(_.camelize('webkit-transform'), 'webkitTransform'); + equal(_.camelize('under_scored'), 'underScored'); + equal(_.camelize(' with spaces'), 'withSpaces'); + equal(_('').camelize(), ''); + equal(_(null).camelize(), ''); + equal(_(undefined).camelize(), ''); + equal(_("_som eWeird---name-").camelize(), 'SomEWeirdName'); + }); + + test('String: join', function(){ + equal(_.join(1, 2, 3, 4), '21314'); + equal(_.join('|', 'foo', 'bar', 'baz'), 'foo|bar|baz'); + equal(_.join('',2,3,null), '23'); + equal(_.join(null,2,3), '23'); + }); + + test('String: classify', function(){ + equal(_.classify(1), '1'); + equal(_('some_class_name').classify(), 'SomeClassName'); + equal(_('my wonderfull class_name').classify(), 'MyWonderfullClassName'); + equal(_('my wonderfull.class.name').classify(), 'MyWonderfullClassName'); + }); + + test('String: humanize', function(){ + equal(_('the_humanize_string_method').humanize(), 'The humanize string method'); + equal(_('ThehumanizeStringMethod').humanize(), 'Thehumanize string method'); + equal(_('the humanize string method').humanize(), 'The humanize string method'); + equal(_('the humanize_id string method_id').humanize(), 'The humanize id string method'); + equal(_('the humanize string method ').humanize(), 'The humanize string method'); + equal(_(' capitalize dash-CamelCase_underscore trim ').humanize(), 'Capitalize dash camel case underscore trim'); + equal(_(123).humanize(), '123'); + equal(_('').humanize(), ''); + equal(_(null).humanize(), ''); + equal(_(undefined).humanize(), ''); + }); + + test('String: truncate', function(){ + equal(_('Hello world').truncate(6, 'read more'), 'Hello read more'); + equal(_('Hello world').truncate(5), 'Hello...'); + equal(_('Hello').truncate(10), 'Hello'); + equal(_('').truncate(10), ''); + equal(_(null).truncate(10), ''); + equal(_(undefined).truncate(10), ''); + equal(_(1234567890).truncate(5), '12345...'); + }); + + test('String: prune', function(){ + equal(_('Hello, cruel world').prune(6, ' read more'), 'Hello read more'); + equal(_('Hello, world').prune(5, 'read a lot more'), 'Hello, world'); + equal(_('Hello, world').prune(5), 'Hello...'); + equal(_('Hello, world').prune(8), 'Hello...'); + equal(_('Hello, cruel world').prune(15), 'Hello, cruel...'); + equal(_('Hello world').prune(22), 'Hello world'); + equal(_('Привет, жестокий мир').prune(6, ' read more'), 'Привет read more'); + equal(_('Привет, мир').prune(6, 'read a lot more'), 'Привет, мир'); + equal(_('Привет, мир').prune(6), 'Привет...'); + equal(_('Привет, мир').prune(8), 'Привет...'); + equal(_('Привет, жестокий мир').prune(16), 'Привет, жестокий...'); + equal(_('Привет, мир').prune(22), 'Привет, мир'); + equal(_('alksjd!!!!!!....').prune(100, ''), 'alksjd!!!!!!....'); + equal(_(123).prune(10), '123'); + equal(_(123).prune(1, 321), '321'); + equal(_('').prune(5), ''); + equal(_(null).prune(5), ''); + equal(_(undefined).prune(5), ''); + }); + + test('String: isBlank', function(){ + ok(_('').isBlank()); + ok(_(' ').isBlank()); + ok(_('\n').isBlank()); + ok(!_('a').isBlank()); + ok(!_('0').isBlank()); + ok(!_(0).isBlank()); + ok(_('').isBlank()); + ok(_(null).isBlank()); + ok(_(undefined).isBlank()); + }); + + test('String: escapeRegExp', function(){ + equal(_.escapeRegExp(/hello(?=\sworld)/.source), 'hello\\(\\?\\=\\\\sworld\\)', 'with lookahead'); + equal(_.escapeRegExp(/hello(?!\shell)/.source), 'hello\\(\\?\\!\\\\shell\\)', 'with negative lookahead'); + }); + + test('String: escapeHTML', function(){ + equal(_('
Blah & "blah" & \'blah\'
').escapeHTML(), + '<div>Blah & "blah" & 'blah'</div>'); + equal(_('<').escapeHTML(), '&lt;'); + equal(_(5).escapeHTML(), '5'); + equal(_('').escapeHTML(), ''); + equal(_(null).escapeHTML(), ''); + equal(_(undefined).escapeHTML(), ''); + }); + + test('String: unescapeHTML', function(){ + equal(_('<div>Blah & "blah" & 'blah'</div>').unescapeHTML(), + '
Blah & "blah" & \'blah\'
'); + equal(_('&lt;').unescapeHTML(), '<'); + equal(_(''').unescapeHTML(), '\''); + equal(_(''').unescapeHTML(), '\''); + equal(_(''').unescapeHTML(), '\''); + equal(_('J').unescapeHTML(), 'J'); + equal(_('J').unescapeHTML(), 'J'); + equal(_('J').unescapeHTML(), 'J'); + equal(_('&_#39;').unescapeHTML(), '&_#39;'); + equal(_(''_;').unescapeHTML(), ''_;'); + equal(_('&#38;').unescapeHTML(), '&'); + equal(_('&amp;').unescapeHTML(), '&'); + equal(_('').unescapeHTML(), ''); + equal(_(null).unescapeHTML(), ''); + equal(_(undefined).unescapeHTML(), ''); + equal(_(5).unescapeHTML(), '5'); + // equal(_(undefined).unescapeHTML(), ''); + }); + + test('String: words', function() { + deepEqual(_('I love you!').words(), ['I', 'love', 'you!']); + deepEqual(_(' I love you! ').words(), ['I', 'love', 'you!']); + deepEqual(_('I_love_you!').words('_'), ['I', 'love', 'you!']); + deepEqual(_('I-love-you!').words(/-/), ['I', 'love', 'you!']); + deepEqual(_(123).words(), ['123'], '123 number has one word "123".'); + deepEqual(_(0).words(), ['0'], 'Zero number has one word "0".'); + deepEqual(_('').words(), [], 'Empty strings has no words.'); + deepEqual(_(' ').words(), [], 'Blank strings has no words.'); + deepEqual(_(null).words(), [], 'null has no words.'); + deepEqual(_(undefined).words(), [], 'undefined has no words.'); + }); + + test('String: chars', function() { + equal(_('Hello').chars().length, 5); + equal(_(123).chars().length, 3); + equal(_('').chars().length, 0); + equal(_(null).chars().length, 0); + equal(_(undefined).chars().length, 0); + }); + + test('String: swapCase', function(){ + equal(_('AaBbCcDdEe').swapCase(), 'aAbBcCdDeE'); + equal(_('Hello World').swapCase(), 'hELLO wORLD'); + equal(_('').swapCase(), ''); + equal(_(null).swapCase(), ''); + equal(_(undefined).swapCase(), ''); + }); + + test('String: lines', function() { + equal(_('Hello\nWorld').lines().length, 2); + equal(_('Hello World').lines().length, 1); + equal(_(123).lines().length, 1); + equal(_('').lines().length, 1); + equal(_(null).lines().length, 0); + equal(_(undefined).lines().length, 0); + }); + + test('String: pad', function() { + equal(_('1').pad(8), ' 1'); + equal(_(1).pad(8), ' 1'); + equal(_('1').pad(8, '0'), '00000001'); + equal(_('1').pad(8, '0', 'left'), '00000001'); + equal(_('1').pad(8, '0', 'right'), '10000000'); + equal(_('1').pad(8, '0', 'both'), '00001000'); + equal(_('foo').pad(8, '0', 'both'), '000foo00'); + equal(_('foo').pad(7, '0', 'both'), '00foo00'); + equal(_('foo').pad(7, '!@$%dofjrofj', 'both'), '!!foo!!'); + equal(_('').pad(2), ' '); + equal(_(null).pad(2), ' '); + equal(_(undefined).pad(2), ' '); + }); + + test('String: lpad', function() { + equal(_('1').lpad(8), ' 1'); + equal(_(1).lpad(8), ' 1'); + equal(_('1').lpad(8, '0'), '00000001'); + equal(_('1').lpad(8, '0', 'left'), '00000001'); + equal(_('').lpad(2), ' '); + equal(_(null).lpad(2), ' '); + equal(_(undefined).lpad(2), ' '); + }); + + test('String: rpad', function() { + equal(_('1').rpad(8), '1 '); + equal(_(1).lpad(8), ' 1'); + equal(_('1').rpad(8, '0'), '10000000'); + equal(_('foo').rpad(8, '0'), 'foo00000'); + equal(_('foo').rpad(7, '0'), 'foo0000'); + equal(_('').rpad(2), ' '); + equal(_(null).rpad(2), ' '); + equal(_(undefined).rpad(2), ' '); + }); + + test('String: lrpad', function() { + equal(_('1').lrpad(8), ' 1 '); + equal(_(1).lrpad(8), ' 1 '); + equal(_('1').lrpad(8, '0'), '00001000'); + equal(_('foo').lrpad(8, '0'), '000foo00'); + equal(_('foo').lrpad(7, '0'), '00foo00'); + equal(_('foo').lrpad(7, '!@$%dofjrofj'), '!!foo!!'); + equal(_('').lrpad(2), ' '); + equal(_(null).lrpad(2), ' '); + equal(_(undefined).lrpad(2), ' '); + }); + + test('String: toNumber', function() { + deepEqual(_('not a number').toNumber(), NaN); + equal(_(0).toNumber(), 0); + equal(_('0').toNumber(), 0); + equal(_('0.0').toNumber(), 0); + equal(_('0.1').toNumber(), 0); + equal(_('0.1').toNumber(1), 0.1); + equal(_(' 0.1 ').toNumber(1), 0.1); + equal(_('0000').toNumber(), 0); + equal(_('2.345').toNumber(), 2); + equal(_('2.345').toNumber(NaN), 2); + equal(_('2.345').toNumber(2), 2.35); + equal(_('2.344').toNumber(2), 2.34); + equal(_('2').toNumber(2), 2.00); + equal(_(2).toNumber(2), 2.00); + equal(_(-2).toNumber(), -2); + equal(_('-2').toNumber(), -2); + equal(_('').toNumber(), 0); + equal(_(null).toNumber(), 0); + equal(_(undefined).toNumber(), 0); + }); + + test('String: numberFormat', function() { + equal(_.numberFormat(9000), '9,000'); + equal(_.numberFormat(9000, 0), '9,000'); + equal(_.numberFormat(9000, 0, '', ''), '9000'); + equal(_.numberFormat(90000, 2), '90,000.00'); + equal(_.numberFormat(1000.754), '1,001'); + equal(_.numberFormat(1000.754, 2), '1,000.75'); + equal(_.numberFormat(1000.754, 0, ',', '.'), '1.001'); + equal(_.numberFormat(1000.754, 2, ',', '.'), '1.000,75'); + equal(_.numberFormat(1000000.754, 2, ',', '.'), '1.000.000,75'); + equal(_.numberFormat(1000000000), '1,000,000,000'); + equal(_.numberFormat(100000000), '100,000,000'); + equal(_.numberFormat('not number'), ''); + equal(_.numberFormat(), ''); + equal(_.numberFormat(null, '.', ','), ''); + equal(_.numberFormat(undefined, '.', ','), ''); + equal(_.numberFormat(new Number(5000)), '5,000'); + }); + + test('String: strRight', function() { + equal(_('This_is_a_test_string').strRight('_'), 'is_a_test_string'); + equal(_('This_is_a_test_string').strRight('string'), ''); + equal(_('This_is_a_test_string').strRight(), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strRight(''), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strRight('-'), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strRight(''), 'This_is_a_test_string'); + equal(_('').strRight('foo'), ''); + equal(_(null).strRight('foo'), ''); + equal(_(undefined).strRight('foo'), ''); + equal(_(12345).strRight(2), '345'); + }); + + test('String: strRightBack', function() { + equal(_('This_is_a_test_string').strRightBack('_'), 'string'); + equal(_('This_is_a_test_string').strRightBack('string'), ''); + equal(_('This_is_a_test_string').strRightBack(), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strRightBack(''), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strRightBack('-'), 'This_is_a_test_string'); + equal(_('').strRightBack('foo'), ''); + equal(_(null).strRightBack('foo'), ''); + equal(_(undefined).strRightBack('foo'), ''); + equal(_(12345).strRightBack(2), '345'); + }); + + test('String: strLeft', function() { + equal(_('This_is_a_test_string').strLeft('_'), 'This'); + equal(_('This_is_a_test_string').strLeft('This'), ''); + equal(_('This_is_a_test_string').strLeft(), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strLeft(''), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strLeft('-'), 'This_is_a_test_string'); + equal(_('').strLeft('foo'), ''); + equal(_(null).strLeft('foo'), ''); + equal(_(undefined).strLeft('foo'), ''); + equal(_(123454321).strLeft(3), '12'); + }); + + test('String: strLeftBack', function() { + equal(_('This_is_a_test_string').strLeftBack('_'), 'This_is_a_test'); + equal(_('This_is_a_test_string').strLeftBack('This'), ''); + equal(_('This_is_a_test_string').strLeftBack(), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strLeftBack(''), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strLeftBack('-'), 'This_is_a_test_string'); + equal(_('').strLeftBack('foo'), ''); + equal(_(null).strLeftBack('foo'), ''); + equal(_(undefined).strLeftBack('foo'), ''); + equal(_(123454321).strLeftBack(3), '123454'); + }); + + test('Strings: stripTags', function() { + equal(_('a
link').stripTags(), 'a link'); + equal(_('a link + + + + + + + + +

Underscore.string Test Suite

+

+

+
    +
    +

    Underscore.string Speed Suite

    + +
    + + diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_standalone.html b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_standalone.html new file mode 100644 index 0000000..9854c17 --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_standalone.html @@ -0,0 +1,18 @@ + + + + Underscore.strings Test Suite + + + + + + + + +

    Underscore.string Test Suite

    +

    +

    +
      + + diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/arrays.js b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/arrays.js new file mode 100644 index 0000000..32252a3 --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/arrays.js @@ -0,0 +1,200 @@ +$(document).ready(function() { + + module("Arrays"); + + test("first", function() { + equal(_.first([1,2,3]), 1, 'can pull out the first element of an array'); + equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"'); + equal(_.first([1,2,3], 0).join(', '), "", 'can pass an index to first'); + equal(_.first([1,2,3], 2).join(', '), '1, 2', 'can pass an index to first'); + equal(_.first([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to first'); + var result = (function(){ return _.first(arguments); })(4, 3, 2, 1); + equal(result, 4, 'works on an arguments object.'); + result = _.map([[1,2,3],[1,2,3]], _.first); + equal(result.join(','), '1,1', 'works well with _.map'); + result = (function() { return _.take([1,2,3], 2); })(); + equal(result.join(','), '1,2', 'aliased as take'); + + equal(_.first(null), undefined, 'handles nulls'); + }); + + test("rest", function() { + var numbers = [1, 2, 3, 4]; + equal(_.rest(numbers).join(", "), "2, 3, 4", 'working rest()'); + equal(_.rest(numbers, 0).join(", "), "1, 2, 3, 4", 'working rest(0)'); + equal(_.rest(numbers, 2).join(', '), '3, 4', 'rest can take an index'); + var result = (function(){ return _(arguments).tail(); })(1, 2, 3, 4); + equal(result.join(', '), '2, 3, 4', 'aliased as tail and works on arguments object'); + result = _.map([[1,2,3],[1,2,3]], _.rest); + equal(_.flatten(result).join(','), '2,3,2,3', 'works well with _.map'); + result = (function(){ return _(arguments).drop(); })(1, 2, 3, 4); + equal(result.join(', '), '2, 3, 4', 'aliased as drop and works on arguments object'); + }); + + test("initial", function() { + equal(_.initial([1,2,3,4,5]).join(", "), "1, 2, 3, 4", 'working initial()'); + equal(_.initial([1,2,3,4],2).join(", "), "1, 2", 'initial can take an index'); + var result = (function(){ return _(arguments).initial(); })(1, 2, 3, 4); + equal(result.join(", "), "1, 2, 3", 'initial works on arguments object'); + result = _.map([[1,2,3],[1,2,3]], _.initial); + equal(_.flatten(result).join(','), '1,2,1,2', 'initial works with _.map'); + }); + + test("last", function() { + equal(_.last([1,2,3]), 3, 'can pull out the last element of an array'); + equal(_.last([1,2,3], 0).join(', '), "", 'can pass an index to last'); + equal(_.last([1,2,3], 2).join(', '), '2, 3', 'can pass an index to last'); + equal(_.last([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to last'); + var result = (function(){ return _(arguments).last(); })(1, 2, 3, 4); + equal(result, 4, 'works on an arguments object'); + result = _.map([[1,2,3],[1,2,3]], _.last); + equal(result.join(','), '3,3', 'works well with _.map'); + + equal(_.last(null), undefined, 'handles nulls'); + }); + + test("compact", function() { + equal(_.compact([0, 1, false, 2, false, 3]).length, 3, 'can trim out all falsy values'); + var result = (function(){ return _(arguments).compact().length; })(0, 1, false, 2, false, 3); + equal(result, 3, 'works on an arguments object'); + }); + + test("flatten", function() { + if (window.JSON) { + var list = [1, [2], [3, [[[4]]]]]; + equal(JSON.stringify(_.flatten(list)), '[1,2,3,4]', 'can flatten nested arrays'); + equal(JSON.stringify(_.flatten(list, true)), '[1,2,3,[[[4]]]]', 'can shallowly flatten nested arrays'); + var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]); + equal(JSON.stringify(result), '[1,2,3,4]', 'works on an arguments object'); + } + }); + + test("without", function() { + var list = [1, 2, 1, 0, 3, 1, 4]; + equal(_.without(list, 0, 1).join(', '), '2, 3, 4', 'can remove all instances of an object'); + var result = (function(){ return _.without(arguments, 0, 1); })(1, 2, 1, 0, 3, 1, 4); + equal(result.join(', '), '2, 3, 4', 'works on an arguments object'); + + var list = [{one : 1}, {two : 2}]; + ok(_.without(list, {one : 1}).length == 2, 'uses real object identity for comparisons.'); + ok(_.without(list, list[0]).length == 1, 'ditto.'); + }); + + test("uniq", function() { + var list = [1, 2, 1, 3, 1, 4]; + equal(_.uniq(list).join(', '), '1, 2, 3, 4', 'can find the unique values of an unsorted array'); + + var list = [1, 1, 1, 2, 2, 3]; + equal(_.uniq(list, true).join(', '), '1, 2, 3', 'can find the unique values of a sorted array faster'); + + var list = [{name:'moe'}, {name:'curly'}, {name:'larry'}, {name:'curly'}]; + var iterator = function(value) { return value.name; }; + equal(_.map(_.uniq(list, false, iterator), iterator).join(', '), 'moe, curly, larry', 'can find the unique values of an array using a custom iterator'); + + var iterator = function(value) { return value +1; }; + var list = [1, 2, 2, 3, 4, 4]; + equal(_.uniq(list, true, iterator).join(', '), '1, 2, 3, 4', 'iterator works with sorted array'); + + var result = (function(){ return _.uniq(arguments); })(1, 2, 1, 3, 1, 4); + equal(result.join(', '), '1, 2, 3, 4', 'works on an arguments object'); + }); + + test("intersection", function() { + var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho']; + equal(_.intersection(stooges, leaders).join(''), 'moe', 'can take the set intersection of two arrays'); + equal(_(stooges).intersection(leaders).join(''), 'moe', 'can perform an OO-style intersection'); + var result = (function(){ return _.intersection(arguments, leaders); })('moe', 'curly', 'larry'); + equal(result.join(''), 'moe', 'works on an arguments object'); + }); + + test("union", function() { + var result = _.union([1, 2, 3], [2, 30, 1], [1, 40]); + equal(result.join(' '), '1 2 3 30 40', 'takes the union of a list of arrays'); + + var result = _.union([1, 2, 3], [2, 30, 1], [1, 40, [1]]); + equal(result.join(' '), '1 2 3 30 40 1', 'takes the union of a list of nested arrays'); + }); + + test("difference", function() { + var result = _.difference([1, 2, 3], [2, 30, 40]); + equal(result.join(' '), '1 3', 'takes the difference of two arrays'); + + var result = _.difference([1, 2, 3, 4], [2, 30, 40], [1, 11, 111]); + equal(result.join(' '), '3 4', 'takes the difference of three arrays'); + }); + + test('zip', function() { + var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true]; + var stooges = _.zip(names, ages, leaders); + equal(String(stooges), 'moe,30,true,larry,40,,curly,50,', 'zipped together arrays of different lengths'); + }); + + test('object', function() { + var result = _.object(['moe', 'larry', 'curly'], [30, 40, 50]); + var shouldBe = {moe: 30, larry: 40, curly: 50}; + ok(_.isEqual(result, shouldBe), 'two arrays zipped together into an object'); + + result = _.object([['one', 1], ['two', 2], ['three', 3]]); + shouldBe = {one: 1, two: 2, three: 3}; + ok(_.isEqual(result, shouldBe), 'an array of pairs zipped together into an object'); + + var stooges = {moe: 30, larry: 40, curly: 50}; + ok(_.isEqual(_.object(_.pairs(stooges)), stooges), 'an object converted to pairs and back to an object'); + + ok(_.isEqual(_.object(null), {}), 'handles nulls'); + }); + + test("indexOf", function() { + var numbers = [1, 2, 3]; + numbers.indexOf = null; + equal(_.indexOf(numbers, 2), 1, 'can compute indexOf, even without the native function'); + var result = (function(){ return _.indexOf(arguments, 2); })(1, 2, 3); + equal(result, 1, 'works on an arguments object'); + equal(_.indexOf(null, 2), -1, 'handles nulls properly'); + + var numbers = [10, 20, 30, 40, 50], num = 35; + var index = _.indexOf(numbers, num, true); + equal(index, -1, '35 is not in the list'); + + numbers = [10, 20, 30, 40, 50]; num = 40; + index = _.indexOf(numbers, num, true); + equal(index, 3, '40 is in the list'); + + numbers = [1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70]; num = 40; + index = _.indexOf(numbers, num, true); + equal(index, 1, '40 is in the list'); + + numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3]; + index = _.indexOf(numbers, 2, 5); + equal(index, 7, 'supports the fromIndex argument'); + }); + + test("lastIndexOf", function() { + var numbers = [1, 0, 1]; + equal(_.lastIndexOf(numbers, 1), 2); + + numbers = [1, 0, 1, 0, 0, 1, 0, 0, 0]; + numbers.lastIndexOf = null; + equal(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function'); + equal(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element'); + var result = (function(){ return _.lastIndexOf(arguments, 1); })(1, 0, 1, 0, 0, 1, 0, 0, 0); + equal(result, 5, 'works on an arguments object'); + equal(_.indexOf(null, 2), -1, 'handles nulls properly'); + + numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3]; + index = _.lastIndexOf(numbers, 2, 2); + equal(index, 1, 'supports the fromIndex argument'); + }); + + test("range", function() { + equal(_.range(0).join(''), '', 'range with 0 as a first argument generates an empty array'); + equal(_.range(4).join(' '), '0 1 2 3', 'range with a single positive argument generates an array of elements 0,1,2,...,n-1'); + equal(_.range(5, 8).join(' '), '5 6 7', 'range with two arguments a & b, a<b generates an array of elements a,a+1,a+2,...,b-2,b-1'); + equal(_.range(8, 5).join(''), '', 'range with two arguments a & b, b<a generates an empty array'); + equal(_.range(3, 10, 3).join(' '), '3 6 9', 'range with three arguments a & b & c, c < b-a, a < b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) < c'); + equal(_.range(3, 10, 15).join(''), '3', 'range with three arguments a & b & c, c > b-a, a < b generates an array with a single element, equal to a'); + equal(_.range(12, 7, -2).join(' '), '12 10 8', 'range with three arguments a & b & c, a > b, c < 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b'); + equal(_.range(0, -10, -1).join(' '), '0 -1 -2 -3 -4 -5 -6 -7 -8 -9', 'final example in the Python docs'); + }); + +}); diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/chaining.js b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/chaining.js new file mode 100644 index 0000000..16cf7bf --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/chaining.js @@ -0,0 +1,59 @@ +$(document).ready(function() { + + module("Chaining"); + + test("map/flatten/reduce", function() { + var lyrics = [ + "I'm a lumberjack and I'm okay", + "I sleep all night and I work all day", + "He's a lumberjack and he's okay", + "He sleeps all night and he works all day" + ]; + var counts = _(lyrics).chain() + .map(function(line) { return line.split(''); }) + .flatten() + .reduce(function(hash, l) { + hash[l] = hash[l] || 0; + hash[l]++; + return hash; + }, {}).value(); + ok(counts['a'] == 16 && counts['e'] == 10, 'counted all the letters in the song'); + }); + + test("select/reject/sortBy", function() { + var numbers = [1,2,3,4,5,6,7,8,9,10]; + numbers = _(numbers).chain().select(function(n) { + return n % 2 == 0; + }).reject(function(n) { + return n % 4 == 0; + }).sortBy(function(n) { + return -n; + }).value(); + equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers"); + }); + + test("select/reject/sortBy in functional style", function() { + var numbers = [1,2,3,4,5,6,7,8,9,10]; + numbers = _.chain(numbers).select(function(n) { + return n % 2 == 0; + }).reject(function(n) { + return n % 4 == 0; + }).sortBy(function(n) { + return -n; + }).value(); + equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers"); + }); + + test("reverse/concat/unshift/pop/map", function() { + var numbers = [1,2,3,4,5]; + numbers = _(numbers).chain() + .reverse() + .concat([5, 5, 5]) + .unshift(17) + .pop() + .map(function(n){ return n * 2; }) + .value(); + equal(numbers.join(', '), "34, 10, 8, 6, 4, 2, 10, 10", 'can chain together array functions.'); + }); + +}); diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/collections.js b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/collections.js new file mode 100644 index 0000000..e089626 --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/collections.js @@ -0,0 +1,426 @@ +$(document).ready(function() { + + module("Collections"); + + test("each", function() { + _.each([1, 2, 3], function(num, i) { + equal(num, i + 1, 'each iterators provide value and iteration count'); + }); + + var answers = []; + _.each([1, 2, 3], function(num){ answers.push(num * this.multiplier);}, {multiplier : 5}); + equal(answers.join(', '), '5, 10, 15', 'context object property accessed'); + + answers = []; + _.forEach([1, 2, 3], function(num){ answers.push(num); }); + equal(answers.join(', '), '1, 2, 3', 'aliased as "forEach"'); + + answers = []; + var obj = {one : 1, two : 2, three : 3}; + obj.constructor.prototype.four = 4; + _.each(obj, function(value, key){ answers.push(key); }); + equal(answers.join(", "), 'one, two, three', 'iterating over objects works, and ignores the object prototype.'); + delete obj.constructor.prototype.four; + + answer = null; + _.each([1, 2, 3], function(num, index, arr){ if (_.include(arr, num)) answer = true; }); + ok(answer, 'can reference the original collection from inside the iterator'); + + answers = 0; + _.each(null, function(){ ++answers; }); + equal(answers, 0, 'handles a null properly'); + }); + + test('map', function() { + var doubled = _.map([1, 2, 3], function(num){ return num * 2; }); + equal(doubled.join(', '), '2, 4, 6', 'doubled numbers'); + + doubled = _.collect([1, 2, 3], function(num){ return num * 2; }); + equal(doubled.join(', '), '2, 4, 6', 'aliased as "collect"'); + + var tripled = _.map([1, 2, 3], function(num){ return num * this.multiplier; }, {multiplier : 3}); + equal(tripled.join(', '), '3, 6, 9', 'tripled numbers with context'); + + var doubled = _([1, 2, 3]).map(function(num){ return num * 2; }); + equal(doubled.join(', '), '2, 4, 6', 'OO-style doubled numbers'); + + if (document.querySelectorAll) { + var ids = _.map(document.querySelectorAll('#map-test *'), function(n){ return n.id; }); + deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on NodeLists.'); + } + + var ids = _.map($('#map-test').children(), function(n){ return n.id; }); + deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on jQuery Array-likes.'); + + var ids = _.map(document.images, function(n){ return n.id; }); + ok(ids[0] == 'chart_image', 'can use collection methods on HTMLCollections'); + + var ifnull = _.map(null, function(){}); + ok(_.isArray(ifnull) && ifnull.length === 0, 'handles a null properly'); + }); + + test('reduce', function() { + var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }, 0); + equal(sum, 6, 'can sum up an array'); + + var context = {multiplier : 3}; + sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num * this.multiplier; }, 0, context); + equal(sum, 18, 'can reduce with a context object'); + + sum = _.inject([1, 2, 3], function(sum, num){ return sum + num; }, 0); + equal(sum, 6, 'aliased as "inject"'); + + sum = _([1, 2, 3]).reduce(function(sum, num){ return sum + num; }, 0); + equal(sum, 6, 'OO-style reduce'); + + var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }); + equal(sum, 6, 'default initial value'); + + var ifnull; + try { + _.reduce(null, function(){}); + } catch (ex) { + ifnull = ex; + } + ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly'); + + ok(_.reduce(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); + equal(_.reduce([], function(){}, undefined), undefined, 'undefined can be passed as a special case'); + raises(function() { _.reduce([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value'); + }); + + test('reduceRight', function() { + var list = _.reduceRight(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); + equal(list, 'bazbarfoo', 'can perform right folds'); + + var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); + equal(list, 'bazbarfoo', 'aliased as "foldr"'); + + var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }); + equal(list, 'bazbarfoo', 'default initial value'); + + var ifnull; + try { + _.reduceRight(null, function(){}); + } catch (ex) { + ifnull = ex; + } + ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly'); + + var sum = _.reduceRight({a: 1, b: 2, c: 3}, function(sum, num){ return sum + num; }); + equal(sum, 6, 'default initial value on object'); + + ok(_.reduceRight(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); + + equal(_.reduceRight([], function(){}, undefined), undefined, 'undefined can be passed as a special case'); + raises(function() { _.reduceRight([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value'); + + // Assert that the correct arguments are being passed. + + var args, + memo = {}, + object = {a: 1, b: 2}, + lastKey = _.keys(object).pop(); + + var expected = lastKey == 'a' + ? [memo, 1, 'a', object] + : [memo, 2, 'b', object]; + + _.reduceRight(object, function() { + args || (args = _.toArray(arguments)); + }, memo); + + deepEqual(args, expected); + + // And again, with numeric keys. + + object = {'2': 'a', '1': 'b'}; + lastKey = _.keys(object).pop(); + args = null; + + expected = lastKey == '2' + ? [memo, 'a', '2', object] + : [memo, 'b', '1', object]; + + _.reduceRight(object, function() { + args || (args = _.toArray(arguments)); + }, memo); + + deepEqual(args, expected); + }); + + test('find', function() { + var array = [1, 2, 3, 4]; + strictEqual(_.find(array, function(n) { return n > 2; }), 3, 'should return first found `value`'); + strictEqual(_.find(array, function() { return false; }), void 0, 'should return `undefined` if `value` is not found'); + }); + + test('detect', function() { + var result = _.detect([1, 2, 3], function(num){ return num * 2 == 4; }); + equal(result, 2, 'found the first "2" and broke the loop'); + }); + + test('select', function() { + var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); + equal(evens.join(', '), '2, 4, 6', 'selected each even number'); + + evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); + equal(evens.join(', '), '2, 4, 6', 'aliased as "filter"'); + }); + + test('reject', function() { + var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); + equal(odds.join(', '), '1, 3, 5', 'rejected each even number'); + + var context = "obj"; + + var evens = _.reject([1, 2, 3, 4, 5, 6], function(num){ + equal(context, "obj"); + return num % 2 != 0; + }, context); + equal(evens.join(', '), '2, 4, 6', 'rejected each odd number'); + }); + + test('all', function() { + ok(_.all([], _.identity), 'the empty set'); + ok(_.all([true, true, true], _.identity), 'all true values'); + ok(!_.all([true, false, true], _.identity), 'one false value'); + ok(_.all([0, 10, 28], function(num){ return num % 2 == 0; }), 'even numbers'); + ok(!_.all([0, 11, 28], function(num){ return num % 2 == 0; }), 'an odd number'); + ok(_.all([1], _.identity) === true, 'cast to boolean - true'); + ok(_.all([0], _.identity) === false, 'cast to boolean - false'); + ok(_.every([true, true, true], _.identity), 'aliased as "every"'); + ok(!_.all([undefined, undefined, undefined], _.identity), 'works with arrays of undefined'); + }); + + test('any', function() { + var nativeSome = Array.prototype.some; + Array.prototype.some = null; + ok(!_.any([]), 'the empty set'); + ok(!_.any([false, false, false]), 'all false values'); + ok(_.any([false, false, true]), 'one true value'); + ok(_.any([null, 0, 'yes', false]), 'a string'); + ok(!_.any([null, 0, '', false]), 'falsy values'); + ok(!_.any([1, 11, 29], function(num){ return num % 2 == 0; }), 'all odd numbers'); + ok(_.any([1, 10, 29], function(num){ return num % 2 == 0; }), 'an even number'); + ok(_.any([1], _.identity) === true, 'cast to boolean - true'); + ok(_.any([0], _.identity) === false, 'cast to boolean - false'); + ok(_.some([false, false, true]), 'aliased as "some"'); + Array.prototype.some = nativeSome; + }); + + test('include', function() { + ok(_.include([1,2,3], 2), 'two is in the array'); + ok(!_.include([1,3,9], 2), 'two is not in the array'); + ok(_.contains({moe:1, larry:3, curly:9}, 3) === true, '_.include on objects checks their values'); + ok(_([1,2,3]).include(2), 'OO-style include'); + }); + + test('invoke', function() { + var list = [[5, 1, 7], [3, 2, 1]]; + var result = _.invoke(list, 'sort'); + equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); + equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); + }); + + test('invoke w/ function reference', function() { + var list = [[5, 1, 7], [3, 2, 1]]; + var result = _.invoke(list, Array.prototype.sort); + equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); + equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); + }); + + // Relevant when using ClojureScript + test('invoke when strings have a call method', function() { + String.prototype.call = function() { + return 42; + }; + var list = [[5, 1, 7], [3, 2, 1]]; + var s = "foo"; + equal(s.call(), 42, "call function exists"); + var result = _.invoke(list, 'sort'); + equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); + equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); + delete String.prototype.call; + equal(s.call, undefined, "call function removed"); + }); + + test('pluck', function() { + var people = [{name : 'moe', age : 30}, {name : 'curly', age : 50}]; + equal(_.pluck(people, 'name').join(', '), 'moe, curly', 'pulls names out of objects'); + }); + + test('where', function() { + var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}]; + var result = _.where(list, {a: 1}); + equal(result.length, 3); + equal(result[result.length - 1].b, 4); + result = _.where(list, {b: 2}); + equal(result.length, 2); + equal(result[0].a, 1); + }); + + test('max', function() { + equal(3, _.max([1, 2, 3]), 'can perform a regular Math.max'); + + var neg = _.max([1, 2, 3], function(num){ return -num; }); + equal(neg, 1, 'can perform a computation-based max'); + + equal(-Infinity, _.max({}), 'Maximum value of an empty object'); + equal(-Infinity, _.max([]), 'Maximum value of an empty array'); + + equal(299999, _.max(_.range(1,300000)), "Maximum value of a too-big array"); + }); + + test('min', function() { + equal(1, _.min([1, 2, 3]), 'can perform a regular Math.min'); + + var neg = _.min([1, 2, 3], function(num){ return -num; }); + equal(neg, 3, 'can perform a computation-based min'); + + equal(Infinity, _.min({}), 'Minimum value of an empty object'); + equal(Infinity, _.min([]), 'Minimum value of an empty array'); + + var now = new Date(9999999999); + var then = new Date(0); + equal(_.min([now, then]), then); + + equal(1, _.min(_.range(1,300000)), "Minimum value of a too-big array"); + }); + + test('sortBy', function() { + var people = [{name : 'curly', age : 50}, {name : 'moe', age : 30}]; + people = _.sortBy(people, function(person){ return person.age; }); + equal(_.pluck(people, 'name').join(', '), 'moe, curly', 'stooges sorted by age'); + + var list = [undefined, 4, 1, undefined, 3, 2]; + equal(_.sortBy(list, _.identity).join(','), '1,2,3,4,,', 'sortBy with undefined values'); + + var list = ["one", "two", "three", "four", "five"]; + var sorted = _.sortBy(list, 'length'); + equal(sorted.join(' '), 'one two four five three', 'sorted by length'); + + function Pair(x, y) { + this.x = x; + this.y = y; + } + + var collection = [ + new Pair(1, 1), new Pair(1, 2), + new Pair(1, 3), new Pair(1, 4), + new Pair(1, 5), new Pair(1, 6), + new Pair(2, 1), new Pair(2, 2), + new Pair(2, 3), new Pair(2, 4), + new Pair(2, 5), new Pair(2, 6), + new Pair(undefined, 1), new Pair(undefined, 2), + new Pair(undefined, 3), new Pair(undefined, 4), + new Pair(undefined, 5), new Pair(undefined, 6) + ]; + + var actual = _.sortBy(collection, function(pair) { + return pair.x; + }); + + deepEqual(actual, collection, 'sortBy should be stable'); + }); + + test('groupBy', function() { + var parity = _.groupBy([1, 2, 3, 4, 5, 6], function(num){ return num % 2; }); + ok('0' in parity && '1' in parity, 'created a group for each value'); + equal(parity[0].join(', '), '2, 4, 6', 'put each even number in the right group'); + + var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]; + var grouped = _.groupBy(list, 'length'); + equal(grouped['3'].join(' '), 'one two six ten'); + equal(grouped['4'].join(' '), 'four five nine'); + equal(grouped['5'].join(' '), 'three seven eight'); + + var context = {}; + _.groupBy([{}], function(){ ok(this === context); }, context); + + grouped = _.groupBy([4.2, 6.1, 6.4], function(num) { + return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor'; + }); + equal(grouped.constructor.length, 1); + equal(grouped.hasOwnProperty.length, 2); + + var array = [{}]; + _.groupBy(array, function(value, index, obj){ ok(obj === array); }); + }); + + test('countBy', function() { + var parity = _.countBy([1, 2, 3, 4, 5], function(num){ return num % 2 == 0; }); + equal(parity['true'], 2); + equal(parity['false'], 3); + + var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]; + var grouped = _.countBy(list, 'length'); + equal(grouped['3'], 4); + equal(grouped['4'], 3); + equal(grouped['5'], 3); + + var context = {}; + _.countBy([{}], function(){ ok(this === context); }, context); + + grouped = _.countBy([4.2, 6.1, 6.4], function(num) { + return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor'; + }); + equal(grouped.constructor, 1); + equal(grouped.hasOwnProperty, 2); + + var array = [{}]; + _.countBy(array, function(value, index, obj){ ok(obj === array); }); + }); + + test('sortedIndex', function() { + var numbers = [10, 20, 30, 40, 50], num = 35; + var indexForNum = _.sortedIndex(numbers, num); + equal(indexForNum, 3, '35 should be inserted at index 3'); + + var indexFor30 = _.sortedIndex(numbers, 30); + equal(indexFor30, 2, '30 should be inserted at index 2'); + + var objects = [{x: 10}, {x: 20}, {x: 30}, {x: 40}]; + var iterator = function(obj){ return obj.x; }; + strictEqual(_.sortedIndex(objects, {x: 25}, iterator), 2); + strictEqual(_.sortedIndex(objects, {x: 35}, 'x'), 3); + + var context = {1: 2, 2: 3, 3: 4}; + iterator = function(obj){ return this[obj]; }; + strictEqual(_.sortedIndex([1, 3], 2, iterator, context), 1); + }); + + test('shuffle', function() { + var numbers = _.range(10); + var shuffled = _.shuffle(numbers).sort(); + notStrictEqual(numbers, shuffled, 'original object is unmodified'); + equal(shuffled.join(','), numbers.join(','), 'contains the same members before and after shuffle'); + }); + + test('toArray', function() { + ok(!_.isArray(arguments), 'arguments object is not an array'); + ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array'); + var a = [1,2,3]; + ok(_.toArray(a) !== a, 'array is cloned'); + equal(_.toArray(a).join(', '), '1, 2, 3', 'cloned array contains same elements'); + + var numbers = _.toArray({one : 1, two : 2, three : 3}); + equal(numbers.join(', '), '1, 2, 3', 'object flattened into array'); + }); + + test('size', function() { + equal(_.size({one : 1, two : 2, three : 3}), 3, 'can compute the size of an object'); + equal(_.size([1, 2, 3]), 3, 'can compute the size of an array'); + + var func = function() { + return _.size(arguments); + }; + + equal(func(1, 2, 3, 4), 4, 'can test the size of the arguments object'); + + equal(_.size('hello'), 5, 'can compute the size of a string'); + + equal(_.size(null), 0, 'handles nulls'); + }); + +}); diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/functions.js b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/functions.js new file mode 100644 index 0000000..a529658 --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/functions.js @@ -0,0 +1,259 @@ +$(document).ready(function() { + + module("Functions"); + + test("bind", function() { + var context = {name : 'moe'}; + var func = function(arg) { return "name: " + (this.name || arg); }; + var bound = _.bind(func, context); + equal(bound(), 'name: moe', 'can bind a function to a context'); + + bound = _(func).bind(context); + equal(bound(), 'name: moe', 'can do OO-style binding'); + + bound = _.bind(func, null, 'curly'); + equal(bound(), 'name: curly', 'can bind without specifying a context'); + + func = function(salutation, name) { return salutation + ': ' + name; }; + func = _.bind(func, this, 'hello'); + equal(func('moe'), 'hello: moe', 'the function was partially applied in advance'); + + var func = _.bind(func, this, 'curly'); + equal(func(), 'hello: curly', 'the function was completely applied in advance'); + + var func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; }; + func = _.bind(func, this, 'hello', 'moe', 'curly'); + equal(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments'); + + func = function(context, message) { equal(this, context, message); }; + _.bind(func, 0, 0, 'can bind a function to `0`')(); + _.bind(func, '', '', 'can bind a function to an empty string')(); + _.bind(func, false, false, 'can bind a function to `false`')(); + + // These tests are only meaningful when using a browser without a native bind function + // To test this with a modern browser, set underscore's nativeBind to undefined + var F = function () { return this; }; + var Boundf = _.bind(F, {hello: "moe curly"}); + equal(new Boundf().hello, undefined, "function should not be bound to the context, to comply with ECMAScript 5"); + equal(Boundf().hello, "moe curly", "When called without the new operator, it's OK to be bound to the context"); + }); + + test("bindAll", function() { + var curly = {name : 'curly'}, moe = { + name : 'moe', + getName : function() { return 'name: ' + this.name; }, + sayHi : function() { return 'hi: ' + this.name; } + }; + curly.getName = moe.getName; + _.bindAll(moe, 'getName', 'sayHi'); + curly.sayHi = moe.sayHi; + equal(curly.getName(), 'name: curly', 'unbound function is bound to current object'); + equal(curly.sayHi(), 'hi: moe', 'bound function is still bound to original object'); + + curly = {name : 'curly'}; + moe = { + name : 'moe', + getName : function() { return 'name: ' + this.name; }, + sayHi : function() { return 'hi: ' + this.name; } + }; + _.bindAll(moe); + curly.sayHi = moe.sayHi; + equal(curly.sayHi(), 'hi: moe', 'calling bindAll with no arguments binds all functions to the object'); + }); + + test("memoize", function() { + var fib = function(n) { + return n < 2 ? n : fib(n - 1) + fib(n - 2); + }; + var fastFib = _.memoize(fib); + equal(fib(10), 55, 'a memoized version of fibonacci produces identical results'); + equal(fastFib(10), 55, 'a memoized version of fibonacci produces identical results'); + + var o = function(str) { + return str; + }; + var fastO = _.memoize(o); + equal(o('toString'), 'toString', 'checks hasOwnProperty'); + equal(fastO('toString'), 'toString', 'checks hasOwnProperty'); + }); + + asyncTest("delay", 2, function() { + var delayed = false; + _.delay(function(){ delayed = true; }, 100); + setTimeout(function(){ ok(!delayed, "didn't delay the function quite yet"); }, 50); + setTimeout(function(){ ok(delayed, 'delayed the function'); start(); }, 150); + }); + + asyncTest("defer", 1, function() { + var deferred = false; + _.defer(function(bool){ deferred = bool; }, true); + _.delay(function(){ ok(deferred, "deferred the function"); start(); }, 50); + }); + + asyncTest("throttle", 2, function() { + var counter = 0; + var incr = function(){ counter++; }; + var throttledIncr = _.throttle(incr, 100); + throttledIncr(); throttledIncr(); throttledIncr(); + setTimeout(throttledIncr, 70); + setTimeout(throttledIncr, 120); + setTimeout(throttledIncr, 140); + setTimeout(throttledIncr, 190); + setTimeout(throttledIncr, 220); + setTimeout(throttledIncr, 240); + _.delay(function(){ equal(counter, 1, "incr was called immediately"); }, 30); + _.delay(function(){ equal(counter, 4, "incr was throttled"); start(); }, 400); + }); + + asyncTest("throttle arguments", 2, function() { + var value = 0; + var update = function(val){ value = val; }; + var throttledUpdate = _.throttle(update, 100); + throttledUpdate(1); throttledUpdate(2); throttledUpdate(3); + setTimeout(function(){ throttledUpdate(4); }, 120); + setTimeout(function(){ throttledUpdate(5); }, 140); + setTimeout(function(){ throttledUpdate(6); }, 250); + _.delay(function(){ equal(value, 1, "updated to latest value"); }, 40); + _.delay(function(){ equal(value, 6, "updated to latest value"); start(); }, 400); + }); + + asyncTest("throttle once", 2, function() { + var counter = 0; + var incr = function(){ return ++counter; }; + var throttledIncr = _.throttle(incr, 100); + var result = throttledIncr(); + _.delay(function(){ + equal(result, 1, "throttled functions return their value"); + equal(counter, 1, "incr was called once"); start(); + }, 220); + }); + + asyncTest("throttle twice", 1, function() { + var counter = 0; + var incr = function(){ counter++; }; + var throttledIncr = _.throttle(incr, 100); + throttledIncr(); throttledIncr(); + _.delay(function(){ equal(counter, 2, "incr was called twice"); start(); }, 220); + }); + + asyncTest("throttle repeatedly with results", 9, function() { + var counter = 0; + var incr = function(){ return ++counter; }; + var throttledIncr = _.throttle(incr, 100); + var results = []; + var saveResult = function() { results.push(throttledIncr()); }; + saveResult(); saveResult(); saveResult(); + setTimeout(saveResult, 70); + setTimeout(saveResult, 120); + setTimeout(saveResult, 140); + setTimeout(saveResult, 190); + setTimeout(saveResult, 240); + setTimeout(saveResult, 260); + _.delay(function() { + equal(results[0], 1, "incr was called once"); + equal(results[1], 1, "incr was throttled"); + equal(results[2], 1, "incr was throttled"); + equal(results[3], 1, "incr was throttled"); + equal(results[4], 2, "incr was called twice"); + equal(results[5], 2, "incr was throttled"); + equal(results[6], 2, "incr was throttled"); + equal(results[7], 3, "incr was called thrice"); + equal(results[8], 3, "incr was throttled"); + start(); + }, 400); + }); + + asyncTest("debounce", 1, function() { + var counter = 0; + var incr = function(){ counter++; }; + var debouncedIncr = _.debounce(incr, 50); + debouncedIncr(); debouncedIncr(); debouncedIncr(); + setTimeout(debouncedIncr, 30); + setTimeout(debouncedIncr, 60); + setTimeout(debouncedIncr, 90); + setTimeout(debouncedIncr, 120); + setTimeout(debouncedIncr, 150); + _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220); + }); + + asyncTest("debounce asap", 5, function() { + var a, b, c; + var counter = 0; + var incr = function(){ return ++counter; }; + var debouncedIncr = _.debounce(incr, 50, true); + a = debouncedIncr(); + b = debouncedIncr(); + c = debouncedIncr(); + equal(a, 1); + equal(b, 1); + equal(c, 1); + equal(counter, 1, 'incr was called immediately'); + setTimeout(debouncedIncr, 30); + setTimeout(debouncedIncr, 60); + setTimeout(debouncedIncr, 90); + setTimeout(debouncedIncr, 120); + setTimeout(debouncedIncr, 150); + _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220); + }); + + asyncTest("debounce asap recursively", 2, function() { + var counter = 0; + var debouncedIncr = _.debounce(function(){ + counter++; + if (counter < 5) debouncedIncr(); + }, 50, true); + debouncedIncr(); + equal(counter, 1, 'incr was called immediately'); + _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 70); + }); + + test("once", function() { + var num = 0; + var increment = _.once(function(){ num++; }); + increment(); + increment(); + equal(num, 1); + }); + + test("wrap", function() { + var greet = function(name){ return "hi: " + name; }; + var backwards = _.wrap(greet, function(func, name){ return func(name) + ' ' + name.split('').reverse().join(''); }); + equal(backwards('moe'), 'hi: moe eom', 'wrapped the saluation function'); + + var inner = function(){ return "Hello "; }; + var obj = {name : "Moe"}; + obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; }); + equal(obj.hi(), "Hello Moe"); + + var noop = function(){}; + var wrapped = _.wrap(noop, function(fn){ return Array.prototype.slice.call(arguments, 0); }); + var ret = wrapped(['whats', 'your'], 'vector', 'victor'); + deepEqual(ret, [noop, ['whats', 'your'], 'vector', 'victor']); + }); + + test("compose", function() { + var greet = function(name){ return "hi: " + name; }; + var exclaim = function(sentence){ return sentence + '!'; }; + var composed = _.compose(exclaim, greet); + equal(composed('moe'), 'hi: moe!', 'can compose a function that takes another'); + + composed = _.compose(greet, exclaim); + equal(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative'); + }); + + test("after", function() { + var testAfter = function(afterAmount, timesCalled) { + var afterCalled = 0; + var after = _.after(afterAmount, function() { + afterCalled++; + }); + while (timesCalled--) after(); + return afterCalled; + }; + + equal(testAfter(5, 5), 1, "after(N) should fire after being called N times"); + equal(testAfter(5, 4), 0, "after(N) should not fire unless called N times"); + equal(testAfter(0, 0), 1, "after(0) should fire immediately"); + }); + +}); diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/index.html b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/index.html new file mode 100644 index 0000000..064fa98 --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/index.html @@ -0,0 +1,45 @@ + + + + Underscore Test Suite + + + + + + + + + + + + + + + + +
      +
      +
      +
      +
      +
      +
      +
      +

      Underscore Speed Suite

      +

      + A representative sample of the functions are benchmarked here, to provide + a sense of how fast they might run in different browsers. + Each iteration runs on an array of 1000 elements.

      + For example, the 'intersection' test measures the number of times you can + find the intersection of two thousand-element arrays in one second. +

      +
      + + + diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/objects.js b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/objects.js new file mode 100644 index 0000000..22949c3 --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/objects.js @@ -0,0 +1,548 @@ +$(document).ready(function() { + + module("Objects"); + + test("keys", function() { + equal(_.keys({one : 1, two : 2}).join(', '), 'one, two', 'can extract the keys from an object'); + // the test above is not safe because it relies on for-in enumeration order + var a = []; a[1] = 0; + equal(_.keys(a).join(', '), '1', 'is not fooled by sparse arrays; see issue #95'); + raises(function() { _.keys(null); }, TypeError, 'throws an error for `null` values'); + raises(function() { _.keys(void 0); }, TypeError, 'throws an error for `undefined` values'); + raises(function() { _.keys(1); }, TypeError, 'throws an error for number primitives'); + raises(function() { _.keys('a'); }, TypeError, 'throws an error for string primitives'); + raises(function() { _.keys(true); }, TypeError, 'throws an error for boolean primitives'); + }); + + test("values", function() { + equal(_.values({one: 1, two: 2}).join(', '), '1, 2', 'can extract the values from an object'); + equal(_.values({one: 1, two: 2, length: 3}).join(', '), '1, 2, 3', '... even when one of them is "length"'); + }); + + test("pairs", function() { + deepEqual(_.pairs({one: 1, two: 2}), [['one', 1], ['two', 2]], 'can convert an object into pairs'); + deepEqual(_.pairs({one: 1, two: 2, length: 3}), [['one', 1], ['two', 2], ['length', 3]], '... even when one of them is "length"'); + }); + + test("invert", function() { + var obj = {first: 'Moe', second: 'Larry', third: 'Curly'}; + equal(_.keys(_.invert(obj)).join(' '), 'Moe Larry Curly', 'can invert an object'); + ok(_.isEqual(_.invert(_.invert(obj)), obj), 'two inverts gets you back where you started'); + + var obj = {length: 3}; + ok(_.invert(obj)['3'] == 'length', 'can invert an object with "length"') + }); + + test("functions", function() { + var obj = {a : 'dash', b : _.map, c : (/yo/), d : _.reduce}; + ok(_.isEqual(['b', 'd'], _.functions(obj)), 'can grab the function names of any passed-in object'); + + var Animal = function(){}; + Animal.prototype.run = function(){}; + equal(_.functions(new Animal).join(''), 'run', 'also looks up functions on the prototype'); + }); + + test("extend", function() { + var result; + equal(_.extend({}, {a:'b'}).a, 'b', 'can extend an object with the attributes of another'); + equal(_.extend({a:'x'}, {a:'b'}).a, 'b', 'properties in source override destination'); + equal(_.extend({x:'x'}, {a:'b'}).x, 'x', 'properties not in source dont get overriden'); + result = _.extend({x:'x'}, {a:'a'}, {b:'b'}); + ok(_.isEqual(result, {x:'x', a:'a', b:'b'}), 'can extend from multiple source objects'); + result = _.extend({x:'x'}, {a:'a', x:2}, {a:'b'}); + ok(_.isEqual(result, {x:2, a:'b'}), 'extending from multiple source objects last property trumps'); + result = _.extend({}, {a: void 0, b: null}); + equal(_.keys(result).join(''), 'ab', 'extend does not copy undefined values'); + }); + + test("pick", function() { + var result; + result = _.pick({a:1, b:2, c:3}, 'a', 'c'); + ok(_.isEqual(result, {a:1, c:3}), 'can restrict properties to those named'); + result = _.pick({a:1, b:2, c:3}, ['b', 'c']); + ok(_.isEqual(result, {b:2, c:3}), 'can restrict properties to those named in an array'); + result = _.pick({a:1, b:2, c:3}, ['a'], 'b'); + ok(_.isEqual(result, {a:1, b:2}), 'can restrict properties to those named in mixed args'); + + var Obj = function(){}; + Obj.prototype = {a: 1, b: 2, c: 3}; + ok(_.isEqual(_.pick(new Obj, 'a', 'c'), {a:1, c: 3}), 'include prototype props'); + }); + + test("omit", function() { + var result; + result = _.omit({a:1, b:2, c:3}, 'b'); + ok(_.isEqual(result, {a:1, c:3}), 'can omit a single named property'); + result = _.omit({a:1, b:2, c:3}, 'a', 'c'); + ok(_.isEqual(result, {b:2}), 'can omit several named properties'); + result = _.omit({a:1, b:2, c:3}, ['b', 'c']); + ok(_.isEqual(result, {a:1}), 'can omit properties named in an array'); + + var Obj = function(){}; + Obj.prototype = {a: 1, b: 2, c: 3}; + ok(_.isEqual(_.omit(new Obj, 'b'), {a:1, c: 3}), 'include prototype props'); + }); + + test("defaults", function() { + var result; + var options = {zero: 0, one: 1, empty: "", nan: NaN, string: "string"}; + + _.defaults(options, {zero: 1, one: 10, twenty: 20}); + equal(options.zero, 0, 'value exists'); + equal(options.one, 1, 'value exists'); + equal(options.twenty, 20, 'default applied'); + + _.defaults(options, {empty: "full"}, {nan: "nan"}, {word: "word"}, {word: "dog"}); + equal(options.empty, "", 'value exists'); + ok(_.isNaN(options.nan), "NaN isn't overridden"); + equal(options.word, "word", 'new value is added, first one wins'); + }); + + test("clone", function() { + var moe = {name : 'moe', lucky : [13, 27, 34]}; + var clone = _.clone(moe); + equal(clone.name, 'moe', 'the clone as the attributes of the original'); + + clone.name = 'curly'; + ok(clone.name == 'curly' && moe.name == 'moe', 'clones can change shallow attributes without affecting the original'); + + clone.lucky.push(101); + equal(_.last(moe.lucky), 101, 'changes to deep attributes are shared with the original'); + + equal(_.clone(undefined), void 0, 'non objects should not be changed by clone'); + equal(_.clone(1), 1, 'non objects should not be changed by clone'); + equal(_.clone(null), null, 'non objects should not be changed by clone'); + }); + + test("isEqual", function() { + function First() { + this.value = 1; + } + First.prototype.value = 1; + function Second() { + this.value = 1; + } + Second.prototype.value = 2; + + // Basic equality and identity comparisons. + ok(_.isEqual(null, null), "`null` is equal to `null`"); + ok(_.isEqual(), "`undefined` is equal to `undefined`"); + + ok(!_.isEqual(0, -0), "`0` is not equal to `-0`"); + ok(!_.isEqual(-0, 0), "Commutative equality is implemented for `0` and `-0`"); + ok(!_.isEqual(null, undefined), "`null` is not equal to `undefined`"); + ok(!_.isEqual(undefined, null), "Commutative equality is implemented for `null` and `undefined`"); + + // String object and primitive comparisons. + ok(_.isEqual("Curly", "Curly"), "Identical string primitives are equal"); + ok(_.isEqual(new String("Curly"), new String("Curly")), "String objects with identical primitive values are equal"); + ok(_.isEqual(new String("Curly"), "Curly"), "String primitives and their corresponding object wrappers are equal"); + ok(_.isEqual("Curly", new String("Curly")), "Commutative equality is implemented for string objects and primitives"); + + ok(!_.isEqual("Curly", "Larry"), "String primitives with different values are not equal"); + ok(!_.isEqual(new String("Curly"), new String("Larry")), "String objects with different primitive values are not equal"); + ok(!_.isEqual(new String("Curly"), {toString: function(){ return "Curly"; }}), "String objects and objects with a custom `toString` method are not equal"); + + // Number object and primitive comparisons. + ok(_.isEqual(75, 75), "Identical number primitives are equal"); + ok(_.isEqual(new Number(75), new Number(75)), "Number objects with identical primitive values are equal"); + ok(_.isEqual(75, new Number(75)), "Number primitives and their corresponding object wrappers are equal"); + ok(_.isEqual(new Number(75), 75), "Commutative equality is implemented for number objects and primitives"); + ok(!_.isEqual(new Number(0), -0), "`new Number(0)` and `-0` are not equal"); + ok(!_.isEqual(0, new Number(-0)), "Commutative equality is implemented for `new Number(0)` and `-0`"); + + ok(!_.isEqual(new Number(75), new Number(63)), "Number objects with different primitive values are not equal"); + ok(!_.isEqual(new Number(63), {valueOf: function(){ return 63; }}), "Number objects and objects with a `valueOf` method are not equal"); + + // Comparisons involving `NaN`. + ok(_.isEqual(NaN, NaN), "`NaN` is equal to `NaN`"); + ok(!_.isEqual(61, NaN), "A number primitive is not equal to `NaN`"); + ok(!_.isEqual(new Number(79), NaN), "A number object is not equal to `NaN`"); + ok(!_.isEqual(Infinity, NaN), "`Infinity` is not equal to `NaN`"); + + // Boolean object and primitive comparisons. + ok(_.isEqual(true, true), "Identical boolean primitives are equal"); + ok(_.isEqual(new Boolean, new Boolean), "Boolean objects with identical primitive values are equal"); + ok(_.isEqual(true, new Boolean(true)), "Boolean primitives and their corresponding object wrappers are equal"); + ok(_.isEqual(new Boolean(true), true), "Commutative equality is implemented for booleans"); + ok(!_.isEqual(new Boolean(true), new Boolean), "Boolean objects with different primitive values are not equal"); + + // Common type coercions. + ok(!_.isEqual(true, new Boolean(false)), "Boolean objects are not equal to the boolean primitive `true`"); + ok(!_.isEqual("75", 75), "String and number primitives with like values are not equal"); + ok(!_.isEqual(new Number(63), new String(63)), "String and number objects with like values are not equal"); + ok(!_.isEqual(75, "75"), "Commutative equality is implemented for like string and number values"); + ok(!_.isEqual(0, ""), "Number and string primitives with like values are not equal"); + ok(!_.isEqual(1, true), "Number and boolean primitives with like values are not equal"); + ok(!_.isEqual(new Boolean(false), new Number(0)), "Boolean and number objects with like values are not equal"); + ok(!_.isEqual(false, new String("")), "Boolean primitives and string objects with like values are not equal"); + ok(!_.isEqual(12564504e5, new Date(2009, 9, 25)), "Dates and their corresponding numeric primitive values are not equal"); + + // Dates. + ok(_.isEqual(new Date(2009, 9, 25), new Date(2009, 9, 25)), "Date objects referencing identical times are equal"); + ok(!_.isEqual(new Date(2009, 9, 25), new Date(2009, 11, 13)), "Date objects referencing different times are not equal"); + ok(!_.isEqual(new Date(2009, 11, 13), { + getTime: function(){ + return 12606876e5; + } + }), "Date objects and objects with a `getTime` method are not equal"); + ok(!_.isEqual(new Date("Curly"), new Date("Curly")), "Invalid dates are not equal"); + + // Functions. + ok(!_.isEqual(First, Second), "Different functions with identical bodies and source code representations are not equal"); + + // RegExps. + ok(_.isEqual(/(?:)/gim, /(?:)/gim), "RegExps with equivalent patterns and flags are equal"); + ok(!_.isEqual(/(?:)/g, /(?:)/gi), "RegExps with equivalent patterns and different flags are not equal"); + ok(!_.isEqual(/Moe/gim, /Curly/gim), "RegExps with different patterns and equivalent flags are not equal"); + ok(!_.isEqual(/(?:)/gi, /(?:)/g), "Commutative equality is implemented for RegExps"); + ok(!_.isEqual(/Curly/g, {source: "Larry", global: true, ignoreCase: false, multiline: false}), "RegExps and RegExp-like objects are not equal"); + + // Empty arrays, array-like objects, and object literals. + ok(_.isEqual({}, {}), "Empty object literals are equal"); + ok(_.isEqual([], []), "Empty array literals are equal"); + ok(_.isEqual([{}], [{}]), "Empty nested arrays and objects are equal"); + ok(!_.isEqual({length: 0}, []), "Array-like objects and arrays are not equal."); + ok(!_.isEqual([], {length: 0}), "Commutative equality is implemented for array-like objects"); + + ok(!_.isEqual({}, []), "Object literals and array literals are not equal"); + ok(!_.isEqual([], {}), "Commutative equality is implemented for objects and arrays"); + + // Arrays with primitive and object values. + ok(_.isEqual([1, "Larry", true], [1, "Larry", true]), "Arrays containing identical primitives are equal"); + ok(_.isEqual([(/Moe/g), new Date(2009, 9, 25)], [(/Moe/g), new Date(2009, 9, 25)]), "Arrays containing equivalent elements are equal"); + + // Multi-dimensional arrays. + var a = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; + var b = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; + ok(_.isEqual(a, b), "Arrays containing nested arrays and objects are recursively compared"); + + // Overwrite the methods defined in ES 5.1 section 15.4.4. + a.forEach = a.map = a.filter = a.every = a.indexOf = a.lastIndexOf = a.some = a.reduce = a.reduceRight = null; + b.join = b.pop = b.reverse = b.shift = b.slice = b.splice = b.concat = b.sort = b.unshift = null; + + // Array elements and properties. + ok(_.isEqual(a, b), "Arrays containing equivalent elements and different non-numeric properties are equal"); + a.push("White Rocks"); + ok(!_.isEqual(a, b), "Arrays of different lengths are not equal"); + a.push("East Boulder"); + b.push("Gunbarrel Ranch", "Teller Farm"); + ok(!_.isEqual(a, b), "Arrays of identical lengths containing different elements are not equal"); + + // Sparse arrays. + ok(_.isEqual(Array(3), Array(3)), "Sparse arrays of identical lengths are equal"); + ok(!_.isEqual(Array(3), Array(6)), "Sparse arrays of different lengths are not equal when both are empty"); + + // Simple objects. + ok(_.isEqual({a: "Curly", b: 1, c: true}, {a: "Curly", b: 1, c: true}), "Objects containing identical primitives are equal"); + ok(_.isEqual({a: /Curly/g, b: new Date(2009, 11, 13)}, {a: /Curly/g, b: new Date(2009, 11, 13)}), "Objects containing equivalent members are equal"); + ok(!_.isEqual({a: 63, b: 75}, {a: 61, b: 55}), "Objects of identical sizes with different values are not equal"); + ok(!_.isEqual({a: 63, b: 75}, {a: 61, c: 55}), "Objects of identical sizes with different property names are not equal"); + ok(!_.isEqual({a: 1, b: 2}, {a: 1}), "Objects of different sizes are not equal"); + ok(!_.isEqual({a: 1}, {a: 1, b: 2}), "Commutative equality is implemented for objects"); + ok(!_.isEqual({x: 1, y: undefined}, {x: 1, z: 2}), "Objects with identical keys and different values are not equivalent"); + + // `A` contains nested objects and arrays. + a = { + name: new String("Moe Howard"), + age: new Number(77), + stooge: true, + hobbies: ["acting"], + film: { + name: "Sing a Song of Six Pants", + release: new Date(1947, 9, 30), + stars: [new String("Larry Fine"), "Shemp Howard"], + minutes: new Number(16), + seconds: 54 + } + }; + + // `B` contains equivalent nested objects and arrays. + b = { + name: new String("Moe Howard"), + age: new Number(77), + stooge: true, + hobbies: ["acting"], + film: { + name: "Sing a Song of Six Pants", + release: new Date(1947, 9, 30), + stars: [new String("Larry Fine"), "Shemp Howard"], + minutes: new Number(16), + seconds: 54 + } + }; + ok(_.isEqual(a, b), "Objects with nested equivalent members are recursively compared"); + + // Instances. + ok(_.isEqual(new First, new First), "Object instances are equal"); + ok(!_.isEqual(new First, new Second), "Objects with different constructors and identical own properties are not equal"); + ok(!_.isEqual({value: 1}, new First), "Object instances and objects sharing equivalent properties are not equal"); + ok(!_.isEqual({value: 2}, new Second), "The prototype chain of objects should not be examined"); + + // Circular Arrays. + (a = []).push(a); + (b = []).push(b); + ok(_.isEqual(a, b), "Arrays containing circular references are equal"); + a.push(new String("Larry")); + b.push(new String("Larry")); + ok(_.isEqual(a, b), "Arrays containing circular references and equivalent properties are equal"); + a.push("Shemp"); + b.push("Curly"); + ok(!_.isEqual(a, b), "Arrays containing circular references and different properties are not equal"); + + // More circular arrays #767. + a = ["everything is checked but", "this", "is not"]; + a[1] = a; + b = ["everything is checked but", ["this", "array"], "is not"]; + ok(!_.isEqual(a, b), "Comparison of circular references with non-circular references are not equal"); + + // Circular Objects. + a = {abc: null}; + b = {abc: null}; + a.abc = a; + b.abc = b; + ok(_.isEqual(a, b), "Objects containing circular references are equal"); + a.def = 75; + b.def = 75; + ok(_.isEqual(a, b), "Objects containing circular references and equivalent properties are equal"); + a.def = new Number(75); + b.def = new Number(63); + ok(!_.isEqual(a, b), "Objects containing circular references and different properties are not equal"); + + // More circular objects #767. + a = {everything: "is checked", but: "this", is: "not"}; + a.but = a; + b = {everything: "is checked", but: {that:"object"}, is: "not"}; + ok(!_.isEqual(a, b), "Comparison of circular references with non-circular object references are not equal"); + + // Cyclic Structures. + a = [{abc: null}]; + b = [{abc: null}]; + (a[0].abc = a).push(a); + (b[0].abc = b).push(b); + ok(_.isEqual(a, b), "Cyclic structures are equal"); + a[0].def = "Larry"; + b[0].def = "Larry"; + ok(_.isEqual(a, b), "Cyclic structures containing equivalent properties are equal"); + a[0].def = new String("Larry"); + b[0].def = new String("Curly"); + ok(!_.isEqual(a, b), "Cyclic structures containing different properties are not equal"); + + // Complex Circular References. + a = {foo: {b: {foo: {c: {foo: null}}}}}; + b = {foo: {b: {foo: {c: {foo: null}}}}}; + a.foo.b.foo.c.foo = a; + b.foo.b.foo.c.foo = b; + ok(_.isEqual(a, b), "Cyclic structures with nested and identically-named properties are equal"); + + // Chaining. + ok(!_.isEqual(_({x: 1, y: undefined}).chain(), _({x: 1, z: 2}).chain()), 'Chained objects containing different values are not equal'); + equal(_({x: 1, y: 2}).chain().isEqual(_({x: 1, y: 2}).chain()).value(), true, '`isEqual` can be chained'); + + // Custom `isEqual` methods. + var isEqualObj = {isEqual: function (o) { return o.isEqual == this.isEqual; }, unique: {}}; + var isEqualObjClone = {isEqual: isEqualObj.isEqual, unique: {}}; + + ok(_.isEqual(isEqualObj, isEqualObjClone), 'Both objects implement identical `isEqual` methods'); + ok(_.isEqual(isEqualObjClone, isEqualObj), 'Commutative equality is implemented for objects with custom `isEqual` methods'); + ok(!_.isEqual(isEqualObj, {}), 'Objects that do not implement equivalent `isEqual` methods are not equal'); + ok(!_.isEqual({}, isEqualObj), 'Commutative equality is implemented for objects with different `isEqual` methods'); + + // Objects from another frame. + ok(_.isEqual({}, iObject)); + }); + + test("isEmpty", function() { + ok(!_([1]).isEmpty(), '[1] is not empty'); + ok(_.isEmpty([]), '[] is empty'); + ok(!_.isEmpty({one : 1}), '{one : 1} is not empty'); + ok(_.isEmpty({}), '{} is empty'); + ok(_.isEmpty(new RegExp('')), 'objects with prototype properties are empty'); + ok(_.isEmpty(null), 'null is empty'); + ok(_.isEmpty(), 'undefined is empty'); + ok(_.isEmpty(''), 'the empty string is empty'); + ok(!_.isEmpty('moe'), 'but other strings are not'); + + var obj = {one : 1}; + delete obj.one; + ok(_.isEmpty(obj), 'deleting all the keys from an object empties it'); + }); + + // Setup remote variables for iFrame tests. + var iframe = document.createElement('iframe'); + jQuery(iframe).appendTo(document.body); + var iDoc = iframe.contentDocument || iframe.contentWindow.document; + iDoc.write( + "" + ); + iDoc.close(); + + test("isElement", function() { + ok(!_.isElement('div'), 'strings are not dom elements'); + ok(_.isElement($('html')[0]), 'the html tag is a DOM element'); + ok(_.isElement(iElement), 'even from another frame'); + }); + + test("isArguments", function() { + var args = (function(){ return arguments; })(1, 2, 3); + ok(!_.isArguments('string'), 'a string is not an arguments object'); + ok(!_.isArguments(_.isArguments), 'a function is not an arguments object'); + ok(_.isArguments(args), 'but the arguments object is an arguments object'); + ok(!_.isArguments(_.toArray(args)), 'but not when it\'s converted into an array'); + ok(!_.isArguments([1,2,3]), 'and not vanilla arrays.'); + ok(_.isArguments(iArguments), 'even from another frame'); + }); + + test("isObject", function() { + ok(_.isObject(arguments), 'the arguments object is object'); + ok(_.isObject([1, 2, 3]), 'and arrays'); + ok(_.isObject($('html')[0]), 'and DOM element'); + ok(_.isObject(iElement), 'even from another frame'); + ok(_.isObject(function () {}), 'and functions'); + ok(_.isObject(iFunction), 'even from another frame'); + ok(!_.isObject(null), 'but not null'); + ok(!_.isObject(undefined), 'and not undefined'); + ok(!_.isObject('string'), 'and not string'); + ok(!_.isObject(12), 'and not number'); + ok(!_.isObject(true), 'and not boolean'); + ok(_.isObject(new String('string')), 'but new String()'); + }); + + test("isArray", function() { + ok(!_.isArray(arguments), 'the arguments object is not an array'); + ok(_.isArray([1, 2, 3]), 'but arrays are'); + ok(_.isArray(iArray), 'even from another frame'); + }); + + test("isString", function() { + ok(!_.isString(document.body), 'the document body is not a string'); + ok(_.isString([1, 2, 3].join(', ')), 'but strings are'); + ok(_.isString(iString), 'even from another frame'); + }); + + test("isNumber", function() { + ok(!_.isNumber('string'), 'a string is not a number'); + ok(!_.isNumber(arguments), 'the arguments object is not a number'); + ok(!_.isNumber(undefined), 'undefined is not a number'); + ok(_.isNumber(3 * 4 - 7 / 10), 'but numbers are'); + ok(_.isNumber(NaN), 'NaN *is* a number'); + ok(_.isNumber(Infinity), 'Infinity is a number'); + ok(_.isNumber(iNumber), 'even from another frame'); + ok(!_.isNumber('1'), 'numeric strings are not numbers'); + }); + + test("isBoolean", function() { + ok(!_.isBoolean(2), 'a number is not a boolean'); + ok(!_.isBoolean("string"), 'a string is not a boolean'); + ok(!_.isBoolean("false"), 'the string "false" is not a boolean'); + ok(!_.isBoolean("true"), 'the string "true" is not a boolean'); + ok(!_.isBoolean(arguments), 'the arguments object is not a boolean'); + ok(!_.isBoolean(undefined), 'undefined is not a boolean'); + ok(!_.isBoolean(NaN), 'NaN is not a boolean'); + ok(!_.isBoolean(null), 'null is not a boolean'); + ok(_.isBoolean(true), 'but true is'); + ok(_.isBoolean(false), 'and so is false'); + ok(_.isBoolean(iBoolean), 'even from another frame'); + }); + + test("isFunction", function() { + ok(!_.isFunction([1, 2, 3]), 'arrays are not functions'); + ok(!_.isFunction('moe'), 'strings are not functions'); + ok(_.isFunction(_.isFunction), 'but functions are'); + ok(_.isFunction(iFunction), 'even from another frame'); + }); + + test("isDate", function() { + ok(!_.isDate(100), 'numbers are not dates'); + ok(!_.isDate({}), 'objects are not dates'); + ok(_.isDate(new Date()), 'but dates are'); + ok(_.isDate(iDate), 'even from another frame'); + }); + + test("isRegExp", function() { + ok(!_.isRegExp(_.identity), 'functions are not RegExps'); + ok(_.isRegExp(/identity/), 'but RegExps are'); + ok(_.isRegExp(iRegExp), 'even from another frame'); + }); + + test("isFinite", function() { + ok(!_.isFinite(undefined), 'undefined is not Finite'); + ok(!_.isFinite(null), 'null is not Finite'); + ok(!_.isFinite(NaN), 'NaN is not Finite'); + ok(!_.isFinite(Infinity), 'Infinity is not Finite'); + ok(!_.isFinite(-Infinity), '-Infinity is not Finite'); + ok(!_.isFinite('12'), 'Strings are not numbers'); + var obj = new Number(5); + ok(_.isFinite(obj), 'Number instances can be finite'); + ok(_.isFinite(0), '0 is Finite'); + ok(_.isFinite(123), 'Ints are Finite'); + ok(_.isFinite(-12.44), 'Floats are Finite'); + }); + + test("isNaN", function() { + ok(!_.isNaN(undefined), 'undefined is not NaN'); + ok(!_.isNaN(null), 'null is not NaN'); + ok(!_.isNaN(0), '0 is not NaN'); + ok(_.isNaN(NaN), 'but NaN is'); + ok(_.isNaN(iNaN), 'even from another frame'); + ok(_.isNaN(new Number(NaN)), 'wrapped NaN is still NaN'); + }); + + test("isNull", function() { + ok(!_.isNull(undefined), 'undefined is not null'); + ok(!_.isNull(NaN), 'NaN is not null'); + ok(_.isNull(null), 'but null is'); + ok(_.isNull(iNull), 'even from another frame'); + }); + + test("isUndefined", function() { + ok(!_.isUndefined(1), 'numbers are defined'); + ok(!_.isUndefined(null), 'null is defined'); + ok(!_.isUndefined(false), 'false is defined'); + ok(!_.isUndefined(NaN), 'NaN is defined'); + ok(_.isUndefined(), 'nothing is undefined'); + ok(_.isUndefined(undefined), 'undefined is undefined'); + ok(_.isUndefined(iUndefined), 'even from another frame'); + }); + + if (window.ActiveXObject) { + test("IE host objects", function() { + var xml = new ActiveXObject("Msxml2.DOMDocument.3.0"); + ok(!_.isNumber(xml)); + ok(!_.isBoolean(xml)); + ok(!_.isNaN(xml)); + ok(!_.isFunction(xml)); + ok(!_.isNull(xml)); + ok(!_.isUndefined(xml)); + }); + } + + test("tap", function() { + var intercepted = null; + var interceptor = function(obj) { intercepted = obj; }; + var returned = _.tap(1, interceptor); + equal(intercepted, 1, "passes tapped object to interceptor"); + equal(returned, 1, "returns tapped object"); + + returned = _([1,2,3]).chain(). + map(function(n){ return n * 2; }). + max(). + tap(interceptor). + value(); + ok(returned == 6 && intercepted == 6, 'can use tapped objects in a chain'); + }); +}); diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/speed.js b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/speed.js new file mode 100644 index 0000000..05e3f2a --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/speed.js @@ -0,0 +1,75 @@ +(function() { + + var numbers = []; + for (var i=0; i<1000; i++) numbers.push(i); + var objects = _.map(numbers, function(n){ return {num : n}; }); + var randomized = _.sortBy(numbers, function(){ return Math.random(); }); + var deep = _.map(_.range(100), function() { return _.range(1000); }); + + JSLitmus.test('_.each()', function() { + var timesTwo = []; + _.each(numbers, function(num){ timesTwo.push(num * 2); }); + return timesTwo; + }); + + JSLitmus.test('_(list).each()', function() { + var timesTwo = []; + _(numbers).each(function(num){ timesTwo.push(num * 2); }); + return timesTwo; + }); + + JSLitmus.test('jQuery.each()', function() { + var timesTwo = []; + jQuery.each(numbers, function(){ timesTwo.push(this * 2); }); + return timesTwo; + }); + + JSLitmus.test('_.map()', function() { + return _.map(objects, function(obj){ return obj.num; }); + }); + + JSLitmus.test('jQuery.map()', function() { + return jQuery.map(objects, function(obj){ return obj.num; }); + }); + + JSLitmus.test('_.pluck()', function() { + return _.pluck(objects, 'num'); + }); + + JSLitmus.test('_.uniq()', function() { + return _.uniq(randomized); + }); + + JSLitmus.test('_.uniq() (sorted)', function() { + return _.uniq(numbers, true); + }); + + JSLitmus.test('_.sortBy()', function() { + return _.sortBy(numbers, function(num){ return -num; }); + }); + + JSLitmus.test('_.isEqual()', function() { + return _.isEqual(numbers, randomized); + }); + + JSLitmus.test('_.keys()', function() { + return _.keys(objects); + }); + + JSLitmus.test('_.values()', function() { + return _.values(objects); + }); + + JSLitmus.test('_.intersection()', function() { + return _.intersection(numbers, randomized); + }); + + JSLitmus.test('_.range()', function() { + return _.range(1000); + }); + + JSLitmus.test('_.flatten()', function() { + return _.flatten(deep); + }); + +})(); diff --git a/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/utility.js b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/utility.js new file mode 100644 index 0000000..c9be20a --- /dev/null +++ b/node_modules/grunt-legacy-log-utils/node_modules/underscore.string/test/test_underscore/utility.js @@ -0,0 +1,249 @@ +$(document).ready(function() { + + var templateSettings; + + module("Utility", { + + setup: function() { + templateSettings = _.clone(_.templateSettings); + }, + + teardown: function() { + _.templateSettings = templateSettings; + } + + }); + + test("#750 - Return _ instance.", 2, function() { + var instance = _([]); + ok(_(instance) === instance); + ok(new _(instance) === instance); + }); + + test("identity", function() { + var moe = {name : 'moe'}; + equal(_.identity(moe), moe, 'moe is the same as his identity'); + }); + + test("uniqueId", function() { + var ids = [], i = 0; + while(i++ < 100) ids.push(_.uniqueId()); + equal(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids'); + }); + + test("times", function() { + var vals = []; + _.times(3, function (i) { vals.push(i); }); + ok(_.isEqual(vals, [0,1,2]), "is 0 indexed"); + // + vals = []; + _(3).times(function (i) { vals.push(i); }); + ok(_.isEqual(vals, [0,1,2]), "works as a wrapper"); + }); + + test("mixin", function() { + _.mixin({ + myReverse: function(string) { + return string.split('').reverse().join(''); + } + }); + equal(_.myReverse('panacea'), 'aecanap', 'mixed in a function to _'); + equal(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper'); + }); + + test("_.escape", function() { + equal(_.escape("Curly & Moe"), "Curly & Moe"); + equal(_.escape("Curly & Moe"), "Curly &amp; Moe"); + equal(_.escape(null), ''); + }); + + test("_.unescape", function() { + var string = "Curly & Moe"; + equal(_.unescape("Curly & Moe"), string); + equal(_.unescape("Curly &amp; Moe"), "Curly & Moe"); + equal(_.unescape(null), ''); + equal(_.unescape(_.escape(string)), string); + }); + + test("template", function() { + var basicTemplate = _.template("<%= thing %> is gettin' on my noives!"); + var result = basicTemplate({thing : 'This'}); + equal(result, "This is gettin' on my noives!", 'can do basic attribute interpolation'); + + var sansSemicolonTemplate = _.template("A <% this %> B"); + equal(sansSemicolonTemplate(), "A B"); + + var backslashTemplate = _.template("<%= thing %> is \\ridanculous"); + equal(backslashTemplate({thing: 'This'}), "This is \\ridanculous"); + + var escapeTemplate = _.template('<%= a ? "checked=\\"checked\\"" : "" %>'); + equal(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.'); + + var fancyTemplate = _.template("
        <% \ + for (key in people) { \ + %>
      • <%= people[key] %>
      • <% } %>
      "); + result = fancyTemplate({people : {moe : "Moe", larry : "Larry", curly : "Curly"}}); + equal(result, "
      • Moe
      • Larry
      • Curly
      ", 'can run arbitrary javascript in templates'); + + var escapedCharsInJavascriptTemplate = _.template("
        <% _.each(numbers.split('\\n'), function(item) { %>
      • <%= item %>
      • <% }) %>
      "); + result = escapedCharsInJavascriptTemplate({numbers: "one\ntwo\nthree\nfour"}); + equal(result, "
      • one
      • two
      • three
      • four
      ", 'Can use escaped characters (e.g. \\n) in Javascript'); + + var namespaceCollisionTemplate = _.template("<%= pageCount %> <%= thumbnails[pageCount] %> <% _.each(thumbnails, function(p) { %>
      \">
      <% }); %>"); + result = namespaceCollisionTemplate({ + pageCount: 3, + thumbnails: { + 1: "p1-thumbnail.gif", + 2: "p2-thumbnail.gif", + 3: "p3-thumbnail.gif" + } + }); + equal(result, "3 p3-thumbnail.gif
      "); + + var noInterpolateTemplate = _.template("

      Just some text. Hey, I know this is silly but it aids consistency.

      "); + result = noInterpolateTemplate(); + equal(result, "

      Just some text. Hey, I know this is silly but it aids consistency.

      "); + + var quoteTemplate = _.template("It's its, not it's"); + equal(quoteTemplate({}), "It's its, not it's"); + + var quoteInStatementAndBody = _.template("<%\ + if(foo == 'bar'){ \ + %>Statement quotes and 'quotes'.<% } %>"); + equal(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'."); + + var withNewlinesAndTabs = _.template('This\n\t\tis: <%= x %>.\n\tok.\nend.'); + equal(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.'); + + var template = _.template("<%- value %>"); + var result = template({value: " +``` + +Using [`npm`](http://npmjs.org/): + +```bash +npm i --save lodash + +{sudo} npm i -g lodash +npm ln lodash +``` + +In [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/): + +```js +var _ = require('lodash'); +// or as Underscore +var _ = require('lodash/dist/lodash.underscore'); +``` + +**Notes:** + * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL + * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it + +In [Rhino](http://www.mozilla.org/rhino/): + +```js +load('lodash.js'); +``` + +In an AMD loader: + +```js +require({ + 'packages': [ + { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' } + ] +}, +['lodash'], function(_) { + console.log(_.VERSION); +}); +``` + +## Resources + + * Podcasts + - [JavaScript Jabber](http://javascriptjabber.com/079-jsj-lo-dash-with-john-david-dalton/) + + * Posts + - [Say “Hello” to Lo-Dash](http://kitcambridge.be/blog/say-hello-to-lo-dash/) + - [Custom builds in Lo-Dash 2.0](http://kitcambridge.be/blog/custom-builds-in-lo-dash-2-dot-0/) + + * Videos + - [Introduction](https://vimeo.com/44154599) + - [Origins](https://vimeo.com/44154600) + - [Optimizations & builds](https://vimeo.com/44154601) + - [Native method use](https://vimeo.com/48576012) + - [Testing](https://vimeo.com/45865290) + - [CascadiaJS ’12](http://www.youtube.com/watch?v=dpPy4f_SeEk) + + A list of other community created podcasts, posts, & videos is available on our [wiki](https://github.com/lodash/lodash/wiki/Resources). + +## Features + + * AMD loader support ([curl](https://github.com/cujojs/curl), [dojo](http://dojotoolkit.org/), [requirejs](http://requirejs.org/), etc.) + * [_(…)](https://lodash.com/docs#_) supports intuitive chaining + * [_.at](https://lodash.com/docs#at) for cherry-picking collection values + * [_.bindKey](https://lodash.com/docs#bindKey) for binding [*“lazy”*](http://michaux.ca/articles/lazy-function-definition-pattern) defined methods + * [_.clone](https://lodash.com/docs#clone) supports shallow cloning of `Date` & `RegExp` objects + * [_.cloneDeep](https://lodash.com/docs#cloneDeep) for deep cloning arrays & objects + * [_.constant](https://lodash.com/docs#constant) & [_.property](https://lodash.com/docs#property) function generators for composing functions + * [_.contains](https://lodash.com/docs#contains) accepts a `fromIndex` + * [_.create](https://lodash.com/docs#create) for easier object inheritance + * [_.createCallback](https://lodash.com/docs#createCallback) for extending callbacks in methods & mixins + * [_.curry](https://lodash.com/docs#curry) for creating [curried](http://hughfdjackson.com/javascript/2013/07/06/why-curry-helps/) functions + * [_.debounce](https://lodash.com/docs#debounce) & [_.throttle](https://lodash.com/docs#throttle) accept additional `options` for more control + * [_.findIndex](https://lodash.com/docs#findIndex) & [_.findKey](https://lodash.com/docs#findKey) for finding indexes & keys + * [_.forEach](https://lodash.com/docs#forEach) is chainable & supports exiting early + * [_.forIn](https://lodash.com/docs#forIn) for iterating own & inherited properties + * [_.forOwn](https://lodash.com/docs#forOwn) for iterating own properties + * [_.isPlainObject](https://lodash.com/docs#isPlainObject) for checking if values are created by `Object` + * [_.mapValues](https://lodash.com/docs#mapValues) for [mapping](https://lodash.com/docs#map) values to an object + * [_.memoize](https://lodash.com/docs#memoize) exposes the `cache` of memoized functions + * [_.merge](https://lodash.com/docs#merge) for a deep [_.extend](https://lodash.com/docs#extend) + * [_.noop](https://lodash.com/docs#noop) for function placeholders + * [_.now](https://lodash.com/docs#now) as a cross-browser `Date.now` alternative + * [_.parseInt](https://lodash.com/docs#parseInt) for consistent behavior + * [_.pull](https://lodash.com/docs#pull) & [_.remove](https://lodash.com/docs#remove) for mutating arrays + * [_.random](https://lodash.com/docs#random) supports returning floating-point numbers + * [_.runInContext](https://lodash.com/docs#runInContext) for easier mocking + * [_.sortBy](https://lodash.com/docs#sortBy) supports sorting by multiple properties + * [_.support](https://lodash.com/docs#support) for flagging environment features + * [_.template](https://lodash.com/docs#template) supports [*“imports”*](https://lodash.com/docs#templateSettings_imports) options & [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals) + * [_.transform](https://lodash.com/docs#transform) as a powerful alternative to [_.reduce](https://lodash.com/docs#reduce) for transforming objects + * [_.where](https://lodash.com/docs#where) supports deep object comparisons + * [_.xor](https://lodash.com/docs#xor) as a companion to [_.difference](https://lodash.com/docs#difference), [_.intersection](https://lodash.com/docs#intersection), & [_.union](https://lodash.com/docs#union) + * [_.zip](https://lodash.com/docs#zip) is capable of unzipping values + * [_.omit](https://lodash.com/docs#omit), [_.pick](https://lodash.com/docs#pick), & + [more](https://lodash.com/docs "_.assign, _.clone, _.cloneDeep, _.first, _.initial, _.isEqual, _.last, _.merge, _.rest") accept callbacks + * [_.contains](https://lodash.com/docs#contains), [_.toArray](https://lodash.com/docs#toArray), & + [more](https://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.forEach, _.forEachRight, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.size, _.some, _.sortBy, _.where") accept strings + * [_.filter](https://lodash.com/docs#filter), [_.map](https://lodash.com/docs#map), & + [more](https://lodash.com/docs "_.countBy, _.every, _.find, _.findKey, _.findLast, _.findLastIndex, _.findLastKey, _.first, _.groupBy, _.initial, _.last, _.max, _.min, _.reject, _.rest, _.some, _.sortBy, _.sortedIndex, _.uniq") support *“_.pluck”* & *“_.where”* shorthands + * [_.findLast](https://lodash.com/docs#findLast), [_.findLastIndex](https://lodash.com/docs#findLastIndex), & + [more](https://lodash.com/docs "_.findLastKey, _.forEachRight, _.forInRight, _.forOwnRight, _.partialRight") right-associative methods + +## Support + +Tested in Chrome 5~31, Firefox 2~25, IE 6-11, Opera 9.25-17, Safari 3-7, Node.js 0.6.21-0.10.22, Narwhal 0.3.2, PhantomJS 1.9.2, RingoJS 0.9, & Rhino 1.7RC5. diff --git a/node_modules/grunt-legacy-log/node_modules/lodash/dist/lodash.compat.js b/node_modules/grunt-legacy-log/node_modules/lodash/dist/lodash.compat.js new file mode 100644 index 0000000..4d35185 --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/lodash/dist/lodash.compat.js @@ -0,0 +1,7158 @@ +/** + * @license + * Lo-Dash 2.4.2 (Custom Build) + * Build: `lodash -o ./dist/lodash.compat.js` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre ES5 environments */ + var undefined; + + /** Used to pool arrays and objects used internally */ + var arrayPool = [], + objectPool = []; + + /** Used to generate unique IDs */ + var idCounter = 0; + + /** Used internally to indicate various things */ + var indicatorObject = {}; + + /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */ + var keyPrefix = +new Date + ''; + + /** Used as the size when optimizations are enabled for large arrays */ + var largeArraySize = 75; + + /** Used as the max size of the `arrayPool` and `objectPool` */ + var maxPoolSize = 40; + + /** Used to detect and test whitespace */ + var whitespace = ( + // whitespace + ' \t\x0B\f\xA0\ufeff' + + + // line terminators + '\n\r\u2028\u2029' + + + // unicode category "Zs" space separators + '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' + ); + + /** Used to match empty string literals in compiled template source */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** + * Used to match ES6 template delimiters + * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals + */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match regexp flags from their coerced string values */ + var reFlags = /\w*$/; + + /** Used to detected named functions */ + var reFuncName = /^\s*function[ \n\r\t]+\w/; + + /** Used to match "interpolate" template delimiters */ + var reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match leading whitespace and zeros to be removed */ + var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)'); + + /** Used to ensure capturing order of template delimiters */ + var reNoMatch = /($^)/; + + /** Used to detect functions containing a `this` reference */ + var reThis = /\bthis\b/; + + /** Used to match unescaped characters in compiled string literals */ + var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; + + /** Used to assign default `context` object properties */ + var contextProps = [ + 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object', + 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', + 'parseInt', 'setTimeout' + ]; + + /** Used to fix the JScript [[DontEnum]] bug */ + var shadowedProps = [ + 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', + 'toLocaleString', 'toString', 'valueOf' + ]; + + /** Used to make template sourceURLs easier to identify */ + var templateCounter = 0; + + /** `Object#toString` result shortcuts */ + var argsClass = '[object Arguments]', + arrayClass = '[object Array]', + boolClass = '[object Boolean]', + dateClass = '[object Date]', + errorClass = '[object Error]', + funcClass = '[object Function]', + numberClass = '[object Number]', + objectClass = '[object Object]', + regexpClass = '[object RegExp]', + stringClass = '[object String]'; + + /** Used to identify object classifications that `_.clone` supports */ + var cloneableClasses = {}; + cloneableClasses[funcClass] = false; + cloneableClasses[argsClass] = cloneableClasses[arrayClass] = + cloneableClasses[boolClass] = cloneableClasses[dateClass] = + cloneableClasses[numberClass] = cloneableClasses[objectClass] = + cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; + + /** Used as an internal `_.debounce` options object */ + var debounceOptions = { + 'leading': false, + 'maxWait': 0, + 'trailing': false + }; + + /** Used as the property descriptor for `__bindData__` */ + var descriptor = { + 'configurable': false, + 'enumerable': false, + 'value': null, + 'writable': false + }; + + /** Used as the data object for `iteratorTemplate` */ + var iteratorData = { + 'args': '', + 'array': null, + 'bottom': '', + 'firstArg': '', + 'init': '', + 'keys': null, + 'loop': '', + 'shadowedProps': null, + 'support': null, + 'top': '', + 'useHas': false + }; + + /** Used to determine if values are of the language type Object */ + var objectTypes = { + 'boolean': false, + 'function': true, + 'object': true, + 'number': false, + 'string': false, + 'undefined': false + }; + + /** Used to escape characters for inclusion in compiled string literals */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\t': 't', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Used as a reference to the global object */ + var root = (objectTypes[typeof window] && window) || this; + + /** Detect free variable `exports` */ + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + + /** Detect free variable `module` */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports` */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + + /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ + var freeGlobal = objectTypes[typeof global] && global; + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { + root = freeGlobal; + } + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.indexOf` without support for binary searches + * or `fromIndex` constraints. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * An implementation of `_.contains` for cache objects that mimics the return + * signature of `_.indexOf` by returning `0` if the value is found, else `-1`. + * + * @private + * @param {Object} cache The cache object to inspect. + * @param {*} value The value to search for. + * @returns {number} Returns `0` if `value` is found, else `-1`. + */ + function cacheIndexOf(cache, value) { + var type = typeof value; + cache = cache.cache; + + if (type == 'boolean' || value == null) { + return cache[value] ? 0 : -1; + } + if (type != 'number' && type != 'string') { + type = 'object'; + } + var key = type == 'number' ? value : keyPrefix + value; + cache = (cache = cache[type]) && cache[key]; + + return type == 'object' + ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1) + : (cache ? 0 : -1); + } + + /** + * Adds a given value to the corresponding cache object. + * + * @private + * @param {*} value The value to add to the cache. + */ + function cachePush(value) { + var cache = this.cache, + type = typeof value; + + if (type == 'boolean' || value == null) { + cache[value] = true; + } else { + if (type != 'number' && type != 'string') { + type = 'object'; + } + var key = type == 'number' ? value : keyPrefix + value, + typeCache = cache[type] || (cache[type] = {}); + + if (type == 'object') { + (typeCache[key] || (typeCache[key] = [])).push(value); + } else { + typeCache[key] = true; + } + } + } + + /** + * Used by `_.max` and `_.min` as the default callback when a given + * collection is a string value. + * + * @private + * @param {string} value The character to inspect. + * @returns {number} Returns the code unit of given character. + */ + function charAtCallback(value) { + return value.charCodeAt(0); + } + + /** + * Used by `sortBy` to compare transformed `collection` elements, stable sorting + * them in ascending order. + * + * @private + * @param {Object} a The object to compare to `b`. + * @param {Object} b The object to compare to `a`. + * @returns {number} Returns the sort order indicator of `1` or `-1`. + */ + function compareAscending(a, b) { + var ac = a.criteria, + bc = b.criteria, + index = -1, + length = ac.length; + + while (++index < length) { + var value = ac[index], + other = bc[index]; + + if (value !== other) { + if (value > other || typeof value == 'undefined') { + return 1; + } + if (value < other || typeof other == 'undefined') { + return -1; + } + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to return the same value for + // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247 + // + // This also ensures a stable sort in V8 and other engines. + // See http://code.google.com/p/v8/issues/detail?id=90 + return a.index - b.index; + } + + /** + * Creates a cache object to optimize linear searches of large arrays. + * + * @private + * @param {Array} [array=[]] The array to search. + * @returns {null|Object} Returns the cache object or `null` if caching should not be used. + */ + function createCache(array) { + var index = -1, + length = array.length, + first = array[0], + mid = array[(length / 2) | 0], + last = array[length - 1]; + + if (first && typeof first == 'object' && + mid && typeof mid == 'object' && last && typeof last == 'object') { + return false; + } + var cache = getObject(); + cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false; + + var result = getObject(); + result.array = array; + result.cache = cache; + result.push = cachePush; + + while (++index < length) { + result.push(array[index]); + } + return result; + } + + /** + * Used by `template` to escape characters for inclusion in compiled + * string literals. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(match) { + return '\\' + stringEscapes[match]; + } + + /** + * Gets an array from the array pool or creates a new one if the pool is empty. + * + * @private + * @returns {Array} The array from the pool. + */ + function getArray() { + return arrayPool.pop() || []; + } + + /** + * Gets an object from the object pool or creates a new one if the pool is empty. + * + * @private + * @returns {Object} The object from the pool. + */ + function getObject() { + return objectPool.pop() || { + 'array': null, + 'cache': null, + 'criteria': null, + 'false': false, + 'index': 0, + 'null': false, + 'number': null, + 'object': null, + 'push': null, + 'string': null, + 'true': false, + 'undefined': false, + 'value': null + }; + } + + /** + * Checks if `value` is a DOM node in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`. + */ + function isNode(value) { + // IE < 9 presents DOM nodes as `Object` objects except they have `toString` + // methods that are `typeof` "string" and still can coerce nodes to strings + return typeof value.toString != 'function' && typeof (value + '') == 'string'; + } + + /** + * Releases the given array back to the array pool. + * + * @private + * @param {Array} [array] The array to release. + */ + function releaseArray(array) { + array.length = 0; + if (arrayPool.length < maxPoolSize) { + arrayPool.push(array); + } + } + + /** + * Releases the given object back to the object pool. + * + * @private + * @param {Object} [object] The object to release. + */ + function releaseObject(object) { + var cache = object.cache; + if (cache) { + releaseObject(cache); + } + object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null; + if (objectPool.length < maxPoolSize) { + objectPool.push(object); + } + } + + /** + * Slices the `collection` from the `start` index up to, but not including, + * the `end` index. + * + * Note: This function is used instead of `Array#slice` to support node lists + * in IE < 9 and to ensure dense arrays are returned. + * + * @private + * @param {Array|Object|string} collection The collection to slice. + * @param {number} start The start index. + * @param {number} end The end index. + * @returns {Array} Returns the new array. + */ + function slice(array, start, end) { + start || (start = 0); + if (typeof end == 'undefined') { + end = array ? array.length : 0; + } + var index = -1, + length = end - start || 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = array[start + index]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new `lodash` function using the given context object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} [context=root] The context object. + * @returns {Function} Returns the `lodash` function. + */ + function runInContext(context) { + // Avoid issues with some ES3 environments that attempt to use values, named + // after built-in constructors like `Object`, for the creation of literals. + // ES5 clears this up by stating that literals must use built-in constructors. + // See http://es5.github.io/#x11.1.5. + context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; + + /** Native constructor references */ + var Array = context.Array, + Boolean = context.Boolean, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Number = context.Number, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** + * Used for `Array` method references. + * + * Normally `Array.prototype` would suffice, however, using an array literal + * avoids issues in Narwhal. + */ + var arrayRef = []; + + /** Used for native method references */ + var errorProto = Error.prototype, + objectProto = Object.prototype, + stringProto = String.prototype; + + /** Used to restore the original `_` reference in `noConflict` */ + var oldDash = context._; + + /** Used to resolve the internal [[Class]] of values */ + var toString = objectProto.toString; + + /** Used to detect if a method is native */ + var reNative = RegExp('^' + + String(toString) + .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + .replace(/toString| for [^\]]+/g, '.*?') + '$' + ); + + /** Native method shortcuts */ + var ceil = Math.ceil, + clearTimeout = context.clearTimeout, + floor = Math.floor, + fnToString = Function.prototype.toString, + getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, + hasOwnProperty = objectProto.hasOwnProperty, + push = arrayRef.push, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + setTimeout = context.setTimeout, + splice = arrayRef.splice, + unshift = arrayRef.unshift; + + /** Used to set meta data on functions */ + var defineProperty = (function() { + // IE 8 only accepts DOM elements + try { + var o = {}, + func = isNative(func = Object.defineProperty) && func, + result = func(o, o, o) && func; + } catch(e) { } + return result; + }()); + + /* Native method shortcuts for methods with the same name as other `lodash` methods */ + var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, + nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, + nativeIsFinite = context.isFinite, + nativeIsNaN = context.isNaN, + nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, + nativeMax = Math.max, + nativeMin = Math.min, + nativeParseInt = context.parseInt, + nativeRandom = Math.random; + + /** Used to lookup a built-in constructor by [[Class]] */ + var ctorByClass = {}; + ctorByClass[arrayClass] = Array; + ctorByClass[boolClass] = Boolean; + ctorByClass[dateClass] = Date; + ctorByClass[funcClass] = Function; + ctorByClass[objectClass] = Object; + ctorByClass[numberClass] = Number; + ctorByClass[regexpClass] = RegExp; + ctorByClass[stringClass] = String; + + /** Used to avoid iterating non-enumerable properties in IE < 9 */ + var nonEnumProps = {}; + nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; + nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true }; + nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true }; + nonEnumProps[objectClass] = { 'constructor': true }; + + (function() { + var length = shadowedProps.length; + while (length--) { + var key = shadowedProps[length]; + for (var className in nonEnumProps) { + if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) { + nonEnumProps[className][key] = false; + } + } + } + }()); + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps the given value to enable intuitive + * method chaining. + * + * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, + * and `unshift` + * + * Chaining is supported in custom builds as long as the `value` method is + * implicitly or explicitly included in the build. + * + * The chainable wrapper functions are: + * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, + * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, + * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, + * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, + * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, + * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, + * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, + * and `zip` + * + * The non-chainable wrapper functions are: + * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`, + * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, + * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, + * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`, + * `template`, `unescape`, `uniqueId`, and `value` + * + * The wrapper functions `first` and `last` return wrapped values when `n` is + * provided, otherwise they return unwrapped values. + * + * Explicit chaining can be enabled by using the `_.chain` method. + * + * @name _ + * @constructor + * @category Chaining + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns a `lodash` instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(num) { + * return num * num; + * }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor + return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__')) + ? value + : new lodashWrapper(value); + } + + /** + * A fast path for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap in a `lodash` instance. + * @param {boolean} chainAll A flag to enable chaining for all methods + * @returns {Object} Returns a `lodash` instance. + */ + function lodashWrapper(value, chainAll) { + this.__chain__ = !!chainAll; + this.__wrapped__ = value; + } + // ensure `new lodashWrapper` is an instance of `lodash` + lodashWrapper.prototype = lodash.prototype; + + /** + * An object used to flag environments features. + * + * @static + * @memberOf _ + * @type Object + */ + var support = lodash.support = {}; + + (function() { + var ctor = function() { this.x = 1; }, + object = { '0': 1, 'length': 1 }, + props = []; + + ctor.prototype = { 'valueOf': 1, 'y': 1 }; + for (var key in new ctor) { props.push(key); } + for (key in arguments) { } + + /** + * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9). + * + * @memberOf _.support + * @type boolean + */ + support.argsClass = toString.call(arguments) == argsClass; + + /** + * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5). + * + * @memberOf _.support + * @type boolean + */ + support.argsObject = arguments.constructor == Object && !(arguments instanceof Array); + + /** + * Detect if `name` or `message` properties of `Error.prototype` are + * enumerable by default. (IE < 9, Safari < 5.1) + * + * @memberOf _.support + * @type boolean + */ + support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name'); + + /** + * Detect if `prototype` properties are enumerable by default. + * + * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 + * (if the prototype or a property on the prototype has been set) + * incorrectly sets a function's `prototype` property [[Enumerable]] + * value to `true`. + * + * @memberOf _.support + * @type boolean + */ + support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype'); + + /** + * Detect if functions can be decompiled by `Function#toString` + * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). + * + * @memberOf _.support + * @type boolean + */ + support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); + + /** + * Detect if `Function#name` is supported (all but IE). + * + * @memberOf _.support + * @type boolean + */ + support.funcNames = typeof Function.name == 'string'; + + /** + * Detect if `arguments` object indexes are non-enumerable + * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1). + * + * @memberOf _.support + * @type boolean + */ + support.nonEnumArgs = key != 0; + + /** + * Detect if properties shadowing those on `Object.prototype` are non-enumerable. + * + * In IE < 9 an objects own properties, shadowing non-enumerable ones, are + * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug). + * + * @memberOf _.support + * @type boolean + */ + support.nonEnumShadows = !/valueOf/.test(props); + + /** + * Detect if own properties are iterated after inherited properties (all but IE < 9). + * + * @memberOf _.support + * @type boolean + */ + support.ownLast = props[0] != 'x'; + + /** + * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly. + * + * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` + * and `splice()` functions that fail to remove the last element, `value[0]`, + * of array-like objects even though the `length` property is set to `0`. + * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` + * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. + * + * @memberOf _.support + * @type boolean + */ + support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]); + + /** + * Detect lack of support for accessing string characters by index. + * + * IE < 8 can't access characters by index and IE 8 can only access + * characters by index on string literals. + * + * @memberOf _.support + * @type boolean + */ + support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; + + /** + * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9) + * and that the JS engine errors when attempting to coerce an object to + * a string without a `toString` function. + * + * @memberOf _.support + * @type boolean + */ + try { + support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + '')); + } catch(e) { + support.nodeClass = true; + } + }(1)); + + /** + * By default, the template delimiters used by Lo-Dash are similar to those in + * embedded Ruby (ERB). Change the following template settings to use alternative + * delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': /<%-([\s\S]+?)%>/g, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': /<%([\s\S]+?)%>/g, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type Object + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type Function + */ + '_': lodash + } + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The template used to create iterator functions. + * + * @private + * @param {Object} data The data object used to populate the text. + * @returns {string} Returns the interpolated text. + */ + var iteratorTemplate = function(obj) { + + var __p = 'var index, iterable = ' + + (obj.firstArg) + + ', result = ' + + (obj.init) + + ';\nif (!iterable) return result;\n' + + (obj.top) + + ';'; + if (obj.array) { + __p += '\nvar length = iterable.length; index = -1;\nif (' + + (obj.array) + + ') { '; + if (support.unindexedChars) { + __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } '; + } + __p += '\n while (++index < length) {\n ' + + (obj.loop) + + ';\n }\n}\nelse { '; + } else if (support.nonEnumArgs) { + __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' + + (obj.loop) + + ';\n }\n } else { '; + } + + if (support.enumPrototypes) { + __p += '\n var skipProto = typeof iterable == \'function\';\n '; + } + + if (support.enumErrorProps) { + __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n '; + } + + var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); } + + if (obj.useHas && obj.keys) { + __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n'; + if (conditions.length) { + __p += ' if (' + + (conditions.join(' && ')) + + ') {\n '; + } + __p += + (obj.loop) + + '; '; + if (conditions.length) { + __p += '\n }'; + } + __p += '\n } '; + } else { + __p += '\n for (index in iterable) {\n'; + if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) { + __p += ' if (' + + (conditions.join(' && ')) + + ') {\n '; + } + __p += + (obj.loop) + + '; '; + if (conditions.length) { + __p += '\n }'; + } + __p += '\n } '; + if (support.nonEnumShadows) { + __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n '; + for (k = 0; k < 7; k++) { + __p += '\n index = \'' + + (obj.shadowedProps[k]) + + '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))'; + if (!obj.useHas) { + __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])'; + } + __p += ') {\n ' + + (obj.loop) + + ';\n } '; + } + __p += '\n } '; + } + + } + + if (obj.array || support.nonEnumArgs) { + __p += '\n}'; + } + __p += + (obj.bottom) + + ';\nreturn result'; + + return __p + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.bind` that creates the bound function and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new bound function. + */ + function baseBind(bindData) { + var func = bindData[0], + partialArgs = bindData[2], + thisArg = bindData[4]; + + function bound() { + // `Function#bind` spec + // http://es5.github.io/#x15.3.4.5 + if (partialArgs) { + // avoid `arguments` object deoptimizations by using `slice` instead + // of `Array.prototype.slice.call` and not assigning `arguments` to a + // variable as a ternary expression + var args = slice(partialArgs); + push.apply(args, arguments); + } + // mimic the constructor's `return` behavior + // http://es5.github.io/#x13.2.2 + if (this instanceof bound) { + // ensure `new bound` is an instance of `func` + var thisBinding = baseCreate(func.prototype), + result = func.apply(thisBinding, args || arguments); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisArg, args || arguments); + } + setBindData(bound, bindData); + return bound; + } + + /** + * The base implementation of `_.clone` without argument juggling or support + * for `thisArg` binding. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep=false] Specify a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates clones with source counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, callback, stackA, stackB) { + if (callback) { + var result = callback(value); + if (typeof result != 'undefined') { + return result; + } + } + // inspect [[Class]] + var isObj = isObject(value); + if (isObj) { + var className = toString.call(value); + if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) { + return value; + } + var ctor = ctorByClass[className]; + switch (className) { + case boolClass: + case dateClass: + return new ctor(+value); + + case numberClass: + case stringClass: + return new ctor(value); + + case regexpClass: + result = ctor(value.source, reFlags.exec(value)); + result.lastIndex = value.lastIndex; + return result; + } + } else { + return value; + } + var isArr = isArray(value); + if (isDeep) { + // check for circular references and return corresponding clone + var initedStack = !stackA; + stackA || (stackA = getArray()); + stackB || (stackB = getArray()); + + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + result = isArr ? ctor(value.length) : {}; + } + else { + result = isArr ? slice(value) : assign({}, value); + } + // add array properties assigned by `RegExp#exec` + if (isArr) { + if (hasOwnProperty.call(value, 'index')) { + result.index = value.index; + } + if (hasOwnProperty.call(value, 'input')) { + result.input = value.input; + } + } + // exit for shallow clone + if (!isDeep) { + return result; + } + // add the source value to the stack of traversed objects + // and associate it with its clone + stackA.push(value); + stackB.push(result); + + // recursively populate clone (susceptible to call stack limits) + (isArr ? baseEach : forOwn)(value, function(objValue, key) { + result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); + }); + + if (initedStack) { + releaseArray(stackA); + releaseArray(stackB); + } + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(prototype, properties) { + return isObject(prototype) ? nativeCreate(prototype) : {}; + } + // fallback for browsers without `Object.create` + if (!nativeCreate) { + baseCreate = (function() { + function Object() {} + return function(prototype) { + if (isObject(prototype)) { + Object.prototype = prototype; + var result = new Object; + Object.prototype = null; + } + return result || context.Object(); + }; + }()); + } + + /** + * The base implementation of `_.createCallback` without support for creating + * "_.pluck" or "_.where" style callbacks. + * + * @private + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + */ + function baseCreateCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + // exit early for no `thisArg` or already bound by `Function#bind` + if (typeof thisArg == 'undefined' || !('prototype' in func)) { + return func; + } + var bindData = func.__bindData__; + if (typeof bindData == 'undefined') { + if (support.funcNames) { + bindData = !func.name; + } + bindData = bindData || !support.funcDecomp; + if (!bindData) { + var source = fnToString.call(func); + if (!support.funcNames) { + bindData = !reFuncName.test(source); + } + if (!bindData) { + // checks if `func` references the `this` keyword and stores the result + bindData = reThis.test(source); + setBindData(func, bindData); + } + } + } + // exit early if there are no `this` references or `func` is bound + if (bindData === false || (bindData !== true && bindData[1] & 1)) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 2: return function(a, b) { + return func.call(thisArg, a, b); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + } + return bind(func, thisArg); + } + + /** + * The base implementation of `createWrapper` that creates the wrapper and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new function. + */ + function baseCreateWrapper(bindData) { + var func = bindData[0], + bitmask = bindData[1], + partialArgs = bindData[2], + partialRightArgs = bindData[3], + thisArg = bindData[4], + arity = bindData[5]; + + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + key = func; + + function bound() { + var thisBinding = isBind ? thisArg : this; + if (partialArgs) { + var args = slice(partialArgs); + push.apply(args, arguments); + } + if (partialRightArgs || isCurry) { + args || (args = slice(arguments)); + if (partialRightArgs) { + push.apply(args, partialRightArgs); + } + if (isCurry && args.length < arity) { + bitmask |= 16 & ~32; + return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); + } + } + args || (args = arguments); + if (isBindKey) { + func = thisBinding[key]; + } + if (this instanceof bound) { + thisBinding = baseCreate(func.prototype); + var result = func.apply(thisBinding, args); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisBinding, args); + } + setBindData(bound, bindData); + return bound; + } + + /** + * The base implementation of `_.difference` that accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to process. + * @param {Array} [values] The array of values to exclude. + * @returns {Array} Returns a new array of filtered values. + */ + function baseDifference(array, values) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + isLarge = length >= largeArraySize && indexOf === baseIndexOf, + result = []; + + if (isLarge) { + var cache = createCache(values); + if (cache) { + indexOf = cacheIndexOf; + values = cache; + } else { + isLarge = false; + } + } + while (++index < length) { + var value = array[index]; + if (indexOf(values, value) < 0) { + result.push(value); + } + } + if (isLarge) { + releaseObject(values); + } + return result; + } + + /** + * The base implementation of `_.flatten` without support for callback + * shorthands or `thisArg` binding. + * + * @private + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. + * @param {number} [fromIndex=0] The index to start from. + * @returns {Array} Returns a new flattened array. + */ + function baseFlatten(array, isShallow, isStrict, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + + if (value && typeof value == 'object' && typeof value.length == 'number' + && (isArray(value) || isArguments(value))) { + // recursively flatten arrays (susceptible to call stack limits) + if (!isShallow) { + value = baseFlatten(value, isShallow, isStrict); + } + var valIndex = -1, + valLength = value.length, + resIndex = result.length; + + result.length += valLength; + while (++valIndex < valLength) { + result[resIndex++] = value[valIndex]; + } + } else if (!isStrict) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.isEqual`, without support for `thisArg` binding, + * that allows partial "_.where" style comparisons. + * + * @private + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `a` objects. + * @param {Array} [stackB=[]] Tracks traversed `b` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { + // used to indicate that when comparing objects, `a` has at least the properties of `b` + if (callback) { + var result = callback(a, b); + if (typeof result != 'undefined') { + return !!result; + } + } + // exit early for identical values + if (a === b) { + // treat `+0` vs. `-0` as not equal + return a !== 0 || (1 / a == 1 / b); + } + var type = typeof a, + otherType = typeof b; + + // exit early for unlike primitive values + if (a === a && + !(a && objectTypes[type]) && + !(b && objectTypes[otherType])) { + return false; + } + // exit early for `null` and `undefined` avoiding ES3's Function#call behavior + // http://es5.github.io/#x15.3.4.4 + if (a == null || b == null) { + return a === b; + } + // compare [[Class]] names + var className = toString.call(a), + otherClass = toString.call(b); + + if (className == argsClass) { + className = objectClass; + } + if (otherClass == argsClass) { + otherClass = objectClass; + } + if (className != otherClass) { + return false; + } + switch (className) { + case boolClass: + case dateClass: + // coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal + return +a == +b; + + case numberClass: + // treat `NaN` vs. `NaN` as equal + return (a != +a) + ? b != +b + // but treat `+0` vs. `-0` as not equal + : (a == 0 ? (1 / a == 1 / b) : a == +b); + + case regexpClass: + case stringClass: + // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) + // treat string primitives and their corresponding object instances as equal + return a == String(b); + } + var isArr = className == arrayClass; + if (!isArr) { + // unwrap any `lodash` wrapped values + var aWrapped = hasOwnProperty.call(a, '__wrapped__'), + bWrapped = hasOwnProperty.call(b, '__wrapped__'); + + if (aWrapped || bWrapped) { + return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); + } + // exit for functions and DOM nodes + if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) { + return false; + } + // in older versions of Opera, `arguments` objects have `Array` constructors + var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor, + ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor; + + // non `Object` object instances with different constructors are not equal + if (ctorA != ctorB && + !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && + ('constructor' in a && 'constructor' in b) + ) { + return false; + } + } + // assume cyclic structures are equal + // the algorithm for detecting cyclic structures is adapted from ES 5.1 + // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) + var initedStack = !stackA; + stackA || (stackA = getArray()); + stackB || (stackB = getArray()); + + var length = stackA.length; + while (length--) { + if (stackA[length] == a) { + return stackB[length] == b; + } + } + var size = 0; + result = true; + + // add `a` and `b` to the stack of traversed objects + stackA.push(a); + stackB.push(b); + + // recursively compare objects and arrays (susceptible to call stack limits) + if (isArr) { + // compare lengths to determine if a deep comparison is necessary + length = a.length; + size = b.length; + result = size == length; + + if (result || isWhere) { + // deep compare the contents, ignoring non-numeric properties + while (size--) { + var index = length, + value = b[size]; + + if (isWhere) { + while (index--) { + if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } + } + else { + // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` + // which, in this case, is more costly + forIn(b, function(value, key, b) { + if (hasOwnProperty.call(b, key)) { + // count the number of properties. + size++; + // deep compare each property value. + return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); + } + }); + + if (result && !isWhere) { + // ensure both objects have the same number of properties + forIn(a, function(value, key, a) { + if (hasOwnProperty.call(a, key)) { + // `size` will be `-1` if `a` has more properties than `b` + return (result = --size > -1); + } + }); + } + } + stackA.pop(); + stackB.pop(); + + if (initedStack) { + releaseArray(stackA); + releaseArray(stackB); + } + return result; + } + + /** + * The base implementation of `_.merge` without argument juggling or support + * for `thisArg` binding. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} [callback] The function to customize merging properties. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + */ + function baseMerge(object, source, callback, stackA, stackB) { + (isArray(source) ? forEach : forOwn)(source, function(source, key) { + var found, + isArr, + result = source, + value = object[key]; + + if (source && ((isArr = isArray(source)) || isPlainObject(source))) { + // avoid merging previously merged cyclic sources + var stackLength = stackA.length; + while (stackLength--) { + if ((found = stackA[stackLength] == source)) { + value = stackB[stackLength]; + break; + } + } + if (!found) { + var isShallow; + if (callback) { + result = callback(value, source); + if ((isShallow = typeof result != 'undefined')) { + value = result; + } + } + if (!isShallow) { + value = isArr + ? (isArray(value) ? value : []) + : (isPlainObject(value) ? value : {}); + } + // add `source` and associated `value` to the stack of traversed objects + stackA.push(source); + stackB.push(value); + + // recursively merge objects and arrays (susceptible to call stack limits) + if (!isShallow) { + baseMerge(value, source, callback, stackA, stackB); + } + } + } + else { + if (callback) { + result = callback(value, source); + if (typeof result == 'undefined') { + result = source; + } + } + if (typeof result != 'undefined') { + value = result; + } + } + object[key] = value; + }); + } + + /** + * The base implementation of `_.random` without argument juggling or support + * for returning floating-point numbers. + * + * @private + * @param {number} min The minimum possible value. + * @param {number} max The maximum possible value. + * @returns {number} Returns a random number. + */ + function baseRandom(min, max) { + return min + floor(nativeRandom() * (max - min + 1)); + } + + /** + * The base implementation of `_.uniq` without support for callback shorthands + * or `thisArg` binding. + * + * @private + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function} [callback] The function called per iteration. + * @returns {Array} Returns a duplicate-value-free array. + */ + function baseUniq(array, isSorted, callback) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + result = []; + + var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf, + seen = (callback || isLarge) ? getArray() : result; + + if (isLarge) { + var cache = createCache(seen); + indexOf = cacheIndexOf; + seen = cache; + } + while (++index < length) { + var value = array[index], + computed = callback ? callback(value, index, array) : value; + + if (isSorted + ? !index || seen[seen.length - 1] !== computed + : indexOf(seen, computed) < 0 + ) { + if (callback || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + if (isLarge) { + releaseArray(seen.array); + releaseObject(seen); + } else if (callback) { + releaseArray(seen); + } + return result; + } + + /** + * Creates a function that aggregates a collection, creating an object composed + * of keys generated from the results of running each element of the collection + * through a callback. The given `setter` function sets the keys and values + * of the composed object. + * + * @private + * @param {Function} setter The setter function. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter) { + return function(collection, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + setter(result, value, callback(value, index, collection), collection); + } + } else { + baseEach(collection, function(value, key, collection) { + setter(result, value, callback(value, key, collection), collection); + }); + } + return result; + }; + } + + /** + * Creates a function that, when called, either curries or invokes `func` + * with an optional `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of method flags to compose. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` + * 8 - `_.curry` (bound) + * 16 - `_.partial` + * 32 - `_.partialRight` + * @param {Array} [partialArgs] An array of arguments to prepend to those + * provided to the new function. + * @param {Array} [partialRightArgs] An array of arguments to append to those + * provided to the new function. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new function. + */ + function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + isPartial = bitmask & 16, + isPartialRight = bitmask & 32; + + if (!isBindKey && !isFunction(func)) { + throw new TypeError; + } + if (isPartial && !partialArgs.length) { + bitmask &= ~16; + isPartial = partialArgs = false; + } + if (isPartialRight && !partialRightArgs.length) { + bitmask &= ~32; + isPartialRight = partialRightArgs = false; + } + var bindData = func && func.__bindData__; + if (bindData && bindData !== true) { + // clone `bindData` + bindData = slice(bindData); + if (bindData[2]) { + bindData[2] = slice(bindData[2]); + } + if (bindData[3]) { + bindData[3] = slice(bindData[3]); + } + // set `thisBinding` is not previously bound + if (isBind && !(bindData[1] & 1)) { + bindData[4] = thisArg; + } + // set if previously bound but not currently (subsequent curried functions) + if (!isBind && bindData[1] & 1) { + bitmask |= 8; + } + // set curried arity if not yet set + if (isCurry && !(bindData[1] & 4)) { + bindData[5] = arity; + } + // append partial left arguments + if (isPartial) { + push.apply(bindData[2] || (bindData[2] = []), partialArgs); + } + // append partial right arguments + if (isPartialRight) { + unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); + } + // merge flags + bindData[1] |= bitmask; + return createWrapper.apply(null, bindData); + } + // fast path for `_.bind` + var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; + return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); + } + + /** + * Creates compiled iteration functions. + * + * @private + * @param {...Object} [options] The compile options object(s). + * @param {string} [options.array] Code to determine if the iterable is an array or array-like. + * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop. + * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration. + * @param {string} [options.args] A comma separated string of iteration function arguments. + * @param {string} [options.top] Code to execute before the iteration branches. + * @param {string} [options.loop] Code to execute in the object loop. + * @param {string} [options.bottom] Code to execute after the iteration branches. + * @returns {Function} Returns the compiled function. + */ + function createIterator() { + // data properties + iteratorData.shadowedProps = shadowedProps; + + // iterator options + iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = ''; + iteratorData.init = 'iterable'; + iteratorData.useHas = true; + + // merge options into a template data object + for (var object, index = 0; object = arguments[index]; index++) { + for (var key in object) { + iteratorData[key] = object[key]; + } + } + var args = iteratorData.args; + iteratorData.firstArg = /^[^,]+/.exec(args)[0]; + + // create the function factory + var factory = Function( + 'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' + + 'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' + + 'objectTypes, nonEnumProps, stringClass, stringProto, toString', + 'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}' + ); + + // return the compiled function + return factory( + baseCreateCallback, errorClass, errorProto, hasOwnProperty, + indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto, + objectTypes, nonEnumProps, stringClass, stringProto, toString + ); + } + + /** + * Used by `escape` to convert characters to HTML entities. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(match) { + return htmlEscapes[match]; + } + + /** + * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * customized, this method returns the custom method, otherwise it returns + * the `baseIndexOf` function. + * + * @private + * @returns {Function} Returns the "indexOf" function. + */ + function getIndexOf() { + var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; + return result; + } + + /** + * Checks if `value` is a native function. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. + */ + function isNative(value) { + return typeof value == 'function' && reNative.test(value); + } + + /** + * Sets `this` binding data on a given function. + * + * @private + * @param {Function} func The function to set data on. + * @param {Array} value The data array to set. + */ + var setBindData = !defineProperty ? noop : function(func, value) { + descriptor.value = value; + defineProperty(func, '__bindData__', descriptor); + descriptor.value = null; + }; + + /** + * A fallback implementation of `isPlainObject` which checks if a given value + * is an object created by the `Object` constructor, assuming objects created + * by the `Object` constructor have no inherited enumerable properties and that + * there are no `Object.prototype` extensions. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + */ + function shimIsPlainObject(value) { + var ctor, + result; + + // avoid non Object objects, `arguments` objects, and DOM elements + if (!(value && toString.call(value) == objectClass) || + (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) || + (!support.argsClass && isArguments(value)) || + (!support.nodeClass && isNode(value))) { + return false; + } + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + if (support.ownLast) { + forIn(value, function(value, key, object) { + result = hasOwnProperty.call(object, key); + return false; + }); + return result !== false; + } + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + forIn(value, function(value, key) { + result = key; + }); + return typeof result == 'undefined' || hasOwnProperty.call(value, result); + } + + /** + * Used by `unescape` to convert HTML entities to characters. + * + * @private + * @param {string} match The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(match) { + return htmlUnescapes[match]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Checks if `value` is an `arguments` object. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. + * @example + * + * (function() { return _.isArguments(arguments); })(1, 2, 3); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == argsClass || false; + } + // fallback for browsers that can't detect `arguments` objects by [[Class]] + if (!support.argsClass) { + isArguments = function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false; + }; + } + + /** + * Checks if `value` is an array. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an array, else `false`. + * @example + * + * (function() { return _.isArray(arguments); })(); + * // => false + * + * _.isArray([1, 2, 3]); + * // => true + */ + var isArray = nativeIsArray || function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == arrayClass || false; + }; + + /** + * A fallback implementation of `Object.keys` which produces an array of the + * given object's own enumerable property names. + * + * @private + * @type Function + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + */ + var shimKeys = createIterator({ + 'args': 'object', + 'init': '[]', + 'top': 'if (!(objectTypes[typeof object])) return result', + 'loop': 'result.push(index)' + }); + + /** + * Creates an array composed of the own enumerable property names of an object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + * @example + * + * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); + * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) + */ + var keys = !nativeKeys ? shimKeys : function(object) { + if (!isObject(object)) { + return []; + } + if ((support.enumPrototypes && typeof object == 'function') || + (support.nonEnumArgs && object.length && isArguments(object))) { + return shimKeys(object); + } + return nativeKeys(object); + }; + + /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */ + var eachIteratorOptions = { + 'args': 'collection, callback, thisArg', + 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)", + 'array': "typeof length == 'number'", + 'keys': keys, + 'loop': 'if (callback(iterable[index], index, collection) === false) return result' + }; + + /** Reusable iterator options for `assign` and `defaults` */ + var defaultsIteratorOptions = { + 'args': 'object, source, guard', + 'top': + 'var args = arguments,\n' + + ' argsIndex = 0,\n' + + " argsLength = typeof guard == 'number' ? 2 : args.length;\n" + + 'while (++argsIndex < argsLength) {\n' + + ' iterable = args[argsIndex];\n' + + ' if (iterable && objectTypes[typeof iterable]) {', + 'keys': keys, + 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]", + 'bottom': ' }\n}' + }; + + /** Reusable iterator options for `forIn` and `forOwn` */ + var forOwnIteratorOptions = { + 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top, + 'array': false + }; + + /** + * Used to convert characters to HTML entities: + * + * Though the `>` character is escaped for symmetry, characters like `>` and `/` + * don't require escaping in HTML and have no special meaning unless they're part + * of a tag or an unquoted attribute value. + * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") + */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + /** Used to convert HTML entities to characters */ + var htmlUnescapes = invert(htmlEscapes); + + /** Used to match HTML entities and HTML characters */ + var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), + reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); + + /** + * A function compiled to iterate `arguments` objects, arrays, objects, and + * strings consistenly across environments, executing the callback for each + * element in the collection. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index|key, collection). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @private + * @type Function + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEach = createIterator(eachIteratorOptions); + + /*--------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources will overwrite property assignments of previous + * sources. If a callback is provided it will be executed to produce the + * assigned values. The callback is bound to `thisArg` and invoked with two + * arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @type Function + * @alias extend + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param {Function} [callback] The function to customize assigning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); + * // => { 'name': 'fred', 'employer': 'slate' } + * + * var defaults = _.partialRight(_.assign, function(a, b) { + * return typeof a == 'undefined' ? b : a; + * }); + * + * var object = { 'name': 'barney' }; + * defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + var assign = createIterator(defaultsIteratorOptions, { + 'top': + defaultsIteratorOptions.top.replace(';', + ';\n' + + "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" + + ' var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' + + "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" + + ' callback = args[--argsLength];\n' + + '}' + ), + 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]' + }); + + /** + * Creates a clone of `value`. If `isDeep` is `true` nested objects will also + * be cloned, otherwise they will be assigned by reference. If a callback + * is provided it will be executed to produce the cloned values. If the + * callback returns `undefined` cloning will be handled by the method instead. + * The callback is bound to `thisArg` and invoked with one argument; (value). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to clone. + * @param {boolean} [isDeep=false] Specify a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the cloned value. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * var shallow = _.clone(characters); + * shallow[0] === characters[0]; + * // => true + * + * var deep = _.clone(characters, true); + * deep[0] === characters[0]; + * // => false + * + * _.mixin({ + * 'clone': _.partialRight(_.clone, function(value) { + * return _.isElement(value) ? value.cloneNode(false) : undefined; + * }) + * }); + * + * var clone = _.clone(document.body); + * clone.childNodes.length; + * // => 0 + */ + function clone(value, isDeep, callback, thisArg) { + // allows working with "Collections" methods without using their `index` + // and `collection` arguments for `isDeep` and `callback` + if (typeof isDeep != 'boolean' && isDeep != null) { + thisArg = callback; + callback = isDeep; + isDeep = false; + } + return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + } + + /** + * Creates a deep clone of `value`. If a callback is provided it will be + * executed to produce the cloned values. If the callback returns `undefined` + * cloning will be handled by the method instead. The callback is bound to + * `thisArg` and invoked with one argument; (value). + * + * Note: This method is loosely based on the structured clone algorithm. Functions + * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and + * objects created by constructors other than `Object` are cloned to plain `Object` objects. + * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the deep cloned value. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * var deep = _.cloneDeep(characters); + * deep[0] === characters[0]; + * // => false + * + * var view = { + * 'label': 'docs', + * 'node': element + * }; + * + * var clone = _.cloneDeep(view, function(value) { + * return _.isElement(value) ? value.cloneNode(true) : undefined; + * }); + * + * clone.node == view.node; + * // => false + */ + function cloneDeep(value, callback, thisArg) { + return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + } + + /** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties ? assign(result, properties) : result; + } + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional defaults of the same property will be ignored. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param- {Object} [guard] Allows working with `_.reduce` without using its + * `key` and `object` arguments as sources. + * @returns {Object} Returns the destination object. + * @example + * + * var object = { 'name': 'barney' }; + * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + var defaults = createIterator(defaultsIteratorOptions); + + /** + * This method is like `_.findIndex` except that it returns the key of the + * first element that passes the callback check, instead of the element itself. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to search. + * @param {Function|Object|string} [callback=identity] The function called per + * iteration. If a property name or object is provided it will be used to + * create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @example + * + * var characters = { + * 'barney': { 'age': 36, 'blocked': false }, + * 'fred': { 'age': 40, 'blocked': true }, + * 'pebbles': { 'age': 1, 'blocked': false } + * }; + * + * _.findKey(characters, function(chr) { + * return chr.age < 40; + * }); + * // => 'barney' (property order is not guaranteed across environments) + * + * // using "_.where" callback shorthand + * _.findKey(characters, { 'age': 1 }); + * // => 'pebbles' + * + * // using "_.pluck" callback shorthand + * _.findKey(characters, 'blocked'); + * // => 'fred' + */ + function findKey(object, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forOwn(object, function(value, key, object) { + if (callback(value, key, object)) { + result = key; + return false; + } + }); + return result; + } + + /** + * This method is like `_.findKey` except that it iterates over elements + * of a `collection` in the opposite order. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to search. + * @param {Function|Object|string} [callback=identity] The function called per + * iteration. If a property name or object is provided it will be used to + * create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @example + * + * var characters = { + * 'barney': { 'age': 36, 'blocked': true }, + * 'fred': { 'age': 40, 'blocked': false }, + * 'pebbles': { 'age': 1, 'blocked': true } + * }; + * + * _.findLastKey(characters, function(chr) { + * return chr.age < 40; + * }); + * // => returns `pebbles`, assuming `_.findKey` returns `barney` + * + * // using "_.where" callback shorthand + * _.findLastKey(characters, { 'age': 40 }); + * // => 'fred' + * + * // using "_.pluck" callback shorthand + * _.findLastKey(characters, 'blocked'); + * // => 'pebbles' + */ + function findLastKey(object, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forOwnRight(object, function(value, key, object) { + if (callback(value, key, object)) { + result = key; + return false; + } + }); + return result; + } + + /** + * Iterates over own and inherited enumerable properties of an object, + * executing the callback for each property. The callback is bound to `thisArg` + * and invoked with three arguments; (value, key, object). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forIn(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) + */ + var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, { + 'useHas': false + }); + + /** + * This method is like `_.forIn` except that it iterates over elements + * of a `collection` in the opposite order. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forInRight(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' + */ + function forInRight(object, callback, thisArg) { + var pairs = []; + + forIn(object, function(value, key) { + pairs.push(key, value); + }); + + var length = pairs.length; + callback = baseCreateCallback(callback, thisArg, 3); + while (length--) { + if (callback(pairs[length--], pairs[length], object) === false) { + break; + } + } + return object; + } + + /** + * Iterates over own enumerable properties of an object, executing the callback + * for each property. The callback is bound to `thisArg` and invoked with three + * arguments; (value, key, object). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) + */ + var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions); + + /** + * This method is like `_.forOwn` except that it iterates over elements + * of a `collection` in the opposite order. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' + */ + function forOwnRight(object, callback, thisArg) { + var props = keys(object), + length = props.length; + + callback = baseCreateCallback(callback, thisArg, 3); + while (length--) { + var key = props[length]; + if (callback(object[key], key, object) === false) { + break; + } + } + return object; + } + + /** + * Creates a sorted array of property names of all enumerable properties, + * own and inherited, of `object` that have function values. + * + * @static + * @memberOf _ + * @alias methods + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names that have function values. + * @example + * + * _.functions(_); + * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] + */ + function functions(object) { + var result = []; + forIn(object, function(value, key) { + if (isFunction(value)) { + result.push(key); + } + }); + return result.sort(); + } + + /** + * Checks if the specified property name exists as a direct property of `object`, + * instead of an inherited property. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to check. + * @returns {boolean} Returns `true` if key is a direct property, else `false`. + * @example + * + * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); + * // => true + */ + function has(object, key) { + return object ? hasOwnProperty.call(object, key) : false; + } + + /** + * Creates an object composed of the inverted keys and values of the given object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to invert. + * @returns {Object} Returns the created inverted object. + * @example + * + * _.invert({ 'first': 'fred', 'second': 'barney' }); + * // => { 'fred': 'first', 'barney': 'second' } + */ + function invert(object) { + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + result[object[key]] = key; + } + return result; + } + + /** + * Checks if `value` is a boolean value. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. + * @example + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + value && typeof value == 'object' && toString.call(value) == boolClass || false; + } + + /** + * Checks if `value` is a date. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a date, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + */ + function isDate(value) { + return value && typeof value == 'object' && toString.call(value) == dateClass || false; + } + + /** + * Checks if `value` is a DOM element. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + */ + function isElement(value) { + return value && value.nodeType === 1 || false; + } + + /** + * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a + * length of `0` and objects with no own enumerable properties are considered + * "empty". + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if the `value` is empty, else `false`. + * @example + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({}); + * // => true + * + * _.isEmpty(''); + * // => true + */ + function isEmpty(value) { + var result = true; + if (!value) { + return result; + } + var className = toString.call(value), + length = value.length; + + if ((className == arrayClass || className == stringClass || + (support.argsClass ? className == argsClass : isArguments(value))) || + (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { + return !length; + } + forOwn(value, function() { + return (result = false); + }); + return result; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent to each other. If a callback is provided it will be executed + * to compare values. If the callback returns `undefined` comparisons will + * be handled by the method instead. The callback is bound to `thisArg` and + * invoked with two arguments; (a, b). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'name': 'fred' }; + * var copy = { 'name': 'fred' }; + * + * object == copy; + * // => false + * + * _.isEqual(object, copy); + * // => true + * + * var words = ['hello', 'goodbye']; + * var otherWords = ['hi', 'goodbye']; + * + * _.isEqual(words, otherWords, function(a, b) { + * var reGreet = /^(?:hello|hi)$/i, + * aGreet = _.isString(a) && reGreet.test(a), + * bGreet = _.isString(b) && reGreet.test(b); + * + * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; + * }); + * // => true + */ + function isEqual(a, b, callback, thisArg) { + return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2)); + } + + /** + * Checks if `value` is, or can be coerced to, a finite number. + * + * Note: This is not the same as native `isFinite` which will return true for + * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is finite, else `false`. + * @example + * + * _.isFinite(-101); + * // => true + * + * _.isFinite('10'); + * // => true + * + * _.isFinite(true); + * // => false + * + * _.isFinite(''); + * // => false + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); + } + + /** + * Checks if `value` is a function. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + */ + function isFunction(value) { + return typeof value == 'function'; + } + // fallback for older versions of Chrome and Safari + if (isFunction(/x/)) { + isFunction = function(value) { + return typeof value == 'function' && toString.call(value) == funcClass; + }; + } + + /** + * Checks if `value` is the language type of Object. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ + function isObject(value) { + // check if the value is the ECMAScript language type of Object + // http://es5.github.io/#x8 + // and avoid a V8 bug + // http://code.google.com/p/v8/issues/detail?id=2291 + return !!(value && objectTypes[typeof value]); + } + + /** + * Checks if `value` is `NaN`. + * + * Note: This is not the same as native `isNaN` which will return `true` for + * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // `NaN` as a primitive is the only value that is not equal to itself + // (perform the [[Class]] check first to avoid errors with some host objects in IE) + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(undefined); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is a number. + * + * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a number, else `false`. + * @example + * + * _.isNumber(8.4 * 5); + * // => true + */ + function isNumber(value) { + return typeof value == 'number' || + value && typeof value == 'object' && toString.call(value) == numberClass || false; + } + + /** + * Checks if `value` is an object created by the `Object` constructor. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * _.isPlainObject(new Shape); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + */ + var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { + if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) { + return false; + } + var valueOf = value.valueOf, + objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); + + return objProto + ? (value == objProto || getPrototypeOf(value) == objProto) + : shimIsPlainObject(value); + }; + + /** + * Checks if `value` is a regular expression. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. + * @example + * + * _.isRegExp(/fred/); + * // => true + */ + function isRegExp(value) { + return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false; + } + + /** + * Checks if `value` is a string. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a string, else `false`. + * @example + * + * _.isString('fred'); + * // => true + */ + function isString(value) { + return typeof value == 'string' || + value && typeof value == 'object' && toString.call(value) == stringClass || false; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + */ + function isUndefined(value) { + return typeof value == 'undefined'; + } + + /** + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through the callback. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new object with values of the results of each `callback` execution. + * @example + * + * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + * + * var characters = { + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * }; + * + * // using "_.pluck" callback shorthand + * _.mapValues(characters, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } + */ + function mapValues(object, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + + forOwn(object, function(value, key, object) { + result[key] = callback(value, key, object); + }); + return result; + } + + /** + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * will overwrite property assignments of previous sources. If a callback is + * provided it will be executed to produce the merged values of the destination + * and source properties. If the callback returns `undefined` merging will + * be handled by the method instead. The callback is bound to `thisArg` and + * invoked with two arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param {Function} [callback] The function to customize merging properties. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * var names = { + * 'characters': [ + * { 'name': 'barney' }, + * { 'name': 'fred' } + * ] + * }; + * + * var ages = { + * 'characters': [ + * { 'age': 36 }, + * { 'age': 40 } + * ] + * }; + * + * _.merge(names, ages); + * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } + * + * var food = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var otherFood = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(food, otherFood, function(a, b) { + * return _.isArray(a) ? a.concat(b) : undefined; + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } + */ + function merge(object) { + var args = arguments, + length = 2; + + if (!isObject(object)) { + return object; + } + // allows working with `_.reduce` and `_.reduceRight` without using + // their `index` and `collection` arguments + if (typeof args[2] != 'number') { + length = args.length; + } + if (length > 3 && typeof args[length - 2] == 'function') { + var callback = baseCreateCallback(args[--length - 1], args[length--], 2); + } else if (length > 2 && typeof args[length - 1] == 'function') { + callback = args[--length]; + } + var sources = slice(arguments, 1, length), + index = -1, + stackA = getArray(), + stackB = getArray(); + + while (++index < length) { + baseMerge(object, sources[index], callback, stackA, stackB); + } + releaseArray(stackA); + releaseArray(stackB); + return object; + } + + /** + * Creates a shallow clone of `object` excluding the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` omitting the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The properties to omit or the + * function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object without the omitted properties. + * @example + * + * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); + * // => { 'name': 'fred' } + * + * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { + * return typeof value == 'number'; + * }); + * // => { 'name': 'fred' } + */ + function omit(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var props = []; + forIn(object, function(value, key) { + props.push(key); + }); + props = baseDifference(props, baseFlatten(arguments, true, false, 1)); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + result[key] = object[key]; + } + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (!callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * Creates a two dimensional array of an object's key-value pairs, + * i.e. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns new array of key-value pairs. + * @example + * + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) + */ + function pairs(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; + } + + /** + * Creates a shallow clone of `object` composed of the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` picking the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The function called per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object composed of the picked properties. + * @example + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); + * // => { 'name': 'fred' } + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { + * return key.charAt(0) != '_'; + * }); + * // => { 'name': 'fred' } + */ + function pick(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var index = -1, + props = baseFlatten(arguments, true, false, 1), + length = isObject(object) ? props.length : 0; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * An alternative to `_.reduce` this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own + * enumerable properties through a callback, with each callback execution + * potentially mutating the `accumulator` object. The callback is bound to + * `thisArg` and invoked with four arguments; (accumulator, value, key, object). + * Callbacks may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) { + * num *= num; + * if (num % 2) { + * return result.push(num) < 3; + * } + * }); + * // => [1, 9, 25] + * + * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function transform(object, callback, accumulator, thisArg) { + var isArr = isArray(object); + if (accumulator == null) { + if (isArr) { + accumulator = []; + } else { + var ctor = object && object.constructor, + proto = ctor && ctor.prototype; + + accumulator = baseCreate(proto); + } + } + if (callback) { + callback = lodash.createCallback(callback, thisArg, 4); + (isArr ? baseEach : forOwn)(object, function(value, index, object) { + return callback(accumulator, value, index, object); + }); + } + return accumulator; + } + + /** + * Creates an array composed of the own enumerable property values of `object`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property values. + * @example + * + * _.values({ 'one': 1, 'two': 2, 'three': 3 }); + * // => [1, 2, 3] (property order is not guaranteed across environments) + */ + function values(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array of elements from the specified indexes, or keys, of the + * `collection`. Indexes may be specified as individual arguments or as arrays + * of indexes. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [index] The indexes of `collection` + * to retrieve, specified as individual indexes or arrays of indexes. + * @returns {Array} Returns a new array of elements corresponding to the + * provided indexes. + * @example + * + * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); + * // => ['a', 'c', 'e'] + * + * _.at(['fred', 'barney', 'pebbles'], 0, 2); + * // => ['fred', 'pebbles'] + */ + function at(collection) { + var args = arguments, + index = -1, + props = baseFlatten(args, true, false, 1), + length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length, + result = Array(length); + + if (support.unindexedChars && isString(collection)) { + collection = collection.split(''); + } + while(++index < length) { + result[index] = collection[props[index]]; + } + return result; + } + + /** + * Checks if a given value is present in a collection using strict equality + * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the + * offset from the end of the collection. + * + * @static + * @memberOf _ + * @alias include + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {*} target The value to check for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {boolean} Returns `true` if the `target` element is found, else `false`. + * @example + * + * _.contains([1, 2, 3], 1); + * // => true + * + * _.contains([1, 2, 3], 1, 2); + * // => false + * + * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.contains('pebbles', 'eb'); + * // => true + */ + function contains(collection, target, fromIndex) { + var index = -1, + indexOf = getIndexOf(), + length = collection ? collection.length : 0, + result = false; + + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; + if (isArray(collection)) { + result = indexOf(collection, target, fromIndex) > -1; + } else if (typeof length == 'number') { + result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1; + } else { + baseEach(collection, function(value) { + if (++index >= fromIndex) { + return !(result = value === target); + } + }); + } + return result; + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through the callback. The corresponding value + * of each key is the number of times the key was returned by the callback. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); + }); + + /** + * Checks if the given callback returns truey value for **all** elements of + * a collection. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if all elements passed the callback check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes']); + * // => false + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.every(characters, 'age'); + * // => true + * + * // using "_.where" callback shorthand + * _.every(characters, { 'age': 36 }); + * // => false + */ + function every(collection, callback, thisArg) { + var result = true; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (!(result = !!callback(collection[index], index, collection))) { + break; + } + } + } else { + baseEach(collection, function(value, index, collection) { + return (result = !!callback(value, index, collection)); + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning an array of all elements + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that passed the callback check. + * @example + * + * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [2, 4, 6] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.filter(characters, 'blocked'); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + * + * // using "_.where" callback shorthand + * _.filter(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + */ + function filter(collection, callback, thisArg) { + var result = []; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + result.push(value); + } + } + } else { + baseEach(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result.push(value); + } + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning the first element that + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias detect, findWhere + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.find(characters, function(chr) { + * return chr.age < 40; + * }); + * // => { 'name': 'barney', 'age': 36, 'blocked': false } + * + * // using "_.where" callback shorthand + * _.find(characters, { 'age': 1 }); + * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } + * + * // using "_.pluck" callback shorthand + * _.find(characters, 'blocked'); + * // => { 'name': 'fred', 'age': 40, 'blocked': true } + */ + function find(collection, callback, thisArg) { + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + return value; + } + } + } else { + var result; + baseEach(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + } + + /** + * This method is like `_.find` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(num) { + * return num % 2 == 1; + * }); + * // => 3 + */ + function findLast(collection, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forEachRight(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + + /** + * Iterates over elements of a collection, executing the callback for each + * element. The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * Note: As with other "Collections" methods, objects with a `length` property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); + * // => logs each number and returns '1,2,3' + * + * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); + * // => logs each number and returns the object (property order is not guaranteed across environments) + */ + function forEach(collection, callback, thisArg) { + if (callback && typeof thisArg == 'undefined' && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (callback(collection[index], index, collection) === false) { + break; + } + } + } else { + baseEach(collection, callback, thisArg); + } + return collection; + } + + /** + * This method is like `_.forEach` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); + * // => logs each number from right to left and returns '3,2,1' + */ + function forEachRight(collection, callback, thisArg) { + var iterable = collection, + length = collection ? collection.length : 0; + + callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); + if (isArray(collection)) { + while (length--) { + if (callback(collection[length], length, collection) === false) { + break; + } + } + } else { + if (typeof length != 'number') { + var props = keys(collection); + length = props.length; + } else if (support.unindexedChars && isString(collection)) { + iterable = collection.split(''); + } + baseEach(collection, function(value, key, collection) { + key = props ? props[--length] : --length; + return callback(iterable[key], key, collection); + }); + } + return collection; + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of a collection through the callback. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false` + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using "_.pluck" callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of the collection through the given callback. The corresponding + * value of each key is the last element responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keys = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keys, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Invokes the method named by `methodName` on each element in the `collection` + * returning an array of the results of each invoked method. Additional arguments + * will be provided to each invoked method. If `methodName` is a function it + * will be invoked for, and `this` bound to, each element in the `collection`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|string} methodName The name of the method to invoke or + * the function invoked per iteration. + * @param {...*} [arg] Arguments to invoke the method with. + * @returns {Array} Returns a new array of the results of each invoked method. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + function invoke(collection, methodName) { + var args = slice(arguments, 2), + index = -1, + isFunc = typeof methodName == 'function', + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); + }); + return result; + } + + /** + * Creates an array of values by running each element in the collection + * through the callback. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias collect + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of the results of each `callback` execution. + * @example + * + * _.map([1, 2, 3], function(num) { return num * 3; }); + * // => [3, 6, 9] + * + * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); + * // => [3, 6, 9] (property order is not guaranteed across environments) + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(characters, 'name'); + * // => ['barney', 'fred'] + */ + function map(collection, callback, thisArg) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + callback = lodash.createCallback(callback, thisArg, 3); + if (isArray(collection)) { + while (++index < length) { + result[index] = callback(collection[index], index, collection); + } + } else { + baseEach(collection, function(value, key, collection) { + result[++index] = callback(value, key, collection); + }); + } + return result; + } + + /** + * Retrieves the maximum value of a collection. If the collection is empty or + * falsey `-Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.max(characters, function(chr) { return chr.age; }); + * // => { 'name': 'fred', 'age': 40 }; + * + * // using "_.pluck" callback shorthand + * _.max(characters, 'age'); + * // => { 'name': 'fred', 'age': 40 }; + */ + function max(collection, callback, thisArg) { + var computed = -Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value > result) { + result = value; + } + } + } else { + callback = (callback == null && isString(collection)) + ? charAtCallback + : lodash.createCallback(callback, thisArg, 3); + + baseEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current > computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the minimum value of a collection. If the collection is empty or + * falsey `Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.min(characters, function(chr) { return chr.age; }); + * // => { 'name': 'barney', 'age': 36 }; + * + * // using "_.pluck" callback shorthand + * _.min(characters, 'age'); + * // => { 'name': 'barney', 'age': 36 }; + */ + function min(collection, callback, thisArg) { + var computed = Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value < result) { + result = value; + } + } + } else { + callback = (callback == null && isString(collection)) + ? charAtCallback + : lodash.createCallback(callback, thisArg, 3); + + baseEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current < computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the value of a specified property from all elements in the collection. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {string} property The name of the property to pluck. + * @returns {Array} Returns a new array of property values. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.pluck(characters, 'name'); + * // => ['barney', 'fred'] + */ + var pluck = map; + + /** + * Reduces a collection to a value which is the accumulated result of running + * each element in the collection through the callback, where each successive + * callback execution consumes the return value of the previous execution. If + * `accumulator` is not provided the first element of the collection will be + * used as the initial `accumulator` value. The callback is bound to `thisArg` + * and invoked with four arguments; (accumulator, value, index|key, collection). + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var sum = _.reduce([1, 2, 3], function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function reduce(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = lodash.createCallback(callback, thisArg, 4); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + if (noaccum) { + accumulator = collection[++index]; + } + while (++index < length) { + accumulator = callback(accumulator, collection[index], index, collection); + } + } else { + baseEach(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection) + }); + } + return accumulator; + } + + /** + * This method is like `_.reduce` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var list = [[0, 1], [2, 3], [4, 5]]; + * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + function reduceRight(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = lodash.createCallback(callback, thisArg, 4); + forEachRight(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The opposite of `_.filter` this method returns the elements of a + * collection that the callback does **not** return truey for. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that failed the callback check. + * @example + * + * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [1, 3, 5] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.reject(characters, 'blocked'); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + * + * // using "_.where" callback shorthand + * _.reject(characters, { 'age': 36 }); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + */ + function reject(collection, callback, thisArg) { + callback = lodash.createCallback(callback, thisArg, 3); + return filter(collection, function(value, index, collection) { + return !callback(value, index, collection); + }); + } + + /** + * Retrieves a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Allows working with functions like `_.map` + * without using their `index` arguments as `n`. + * @returns {Array} Returns the random sample(s) of `collection`. + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ + function sample(collection, n, guard) { + if (collection && typeof collection.length != 'number') { + collection = values(collection); + } else if (support.unindexedChars && isString(collection)) { + collection = collection.split(''); + } + if (n == null || guard) { + return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; + } + var result = shuffle(collection); + result.length = nativeMin(nativeMax(0, n), result.length); + return result; + } + + /** + * Creates an array of shuffled values, using a version of the Fisher-Yates + * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns a new shuffled collection. + * @example + * + * _.shuffle([1, 2, 3, 4, 5, 6]); + * // => [4, 1, 6, 3, 5, 2] + */ + function shuffle(collection) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + var rand = baseRandom(0, ++index); + result[index] = result[rand]; + result[rand] = value; + }); + return result; + } + + /** + * Gets the size of the `collection` by returning `collection.length` for arrays + * and array-like objects or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns `collection.length` or number of own enumerable properties. + * @example + * + * _.size([1, 2]); + * // => 2 + * + * _.size({ 'one': 1, 'two': 2, 'three': 3 }); + * // => 3 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + var length = collection ? collection.length : 0; + return typeof length == 'number' ? length : keys(collection).length; + } + + /** + * Checks if the callback returns a truey value for **any** element of a + * collection. The function returns as soon as it finds a passing value and + * does not iterate over the entire collection. The callback is bound to + * `thisArg` and invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if any element passed the callback check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.some(characters, 'blocked'); + * // => true + * + * // using "_.where" callback shorthand + * _.some(characters, { 'age': 1 }); + * // => false + */ + function some(collection, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if ((result = callback(collection[index], index, collection))) { + break; + } + } + } else { + baseEach(collection, function(value, index, collection) { + return !(result = callback(value, index, collection)); + }); + } + return !!result; + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through the callback. This method + * performs a stable sort, that is, it will preserve the original sort order + * of equal elements. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an array of property names is provided for `callback` the collection + * will be sorted by each property value. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of sorted elements. + * @example + * + * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); + * // => [3, 1, 2] + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 26 }, + * { 'name': 'fred', 'age': 30 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(_.sortBy(characters, 'age'), _.values); + * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] + * + * // sorting by multiple properties + * _.map(_.sortBy(characters, ['name', 'age']), _.values); + * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] + */ + function sortBy(collection, callback, thisArg) { + var index = -1, + isArr = isArray(callback), + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + if (!isArr) { + callback = lodash.createCallback(callback, thisArg, 3); + } + forEach(collection, function(value, key, collection) { + var object = result[++index] = getObject(); + if (isArr) { + object.criteria = map(callback, function(key) { return value[key]; }); + } else { + (object.criteria = getArray())[0] = callback(value, key, collection); + } + object.index = index; + object.value = value; + }); + + length = result.length; + result.sort(compareAscending); + while (length--) { + var object = result[length]; + result[length] = object.value; + if (!isArr) { + releaseArray(object.criteria); + } + releaseObject(object); + } + return result; + } + + /** + * Converts the `collection` to an array. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to convert. + * @returns {Array} Returns the new converted array. + * @example + * + * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); + * // => [2, 3, 4] + */ + function toArray(collection) { + if (collection && typeof collection.length == 'number') { + return (support.unindexedChars && isString(collection)) + ? collection.split('') + : slice(collection); + } + return values(collection); + } + + /** + * Performs a deep comparison of each element in a `collection` to the given + * `properties` object, returning an array of all elements that have equivalent + * property values. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Object} props The object of property values to filter by. + * @returns {Array} Returns a new array of elements that have the given properties. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.where(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] + * + * _.where(characters, { 'pets': ['dino'] }); + * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] + */ + var where = filter; + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are all falsey. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to compact. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result.push(value); + } + } + return result; + } + + /** + * Creates an array excluding all values of the provided arrays using strict + * equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to process. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); + * // => [1, 3, 4] + */ + function difference(array) { + return baseDifference(array, baseFlatten(arguments, true, true, 1)); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element that passes the callback check, instead of the element itself. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.findIndex(characters, function(chr) { + * return chr.age < 20; + * }); + * // => 2 + * + * // using "_.where" callback shorthand + * _.findIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findIndex(characters, 'blocked'); + * // => 1 + */ + function findIndex(array, callback, thisArg) { + var index = -1, + length = array ? array.length : 0; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length) { + if (callback(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of a `collection` from right to left. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': true }, + * { 'name': 'fred', 'age': 40, 'blocked': false }, + * { 'name': 'pebbles', 'age': 1, 'blocked': true } + * ]; + * + * _.findLastIndex(characters, function(chr) { + * return chr.age > 30; + * }); + * // => 1 + * + * // using "_.where" callback shorthand + * _.findLastIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findLastIndex(characters, 'blocked'); + * // => 2 + */ + function findLastIndex(array, callback, thisArg) { + var length = array ? array.length : 0; + callback = lodash.createCallback(callback, thisArg, 3); + while (length--) { + if (callback(array[length], length, array)) { + return length; + } + } + return -1; + } + + /** + * Gets the first element or first `n` elements of an array. If a callback + * is provided elements at the beginning of the array are returned as long + * as the callback returns truey. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias head, take + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the first element(s) of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([1, 2, 3], 2); + * // => [1, 2] + * + * _.first([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [1, 2] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.first(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); + * // => ['barney', 'fred'] + */ + function first(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = -1; + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[0] : undefined; + } + } + return slice(array, 0, nativeMin(nativeMax(0, n), length)); + } + + /** + * Flattens a nested array (the nesting can be to any depth). If `isShallow` + * is truey, the array will only be flattened a single level. If a callback + * is provided each element of the array is passed through the callback before + * flattening. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new flattened array. + * @example + * + * _.flatten([1, [2], [3, [[4]]]]); + * // => [1, 2, 3, 4]; + * + * _.flatten([1, [2], [3, [[4]]]], true); + * // => [1, 2, 3, [[4]]]; + * + * var characters = [ + * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * // using "_.pluck" callback shorthand + * _.flatten(characters, 'pets'); + * // => ['hoppy', 'baby puss', 'dino'] + */ + function flatten(array, isShallow, callback, thisArg) { + // juggle arguments + if (typeof isShallow != 'boolean' && isShallow != null) { + thisArg = callback; + callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; + isShallow = false; + } + if (callback != null) { + array = map(array, callback, thisArg); + } + return baseFlatten(array, isShallow); + } + + /** + * Gets the index at which the first occurrence of `value` is found using + * strict equality for comparisons, i.e. `===`. If the array is already sorted + * providing `true` for `fromIndex` will run a faster binary search. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2); + * // => 1 + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 4 + * + * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + if (typeof fromIndex == 'number') { + var length = array ? array.length : 0; + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); + } else if (fromIndex) { + var index = sortedIndex(array, value); + return array[index] === value ? index : -1; + } + return baseIndexOf(array, value, fromIndex); + } + + /** + * Gets all but the last element or last `n` elements of an array. If a + * callback is provided elements at the end of the array are excluded from + * the result as long as the callback returns truey. The callback is bound + * to `thisArg` and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + * + * _.initial([1, 2, 3], 2); + * // => [1] + * + * _.initial([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [1] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.initial(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); + * // => ['barney', 'fred'] + */ + function initial(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = lodash.createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : callback || n; + } + return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); + } + + /** + * Creates an array of unique values present in all provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of shared values. + * @example + * + * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2] + */ + function intersection() { + var args = [], + argsIndex = -1, + argsLength = arguments.length, + caches = getArray(), + indexOf = getIndexOf(), + trustIndexOf = indexOf === baseIndexOf, + seen = getArray(); + + while (++argsIndex < argsLength) { + var value = arguments[argsIndex]; + if (isArray(value) || isArguments(value)) { + args.push(value); + caches.push(trustIndexOf && value.length >= largeArraySize && + createCache(argsIndex ? args[argsIndex] : seen)); + } + } + var array = args[0], + index = -1, + length = array ? array.length : 0, + result = []; + + outer: + while (++index < length) { + var cache = caches[0]; + value = array[index]; + + if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) { + argsIndex = argsLength; + (cache || seen).push(value); + while (--argsIndex) { + cache = caches[argsIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { + continue outer; + } + } + result.push(value); + } + } + while (argsLength--) { + cache = caches[argsLength]; + if (cache) { + releaseObject(cache); + } + } + releaseArray(caches); + releaseArray(seen); + return result; + } + + /** + * Gets the last element or last `n` elements of an array. If a callback is + * provided elements at the end of the array are returned as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the last element(s) of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + * + * _.last([1, 2, 3], 2); + * // => [2, 3] + * + * _.last([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [2, 3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.last(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.last(characters, { 'employer': 'na' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function last(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = lodash.createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[length - 1] : undefined; + } + } + return slice(array, nativeMax(0, length - n)); + } + + /** + * Gets the index at which the last occurrence of `value` is found using strict + * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used + * as the offset from the end of the collection. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); + * // => 4 + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 1 + */ + function lastIndexOf(array, value, fromIndex) { + var index = array ? array.length : 0; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Removes all provided values from the given array using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to modify. + * @param {...*} [value] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ + function pull(array) { + var args = arguments, + argsIndex = 0, + argsLength = args.length, + length = array ? array.length : 0; + + while (++argsIndex < argsLength) { + var index = -1, + value = args[argsIndex]; + while (++index < length) { + if (array[index] === value) { + splice.call(array, index--, 1); + length--; + } + } + } + return array; + } + + /** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to but not including `end`. If `start` is less than `stop` a + * zero-length range is created unless a negative `step` is specified. + * + * @static + * @memberOf _ + * @category Arrays + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns a new range array. + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ + function range(start, end, step) { + start = +start || 0; + step = typeof step == 'number' ? step : (+step || 1); + + if (end == null) { + end = start; + start = 0; + } + // use `Array(length)` so engines like Chakra and V8 avoid slower modes + // http://youtu.be/XAqIpGU8ZZk#t=17m25s + var index = -1, + length = nativeMax(0, ceil((end - start) / (step || 1))), + result = Array(length); + + while (++index < length) { + result[index] = start; + start += step; + } + return result; + } + + /** + * Removes all elements from an array that the callback returns truey for + * and returns an array of removed elements. The callback is bound to `thisArg` + * and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to modify. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4, 5, 6]; + * var evens = _.remove(array, function(num) { return num % 2 == 0; }); + * + * console.log(array); + * // => [1, 3, 5] + * + * console.log(evens); + * // => [2, 4, 6] + */ + function remove(array, callback, thisArg) { + var index = -1, + length = array ? array.length : 0, + result = []; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (callback(value, index, array)) { + result.push(value); + splice.call(array, index--, 1); + length--; + } + } + return result; + } + + /** + * The opposite of `_.initial` this method gets all but the first element or + * first `n` elements of an array. If a callback function is provided elements + * at the beginning of the array are excluded from the result as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias drop, tail + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + * + * _.rest([1, 2, 3], 2); + * // => [3] + * + * _.rest([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.rest(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.rest(characters, { 'employer': 'slate' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function rest(array, callback, thisArg) { + if (typeof callback != 'number' && callback != null) { + var n = 0, + index = -1, + length = array ? array.length : 0; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); + } + return slice(array, n); + } + + /** + * Uses a binary search to determine the smallest index at which a value + * should be inserted into a given sorted array in order to maintain the sort + * order of the array. If a callback is provided it will be executed for + * `value` and each element of `array` to compute their sort ranking. The + * callback is bound to `thisArg` and invoked with one argument; (value). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([20, 30, 50], 40); + * // => 2 + * + * // using "_.pluck" callback shorthand + * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 2 + * + * var dict = { + * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } + * }; + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return dict.wordToNumber[word]; + * }); + * // => 2 + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return this.wordToNumber[word]; + * }, dict); + * // => 2 + */ + function sortedIndex(array, value, callback, thisArg) { + var low = 0, + high = array ? array.length : low; + + // explicitly reference `identity` for better inlining in Firefox + callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; + value = callback(value); + + while (low < high) { + var mid = (low + high) >>> 1; + (callback(array[mid]) < value) + ? low = mid + 1 + : high = mid; + } + return low; + } + + /** + * Creates an array of unique values, in order, of the provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of combined values. + * @example + * + * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2, 3, 5, 4] + */ + function union() { + return baseUniq(baseFlatten(arguments, true, true)); + } + + /** + * Creates a duplicate-value-free version of an array using strict equality + * for comparisons, i.e. `===`. If the array is sorted, providing + * `true` for `isSorted` will use a faster algorithm. If a callback is provided + * each element of `array` is passed through the callback before uniqueness + * is computed. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Arrays + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a duplicate-value-free array. + * @example + * + * _.uniq([1, 2, 1, 3, 1]); + * // => [1, 2, 3] + * + * _.uniq([1, 1, 2, 2, 3], true); + * // => [1, 2, 3] + * + * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); + * // => ['A', 'b', 'C'] + * + * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); + * // => [1, 2.5, 3] + * + * // using "_.pluck" callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniq(array, isSorted, callback, thisArg) { + // juggle arguments + if (typeof isSorted != 'boolean' && isSorted != null) { + thisArg = callback; + callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; + isSorted = false; + } + if (callback != null) { + callback = lodash.createCallback(callback, thisArg, 3); + } + return baseUniq(array, isSorted, callback); + } + + /** + * Creates an array excluding all provided values using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to filter. + * @param {...*} [value] The values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); + * // => [2, 3, 4] + */ + function without(array) { + return baseDifference(array, slice(arguments, 1)); + } + + /** + * Creates an array that is the symmetric difference of the provided arrays. + * See http://en.wikipedia.org/wiki/Symmetric_difference. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of values. + * @example + * + * _.xor([1, 2, 3], [5, 2, 1, 4]); + * // => [3, 5, 4] + * + * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); + * // => [1, 4, 5] + */ + function xor() { + var index = -1, + length = arguments.length; + + while (++index < length) { + var array = arguments[index]; + if (isArray(array) || isArguments(array)) { + var result = result + ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result))) + : array; + } + } + return result || []; + } + + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second + * elements of the given arrays, and so on. + * + * @static + * @memberOf _ + * @alias unzip + * @category Arrays + * @param {...Array} [array] Arrays to process. + * @returns {Array} Returns a new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + function zip() { + var array = arguments.length > 1 ? arguments : arguments[0], + index = -1, + length = array ? max(pluck(array, 'length')) : 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = pluck(array, index); + } + return result; + } + + /** + * Creates an object composed from arrays of `keys` and `values`. Provide + * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` + * or two arrays, one of `keys` and one of corresponding `values`. + * + * @static + * @memberOf _ + * @alias object + * @category Arrays + * @param {Array} keys The array of keys. + * @param {Array} [values=[]] The array of values. + * @returns {Object} Returns an object composed of the given keys and + * corresponding values. + * @example + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ + function zipObject(keys, values) { + var index = -1, + length = keys ? keys.length : 0, + result = {}; + + if (!values && length && !isArray(keys[0])) { + values = []; + } + while (++index < length) { + var key = keys[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that executes `func`, with the `this` binding and + * arguments of the created function, only after being called `n` times. + * + * @static + * @memberOf _ + * @category Functions + * @param {number} n The number of times the function must be called before + * `func` is executed. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('Done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'Done saving!', after all saves have completed + */ + function after(n, func) { + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that, when called, invokes `func` with the `this` + * binding of `thisArg` and prepends any additional `bind` arguments to those + * provided to the bound function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var func = function(greeting) { + * return greeting + ' ' + this.name; + * }; + * + * func = _.bind(func, { 'name': 'fred' }, 'hi'); + * func(); + * // => 'hi fred' + */ + function bind(func, thisArg) { + return arguments.length > 2 + ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) + : createWrapper(func, 1, null, null, thisArg); + } + + /** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all the function properties + * of `object` will be bound. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...string} [methodName] The object method names to + * bind, specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { console.log('clicked ' + this.label); } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs', when the button is clicked + */ + function bindAll(object) { + var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), + index = -1, + length = funcs.length; + + while (++index < length) { + var key = funcs[index]; + object[key] = createWrapper(object[key], 1, null, null, object); + } + return object; + } + + /** + * Creates a function that, when called, invokes the method at `object[key]` + * and prepends any additional `bindKey` arguments to those provided to the bound + * function. This method differs from `_.bind` by allowing bound functions to + * reference methods that will be redefined or don't yet exist. + * See http://michaux.ca/articles/lazy-function-definition-pattern. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'name': 'fred', + * 'greet': function(greeting) { + * return greeting + ' ' + this.name; + * } + * }; + * + * var func = _.bindKey(object, 'greet', 'hi'); + * func(); + * // => 'hi fred' + * + * object.greet = function(greeting) { + * return greeting + 'ya ' + this.name + '!'; + * }; + * + * func(); + * // => 'hiya fred!' + */ + function bindKey(object, key) { + return arguments.length > 2 + ? createWrapper(key, 19, slice(arguments, 2), null, object) + : createWrapper(key, 3, null, null, object); + } + + /** + * Creates a function that is the composition of the provided functions, + * where each function consumes the return value of the function that follows. + * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. + * Each function is executed with the `this` binding of the composed function. + * + * @static + * @memberOf _ + * @category Functions + * @param {...Function} [func] Functions to compose. + * @returns {Function} Returns the new composed function. + * @example + * + * var realNameMap = { + * 'pebbles': 'penelope' + * }; + * + * var format = function(name) { + * name = realNameMap[name.toLowerCase()] || name; + * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); + * }; + * + * var greet = function(formatted) { + * return 'Hiya ' + formatted + '!'; + * }; + * + * var welcome = _.compose(greet, format); + * welcome('pebbles'); + * // => 'Hiya Penelope!' + */ + function compose() { + var funcs = arguments, + length = funcs.length; + + while (length--) { + if (!isFunction(funcs[length])) { + throw new TypeError; + } + } + return function() { + var args = arguments, + length = funcs.length; + + while (length--) { + args = [funcs[length].apply(this, args)]; + } + return args[0]; + }; + } + + /** + * Creates a function which accepts one or more arguments of `func` that when + * invoked either executes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` can be specified + * if `func.length` is not sufficient. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @returns {Function} Returns the new curried function. + * @example + * + * var curried = _.curry(function(a, b, c) { + * console.log(a + b + c); + * }); + * + * curried(1)(2)(3); + * // => 6 + * + * curried(1, 2)(3); + * // => 6 + * + * curried(1, 2, 3); + * // => 6 + */ + function curry(func, arity) { + arity = typeof arity == 'number' ? arity : (+arity || func.length); + return createWrapper(func, 4, null, null, null, arity); + } + + /** + * Creates a function that will delay the execution of `func` until after + * `wait` milliseconds have elapsed since the last time it was invoked. + * Provide an options object to indicate that `func` should be invoked on + * the leading and/or trailing edge of the `wait` timeout. Subsequent calls + * to the debounced function will return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to debounce. + * @param {number} wait The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * var lazyLayout = _.debounce(calculateLayout, 150); + * jQuery(window).on('resize', lazyLayout); + * + * // execute `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * }); + * + * // ensure `batchLog` is executed once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * source.addEventListener('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * }, false); + */ + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + wait = nativeMax(0, wait) || 0; + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = options.leading; + maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0); + trailing = 'trailing' in options ? options.trailing : trailing; + } + var delayed = function() { + var remaining = wait - (now() - stamp); + if (remaining <= 0) { + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + var isCalled = trailingCall; + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + } else { + timeoutId = setTimeout(delayed, remaining); + } + }; + + var maxDelayed = function() { + if (timeoutId) { + clearTimeout(timeoutId); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (trailing || (maxWait !== wait)) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + }; + + return function() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + return result; + }; + } + + /** + * Defers executing the `func` function until the current call stack has cleared. + * Additional arguments will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to defer. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { console.log(text); }, 'deferred'); + * // logs 'deferred' after one or more milliseconds + */ + function defer(func) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 1); + return setTimeout(function() { func.apply(undefined, args); }, 1); + } + + /** + * Executes the `func` function after `wait` milliseconds. Additional arguments + * will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay execution. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { console.log(text); }, 1000, 'later'); + * // => logs 'later' after one second + */ + function delay(func, wait) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 2); + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it will be used to determine the cache key for storing the result + * based on the arguments provided to the memoized function. By default, the + * first argument provided to the memoized function is used as the cache key. + * The `func` is executed with the `this` binding of the memoized function. + * The result cache is exposed as the `cache` property on the memoized function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] A function used to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var fibonacci = _.memoize(function(n) { + * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); + * }); + * + * fibonacci(9) + * // => 34 + * + * var data = { + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * }; + * + * // modifying the result cache + * var get = _.memoize(function(name) { return data[name]; }, _.identity); + * get('pebbles'); + * // => { 'name': 'pebbles', 'age': 1 } + * + * get.cache.pebbles.name = 'penelope'; + * get('pebbles'); + * // => { 'name': 'penelope', 'age': 1 } + */ + function memoize(func, resolver) { + if (!isFunction(func)) { + throw new TypeError; + } + var memoized = function() { + var cache = memoized.cache, + key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0]; + + return hasOwnProperty.call(cache, key) + ? cache[key] + : (cache[key] = func.apply(this, arguments)); + } + memoized.cache = {}; + return memoized; + } + + /** + * Creates a function that is restricted to execute `func` once. Repeat calls to + * the function will return the value of the first call. The `func` is executed + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` executes `createApplication` once + */ + function once(func) { + var ran, + result; + + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (ran) { + return result; + } + ran = true; + result = func.apply(this, arguments); + + // clear the `func` variable so the function may be garbage collected + func = null; + return result; + }; + } + + /** + * Creates a function that, when called, invokes `func` with any additional + * `partial` arguments prepended to those provided to the new function. This + * method is similar to `_.bind` except it does **not** alter the `this` binding. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { return greeting + ' ' + name; }; + * var hi = _.partial(greet, 'hi'); + * hi('fred'); + * // => 'hi fred' + */ + function partial(func) { + return createWrapper(func, 16, slice(arguments, 1)); + } + + /** + * This method is like `_.partial` except that `partial` arguments are + * appended to those provided to the new function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var defaultsDeep = _.partialRight(_.merge, _.defaults); + * + * var options = { + * 'variable': 'data', + * 'imports': { 'jq': $ } + * }; + * + * defaultsDeep(options, _.templateSettings); + * + * options.variable + * // => 'data' + * + * options.imports + * // => { '_': _, 'jq': $ } + */ + function partialRight(func) { + return createWrapper(func, 32, null, slice(arguments, 1)); + } + + /** + * Creates a function that, when executed, will only call the `func` function + * at most once per every `wait` milliseconds. Provide an options object to + * indicate that `func` should be invoked on the leading and/or trailing edge + * of the `wait` timeout. Subsequent calls to the throttled function will + * return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to throttle. + * @param {number} wait The number of milliseconds to throttle executions to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // avoid excessively updating the position while scrolling + * var throttled = _.throttle(updatePosition, 100); + * jQuery(window).on('scroll', throttled); + * + * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? options.leading : leading; + trailing = 'trailing' in options ? options.trailing : trailing; + } + debounceOptions.leading = leading; + debounceOptions.maxWait = wait; + debounceOptions.trailing = trailing; + + return debounce(func, wait, debounceOptions); + } + + /** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Additional arguments provided to the function are appended + * to those provided to the wrapper function. The wrapper is executed with + * the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

      ' + func(text) + '

      '; + * }); + * + * p('Fred, Wilma, & Pebbles'); + * // => '

      Fred, Wilma, & Pebbles

      ' + */ + function wrap(value, wrapper) { + return createWrapper(wrapper, 16, [value]); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new function. + * @example + * + * var object = { 'name': 'fred' }; + * var getter = _.constant(object); + * getter() === object; + * // => true + */ + function constant(value) { + return function() { + return value; + }; + } + + /** + * Produces a callback bound to an optional `thisArg`. If `func` is a property + * name the created callback will return the property value for a given element. + * If `func` is an object the created callback will return `true` for elements + * that contain the equivalent object properties, otherwise it will return `false`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // wrap to create custom callback shorthands + * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { + * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); + * return !match ? func(callback, thisArg) : function(object) { + * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; + * }; + * }); + * + * _.filter(characters, 'age__gt38'); + * // => [{ 'name': 'fred', 'age': 40 }] + */ + function createCallback(func, thisArg, argCount) { + var type = typeof func; + if (func == null || type == 'function') { + return baseCreateCallback(func, thisArg, argCount); + } + // handle "_.pluck" style callback shorthands + if (type != 'object') { + return property(func); + } + var props = keys(func), + key = props[0], + a = func[key]; + + // handle "_.where" style callback shorthands + if (props.length == 1 && a === a && !isObject(a)) { + // fast path the common case of providing an object with a single + // property containing a primitive value + return function(object) { + var b = object[key]; + return a === b && (a !== 0 || (1 / a == 1 / b)); + }; + } + return function(object) { + var length = props.length, + result = false; + + while (length--) { + if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { + break; + } + } + return result; + }; + } + + /** + * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their + * corresponding HTML entities. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} string The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('Fred, Wilma, & Pebbles'); + * // => 'Fred, Wilma, & Pebbles' + */ + function escape(string) { + return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); + } + + /** + * This method returns the first argument provided to it. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'name': 'fred' }; + * _.identity(object) === object; + * // => true + */ + function identity(value) { + return value; + } + + /** + * Adds function properties of a source object to the destination object. + * If `object` is a function methods will be added to its prototype as well. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Function|Object} [object=lodash] object The destination object. + * @param {Object} source The object of functions to add. + * @param {Object} [options] The options object. + * @param {boolean} [options.chain=true] Specify whether the functions added are chainable. + * @example + * + * function capitalize(string) { + * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); + * } + * + * _.mixin({ 'capitalize': capitalize }); + * _.capitalize('fred'); + * // => 'Fred' + * + * _('fred').capitalize().value(); + * // => 'Fred' + * + * _.mixin({ 'capitalize': capitalize }, { 'chain': false }); + * _('fred').capitalize(); + * // => 'Fred' + */ + function mixin(object, source, options) { + var chain = true, + methodNames = source && functions(source); + + if (!source || (!options && !methodNames.length)) { + if (options == null) { + options = source; + } + ctor = lodashWrapper; + source = object; + object = lodash; + methodNames = functions(source); + } + if (options === false) { + chain = false; + } else if (isObject(options) && 'chain' in options) { + chain = options.chain; + } + var ctor = object, + isFunc = isFunction(ctor); + + forEach(methodNames, function(methodName) { + var func = object[methodName] = source[methodName]; + if (isFunc) { + ctor.prototype[methodName] = function() { + var chainAll = this.__chain__, + value = this.__wrapped__, + args = [value]; + + push.apply(args, arguments); + var result = func.apply(object, args); + if (chain || chainAll) { + if (value === result && isObject(result)) { + return this; + } + result = new ctor(result); + result.__chain__ = chainAll; + } + return result; + }; + } + }); + } + + /** + * Reverts the '_' variable to its previous value and returns a reference to + * the `lodash` function. + * + * @static + * @memberOf _ + * @category Utilities + * @returns {Function} Returns the `lodash` function. + * @example + * + * var lodash = _.noConflict(); + */ + function noConflict() { + context._ = oldDash; + return this; + } + + /** + * A no-operation function. + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var object = { 'name': 'fred' }; + * _.noop(object) === undefined; + * // => true + */ + function noop() { + // no operation performed + } + + /** + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var stamp = _.now(); + * _.defer(function() { console.log(_.now() - stamp); }); + * // => logs the number of milliseconds it took for the deferred function to be called + */ + var now = isNative(now = Date.now) && now || function() { + return new Date().getTime(); + }; + + /** + * Converts the given value into an integer of the specified radix. + * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the + * `value` is a hexadecimal, in which case a `radix` of `16` is used. + * + * Note: This method avoids differences in native ES3 and ES5 `parseInt` + * implementations. See http://es5.github.io/#E. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} value The value to parse. + * @param {number} [radix] The radix used to interpret the value to parse. + * @returns {number} Returns the new integer value. + * @example + * + * _.parseInt('08'); + * // => 8 + */ + var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) { + // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt` + return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0); + }; + + /** + * Creates a "_.pluck" style function, which returns the `key` value of a + * given object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} key The name of the property to retrieve. + * @returns {Function} Returns the new function. + * @example + * + * var characters = [ + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 36 } + * ]; + * + * var getName = _.property('name'); + * + * _.map(characters, getName); + * // => ['barney', 'fred'] + * + * _.sortBy(characters, getName); + * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] + */ + function property(key) { + return function(object) { + return object[key]; + }; + } + + /** + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is provided a number between `0` and the given number will be + * returned. If `floating` is truey or either `min` or `max` are floats a + * floating-point number will be returned instead of an integer. + * + * @static + * @memberOf _ + * @category Utilities + * @param {number} [min=0] The minimum possible value. + * @param {number} [max=1] The maximum possible value. + * @param {boolean} [floating=false] Specify returning a floating-point number. + * @returns {number} Returns a random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(min, max, floating) { + var noMin = min == null, + noMax = max == null; + + if (floating == null) { + if (typeof min == 'boolean' && noMax) { + floating = min; + min = 1; + } + else if (!noMax && typeof max == 'boolean') { + floating = max; + noMax = true; + } + } + if (noMin && noMax) { + max = 1; + } + min = +min || 0; + if (noMax) { + max = min; + min = 0; + } else { + max = +max || 0; + } + if (floating || min % 1 || max % 1) { + var rand = nativeRandom(); + return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max); + } + return baseRandom(min, max); + } + + /** + * Resolves the value of property `key` on `object`. If `key` is a function + * it will be invoked with the `this` binding of `object` and its result returned, + * else the property value is returned. If `object` is falsey then `undefined` + * is returned. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to resolve. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { + * 'cheese': 'crumpets', + * 'stuff': function() { + * return 'nonsense'; + * } + * }; + * + * _.result(object, 'cheese'); + * // => 'crumpets' + * + * _.result(object, 'stuff'); + * // => 'nonsense' + */ + function result(object, key) { + if (object) { + var value = object[key]; + return isFunction(value) ? object[key]() : value; + } + } + + /** + * A micro-templating method that handles arbitrary delimiters, preserves + * whitespace, and correctly escapes quotes within interpolated code. + * + * Note: In the development build, `_.template` utilizes sourceURLs for easier + * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl + * + * For more information on precompiling templates see: + * https://lodash.com/custom-builds + * + * For more information on Chrome extension sandboxes see: + * http://developer.chrome.com/stable/extensions/sandboxingEval.html + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} text The template text. + * @param {Object} data The data object used to populate the text. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as local variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [sourceURL] The sourceURL of the template's compiled source. + * @param {string} [variable] The data object variable name. + * @returns {Function|string} Returns a compiled function when no `data` object + * is given, else it returns the interpolated text. + * @example + * + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= name %>'); + * compiled({ 'name': 'fred' }); + * // => 'hello fred' + * + * // using the "escape" delimiter to escape HTML in data property values + * _.template('<%- value %>', { 'value': '').stripTags() +=> 'a linkalert("hello world!")' +``` + +**toSentence** _.toSentence(array, [delimiter, lastDelimiter]) + +Join an array into a human readable sentence. + +```javascript +_.toSentence(['jQuery', 'Mootools', 'Prototype']) +=> 'jQuery, Mootools and Prototype'; + +_.toSentence(['jQuery', 'Mootools', 'Prototype'], ', ', ' unt ') +=> 'jQuery, Mootools unt Prototype'; +``` + +**toSentenceSerial** _.toSentenceSerial(array, [delimiter, lastDelimiter]) + +The same as `toSentence`, but adjusts delimeters to use [Serial comma](http://en.wikipedia.org/wiki/Serial_comma). + +```javascript +_.toSentenceSerial(['jQuery', 'Mootools']) +=> 'jQuery and Mootools'; + +_.toSentenceSerial(['jQuery', 'Mootools', 'Prototype']) +=> 'jQuery, Mootools, and Prototype' + +_.toSentenceSerial(['jQuery', 'Mootools', 'Prototype'], ', ', ' unt '); +=> 'jQuery, Mootools, unt Prototype'; +``` + +**repeat** _.repeat(string, count, [separator]) + +Repeats a string count times. + +```javascript +_.repeat("foo", 3) +=> 'foofoofoo'; + +_.repeat("foo", 3, "bar") +=> 'foobarfoobarfoo' +``` + +**surround** _.surround(string, wrap) + +Surround a string with another string. + +```javascript +_.surround("foo", "ab") +=> 'abfooab'; +``` + +**quote** _.quote(string, quoteChar) or _.q(string, quoteChar) + +Quotes a string. `quoteChar` defaults to `"`. + +```javascript +_.quote('foo', quoteChar) +=> '"foo"'; +``` +**unquote** _.unquote(string, quoteChar) + +Unquotes a string. `quoteChar` defaults to `"`. + +```javascript +_.unquote('"foo"') +=> 'foo'; +_.unquote("'foo'", "'") +=> 'foo'; +``` + + +**slugify** _.slugify(string) + +Transform text into a URL slug. Replaces whitespaces, accentuated, and special characters with a dash. + +```javascript +_.slugify("Un éléphant à l'orée du bois") +=> 'un-elephant-a-loree-du-bois'; +``` + +***Caution: this function is charset dependent*** + +**naturalCmp** array.sort(_.naturalCmp) + +Naturally sort strings like humans would do. + +```javascript +['foo20', 'foo5'].sort(_.naturalCmp) +=> [ 'foo5', 'foo20' ] +``` + +**toBoolean** _.toBoolean(string) or _.toBool(string) + +Turn strings that can be commonly considered as booleas to real booleans. Such as "true", "false", "1" and "0". This function is case insensitive. + +```javascript +_.toBoolean("true") +=> true +_.toBoolean("FALSE") +=> false +_.toBoolean("random") +=> undefined +``` + +It can be customized by giving arrays of truth and falsy value matcher as parameters. Matchers can be also RegExp objects. + +```javascript +_.toBoolean("truthy", ["truthy"], ["falsy"]) +=> true +_.toBoolean("true only at start", [/^true/]) +=> true +``` + +## Roadmap ## + +Any suggestions or bug reports are welcome. Just email me or more preferably open an issue. + +#### Problems + +We lose two things for `include` and `reverse` methods from `_.string`: + +* Calls like `_('foobar').include('bar')` aren't available; +* Chaining isn't available too. + +But if you need this functionality you can create aliases for conflict functions which will be convenient for you: + +```javascript +_.mixin({ + includeString: _.str.include, + reverseString: _.str.reverse +}) + +// Now wrapper calls and chaining are available. +_('foobar').chain().reverseString().includeString('rab').value() +``` + +#### Standalone Usage + +If you are using Underscore.string without Underscore. You also have `_.string` namespace for it and `_.str` alias +But of course you can just reassign `_` variable with `_.string` + +```javascript +_ = _.string +``` + +## Changelog ## + +### 2.3.3 ### + +* Add `toBoolean` +* Add `unquote` +* Add quote char option to `quote` +* Support dash-separated words in `titleize` + +### 2.3.2 ### + +* Add `naturalCmp` +* Bug fix to `camelize` +* Add ă, ș, ț and ś to `slugify` +* Doc updates +* Add support for [component](http://component.io/) +* [Full changelog](https://github.com/epeli/underscore.string/compare/v2.3.1...v2.3.2) + +### 2.3.1 ### + +* Bug fixes to `escapeHTML`, `classify`, `substr` +* Faster `count` +* Documentation fixes +* [Full changelog](https://github.com/epeli/underscore.string/compare/v2.3.0...v2.3.1) + +### 2.3.0 ### + +* Added `numberformat` method +* Added `levenshtein` method (Levenshtein distance calculation) +* Added `swapCase` method +* Changed default behavior of `words` method +* Added `toSentenceSerial` method +* Added `surround` and `quote` methods + +### 2.2.1 ### + +* Same as 2.2.0 (2.2.0rc on npm) to fix some npm drama + +### 2.2.0 ### + +* Capitalize method behavior changed +* Various perfomance tweaks + +### 2.1.1### + +* Fixed words method bug +* Added classify method + +### 2.1.0 ### + +* AMD support +* Added toSentence method +* Added slugify method +* Lots of speed optimizations + +### 2.0.0 ### + +* Added prune, humanize functions +* Added _.string (_.str) namespace for Underscore.string library +* Removed includes function + +For upgrading to this version you need to mix in Underscore.string library to Underscore object: + +```javascript +_.mixin(_.string.exports()); +``` + +and all non-conflict Underscore.string functions will be available through Underscore object. +Also function `includes` has been removed, you should replace this function by `_.str.include` +or create alias `_.includes = _.str.include` and all your code will work fine. + +### 1.1.6 ### + +* Fixed reverse and truncate +* Added isBlank, stripTags, inlude(alias for includes) +* Added uglifier compression + +### 1.1.5 ### + +* Added strRight, strRightBack, strLeft, strLeftBack + +### 1.1.4 ### + +* Added pad, lpad, rpad, lrpad methods and aliases center, ljust, rjust +* Integration with Underscore 1.1.6 + +### 1.1.3 ### + +* Added methods: underscored, camelize, dasherize +* Support newer version of npm + +### 1.1.2 ### + +* Created functions: lines, chars, words functions + +### 1.0.2 ### + +* Created integration test suite with underscore.js 1.1.4 (now it's absolutely compatible) +* Removed 'reverse' function, because this function override underscore.js 'reverse' + +## Contribute ## + +* Fork & pull request. Don't forget about tests. +* If you planning add some feature please create issue before. + +Otherwise changes will be rejected. + +## Contributors list ## +[Can be found here](https://github.com/epeli/underscore.string/graphs/contributors). + + +## Licence ## + +The MIT License + +Copyright (c) 2011 Esa-Matti Suuronen esa-matti@suuronen.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/Rakefile b/node_modules/grunt-legacy-log/node_modules/underscore.string/Rakefile new file mode 100644 index 0000000..2cd9eed --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/underscore.string/Rakefile @@ -0,0 +1,23 @@ +# encoding: utf-8 +task default: :test + +desc 'Use UglifyJS to compress Underscore.string' +task :build do + require 'uglifier' + source = File.read('lib/underscore.string.js', :encoding => 'utf-8') + compressed = Uglifier.compile(source, copyright: false) + File.open('dist/underscore.string.min.js', 'w'){ |f| f.write compressed } + compression_rate = compressed.length.to_f/source.length + puts "compressed dist/underscore.string.min.js: #{compressed.length}/#{source.length} #{(compression_rate * 100).round}%" +end + +desc 'Run tests' +task :test do + puts "Running underscore.string test suite." + result1 = system %{phantomjs ./test/run-qunit.js "test/test.html"} + + puts "Running Underscore test suite." + result2 = system %{phantomjs ./test/run-qunit.js "test/test_underscore/index.html"} + + exit(result1 && result2 ? 0 : 1) +end diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/component.json b/node_modules/grunt-legacy-log/node_modules/underscore.string/component.json new file mode 100644 index 0000000..ae91b65 --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/underscore.string/component.json @@ -0,0 +1,11 @@ +{ + "name": "underscore.string", + "repo": "epeli/underscore.string", + "description": "String manipulation extensions for Underscore.js javascript library", + "version": "2.3.3", + "keywords": ["underscore", "string"], + "dependencies": {}, + "development": {}, + "main": "lib/underscore.string.js", + "scripts": ["lib/underscore.string.js"] +} diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/dist/underscore.string.min.js b/node_modules/grunt-legacy-log/node_modules/underscore.string/dist/underscore.string.min.js new file mode 100644 index 0000000..4f6b2b9 --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/underscore.string/dist/underscore.string.min.js @@ -0,0 +1 @@ +!function(e,n){"use strict";function r(e,n){var r,t,u=e.toLowerCase();for(n=[].concat(n),r=0;n.length>r;r+=1)if(t=n[r]){if(t.test&&t.test(e))return!0;if(t.toLowerCase()===u)return!0}}var t=n.prototype.trim,u=n.prototype.trimRight,i=n.prototype.trimLeft,l=function(e){return 1*e||0},o=function(e,n){if(1>n)return"";for(var r="";n>0;)1&n&&(r+=e),n>>=1,e+=e;return r},a=[].slice,c=function(e){return null==e?"\\s":e.source?e.source:"["+g.escapeRegExp(e)+"]"},s={lt:"<",gt:">",quot:'"',amp:"&",apos:"'"},f={};for(var p in s)f[s[p]]=p;f["'"]="#39";var h=function(){function e(e){return Object.prototype.toString.call(e).slice(8,-1).toLowerCase()}var r=o,t=function(){return t.cache.hasOwnProperty(arguments[0])||(t.cache[arguments[0]]=t.parse(arguments[0])),t.format.call(null,t.cache[arguments[0]],arguments)};return t.format=function(t,u){var i,l,o,a,c,s,f,p=1,g=t.length,d="",m=[];for(l=0;g>l;l++)if(d=e(t[l]),"string"===d)m.push(t[l]);else if("array"===d){if(a=t[l],a[2])for(i=u[p],o=0;a[2].length>o;o++){if(!i.hasOwnProperty(a[2][o]))throw new Error(h('[_.sprintf] property "%s" does not exist',a[2][o]));i=i[a[2][o]]}else i=a[1]?u[a[1]]:u[p++];if(/[^s]/.test(a[8])&&"number"!=e(i))throw new Error(h("[_.sprintf] expecting number but found %s",e(i)));switch(a[8]){case"b":i=i.toString(2);break;case"c":i=n.fromCharCode(i);break;case"d":i=parseInt(i,10);break;case"e":i=a[7]?i.toExponential(a[7]):i.toExponential();break;case"f":i=a[7]?parseFloat(i).toFixed(a[7]):parseFloat(i);break;case"o":i=i.toString(8);break;case"s":i=(i=n(i))&&a[7]?i.substring(0,a[7]):i;break;case"u":i=Math.abs(i);break;case"x":i=i.toString(16);break;case"X":i=i.toString(16).toUpperCase()}i=/[def]/.test(a[8])&&a[3]&&i>=0?"+"+i:i,s=a[4]?"0"==a[4]?"0":a[4].charAt(1):" ",f=a[6]-n(i).length,c=a[6]?r(s,f):"",m.push(a[5]?i+c:c+i)}return m.join("")},t.cache={},t.parse=function(e){for(var n=e,r=[],t=[],u=0;n;){if(null!==(r=/^[^\x25]+/.exec(n)))t.push(r[0]);else if(null!==(r=/^\x25{2}/.exec(n)))t.push("%");else{if(null===(r=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(n)))throw new Error("[_.sprintf] huh?");if(r[2]){u|=1;var i=[],l=r[2],o=[];if(null===(o=/^([a-z_][a-z_\d]*)/i.exec(l)))throw new Error("[_.sprintf] huh?");for(i.push(o[1]);""!==(l=l.substring(o[0].length));)if(null!==(o=/^\.([a-z_][a-z_\d]*)/i.exec(l)))i.push(o[1]);else{if(null===(o=/^\[(\d+)\]/.exec(l)))throw new Error("[_.sprintf] huh?");i.push(o[1])}r[2]=i}else u|=2;if(3===u)throw new Error("[_.sprintf] mixing positional and named placeholders is not (yet) supported");t.push(r)}n=n.substring(r[0].length)}return t},t}(),g={VERSION:"2.3.0",isBlank:function(e){return null==e&&(e=""),/^\s*$/.test(e)},stripTags:function(e){return null==e?"":n(e).replace(/<\/?[^>]+>/g,"")},capitalize:function(e){return e=null==e?"":n(e),e.charAt(0).toUpperCase()+e.slice(1)},chop:function(e,r){return null==e?[]:(e=n(e),r=~~r,r>0?e.match(new RegExp(".{1,"+r+"}","g")):[e])},clean:function(e){return g.strip(e).replace(/\s+/g," ")},count:function(e,r){if(null==e||null==r)return 0;e=n(e),r=n(r);for(var t=0,u=0,i=r.length;;){if(u=e.indexOf(r,u),-1===u)break;t++,u+=i}return t},chars:function(e){return null==e?[]:n(e).split("")},swapCase:function(e){return null==e?"":n(e).replace(/\S/g,function(e){return e===e.toUpperCase()?e.toLowerCase():e.toUpperCase()})},escapeHTML:function(e){return null==e?"":n(e).replace(/[&<>"']/g,function(e){return"&"+f[e]+";"})},unescapeHTML:function(e){return null==e?"":n(e).replace(/\&([^;]+);/g,function(e,r){var t;return r in s?s[r]:(t=r.match(/^#x([\da-fA-F]+)$/))?n.fromCharCode(parseInt(t[1],16)):(t=r.match(/^#(\d+)$/))?n.fromCharCode(~~t[1]):e})},escapeRegExp:function(e){return null==e?"":n(e).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")},splice:function(e,n,r,t){var u=g.chars(e);return u.splice(~~n,~~r,t),u.join("")},insert:function(e,n,r){return g.splice(e,n,0,r)},include:function(e,r){return""===r?!0:null==e?!1:-1!==n(e).indexOf(r)},join:function(){var e=a.call(arguments),n=e.shift();return null==n&&(n=""),e.join(n)},lines:function(e){return null==e?[]:n(e).split("\n")},reverse:function(e){return g.chars(e).reverse().join("")},startsWith:function(e,r){return""===r?!0:null==e||null==r?!1:(e=n(e),r=n(r),e.length>=r.length&&e.slice(0,r.length)===r)},endsWith:function(e,r){return""===r?!0:null==e||null==r?!1:(e=n(e),r=n(r),e.length>=r.length&&e.slice(e.length-r.length)===r)},succ:function(e){return null==e?"":(e=n(e),e.slice(0,-1)+n.fromCharCode(e.charCodeAt(e.length-1)+1))},titleize:function(e){return null==e?"":(e=n(e).toLowerCase(),e.replace(/(?:^|\s|-)\S/g,function(e){return e.toUpperCase()}))},camelize:function(e){return g.trim(e).replace(/[-_\s]+(.)?/g,function(e,n){return n?n.toUpperCase():""})},underscored:function(e){return g.trim(e).replace(/([a-z\d])([A-Z]+)/g,"$1_$2").replace(/[-\s]+/g,"_").toLowerCase()},dasherize:function(e){return g.trim(e).replace(/([A-Z])/g,"-$1").replace(/[-_\s]+/g,"-").toLowerCase()},classify:function(e){return g.titleize(n(e).replace(/[\W_]/g," ")).replace(/\s/g,"")},humanize:function(e){return g.capitalize(g.underscored(e).replace(/_id$/,"").replace(/_/g," "))},trim:function(e,r){return null==e?"":!r&&t?t.call(e):(r=c(r),n(e).replace(new RegExp("^"+r+"+|"+r+"+$","g"),""))},ltrim:function(e,r){return null==e?"":!r&&i?i.call(e):(r=c(r),n(e).replace(new RegExp("^"+r+"+"),""))},rtrim:function(e,r){return null==e?"":!r&&u?u.call(e):(r=c(r),n(e).replace(new RegExp(r+"+$"),""))},truncate:function(e,r,t){return null==e?"":(e=n(e),t=t||"...",r=~~r,e.length>r?e.slice(0,r)+t:e)},prune:function(e,r,t){if(null==e)return"";if(e=n(e),r=~~r,t=null!=t?n(t):"...",r>=e.length)return e;var u=function(e){return e.toUpperCase()!==e.toLowerCase()?"A":" "},i=e.slice(0,r+1).replace(/.(?=\W*\w*$)/g,u);return i=i.slice(i.length-2).match(/\w\w/)?i.replace(/\s*\S+$/,""):g.rtrim(i.slice(0,i.length-1)),(i+t).length>e.length?e:e.slice(0,i.length)+t},words:function(e,n){return g.isBlank(e)?[]:g.trim(e,n).split(n||/\s+/)},pad:function(e,r,t,u){e=null==e?"":n(e),r=~~r;var i=0;switch(t?t.length>1&&(t=t.charAt(0)):t=" ",u){case"right":return i=r-e.length,e+o(t,i);case"both":return i=r-e.length,o(t,Math.ceil(i/2))+e+o(t,Math.floor(i/2));default:return i=r-e.length,o(t,i)+e}},lpad:function(e,n,r){return g.pad(e,n,r)},rpad:function(e,n,r){return g.pad(e,n,r,"right")},lrpad:function(e,n,r){return g.pad(e,n,r,"both")},sprintf:h,vsprintf:function(e,n){return n.unshift(e),h.apply(null,n)},toNumber:function(e,n){return e?(e=g.trim(e),e.match(/^-?\d+(?:\.\d+)?$/)?l(l(e).toFixed(~~n)):0/0):0},numberFormat:function(e,n,r,t){if(isNaN(e)||null==e)return"";e=e.toFixed(~~n),t="string"==typeof t?t:",";var u=e.split("."),i=u[0],l=u[1]?(r||".")+u[1]:"";return i.replace(/(\d)(?=(?:\d{3})+$)/g,"$1"+t)+l},strRight:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.indexOf(r):-1;return~t?e.slice(t+r.length,e.length):e},strRightBack:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.lastIndexOf(r):-1;return~t?e.slice(t+r.length,e.length):e},strLeft:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.indexOf(r):-1;return~t?e.slice(0,t):e},strLeftBack:function(e,n){if(null==e)return"";e+="",n=null!=n?""+n:n;var r=e.lastIndexOf(n);return~r?e.slice(0,r):e},toSentence:function(e,n,r,t){n=n||", ",r=r||" and ";var u=e.slice(),i=u.pop();return e.length>2&&t&&(r=g.rtrim(n)+r),u.length?u.join(n)+r+i:i},toSentenceSerial:function(){var e=a.call(arguments);return e[3]=!0,g.toSentence.apply(g,e)},slugify:function(e){if(null==e)return"";var r="ąàáäâãåæăćęèéëêìíïîłńòóöôõøśșțùúüûñçżź",t="aaaaaaaaaceeeeeiiiilnoooooosstuuuunczz",u=new RegExp(c(r),"g");return e=n(e).toLowerCase().replace(u,function(e){var n=r.indexOf(e);return t.charAt(n)||"-"}),g.dasherize(e.replace(/[^\w\s-]/g,""))},surround:function(e,n){return[n,e,n].join("")},quote:function(e,n){return g.surround(e,n||'"')},unquote:function(e,n){return n=n||'"',e[0]===n&&e[e.length-1]===n?e.slice(1,e.length-1):e},exports:function(){var e={};for(var n in this)this.hasOwnProperty(n)&&!n.match(/^(?:include|contains|reverse)$/)&&(e[n]=this[n]);return e},repeat:function(e,r,t){if(null==e)return"";if(r=~~r,null==t)return o(n(e),r);for(var u=[];r>0;u[--r]=e);return u.join(t)},naturalCmp:function(e,r){if(e==r)return 0;if(!e)return-1;if(!r)return 1;for(var t=/(\.\d+)|(\d+)|(\D+)/g,u=n(e).toLowerCase().match(t),i=n(r).toLowerCase().match(t),l=Math.min(u.length,i.length),o=0;l>o;o++){var a=u[o],c=i[o];if(a!==c){var s=parseInt(a,10);if(!isNaN(s)){var f=parseInt(c,10);if(!isNaN(f)&&s-f)return s-f}return c>a?-1:1}}return u.length===i.length?u.length-i.length:r>e?-1:1},levenshtein:function(e,r){if(null==e&&null==r)return 0;if(null==e)return n(r).length;if(null==r)return n(e).length;e=n(e),r=n(r);for(var t,u,i=[],l=0;r.length>=l;l++)for(var o=0;e.length>=o;o++)u=l&&o?e.charAt(o-1)===r.charAt(l-1)?t:Math.min(i[o],i[o-1],t)+1:l+o,t=i[o],i[o]=u;return i.pop()},toBoolean:function(e,n,t){return"number"==typeof e&&(e=""+e),"string"!=typeof e?!!e:(e=g.trim(e),r(e,n||["true","1"])?!0:r(e,t||["false","0"])?!1:void 0)}};g.strip=g.trim,g.lstrip=g.ltrim,g.rstrip=g.rtrim,g.center=g.lrpad,g.rjust=g.lpad,g.ljust=g.rpad,g.contains=g.include,g.q=g.quote,g.toBool=g.toBoolean,"undefined"!=typeof exports&&("undefined"!=typeof module&&module.exports&&(module.exports=g),exports._s=g),"function"==typeof define&&define.amd&&define("underscore.string",[],function(){return g}),e._=e._||{},e._.string=e._.str=g}(this,String); \ No newline at end of file diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/lib/underscore.string.js b/node_modules/grunt-legacy-log/node_modules/underscore.string/lib/underscore.string.js new file mode 100644 index 0000000..8761117 --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/underscore.string/lib/underscore.string.js @@ -0,0 +1,673 @@ +// Underscore.string +// (c) 2010 Esa-Matti Suuronen +// Underscore.string is freely distributable under the terms of the MIT license. +// Documentation: https://github.com/epeli/underscore.string +// Some code is borrowed from MooTools and Alexandru Marasteanu. +// Version '2.3.2' + +!function(root, String){ + 'use strict'; + + // Defining helper functions. + + var nativeTrim = String.prototype.trim; + var nativeTrimRight = String.prototype.trimRight; + var nativeTrimLeft = String.prototype.trimLeft; + + var parseNumber = function(source) { return source * 1 || 0; }; + + var strRepeat = function(str, qty){ + if (qty < 1) return ''; + var result = ''; + while (qty > 0) { + if (qty & 1) result += str; + qty >>= 1, str += str; + } + return result; + }; + + var slice = [].slice; + + var defaultToWhiteSpace = function(characters) { + if (characters == null) + return '\\s'; + else if (characters.source) + return characters.source; + else + return '[' + _s.escapeRegExp(characters) + ']'; + }; + + // Helper for toBoolean + function boolMatch(s, matchers) { + var i, matcher, down = s.toLowerCase(); + matchers = [].concat(matchers); + for (i = 0; i < matchers.length; i += 1) { + matcher = matchers[i]; + if (!matcher) continue; + if (matcher.test && matcher.test(s)) return true; + if (matcher.toLowerCase() === down) return true; + } + } + + var escapeChars = { + lt: '<', + gt: '>', + quot: '"', + amp: '&', + apos: "'" + }; + + var reversedEscapeChars = {}; + for(var key in escapeChars) reversedEscapeChars[escapeChars[key]] = key; + reversedEscapeChars["'"] = '#39'; + + // sprintf() for JavaScript 0.7-beta1 + // http://www.diveintojavascript.com/projects/javascript-sprintf + // + // Copyright (c) Alexandru Marasteanu + // All rights reserved. + + var sprintf = (function() { + function get_type(variable) { + return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase(); + } + + var str_repeat = strRepeat; + + var str_format = function() { + if (!str_format.cache.hasOwnProperty(arguments[0])) { + str_format.cache[arguments[0]] = str_format.parse(arguments[0]); + } + return str_format.format.call(null, str_format.cache[arguments[0]], arguments); + }; + + str_format.format = function(parse_tree, argv) { + var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length; + for (i = 0; i < tree_length; i++) { + node_type = get_type(parse_tree[i]); + if (node_type === 'string') { + output.push(parse_tree[i]); + } + else if (node_type === 'array') { + match = parse_tree[i]; // convenience purposes only + if (match[2]) { // keyword argument + arg = argv[cursor]; + for (k = 0; k < match[2].length; k++) { + if (!arg.hasOwnProperty(match[2][k])) { + throw new Error(sprintf('[_.sprintf] property "%s" does not exist', match[2][k])); + } + arg = arg[match[2][k]]; + } + } else if (match[1]) { // positional argument (explicit) + arg = argv[match[1]]; + } + else { // positional argument (implicit) + arg = argv[cursor++]; + } + + if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) { + throw new Error(sprintf('[_.sprintf] expecting number but found %s', get_type(arg))); + } + switch (match[8]) { + case 'b': arg = arg.toString(2); break; + case 'c': arg = String.fromCharCode(arg); break; + case 'd': arg = parseInt(arg, 10); break; + case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; + case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; + case 'o': arg = arg.toString(8); break; + case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break; + case 'u': arg = Math.abs(arg); break; + case 'x': arg = arg.toString(16); break; + case 'X': arg = arg.toString(16).toUpperCase(); break; + } + arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); + pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' '; + pad_length = match[6] - String(arg).length; + pad = match[6] ? str_repeat(pad_character, pad_length) : ''; + output.push(match[5] ? arg + pad : pad + arg); + } + } + return output.join(''); + }; + + str_format.cache = {}; + + str_format.parse = function(fmt) { + var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; + while (_fmt) { + if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { + parse_tree.push(match[0]); + } + else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { + parse_tree.push('%'); + } + else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { + if (match[2]) { + arg_names |= 1; + var field_list = [], replacement_field = match[2], field_match = []; + if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { + if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + } + else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + } + else { + throw new Error('[_.sprintf] huh?'); + } + } + } + else { + throw new Error('[_.sprintf] huh?'); + } + match[2] = field_list; + } + else { + arg_names |= 2; + } + if (arg_names === 3) { + throw new Error('[_.sprintf] mixing positional and named placeholders is not (yet) supported'); + } + parse_tree.push(match); + } + else { + throw new Error('[_.sprintf] huh?'); + } + _fmt = _fmt.substring(match[0].length); + } + return parse_tree; + }; + + return str_format; + })(); + + + + // Defining underscore.string + + var _s = { + + VERSION: '2.3.0', + + isBlank: function(str){ + if (str == null) str = ''; + return (/^\s*$/).test(str); + }, + + stripTags: function(str){ + if (str == null) return ''; + return String(str).replace(/<\/?[^>]+>/g, ''); + }, + + capitalize : function(str){ + str = str == null ? '' : String(str); + return str.charAt(0).toUpperCase() + str.slice(1); + }, + + chop: function(str, step){ + if (str == null) return []; + str = String(str); + step = ~~step; + return step > 0 ? str.match(new RegExp('.{1,' + step + '}', 'g')) : [str]; + }, + + clean: function(str){ + return _s.strip(str).replace(/\s+/g, ' '); + }, + + count: function(str, substr){ + if (str == null || substr == null) return 0; + + str = String(str); + substr = String(substr); + + var count = 0, + pos = 0, + length = substr.length; + + while (true) { + pos = str.indexOf(substr, pos); + if (pos === -1) break; + count++; + pos += length; + } + + return count; + }, + + chars: function(str) { + if (str == null) return []; + return String(str).split(''); + }, + + swapCase: function(str) { + if (str == null) return ''; + return String(str).replace(/\S/g, function(c){ + return c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase(); + }); + }, + + escapeHTML: function(str) { + if (str == null) return ''; + return String(str).replace(/[&<>"']/g, function(m){ return '&' + reversedEscapeChars[m] + ';'; }); + }, + + unescapeHTML: function(str) { + if (str == null) return ''; + return String(str).replace(/\&([^;]+);/g, function(entity, entityCode){ + var match; + + if (entityCode in escapeChars) { + return escapeChars[entityCode]; + } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) { + return String.fromCharCode(parseInt(match[1], 16)); + } else if (match = entityCode.match(/^#(\d+)$/)) { + return String.fromCharCode(~~match[1]); + } else { + return entity; + } + }); + }, + + escapeRegExp: function(str){ + if (str == null) return ''; + return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); + }, + + splice: function(str, i, howmany, substr){ + var arr = _s.chars(str); + arr.splice(~~i, ~~howmany, substr); + return arr.join(''); + }, + + insert: function(str, i, substr){ + return _s.splice(str, i, 0, substr); + }, + + include: function(str, needle){ + if (needle === '') return true; + if (str == null) return false; + return String(str).indexOf(needle) !== -1; + }, + + join: function() { + var args = slice.call(arguments), + separator = args.shift(); + + if (separator == null) separator = ''; + + return args.join(separator); + }, + + lines: function(str) { + if (str == null) return []; + return String(str).split("\n"); + }, + + reverse: function(str){ + return _s.chars(str).reverse().join(''); + }, + + startsWith: function(str, starts){ + if (starts === '') return true; + if (str == null || starts == null) return false; + str = String(str); starts = String(starts); + return str.length >= starts.length && str.slice(0, starts.length) === starts; + }, + + endsWith: function(str, ends){ + if (ends === '') return true; + if (str == null || ends == null) return false; + str = String(str); ends = String(ends); + return str.length >= ends.length && str.slice(str.length - ends.length) === ends; + }, + + succ: function(str){ + if (str == null) return ''; + str = String(str); + return str.slice(0, -1) + String.fromCharCode(str.charCodeAt(str.length-1) + 1); + }, + + titleize: function(str){ + if (str == null) return ''; + str = String(str).toLowerCase(); + return str.replace(/(?:^|\s|-)\S/g, function(c){ return c.toUpperCase(); }); + }, + + camelize: function(str){ + return _s.trim(str).replace(/[-_\s]+(.)?/g, function(match, c){ return c ? c.toUpperCase() : ""; }); + }, + + underscored: function(str){ + return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase(); + }, + + dasherize: function(str){ + return _s.trim(str).replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase(); + }, + + classify: function(str){ + return _s.titleize(String(str).replace(/[\W_]/g, ' ')).replace(/\s/g, ''); + }, + + humanize: function(str){ + return _s.capitalize(_s.underscored(str).replace(/_id$/,'').replace(/_/g, ' ')); + }, + + trim: function(str, characters){ + if (str == null) return ''; + if (!characters && nativeTrim) return nativeTrim.call(str); + characters = defaultToWhiteSpace(characters); + return String(str).replace(new RegExp('\^' + characters + '+|' + characters + '+$', 'g'), ''); + }, + + ltrim: function(str, characters){ + if (str == null) return ''; + if (!characters && nativeTrimLeft) return nativeTrimLeft.call(str); + characters = defaultToWhiteSpace(characters); + return String(str).replace(new RegExp('^' + characters + '+'), ''); + }, + + rtrim: function(str, characters){ + if (str == null) return ''; + if (!characters && nativeTrimRight) return nativeTrimRight.call(str); + characters = defaultToWhiteSpace(characters); + return String(str).replace(new RegExp(characters + '+$'), ''); + }, + + truncate: function(str, length, truncateStr){ + if (str == null) return ''; + str = String(str); truncateStr = truncateStr || '...'; + length = ~~length; + return str.length > length ? str.slice(0, length) + truncateStr : str; + }, + + /** + * _s.prune: a more elegant version of truncate + * prune extra chars, never leaving a half-chopped word. + * @author github.com/rwz + */ + prune: function(str, length, pruneStr){ + if (str == null) return ''; + + str = String(str); length = ~~length; + pruneStr = pruneStr != null ? String(pruneStr) : '...'; + + if (str.length <= length) return str; + + var tmpl = function(c){ return c.toUpperCase() !== c.toLowerCase() ? 'A' : ' '; }, + template = str.slice(0, length+1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA' + + if (template.slice(template.length-2).match(/\w\w/)) + template = template.replace(/\s*\S+$/, ''); + else + template = _s.rtrim(template.slice(0, template.length-1)); + + return (template+pruneStr).length > str.length ? str : str.slice(0, template.length)+pruneStr; + }, + + words: function(str, delimiter) { + if (_s.isBlank(str)) return []; + return _s.trim(str, delimiter).split(delimiter || /\s+/); + }, + + pad: function(str, length, padStr, type) { + str = str == null ? '' : String(str); + length = ~~length; + + var padlen = 0; + + if (!padStr) + padStr = ' '; + else if (padStr.length > 1) + padStr = padStr.charAt(0); + + switch(type) { + case 'right': + padlen = length - str.length; + return str + strRepeat(padStr, padlen); + case 'both': + padlen = length - str.length; + return strRepeat(padStr, Math.ceil(padlen/2)) + str + + strRepeat(padStr, Math.floor(padlen/2)); + default: // 'left' + padlen = length - str.length; + return strRepeat(padStr, padlen) + str; + } + }, + + lpad: function(str, length, padStr) { + return _s.pad(str, length, padStr); + }, + + rpad: function(str, length, padStr) { + return _s.pad(str, length, padStr, 'right'); + }, + + lrpad: function(str, length, padStr) { + return _s.pad(str, length, padStr, 'both'); + }, + + sprintf: sprintf, + + vsprintf: function(fmt, argv){ + argv.unshift(fmt); + return sprintf.apply(null, argv); + }, + + toNumber: function(str, decimals) { + if (!str) return 0; + str = _s.trim(str); + if (!str.match(/^-?\d+(?:\.\d+)?$/)) return NaN; + return parseNumber(parseNumber(str).toFixed(~~decimals)); + }, + + numberFormat : function(number, dec, dsep, tsep) { + if (isNaN(number) || number == null) return ''; + + number = number.toFixed(~~dec); + tsep = typeof tsep == 'string' ? tsep : ','; + + var parts = number.split('.'), fnums = parts[0], + decimals = parts[1] ? (dsep || '.') + parts[1] : ''; + + return fnums.replace(/(\d)(?=(?:\d{3})+$)/g, '$1' + tsep) + decimals; + }, + + strRight: function(str, sep){ + if (str == null) return ''; + str = String(str); sep = sep != null ? String(sep) : sep; + var pos = !sep ? -1 : str.indexOf(sep); + return ~pos ? str.slice(pos+sep.length, str.length) : str; + }, + + strRightBack: function(str, sep){ + if (str == null) return ''; + str = String(str); sep = sep != null ? String(sep) : sep; + var pos = !sep ? -1 : str.lastIndexOf(sep); + return ~pos ? str.slice(pos+sep.length, str.length) : str; + }, + + strLeft: function(str, sep){ + if (str == null) return ''; + str = String(str); sep = sep != null ? String(sep) : sep; + var pos = !sep ? -1 : str.indexOf(sep); + return ~pos ? str.slice(0, pos) : str; + }, + + strLeftBack: function(str, sep){ + if (str == null) return ''; + str += ''; sep = sep != null ? ''+sep : sep; + var pos = str.lastIndexOf(sep); + return ~pos ? str.slice(0, pos) : str; + }, + + toSentence: function(array, separator, lastSeparator, serial) { + separator = separator || ', '; + lastSeparator = lastSeparator || ' and '; + var a = array.slice(), lastMember = a.pop(); + + if (array.length > 2 && serial) lastSeparator = _s.rtrim(separator) + lastSeparator; + + return a.length ? a.join(separator) + lastSeparator + lastMember : lastMember; + }, + + toSentenceSerial: function() { + var args = slice.call(arguments); + args[3] = true; + return _s.toSentence.apply(_s, args); + }, + + slugify: function(str) { + if (str == null) return ''; + + var from = "ąàáäâãåæăćęèéëêìíïîłńòóöôõøśșțùúüûñçżź", + to = "aaaaaaaaaceeeeeiiiilnoooooosstuuuunczz", + regex = new RegExp(defaultToWhiteSpace(from), 'g'); + + str = String(str).toLowerCase().replace(regex, function(c){ + var index = from.indexOf(c); + return to.charAt(index) || '-'; + }); + + return _s.dasherize(str.replace(/[^\w\s-]/g, '')); + }, + + surround: function(str, wrapper) { + return [wrapper, str, wrapper].join(''); + }, + + quote: function(str, quoteChar) { + return _s.surround(str, quoteChar || '"'); + }, + + unquote: function(str, quoteChar) { + quoteChar = quoteChar || '"'; + if (str[0] === quoteChar && str[str.length-1] === quoteChar) + return str.slice(1,str.length-1); + else return str; + }, + + exports: function() { + var result = {}; + + for (var prop in this) { + if (!this.hasOwnProperty(prop) || prop.match(/^(?:include|contains|reverse)$/)) continue; + result[prop] = this[prop]; + } + + return result; + }, + + repeat: function(str, qty, separator){ + if (str == null) return ''; + + qty = ~~qty; + + // using faster implementation if separator is not needed; + if (separator == null) return strRepeat(String(str), qty); + + // this one is about 300x slower in Google Chrome + for (var repeat = []; qty > 0; repeat[--qty] = str) {} + return repeat.join(separator); + }, + + naturalCmp: function(str1, str2){ + if (str1 == str2) return 0; + if (!str1) return -1; + if (!str2) return 1; + + var cmpRegex = /(\.\d+)|(\d+)|(\D+)/g, + tokens1 = String(str1).toLowerCase().match(cmpRegex), + tokens2 = String(str2).toLowerCase().match(cmpRegex), + count = Math.min(tokens1.length, tokens2.length); + + for(var i = 0; i < count; i++) { + var a = tokens1[i], b = tokens2[i]; + + if (a !== b){ + var num1 = parseInt(a, 10); + if (!isNaN(num1)){ + var num2 = parseInt(b, 10); + if (!isNaN(num2) && num1 - num2) + return num1 - num2; + } + return a < b ? -1 : 1; + } + } + + if (tokens1.length === tokens2.length) + return tokens1.length - tokens2.length; + + return str1 < str2 ? -1 : 1; + }, + + levenshtein: function(str1, str2) { + if (str1 == null && str2 == null) return 0; + if (str1 == null) return String(str2).length; + if (str2 == null) return String(str1).length; + + str1 = String(str1); str2 = String(str2); + + var current = [], prev, value; + + for (var i = 0; i <= str2.length; i++) + for (var j = 0; j <= str1.length; j++) { + if (i && j) + if (str1.charAt(j - 1) === str2.charAt(i - 1)) + value = prev; + else + value = Math.min(current[j], current[j - 1], prev) + 1; + else + value = i + j; + + prev = current[j]; + current[j] = value; + } + + return current.pop(); + }, + + toBoolean: function(str, trueValues, falseValues) { + if (typeof str === "number") str = "" + str; + if (typeof str !== "string") return !!str; + str = _s.trim(str); + if (boolMatch(str, trueValues || ["true", "1"])) return true; + if (boolMatch(str, falseValues || ["false", "0"])) return false; + } + }; + + // Aliases + + _s.strip = _s.trim; + _s.lstrip = _s.ltrim; + _s.rstrip = _s.rtrim; + _s.center = _s.lrpad; + _s.rjust = _s.lpad; + _s.ljust = _s.rpad; + _s.contains = _s.include; + _s.q = _s.quote; + _s.toBool = _s.toBoolean; + + // Exporting + + // CommonJS module is defined + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) + module.exports = _s; + + exports._s = _s; + } + + // Register as a named module with AMD. + if (typeof define === 'function' && define.amd) + define('underscore.string', [], function(){ return _s; }); + + + // Integrate with Underscore.js if defined + // or create our own underscore object. + root._ = root._ || {}; + root._.string = root._.str = _s; +}(this, String); diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/libpeerconnection.log b/node_modules/grunt-legacy-log/node_modules/underscore.string/libpeerconnection.log new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/package.json b/node_modules/grunt-legacy-log/node_modules/underscore.string/package.json new file mode 100644 index 0000000..c2e03c9 --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/underscore.string/package.json @@ -0,0 +1,132 @@ +{ + "_args": [ + [ + { + "raw": "underscore.string@~2.3.3", + "scope": null, + "escapedName": "underscore.string", + "name": "underscore.string", + "rawSpec": "~2.3.3", + "spec": ">=2.3.3 <2.4.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt-legacy-log" + ] + ], + "_from": "underscore.string@>=2.3.3 <2.4.0", + "_id": "underscore.string@2.3.3", + "_inCache": true, + "_location": "/grunt-legacy-log/underscore.string", + "_npmUser": { + "name": "epeli", + "email": "esa-matti@suuronen.org" + }, + "_npmVersion": "1.2.32", + "_phantomChildren": {}, + "_requested": { + "raw": "underscore.string@~2.3.3", + "scope": null, + "escapedName": "underscore.string", + "name": "underscore.string", + "rawSpec": "~2.3.3", + "spec": ">=2.3.3 <2.4.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt-legacy-log" + ], + "_resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", + "_shasum": "71c08bf6b428b1133f37e78fa3a21c82f7329b0d", + "_shrinkwrap": null, + "_spec": "underscore.string@~2.3.3", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt-legacy-log", + "bugs": { + "url": "https://github.com/epeli/underscore.string/issues" + }, + "contributors": [ + { + "name": "Esa-Matti Suuronen", + "email": "esa-matti@suuronen.org", + "url": "http://esa-matti.suuronen.org/" + }, + { + "name": "Edward Tsech", + "email": "edtsech@gmail.com" + }, + { + "name": "Pavel Pravosud", + "email": "pavel@pravosud.com", + "url": "" + }, + { + "name": "Sasha Koss", + "email": "kossnocorp@gmail.com", + "url": "http://koss.nocorp.me/" + }, + { + "name": "Vladimir Dronnikov", + "email": "dronnikov@gmail.com" + }, + { + "name": "Pete Kruckenberg", + "email": "https://github.com/kruckenb", + "url": "" + }, + { + "name": "Paul Chavard", + "email": "paul@chavard.net", + "url": "" + }, + { + "name": "Ed Finkler", + "email": "coj@funkatron.com", + "url": "" + } + ], + "dependencies": {}, + "description": "String manipulation extensions for Underscore.js javascript library.", + "devDependencies": {}, + "directories": { + "lib": "./lib" + }, + "dist": { + "shasum": "71c08bf6b428b1133f37e78fa3a21c82f7329b0d", + "tarball": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz" + }, + "engines": { + "node": "*" + }, + "homepage": "http://epeli.github.com/underscore.string/", + "keywords": [ + "underscore", + "string" + ], + "licenses": [ + { + "type": "MIT" + } + ], + "main": "./lib/underscore.string", + "maintainers": [ + { + "name": "edtsech", + "email": "edtsech@gmail.com" + }, + { + "name": "rwz", + "email": "rwz@duckroll.ru" + }, + { + "name": "epeli", + "email": "esa-matti@suuronen.org" + } + ], + "name": "underscore.string", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/epeli/underscore.string.git" + }, + "version": "2.3.3" +} diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/test/run-qunit.js b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/run-qunit.js new file mode 100644 index 0000000..44a2167 --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/run-qunit.js @@ -0,0 +1,45 @@ +function waitFor(test, complete, timeout) { + var result, start = new Date().getTime() + setInterval(function interval() { + if ((new Date().getTime() - start < timeout) && !result) { + result = test() + } else { + if (!result) { + phantom.exit(1) + } else { + complete() + clearInterval(interval) + } + } + }, 100) +} + + +var fs = require('fs'), page = require('webpage').create(); +var url = 'file://localhost' + fs.workingDirectory + '/' + phantom.args[0]; + +page.onConsoleMessage = function(msg) { + console.log(msg) +} + +page.open(url, function(status) { + waitFor(function() { + return page.evaluate(function(){ + var el = document.getElementById('qunit-testresult') + return el && el.innerText.match('completed') + }) + }, function() { + var failures = page.evaluate(function() { + var el = document.getElementById('qunit-testresult'), + fails = document.getElementsByClassName('fail') + + for (var i = 0; i < fails.length; i++) + console.log(fails[i].innerText) + + console.log(el.innerText) + + return parseInt(el.getElementsByClassName('failed')[0].innerHTML) + }) + phantom.exit(failures > 0 ? 1 : 0) + }, 10000) +}) \ No newline at end of file diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/test/speed.js b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/speed.js new file mode 100644 index 0000000..9ceeea7 --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/speed.js @@ -0,0 +1,148 @@ +(function() { + + JSLitmus.test('levenshtein', function() { + return [ + _.levenshtein('pineapple', 'potato'), + _.levenshtein('seven', 'eight'), + _.levenshtein('the very same string', 'the very same string'), + _.levenshtein('very very very long string', 'something completely different') + ]; + }); + + + JSLitmus.test('trimNoNative', function() { + return _.trim(" foobar ", " "); + }); + + JSLitmus.test('trim', function() { + return _.trim(" foobar "); + }); + + JSLitmus.test('trim object-oriented', function() { + return _(" foobar ").trim(); + }); + + JSLitmus.test('trim jQuery', function() { + return jQuery.trim(" foobar "); + }); + + JSLitmus.test('ltrimp', function() { + return _.ltrim(" foobar ", " "); + }); + + JSLitmus.test('rtrimp', function() { + return _.rtrim(" foobar ", " "); + }); + + JSLitmus.test('startsWith', function() { + return _.startsWith("foobar", "foo"); + }); + + JSLitmus.test('endsWith', function() { + return _.endsWith("foobar", "xx"); + }); + + JSLitmus.test('chop', function(){ + return _('whitespace').chop(2); + }); + + JSLitmus.test('count', function(){ + return _('Hello worls').count('l'); + }); + + JSLitmus.test('insert', function() { + return _('Hello ').insert(6, 'world'); + }); + + JSLitmus.test('splice', function() { + return _('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli'); + }); + + JSLitmus.test('succ', function(){ + var let = 'a', alphabet = []; + + for (var i=0; i < 26; i++) { + alphabet.push(let); + let = _(let).succ(); + } + + return alphabet; + }); + + JSLitmus.test('titleize', function(){ + return _('the titleize string method').titleize(); + }); + + JSLitmus.test('truncate', function(){ + return _('Hello world').truncate(5); + }); + + JSLitmus.test('prune', function(){ + return _('Hello world').prune(5); + }); + + JSLitmus.test('isBlank', function(){ + return _('').isBlank(); + }); + + JSLitmus.test('escapeHTML', function(){ + _('
      Blah blah blah
      ').escapeHTML(); + }); + + JSLitmus.test('unescapeHTML', function(){ + _('<div>Blah blah blah</div>').unescapeHTML(); + }); + + JSLitmus.test('reverse', function(){ + _('Hello World').reverse(); + }); + + JSLitmus.test('pad default', function(){ + _('foo').pad(12); + }); + + JSLitmus.test('pad hash left', function(){ + _('foo').pad(12, '#'); + }); + + JSLitmus.test('pad hash right', function(){ + _('foo').pad(12, '#', 'right'); + }); + + JSLitmus.test('pad hash both', function(){ + _('foo').pad(12, '#', 'both'); + }); + + JSLitmus.test('pad hash both longPad', function(){ + _('foo').pad(12, 'f00f00f00', 'both'); + }); + + JSLitmus.test('toNumber', function(){ + _('10.232323').toNumber(2); + }); + + JSLitmus.test('strRight', function(){ + _('aaa_bbb_ccc').strRight('_'); + }); + + JSLitmus.test('strRightBack', function(){ + _('aaa_bbb_ccc').strRightBack('_'); + }); + + JSLitmus.test('strLeft', function(){ + _('aaa_bbb_ccc').strLeft('_'); + }); + + JSLitmus.test('strLeftBack', function(){ + _('aaa_bbb_ccc').strLeftBack('_'); + }); + + JSLitmus.test('join', function(){ + _('separator').join(1, 2, 3, 4, 5, 6, 7, 8, 'foo', 'bar', 'lol', 'wut'); + }); + + JSLitmus.test('slugify', function(){ + _("Un éléphant à l'orée du bois").slugify(); + }); + +})(); diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/test/strings.js b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/strings.js new file mode 100644 index 0000000..77364f2 --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/strings.js @@ -0,0 +1,685 @@ +$(document).ready(function() { + + // Include Underscore.string methods to Underscore namespace + _.mixin(_.str.exports()); + + module('String extensions'); + + test('Strings: naturalSort', function() { + var arr = ['foo2', 'foo1', 'foo10', 'foo30', 'foo100', 'foo10bar'], + sorted = ['foo1', 'foo2', 'foo10', 'foo10bar', 'foo30', 'foo100']; + deepEqual(arr.sort(_.naturalCmp), sorted); + }); + + test('Strings: trim', function() { + equal(_.trim(123), '123', 'Non string'); + equal(_(' foo').trim(), 'foo'); + equal(_('foo ').trim(), 'foo'); + equal(_(' foo ').trim(), 'foo'); + equal(_(' foo ').trim(), 'foo'); + equal(_(' foo ').trim(' '), 'foo', 'Manually set whitespace'); + equal(_('\t foo \t ').trim(/\s/), 'foo', 'Manually set RegExp /\\s+/'); + + equal(_('ffoo').trim('f'), 'oo'); + equal(_('ooff').trim('f'), 'oo'); + equal(_('ffooff').trim('f'), 'oo'); + + + equal(_('_-foobar-_').trim('_-'), 'foobar'); + + equal(_('http://foo/').trim('/'), 'http://foo'); + equal(_('c:\\').trim('\\'), 'c:'); + + equal(_(123).trim(), '123'); + equal(_(123).trim(3), '12'); + equal(_('').trim(), '', 'Trim empty string should return empty string'); + equal(_(null).trim(), '', 'Trim null should return empty string'); + equal(_(undefined).trim(), '', 'Trim undefined should return empty string'); + }); + + test('String: levenshtein', function() { + equal(_.levenshtein('Godfather', 'Godfather'), 0); + equal(_.levenshtein('Godfather', 'Godfathe'), 1); + equal(_.levenshtein('Godfather', 'odfather'), 1); + equal(_.levenshtein('Godfather', 'Gdfthr'), 3); + equal(_.levenshtein('seven', 'eight'), 5); + equal(_.levenshtein('123', 123), 0); + equal(_.levenshtein(321, '321'), 0); + equal(_.levenshtein('lol', null), 3); + equal(_.levenshtein('lol'), 3); + equal(_.levenshtein(null, 'lol'), 3); + equal(_.levenshtein(undefined, 'lol'), 3); + equal(_.levenshtein(), 0); + }); + + test('Strings: ltrim', function() { + equal(_(' foo').ltrim(), 'foo'); + equal(_(' foo').ltrim(), 'foo'); + equal(_('foo ').ltrim(), 'foo '); + equal(_(' foo ').ltrim(), 'foo '); + equal(_('').ltrim(), '', 'ltrim empty string should return empty string'); + equal(_(null).ltrim(), '', 'ltrim null should return empty string'); + equal(_(undefined).ltrim(), '', 'ltrim undefined should return empty string'); + + equal(_('ffoo').ltrim('f'), 'oo'); + equal(_('ooff').ltrim('f'), 'ooff'); + equal(_('ffooff').ltrim('f'), 'ooff'); + + equal(_('_-foobar-_').ltrim('_-'), 'foobar-_'); + + equal(_(123).ltrim(1), '23'); + }); + + test('Strings: rtrim', function() { + equal(_('http://foo/').rtrim('/'), 'http://foo', 'clean trailing slash'); + equal(_(' foo').rtrim(), ' foo'); + equal(_('foo ').rtrim(), 'foo'); + equal(_('foo ').rtrim(), 'foo'); + equal(_('foo bar ').rtrim(), 'foo bar'); + equal(_(' foo ').rtrim(), ' foo'); + + equal(_('ffoo').rtrim('f'), 'ffoo'); + equal(_('ooff').rtrim('f'), 'oo'); + equal(_('ffooff').rtrim('f'), 'ffoo'); + + equal(_('_-foobar-_').rtrim('_-'), '_-foobar'); + + equal(_(123).rtrim(3), '12'); + equal(_('').rtrim(), '', 'rtrim empty string should return empty string'); + equal(_(null).rtrim(), '', 'rtrim null should return empty string'); + }); + + test('Strings: capitalize', function() { + equal(_('fabio').capitalize(), 'Fabio', 'First letter is upper case'); + equal(_.capitalize('fabio'), 'Fabio', 'First letter is upper case'); + equal(_.capitalize('FOO'), 'FOO', 'Other letters unchanged'); + equal(_(123).capitalize(), '123', 'Non string'); + equal(_.capitalize(''), '', 'Capitalizing empty string returns empty string'); + equal(_.capitalize(null), '', 'Capitalizing null returns empty string'); + equal(_.capitalize(undefined), '', 'Capitalizing undefined returns empty string'); + }); + + test('Strings: join', function() { + equal(_.join('', 'foo', 'bar'), 'foobar', 'basic join'); + equal(_.join('', 1, 'foo', 2), '1foo2', 'join numbers and strings'); + equal(_.join(' ','foo', 'bar'), 'foo bar', 'join with spaces'); + equal(_.join('1', '2', '2'), '212', 'join number strings'); + equal(_.join(1, 2, 2), '212', 'join numbers'); + equal(_.join('','foo', null), 'foo', 'join null with string returns string'); + equal(_.join(null,'foo', 'bar'), 'foobar', 'join strings with null returns string'); + equal(_(' ').join('foo', 'bar'), 'foo bar', 'join object oriented'); + }); + + test('Strings: reverse', function() { + equal(_.str.reverse('foo'), 'oof' ); + equal(_.str.reverse('foobar'), 'raboof' ); + equal(_.str.reverse('foo bar'), 'rab oof' ); + equal(_.str.reverse('saippuakauppias'), 'saippuakauppias' ); + equal(_.str.reverse(123), '321', 'Non string'); + equal(_.str.reverse(123.45), '54.321', 'Non string'); + equal(_.str.reverse(''), '', 'reversing empty string returns empty string' ); + equal(_.str.reverse(null), '', 'reversing null returns empty string' ); + equal(_.str.reverse(undefined), '', 'reversing undefined returns empty string' ); + }); + + test('Strings: clean', function() { + equal(_(' foo bar ').clean(), 'foo bar'); + equal(_(123).clean(), '123'); + equal(_('').clean(), '', 'claning empty string returns empty string'); + equal(_(null).clean(), '', 'claning null returns empty string'); + equal(_(undefined).clean(), '', 'claning undefined returns empty string'); + }); + + test('Strings: sprintf', function() { + // Should be very tested function already. Thanks to + // http://www.diveintojavascript.com/projects/sprintf-for-javascript + equal(_.sprintf('Hello %s', 'me'), 'Hello me', 'basic'); + equal(_('Hello %s').sprintf('me'), 'Hello me', 'object'); + equal(_('hello %s').chain().sprintf('me').capitalize().value(), 'Hello me', 'Chaining works'); + equal(_.sprintf('%.1f', 1.22222), '1.2', 'round'); + equal(_.sprintf('%.1f', 1.17), '1.2', 'round 2'); + equal(_.sprintf('%(id)d - %(name)s', {id: 824, name: 'Hello World'}), '824 - Hello World', 'Named replacements work'); + equal(_.sprintf('%(args[0].id)d - %(args[1].name)s', {args: [{id: 824}, {name: 'Hello World'}]}), '824 - Hello World', 'Named replacements with arrays work'); + }); + + + test('Strings: vsprintf', function() { + equal(_.vsprintf('Hello %s', ['me']), 'Hello me', 'basic'); + equal(_('Hello %s').vsprintf(['me']), 'Hello me', 'object'); + equal(_('hello %s').chain().vsprintf(['me']).capitalize().value(), 'Hello me', 'Chaining works'); + equal(_.vsprintf('%.1f', [1.22222]), '1.2', 'round'); + equal(_.vsprintf('%.1f', [1.17]), '1.2', 'round 2'); + equal(_.vsprintf('%(id)d - %(name)s', [{id: 824, name: 'Hello World'}]), '824 - Hello World', 'Named replacement works'); + equal(_.vsprintf('%(args[0].id)d - %(args[1].name)s', [{args: [{id: 824}, {name: 'Hello World'}]}]), '824 - Hello World', 'Named replacement with arrays works'); + }); + + test('Strings: startsWith', function() { + ok(_('foobar').startsWith('foo'), 'foobar starts with foo'); + ok(!_('oobar').startsWith('foo'), 'oobar does not start with foo'); + ok(_(12345).startsWith(123), '12345 starts with 123'); + ok(!_(2345).startsWith(123), '2345 does not start with 123'); + ok(_('').startsWith(''), 'empty string starts with empty string'); + ok(_(null).startsWith(''), 'null starts with empty string'); + ok(!_(null).startsWith('foo'), 'null starts with foo'); + }); + + test('Strings: endsWith', function() { + ok(_('foobar').endsWith('bar'), 'foobar ends with bar'); + ok(_.endsWith('foobar', 'bar'), 'foobar ends with bar'); + ok(_.endsWith('00018-0000062.Plone.sdh264.1a7264e6912a91aa4a81b64dc5517df7b8875994.mp4', 'mp4'), 'endsWith .mp4'); + ok(!_('fooba').endsWith('bar'), 'fooba does not end with bar'); + ok(_.endsWith(12345, 45), '12345 ends with 45'); + ok(!_.endsWith(12345, 6), '12345 does not end with 6'); + ok(_('').endsWith(''), 'empty string ends with empty string'); + ok(_(null).endsWith(''), 'null ends with empty string'); + ok(!_(null).endsWith('foo'), 'null ends with foo'); + }); + + test('Strings: include', function() { + ok(_.str.include('foobar', 'bar'), 'foobar includes bar'); + ok(!_.str.include('foobar', 'buzz'), 'foobar does not includes buzz'); + ok(_.str.include(12345, 34), '12345 includes 34'); + ok(!_.str.contains(12345, 6), '12345 does not includes 6'); + ok(!_.str.include('', 34), 'empty string includes 34'); + ok(!_.str.include(null, 34), 'null includes 34'); + ok(_.str.include(null, ''), 'null includes empty string'); + }); + + test('String: chop', function(){ + ok(_('whitespace').chop(2).length === 5, 'output [wh, it, es, pa, ce]'); + ok(_('whitespace').chop(3).length === 4, 'output [whi, tes, pac, e]'); + ok(_('whitespace').chop()[0].length === 10, 'output [whitespace]'); + ok(_(12345).chop(1).length === 5, 'output [1, 2, 3, 4, 5]'); + }); + + test('String: clean', function(){ + equal(_.clean(' foo bar '), 'foo bar'); + equal(_.clean(''), ''); + equal(_.clean(null), ''); + equal(_.clean(1), '1'); + }); + + test('String: count', function(){ + equal(_('Hello world').count('l'), 3); + equal(_('Hello world').count('Hello'), 1); + equal(_('Hello world').count('foo'), 0); + equal(_('x.xx....x.x').count('x'), 5); + equal(_('').count('x'), 0); + equal(_(null).count('x'), 0); + equal(_(undefined).count('x'), 0); + equal(_(12345).count(1), 1); + equal(_(11345).count(1), 2); + }); + + test('String: insert', function(){ + equal(_('Hello ').insert(6, 'Jessy'), 'Hello Jessy'); + equal(_('Hello ').insert(100, 'Jessy'), 'Hello Jessy'); + equal(_('').insert(100, 'Jessy'), 'Jessy'); + equal(_(null).insert(100, 'Jessy'), 'Jessy'); + equal(_(undefined).insert(100, 'Jessy'), 'Jessy'); + equal(_(12345).insert(6, 'Jessy'), '12345Jessy'); + }); + + test('String: splice', function(){ + equal(_('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli'), + 'https://edtsech@bitbucket.org/epeli/underscore.strings'); + equal(_.splice(12345, 1, 2, 321), '132145', 'Non strings'); + }); + + test('String: succ', function(){ + equal(_('a').succ(), 'b'); + equal(_('A').succ(), 'B'); + equal(_('+').succ(), ','); + equal(_(1).succ(), '2'); + }); + + test('String: titleize', function(){ + equal(_('the titleize string method').titleize(), 'The Titleize String Method'); + equal(_('the titleize string method').titleize(), 'The Titleize String Method'); + equal(_('').titleize(), '', 'Titleize empty string returns empty string'); + equal(_(null).titleize(), '', 'Titleize null returns empty string'); + equal(_(undefined).titleize(), '', 'Titleize undefined returns empty string'); + equal(_('let\'s have some fun').titleize(), 'Let\'s Have Some Fun'); + equal(_('a-dash-separated-string').titleize(), 'A-Dash-Separated-String'); + equal(_('A-DASH-SEPARATED-STRING').titleize(), 'A-Dash-Separated-String'); + equal(_(123).titleize(), '123'); + }); + + test('String: camelize', function(){ + equal(_('the_camelize_string_method').camelize(), 'theCamelizeStringMethod'); + equal(_('-the-camelize-string-method').camelize(), 'TheCamelizeStringMethod'); + equal(_('the camelize string method').camelize(), 'theCamelizeStringMethod'); + equal(_(' the camelize string method').camelize(), 'theCamelizeStringMethod'); + equal(_('the camelize string method').camelize(), 'theCamelizeStringMethod'); + equal(_('').camelize(), '', 'Camelize empty string returns empty string'); + equal(_(null).camelize(), '', 'Camelize null returns empty string'); + equal(_(undefined).camelize(), '', 'Camelize undefined returns empty string'); + equal(_(123).camelize(), '123'); + }); + + test('String: underscored', function(){ + equal(_('the-underscored-string-method').underscored(), 'the_underscored_string_method'); + equal(_('theUnderscoredStringMethod').underscored(), 'the_underscored_string_method'); + equal(_('TheUnderscoredStringMethod').underscored(), 'the_underscored_string_method'); + equal(_(' the underscored string method').underscored(), 'the_underscored_string_method'); + equal(_('').underscored(), ''); + equal(_(null).underscored(), ''); + equal(_(undefined).underscored(), ''); + equal(_(123).underscored(), '123'); + }); + + test('String: dasherize', function(){ + equal(_('the_dasherize_string_method').dasherize(), 'the-dasherize-string-method'); + equal(_('TheDasherizeStringMethod').dasherize(), '-the-dasherize-string-method'); + equal(_('thisIsATest').dasherize(), 'this-is-a-test'); + equal(_('this Is A Test').dasherize(), 'this-is-a-test'); + equal(_('thisIsATest123').dasherize(), 'this-is-a-test123'); + equal(_('123thisIsATest').dasherize(), '123this-is-a-test'); + equal(_('the dasherize string method').dasherize(), 'the-dasherize-string-method'); + equal(_('the dasherize string method ').dasherize(), 'the-dasherize-string-method'); + equal(_('téléphone').dasherize(), 'téléphone'); + equal(_('foo$bar').dasherize(), 'foo$bar'); + equal(_('').dasherize(), ''); + equal(_(null).dasherize(), ''); + equal(_(undefined).dasherize(), ''); + equal(_(123).dasherize(), '123'); + }); + + test('String: camelize', function(){ + equal(_.camelize('-moz-transform'), 'MozTransform'); + equal(_.camelize('webkit-transform'), 'webkitTransform'); + equal(_.camelize('under_scored'), 'underScored'); + equal(_.camelize(' with spaces'), 'withSpaces'); + equal(_('').camelize(), ''); + equal(_(null).camelize(), ''); + equal(_(undefined).camelize(), ''); + equal(_("_som eWeird---name-").camelize(), 'SomEWeirdName'); + }); + + test('String: join', function(){ + equal(_.join(1, 2, 3, 4), '21314'); + equal(_.join('|', 'foo', 'bar', 'baz'), 'foo|bar|baz'); + equal(_.join('',2,3,null), '23'); + equal(_.join(null,2,3), '23'); + }); + + test('String: classify', function(){ + equal(_.classify(1), '1'); + equal(_('some_class_name').classify(), 'SomeClassName'); + equal(_('my wonderfull class_name').classify(), 'MyWonderfullClassName'); + equal(_('my wonderfull.class.name').classify(), 'MyWonderfullClassName'); + }); + + test('String: humanize', function(){ + equal(_('the_humanize_string_method').humanize(), 'The humanize string method'); + equal(_('ThehumanizeStringMethod').humanize(), 'Thehumanize string method'); + equal(_('the humanize string method').humanize(), 'The humanize string method'); + equal(_('the humanize_id string method_id').humanize(), 'The humanize id string method'); + equal(_('the humanize string method ').humanize(), 'The humanize string method'); + equal(_(' capitalize dash-CamelCase_underscore trim ').humanize(), 'Capitalize dash camel case underscore trim'); + equal(_(123).humanize(), '123'); + equal(_('').humanize(), ''); + equal(_(null).humanize(), ''); + equal(_(undefined).humanize(), ''); + }); + + test('String: truncate', function(){ + equal(_('Hello world').truncate(6, 'read more'), 'Hello read more'); + equal(_('Hello world').truncate(5), 'Hello...'); + equal(_('Hello').truncate(10), 'Hello'); + equal(_('').truncate(10), ''); + equal(_(null).truncate(10), ''); + equal(_(undefined).truncate(10), ''); + equal(_(1234567890).truncate(5), '12345...'); + }); + + test('String: prune', function(){ + equal(_('Hello, cruel world').prune(6, ' read more'), 'Hello read more'); + equal(_('Hello, world').prune(5, 'read a lot more'), 'Hello, world'); + equal(_('Hello, world').prune(5), 'Hello...'); + equal(_('Hello, world').prune(8), 'Hello...'); + equal(_('Hello, cruel world').prune(15), 'Hello, cruel...'); + equal(_('Hello world').prune(22), 'Hello world'); + equal(_('Привет, жестокий мир').prune(6, ' read more'), 'Привет read more'); + equal(_('Привет, мир').prune(6, 'read a lot more'), 'Привет, мир'); + equal(_('Привет, мир').prune(6), 'Привет...'); + equal(_('Привет, мир').prune(8), 'Привет...'); + equal(_('Привет, жестокий мир').prune(16), 'Привет, жестокий...'); + equal(_('Привет, мир').prune(22), 'Привет, мир'); + equal(_('alksjd!!!!!!....').prune(100, ''), 'alksjd!!!!!!....'); + equal(_(123).prune(10), '123'); + equal(_(123).prune(1, 321), '321'); + equal(_('').prune(5), ''); + equal(_(null).prune(5), ''); + equal(_(undefined).prune(5), ''); + }); + + test('String: isBlank', function(){ + ok(_('').isBlank()); + ok(_(' ').isBlank()); + ok(_('\n').isBlank()); + ok(!_('a').isBlank()); + ok(!_('0').isBlank()); + ok(!_(0).isBlank()); + ok(_('').isBlank()); + ok(_(null).isBlank()); + ok(_(undefined).isBlank()); + }); + + test('String: escapeRegExp', function(){ + equal(_.escapeRegExp(/hello(?=\sworld)/.source), 'hello\\(\\?\\=\\\\sworld\\)', 'with lookahead'); + equal(_.escapeRegExp(/hello(?!\shell)/.source), 'hello\\(\\?\\!\\\\shell\\)', 'with negative lookahead'); + }); + + test('String: escapeHTML', function(){ + equal(_('
      Blah & "blah" & \'blah\'
      ').escapeHTML(), + '<div>Blah & "blah" & 'blah'</div>'); + equal(_('<').escapeHTML(), '&lt;'); + equal(_(5).escapeHTML(), '5'); + equal(_('').escapeHTML(), ''); + equal(_(null).escapeHTML(), ''); + equal(_(undefined).escapeHTML(), ''); + }); + + test('String: unescapeHTML', function(){ + equal(_('<div>Blah & "blah" & 'blah'</div>').unescapeHTML(), + '
      Blah & "blah" & \'blah\'
      '); + equal(_('&lt;').unescapeHTML(), '<'); + equal(_(''').unescapeHTML(), '\''); + equal(_(''').unescapeHTML(), '\''); + equal(_(''').unescapeHTML(), '\''); + equal(_('J').unescapeHTML(), 'J'); + equal(_('J').unescapeHTML(), 'J'); + equal(_('J').unescapeHTML(), 'J'); + equal(_('&_#39;').unescapeHTML(), '&_#39;'); + equal(_(''_;').unescapeHTML(), ''_;'); + equal(_('&#38;').unescapeHTML(), '&'); + equal(_('&amp;').unescapeHTML(), '&'); + equal(_('').unescapeHTML(), ''); + equal(_(null).unescapeHTML(), ''); + equal(_(undefined).unescapeHTML(), ''); + equal(_(5).unescapeHTML(), '5'); + // equal(_(undefined).unescapeHTML(), ''); + }); + + test('String: words', function() { + deepEqual(_('I love you!').words(), ['I', 'love', 'you!']); + deepEqual(_(' I love you! ').words(), ['I', 'love', 'you!']); + deepEqual(_('I_love_you!').words('_'), ['I', 'love', 'you!']); + deepEqual(_('I-love-you!').words(/-/), ['I', 'love', 'you!']); + deepEqual(_(123).words(), ['123'], '123 number has one word "123".'); + deepEqual(_(0).words(), ['0'], 'Zero number has one word "0".'); + deepEqual(_('').words(), [], 'Empty strings has no words.'); + deepEqual(_(' ').words(), [], 'Blank strings has no words.'); + deepEqual(_(null).words(), [], 'null has no words.'); + deepEqual(_(undefined).words(), [], 'undefined has no words.'); + }); + + test('String: chars', function() { + equal(_('Hello').chars().length, 5); + equal(_(123).chars().length, 3); + equal(_('').chars().length, 0); + equal(_(null).chars().length, 0); + equal(_(undefined).chars().length, 0); + }); + + test('String: swapCase', function(){ + equal(_('AaBbCcDdEe').swapCase(), 'aAbBcCdDeE'); + equal(_('Hello World').swapCase(), 'hELLO wORLD'); + equal(_('').swapCase(), ''); + equal(_(null).swapCase(), ''); + equal(_(undefined).swapCase(), ''); + }); + + test('String: lines', function() { + equal(_('Hello\nWorld').lines().length, 2); + equal(_('Hello World').lines().length, 1); + equal(_(123).lines().length, 1); + equal(_('').lines().length, 1); + equal(_(null).lines().length, 0); + equal(_(undefined).lines().length, 0); + }); + + test('String: pad', function() { + equal(_('1').pad(8), ' 1'); + equal(_(1).pad(8), ' 1'); + equal(_('1').pad(8, '0'), '00000001'); + equal(_('1').pad(8, '0', 'left'), '00000001'); + equal(_('1').pad(8, '0', 'right'), '10000000'); + equal(_('1').pad(8, '0', 'both'), '00001000'); + equal(_('foo').pad(8, '0', 'both'), '000foo00'); + equal(_('foo').pad(7, '0', 'both'), '00foo00'); + equal(_('foo').pad(7, '!@$%dofjrofj', 'both'), '!!foo!!'); + equal(_('').pad(2), ' '); + equal(_(null).pad(2), ' '); + equal(_(undefined).pad(2), ' '); + }); + + test('String: lpad', function() { + equal(_('1').lpad(8), ' 1'); + equal(_(1).lpad(8), ' 1'); + equal(_('1').lpad(8, '0'), '00000001'); + equal(_('1').lpad(8, '0', 'left'), '00000001'); + equal(_('').lpad(2), ' '); + equal(_(null).lpad(2), ' '); + equal(_(undefined).lpad(2), ' '); + }); + + test('String: rpad', function() { + equal(_('1').rpad(8), '1 '); + equal(_(1).lpad(8), ' 1'); + equal(_('1').rpad(8, '0'), '10000000'); + equal(_('foo').rpad(8, '0'), 'foo00000'); + equal(_('foo').rpad(7, '0'), 'foo0000'); + equal(_('').rpad(2), ' '); + equal(_(null).rpad(2), ' '); + equal(_(undefined).rpad(2), ' '); + }); + + test('String: lrpad', function() { + equal(_('1').lrpad(8), ' 1 '); + equal(_(1).lrpad(8), ' 1 '); + equal(_('1').lrpad(8, '0'), '00001000'); + equal(_('foo').lrpad(8, '0'), '000foo00'); + equal(_('foo').lrpad(7, '0'), '00foo00'); + equal(_('foo').lrpad(7, '!@$%dofjrofj'), '!!foo!!'); + equal(_('').lrpad(2), ' '); + equal(_(null).lrpad(2), ' '); + equal(_(undefined).lrpad(2), ' '); + }); + + test('String: toNumber', function() { + deepEqual(_('not a number').toNumber(), NaN); + equal(_(0).toNumber(), 0); + equal(_('0').toNumber(), 0); + equal(_('0.0').toNumber(), 0); + equal(_('0.1').toNumber(), 0); + equal(_('0.1').toNumber(1), 0.1); + equal(_(' 0.1 ').toNumber(1), 0.1); + equal(_('0000').toNumber(), 0); + equal(_('2.345').toNumber(), 2); + equal(_('2.345').toNumber(NaN), 2); + equal(_('2.345').toNumber(2), 2.35); + equal(_('2.344').toNumber(2), 2.34); + equal(_('2').toNumber(2), 2.00); + equal(_(2).toNumber(2), 2.00); + equal(_(-2).toNumber(), -2); + equal(_('-2').toNumber(), -2); + equal(_('').toNumber(), 0); + equal(_(null).toNumber(), 0); + equal(_(undefined).toNumber(), 0); + }); + + test('String: numberFormat', function() { + equal(_.numberFormat(9000), '9,000'); + equal(_.numberFormat(9000, 0), '9,000'); + equal(_.numberFormat(9000, 0, '', ''), '9000'); + equal(_.numberFormat(90000, 2), '90,000.00'); + equal(_.numberFormat(1000.754), '1,001'); + equal(_.numberFormat(1000.754, 2), '1,000.75'); + equal(_.numberFormat(1000.754, 0, ',', '.'), '1.001'); + equal(_.numberFormat(1000.754, 2, ',', '.'), '1.000,75'); + equal(_.numberFormat(1000000.754, 2, ',', '.'), '1.000.000,75'); + equal(_.numberFormat(1000000000), '1,000,000,000'); + equal(_.numberFormat(100000000), '100,000,000'); + equal(_.numberFormat('not number'), ''); + equal(_.numberFormat(), ''); + equal(_.numberFormat(null, '.', ','), ''); + equal(_.numberFormat(undefined, '.', ','), ''); + equal(_.numberFormat(new Number(5000)), '5,000'); + }); + + test('String: strRight', function() { + equal(_('This_is_a_test_string').strRight('_'), 'is_a_test_string'); + equal(_('This_is_a_test_string').strRight('string'), ''); + equal(_('This_is_a_test_string').strRight(), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strRight(''), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strRight('-'), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strRight(''), 'This_is_a_test_string'); + equal(_('').strRight('foo'), ''); + equal(_(null).strRight('foo'), ''); + equal(_(undefined).strRight('foo'), ''); + equal(_(12345).strRight(2), '345'); + }); + + test('String: strRightBack', function() { + equal(_('This_is_a_test_string').strRightBack('_'), 'string'); + equal(_('This_is_a_test_string').strRightBack('string'), ''); + equal(_('This_is_a_test_string').strRightBack(), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strRightBack(''), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strRightBack('-'), 'This_is_a_test_string'); + equal(_('').strRightBack('foo'), ''); + equal(_(null).strRightBack('foo'), ''); + equal(_(undefined).strRightBack('foo'), ''); + equal(_(12345).strRightBack(2), '345'); + }); + + test('String: strLeft', function() { + equal(_('This_is_a_test_string').strLeft('_'), 'This'); + equal(_('This_is_a_test_string').strLeft('This'), ''); + equal(_('This_is_a_test_string').strLeft(), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strLeft(''), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strLeft('-'), 'This_is_a_test_string'); + equal(_('').strLeft('foo'), ''); + equal(_(null).strLeft('foo'), ''); + equal(_(undefined).strLeft('foo'), ''); + equal(_(123454321).strLeft(3), '12'); + }); + + test('String: strLeftBack', function() { + equal(_('This_is_a_test_string').strLeftBack('_'), 'This_is_a_test'); + equal(_('This_is_a_test_string').strLeftBack('This'), ''); + equal(_('This_is_a_test_string').strLeftBack(), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strLeftBack(''), 'This_is_a_test_string'); + equal(_('This_is_a_test_string').strLeftBack('-'), 'This_is_a_test_string'); + equal(_('').strLeftBack('foo'), ''); + equal(_(null).strLeftBack('foo'), ''); + equal(_(undefined).strLeftBack('foo'), ''); + equal(_(123454321).strLeftBack(3), '123454'); + }); + + test('Strings: stripTags', function() { + equal(_('a link').stripTags(), 'a link'); + equal(_('a link + + + + + + + + +

      Underscore.string Test Suite

      +

      +

      +
        +
        +

        Underscore.string Speed Suite

        + +
        + + diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_standalone.html b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_standalone.html new file mode 100644 index 0000000..9854c17 --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_standalone.html @@ -0,0 +1,18 @@ + + + + Underscore.strings Test Suite + + + + + + + + +

        Underscore.string Test Suite

        +

        +

        +
          + + diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/arrays.js b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/arrays.js new file mode 100644 index 0000000..32252a3 --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/arrays.js @@ -0,0 +1,200 @@ +$(document).ready(function() { + + module("Arrays"); + + test("first", function() { + equal(_.first([1,2,3]), 1, 'can pull out the first element of an array'); + equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"'); + equal(_.first([1,2,3], 0).join(', '), "", 'can pass an index to first'); + equal(_.first([1,2,3], 2).join(', '), '1, 2', 'can pass an index to first'); + equal(_.first([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to first'); + var result = (function(){ return _.first(arguments); })(4, 3, 2, 1); + equal(result, 4, 'works on an arguments object.'); + result = _.map([[1,2,3],[1,2,3]], _.first); + equal(result.join(','), '1,1', 'works well with _.map'); + result = (function() { return _.take([1,2,3], 2); })(); + equal(result.join(','), '1,2', 'aliased as take'); + + equal(_.first(null), undefined, 'handles nulls'); + }); + + test("rest", function() { + var numbers = [1, 2, 3, 4]; + equal(_.rest(numbers).join(", "), "2, 3, 4", 'working rest()'); + equal(_.rest(numbers, 0).join(", "), "1, 2, 3, 4", 'working rest(0)'); + equal(_.rest(numbers, 2).join(', '), '3, 4', 'rest can take an index'); + var result = (function(){ return _(arguments).tail(); })(1, 2, 3, 4); + equal(result.join(', '), '2, 3, 4', 'aliased as tail and works on arguments object'); + result = _.map([[1,2,3],[1,2,3]], _.rest); + equal(_.flatten(result).join(','), '2,3,2,3', 'works well with _.map'); + result = (function(){ return _(arguments).drop(); })(1, 2, 3, 4); + equal(result.join(', '), '2, 3, 4', 'aliased as drop and works on arguments object'); + }); + + test("initial", function() { + equal(_.initial([1,2,3,4,5]).join(", "), "1, 2, 3, 4", 'working initial()'); + equal(_.initial([1,2,3,4],2).join(", "), "1, 2", 'initial can take an index'); + var result = (function(){ return _(arguments).initial(); })(1, 2, 3, 4); + equal(result.join(", "), "1, 2, 3", 'initial works on arguments object'); + result = _.map([[1,2,3],[1,2,3]], _.initial); + equal(_.flatten(result).join(','), '1,2,1,2', 'initial works with _.map'); + }); + + test("last", function() { + equal(_.last([1,2,3]), 3, 'can pull out the last element of an array'); + equal(_.last([1,2,3], 0).join(', '), "", 'can pass an index to last'); + equal(_.last([1,2,3], 2).join(', '), '2, 3', 'can pass an index to last'); + equal(_.last([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to last'); + var result = (function(){ return _(arguments).last(); })(1, 2, 3, 4); + equal(result, 4, 'works on an arguments object'); + result = _.map([[1,2,3],[1,2,3]], _.last); + equal(result.join(','), '3,3', 'works well with _.map'); + + equal(_.last(null), undefined, 'handles nulls'); + }); + + test("compact", function() { + equal(_.compact([0, 1, false, 2, false, 3]).length, 3, 'can trim out all falsy values'); + var result = (function(){ return _(arguments).compact().length; })(0, 1, false, 2, false, 3); + equal(result, 3, 'works on an arguments object'); + }); + + test("flatten", function() { + if (window.JSON) { + var list = [1, [2], [3, [[[4]]]]]; + equal(JSON.stringify(_.flatten(list)), '[1,2,3,4]', 'can flatten nested arrays'); + equal(JSON.stringify(_.flatten(list, true)), '[1,2,3,[[[4]]]]', 'can shallowly flatten nested arrays'); + var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]); + equal(JSON.stringify(result), '[1,2,3,4]', 'works on an arguments object'); + } + }); + + test("without", function() { + var list = [1, 2, 1, 0, 3, 1, 4]; + equal(_.without(list, 0, 1).join(', '), '2, 3, 4', 'can remove all instances of an object'); + var result = (function(){ return _.without(arguments, 0, 1); })(1, 2, 1, 0, 3, 1, 4); + equal(result.join(', '), '2, 3, 4', 'works on an arguments object'); + + var list = [{one : 1}, {two : 2}]; + ok(_.without(list, {one : 1}).length == 2, 'uses real object identity for comparisons.'); + ok(_.without(list, list[0]).length == 1, 'ditto.'); + }); + + test("uniq", function() { + var list = [1, 2, 1, 3, 1, 4]; + equal(_.uniq(list).join(', '), '1, 2, 3, 4', 'can find the unique values of an unsorted array'); + + var list = [1, 1, 1, 2, 2, 3]; + equal(_.uniq(list, true).join(', '), '1, 2, 3', 'can find the unique values of a sorted array faster'); + + var list = [{name:'moe'}, {name:'curly'}, {name:'larry'}, {name:'curly'}]; + var iterator = function(value) { return value.name; }; + equal(_.map(_.uniq(list, false, iterator), iterator).join(', '), 'moe, curly, larry', 'can find the unique values of an array using a custom iterator'); + + var iterator = function(value) { return value +1; }; + var list = [1, 2, 2, 3, 4, 4]; + equal(_.uniq(list, true, iterator).join(', '), '1, 2, 3, 4', 'iterator works with sorted array'); + + var result = (function(){ return _.uniq(arguments); })(1, 2, 1, 3, 1, 4); + equal(result.join(', '), '1, 2, 3, 4', 'works on an arguments object'); + }); + + test("intersection", function() { + var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho']; + equal(_.intersection(stooges, leaders).join(''), 'moe', 'can take the set intersection of two arrays'); + equal(_(stooges).intersection(leaders).join(''), 'moe', 'can perform an OO-style intersection'); + var result = (function(){ return _.intersection(arguments, leaders); })('moe', 'curly', 'larry'); + equal(result.join(''), 'moe', 'works on an arguments object'); + }); + + test("union", function() { + var result = _.union([1, 2, 3], [2, 30, 1], [1, 40]); + equal(result.join(' '), '1 2 3 30 40', 'takes the union of a list of arrays'); + + var result = _.union([1, 2, 3], [2, 30, 1], [1, 40, [1]]); + equal(result.join(' '), '1 2 3 30 40 1', 'takes the union of a list of nested arrays'); + }); + + test("difference", function() { + var result = _.difference([1, 2, 3], [2, 30, 40]); + equal(result.join(' '), '1 3', 'takes the difference of two arrays'); + + var result = _.difference([1, 2, 3, 4], [2, 30, 40], [1, 11, 111]); + equal(result.join(' '), '3 4', 'takes the difference of three arrays'); + }); + + test('zip', function() { + var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true]; + var stooges = _.zip(names, ages, leaders); + equal(String(stooges), 'moe,30,true,larry,40,,curly,50,', 'zipped together arrays of different lengths'); + }); + + test('object', function() { + var result = _.object(['moe', 'larry', 'curly'], [30, 40, 50]); + var shouldBe = {moe: 30, larry: 40, curly: 50}; + ok(_.isEqual(result, shouldBe), 'two arrays zipped together into an object'); + + result = _.object([['one', 1], ['two', 2], ['three', 3]]); + shouldBe = {one: 1, two: 2, three: 3}; + ok(_.isEqual(result, shouldBe), 'an array of pairs zipped together into an object'); + + var stooges = {moe: 30, larry: 40, curly: 50}; + ok(_.isEqual(_.object(_.pairs(stooges)), stooges), 'an object converted to pairs and back to an object'); + + ok(_.isEqual(_.object(null), {}), 'handles nulls'); + }); + + test("indexOf", function() { + var numbers = [1, 2, 3]; + numbers.indexOf = null; + equal(_.indexOf(numbers, 2), 1, 'can compute indexOf, even without the native function'); + var result = (function(){ return _.indexOf(arguments, 2); })(1, 2, 3); + equal(result, 1, 'works on an arguments object'); + equal(_.indexOf(null, 2), -1, 'handles nulls properly'); + + var numbers = [10, 20, 30, 40, 50], num = 35; + var index = _.indexOf(numbers, num, true); + equal(index, -1, '35 is not in the list'); + + numbers = [10, 20, 30, 40, 50]; num = 40; + index = _.indexOf(numbers, num, true); + equal(index, 3, '40 is in the list'); + + numbers = [1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70]; num = 40; + index = _.indexOf(numbers, num, true); + equal(index, 1, '40 is in the list'); + + numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3]; + index = _.indexOf(numbers, 2, 5); + equal(index, 7, 'supports the fromIndex argument'); + }); + + test("lastIndexOf", function() { + var numbers = [1, 0, 1]; + equal(_.lastIndexOf(numbers, 1), 2); + + numbers = [1, 0, 1, 0, 0, 1, 0, 0, 0]; + numbers.lastIndexOf = null; + equal(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function'); + equal(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element'); + var result = (function(){ return _.lastIndexOf(arguments, 1); })(1, 0, 1, 0, 0, 1, 0, 0, 0); + equal(result, 5, 'works on an arguments object'); + equal(_.indexOf(null, 2), -1, 'handles nulls properly'); + + numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3]; + index = _.lastIndexOf(numbers, 2, 2); + equal(index, 1, 'supports the fromIndex argument'); + }); + + test("range", function() { + equal(_.range(0).join(''), '', 'range with 0 as a first argument generates an empty array'); + equal(_.range(4).join(' '), '0 1 2 3', 'range with a single positive argument generates an array of elements 0,1,2,...,n-1'); + equal(_.range(5, 8).join(' '), '5 6 7', 'range with two arguments a & b, a<b generates an array of elements a,a+1,a+2,...,b-2,b-1'); + equal(_.range(8, 5).join(''), '', 'range with two arguments a & b, b<a generates an empty array'); + equal(_.range(3, 10, 3).join(' '), '3 6 9', 'range with three arguments a & b & c, c < b-a, a < b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) < c'); + equal(_.range(3, 10, 15).join(''), '3', 'range with three arguments a & b & c, c > b-a, a < b generates an array with a single element, equal to a'); + equal(_.range(12, 7, -2).join(' '), '12 10 8', 'range with three arguments a & b & c, a > b, c < 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b'); + equal(_.range(0, -10, -1).join(' '), '0 -1 -2 -3 -4 -5 -6 -7 -8 -9', 'final example in the Python docs'); + }); + +}); diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/chaining.js b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/chaining.js new file mode 100644 index 0000000..16cf7bf --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/chaining.js @@ -0,0 +1,59 @@ +$(document).ready(function() { + + module("Chaining"); + + test("map/flatten/reduce", function() { + var lyrics = [ + "I'm a lumberjack and I'm okay", + "I sleep all night and I work all day", + "He's a lumberjack and he's okay", + "He sleeps all night and he works all day" + ]; + var counts = _(lyrics).chain() + .map(function(line) { return line.split(''); }) + .flatten() + .reduce(function(hash, l) { + hash[l] = hash[l] || 0; + hash[l]++; + return hash; + }, {}).value(); + ok(counts['a'] == 16 && counts['e'] == 10, 'counted all the letters in the song'); + }); + + test("select/reject/sortBy", function() { + var numbers = [1,2,3,4,5,6,7,8,9,10]; + numbers = _(numbers).chain().select(function(n) { + return n % 2 == 0; + }).reject(function(n) { + return n % 4 == 0; + }).sortBy(function(n) { + return -n; + }).value(); + equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers"); + }); + + test("select/reject/sortBy in functional style", function() { + var numbers = [1,2,3,4,5,6,7,8,9,10]; + numbers = _.chain(numbers).select(function(n) { + return n % 2 == 0; + }).reject(function(n) { + return n % 4 == 0; + }).sortBy(function(n) { + return -n; + }).value(); + equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers"); + }); + + test("reverse/concat/unshift/pop/map", function() { + var numbers = [1,2,3,4,5]; + numbers = _(numbers).chain() + .reverse() + .concat([5, 5, 5]) + .unshift(17) + .pop() + .map(function(n){ return n * 2; }) + .value(); + equal(numbers.join(', '), "34, 10, 8, 6, 4, 2, 10, 10", 'can chain together array functions.'); + }); + +}); diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/collections.js b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/collections.js new file mode 100644 index 0000000..e089626 --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/collections.js @@ -0,0 +1,426 @@ +$(document).ready(function() { + + module("Collections"); + + test("each", function() { + _.each([1, 2, 3], function(num, i) { + equal(num, i + 1, 'each iterators provide value and iteration count'); + }); + + var answers = []; + _.each([1, 2, 3], function(num){ answers.push(num * this.multiplier);}, {multiplier : 5}); + equal(answers.join(', '), '5, 10, 15', 'context object property accessed'); + + answers = []; + _.forEach([1, 2, 3], function(num){ answers.push(num); }); + equal(answers.join(', '), '1, 2, 3', 'aliased as "forEach"'); + + answers = []; + var obj = {one : 1, two : 2, three : 3}; + obj.constructor.prototype.four = 4; + _.each(obj, function(value, key){ answers.push(key); }); + equal(answers.join(", "), 'one, two, three', 'iterating over objects works, and ignores the object prototype.'); + delete obj.constructor.prototype.four; + + answer = null; + _.each([1, 2, 3], function(num, index, arr){ if (_.include(arr, num)) answer = true; }); + ok(answer, 'can reference the original collection from inside the iterator'); + + answers = 0; + _.each(null, function(){ ++answers; }); + equal(answers, 0, 'handles a null properly'); + }); + + test('map', function() { + var doubled = _.map([1, 2, 3], function(num){ return num * 2; }); + equal(doubled.join(', '), '2, 4, 6', 'doubled numbers'); + + doubled = _.collect([1, 2, 3], function(num){ return num * 2; }); + equal(doubled.join(', '), '2, 4, 6', 'aliased as "collect"'); + + var tripled = _.map([1, 2, 3], function(num){ return num * this.multiplier; }, {multiplier : 3}); + equal(tripled.join(', '), '3, 6, 9', 'tripled numbers with context'); + + var doubled = _([1, 2, 3]).map(function(num){ return num * 2; }); + equal(doubled.join(', '), '2, 4, 6', 'OO-style doubled numbers'); + + if (document.querySelectorAll) { + var ids = _.map(document.querySelectorAll('#map-test *'), function(n){ return n.id; }); + deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on NodeLists.'); + } + + var ids = _.map($('#map-test').children(), function(n){ return n.id; }); + deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on jQuery Array-likes.'); + + var ids = _.map(document.images, function(n){ return n.id; }); + ok(ids[0] == 'chart_image', 'can use collection methods on HTMLCollections'); + + var ifnull = _.map(null, function(){}); + ok(_.isArray(ifnull) && ifnull.length === 0, 'handles a null properly'); + }); + + test('reduce', function() { + var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }, 0); + equal(sum, 6, 'can sum up an array'); + + var context = {multiplier : 3}; + sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num * this.multiplier; }, 0, context); + equal(sum, 18, 'can reduce with a context object'); + + sum = _.inject([1, 2, 3], function(sum, num){ return sum + num; }, 0); + equal(sum, 6, 'aliased as "inject"'); + + sum = _([1, 2, 3]).reduce(function(sum, num){ return sum + num; }, 0); + equal(sum, 6, 'OO-style reduce'); + + var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }); + equal(sum, 6, 'default initial value'); + + var ifnull; + try { + _.reduce(null, function(){}); + } catch (ex) { + ifnull = ex; + } + ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly'); + + ok(_.reduce(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); + equal(_.reduce([], function(){}, undefined), undefined, 'undefined can be passed as a special case'); + raises(function() { _.reduce([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value'); + }); + + test('reduceRight', function() { + var list = _.reduceRight(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); + equal(list, 'bazbarfoo', 'can perform right folds'); + + var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); + equal(list, 'bazbarfoo', 'aliased as "foldr"'); + + var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }); + equal(list, 'bazbarfoo', 'default initial value'); + + var ifnull; + try { + _.reduceRight(null, function(){}); + } catch (ex) { + ifnull = ex; + } + ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly'); + + var sum = _.reduceRight({a: 1, b: 2, c: 3}, function(sum, num){ return sum + num; }); + equal(sum, 6, 'default initial value on object'); + + ok(_.reduceRight(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); + + equal(_.reduceRight([], function(){}, undefined), undefined, 'undefined can be passed as a special case'); + raises(function() { _.reduceRight([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value'); + + // Assert that the correct arguments are being passed. + + var args, + memo = {}, + object = {a: 1, b: 2}, + lastKey = _.keys(object).pop(); + + var expected = lastKey == 'a' + ? [memo, 1, 'a', object] + : [memo, 2, 'b', object]; + + _.reduceRight(object, function() { + args || (args = _.toArray(arguments)); + }, memo); + + deepEqual(args, expected); + + // And again, with numeric keys. + + object = {'2': 'a', '1': 'b'}; + lastKey = _.keys(object).pop(); + args = null; + + expected = lastKey == '2' + ? [memo, 'a', '2', object] + : [memo, 'b', '1', object]; + + _.reduceRight(object, function() { + args || (args = _.toArray(arguments)); + }, memo); + + deepEqual(args, expected); + }); + + test('find', function() { + var array = [1, 2, 3, 4]; + strictEqual(_.find(array, function(n) { return n > 2; }), 3, 'should return first found `value`'); + strictEqual(_.find(array, function() { return false; }), void 0, 'should return `undefined` if `value` is not found'); + }); + + test('detect', function() { + var result = _.detect([1, 2, 3], function(num){ return num * 2 == 4; }); + equal(result, 2, 'found the first "2" and broke the loop'); + }); + + test('select', function() { + var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); + equal(evens.join(', '), '2, 4, 6', 'selected each even number'); + + evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); + equal(evens.join(', '), '2, 4, 6', 'aliased as "filter"'); + }); + + test('reject', function() { + var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); + equal(odds.join(', '), '1, 3, 5', 'rejected each even number'); + + var context = "obj"; + + var evens = _.reject([1, 2, 3, 4, 5, 6], function(num){ + equal(context, "obj"); + return num % 2 != 0; + }, context); + equal(evens.join(', '), '2, 4, 6', 'rejected each odd number'); + }); + + test('all', function() { + ok(_.all([], _.identity), 'the empty set'); + ok(_.all([true, true, true], _.identity), 'all true values'); + ok(!_.all([true, false, true], _.identity), 'one false value'); + ok(_.all([0, 10, 28], function(num){ return num % 2 == 0; }), 'even numbers'); + ok(!_.all([0, 11, 28], function(num){ return num % 2 == 0; }), 'an odd number'); + ok(_.all([1], _.identity) === true, 'cast to boolean - true'); + ok(_.all([0], _.identity) === false, 'cast to boolean - false'); + ok(_.every([true, true, true], _.identity), 'aliased as "every"'); + ok(!_.all([undefined, undefined, undefined], _.identity), 'works with arrays of undefined'); + }); + + test('any', function() { + var nativeSome = Array.prototype.some; + Array.prototype.some = null; + ok(!_.any([]), 'the empty set'); + ok(!_.any([false, false, false]), 'all false values'); + ok(_.any([false, false, true]), 'one true value'); + ok(_.any([null, 0, 'yes', false]), 'a string'); + ok(!_.any([null, 0, '', false]), 'falsy values'); + ok(!_.any([1, 11, 29], function(num){ return num % 2 == 0; }), 'all odd numbers'); + ok(_.any([1, 10, 29], function(num){ return num % 2 == 0; }), 'an even number'); + ok(_.any([1], _.identity) === true, 'cast to boolean - true'); + ok(_.any([0], _.identity) === false, 'cast to boolean - false'); + ok(_.some([false, false, true]), 'aliased as "some"'); + Array.prototype.some = nativeSome; + }); + + test('include', function() { + ok(_.include([1,2,3], 2), 'two is in the array'); + ok(!_.include([1,3,9], 2), 'two is not in the array'); + ok(_.contains({moe:1, larry:3, curly:9}, 3) === true, '_.include on objects checks their values'); + ok(_([1,2,3]).include(2), 'OO-style include'); + }); + + test('invoke', function() { + var list = [[5, 1, 7], [3, 2, 1]]; + var result = _.invoke(list, 'sort'); + equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); + equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); + }); + + test('invoke w/ function reference', function() { + var list = [[5, 1, 7], [3, 2, 1]]; + var result = _.invoke(list, Array.prototype.sort); + equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); + equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); + }); + + // Relevant when using ClojureScript + test('invoke when strings have a call method', function() { + String.prototype.call = function() { + return 42; + }; + var list = [[5, 1, 7], [3, 2, 1]]; + var s = "foo"; + equal(s.call(), 42, "call function exists"); + var result = _.invoke(list, 'sort'); + equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); + equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); + delete String.prototype.call; + equal(s.call, undefined, "call function removed"); + }); + + test('pluck', function() { + var people = [{name : 'moe', age : 30}, {name : 'curly', age : 50}]; + equal(_.pluck(people, 'name').join(', '), 'moe, curly', 'pulls names out of objects'); + }); + + test('where', function() { + var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}]; + var result = _.where(list, {a: 1}); + equal(result.length, 3); + equal(result[result.length - 1].b, 4); + result = _.where(list, {b: 2}); + equal(result.length, 2); + equal(result[0].a, 1); + }); + + test('max', function() { + equal(3, _.max([1, 2, 3]), 'can perform a regular Math.max'); + + var neg = _.max([1, 2, 3], function(num){ return -num; }); + equal(neg, 1, 'can perform a computation-based max'); + + equal(-Infinity, _.max({}), 'Maximum value of an empty object'); + equal(-Infinity, _.max([]), 'Maximum value of an empty array'); + + equal(299999, _.max(_.range(1,300000)), "Maximum value of a too-big array"); + }); + + test('min', function() { + equal(1, _.min([1, 2, 3]), 'can perform a regular Math.min'); + + var neg = _.min([1, 2, 3], function(num){ return -num; }); + equal(neg, 3, 'can perform a computation-based min'); + + equal(Infinity, _.min({}), 'Minimum value of an empty object'); + equal(Infinity, _.min([]), 'Minimum value of an empty array'); + + var now = new Date(9999999999); + var then = new Date(0); + equal(_.min([now, then]), then); + + equal(1, _.min(_.range(1,300000)), "Minimum value of a too-big array"); + }); + + test('sortBy', function() { + var people = [{name : 'curly', age : 50}, {name : 'moe', age : 30}]; + people = _.sortBy(people, function(person){ return person.age; }); + equal(_.pluck(people, 'name').join(', '), 'moe, curly', 'stooges sorted by age'); + + var list = [undefined, 4, 1, undefined, 3, 2]; + equal(_.sortBy(list, _.identity).join(','), '1,2,3,4,,', 'sortBy with undefined values'); + + var list = ["one", "two", "three", "four", "five"]; + var sorted = _.sortBy(list, 'length'); + equal(sorted.join(' '), 'one two four five three', 'sorted by length'); + + function Pair(x, y) { + this.x = x; + this.y = y; + } + + var collection = [ + new Pair(1, 1), new Pair(1, 2), + new Pair(1, 3), new Pair(1, 4), + new Pair(1, 5), new Pair(1, 6), + new Pair(2, 1), new Pair(2, 2), + new Pair(2, 3), new Pair(2, 4), + new Pair(2, 5), new Pair(2, 6), + new Pair(undefined, 1), new Pair(undefined, 2), + new Pair(undefined, 3), new Pair(undefined, 4), + new Pair(undefined, 5), new Pair(undefined, 6) + ]; + + var actual = _.sortBy(collection, function(pair) { + return pair.x; + }); + + deepEqual(actual, collection, 'sortBy should be stable'); + }); + + test('groupBy', function() { + var parity = _.groupBy([1, 2, 3, 4, 5, 6], function(num){ return num % 2; }); + ok('0' in parity && '1' in parity, 'created a group for each value'); + equal(parity[0].join(', '), '2, 4, 6', 'put each even number in the right group'); + + var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]; + var grouped = _.groupBy(list, 'length'); + equal(grouped['3'].join(' '), 'one two six ten'); + equal(grouped['4'].join(' '), 'four five nine'); + equal(grouped['5'].join(' '), 'three seven eight'); + + var context = {}; + _.groupBy([{}], function(){ ok(this === context); }, context); + + grouped = _.groupBy([4.2, 6.1, 6.4], function(num) { + return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor'; + }); + equal(grouped.constructor.length, 1); + equal(grouped.hasOwnProperty.length, 2); + + var array = [{}]; + _.groupBy(array, function(value, index, obj){ ok(obj === array); }); + }); + + test('countBy', function() { + var parity = _.countBy([1, 2, 3, 4, 5], function(num){ return num % 2 == 0; }); + equal(parity['true'], 2); + equal(parity['false'], 3); + + var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]; + var grouped = _.countBy(list, 'length'); + equal(grouped['3'], 4); + equal(grouped['4'], 3); + equal(grouped['5'], 3); + + var context = {}; + _.countBy([{}], function(){ ok(this === context); }, context); + + grouped = _.countBy([4.2, 6.1, 6.4], function(num) { + return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor'; + }); + equal(grouped.constructor, 1); + equal(grouped.hasOwnProperty, 2); + + var array = [{}]; + _.countBy(array, function(value, index, obj){ ok(obj === array); }); + }); + + test('sortedIndex', function() { + var numbers = [10, 20, 30, 40, 50], num = 35; + var indexForNum = _.sortedIndex(numbers, num); + equal(indexForNum, 3, '35 should be inserted at index 3'); + + var indexFor30 = _.sortedIndex(numbers, 30); + equal(indexFor30, 2, '30 should be inserted at index 2'); + + var objects = [{x: 10}, {x: 20}, {x: 30}, {x: 40}]; + var iterator = function(obj){ return obj.x; }; + strictEqual(_.sortedIndex(objects, {x: 25}, iterator), 2); + strictEqual(_.sortedIndex(objects, {x: 35}, 'x'), 3); + + var context = {1: 2, 2: 3, 3: 4}; + iterator = function(obj){ return this[obj]; }; + strictEqual(_.sortedIndex([1, 3], 2, iterator, context), 1); + }); + + test('shuffle', function() { + var numbers = _.range(10); + var shuffled = _.shuffle(numbers).sort(); + notStrictEqual(numbers, shuffled, 'original object is unmodified'); + equal(shuffled.join(','), numbers.join(','), 'contains the same members before and after shuffle'); + }); + + test('toArray', function() { + ok(!_.isArray(arguments), 'arguments object is not an array'); + ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array'); + var a = [1,2,3]; + ok(_.toArray(a) !== a, 'array is cloned'); + equal(_.toArray(a).join(', '), '1, 2, 3', 'cloned array contains same elements'); + + var numbers = _.toArray({one : 1, two : 2, three : 3}); + equal(numbers.join(', '), '1, 2, 3', 'object flattened into array'); + }); + + test('size', function() { + equal(_.size({one : 1, two : 2, three : 3}), 3, 'can compute the size of an object'); + equal(_.size([1, 2, 3]), 3, 'can compute the size of an array'); + + var func = function() { + return _.size(arguments); + }; + + equal(func(1, 2, 3, 4), 4, 'can test the size of the arguments object'); + + equal(_.size('hello'), 5, 'can compute the size of a string'); + + equal(_.size(null), 0, 'handles nulls'); + }); + +}); diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/functions.js b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/functions.js new file mode 100644 index 0000000..a529658 --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/functions.js @@ -0,0 +1,259 @@ +$(document).ready(function() { + + module("Functions"); + + test("bind", function() { + var context = {name : 'moe'}; + var func = function(arg) { return "name: " + (this.name || arg); }; + var bound = _.bind(func, context); + equal(bound(), 'name: moe', 'can bind a function to a context'); + + bound = _(func).bind(context); + equal(bound(), 'name: moe', 'can do OO-style binding'); + + bound = _.bind(func, null, 'curly'); + equal(bound(), 'name: curly', 'can bind without specifying a context'); + + func = function(salutation, name) { return salutation + ': ' + name; }; + func = _.bind(func, this, 'hello'); + equal(func('moe'), 'hello: moe', 'the function was partially applied in advance'); + + var func = _.bind(func, this, 'curly'); + equal(func(), 'hello: curly', 'the function was completely applied in advance'); + + var func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; }; + func = _.bind(func, this, 'hello', 'moe', 'curly'); + equal(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments'); + + func = function(context, message) { equal(this, context, message); }; + _.bind(func, 0, 0, 'can bind a function to `0`')(); + _.bind(func, '', '', 'can bind a function to an empty string')(); + _.bind(func, false, false, 'can bind a function to `false`')(); + + // These tests are only meaningful when using a browser without a native bind function + // To test this with a modern browser, set underscore's nativeBind to undefined + var F = function () { return this; }; + var Boundf = _.bind(F, {hello: "moe curly"}); + equal(new Boundf().hello, undefined, "function should not be bound to the context, to comply with ECMAScript 5"); + equal(Boundf().hello, "moe curly", "When called without the new operator, it's OK to be bound to the context"); + }); + + test("bindAll", function() { + var curly = {name : 'curly'}, moe = { + name : 'moe', + getName : function() { return 'name: ' + this.name; }, + sayHi : function() { return 'hi: ' + this.name; } + }; + curly.getName = moe.getName; + _.bindAll(moe, 'getName', 'sayHi'); + curly.sayHi = moe.sayHi; + equal(curly.getName(), 'name: curly', 'unbound function is bound to current object'); + equal(curly.sayHi(), 'hi: moe', 'bound function is still bound to original object'); + + curly = {name : 'curly'}; + moe = { + name : 'moe', + getName : function() { return 'name: ' + this.name; }, + sayHi : function() { return 'hi: ' + this.name; } + }; + _.bindAll(moe); + curly.sayHi = moe.sayHi; + equal(curly.sayHi(), 'hi: moe', 'calling bindAll with no arguments binds all functions to the object'); + }); + + test("memoize", function() { + var fib = function(n) { + return n < 2 ? n : fib(n - 1) + fib(n - 2); + }; + var fastFib = _.memoize(fib); + equal(fib(10), 55, 'a memoized version of fibonacci produces identical results'); + equal(fastFib(10), 55, 'a memoized version of fibonacci produces identical results'); + + var o = function(str) { + return str; + }; + var fastO = _.memoize(o); + equal(o('toString'), 'toString', 'checks hasOwnProperty'); + equal(fastO('toString'), 'toString', 'checks hasOwnProperty'); + }); + + asyncTest("delay", 2, function() { + var delayed = false; + _.delay(function(){ delayed = true; }, 100); + setTimeout(function(){ ok(!delayed, "didn't delay the function quite yet"); }, 50); + setTimeout(function(){ ok(delayed, 'delayed the function'); start(); }, 150); + }); + + asyncTest("defer", 1, function() { + var deferred = false; + _.defer(function(bool){ deferred = bool; }, true); + _.delay(function(){ ok(deferred, "deferred the function"); start(); }, 50); + }); + + asyncTest("throttle", 2, function() { + var counter = 0; + var incr = function(){ counter++; }; + var throttledIncr = _.throttle(incr, 100); + throttledIncr(); throttledIncr(); throttledIncr(); + setTimeout(throttledIncr, 70); + setTimeout(throttledIncr, 120); + setTimeout(throttledIncr, 140); + setTimeout(throttledIncr, 190); + setTimeout(throttledIncr, 220); + setTimeout(throttledIncr, 240); + _.delay(function(){ equal(counter, 1, "incr was called immediately"); }, 30); + _.delay(function(){ equal(counter, 4, "incr was throttled"); start(); }, 400); + }); + + asyncTest("throttle arguments", 2, function() { + var value = 0; + var update = function(val){ value = val; }; + var throttledUpdate = _.throttle(update, 100); + throttledUpdate(1); throttledUpdate(2); throttledUpdate(3); + setTimeout(function(){ throttledUpdate(4); }, 120); + setTimeout(function(){ throttledUpdate(5); }, 140); + setTimeout(function(){ throttledUpdate(6); }, 250); + _.delay(function(){ equal(value, 1, "updated to latest value"); }, 40); + _.delay(function(){ equal(value, 6, "updated to latest value"); start(); }, 400); + }); + + asyncTest("throttle once", 2, function() { + var counter = 0; + var incr = function(){ return ++counter; }; + var throttledIncr = _.throttle(incr, 100); + var result = throttledIncr(); + _.delay(function(){ + equal(result, 1, "throttled functions return their value"); + equal(counter, 1, "incr was called once"); start(); + }, 220); + }); + + asyncTest("throttle twice", 1, function() { + var counter = 0; + var incr = function(){ counter++; }; + var throttledIncr = _.throttle(incr, 100); + throttledIncr(); throttledIncr(); + _.delay(function(){ equal(counter, 2, "incr was called twice"); start(); }, 220); + }); + + asyncTest("throttle repeatedly with results", 9, function() { + var counter = 0; + var incr = function(){ return ++counter; }; + var throttledIncr = _.throttle(incr, 100); + var results = []; + var saveResult = function() { results.push(throttledIncr()); }; + saveResult(); saveResult(); saveResult(); + setTimeout(saveResult, 70); + setTimeout(saveResult, 120); + setTimeout(saveResult, 140); + setTimeout(saveResult, 190); + setTimeout(saveResult, 240); + setTimeout(saveResult, 260); + _.delay(function() { + equal(results[0], 1, "incr was called once"); + equal(results[1], 1, "incr was throttled"); + equal(results[2], 1, "incr was throttled"); + equal(results[3], 1, "incr was throttled"); + equal(results[4], 2, "incr was called twice"); + equal(results[5], 2, "incr was throttled"); + equal(results[6], 2, "incr was throttled"); + equal(results[7], 3, "incr was called thrice"); + equal(results[8], 3, "incr was throttled"); + start(); + }, 400); + }); + + asyncTest("debounce", 1, function() { + var counter = 0; + var incr = function(){ counter++; }; + var debouncedIncr = _.debounce(incr, 50); + debouncedIncr(); debouncedIncr(); debouncedIncr(); + setTimeout(debouncedIncr, 30); + setTimeout(debouncedIncr, 60); + setTimeout(debouncedIncr, 90); + setTimeout(debouncedIncr, 120); + setTimeout(debouncedIncr, 150); + _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220); + }); + + asyncTest("debounce asap", 5, function() { + var a, b, c; + var counter = 0; + var incr = function(){ return ++counter; }; + var debouncedIncr = _.debounce(incr, 50, true); + a = debouncedIncr(); + b = debouncedIncr(); + c = debouncedIncr(); + equal(a, 1); + equal(b, 1); + equal(c, 1); + equal(counter, 1, 'incr was called immediately'); + setTimeout(debouncedIncr, 30); + setTimeout(debouncedIncr, 60); + setTimeout(debouncedIncr, 90); + setTimeout(debouncedIncr, 120); + setTimeout(debouncedIncr, 150); + _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220); + }); + + asyncTest("debounce asap recursively", 2, function() { + var counter = 0; + var debouncedIncr = _.debounce(function(){ + counter++; + if (counter < 5) debouncedIncr(); + }, 50, true); + debouncedIncr(); + equal(counter, 1, 'incr was called immediately'); + _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 70); + }); + + test("once", function() { + var num = 0; + var increment = _.once(function(){ num++; }); + increment(); + increment(); + equal(num, 1); + }); + + test("wrap", function() { + var greet = function(name){ return "hi: " + name; }; + var backwards = _.wrap(greet, function(func, name){ return func(name) + ' ' + name.split('').reverse().join(''); }); + equal(backwards('moe'), 'hi: moe eom', 'wrapped the saluation function'); + + var inner = function(){ return "Hello "; }; + var obj = {name : "Moe"}; + obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; }); + equal(obj.hi(), "Hello Moe"); + + var noop = function(){}; + var wrapped = _.wrap(noop, function(fn){ return Array.prototype.slice.call(arguments, 0); }); + var ret = wrapped(['whats', 'your'], 'vector', 'victor'); + deepEqual(ret, [noop, ['whats', 'your'], 'vector', 'victor']); + }); + + test("compose", function() { + var greet = function(name){ return "hi: " + name; }; + var exclaim = function(sentence){ return sentence + '!'; }; + var composed = _.compose(exclaim, greet); + equal(composed('moe'), 'hi: moe!', 'can compose a function that takes another'); + + composed = _.compose(greet, exclaim); + equal(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative'); + }); + + test("after", function() { + var testAfter = function(afterAmount, timesCalled) { + var afterCalled = 0; + var after = _.after(afterAmount, function() { + afterCalled++; + }); + while (timesCalled--) after(); + return afterCalled; + }; + + equal(testAfter(5, 5), 1, "after(N) should fire after being called N times"); + equal(testAfter(5, 4), 0, "after(N) should not fire unless called N times"); + equal(testAfter(0, 0), 1, "after(0) should fire immediately"); + }); + +}); diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/index.html b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/index.html new file mode 100644 index 0000000..064fa98 --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/index.html @@ -0,0 +1,45 @@ + + + + Underscore Test Suite + + + + + + + + + + + + + + + + +
          +
          +
          +
          +
          +
          +
          +
          +

          Underscore Speed Suite

          +

          + A representative sample of the functions are benchmarked here, to provide + a sense of how fast they might run in different browsers. + Each iteration runs on an array of 1000 elements.

          + For example, the 'intersection' test measures the number of times you can + find the intersection of two thousand-element arrays in one second. +

          +
          + + + diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/objects.js b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/objects.js new file mode 100644 index 0000000..22949c3 --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/objects.js @@ -0,0 +1,548 @@ +$(document).ready(function() { + + module("Objects"); + + test("keys", function() { + equal(_.keys({one : 1, two : 2}).join(', '), 'one, two', 'can extract the keys from an object'); + // the test above is not safe because it relies on for-in enumeration order + var a = []; a[1] = 0; + equal(_.keys(a).join(', '), '1', 'is not fooled by sparse arrays; see issue #95'); + raises(function() { _.keys(null); }, TypeError, 'throws an error for `null` values'); + raises(function() { _.keys(void 0); }, TypeError, 'throws an error for `undefined` values'); + raises(function() { _.keys(1); }, TypeError, 'throws an error for number primitives'); + raises(function() { _.keys('a'); }, TypeError, 'throws an error for string primitives'); + raises(function() { _.keys(true); }, TypeError, 'throws an error for boolean primitives'); + }); + + test("values", function() { + equal(_.values({one: 1, two: 2}).join(', '), '1, 2', 'can extract the values from an object'); + equal(_.values({one: 1, two: 2, length: 3}).join(', '), '1, 2, 3', '... even when one of them is "length"'); + }); + + test("pairs", function() { + deepEqual(_.pairs({one: 1, two: 2}), [['one', 1], ['two', 2]], 'can convert an object into pairs'); + deepEqual(_.pairs({one: 1, two: 2, length: 3}), [['one', 1], ['two', 2], ['length', 3]], '... even when one of them is "length"'); + }); + + test("invert", function() { + var obj = {first: 'Moe', second: 'Larry', third: 'Curly'}; + equal(_.keys(_.invert(obj)).join(' '), 'Moe Larry Curly', 'can invert an object'); + ok(_.isEqual(_.invert(_.invert(obj)), obj), 'two inverts gets you back where you started'); + + var obj = {length: 3}; + ok(_.invert(obj)['3'] == 'length', 'can invert an object with "length"') + }); + + test("functions", function() { + var obj = {a : 'dash', b : _.map, c : (/yo/), d : _.reduce}; + ok(_.isEqual(['b', 'd'], _.functions(obj)), 'can grab the function names of any passed-in object'); + + var Animal = function(){}; + Animal.prototype.run = function(){}; + equal(_.functions(new Animal).join(''), 'run', 'also looks up functions on the prototype'); + }); + + test("extend", function() { + var result; + equal(_.extend({}, {a:'b'}).a, 'b', 'can extend an object with the attributes of another'); + equal(_.extend({a:'x'}, {a:'b'}).a, 'b', 'properties in source override destination'); + equal(_.extend({x:'x'}, {a:'b'}).x, 'x', 'properties not in source dont get overriden'); + result = _.extend({x:'x'}, {a:'a'}, {b:'b'}); + ok(_.isEqual(result, {x:'x', a:'a', b:'b'}), 'can extend from multiple source objects'); + result = _.extend({x:'x'}, {a:'a', x:2}, {a:'b'}); + ok(_.isEqual(result, {x:2, a:'b'}), 'extending from multiple source objects last property trumps'); + result = _.extend({}, {a: void 0, b: null}); + equal(_.keys(result).join(''), 'ab', 'extend does not copy undefined values'); + }); + + test("pick", function() { + var result; + result = _.pick({a:1, b:2, c:3}, 'a', 'c'); + ok(_.isEqual(result, {a:1, c:3}), 'can restrict properties to those named'); + result = _.pick({a:1, b:2, c:3}, ['b', 'c']); + ok(_.isEqual(result, {b:2, c:3}), 'can restrict properties to those named in an array'); + result = _.pick({a:1, b:2, c:3}, ['a'], 'b'); + ok(_.isEqual(result, {a:1, b:2}), 'can restrict properties to those named in mixed args'); + + var Obj = function(){}; + Obj.prototype = {a: 1, b: 2, c: 3}; + ok(_.isEqual(_.pick(new Obj, 'a', 'c'), {a:1, c: 3}), 'include prototype props'); + }); + + test("omit", function() { + var result; + result = _.omit({a:1, b:2, c:3}, 'b'); + ok(_.isEqual(result, {a:1, c:3}), 'can omit a single named property'); + result = _.omit({a:1, b:2, c:3}, 'a', 'c'); + ok(_.isEqual(result, {b:2}), 'can omit several named properties'); + result = _.omit({a:1, b:2, c:3}, ['b', 'c']); + ok(_.isEqual(result, {a:1}), 'can omit properties named in an array'); + + var Obj = function(){}; + Obj.prototype = {a: 1, b: 2, c: 3}; + ok(_.isEqual(_.omit(new Obj, 'b'), {a:1, c: 3}), 'include prototype props'); + }); + + test("defaults", function() { + var result; + var options = {zero: 0, one: 1, empty: "", nan: NaN, string: "string"}; + + _.defaults(options, {zero: 1, one: 10, twenty: 20}); + equal(options.zero, 0, 'value exists'); + equal(options.one, 1, 'value exists'); + equal(options.twenty, 20, 'default applied'); + + _.defaults(options, {empty: "full"}, {nan: "nan"}, {word: "word"}, {word: "dog"}); + equal(options.empty, "", 'value exists'); + ok(_.isNaN(options.nan), "NaN isn't overridden"); + equal(options.word, "word", 'new value is added, first one wins'); + }); + + test("clone", function() { + var moe = {name : 'moe', lucky : [13, 27, 34]}; + var clone = _.clone(moe); + equal(clone.name, 'moe', 'the clone as the attributes of the original'); + + clone.name = 'curly'; + ok(clone.name == 'curly' && moe.name == 'moe', 'clones can change shallow attributes without affecting the original'); + + clone.lucky.push(101); + equal(_.last(moe.lucky), 101, 'changes to deep attributes are shared with the original'); + + equal(_.clone(undefined), void 0, 'non objects should not be changed by clone'); + equal(_.clone(1), 1, 'non objects should not be changed by clone'); + equal(_.clone(null), null, 'non objects should not be changed by clone'); + }); + + test("isEqual", function() { + function First() { + this.value = 1; + } + First.prototype.value = 1; + function Second() { + this.value = 1; + } + Second.prototype.value = 2; + + // Basic equality and identity comparisons. + ok(_.isEqual(null, null), "`null` is equal to `null`"); + ok(_.isEqual(), "`undefined` is equal to `undefined`"); + + ok(!_.isEqual(0, -0), "`0` is not equal to `-0`"); + ok(!_.isEqual(-0, 0), "Commutative equality is implemented for `0` and `-0`"); + ok(!_.isEqual(null, undefined), "`null` is not equal to `undefined`"); + ok(!_.isEqual(undefined, null), "Commutative equality is implemented for `null` and `undefined`"); + + // String object and primitive comparisons. + ok(_.isEqual("Curly", "Curly"), "Identical string primitives are equal"); + ok(_.isEqual(new String("Curly"), new String("Curly")), "String objects with identical primitive values are equal"); + ok(_.isEqual(new String("Curly"), "Curly"), "String primitives and their corresponding object wrappers are equal"); + ok(_.isEqual("Curly", new String("Curly")), "Commutative equality is implemented for string objects and primitives"); + + ok(!_.isEqual("Curly", "Larry"), "String primitives with different values are not equal"); + ok(!_.isEqual(new String("Curly"), new String("Larry")), "String objects with different primitive values are not equal"); + ok(!_.isEqual(new String("Curly"), {toString: function(){ return "Curly"; }}), "String objects and objects with a custom `toString` method are not equal"); + + // Number object and primitive comparisons. + ok(_.isEqual(75, 75), "Identical number primitives are equal"); + ok(_.isEqual(new Number(75), new Number(75)), "Number objects with identical primitive values are equal"); + ok(_.isEqual(75, new Number(75)), "Number primitives and their corresponding object wrappers are equal"); + ok(_.isEqual(new Number(75), 75), "Commutative equality is implemented for number objects and primitives"); + ok(!_.isEqual(new Number(0), -0), "`new Number(0)` and `-0` are not equal"); + ok(!_.isEqual(0, new Number(-0)), "Commutative equality is implemented for `new Number(0)` and `-0`"); + + ok(!_.isEqual(new Number(75), new Number(63)), "Number objects with different primitive values are not equal"); + ok(!_.isEqual(new Number(63), {valueOf: function(){ return 63; }}), "Number objects and objects with a `valueOf` method are not equal"); + + // Comparisons involving `NaN`. + ok(_.isEqual(NaN, NaN), "`NaN` is equal to `NaN`"); + ok(!_.isEqual(61, NaN), "A number primitive is not equal to `NaN`"); + ok(!_.isEqual(new Number(79), NaN), "A number object is not equal to `NaN`"); + ok(!_.isEqual(Infinity, NaN), "`Infinity` is not equal to `NaN`"); + + // Boolean object and primitive comparisons. + ok(_.isEqual(true, true), "Identical boolean primitives are equal"); + ok(_.isEqual(new Boolean, new Boolean), "Boolean objects with identical primitive values are equal"); + ok(_.isEqual(true, new Boolean(true)), "Boolean primitives and their corresponding object wrappers are equal"); + ok(_.isEqual(new Boolean(true), true), "Commutative equality is implemented for booleans"); + ok(!_.isEqual(new Boolean(true), new Boolean), "Boolean objects with different primitive values are not equal"); + + // Common type coercions. + ok(!_.isEqual(true, new Boolean(false)), "Boolean objects are not equal to the boolean primitive `true`"); + ok(!_.isEqual("75", 75), "String and number primitives with like values are not equal"); + ok(!_.isEqual(new Number(63), new String(63)), "String and number objects with like values are not equal"); + ok(!_.isEqual(75, "75"), "Commutative equality is implemented for like string and number values"); + ok(!_.isEqual(0, ""), "Number and string primitives with like values are not equal"); + ok(!_.isEqual(1, true), "Number and boolean primitives with like values are not equal"); + ok(!_.isEqual(new Boolean(false), new Number(0)), "Boolean and number objects with like values are not equal"); + ok(!_.isEqual(false, new String("")), "Boolean primitives and string objects with like values are not equal"); + ok(!_.isEqual(12564504e5, new Date(2009, 9, 25)), "Dates and their corresponding numeric primitive values are not equal"); + + // Dates. + ok(_.isEqual(new Date(2009, 9, 25), new Date(2009, 9, 25)), "Date objects referencing identical times are equal"); + ok(!_.isEqual(new Date(2009, 9, 25), new Date(2009, 11, 13)), "Date objects referencing different times are not equal"); + ok(!_.isEqual(new Date(2009, 11, 13), { + getTime: function(){ + return 12606876e5; + } + }), "Date objects and objects with a `getTime` method are not equal"); + ok(!_.isEqual(new Date("Curly"), new Date("Curly")), "Invalid dates are not equal"); + + // Functions. + ok(!_.isEqual(First, Second), "Different functions with identical bodies and source code representations are not equal"); + + // RegExps. + ok(_.isEqual(/(?:)/gim, /(?:)/gim), "RegExps with equivalent patterns and flags are equal"); + ok(!_.isEqual(/(?:)/g, /(?:)/gi), "RegExps with equivalent patterns and different flags are not equal"); + ok(!_.isEqual(/Moe/gim, /Curly/gim), "RegExps with different patterns and equivalent flags are not equal"); + ok(!_.isEqual(/(?:)/gi, /(?:)/g), "Commutative equality is implemented for RegExps"); + ok(!_.isEqual(/Curly/g, {source: "Larry", global: true, ignoreCase: false, multiline: false}), "RegExps and RegExp-like objects are not equal"); + + // Empty arrays, array-like objects, and object literals. + ok(_.isEqual({}, {}), "Empty object literals are equal"); + ok(_.isEqual([], []), "Empty array literals are equal"); + ok(_.isEqual([{}], [{}]), "Empty nested arrays and objects are equal"); + ok(!_.isEqual({length: 0}, []), "Array-like objects and arrays are not equal."); + ok(!_.isEqual([], {length: 0}), "Commutative equality is implemented for array-like objects"); + + ok(!_.isEqual({}, []), "Object literals and array literals are not equal"); + ok(!_.isEqual([], {}), "Commutative equality is implemented for objects and arrays"); + + // Arrays with primitive and object values. + ok(_.isEqual([1, "Larry", true], [1, "Larry", true]), "Arrays containing identical primitives are equal"); + ok(_.isEqual([(/Moe/g), new Date(2009, 9, 25)], [(/Moe/g), new Date(2009, 9, 25)]), "Arrays containing equivalent elements are equal"); + + // Multi-dimensional arrays. + var a = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; + var b = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; + ok(_.isEqual(a, b), "Arrays containing nested arrays and objects are recursively compared"); + + // Overwrite the methods defined in ES 5.1 section 15.4.4. + a.forEach = a.map = a.filter = a.every = a.indexOf = a.lastIndexOf = a.some = a.reduce = a.reduceRight = null; + b.join = b.pop = b.reverse = b.shift = b.slice = b.splice = b.concat = b.sort = b.unshift = null; + + // Array elements and properties. + ok(_.isEqual(a, b), "Arrays containing equivalent elements and different non-numeric properties are equal"); + a.push("White Rocks"); + ok(!_.isEqual(a, b), "Arrays of different lengths are not equal"); + a.push("East Boulder"); + b.push("Gunbarrel Ranch", "Teller Farm"); + ok(!_.isEqual(a, b), "Arrays of identical lengths containing different elements are not equal"); + + // Sparse arrays. + ok(_.isEqual(Array(3), Array(3)), "Sparse arrays of identical lengths are equal"); + ok(!_.isEqual(Array(3), Array(6)), "Sparse arrays of different lengths are not equal when both are empty"); + + // Simple objects. + ok(_.isEqual({a: "Curly", b: 1, c: true}, {a: "Curly", b: 1, c: true}), "Objects containing identical primitives are equal"); + ok(_.isEqual({a: /Curly/g, b: new Date(2009, 11, 13)}, {a: /Curly/g, b: new Date(2009, 11, 13)}), "Objects containing equivalent members are equal"); + ok(!_.isEqual({a: 63, b: 75}, {a: 61, b: 55}), "Objects of identical sizes with different values are not equal"); + ok(!_.isEqual({a: 63, b: 75}, {a: 61, c: 55}), "Objects of identical sizes with different property names are not equal"); + ok(!_.isEqual({a: 1, b: 2}, {a: 1}), "Objects of different sizes are not equal"); + ok(!_.isEqual({a: 1}, {a: 1, b: 2}), "Commutative equality is implemented for objects"); + ok(!_.isEqual({x: 1, y: undefined}, {x: 1, z: 2}), "Objects with identical keys and different values are not equivalent"); + + // `A` contains nested objects and arrays. + a = { + name: new String("Moe Howard"), + age: new Number(77), + stooge: true, + hobbies: ["acting"], + film: { + name: "Sing a Song of Six Pants", + release: new Date(1947, 9, 30), + stars: [new String("Larry Fine"), "Shemp Howard"], + minutes: new Number(16), + seconds: 54 + } + }; + + // `B` contains equivalent nested objects and arrays. + b = { + name: new String("Moe Howard"), + age: new Number(77), + stooge: true, + hobbies: ["acting"], + film: { + name: "Sing a Song of Six Pants", + release: new Date(1947, 9, 30), + stars: [new String("Larry Fine"), "Shemp Howard"], + minutes: new Number(16), + seconds: 54 + } + }; + ok(_.isEqual(a, b), "Objects with nested equivalent members are recursively compared"); + + // Instances. + ok(_.isEqual(new First, new First), "Object instances are equal"); + ok(!_.isEqual(new First, new Second), "Objects with different constructors and identical own properties are not equal"); + ok(!_.isEqual({value: 1}, new First), "Object instances and objects sharing equivalent properties are not equal"); + ok(!_.isEqual({value: 2}, new Second), "The prototype chain of objects should not be examined"); + + // Circular Arrays. + (a = []).push(a); + (b = []).push(b); + ok(_.isEqual(a, b), "Arrays containing circular references are equal"); + a.push(new String("Larry")); + b.push(new String("Larry")); + ok(_.isEqual(a, b), "Arrays containing circular references and equivalent properties are equal"); + a.push("Shemp"); + b.push("Curly"); + ok(!_.isEqual(a, b), "Arrays containing circular references and different properties are not equal"); + + // More circular arrays #767. + a = ["everything is checked but", "this", "is not"]; + a[1] = a; + b = ["everything is checked but", ["this", "array"], "is not"]; + ok(!_.isEqual(a, b), "Comparison of circular references with non-circular references are not equal"); + + // Circular Objects. + a = {abc: null}; + b = {abc: null}; + a.abc = a; + b.abc = b; + ok(_.isEqual(a, b), "Objects containing circular references are equal"); + a.def = 75; + b.def = 75; + ok(_.isEqual(a, b), "Objects containing circular references and equivalent properties are equal"); + a.def = new Number(75); + b.def = new Number(63); + ok(!_.isEqual(a, b), "Objects containing circular references and different properties are not equal"); + + // More circular objects #767. + a = {everything: "is checked", but: "this", is: "not"}; + a.but = a; + b = {everything: "is checked", but: {that:"object"}, is: "not"}; + ok(!_.isEqual(a, b), "Comparison of circular references with non-circular object references are not equal"); + + // Cyclic Structures. + a = [{abc: null}]; + b = [{abc: null}]; + (a[0].abc = a).push(a); + (b[0].abc = b).push(b); + ok(_.isEqual(a, b), "Cyclic structures are equal"); + a[0].def = "Larry"; + b[0].def = "Larry"; + ok(_.isEqual(a, b), "Cyclic structures containing equivalent properties are equal"); + a[0].def = new String("Larry"); + b[0].def = new String("Curly"); + ok(!_.isEqual(a, b), "Cyclic structures containing different properties are not equal"); + + // Complex Circular References. + a = {foo: {b: {foo: {c: {foo: null}}}}}; + b = {foo: {b: {foo: {c: {foo: null}}}}}; + a.foo.b.foo.c.foo = a; + b.foo.b.foo.c.foo = b; + ok(_.isEqual(a, b), "Cyclic structures with nested and identically-named properties are equal"); + + // Chaining. + ok(!_.isEqual(_({x: 1, y: undefined}).chain(), _({x: 1, z: 2}).chain()), 'Chained objects containing different values are not equal'); + equal(_({x: 1, y: 2}).chain().isEqual(_({x: 1, y: 2}).chain()).value(), true, '`isEqual` can be chained'); + + // Custom `isEqual` methods. + var isEqualObj = {isEqual: function (o) { return o.isEqual == this.isEqual; }, unique: {}}; + var isEqualObjClone = {isEqual: isEqualObj.isEqual, unique: {}}; + + ok(_.isEqual(isEqualObj, isEqualObjClone), 'Both objects implement identical `isEqual` methods'); + ok(_.isEqual(isEqualObjClone, isEqualObj), 'Commutative equality is implemented for objects with custom `isEqual` methods'); + ok(!_.isEqual(isEqualObj, {}), 'Objects that do not implement equivalent `isEqual` methods are not equal'); + ok(!_.isEqual({}, isEqualObj), 'Commutative equality is implemented for objects with different `isEqual` methods'); + + // Objects from another frame. + ok(_.isEqual({}, iObject)); + }); + + test("isEmpty", function() { + ok(!_([1]).isEmpty(), '[1] is not empty'); + ok(_.isEmpty([]), '[] is empty'); + ok(!_.isEmpty({one : 1}), '{one : 1} is not empty'); + ok(_.isEmpty({}), '{} is empty'); + ok(_.isEmpty(new RegExp('')), 'objects with prototype properties are empty'); + ok(_.isEmpty(null), 'null is empty'); + ok(_.isEmpty(), 'undefined is empty'); + ok(_.isEmpty(''), 'the empty string is empty'); + ok(!_.isEmpty('moe'), 'but other strings are not'); + + var obj = {one : 1}; + delete obj.one; + ok(_.isEmpty(obj), 'deleting all the keys from an object empties it'); + }); + + // Setup remote variables for iFrame tests. + var iframe = document.createElement('iframe'); + jQuery(iframe).appendTo(document.body); + var iDoc = iframe.contentDocument || iframe.contentWindow.document; + iDoc.write( + "" + ); + iDoc.close(); + + test("isElement", function() { + ok(!_.isElement('div'), 'strings are not dom elements'); + ok(_.isElement($('html')[0]), 'the html tag is a DOM element'); + ok(_.isElement(iElement), 'even from another frame'); + }); + + test("isArguments", function() { + var args = (function(){ return arguments; })(1, 2, 3); + ok(!_.isArguments('string'), 'a string is not an arguments object'); + ok(!_.isArguments(_.isArguments), 'a function is not an arguments object'); + ok(_.isArguments(args), 'but the arguments object is an arguments object'); + ok(!_.isArguments(_.toArray(args)), 'but not when it\'s converted into an array'); + ok(!_.isArguments([1,2,3]), 'and not vanilla arrays.'); + ok(_.isArguments(iArguments), 'even from another frame'); + }); + + test("isObject", function() { + ok(_.isObject(arguments), 'the arguments object is object'); + ok(_.isObject([1, 2, 3]), 'and arrays'); + ok(_.isObject($('html')[0]), 'and DOM element'); + ok(_.isObject(iElement), 'even from another frame'); + ok(_.isObject(function () {}), 'and functions'); + ok(_.isObject(iFunction), 'even from another frame'); + ok(!_.isObject(null), 'but not null'); + ok(!_.isObject(undefined), 'and not undefined'); + ok(!_.isObject('string'), 'and not string'); + ok(!_.isObject(12), 'and not number'); + ok(!_.isObject(true), 'and not boolean'); + ok(_.isObject(new String('string')), 'but new String()'); + }); + + test("isArray", function() { + ok(!_.isArray(arguments), 'the arguments object is not an array'); + ok(_.isArray([1, 2, 3]), 'but arrays are'); + ok(_.isArray(iArray), 'even from another frame'); + }); + + test("isString", function() { + ok(!_.isString(document.body), 'the document body is not a string'); + ok(_.isString([1, 2, 3].join(', ')), 'but strings are'); + ok(_.isString(iString), 'even from another frame'); + }); + + test("isNumber", function() { + ok(!_.isNumber('string'), 'a string is not a number'); + ok(!_.isNumber(arguments), 'the arguments object is not a number'); + ok(!_.isNumber(undefined), 'undefined is not a number'); + ok(_.isNumber(3 * 4 - 7 / 10), 'but numbers are'); + ok(_.isNumber(NaN), 'NaN *is* a number'); + ok(_.isNumber(Infinity), 'Infinity is a number'); + ok(_.isNumber(iNumber), 'even from another frame'); + ok(!_.isNumber('1'), 'numeric strings are not numbers'); + }); + + test("isBoolean", function() { + ok(!_.isBoolean(2), 'a number is not a boolean'); + ok(!_.isBoolean("string"), 'a string is not a boolean'); + ok(!_.isBoolean("false"), 'the string "false" is not a boolean'); + ok(!_.isBoolean("true"), 'the string "true" is not a boolean'); + ok(!_.isBoolean(arguments), 'the arguments object is not a boolean'); + ok(!_.isBoolean(undefined), 'undefined is not a boolean'); + ok(!_.isBoolean(NaN), 'NaN is not a boolean'); + ok(!_.isBoolean(null), 'null is not a boolean'); + ok(_.isBoolean(true), 'but true is'); + ok(_.isBoolean(false), 'and so is false'); + ok(_.isBoolean(iBoolean), 'even from another frame'); + }); + + test("isFunction", function() { + ok(!_.isFunction([1, 2, 3]), 'arrays are not functions'); + ok(!_.isFunction('moe'), 'strings are not functions'); + ok(_.isFunction(_.isFunction), 'but functions are'); + ok(_.isFunction(iFunction), 'even from another frame'); + }); + + test("isDate", function() { + ok(!_.isDate(100), 'numbers are not dates'); + ok(!_.isDate({}), 'objects are not dates'); + ok(_.isDate(new Date()), 'but dates are'); + ok(_.isDate(iDate), 'even from another frame'); + }); + + test("isRegExp", function() { + ok(!_.isRegExp(_.identity), 'functions are not RegExps'); + ok(_.isRegExp(/identity/), 'but RegExps are'); + ok(_.isRegExp(iRegExp), 'even from another frame'); + }); + + test("isFinite", function() { + ok(!_.isFinite(undefined), 'undefined is not Finite'); + ok(!_.isFinite(null), 'null is not Finite'); + ok(!_.isFinite(NaN), 'NaN is not Finite'); + ok(!_.isFinite(Infinity), 'Infinity is not Finite'); + ok(!_.isFinite(-Infinity), '-Infinity is not Finite'); + ok(!_.isFinite('12'), 'Strings are not numbers'); + var obj = new Number(5); + ok(_.isFinite(obj), 'Number instances can be finite'); + ok(_.isFinite(0), '0 is Finite'); + ok(_.isFinite(123), 'Ints are Finite'); + ok(_.isFinite(-12.44), 'Floats are Finite'); + }); + + test("isNaN", function() { + ok(!_.isNaN(undefined), 'undefined is not NaN'); + ok(!_.isNaN(null), 'null is not NaN'); + ok(!_.isNaN(0), '0 is not NaN'); + ok(_.isNaN(NaN), 'but NaN is'); + ok(_.isNaN(iNaN), 'even from another frame'); + ok(_.isNaN(new Number(NaN)), 'wrapped NaN is still NaN'); + }); + + test("isNull", function() { + ok(!_.isNull(undefined), 'undefined is not null'); + ok(!_.isNull(NaN), 'NaN is not null'); + ok(_.isNull(null), 'but null is'); + ok(_.isNull(iNull), 'even from another frame'); + }); + + test("isUndefined", function() { + ok(!_.isUndefined(1), 'numbers are defined'); + ok(!_.isUndefined(null), 'null is defined'); + ok(!_.isUndefined(false), 'false is defined'); + ok(!_.isUndefined(NaN), 'NaN is defined'); + ok(_.isUndefined(), 'nothing is undefined'); + ok(_.isUndefined(undefined), 'undefined is undefined'); + ok(_.isUndefined(iUndefined), 'even from another frame'); + }); + + if (window.ActiveXObject) { + test("IE host objects", function() { + var xml = new ActiveXObject("Msxml2.DOMDocument.3.0"); + ok(!_.isNumber(xml)); + ok(!_.isBoolean(xml)); + ok(!_.isNaN(xml)); + ok(!_.isFunction(xml)); + ok(!_.isNull(xml)); + ok(!_.isUndefined(xml)); + }); + } + + test("tap", function() { + var intercepted = null; + var interceptor = function(obj) { intercepted = obj; }; + var returned = _.tap(1, interceptor); + equal(intercepted, 1, "passes tapped object to interceptor"); + equal(returned, 1, "returns tapped object"); + + returned = _([1,2,3]).chain(). + map(function(n){ return n * 2; }). + max(). + tap(interceptor). + value(); + ok(returned == 6 && intercepted == 6, 'can use tapped objects in a chain'); + }); +}); diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/speed.js b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/speed.js new file mode 100644 index 0000000..05e3f2a --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/speed.js @@ -0,0 +1,75 @@ +(function() { + + var numbers = []; + for (var i=0; i<1000; i++) numbers.push(i); + var objects = _.map(numbers, function(n){ return {num : n}; }); + var randomized = _.sortBy(numbers, function(){ return Math.random(); }); + var deep = _.map(_.range(100), function() { return _.range(1000); }); + + JSLitmus.test('_.each()', function() { + var timesTwo = []; + _.each(numbers, function(num){ timesTwo.push(num * 2); }); + return timesTwo; + }); + + JSLitmus.test('_(list).each()', function() { + var timesTwo = []; + _(numbers).each(function(num){ timesTwo.push(num * 2); }); + return timesTwo; + }); + + JSLitmus.test('jQuery.each()', function() { + var timesTwo = []; + jQuery.each(numbers, function(){ timesTwo.push(this * 2); }); + return timesTwo; + }); + + JSLitmus.test('_.map()', function() { + return _.map(objects, function(obj){ return obj.num; }); + }); + + JSLitmus.test('jQuery.map()', function() { + return jQuery.map(objects, function(obj){ return obj.num; }); + }); + + JSLitmus.test('_.pluck()', function() { + return _.pluck(objects, 'num'); + }); + + JSLitmus.test('_.uniq()', function() { + return _.uniq(randomized); + }); + + JSLitmus.test('_.uniq() (sorted)', function() { + return _.uniq(numbers, true); + }); + + JSLitmus.test('_.sortBy()', function() { + return _.sortBy(numbers, function(num){ return -num; }); + }); + + JSLitmus.test('_.isEqual()', function() { + return _.isEqual(numbers, randomized); + }); + + JSLitmus.test('_.keys()', function() { + return _.keys(objects); + }); + + JSLitmus.test('_.values()', function() { + return _.values(objects); + }); + + JSLitmus.test('_.intersection()', function() { + return _.intersection(numbers, randomized); + }); + + JSLitmus.test('_.range()', function() { + return _.range(1000); + }); + + JSLitmus.test('_.flatten()', function() { + return _.flatten(deep); + }); + +})(); diff --git a/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/utility.js b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/utility.js new file mode 100644 index 0000000..c9be20a --- /dev/null +++ b/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/utility.js @@ -0,0 +1,249 @@ +$(document).ready(function() { + + var templateSettings; + + module("Utility", { + + setup: function() { + templateSettings = _.clone(_.templateSettings); + }, + + teardown: function() { + _.templateSettings = templateSettings; + } + + }); + + test("#750 - Return _ instance.", 2, function() { + var instance = _([]); + ok(_(instance) === instance); + ok(new _(instance) === instance); + }); + + test("identity", function() { + var moe = {name : 'moe'}; + equal(_.identity(moe), moe, 'moe is the same as his identity'); + }); + + test("uniqueId", function() { + var ids = [], i = 0; + while(i++ < 100) ids.push(_.uniqueId()); + equal(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids'); + }); + + test("times", function() { + var vals = []; + _.times(3, function (i) { vals.push(i); }); + ok(_.isEqual(vals, [0,1,2]), "is 0 indexed"); + // + vals = []; + _(3).times(function (i) { vals.push(i); }); + ok(_.isEqual(vals, [0,1,2]), "works as a wrapper"); + }); + + test("mixin", function() { + _.mixin({ + myReverse: function(string) { + return string.split('').reverse().join(''); + } + }); + equal(_.myReverse('panacea'), 'aecanap', 'mixed in a function to _'); + equal(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper'); + }); + + test("_.escape", function() { + equal(_.escape("Curly & Moe"), "Curly & Moe"); + equal(_.escape("Curly & Moe"), "Curly &amp; Moe"); + equal(_.escape(null), ''); + }); + + test("_.unescape", function() { + var string = "Curly & Moe"; + equal(_.unescape("Curly & Moe"), string); + equal(_.unescape("Curly &amp; Moe"), "Curly & Moe"); + equal(_.unescape(null), ''); + equal(_.unescape(_.escape(string)), string); + }); + + test("template", function() { + var basicTemplate = _.template("<%= thing %> is gettin' on my noives!"); + var result = basicTemplate({thing : 'This'}); + equal(result, "This is gettin' on my noives!", 'can do basic attribute interpolation'); + + var sansSemicolonTemplate = _.template("A <% this %> B"); + equal(sansSemicolonTemplate(), "A B"); + + var backslashTemplate = _.template("<%= thing %> is \\ridanculous"); + equal(backslashTemplate({thing: 'This'}), "This is \\ridanculous"); + + var escapeTemplate = _.template('<%= a ? "checked=\\"checked\\"" : "" %>'); + equal(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.'); + + var fancyTemplate = _.template("
            <% \ + for (key in people) { \ + %>
          • <%= people[key] %>
          • <% } %>
          "); + result = fancyTemplate({people : {moe : "Moe", larry : "Larry", curly : "Curly"}}); + equal(result, "
          • Moe
          • Larry
          • Curly
          ", 'can run arbitrary javascript in templates'); + + var escapedCharsInJavascriptTemplate = _.template("
            <% _.each(numbers.split('\\n'), function(item) { %>
          • <%= item %>
          • <% }) %>
          "); + result = escapedCharsInJavascriptTemplate({numbers: "one\ntwo\nthree\nfour"}); + equal(result, "
          • one
          • two
          • three
          • four
          ", 'Can use escaped characters (e.g. \\n) in Javascript'); + + var namespaceCollisionTemplate = _.template("<%= pageCount %> <%= thumbnails[pageCount] %> <% _.each(thumbnails, function(p) { %>
          \">
          <% }); %>"); + result = namespaceCollisionTemplate({ + pageCount: 3, + thumbnails: { + 1: "p1-thumbnail.gif", + 2: "p2-thumbnail.gif", + 3: "p3-thumbnail.gif" + } + }); + equal(result, "3 p3-thumbnail.gif
          "); + + var noInterpolateTemplate = _.template("

          Just some text. Hey, I know this is silly but it aids consistency.

          "); + result = noInterpolateTemplate(); + equal(result, "

          Just some text. Hey, I know this is silly but it aids consistency.

          "); + + var quoteTemplate = _.template("It's its, not it's"); + equal(quoteTemplate({}), "It's its, not it's"); + + var quoteInStatementAndBody = _.template("<%\ + if(foo == 'bar'){ \ + %>Statement quotes and 'quotes'.<% } %>"); + equal(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'."); + + var withNewlinesAndTabs = _.template('This\n\t\tis: <%= x %>.\n\tok.\nend.'); + equal(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.'); + + var template = _.template("<%- value %>"); + var result = template({value: " + +``` + +## Documentation + +Some functions are also available in the following forms: +* `Series` - the same as `` but runs only a single async operation at a time +* `Limit` - the same as `` but runs a maximum of `limit` async operations at a time + +### Collections + +* [`each`](#each), `eachSeries`, `eachLimit` +* [`forEachOf`](#forEachOf), `forEachOfSeries`, `forEachOfLimit` +* [`map`](#map), `mapSeries`, `mapLimit` +* [`filter`](#filter), `filterSeries`, `filterLimit` +* [`reject`](#reject), `rejectSeries`, `rejectLimit` +* [`reduce`](#reduce), [`reduceRight`](#reduceRight) +* [`detect`](#detect), `detectSeries`, `detectLimit` +* [`sortBy`](#sortBy) +* [`some`](#some), `someLimit` +* [`every`](#every), `everyLimit` +* [`concat`](#concat), `concatSeries` + +### Control Flow + +* [`series`](#seriestasks-callback) +* [`parallel`](#parallel), `parallelLimit` +* [`whilst`](#whilst), [`doWhilst`](#doWhilst) +* [`until`](#until), [`doUntil`](#doUntil) +* [`during`](#during), [`doDuring`](#doDuring) +* [`forever`](#forever) +* [`waterfall`](#waterfall) +* [`compose`](#compose) +* [`seq`](#seq) +* [`applyEach`](#applyEach), `applyEachSeries` +* [`queue`](#queue), [`priorityQueue`](#priorityQueue) +* [`cargo`](#cargo) +* [`auto`](#auto) +* [`retry`](#retry) +* [`iterator`](#iterator) +* [`times`](#times), `timesSeries`, `timesLimit` + +### Utils + +* [`apply`](#apply) +* [`nextTick`](#nextTick) +* [`memoize`](#memoize) +* [`unmemoize`](#unmemoize) +* [`ensureAsync`](#ensureAsync) +* [`constant`](#constant) +* [`asyncify`](#asyncify) +* [`wrapSync`](#wrapSync) +* [`log`](#log) +* [`dir`](#dir) +* [`noConflict`](#noConflict) + +## Collections + + + +### each(arr, iterator, [callback]) + +Applies the function `iterator` to each item in `arr`, in parallel. +The `iterator` is called with an item from the list, and a callback for when it +has finished. If the `iterator` passes an error to its `callback`, the main +`callback` (for the `each` function) is immediately called with the error. + +Note, that since this function applies `iterator` to each item in parallel, +there is no guarantee that the iterator functions will complete in order. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err)` which must be called once it has + completed. If no error has occurred, the `callback` should be run without + arguments or with an explicit `null` argument. The array index is not passed + to the iterator. If you need the index, use [`forEachOf`](#forEachOf). +* `callback(err)` - *Optional* A callback which is called when all `iterator` functions + have finished, or an error occurs. + +__Examples__ + + +```js +// assuming openFiles is an array of file names and saveFile is a function +// to save the modified contents of that file: + +async.each(openFiles, saveFile, function(err){ + // if any of the saves produced an error, err would equal that error +}); +``` + +```js +// assuming openFiles is an array of file names + +async.each(openFiles, function(file, callback) { + + // Perform operation on file here. + console.log('Processing file ' + file); + + if( file.length > 32 ) { + console.log('This file name is too long'); + callback('File name too long'); + } else { + // Do work to process file here + console.log('File processed'); + callback(); + } +}, function(err){ + // if any of the file processing produced an error, err would equal that error + if( err ) { + // One of the iterations produced an error. + // All processing will now stop. + console.log('A file failed to process'); + } else { + console.log('All files have been processed successfully'); + } +}); +``` + +__Related__ + +* eachSeries(arr, iterator, [callback]) +* eachLimit(arr, limit, iterator, [callback]) + +--------------------------------------- + + + + +### forEachOf(obj, iterator, [callback]) + +Like `each`, except that it iterates over objects, and passes the key as the second argument to the iterator. + +__Arguments__ + +* `obj` - An object or array to iterate over. +* `iterator(item, key, callback)` - A function to apply to each item in `obj`. +The `key` is the item's key, or index in the case of an array. The iterator is +passed a `callback(err)` which must be called once it has completed. If no +error has occurred, the callback should be run without arguments or with an +explicit `null` argument. +* `callback(err)` - *Optional* A callback which is called when all `iterator` functions have finished, or an error occurs. + +__Example__ + +```js +var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"}; +var configs = {}; + +async.forEachOf(obj, function (value, key, callback) { + fs.readFile(__dirname + value, "utf8", function (err, data) { + if (err) return callback(err); + try { + configs[key] = JSON.parse(data); + } catch (e) { + return callback(e); + } + callback(); + }) +}, function (err) { + if (err) console.error(err.message); + // configs is now a map of JSON data + doSomethingWith(configs); +}) +``` + +__Related__ + +* forEachOfSeries(obj, iterator, [callback]) +* forEachOfLimit(obj, limit, iterator, [callback]) + +--------------------------------------- + + +### map(arr, iterator, [callback]) + +Produces a new array of values by mapping each value in `arr` through +the `iterator` function. The `iterator` is called with an item from `arr` and a +callback for when it has finished processing. Each of these callback takes 2 arguments: +an `error`, and the transformed item from `arr`. If `iterator` passes an error to its +callback, the main `callback` (for the `map` function) is immediately called with the error. + +Note, that since this function applies the `iterator` to each item in parallel, +there is no guarantee that the `iterator` functions will complete in order. +However, the results array will be in the same order as the original `arr`. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err, transformed)` which must be called once + it has completed with an error (which can be `null`) and a transformed item. +* `callback(err, results)` - *Optional* A callback which is called when all `iterator` + functions have finished, or an error occurs. Results is an array of the + transformed items from the `arr`. + +__Example__ + +```js +async.map(['file1','file2','file3'], fs.stat, function(err, results){ + // results is now an array of stats for each file +}); +``` + +__Related__ +* mapSeries(arr, iterator, [callback]) +* mapLimit(arr, limit, iterator, [callback]) + +--------------------------------------- + + + +### filter(arr, iterator, [callback]) + +__Alias:__ `select` + +Returns a new array of all the values in `arr` which pass an async truth test. +_The callback for each `iterator` call only accepts a single argument of `true` or +`false`; it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like `fs.exists`. This operation is +performed in parallel, but the results array will be in the same order as the +original. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in `arr`. + The `iterator` is passed a `callback(truthValue)`, which must be called with a + boolean argument once it has completed. +* `callback(results)` - *Optional* A callback which is called after all the `iterator` + functions have finished. + +__Example__ + +```js +async.filter(['file1','file2','file3'], fs.exists, function(results){ + // results now equals an array of the existing files +}); +``` + +__Related__ + +* filterSeries(arr, iterator, [callback]) +* filterLimit(arr, limit, iterator, [callback]) + +--------------------------------------- + + +### reject(arr, iterator, [callback]) + +The opposite of [`filter`](#filter). Removes values that pass an `async` truth test. + +__Related__ + +* rejectSeries(arr, iterator, [callback]) +* rejectLimit(arr, limit, iterator, [callback]) + +--------------------------------------- + + +### reduce(arr, memo, iterator, [callback]) + +__Aliases:__ `inject`, `foldl` + +Reduces `arr` into a single value using an async `iterator` to return +each successive step. `memo` is the initial state of the reduction. +This function only operates in series. + +For performance reasons, it may make sense to split a call to this function into +a parallel map, and then use the normal `Array.prototype.reduce` on the results. +This function is for situations where each step in the reduction needs to be async; +if you can get the data before reducing it, then it's probably a good idea to do so. + +__Arguments__ + +* `arr` - An array to iterate over. +* `memo` - The initial state of the reduction. +* `iterator(memo, item, callback)` - A function applied to each item in the + array to produce the next step in the reduction. The `iterator` is passed a + `callback(err, reduction)` which accepts an optional error as its first + argument, and the state of the reduction as the second. If an error is + passed to the callback, the reduction is stopped and the main `callback` is + immediately called with the error. +* `callback(err, result)` - *Optional* A callback which is called after all the `iterator` + functions have finished. Result is the reduced value. + +__Example__ + +```js +async.reduce([1,2,3], 0, function(memo, item, callback){ + // pointless async: + process.nextTick(function(){ + callback(null, memo + item) + }); +}, function(err, result){ + // result is now equal to the last value of memo, which is 6 +}); +``` + +--------------------------------------- + + +### reduceRight(arr, memo, iterator, [callback]) + +__Alias:__ `foldr` + +Same as [`reduce`](#reduce), only operates on `arr` in reverse order. + + +--------------------------------------- + + +### detect(arr, iterator, [callback]) + +Returns the first value in `arr` that passes an async truth test. The +`iterator` is applied in parallel, meaning the first iterator to return `true` will +fire the detect `callback` with that result. That means the result might not be +the first item in the original `arr` (in terms of order) that passes the test. + +If order within the original `arr` is important, then look at [`detectSeries`](#detectSeries). + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in `arr`. + The iterator is passed a `callback(truthValue)` which must be called with a + boolean argument once it has completed. **Note: this callback does not take an error as its first argument.** +* `callback(result)` - *Optional* A callback which is called as soon as any iterator returns + `true`, or after all the `iterator` functions have finished. Result will be + the first item in the array that passes the truth test (iterator) or the + value `undefined` if none passed. **Note: this callback does not take an error as its first argument.** + +__Example__ + +```js +async.detect(['file1','file2','file3'], fs.exists, function(result){ + // result now equals the first file in the list that exists +}); +``` + +__Related__ + +* detectSeries(arr, iterator, [callback]) +* detectLimit(arr, limit, iterator, [callback]) + +--------------------------------------- + + +### sortBy(arr, iterator, [callback]) + +Sorts a list by the results of running each `arr` value through an async `iterator`. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err, sortValue)` which must be called once it + has completed with an error (which can be `null`) and a value to use as the sort + criteria. +* `callback(err, results)` - *Optional* A callback which is called after all the `iterator` + functions have finished, or an error occurs. Results is the items from + the original `arr` sorted by the values returned by the `iterator` calls. + +__Example__ + +```js +async.sortBy(['file1','file2','file3'], function(file, callback){ + fs.stat(file, function(err, stats){ + callback(err, stats.mtime); + }); +}, function(err, results){ + // results is now the original array of files sorted by + // modified date +}); +``` + +__Sort Order__ + +By modifying the callback parameter the sorting order can be influenced: + +```js +//ascending order +async.sortBy([1,9,3,5], function(x, callback){ + callback(null, x); +}, function(err,result){ + //result callback +} ); + +//descending order +async.sortBy([1,9,3,5], function(x, callback){ + callback(null, x*-1); //<- x*-1 instead of x, turns the order around +}, function(err,result){ + //result callback +} ); +``` + +--------------------------------------- + + +### some(arr, iterator, [callback]) + +__Alias:__ `any` + +Returns `true` if at least one element in the `arr` satisfies an async test. +_The callback for each iterator call only accepts a single argument of `true` or +`false`; it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like `fs.exists`. Once any iterator +call returns `true`, the main `callback` is immediately called. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in the array + in parallel. The iterator is passed a `callback(truthValue)`` which must be + called with a boolean argument once it has completed. +* `callback(result)` - *Optional* A callback which is called as soon as any iterator returns + `true`, or after all the iterator functions have finished. Result will be + either `true` or `false` depending on the values of the async tests. + + **Note: the callbacks do not take an error as their first argument.** +__Example__ + +```js +async.some(['file1','file2','file3'], fs.exists, function(result){ + // if result is true then at least one of the files exists +}); +``` + +__Related__ + +* someLimit(arr, limit, iterator, callback) + +--------------------------------------- + + +### every(arr, iterator, [callback]) + +__Alias:__ `all` + +Returns `true` if every element in `arr` satisfies an async test. +_The callback for each `iterator` call only accepts a single argument of `true` or +`false`; it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like `fs.exists`. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in the array + in parallel. The iterator is passed a `callback(truthValue)` which must be + called with a boolean argument once it has completed. +* `callback(result)` - *Optional* A callback which is called as soon as any iterator returns + `false`, or after all the iterator functions have finished. Result will be + either `true` or `false` depending on the values of the async tests. + + **Note: the callbacks do not take an error as their first argument.** + +__Example__ + +```js +async.every(['file1','file2','file3'], fs.exists, function(result){ + // if result is true then every file exists +}); +``` + +__Related__ + +* everyLimit(arr, limit, iterator, callback) + +--------------------------------------- + + +### concat(arr, iterator, [callback]) + +Applies `iterator` to each item in `arr`, concatenating the results. Returns the +concatenated list. The `iterator`s are called in parallel, and the results are +concatenated as they return. There is no guarantee that the results array will +be returned in the original order of `arr` passed to the `iterator` function. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err, results)` which must be called once it + has completed with an error (which can be `null`) and an array of results. +* `callback(err, results)` - *Optional* A callback which is called after all the `iterator` + functions have finished, or an error occurs. Results is an array containing + the concatenated results of the `iterator` function. + +__Example__ + +```js +async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){ + // files is now a list of filenames that exist in the 3 directories +}); +``` + +__Related__ + +* concatSeries(arr, iterator, [callback]) + + +## Control Flow + + +### series(tasks, [callback]) + +Run the functions in the `tasks` array in series, each one running once the previous +function has completed. If any functions in the series pass an error to its +callback, no more functions are run, and `callback` is immediately called with the value of the error. +Otherwise, `callback` receives an array of results when `tasks` have completed. + +It is also possible to use an object instead of an array. Each property will be +run as a function, and the results will be passed to the final `callback` as an object +instead of an array. This can be a more readable way of handling results from +[`series`](#series). + +**Note** that while many implementations preserve the order of object properties, the +[ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) +explicitly states that + +> The mechanics and order of enumerating the properties is not specified. + +So if you rely on the order in which your series of functions are executed, and want +this to work on all platforms, consider using an array. + +__Arguments__ + +* `tasks` - An array or object containing functions to run, each function is passed + a `callback(err, result)` it must call on completion with an error `err` (which can + be `null`) and an optional `result` value. +* `callback(err, results)` - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the `task` callbacks. + +__Example__ + +```js +async.series([ + function(callback){ + // do some stuff ... + callback(null, 'one'); + }, + function(callback){ + // do some more stuff ... + callback(null, 'two'); + } +], +// optional callback +function(err, results){ + // results is now equal to ['one', 'two'] +}); + + +// an example using an object instead of an array +async.series({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + } +}, +function(err, results) { + // results is now equal to: {one: 1, two: 2} +}); +``` + +--------------------------------------- + + +### parallel(tasks, [callback]) + +Run the `tasks` array of functions in parallel, without waiting until the previous +function has completed. If any of the functions pass an error to its +callback, the main `callback` is immediately called with the value of the error. +Once the `tasks` have completed, the results are passed to the final `callback` as an +array. + +**Note:** `parallel` is about kicking-off I/O tasks in parallel, not about parallel execution of code. If your tasks do not use any timers or perform any I/O, they will actually be executed in series. Any synchronous setup sections for each task will happen one after the other. JavaScript remains single-threaded. + +It is also possible to use an object instead of an array. Each property will be +run as a function and the results will be passed to the final `callback` as an object +instead of an array. This can be a more readable way of handling results from +[`parallel`](#parallel). + + +__Arguments__ + +* `tasks` - An array or object containing functions to run. Each function is passed + a `callback(err, result)` which it must call on completion with an error `err` + (which can be `null`) and an optional `result` value. +* `callback(err, results)` - An optional callback to run once all the functions + have completed successfully. This function gets a results array (or object) containing all + the result arguments passed to the task callbacks. + +__Example__ + +```js +async.parallel([ + function(callback){ + setTimeout(function(){ + callback(null, 'one'); + }, 200); + }, + function(callback){ + setTimeout(function(){ + callback(null, 'two'); + }, 100); + } +], +// optional callback +function(err, results){ + // the results array will equal ['one','two'] even though + // the second function had a shorter timeout. +}); + + +// an example using an object instead of an array +async.parallel({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + } +}, +function(err, results) { + // results is now equals to: {one: 1, two: 2} +}); +``` + +__Related__ + +* parallelLimit(tasks, limit, [callback]) + +--------------------------------------- + + +### whilst(test, fn, callback) + +Repeatedly call `fn`, while `test` returns `true`. Calls `callback` when stopped, +or an error occurs. + +__Arguments__ + +* `test()` - synchronous truth test to perform before each execution of `fn`. +* `fn(callback)` - A function which is called each time `test` passes. The function is + passed a `callback(err)`, which must be called once it has completed with an + optional `err` argument. +* `callback(err, [results])` - A callback which is called after the test + function has failed and repeated execution of `fn` has stopped. `callback` + will be passed an error and any arguments passed to the final `fn`'s callback. + +__Example__ + +```js +var count = 0; + +async.whilst( + function () { return count < 5; }, + function (callback) { + count++; + setTimeout(function () { + callback(null, count); + }, 1000); + }, + function (err, n) { + // 5 seconds have passed, n = 5 + } +); +``` + +--------------------------------------- + + +### doWhilst(fn, test, callback) + +The post-check version of [`whilst`](#whilst). To reflect the difference in +the order of operations, the arguments `test` and `fn` are switched. + +`doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. + +--------------------------------------- + + +### until(test, fn, callback) + +Repeatedly call `fn` until `test` returns `true`. Calls `callback` when stopped, +or an error occurs. `callback` will be passed an error and any arguments passed +to the final `fn`'s callback. + +The inverse of [`whilst`](#whilst). + +--------------------------------------- + + +### doUntil(fn, test, callback) + +Like [`doWhilst`](#doWhilst), except the `test` is inverted. Note the argument ordering differs from `until`. + +--------------------------------------- + + +### during(test, fn, callback) + +Like [`whilst`](#whilst), except the `test` is an asynchronous function that is passed a callback in the form of `function (err, truth)`. If error is passed to `test` or `fn`, the main callback is immediately called with the value of the error. + +__Example__ + +```js +var count = 0; + +async.during( + function (callback) { + return callback(null, count < 5); + }, + function (callback) { + count++; + setTimeout(callback, 1000); + }, + function (err) { + // 5 seconds have passed + } +); +``` + +--------------------------------------- + + +### doDuring(fn, test, callback) + +The post-check version of [`during`](#during). To reflect the difference in +the order of operations, the arguments `test` and `fn` are switched. + +Also a version of [`doWhilst`](#doWhilst) with asynchronous `test` function. + +--------------------------------------- + + +### forever(fn, [errback]) + +Calls the asynchronous function `fn` with a callback parameter that allows it to +call itself again, in series, indefinitely. + +If an error is passed to the callback then `errback` is called with the +error, and execution stops, otherwise it will never be called. + +```js +async.forever( + function(next) { + // next is suitable for passing to things that need a callback(err [, whatever]); + // it will result in this function being called again. + }, + function(err) { + // if next is called with a value in its first parameter, it will appear + // in here as 'err', and execution will stop. + } +); +``` + +--------------------------------------- + + +### waterfall(tasks, [callback]) + +Runs the `tasks` array of functions in series, each passing their results to the next in +the array. However, if any of the `tasks` pass an error to their own callback, the +next function is not executed, and the main `callback` is immediately called with +the error. + +__Arguments__ + +* `tasks` - An array of functions to run, each function is passed a + `callback(err, result1, result2, ...)` it must call on completion. The first + argument is an error (which can be `null`) and any further arguments will be + passed as arguments in order to the next task. +* `callback(err, [results])` - An optional callback to run once all the functions + have completed. This will be passed the results of the last task's callback. + + + +__Example__ + +```js +async.waterfall([ + function(callback) { + callback(null, 'one', 'two'); + }, + function(arg1, arg2, callback) { + // arg1 now equals 'one' and arg2 now equals 'two' + callback(null, 'three'); + }, + function(arg1, callback) { + // arg1 now equals 'three' + callback(null, 'done'); + } +], function (err, result) { + // result now equals 'done' +}); +``` +Or, with named functions: + +```js +async.waterfall([ + myFirstFunction, + mySecondFunction, + myLastFunction, +], function (err, result) { + // result now equals 'done' +}); +function myFirstFunction(callback) { + callback(null, 'one', 'two'); +} +function mySecondFunction(arg1, arg2, callback) { + // arg1 now equals 'one' and arg2 now equals 'two' + callback(null, 'three'); +} +function myLastFunction(arg1, callback) { + // arg1 now equals 'three' + callback(null, 'done'); +} +``` + +Or, if you need to pass any argument to the first function: + +```js +async.waterfall([ + async.apply(myFirstFunction, 'zero'), + mySecondFunction, + myLastFunction, +], function (err, result) { + // result now equals 'done' +}); +function myFirstFunction(arg1, callback) { + // arg1 now equals 'zero' + callback(null, 'one', 'two'); +} +function mySecondFunction(arg1, arg2, callback) { + // arg1 now equals 'one' and arg2 now equals 'two' + callback(null, 'three'); +} +function myLastFunction(arg1, callback) { + // arg1 now equals 'three' + callback(null, 'done'); +} +``` + +--------------------------------------- + +### compose(fn1, fn2...) + +Creates a function which is a composition of the passed asynchronous +functions. Each function consumes the return value of the function that +follows. Composing functions `f()`, `g()`, and `h()` would produce the result of +`f(g(h()))`, only this version uses callbacks to obtain the return values. + +Each function is executed with the `this` binding of the composed function. + +__Arguments__ + +* `functions...` - the asynchronous functions to compose + + +__Example__ + +```js +function add1(n, callback) { + setTimeout(function () { + callback(null, n + 1); + }, 10); +} + +function mul3(n, callback) { + setTimeout(function () { + callback(null, n * 3); + }, 10); +} + +var add1mul3 = async.compose(mul3, add1); + +add1mul3(4, function (err, result) { + // result now equals 15 +}); +``` + +--------------------------------------- + +### seq(fn1, fn2...) + +Version of the compose function that is more natural to read. +Each function consumes the return value of the previous function. +It is the equivalent of [`compose`](#compose) with the arguments reversed. + +Each function is executed with the `this` binding of the composed function. + +__Arguments__ + +* `functions...` - the asynchronous functions to compose + + +__Example__ + +```js +// Requires lodash (or underscore), express3 and dresende's orm2. +// Part of an app, that fetches cats of the logged user. +// This example uses `seq` function to avoid overnesting and error +// handling clutter. +app.get('/cats', function(request, response) { + var User = request.models.User; + async.seq( + _.bind(User.get, User), // 'User.get' has signature (id, callback(err, data)) + function(user, fn) { + user.getCats(fn); // 'getCats' has signature (callback(err, data)) + } + )(req.session.user_id, function (err, cats) { + if (err) { + console.error(err); + response.json({ status: 'error', message: err.message }); + } else { + response.json({ status: 'ok', message: 'Cats found', data: cats }); + } + }); +}); +``` + +--------------------------------------- + +### applyEach(fns, args..., callback) + +Applies the provided arguments to each function in the array, calling +`callback` after all functions have completed. If you only provide the first +argument, then it will return a function which lets you pass in the +arguments as if it were a single function call. + +__Arguments__ + +* `fns` - the asynchronous functions to all call with the same arguments +* `args...` - any number of separate arguments to pass to the function +* `callback` - the final argument should be the callback, called when all + functions have completed processing + + +__Example__ + +```js +async.applyEach([enableSearch, updateSchema], 'bucket', callback); + +// partial application example: +async.each( + buckets, + async.applyEach([enableSearch, updateSchema]), + callback +); +``` + +__Related__ + +* applyEachSeries(tasks, args..., [callback]) + +--------------------------------------- + + +### queue(worker, [concurrency]) + +Creates a `queue` object with the specified `concurrency`. Tasks added to the +`queue` are processed in parallel (up to the `concurrency` limit). If all +`worker`s are in progress, the task is queued until one becomes available. +Once a `worker` completes a `task`, that `task`'s callback is called. + +__Arguments__ + +* `worker(task, callback)` - An asynchronous function for processing a queued + task, which must call its `callback(err)` argument when finished, with an + optional `error` as an argument. If you want to handle errors from an individual task, pass a callback to `q.push()`. +* `concurrency` - An `integer` for determining how many `worker` functions should be + run in parallel. If omitted, the concurrency defaults to `1`. If the concurrency is `0`, an error is thrown. + +__Queue objects__ + +The `queue` object returned by this function has the following properties and +methods: + +* `length()` - a function returning the number of items waiting to be processed. +* `started` - a function returning whether or not any items have been pushed and processed by the queue +* `running()` - a function returning the number of items currently being processed. +* `workersList()` - a function returning the array of items currently being processed. +* `idle()` - a function returning false if there are items waiting or being processed, or true if not. +* `concurrency` - an integer for determining how many `worker` functions should be + run in parallel. This property can be changed after a `queue` is created to + alter the concurrency on-the-fly. +* `push(task, [callback])` - add a new task to the `queue`. Calls `callback` once + the `worker` has finished processing the task. Instead of a single task, a `tasks` array + can be submitted. The respective callback is used for every task in the list. +* `unshift(task, [callback])` - add a new task to the front of the `queue`. +* `saturated` - a callback that is called when the `queue` length hits the `concurrency` limit, + and further tasks will be queued. +* `empty` - a callback that is called when the last item from the `queue` is given to a `worker`. +* `drain` - a callback that is called when the last item from the `queue` has returned from the `worker`. +* `paused` - a boolean for determining whether the queue is in a paused state +* `pause()` - a function that pauses the processing of tasks until `resume()` is called. +* `resume()` - a function that resumes the processing of queued tasks when the queue is paused. +* `kill()` - a function that removes the `drain` callback and empties remaining tasks from the queue forcing it to go idle. + +__Example__ + +```js +// create a queue object with concurrency 2 + +var q = async.queue(function (task, callback) { + console.log('hello ' + task.name); + callback(); +}, 2); + + +// assign a callback +q.drain = function() { + console.log('all items have been processed'); +} + +// add some items to the queue + +q.push({name: 'foo'}, function (err) { + console.log('finished processing foo'); +}); +q.push({name: 'bar'}, function (err) { + console.log('finished processing bar'); +}); + +// add some items to the queue (batch-wise) + +q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) { + console.log('finished processing item'); +}); + +// add some items to the front of the queue + +q.unshift({name: 'bar'}, function (err) { + console.log('finished processing bar'); +}); +``` + + +--------------------------------------- + + +### priorityQueue(worker, concurrency) + +The same as [`queue`](#queue) only tasks are assigned a priority and completed in ascending priority order. There are two differences between `queue` and `priorityQueue` objects: + +* `push(task, priority, [callback])` - `priority` should be a number. If an array of + `tasks` is given, all tasks will be assigned the same priority. +* The `unshift` method was removed. + +--------------------------------------- + + +### cargo(worker, [payload]) + +Creates a `cargo` object with the specified payload. Tasks added to the +cargo will be processed altogether (up to the `payload` limit). If the +`worker` is in progress, the task is queued until it becomes available. Once +the `worker` has completed some tasks, each callback of those tasks is called. +Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966) for how `cargo` and `queue` work. + +While [queue](#queue) passes only one task to one of a group of workers +at a time, cargo passes an array of tasks to a single worker, repeating +when the worker is finished. + +__Arguments__ + +* `worker(tasks, callback)` - An asynchronous function for processing an array of + queued tasks, which must call its `callback(err)` argument when finished, with + an optional `err` argument. +* `payload` - An optional `integer` for determining how many tasks should be + processed per round; if omitted, the default is unlimited. + +__Cargo objects__ + +The `cargo` object returned by this function has the following properties and +methods: + +* `length()` - A function returning the number of items waiting to be processed. +* `payload` - An `integer` for determining how many tasks should be + process per round. This property can be changed after a `cargo` is created to + alter the payload on-the-fly. +* `push(task, [callback])` - Adds `task` to the `queue`. The callback is called + once the `worker` has finished processing the task. Instead of a single task, an array of `tasks` + can be submitted. The respective callback is used for every task in the list. +* `saturated` - A callback that is called when the `queue.length()` hits the concurrency and further tasks will be queued. +* `empty` - A callback that is called when the last item from the `queue` is given to a `worker`. +* `drain` - A callback that is called when the last item from the `queue` has returned from the `worker`. +* `idle()`, `pause()`, `resume()`, `kill()` - cargo inherits all of the same methods and event calbacks as [`queue`](#queue) + +__Example__ + +```js +// create a cargo object with payload 2 + +var cargo = async.cargo(function (tasks, callback) { + for(var i=0; i +### auto(tasks, [concurrency], [callback]) + +Determines the best order for running the functions in `tasks`, based on their requirements. Each function can optionally depend on other functions being completed first, and each function is run as soon as its requirements are satisfied. + +If any of the functions pass an error to their callback, the `auto` sequence will stop. Further tasks will not execute (so any other functions depending on it will not run), and the main `callback` is immediately called with the error. Functions also receive an object containing the results of functions which have completed so far. + +Note, all functions are called with a `results` object as a second argument, +so it is unsafe to pass functions in the `tasks` object which cannot handle the +extra argument. + +For example, this snippet of code: + +```js +async.auto({ + readData: async.apply(fs.readFile, 'data.txt', 'utf-8') +}, callback); +``` + +will have the effect of calling `readFile` with the results object as the last +argument, which will fail: + +```js +fs.readFile('data.txt', 'utf-8', cb, {}); +``` + +Instead, wrap the call to `readFile` in a function which does not forward the +`results` object: + +```js +async.auto({ + readData: function(cb, results){ + fs.readFile('data.txt', 'utf-8', cb); + } +}, callback); +``` + +__Arguments__ + +* `tasks` - An object. Each of its properties is either a function or an array of + requirements, with the function itself the last item in the array. The object's key + of a property serves as the name of the task defined by that property, + i.e. can be used when specifying requirements for other tasks. + The function receives two arguments: (1) a `callback(err, result)` which must be + called when finished, passing an `error` (which can be `null`) and the result of + the function's execution, and (2) a `results` object, containing the results of + the previously executed functions. +* `concurrency` - An optional `integer` for determining the maximum number of tasks that can be run in parallel. By default, as many as possible. +* `callback(err, results)` - An optional callback which is called when all the + tasks have been completed. It receives the `err` argument if any `tasks` + pass an error to their callback. Results are always returned; however, if + an error occurs, no further `tasks` will be performed, and the results + object will only contain partial results. + + +__Example__ + +```js +async.auto({ + get_data: function(callback){ + console.log('in get_data'); + // async code to get some data + callback(null, 'data', 'converted to array'); + }, + make_folder: function(callback){ + console.log('in make_folder'); + // async code to create a directory to store a file in + // this is run at the same time as getting the data + callback(null, 'folder'); + }, + write_file: ['get_data', 'make_folder', function(callback, results){ + console.log('in write_file', JSON.stringify(results)); + // once there is some data and the directory exists, + // write the data to a file in the directory + callback(null, 'filename'); + }], + email_link: ['write_file', function(callback, results){ + console.log('in email_link', JSON.stringify(results)); + // once the file is written let's email a link to it... + // results.write_file contains the filename returned by write_file. + callback(null, {'file':results.write_file, 'email':'user@example.com'}); + }] +}, function(err, results) { + console.log('err = ', err); + console.log('results = ', results); +}); +``` + +This is a fairly trivial example, but to do this using the basic parallel and +series functions would look like this: + +```js +async.parallel([ + function(callback){ + console.log('in get_data'); + // async code to get some data + callback(null, 'data', 'converted to array'); + }, + function(callback){ + console.log('in make_folder'); + // async code to create a directory to store a file in + // this is run at the same time as getting the data + callback(null, 'folder'); + } +], +function(err, results){ + async.series([ + function(callback){ + console.log('in write_file', JSON.stringify(results)); + // once there is some data and the directory exists, + // write the data to a file in the directory + results.push('filename'); + callback(null); + }, + function(callback){ + console.log('in email_link', JSON.stringify(results)); + // once the file is written let's email a link to it... + callback(null, {'file':results.pop(), 'email':'user@example.com'}); + } + ]); +}); +``` + +For a complicated series of `async` tasks, using the [`auto`](#auto) function makes adding +new tasks much easier (and the code more readable). + + +--------------------------------------- + + +### retry([opts = {times: 5, interval: 0}| 5], task, [callback]) + +Attempts to get a successful response from `task` no more than `times` times before +returning an error. If the task is successful, the `callback` will be passed the result +of the successful task. If all attempts fail, the callback will be passed the error and +result (if any) of the final attempt. + +__Arguments__ + +* `opts` - Can be either an object with `times` and `interval` or a number. + * `times` - The number of attempts to make before giving up. The default is `5`. + * `interval` - The time to wait between retries, in milliseconds. The default is `0`. + * If `opts` is a number, the number specifies the number of times to retry, with the default interval of `0`. +* `task(callback, results)` - A function which receives two arguments: (1) a `callback(err, result)` + which must be called when finished, passing `err` (which can be `null`) and the `result` of + the function's execution, and (2) a `results` object, containing the results of + the previously executed functions (if nested inside another control flow). +* `callback(err, results)` - An optional callback which is called when the + task has succeeded, or after the final failed attempt. It receives the `err` and `result` arguments of the last attempt at completing the `task`. + +The [`retry`](#retry) function can be used as a stand-alone control flow by passing a callback, as shown below: + +```js +// try calling apiMethod 3 times +async.retry(3, apiMethod, function(err, result) { + // do something with the result +}); +``` + +```js +// try calling apiMethod 3 times, waiting 200 ms between each retry +async.retry({times: 3, interval: 200}, apiMethod, function(err, result) { + // do something with the result +}); +``` + +```js +// try calling apiMethod the default 5 times no delay between each retry +async.retry(apiMethod, function(err, result) { + // do something with the result +}); +``` + +It can also be embedded within other control flow functions to retry individual methods +that are not as reliable, like this: + +```js +async.auto({ + users: api.getUsers.bind(api), + payments: async.retry(3, api.getPayments.bind(api)) +}, function(err, results) { + // do something with the results +}); +``` + + +--------------------------------------- + + +### iterator(tasks) + +Creates an iterator function which calls the next function in the `tasks` array, +returning a continuation to call the next one after that. It's also possible to +“peek” at the next iterator with `iterator.next()`. + +This function is used internally by the `async` module, but can be useful when +you want to manually control the flow of functions in series. + +__Arguments__ + +* `tasks` - An array of functions to run. + +__Example__ + +```js +var iterator = async.iterator([ + function(){ sys.p('one'); }, + function(){ sys.p('two'); }, + function(){ sys.p('three'); } +]); + +node> var iterator2 = iterator(); +'one' +node> var iterator3 = iterator2(); +'two' +node> iterator3(); +'three' +node> var nextfn = iterator2.next(); +node> nextfn(); +'three' +``` + +--------------------------------------- + + +### apply(function, arguments..) + +Creates a continuation function with some arguments already applied. + +Useful as a shorthand when combined with other control flow functions. Any arguments +passed to the returned function are added to the arguments originally passed +to apply. + +__Arguments__ + +* `function` - The function you want to eventually apply all arguments to. +* `arguments...` - Any number of arguments to automatically apply when the + continuation is called. + +__Example__ + +```js +// using apply + +async.parallel([ + async.apply(fs.writeFile, 'testfile1', 'test1'), + async.apply(fs.writeFile, 'testfile2', 'test2'), +]); + + +// the same process without using apply + +async.parallel([ + function(callback){ + fs.writeFile('testfile1', 'test1', callback); + }, + function(callback){ + fs.writeFile('testfile2', 'test2', callback); + } +]); +``` + +It's possible to pass any number of additional arguments when calling the +continuation: + +```js +node> var fn = async.apply(sys.puts, 'one'); +node> fn('two', 'three'); +one +two +three +``` + +--------------------------------------- + + +### nextTick(callback), setImmediate(callback) + +Calls `callback` on a later loop around the event loop. In Node.js this just +calls `process.nextTick`; in the browser it falls back to `setImmediate(callback)` +if available, otherwise `setTimeout(callback, 0)`, which means other higher priority +events may precede the execution of `callback`. + +This is used internally for browser-compatibility purposes. + +__Arguments__ + +* `callback` - The function to call on a later loop around the event loop. + +__Example__ + +```js +var call_order = []; +async.nextTick(function(){ + call_order.push('two'); + // call_order now equals ['one','two'] +}); +call_order.push('one') +``` + + +### times(n, iterator, [callback]) + +Calls the `iterator` function `n` times, and accumulates results in the same manner +you would use with [`map`](#map). + +__Arguments__ + +* `n` - The number of times to run the function. +* `iterator` - The function to call `n` times. +* `callback` - see [`map`](#map) + +__Example__ + +```js +// Pretend this is some complicated async factory +var createUser = function(id, callback) { + callback(null, { + id: 'user' + id + }) +} +// generate 5 users +async.times(5, function(n, next){ + createUser(n, function(err, user) { + next(err, user) + }) +}, function(err, users) { + // we should now have 5 users +}); +``` + +__Related__ + +* timesSeries(n, iterator, [callback]) +* timesLimit(n, limit, iterator, [callback]) + + +## Utils + + +### memoize(fn, [hasher]) + +Caches the results of an `async` function. When creating a hash to store function +results against, the callback is omitted from the hash and an optional hash +function can be used. + +If no hash function is specified, the first argument is used as a hash key, which may work reasonably if it is a string or a data type that converts to a distinct string. Note that objects and arrays will not behave reasonably. Neither will cases where the other arguments are significant. In such cases, specify your own hash function. + +The cache of results is exposed as the `memo` property of the function returned +by `memoize`. + +__Arguments__ + +* `fn` - The function to proxy and cache results from. +* `hasher` - An optional function for generating a custom hash for storing + results. It has all the arguments applied to it apart from the callback, and + must be synchronous. + +__Example__ + +```js +var slow_fn = function (name, callback) { + // do something + callback(null, result); +}; +var fn = async.memoize(slow_fn); + +// fn can now be used as if it were slow_fn +fn('some name', function () { + // callback +}); +``` + + +### unmemoize(fn) + +Undoes a [`memoize`](#memoize)d function, reverting it to the original, unmemoized +form. Handy for testing. + +__Arguments__ + +* `fn` - the memoized function + +--------------------------------------- + + +### ensureAsync(fn) + +Wrap an async function and ensure it calls its callback on a later tick of the event loop. If the function already calls its callback on a next tick, no extra deferral is added. This is useful for preventing stack overflows (`RangeError: Maximum call stack size exceeded`) and generally keeping [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony) contained. + +__Arguments__ + +* `fn` - an async function, one that expects a node-style callback as its last argument + +Returns a wrapped function with the exact same call signature as the function passed in. + +__Example__ + +```js +function sometimesAsync(arg, callback) { + if (cache[arg]) { + return callback(null, cache[arg]); // this would be synchronous!! + } else { + doSomeIO(arg, callback); // this IO would be asynchronous + } +} + +// this has a risk of stack overflows if many results are cached in a row +async.mapSeries(args, sometimesAsync, done); + +// this will defer sometimesAsync's callback if necessary, +// preventing stack overflows +async.mapSeries(args, async.ensureAsync(sometimesAsync), done); + +``` + +--------------------------------------- + + +### constant(values...) + +Returns a function that when called, calls-back with the values provided. Useful as the first function in a `waterfall`, or for plugging values in to `auto`. + +__Example__ + +```js +async.waterfall([ + async.constant(42), + function (value, next) { + // value === 42 + }, + //... +], callback); + +async.waterfall([ + async.constant(filename, "utf8"), + fs.readFile, + function (fileData, next) { + //... + } + //... +], callback); + +async.auto({ + hostname: async.constant("https://server.net/"), + port: findFreePort, + launchServer: ["hostname", "port", function (cb, options) { + startServer(options, cb); + }], + //... +}, callback); + +``` + +--------------------------------------- + + + +### asyncify(func) + +__Alias:__ `wrapSync` + +Take a sync function and make it async, passing its return value to a callback. This is useful for plugging sync functions into a waterfall, series, or other async functions. Any arguments passed to the generated function will be passed to the wrapped function (except for the final callback argument). Errors thrown will be passed to the callback. + +__Example__ + +```js +async.waterfall([ + async.apply(fs.readFile, filename, "utf8"), + async.asyncify(JSON.parse), + function (data, next) { + // data is the result of parsing the text. + // If there was a parsing error, it would have been caught. + } +], callback) +``` + +If the function passed to `asyncify` returns a Promise, that promises's resolved/rejected state will be used to call the callback, rather than simply the synchronous return value. Example: + +```js +async.waterfall([ + async.apply(fs.readFile, filename, "utf8"), + async.asyncify(function (contents) { + return db.model.create(contents); + }), + function (model, next) { + // `model` is the instantiated model object. + // If there was an error, this function would be skipped. + } +], callback) +``` + +This also means you can asyncify ES2016 `async` functions. + +```js +var q = async.queue(async.asyncify(async function (file) { + var intermediateStep = await processFile(file); + return await somePromise(intermediateStep) +})); + +q.push(files); +``` + +--------------------------------------- + + +### log(function, arguments) + +Logs the result of an `async` function to the `console`. Only works in Node.js or +in browsers that support `console.log` and `console.error` (such as FF and Chrome). +If multiple arguments are returned from the async function, `console.log` is +called on each argument in order. + +__Arguments__ + +* `function` - The function you want to eventually apply all arguments to. +* `arguments...` - Any number of arguments to apply to the function. + +__Example__ + +```js +var hello = function(name, callback){ + setTimeout(function(){ + callback(null, 'hello ' + name); + }, 1000); +}; +``` +```js +node> async.log(hello, 'world'); +'hello world' +``` + +--------------------------------------- + + +### dir(function, arguments) + +Logs the result of an `async` function to the `console` using `console.dir` to +display the properties of the resulting object. Only works in Node.js or +in browsers that support `console.dir` and `console.error` (such as FF and Chrome). +If multiple arguments are returned from the async function, `console.dir` is +called on each argument in order. + +__Arguments__ + +* `function` - The function you want to eventually apply all arguments to. +* `arguments...` - Any number of arguments to apply to the function. + +__Example__ + +```js +var hello = function(name, callback){ + setTimeout(function(){ + callback(null, {hello: name}); + }, 1000); +}; +``` +```js +node> async.dir(hello, 'world'); +{hello: 'world'} +``` + +--------------------------------------- + + +### noConflict() + +Changes the value of `async` back to its original value, returning a reference to the +`async` object. diff --git a/node_modules/grunt-sftp-deploy/node_modules/async/dist/async.js b/node_modules/grunt-sftp-deploy/node_modules/async/dist/async.js new file mode 100644 index 0000000..31e7620 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/async/dist/async.js @@ -0,0 +1,1265 @@ +/*! + * async + * https://github.com/caolan/async + * + * Copyright 2010-2014 Caolan McMahon + * Released under the MIT license + */ +(function () { + + var async = {}; + function noop() {} + function identity(v) { + return v; + } + function toBool(v) { + return !!v; + } + function notId(v) { + return !v; + } + + // global on the server, window in the browser + var previous_async; + + // Establish the root object, `window` (`self`) in the browser, `global` + // on the server, or `this` in some virtual machines. We use `self` + // instead of `window` for `WebWorker` support. + var root = typeof self === 'object' && self.self === self && self || + typeof global === 'object' && global.global === global && global || + this; + + if (root != null) { + previous_async = root.async; + } + + async.noConflict = function () { + root.async = previous_async; + return async; + }; + + function only_once(fn) { + return function() { + if (fn === null) throw new Error("Callback was already called."); + fn.apply(this, arguments); + fn = null; + }; + } + + function _once(fn) { + return function() { + if (fn === null) return; + fn.apply(this, arguments); + fn = null; + }; + } + + //// cross-browser compatiblity functions //// + + var _toString = Object.prototype.toString; + + var _isArray = Array.isArray || function (obj) { + return _toString.call(obj) === '[object Array]'; + }; + + // Ported from underscore.js isObject + var _isObject = function(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + }; + + function _isArrayLike(arr) { + return _isArray(arr) || ( + // has a positive integer length property + typeof arr.length === "number" && + arr.length >= 0 && + arr.length % 1 === 0 + ); + } + + function _arrayEach(arr, iterator) { + var index = -1, + length = arr.length; + + while (++index < length) { + iterator(arr[index], index, arr); + } + } + + function _map(arr, iterator) { + var index = -1, + length = arr.length, + result = Array(length); + + while (++index < length) { + result[index] = iterator(arr[index], index, arr); + } + return result; + } + + function _range(count) { + return _map(Array(count), function (v, i) { return i; }); + } + + function _reduce(arr, iterator, memo) { + _arrayEach(arr, function (x, i, a) { + memo = iterator(memo, x, i, a); + }); + return memo; + } + + function _forEachOf(object, iterator) { + _arrayEach(_keys(object), function (key) { + iterator(object[key], key); + }); + } + + function _indexOf(arr, item) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] === item) return i; + } + return -1; + } + + var _keys = Object.keys || function (obj) { + var keys = []; + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + keys.push(k); + } + } + return keys; + }; + + function _keyIterator(coll) { + var i = -1; + var len; + var keys; + if (_isArrayLike(coll)) { + len = coll.length; + return function next() { + i++; + return i < len ? i : null; + }; + } else { + keys = _keys(coll); + len = keys.length; + return function next() { + i++; + return i < len ? keys[i] : null; + }; + } + } + + // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html) + // This accumulates the arguments passed into an array, after a given index. + // From underscore.js (https://github.com/jashkenas/underscore/pull/2140). + function _restParam(func, startIndex) { + startIndex = startIndex == null ? func.length - 1 : +startIndex; + return function() { + var length = Math.max(arguments.length - startIndex, 0); + var rest = Array(length); + for (var index = 0; index < length; index++) { + rest[index] = arguments[index + startIndex]; + } + switch (startIndex) { + case 0: return func.call(this, rest); + case 1: return func.call(this, arguments[0], rest); + } + // Currently unused but handle cases outside of the switch statement: + // var args = Array(startIndex + 1); + // for (index = 0; index < startIndex; index++) { + // args[index] = arguments[index]; + // } + // args[startIndex] = rest; + // return func.apply(this, args); + }; + } + + function _withoutIndex(iterator) { + return function (value, index, callback) { + return iterator(value, callback); + }; + } + + //// exported async module functions //// + + //// nextTick implementation with browser-compatible fallback //// + + // capture the global reference to guard against fakeTimer mocks + var _setImmediate = typeof setImmediate === 'function' && setImmediate; + + var _delay = _setImmediate ? function(fn) { + // not a direct alias for IE10 compatibility + _setImmediate(fn); + } : function(fn) { + setTimeout(fn, 0); + }; + + if (typeof process === 'object' && typeof process.nextTick === 'function') { + async.nextTick = process.nextTick; + } else { + async.nextTick = _delay; + } + async.setImmediate = _setImmediate ? _delay : async.nextTick; + + + async.forEach = + async.each = function (arr, iterator, callback) { + return async.eachOf(arr, _withoutIndex(iterator), callback); + }; + + async.forEachSeries = + async.eachSeries = function (arr, iterator, callback) { + return async.eachOfSeries(arr, _withoutIndex(iterator), callback); + }; + + + async.forEachLimit = + async.eachLimit = function (arr, limit, iterator, callback) { + return _eachOfLimit(limit)(arr, _withoutIndex(iterator), callback); + }; + + async.forEachOf = + async.eachOf = function (object, iterator, callback) { + callback = _once(callback || noop); + object = object || []; + + var iter = _keyIterator(object); + var key, completed = 0; + + while ((key = iter()) != null) { + completed += 1; + iterator(object[key], key, only_once(done)); + } + + if (completed === 0) callback(null); + + function done(err) { + completed--; + if (err) { + callback(err); + } + // Check key is null in case iterator isn't exhausted + // and done resolved synchronously. + else if (key === null && completed <= 0) { + callback(null); + } + } + }; + + async.forEachOfSeries = + async.eachOfSeries = function (obj, iterator, callback) { + callback = _once(callback || noop); + obj = obj || []; + var nextKey = _keyIterator(obj); + var key = nextKey(); + function iterate() { + var sync = true; + if (key === null) { + return callback(null); + } + iterator(obj[key], key, only_once(function (err) { + if (err) { + callback(err); + } + else { + key = nextKey(); + if (key === null) { + return callback(null); + } else { + if (sync) { + async.setImmediate(iterate); + } else { + iterate(); + } + } + } + })); + sync = false; + } + iterate(); + }; + + + + async.forEachOfLimit = + async.eachOfLimit = function (obj, limit, iterator, callback) { + _eachOfLimit(limit)(obj, iterator, callback); + }; + + function _eachOfLimit(limit) { + + return function (obj, iterator, callback) { + callback = _once(callback || noop); + obj = obj || []; + var nextKey = _keyIterator(obj); + if (limit <= 0) { + return callback(null); + } + var done = false; + var running = 0; + var errored = false; + + (function replenish () { + if (done && running <= 0) { + return callback(null); + } + + while (running < limit && !errored) { + var key = nextKey(); + if (key === null) { + done = true; + if (running <= 0) { + callback(null); + } + return; + } + running += 1; + iterator(obj[key], key, only_once(function (err) { + running -= 1; + if (err) { + callback(err); + errored = true; + } + else { + replenish(); + } + })); + } + })(); + }; + } + + + function doParallel(fn) { + return function (obj, iterator, callback) { + return fn(async.eachOf, obj, iterator, callback); + }; + } + function doParallelLimit(fn) { + return function (obj, limit, iterator, callback) { + return fn(_eachOfLimit(limit), obj, iterator, callback); + }; + } + function doSeries(fn) { + return function (obj, iterator, callback) { + return fn(async.eachOfSeries, obj, iterator, callback); + }; + } + + function _asyncMap(eachfn, arr, iterator, callback) { + callback = _once(callback || noop); + arr = arr || []; + var results = _isArrayLike(arr) ? [] : {}; + eachfn(arr, function (value, index, callback) { + iterator(value, function (err, v) { + results[index] = v; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + + async.map = doParallel(_asyncMap); + async.mapSeries = doSeries(_asyncMap); + async.mapLimit = doParallelLimit(_asyncMap); + + // reduce only has a series version, as doing reduce in parallel won't + // work in many situations. + async.inject = + async.foldl = + async.reduce = function (arr, memo, iterator, callback) { + async.eachOfSeries(arr, function (x, i, callback) { + iterator(memo, x, function (err, v) { + memo = v; + callback(err); + }); + }, function (err) { + callback(err, memo); + }); + }; + + async.foldr = + async.reduceRight = function (arr, memo, iterator, callback) { + var reversed = _map(arr, identity).reverse(); + async.reduce(reversed, memo, iterator, callback); + }; + + async.transform = function (arr, memo, iterator, callback) { + if (arguments.length === 3) { + callback = iterator; + iterator = memo; + memo = _isArray(arr) ? [] : {}; + } + + async.eachOf(arr, function(v, k, cb) { + iterator(memo, v, k, cb); + }, function(err) { + callback(err, memo); + }); + }; + + function _filter(eachfn, arr, iterator, callback) { + var results = []; + eachfn(arr, function (x, index, callback) { + iterator(x, function (v) { + if (v) { + results.push({index: index, value: x}); + } + callback(); + }); + }, function () { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + } + + async.select = + async.filter = doParallel(_filter); + + async.selectLimit = + async.filterLimit = doParallelLimit(_filter); + + async.selectSeries = + async.filterSeries = doSeries(_filter); + + function _reject(eachfn, arr, iterator, callback) { + _filter(eachfn, arr, function(value, cb) { + iterator(value, function(v) { + cb(!v); + }); + }, callback); + } + async.reject = doParallel(_reject); + async.rejectLimit = doParallelLimit(_reject); + async.rejectSeries = doSeries(_reject); + + function _createTester(eachfn, check, getResult) { + return function(arr, limit, iterator, cb) { + function done() { + if (cb) cb(getResult(false, void 0)); + } + function iteratee(x, _, callback) { + if (!cb) return callback(); + iterator(x, function (v) { + if (cb && check(v)) { + cb(getResult(true, x)); + cb = iterator = false; + } + callback(); + }); + } + if (arguments.length > 3) { + eachfn(arr, limit, iteratee, done); + } else { + cb = iterator; + iterator = limit; + eachfn(arr, iteratee, done); + } + }; + } + + async.any = + async.some = _createTester(async.eachOf, toBool, identity); + + async.someLimit = _createTester(async.eachOfLimit, toBool, identity); + + async.all = + async.every = _createTester(async.eachOf, notId, notId); + + async.everyLimit = _createTester(async.eachOfLimit, notId, notId); + + function _findGetResult(v, x) { + return x; + } + async.detect = _createTester(async.eachOf, identity, _findGetResult); + async.detectSeries = _createTester(async.eachOfSeries, identity, _findGetResult); + async.detectLimit = _createTester(async.eachOfLimit, identity, _findGetResult); + + async.sortBy = function (arr, iterator, callback) { + async.map(arr, function (x, callback) { + iterator(x, function (err, criteria) { + if (err) { + callback(err); + } + else { + callback(null, {value: x, criteria: criteria}); + } + }); + }, function (err, results) { + if (err) { + return callback(err); + } + else { + callback(null, _map(results.sort(comparator), function (x) { + return x.value; + })); + } + + }); + + function comparator(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + } + }; + + async.auto = function (tasks, concurrency, callback) { + if (typeof arguments[1] === 'function') { + // concurrency is optional, shift the args. + callback = concurrency; + concurrency = null; + } + callback = _once(callback || noop); + var keys = _keys(tasks); + var remainingTasks = keys.length; + if (!remainingTasks) { + return callback(null); + } + if (!concurrency) { + concurrency = remainingTasks; + } + + var results = {}; + var runningTasks = 0; + + var hasError = false; + + var listeners = []; + function addListener(fn) { + listeners.unshift(fn); + } + function removeListener(fn) { + var idx = _indexOf(listeners, fn); + if (idx >= 0) listeners.splice(idx, 1); + } + function taskComplete() { + remainingTasks--; + _arrayEach(listeners.slice(0), function (fn) { + fn(); + }); + } + + addListener(function () { + if (!remainingTasks) { + callback(null, results); + } + }); + + _arrayEach(keys, function (k) { + if (hasError) return; + var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]]; + var taskCallback = _restParam(function(err, args) { + runningTasks--; + if (args.length <= 1) { + args = args[0]; + } + if (err) { + var safeResults = {}; + _forEachOf(results, function(val, rkey) { + safeResults[rkey] = val; + }); + safeResults[k] = args; + hasError = true; + + callback(err, safeResults); + } + else { + results[k] = args; + async.setImmediate(taskComplete); + } + }); + var requires = task.slice(0, task.length - 1); + // prevent dead-locks + var len = requires.length; + var dep; + while (len--) { + if (!(dep = tasks[requires[len]])) { + throw new Error('Has nonexistent dependency in ' + requires.join(', ')); + } + if (_isArray(dep) && _indexOf(dep, k) >= 0) { + throw new Error('Has cyclic dependencies'); + } + } + function ready() { + return runningTasks < concurrency && _reduce(requires, function (a, x) { + return (a && results.hasOwnProperty(x)); + }, true) && !results.hasOwnProperty(k); + } + if (ready()) { + runningTasks++; + task[task.length - 1](taskCallback, results); + } + else { + addListener(listener); + } + function listener() { + if (ready()) { + runningTasks++; + removeListener(listener); + task[task.length - 1](taskCallback, results); + } + } + }); + }; + + + + async.retry = function(times, task, callback) { + var DEFAULT_TIMES = 5; + var DEFAULT_INTERVAL = 0; + + var attempts = []; + + var opts = { + times: DEFAULT_TIMES, + interval: DEFAULT_INTERVAL + }; + + function parseTimes(acc, t){ + if(typeof t === 'number'){ + acc.times = parseInt(t, 10) || DEFAULT_TIMES; + } else if(typeof t === 'object'){ + acc.times = parseInt(t.times, 10) || DEFAULT_TIMES; + acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL; + } else { + throw new Error('Unsupported argument type for \'times\': ' + typeof t); + } + } + + var length = arguments.length; + if (length < 1 || length > 3) { + throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)'); + } else if (length <= 2 && typeof times === 'function') { + callback = task; + task = times; + } + if (typeof times !== 'function') { + parseTimes(opts, times); + } + opts.callback = callback; + opts.task = task; + + function wrappedTask(wrappedCallback, wrappedResults) { + function retryAttempt(task, finalAttempt) { + return function(seriesCallback) { + task(function(err, result){ + seriesCallback(!err || finalAttempt, {err: err, result: result}); + }, wrappedResults); + }; + } + + function retryInterval(interval){ + return function(seriesCallback){ + setTimeout(function(){ + seriesCallback(null); + }, interval); + }; + } + + while (opts.times) { + + var finalAttempt = !(opts.times-=1); + attempts.push(retryAttempt(opts.task, finalAttempt)); + if(!finalAttempt && opts.interval > 0){ + attempts.push(retryInterval(opts.interval)); + } + } + + async.series(attempts, function(done, data){ + data = data[data.length - 1]; + (wrappedCallback || opts.callback)(data.err, data.result); + }); + } + + // If a callback is passed, run this as a controll flow + return opts.callback ? wrappedTask() : wrappedTask; + }; + + async.waterfall = function (tasks, callback) { + callback = _once(callback || noop); + if (!_isArray(tasks)) { + var err = new Error('First argument to waterfall must be an array of functions'); + return callback(err); + } + if (!tasks.length) { + return callback(); + } + function wrapIterator(iterator) { + return _restParam(function (err, args) { + if (err) { + callback.apply(null, [err].concat(args)); + } + else { + var next = iterator.next(); + if (next) { + args.push(wrapIterator(next)); + } + else { + args.push(callback); + } + ensureAsync(iterator).apply(null, args); + } + }); + } + wrapIterator(async.iterator(tasks))(); + }; + + function _parallel(eachfn, tasks, callback) { + callback = callback || noop; + var results = _isArrayLike(tasks) ? [] : {}; + + eachfn(tasks, function (task, key, callback) { + task(_restParam(function (err, args) { + if (args.length <= 1) { + args = args[0]; + } + results[key] = args; + callback(err); + })); + }, function (err) { + callback(err, results); + }); + } + + async.parallel = function (tasks, callback) { + _parallel(async.eachOf, tasks, callback); + }; + + async.parallelLimit = function(tasks, limit, callback) { + _parallel(_eachOfLimit(limit), tasks, callback); + }; + + async.series = function(tasks, callback) { + _parallel(async.eachOfSeries, tasks, callback); + }; + + async.iterator = function (tasks) { + function makeCallback(index) { + function fn() { + if (tasks.length) { + tasks[index].apply(null, arguments); + } + return fn.next(); + } + fn.next = function () { + return (index < tasks.length - 1) ? makeCallback(index + 1): null; + }; + return fn; + } + return makeCallback(0); + }; + + async.apply = _restParam(function (fn, args) { + return _restParam(function (callArgs) { + return fn.apply( + null, args.concat(callArgs) + ); + }); + }); + + function _concat(eachfn, arr, fn, callback) { + var result = []; + eachfn(arr, function (x, index, cb) { + fn(x, function (err, y) { + result = result.concat(y || []); + cb(err); + }); + }, function (err) { + callback(err, result); + }); + } + async.concat = doParallel(_concat); + async.concatSeries = doSeries(_concat); + + async.whilst = function (test, iterator, callback) { + callback = callback || noop; + if (test()) { + var next = _restParam(function(err, args) { + if (err) { + callback(err); + } else if (test.apply(this, args)) { + iterator(next); + } else { + callback.apply(null, [null].concat(args)); + } + }); + iterator(next); + } else { + callback(null); + } + }; + + async.doWhilst = function (iterator, test, callback) { + var calls = 0; + return async.whilst(function() { + return ++calls <= 1 || test.apply(this, arguments); + }, iterator, callback); + }; + + async.until = function (test, iterator, callback) { + return async.whilst(function() { + return !test.apply(this, arguments); + }, iterator, callback); + }; + + async.doUntil = function (iterator, test, callback) { + return async.doWhilst(iterator, function() { + return !test.apply(this, arguments); + }, callback); + }; + + async.during = function (test, iterator, callback) { + callback = callback || noop; + + var next = _restParam(function(err, args) { + if (err) { + callback(err); + } else { + args.push(check); + test.apply(this, args); + } + }); + + var check = function(err, truth) { + if (err) { + callback(err); + } else if (truth) { + iterator(next); + } else { + callback(null); + } + }; + + test(check); + }; + + async.doDuring = function (iterator, test, callback) { + var calls = 0; + async.during(function(next) { + if (calls++ < 1) { + next(null, true); + } else { + test.apply(this, arguments); + } + }, iterator, callback); + }; + + function _queue(worker, concurrency, payload) { + if (concurrency == null) { + concurrency = 1; + } + else if(concurrency === 0) { + throw new Error('Concurrency must not be zero'); + } + function _insert(q, data, pos, callback) { + if (callback != null && typeof callback !== "function") { + throw new Error("task callback must be a function"); + } + q.started = true; + if (!_isArray(data)) { + data = [data]; + } + if(data.length === 0 && q.idle()) { + // call drain immediately if there are no tasks + return async.setImmediate(function() { + q.drain(); + }); + } + _arrayEach(data, function(task) { + var item = { + data: task, + callback: callback || noop + }; + + if (pos) { + q.tasks.unshift(item); + } else { + q.tasks.push(item); + } + + if (q.tasks.length === q.concurrency) { + q.saturated(); + } + }); + async.setImmediate(q.process); + } + function _next(q, tasks) { + return function(){ + workers -= 1; + + var removed = false; + var args = arguments; + _arrayEach(tasks, function (task) { + _arrayEach(workersList, function (worker, index) { + if (worker === task && !removed) { + workersList.splice(index, 1); + removed = true; + } + }); + + task.callback.apply(task, args); + }); + if (q.tasks.length + workers === 0) { + q.drain(); + } + q.process(); + }; + } + + var workers = 0; + var workersList = []; + var q = { + tasks: [], + concurrency: concurrency, + payload: payload, + saturated: noop, + empty: noop, + drain: noop, + started: false, + paused: false, + push: function (data, callback) { + _insert(q, data, false, callback); + }, + kill: function () { + q.drain = noop; + q.tasks = []; + }, + unshift: function (data, callback) { + _insert(q, data, true, callback); + }, + process: function () { + while(!q.paused && workers < q.concurrency && q.tasks.length){ + + var tasks = q.payload ? + q.tasks.splice(0, q.payload) : + q.tasks.splice(0, q.tasks.length); + + var data = _map(tasks, function (task) { + return task.data; + }); + + if (q.tasks.length === 0) { + q.empty(); + } + workers += 1; + workersList.push(tasks[0]); + var cb = only_once(_next(q, tasks)); + worker(data, cb); + } + }, + length: function () { + return q.tasks.length; + }, + running: function () { + return workers; + }, + workersList: function () { + return workersList; + }, + idle: function() { + return q.tasks.length + workers === 0; + }, + pause: function () { + q.paused = true; + }, + resume: function () { + if (q.paused === false) { return; } + q.paused = false; + var resumeCount = Math.min(q.concurrency, q.tasks.length); + // Need to call q.process once per concurrent + // worker to preserve full concurrency after pause + for (var w = 1; w <= resumeCount; w++) { + async.setImmediate(q.process); + } + } + }; + return q; + } + + async.queue = function (worker, concurrency) { + var q = _queue(function (items, cb) { + worker(items[0], cb); + }, concurrency, 1); + + return q; + }; + + async.priorityQueue = function (worker, concurrency) { + + function _compareTasks(a, b){ + return a.priority - b.priority; + } + + function _binarySearch(sequence, item, compare) { + var beg = -1, + end = sequence.length - 1; + while (beg < end) { + var mid = beg + ((end - beg + 1) >>> 1); + if (compare(item, sequence[mid]) >= 0) { + beg = mid; + } else { + end = mid - 1; + } + } + return beg; + } + + function _insert(q, data, priority, callback) { + if (callback != null && typeof callback !== "function") { + throw new Error("task callback must be a function"); + } + q.started = true; + if (!_isArray(data)) { + data = [data]; + } + if(data.length === 0) { + // call drain immediately if there are no tasks + return async.setImmediate(function() { + q.drain(); + }); + } + _arrayEach(data, function(task) { + var item = { + data: task, + priority: priority, + callback: typeof callback === 'function' ? callback : noop + }; + + q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item); + + if (q.tasks.length === q.concurrency) { + q.saturated(); + } + async.setImmediate(q.process); + }); + } + + // Start with a normal queue + var q = async.queue(worker, concurrency); + + // Override push to accept second parameter representing priority + q.push = function (data, priority, callback) { + _insert(q, data, priority, callback); + }; + + // Remove unshift function + delete q.unshift; + + return q; + }; + + async.cargo = function (worker, payload) { + return _queue(worker, 1, payload); + }; + + function _console_fn(name) { + return _restParam(function (fn, args) { + fn.apply(null, args.concat([_restParam(function (err, args) { + if (typeof console === 'object') { + if (err) { + if (console.error) { + console.error(err); + } + } + else if (console[name]) { + _arrayEach(args, function (x) { + console[name](x); + }); + } + } + })])); + }); + } + async.log = _console_fn('log'); + async.dir = _console_fn('dir'); + /*async.info = _console_fn('info'); + async.warn = _console_fn('warn'); + async.error = _console_fn('error');*/ + + async.memoize = function (fn, hasher) { + var memo = {}; + var queues = {}; + var has = Object.prototype.hasOwnProperty; + hasher = hasher || identity; + var memoized = _restParam(function memoized(args) { + var callback = args.pop(); + var key = hasher.apply(null, args); + if (has.call(memo, key)) { + async.setImmediate(function () { + callback.apply(null, memo[key]); + }); + } + else if (has.call(queues, key)) { + queues[key].push(callback); + } + else { + queues[key] = [callback]; + fn.apply(null, args.concat([_restParam(function (args) { + memo[key] = args; + var q = queues[key]; + delete queues[key]; + for (var i = 0, l = q.length; i < l; i++) { + q[i].apply(null, args); + } + })])); + } + }); + memoized.memo = memo; + memoized.unmemoized = fn; + return memoized; + }; + + async.unmemoize = function (fn) { + return function () { + return (fn.unmemoized || fn).apply(null, arguments); + }; + }; + + function _times(mapper) { + return function (count, iterator, callback) { + mapper(_range(count), iterator, callback); + }; + } + + async.times = _times(async.map); + async.timesSeries = _times(async.mapSeries); + async.timesLimit = function (count, limit, iterator, callback) { + return async.mapLimit(_range(count), limit, iterator, callback); + }; + + async.seq = function (/* functions... */) { + var fns = arguments; + return _restParam(function (args) { + var that = this; + + var callback = args[args.length - 1]; + if (typeof callback == 'function') { + args.pop(); + } else { + callback = noop; + } + + async.reduce(fns, args, function (newargs, fn, cb) { + fn.apply(that, newargs.concat([_restParam(function (err, nextargs) { + cb(err, nextargs); + })])); + }, + function (err, results) { + callback.apply(that, [err].concat(results)); + }); + }); + }; + + async.compose = function (/* functions... */) { + return async.seq.apply(null, Array.prototype.reverse.call(arguments)); + }; + + + function _applyEach(eachfn) { + return _restParam(function(fns, args) { + var go = _restParam(function(args) { + var that = this; + var callback = args.pop(); + return eachfn(fns, function (fn, _, cb) { + fn.apply(that, args.concat([cb])); + }, + callback); + }); + if (args.length) { + return go.apply(this, args); + } + else { + return go; + } + }); + } + + async.applyEach = _applyEach(async.eachOf); + async.applyEachSeries = _applyEach(async.eachOfSeries); + + + async.forever = function (fn, callback) { + var done = only_once(callback || noop); + var task = ensureAsync(fn); + function next(err) { + if (err) { + return done(err); + } + task(next); + } + next(); + }; + + function ensureAsync(fn) { + return _restParam(function (args) { + var callback = args.pop(); + args.push(function () { + var innerArgs = arguments; + if (sync) { + async.setImmediate(function () { + callback.apply(null, innerArgs); + }); + } else { + callback.apply(null, innerArgs); + } + }); + var sync = true; + fn.apply(this, args); + sync = false; + }); + } + + async.ensureAsync = ensureAsync; + + async.constant = _restParam(function(values) { + var args = [null].concat(values); + return function (callback) { + return callback.apply(this, args); + }; + }); + + async.wrapSync = + async.asyncify = function asyncify(func) { + return _restParam(function (args) { + var callback = args.pop(); + var result; + try { + result = func.apply(this, args); + } catch (e) { + return callback(e); + } + // if result is Promise object + if (_isObject(result) && typeof result.then === "function") { + result.then(function(value) { + callback(null, value); + })["catch"](function(err) { + callback(err.message ? err : new Error(err)); + }); + } else { + callback(null, result); + } + }); + }; + + // Node.js + if (typeof module === 'object' && module.exports) { + module.exports = async; + } + // AMD / RequireJS + else if (typeof define === 'function' && define.amd) { + define([], function () { + return async; + }); + } + // included directly via + + +``` + +Browser support was done mostly for online demo. If you find any errors - feel +free to send pull requests with fixes. Also note, that IE and other old browsers +needs [es5-shims](https://github.com/kriskowal/es5-shim) to operate. + +Notes: + +1. We have no resources to support browserified version. Don't expect it to be + well tested. Don't expect fast fixes if something goes wrong there. +2. `!!js/function` in browser bundle will not work by default. If you really need + it - load `esprima` parser first (via amd or directly). +3. `!!bin` in browser will return `Array`, because browsers do not support + node.js `Buffer` and adding Buffer shims is completely useless on practice. + + +API +--- + +Here we cover the most 'useful' methods. If you need advanced details (creating +your own tags), see [wiki](https://github.com/nodeca/js-yaml/wiki) and +[examples](https://github.com/nodeca/js-yaml/tree/master/examples) for more +info. + +``` javascript +yaml = require('js-yaml'); +fs = require('fs'); + +// Get document, or throw exception on error +try { + var doc = yaml.safeLoad(fs.readFileSync('/home/ixti/example.yml', 'utf8')); + console.log(doc); +} catch (e) { + console.log(e); +} +``` + + +### safeLoad (string [ , options ]) + +**Recommended loading way.** Parses `string` as single YAML document. Returns a JavaScript +object or throws `YAMLException` on error. By default, does not support regexps, +functions and undefined. This method is safe for untrusted data. + +options: + +- `filename` _(default: null)_ - string to be used as a file path in + error/warning messages. +- `onWarning` _(default: null)_ - function to call on warning messages. + Loader will throw on warnings if this function is not provided. +- `schema` _(default: `DEFAULT_SAFE_SCHEMA`)_ - specifies a schema to use. + - `FAILSAFE_SCHEMA` - only strings, arrays and plain objects: + http://www.yaml.org/spec/1.2/spec.html#id2802346 + - `JSON_SCHEMA` - all JSON-supported types: + http://www.yaml.org/spec/1.2/spec.html#id2803231 + - `CORE_SCHEMA` - same as `JSON_SCHEMA`: + http://www.yaml.org/spec/1.2/spec.html#id2804923 + - `DEFAULT_SAFE_SCHEMA` - all supported YAML types, without unsafe ones + (`!!js/undefined`, `!!js/regexp` and `!!js/function`): + http://yaml.org/type/ + - `DEFAULT_FULL_SCHEMA` - all supported YAML types. +- `json` _(default: false)_ - compatibility with JSON.parse behaviour. If true, then duplicate keys in a mapping will override values rather than throwing an error. + +NOTE: This function **does not** understand multi-document sources, it throws +exception on those. + +NOTE: JS-YAML **does not** support schema-specific tag resolution restrictions. +So, JSON schema is not as strict as defined in the YAML specification. +It allows numbers in any notation, use `Null` and `NULL` as `null`, etc. +Core schema also has no such restrictions. It allows binary notation for integers. + + +### load (string [ , options ]) + +**Use with care with untrusted sources**. The same as `safeLoad()` but uses +`DEFAULT_FULL_SCHEMA` by default - adds some JavaScript-specific types: +`!!js/function`, `!!js/regexp` and `!!js/undefined`. For untrusted sources you +must additionally validate object structure, to avoid injections: + +``` javascript +var untrusted_code = '"toString": ! "function (){very_evil_thing();}"'; + +// I'm just converting that string, what could possibly go wrong? +require('js-yaml').load(untrusted_code) + '' +``` + + +### safeLoadAll (string, iterator [ , options ]) + +Same as `safeLoad()`, but understands multi-document sources and apply +`iterator` to each document. + +``` javascript +var yaml = require('js-yaml'); + +yaml.safeLoadAll(data, function (doc) { + console.log(doc); +}); +``` + + +### loadAll (string, iterator [ , options ]) + +Same as `safeLoadAll()` but uses `DEFAULT_FULL_SCHEMA` by default. + + +### safeDump (object [ , options ]) + +Serializes `object` as YAML document. Uses `DEFAULT_SAFE_SCHEMA`, so it will +throw exception if you try to dump regexps or functions. However, you can +disable exceptions by `skipInvalid` option. + +options: + +- `indent` _(default: 2)_ - indentation width to use (in spaces). +- `skipInvalid` _(default: false)_ - do not throw on invalid types (like function + in the safe schema) and skip pairs and single values with such types. +- `flowLevel` (default: -1) - specifies level of nesting, when to switch from + block to flow style for collections. -1 means block style everwhere +- `styles` - "tag" => "style" map. Each tag may have own set of styles. +- `schema` _(default: `DEFAULT_SAFE_SCHEMA`)_ specifies a schema to use. +- `sortKeys` _(default: `false`)_ - if `true`, sort keys when dumping YAML. If a + function, use the function to sort the keys. +- `lineWidth` _(default: `80`)_ - set max line width. +- `noRefs` _(default: `false`)_ - if `true`, don't convert duplicate objects into references +- `noCompatMode` _(default: `false`)_ - if `true` don't try to be compatible with older + yaml versions. Currently: don't quote "yes", "no" and so on, as required for YAML 1.1 + +styles: + +``` none +!!null + "canonical" => "~" + +!!int + "binary" => "0b1", "0b101010", "0b1110001111010" + "octal" => "01", "052", "016172" + "decimal" => "1", "42", "7290" + "hexadecimal" => "0x1", "0x2A", "0x1C7A" + +!!null, !!bool, !!float + "lowercase" => "null", "true", "false", ".nan", '.inf' + "uppercase" => "NULL", "TRUE", "FALSE", ".NAN", '.INF' + "camelcase" => "Null", "True", "False", ".NaN", '.Inf' +``` + +By default, !!int uses `decimal`, and !!null, !!bool, !!float use `lowercase`. + + + +### dump (object [ , options ]) + +Same as `safeDump()` but without limits (uses `DEFAULT_FULL_SCHEMA` by default). + + +Supported YAML types +-------------------- + +The list of standard YAML tags and corresponding JavaScipt types. See also +[YAML tag discussion](http://pyyaml.org/wiki/YAMLTagDiscussion) and +[YAML types repository](http://yaml.org/type/). + +``` +!!null '' # null +!!bool 'yes' # bool +!!int '3...' # number +!!float '3.14...' # number +!!binary '...base64...' # buffer +!!timestamp 'YYYY-...' # date +!!omap [ ... ] # array of key-value pairs +!!pairs [ ... ] # array or array pairs +!!set { ... } # array of objects with given keys and null values +!!str '...' # string +!!seq [ ... ] # array +!!map { ... } # object +``` + +**JavaScript-specific tags** + +``` +!!js/regexp /pattern/gim # RegExp +!!js/undefined '' # Undefined +!!js/function 'function () {...}' # Function +``` + +Caveats +------- + +Note, that you use arrays or objects as key in JS-YAML. JS does not allow objects +or array as keys, and stringifies (by calling .toString method) them at the +moment of adding them. + +``` yaml +--- +? [ foo, bar ] +: - baz +? { foo: bar } +: - baz + - baz +``` + +``` javascript +{ "foo,bar": ["baz"], "[object Object]": ["baz", "baz"] } +``` + +Also, reading of properties on implicit block mapping keys is not supported yet. +So, the following YAML document cannot be loaded. + +``` yaml +&anchor foo: + foo: bar + *anchor: duplicate key + baz: bat + *anchor: duplicate key +``` + + +Breaking changes in 2.x.x -> 3.x.x +---------------------------------- + +If you have not used __custom__ tags or loader classes and not loaded yaml +files via `require()` - no changes needed. Just upgrade library. + +Otherwise, you should: + +1. Replace all occurences of `require('xxxx.yml')` by `fs.readFileSync()` + + `yaml.safeLoad()`. +2. rewrite your custom tags constructors and custom loader + classes, to conform new API. See + [examples](https://github.com/nodeca/js-yaml/tree/master/examples) and + [wiki](https://github.com/nodeca/js-yaml/wiki) for details. + + +License +------- + +View the [LICENSE](https://github.com/nodeca/js-yaml/blob/master/LICENSE) file +(MIT). diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/bin/js-yaml.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/bin/js-yaml.js new file mode 100644 index 0000000..5e32400 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/bin/js-yaml.js @@ -0,0 +1,134 @@ +#!/usr/bin/env node + + +'use strict'; + +/*eslint-disable no-console*/ + + +// stdlib +var fs = require('fs'); + + +// 3rd-party +var argparse = require('argparse'); + + +// internal +var yaml = require('..'); + + +//////////////////////////////////////////////////////////////////////////////// + + +var cli = new argparse.ArgumentParser({ + prog: 'js-yaml', + version: require('../package.json').version, + addHelp: true +}); + + +cli.addArgument([ '-c', '--compact' ], { + help: 'Display errors in compact mode', + action: 'storeTrue' +}); + + +// deprecated (not needed after we removed output colors) +// option suppressed, but not completely removed for compatibility +cli.addArgument([ '-j', '--to-json' ], { + help: argparse.Const.SUPPRESS, + dest: 'json', + action: 'storeTrue' +}); + + +cli.addArgument([ '-t', '--trace' ], { + help: 'Show stack trace on error', + action: 'storeTrue' +}); + +cli.addArgument([ 'file' ], { + help: 'File to read, utf-8 encoded without BOM', + nargs: '?', + defaultValue: '-' +}); + + +//////////////////////////////////////////////////////////////////////////////// + + +var options = cli.parseArgs(); + + +//////////////////////////////////////////////////////////////////////////////// + +function readFile(filename, encoding, callback) { + if (options.file === '-') { + // read from stdin + + var chunks = []; + + process.stdin.on('data', function (chunk) { + chunks.push(chunk); + }); + + process.stdin.on('end', function () { + return callback(null, Buffer.concat(chunks).toString(encoding)); + }); + } else { + fs.readFile(filename, encoding, callback); + } +} + +readFile(options.file, 'utf8', function (error, input) { + var output, isYaml; + + if (error) { + if (error.code === 'ENOENT') { + console.error('File not found: ' + options.file); + process.exit(2); + } + + console.error( + options.trace && error.stack || + error.message || + String(error)); + + process.exit(1); + } + + try { + output = JSON.parse(input); + isYaml = false; + } catch (err) { + if (err instanceof SyntaxError) { + try { + output = []; + yaml.loadAll(input, function (doc) { output.push(doc); }, {}); + isYaml = true; + + if (output.length === 0) output = null; + else if (output.length === 1) output = output[0]; + + } catch (e) { + if (options.trace && err.stack) console.error(e.stack); + else console.error(e.toString(options.compact)); + + process.exit(1); + } + } else { + console.error( + options.trace && err.stack || + err.message || + String(err)); + + process.exit(1); + } + } + + if (isYaml) console.log(JSON.stringify(output, null, ' ')); + else console.log(yaml.dump(output)); + + process.exit(0); +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/dist/js-yaml.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/dist/js-yaml.js new file mode 100644 index 0000000..5f20e9b --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/dist/js-yaml.js @@ -0,0 +1,3858 @@ +/* js-yaml 3.5.5 https://github.com/nodeca/js-yaml */(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.jsyaml = 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 */ +var CHAR_QUESTION = 0x3F; /* ? */ +var CHAR_COMMERCIAL_AT = 0x40; /* @ */ +var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ +var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ +var CHAR_GRAVE_ACCENT = 0x60; /* ` */ +var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ +var CHAR_VERTICAL_LINE = 0x7C; /* | */ +var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ + +var ESCAPE_SEQUENCES = {}; + +ESCAPE_SEQUENCES[0x00] = '\\0'; +ESCAPE_SEQUENCES[0x07] = '\\a'; +ESCAPE_SEQUENCES[0x08] = '\\b'; +ESCAPE_SEQUENCES[0x09] = '\\t'; +ESCAPE_SEQUENCES[0x0A] = '\\n'; +ESCAPE_SEQUENCES[0x0B] = '\\v'; +ESCAPE_SEQUENCES[0x0C] = '\\f'; +ESCAPE_SEQUENCES[0x0D] = '\\r'; +ESCAPE_SEQUENCES[0x1B] = '\\e'; +ESCAPE_SEQUENCES[0x22] = '\\"'; +ESCAPE_SEQUENCES[0x5C] = '\\\\'; +ESCAPE_SEQUENCES[0x85] = '\\N'; +ESCAPE_SEQUENCES[0xA0] = '\\_'; +ESCAPE_SEQUENCES[0x2028] = '\\L'; +ESCAPE_SEQUENCES[0x2029] = '\\P'; + +var DEPRECATED_BOOLEANS_SYNTAX = [ + 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON', + 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF' +]; + +function compileStyleMap(schema, map) { + var result, keys, index, length, tag, style, type; + + if (map === null) return {}; + + result = {}; + keys = Object.keys(map); + + for (index = 0, length = keys.length; index < length; index += 1) { + tag = keys[index]; + style = String(map[tag]); + + if (tag.slice(0, 2) === '!!') { + tag = 'tag:yaml.org,2002:' + tag.slice(2); + } + + type = schema.compiledTypeMap[tag]; + + if (type && _hasOwnProperty.call(type.styleAliases, style)) { + style = type.styleAliases[style]; + } + + result[tag] = style; + } + + return result; +} + +function encodeHex(character) { + var string, handle, length; + + string = character.toString(16).toUpperCase(); + + if (character <= 0xFF) { + handle = 'x'; + length = 2; + } else if (character <= 0xFFFF) { + handle = 'u'; + length = 4; + } else if (character <= 0xFFFFFFFF) { + handle = 'U'; + length = 8; + } else { + throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF'); + } + + return '\\' + handle + common.repeat('0', length - string.length) + string; +} + +function State(options) { + this.schema = options['schema'] || DEFAULT_FULL_SCHEMA; + this.indent = Math.max(1, (options['indent'] || 2)); + this.skipInvalid = options['skipInvalid'] || false; + this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']); + this.styleMap = compileStyleMap(this.schema, options['styles'] || null); + this.sortKeys = options['sortKeys'] || false; + this.lineWidth = options['lineWidth'] || 80; + this.noRefs = options['noRefs'] || false; + this.noCompatMode = options['noCompatMode'] || false; + + this.implicitTypes = this.schema.compiledImplicit; + this.explicitTypes = this.schema.compiledExplicit; + + this.tag = null; + this.result = ''; + + this.duplicates = []; + this.usedDuplicates = null; +} + +function indentString(string, spaces) { + var ind = common.repeat(' ', spaces), + position = 0, + next = -1, + result = '', + line, + length = string.length; + + while (position < length) { + next = string.indexOf('\n', position); + if (next === -1) { + line = string.slice(position); + position = length; + } else { + line = string.slice(position, next + 1); + position = next + 1; + } + + if (line.length && line !== '\n') result += ind; + + result += line; + } + + return result; +} + +function generateNextLine(state, level) { + return '\n' + common.repeat(' ', state.indent * level); +} + +function testImplicitResolving(state, str) { + var index, length, type; + + for (index = 0, length = state.implicitTypes.length; index < length; index += 1) { + type = state.implicitTypes[index]; + + if (type.resolve(str)) { + return true; + } + } + + return false; +} + +function StringBuilder(source) { + this.source = source; + this.result = ''; + this.checkpoint = 0; +} + +StringBuilder.prototype.takeUpTo = function (position) { + var er; + + if (position < this.checkpoint) { + er = new Error('position should be > checkpoint'); + er.position = position; + er.checkpoint = this.checkpoint; + throw er; + } + + this.result += this.source.slice(this.checkpoint, position); + this.checkpoint = position; + return this; +}; + +StringBuilder.prototype.escapeChar = function () { + var character, esc; + + character = this.source.charCodeAt(this.checkpoint); + esc = ESCAPE_SEQUENCES[character] || encodeHex(character); + this.result += esc; + this.checkpoint += 1; + + return this; +}; + +StringBuilder.prototype.finish = function () { + if (this.source.length > this.checkpoint) { + this.takeUpTo(this.source.length); + } +}; + +function writeScalar(state, object, level, iskey) { + var simple, first, spaceWrap, folded, literal, single, double, + sawLineFeed, linePosition, longestLine, indent, max, character, + position, escapeSeq, hexEsc, previous, lineLength, modifier, + trailingLineBreaks, result; + + if (object.length === 0) { + state.dump = "''"; + return; + } + + if (!state.noCompatMode && + DEPRECATED_BOOLEANS_SYNTAX.indexOf(object) !== -1) { + state.dump = "'" + object + "'"; + return; + } + + simple = true; + first = object.length ? object.charCodeAt(0) : 0; + spaceWrap = (CHAR_SPACE === first || + CHAR_SPACE === object.charCodeAt(object.length - 1)); + + // Simplified check for restricted first characters + // http://www.yaml.org/spec/1.2/spec.html#ns-plain-first%28c%29 + if (CHAR_MINUS === first || + CHAR_QUESTION === first || + CHAR_COMMERCIAL_AT === first || + CHAR_GRAVE_ACCENT === first) { + simple = false; + } + + // Can only use > and | if not wrapped in spaces or is not a key. + // Also, don't use if in flow mode. + if (spaceWrap || (state.flowLevel > -1 && state.flowLevel <= level)) { + if (spaceWrap) simple = false; + + folded = false; + literal = false; + } else { + folded = !iskey; + literal = !iskey; + } + + single = true; + double = new StringBuilder(object); + + sawLineFeed = false; + linePosition = 0; + longestLine = 0; + + indent = state.indent * level; + max = state.lineWidth; + + // Replace -1 with biggest ingeger number according to + // http://ecma262-5.com/ELS5_HTML.htm#Section_8.5 + if (max === -1) max = 9007199254740991; + + if (indent < 40) max -= indent; + else max = 40; + + for (position = 0; position < object.length; position++) { + character = object.charCodeAt(position); + if (simple) { + // Characters that can never appear in the simple scalar + if (!simpleChar(character)) { + simple = false; + } else { + // Still simple. If we make it all the way through like + // this, then we can just dump the string as-is. + continue; + } + } + + if (single && character === CHAR_SINGLE_QUOTE) { + single = false; + } + + escapeSeq = ESCAPE_SEQUENCES[character]; + hexEsc = needsHexEscape(character); + + if (!escapeSeq && !hexEsc) { + continue; + } + + if (character !== CHAR_LINE_FEED && + character !== CHAR_DOUBLE_QUOTE && + character !== CHAR_SINGLE_QUOTE) { + folded = false; + literal = false; + } else if (character === CHAR_LINE_FEED) { + sawLineFeed = true; + single = false; + if (position > 0) { + previous = object.charCodeAt(position - 1); + if (previous === CHAR_SPACE) { + literal = false; + folded = false; + } + } + if (folded) { + lineLength = position - linePosition; + linePosition = position; + if (lineLength > longestLine) longestLine = lineLength; + } + } + + if (character !== CHAR_DOUBLE_QUOTE) single = false; + + double.takeUpTo(position); + double.escapeChar(); + } + + if (simple && testImplicitResolving(state, object)) simple = false; + + modifier = ''; + if (folded || literal) { + trailingLineBreaks = 0; + if (object.charCodeAt(object.length - 1) === CHAR_LINE_FEED) { + trailingLineBreaks += 1; + if (object.charCodeAt(object.length - 2) === CHAR_LINE_FEED) { + trailingLineBreaks += 1; + } + } + + if (trailingLineBreaks === 0) modifier = '-'; + else if (trailingLineBreaks === 2) modifier = '+'; + } + + if (literal && longestLine < max || state.tag !== null) { + folded = false; + } + + // If it's literally one line, then don't bother with the literal. + // We may still want to do a fold, though, if it's a super long line. + if (!sawLineFeed) literal = false; + + if (simple) { + state.dump = object; + } else if (single) { + state.dump = '\'' + object + '\''; + } else if (folded) { + result = fold(object, max); + state.dump = '>' + modifier + '\n' + indentString(result, indent); + } else if (literal) { + if (!modifier) object = object.replace(/\n$/, ''); + state.dump = '|' + modifier + '\n' + indentString(object, indent); + } else if (double) { + double.finish(); + state.dump = '"' + double.result + '"'; + } else { + throw new Error('Failed to dump scalar value'); + } + + return; +} + +// The `trailing` var is a regexp match of any trailing `\n` characters. +// +// There are three cases we care about: +// +// 1. One trailing `\n` on the string. Just use `|` or `>`. +// This is the assumed default. (trailing = null) +// 2. No trailing `\n` on the string. Use `|-` or `>-` to "chomp" the end. +// 3. More than one trailing `\n` on the string. Use `|+` or `>+`. +// +// In the case of `>+`, these line breaks are *not* doubled (like the line +// breaks within the string), so it's important to only end with the exact +// same number as we started. +function fold(object, max) { + var result = '', + position = 0, + length = object.length, + trailing = /\n+$/.exec(object), + newLine; + + if (trailing) { + length = trailing.index + 1; + } + + while (position < length) { + newLine = object.indexOf('\n', position); + if (newLine > length || newLine === -1) { + if (result) result += '\n\n'; + result += foldLine(object.slice(position, length), max); + position = length; + + } else { + if (result) result += '\n\n'; + result += foldLine(object.slice(position, newLine), max); + position = newLine + 1; + } + } + + if (trailing && trailing[0] !== '\n') result += trailing[0]; + + return result; +} + +function foldLine(line, max) { + if (line === '') return line; + + var foldRe = /[^\s] [^\s]/g, + result = '', + prevMatch = 0, + foldStart = 0, + match = foldRe.exec(line), + index, + foldEnd, + folded; + + while (match) { + index = match.index; + + // when we cross the max len, if the previous match would've + // been ok, use that one, and carry on. If there was no previous + // match on this fold section, then just have a long line. + if (index - foldStart > max) { + if (prevMatch !== foldStart) foldEnd = prevMatch; + else foldEnd = index; + + if (result) result += '\n'; + folded = line.slice(foldStart, foldEnd); + result += folded; + foldStart = foldEnd + 1; + } + prevMatch = index + 1; + match = foldRe.exec(line); + } + + if (result) result += '\n'; + + // if we end up with one last word at the end, then the last bit might + // be slightly bigger than we wanted, because we exited out of the loop. + if (foldStart !== prevMatch && line.length - foldStart > max) { + result += line.slice(foldStart, prevMatch) + '\n' + + line.slice(prevMatch + 1); + } else { + result += line.slice(foldStart); + } + + return result; +} + +// Returns true if character can be found in a simple scalar +function simpleChar(character) { + return CHAR_TAB !== character && + CHAR_LINE_FEED !== character && + CHAR_CARRIAGE_RETURN !== character && + CHAR_COMMA !== character && + CHAR_LEFT_SQUARE_BRACKET !== character && + CHAR_RIGHT_SQUARE_BRACKET !== character && + CHAR_LEFT_CURLY_BRACKET !== character && + CHAR_RIGHT_CURLY_BRACKET !== character && + CHAR_SHARP !== character && + CHAR_AMPERSAND !== character && + CHAR_ASTERISK !== character && + CHAR_EXCLAMATION !== character && + CHAR_VERTICAL_LINE !== character && + CHAR_GREATER_THAN !== character && + CHAR_SINGLE_QUOTE !== character && + CHAR_DOUBLE_QUOTE !== character && + CHAR_PERCENT !== character && + CHAR_COLON !== character && + !ESCAPE_SEQUENCES[character] && + !needsHexEscape(character); +} + +// Returns true if the character code needs to be escaped. +function needsHexEscape(character) { + return !((0x00020 <= character && character <= 0x00007E) || + (character === 0x00085) || + (0x000A0 <= character && character <= 0x00D7FF) || + (0x0E000 <= character && character <= 0x00FFFD) || + (0x10000 <= character && character <= 0x10FFFF)); +} + +function writeFlowSequence(state, level, object) { + var _result = '', + _tag = state.tag, + index, + length; + + for (index = 0, length = object.length; index < length; index += 1) { + // Write only valid elements. + if (writeNode(state, level, object[index], false, false)) { + if (index !== 0) _result += ', '; + _result += state.dump; + } + } + + state.tag = _tag; + state.dump = '[' + _result + ']'; +} + +function writeBlockSequence(state, level, object, compact) { + var _result = '', + _tag = state.tag, + index, + length; + + for (index = 0, length = object.length; index < length; index += 1) { + // Write only valid elements. + if (writeNode(state, level + 1, object[index], true, true)) { + if (!compact || index !== 0) { + _result += generateNextLine(state, level); + } + _result += '- ' + state.dump; + } + } + + state.tag = _tag; + state.dump = _result || '[]'; // Empty sequence if no valid values. +} + +function writeFlowMapping(state, level, object) { + var _result = '', + _tag = state.tag, + objectKeyList = Object.keys(object), + index, + length, + objectKey, + objectValue, + pairBuffer; + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + pairBuffer = ''; + + if (index !== 0) pairBuffer += ', '; + + objectKey = objectKeyList[index]; + objectValue = object[objectKey]; + + if (!writeNode(state, level, objectKey, false, false)) { + continue; // Skip this pair because of invalid key; + } + + if (state.dump.length > 1024) pairBuffer += '? '; + + pairBuffer += state.dump + ': '; + + if (!writeNode(state, level, objectValue, false, false)) { + continue; // Skip this pair because of invalid value. + } + + pairBuffer += state.dump; + + // Both key and value are valid. + _result += pairBuffer; + } + + state.tag = _tag; + state.dump = '{' + _result + '}'; +} + +function writeBlockMapping(state, level, object, compact) { + var _result = '', + _tag = state.tag, + objectKeyList = Object.keys(object), + index, + length, + objectKey, + objectValue, + explicitPair, + pairBuffer; + + // Allow sorting keys so that the output file is deterministic + if (state.sortKeys === true) { + // Default sorting + objectKeyList.sort(); + } else if (typeof state.sortKeys === 'function') { + // Custom sort function + objectKeyList.sort(state.sortKeys); + } else if (state.sortKeys) { + // Something is wrong + throw new YAMLException('sortKeys must be a boolean or a function'); + } + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + pairBuffer = ''; + + if (!compact || index !== 0) { + pairBuffer += generateNextLine(state, level); + } + + objectKey = objectKeyList[index]; + objectValue = object[objectKey]; + + if (!writeNode(state, level + 1, objectKey, true, true, true)) { + continue; // Skip this pair because of invalid key. + } + + explicitPair = (state.tag !== null && state.tag !== '?') || + (state.dump && state.dump.length > 1024); + + if (explicitPair) { + if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { + pairBuffer += '?'; + } else { + pairBuffer += '? '; + } + } + + pairBuffer += state.dump; + + if (explicitPair) { + pairBuffer += generateNextLine(state, level); + } + + if (!writeNode(state, level + 1, objectValue, true, explicitPair)) { + continue; // Skip this pair because of invalid value. + } + + if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { + pairBuffer += ':'; + } else { + pairBuffer += ': '; + } + + pairBuffer += state.dump; + + // Both key and value are valid. + _result += pairBuffer; + } + + state.tag = _tag; + state.dump = _result || '{}'; // Empty mapping if no valid pairs. +} + +function detectType(state, object, explicit) { + var _result, typeList, index, length, type, style; + + typeList = explicit ? state.explicitTypes : state.implicitTypes; + + for (index = 0, length = typeList.length; index < length; index += 1) { + type = typeList[index]; + + if ((type.instanceOf || type.predicate) && + (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) && + (!type.predicate || type.predicate(object))) { + + state.tag = explicit ? type.tag : '?'; + + if (type.represent) { + style = state.styleMap[type.tag] || type.defaultStyle; + + if (_toString.call(type.represent) === '[object Function]') { + _result = type.represent(object, style); + } else if (_hasOwnProperty.call(type.represent, style)) { + _result = type.represent[style](object, style); + } else { + throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style'); + } + + state.dump = _result; + } + + return true; + } + } + + return false; +} + +// Serializes `object` and writes it to global `result`. +// Returns true on success, or false on invalid object. +// +function writeNode(state, level, object, block, compact, iskey) { + state.tag = null; + state.dump = object; + + if (!detectType(state, object, false)) { + detectType(state, object, true); + } + + var type = _toString.call(state.dump); + + if (block) { + block = (state.flowLevel < 0 || state.flowLevel > level); + } + + var objectOrArray = type === '[object Object]' || type === '[object Array]', + duplicateIndex, + duplicate; + + if (objectOrArray) { + duplicateIndex = state.duplicates.indexOf(object); + duplicate = duplicateIndex !== -1; + } + + if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) { + compact = false; + } + + if (duplicate && state.usedDuplicates[duplicateIndex]) { + state.dump = '*ref_' + duplicateIndex; + } else { + if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) { + state.usedDuplicates[duplicateIndex] = true; + } + if (type === '[object Object]') { + if (block && (Object.keys(state.dump).length !== 0)) { + writeBlockMapping(state, level, state.dump, compact); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + state.dump; + } + } else { + writeFlowMapping(state, level, state.dump); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; + } + } + } else if (type === '[object Array]') { + if (block && (state.dump.length !== 0)) { + writeBlockSequence(state, level, state.dump, compact); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + state.dump; + } + } else { + writeFlowSequence(state, level, state.dump); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; + } + } + } else if (type === '[object String]') { + if (state.tag !== '?') { + writeScalar(state, state.dump, level, iskey); + } + } else { + if (state.skipInvalid) return false; + throw new YAMLException('unacceptable kind of an object to dump ' + type); + } + + if (state.tag !== null && state.tag !== '?') { + state.dump = '!<' + state.tag + '> ' + state.dump; + } + } + + return true; +} + +function getDuplicateReferences(object, state) { + var objects = [], + duplicatesIndexes = [], + index, + length; + + inspectNode(object, objects, duplicatesIndexes); + + for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) { + state.duplicates.push(objects[duplicatesIndexes[index]]); + } + state.usedDuplicates = new Array(length); +} + +function inspectNode(object, objects, duplicatesIndexes) { + var objectKeyList, + index, + length; + + if (object !== null && typeof object === 'object') { + index = objects.indexOf(object); + if (index !== -1) { + if (duplicatesIndexes.indexOf(index) === -1) { + duplicatesIndexes.push(index); + } + } else { + objects.push(object); + + if (Array.isArray(object)) { + for (index = 0, length = object.length; index < length; index += 1) { + inspectNode(object[index], objects, duplicatesIndexes); + } + } else { + objectKeyList = Object.keys(object); + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes); + } + } + } + } +} + +function dump(input, options) { + options = options || {}; + + var state = new State(options); + + if (!state.noRefs) getDuplicateReferences(input, state); + + if (writeNode(state, 0, input, true, true)) return state.dump + '\n'; + + return ''; +} + +function safeDump(input, options) { + return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); +} + +module.exports.dump = dump; +module.exports.safeDump = safeDump; + +},{"./common":2,"./exception":4,"./schema/default_full":9,"./schema/default_safe":10}],4:[function(require,module,exports){ +// YAML error class. http://stackoverflow.com/questions/8458984 +// +'use strict'; + +function YAMLException(reason, mark) { + // Super constructor + Error.call(this); + + // Include stack trace in error object + if (Error.captureStackTrace) { + // Chrome and NodeJS + Error.captureStackTrace(this, this.constructor); + } else { + // FF, IE 10+ and Safari 6+. Fallback for others + this.stack = (new Error()).stack || ''; + } + + this.name = 'YAMLException'; + this.reason = reason; + this.mark = mark; + this.message = (this.reason || '(unknown reason)') + (this.mark ? ' ' + this.mark.toString() : ''); +} + + +// Inherit from Error +YAMLException.prototype = Object.create(Error.prototype); +YAMLException.prototype.constructor = YAMLException; + + +YAMLException.prototype.toString = function toString(compact) { + var result = this.name + ': '; + + result += this.reason || '(unknown reason)'; + + if (!compact && this.mark) { + result += ' ' + this.mark.toString(); + } + + return result; +}; + + +module.exports = YAMLException; + +},{}],5:[function(require,module,exports){ +'use strict'; + +/*eslint-disable max-len,no-use-before-define*/ + +var common = require('./common'); +var YAMLException = require('./exception'); +var Mark = require('./mark'); +var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe'); +var DEFAULT_FULL_SCHEMA = require('./schema/default_full'); + + +var _hasOwnProperty = Object.prototype.hasOwnProperty; + + +var CONTEXT_FLOW_IN = 1; +var CONTEXT_FLOW_OUT = 2; +var CONTEXT_BLOCK_IN = 3; +var CONTEXT_BLOCK_OUT = 4; + + +var CHOMPING_CLIP = 1; +var CHOMPING_STRIP = 2; +var CHOMPING_KEEP = 3; + + +var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; +var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/; +var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/; +var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i; +var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; + + +function is_EOL(c) { + return (c === 0x0A/* LF */) || (c === 0x0D/* CR */); +} + +function is_WHITE_SPACE(c) { + return (c === 0x09/* Tab */) || (c === 0x20/* Space */); +} + +function is_WS_OR_EOL(c) { + return (c === 0x09/* Tab */) || + (c === 0x20/* Space */) || + (c === 0x0A/* LF */) || + (c === 0x0D/* CR */); +} + +function is_FLOW_INDICATOR(c) { + return c === 0x2C/* , */ || + c === 0x5B/* [ */ || + c === 0x5D/* ] */ || + c === 0x7B/* { */ || + c === 0x7D/* } */; +} + +function fromHexCode(c) { + var lc; + + if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { + return c - 0x30; + } + + /*eslint-disable no-bitwise*/ + lc = c | 0x20; + + if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) { + return lc - 0x61 + 10; + } + + return -1; +} + +function escapedHexLen(c) { + if (c === 0x78/* x */) { return 2; } + if (c === 0x75/* u */) { return 4; } + if (c === 0x55/* U */) { return 8; } + return 0; +} + +function fromDecimalCode(c) { + if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { + return c - 0x30; + } + + return -1; +} + +function simpleEscapeSequence(c) { + return (c === 0x30/* 0 */) ? '\x00' : + (c === 0x61/* a */) ? '\x07' : + (c === 0x62/* b */) ? '\x08' : + (c === 0x74/* t */) ? '\x09' : + (c === 0x09/* Tab */) ? '\x09' : + (c === 0x6E/* n */) ? '\x0A' : + (c === 0x76/* v */) ? '\x0B' : + (c === 0x66/* f */) ? '\x0C' : + (c === 0x72/* r */) ? '\x0D' : + (c === 0x65/* e */) ? '\x1B' : + (c === 0x20/* Space */) ? ' ' : + (c === 0x22/* " */) ? '\x22' : + (c === 0x2F/* / */) ? '/' : + (c === 0x5C/* \ */) ? '\x5C' : + (c === 0x4E/* N */) ? '\x85' : + (c === 0x5F/* _ */) ? '\xA0' : + (c === 0x4C/* L */) ? '\u2028' : + (c === 0x50/* P */) ? '\u2029' : ''; +} + +function charFromCodepoint(c) { + if (c <= 0xFFFF) { + return String.fromCharCode(c); + } + // Encode UTF-16 surrogate pair + // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF + return String.fromCharCode(((c - 0x010000) >> 10) + 0xD800, + ((c - 0x010000) & 0x03FF) + 0xDC00); +} + +var simpleEscapeCheck = new Array(256); // integer, for fast access +var simpleEscapeMap = new Array(256); +for (var i = 0; i < 256; i++) { + simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0; + simpleEscapeMap[i] = simpleEscapeSequence(i); +} + + +function State(input, options) { + this.input = input; + + this.filename = options['filename'] || null; + this.schema = options['schema'] || DEFAULT_FULL_SCHEMA; + this.onWarning = options['onWarning'] || null; + this.legacy = options['legacy'] || false; + this.json = options['json'] || false; + this.listener = options['listener'] || null; + + this.implicitTypes = this.schema.compiledImplicit; + this.typeMap = this.schema.compiledTypeMap; + + this.length = input.length; + this.position = 0; + this.line = 0; + this.lineStart = 0; + this.lineIndent = 0; + + this.documents = []; + + /* + this.version; + this.checkLineBreaks; + this.tagMap; + this.anchorMap; + this.tag; + this.anchor; + this.kind; + this.result;*/ + +} + + +function generateError(state, message) { + return new YAMLException( + message, + new Mark(state.filename, state.input, state.position, state.line, (state.position - state.lineStart))); +} + +function throwError(state, message) { + throw generateError(state, message); +} + +function throwWarning(state, message) { + if (state.onWarning) { + state.onWarning.call(null, generateError(state, message)); + } +} + + +var directiveHandlers = { + + YAML: function handleYamlDirective(state, name, args) { + + var match, major, minor; + + if (state.version !== null) { + throwError(state, 'duplication of %YAML directive'); + } + + if (args.length !== 1) { + throwError(state, 'YAML directive accepts exactly one argument'); + } + + match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]); + + if (match === null) { + throwError(state, 'ill-formed argument of the YAML directive'); + } + + major = parseInt(match[1], 10); + minor = parseInt(match[2], 10); + + if (major !== 1) { + throwError(state, 'unacceptable YAML version of the document'); + } + + state.version = args[0]; + state.checkLineBreaks = (minor < 2); + + if (minor !== 1 && minor !== 2) { + throwWarning(state, 'unsupported YAML version of the document'); + } + }, + + TAG: function handleTagDirective(state, name, args) { + + var handle, prefix; + + if (args.length !== 2) { + throwError(state, 'TAG directive accepts exactly two arguments'); + } + + handle = args[0]; + prefix = args[1]; + + if (!PATTERN_TAG_HANDLE.test(handle)) { + throwError(state, 'ill-formed tag handle (first argument) of the TAG directive'); + } + + if (_hasOwnProperty.call(state.tagMap, handle)) { + throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle'); + } + + if (!PATTERN_TAG_URI.test(prefix)) { + throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive'); + } + + state.tagMap[handle] = prefix; + } +}; + + +function captureSegment(state, start, end, checkJson) { + var _position, _length, _character, _result; + + if (start < end) { + _result = state.input.slice(start, end); + + if (checkJson) { + for (_position = 0, _length = _result.length; + _position < _length; + _position += 1) { + _character = _result.charCodeAt(_position); + if (!(_character === 0x09 || + (0x20 <= _character && _character <= 0x10FFFF))) { + throwError(state, 'expected valid JSON character'); + } + } + } else if (PATTERN_NON_PRINTABLE.test(_result)) { + throwError(state, 'the stream contains non-printable characters'); + } + + state.result += _result; + } +} + +function mergeMappings(state, destination, source, overridableKeys) { + var sourceKeys, key, index, quantity; + + if (!common.isObject(source)) { + throwError(state, 'cannot merge mappings; the provided source object is unacceptable'); + } + + sourceKeys = Object.keys(source); + + for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) { + key = sourceKeys[index]; + + if (!_hasOwnProperty.call(destination, key)) { + destination[key] = source[key]; + overridableKeys[key] = true; + } + } +} + +function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode) { + var index, quantity; + + keyNode = String(keyNode); + + if (_result === null) { + _result = {}; + } + + if (keyTag === 'tag:yaml.org,2002:merge') { + if (Array.isArray(valueNode)) { + for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { + mergeMappings(state, _result, valueNode[index], overridableKeys); + } + } else { + mergeMappings(state, _result, valueNode, overridableKeys); + } + } else { + if (!state.json && + !_hasOwnProperty.call(overridableKeys, keyNode) && + _hasOwnProperty.call(_result, keyNode)) { + throwError(state, 'duplicated mapping key'); + } + _result[keyNode] = valueNode; + delete overridableKeys[keyNode]; + } + + return _result; +} + +function readLineBreak(state) { + var ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x0A/* LF */) { + state.position++; + } else if (ch === 0x0D/* CR */) { + state.position++; + if (state.input.charCodeAt(state.position) === 0x0A/* LF */) { + state.position++; + } + } else { + throwError(state, 'a line break is expected'); + } + + state.line += 1; + state.lineStart = state.position; +} + +function skipSeparationSpace(state, allowComments, checkIndent) { + var lineBreaks = 0, + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + while (is_WHITE_SPACE(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (allowComments && ch === 0x23/* # */) { + do { + ch = state.input.charCodeAt(++state.position); + } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0); + } + + if (is_EOL(ch)) { + readLineBreak(state); + + ch = state.input.charCodeAt(state.position); + lineBreaks++; + state.lineIndent = 0; + + while (ch === 0x20/* Space */) { + state.lineIndent++; + ch = state.input.charCodeAt(++state.position); + } + } else { + break; + } + } + + if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) { + throwWarning(state, 'deficient indentation'); + } + + return lineBreaks; +} + +function testDocumentSeparator(state) { + var _position = state.position, + ch; + + ch = state.input.charCodeAt(_position); + + // Condition state.position === state.lineStart is tested + // in parent on each call, for efficiency. No needs to test here again. + if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) && + ch === state.input.charCodeAt(_position + 1) && + ch === state.input.charCodeAt(_position + 2)) { + + _position += 3; + + ch = state.input.charCodeAt(_position); + + if (ch === 0 || is_WS_OR_EOL(ch)) { + return true; + } + } + + return false; +} + +function writeFoldedLines(state, count) { + if (count === 1) { + state.result += ' '; + } else if (count > 1) { + state.result += common.repeat('\n', count - 1); + } +} + + +function readPlainScalar(state, nodeIndent, withinFlowCollection) { + var preceding, + following, + captureStart, + captureEnd, + hasPendingContent, + _line, + _lineStart, + _lineIndent, + _kind = state.kind, + _result = state.result, + ch; + + ch = state.input.charCodeAt(state.position); + + if (is_WS_OR_EOL(ch) || + is_FLOW_INDICATOR(ch) || + ch === 0x23/* # */ || + ch === 0x26/* & */ || + ch === 0x2A/* * */ || + ch === 0x21/* ! */ || + ch === 0x7C/* | */ || + ch === 0x3E/* > */ || + ch === 0x27/* ' */ || + ch === 0x22/* " */ || + ch === 0x25/* % */ || + ch === 0x40/* @ */ || + ch === 0x60/* ` */) { + return false; + } + + if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following) || + withinFlowCollection && is_FLOW_INDICATOR(following)) { + return false; + } + } + + state.kind = 'scalar'; + state.result = ''; + captureStart = captureEnd = state.position; + hasPendingContent = false; + + while (ch !== 0) { + if (ch === 0x3A/* : */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following) || + withinFlowCollection && is_FLOW_INDICATOR(following)) { + break; + } + + } else if (ch === 0x23/* # */) { + preceding = state.input.charCodeAt(state.position - 1); + + if (is_WS_OR_EOL(preceding)) { + break; + } + + } else if ((state.position === state.lineStart && testDocumentSeparator(state)) || + withinFlowCollection && is_FLOW_INDICATOR(ch)) { + break; + + } else if (is_EOL(ch)) { + _line = state.line; + _lineStart = state.lineStart; + _lineIndent = state.lineIndent; + skipSeparationSpace(state, false, -1); + + if (state.lineIndent >= nodeIndent) { + hasPendingContent = true; + ch = state.input.charCodeAt(state.position); + continue; + } else { + state.position = captureEnd; + state.line = _line; + state.lineStart = _lineStart; + state.lineIndent = _lineIndent; + break; + } + } + + if (hasPendingContent) { + captureSegment(state, captureStart, captureEnd, false); + writeFoldedLines(state, state.line - _line); + captureStart = captureEnd = state.position; + hasPendingContent = false; + } + + if (!is_WHITE_SPACE(ch)) { + captureEnd = state.position + 1; + } + + ch = state.input.charCodeAt(++state.position); + } + + captureSegment(state, captureStart, captureEnd, false); + + if (state.result) { + return true; + } + + state.kind = _kind; + state.result = _result; + return false; +} + +function readSingleQuotedScalar(state, nodeIndent) { + var ch, + captureStart, captureEnd; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x27/* ' */) { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + state.position++; + captureStart = captureEnd = state.position; + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + if (ch === 0x27/* ' */) { + captureSegment(state, captureStart, state.position, true); + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x27/* ' */) { + captureStart = captureEnd = state.position; + state.position++; + } else { + return true; + } + + } else if (is_EOL(ch)) { + captureSegment(state, captureStart, captureEnd, true); + writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); + captureStart = captureEnd = state.position; + + } else if (state.position === state.lineStart && testDocumentSeparator(state)) { + throwError(state, 'unexpected end of the document within a single quoted scalar'); + + } else { + state.position++; + captureEnd = state.position; + } + } + + throwError(state, 'unexpected end of the stream within a single quoted scalar'); +} + +function readDoubleQuotedScalar(state, nodeIndent) { + var captureStart, + captureEnd, + hexLength, + hexResult, + tmp, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x22/* " */) { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + state.position++; + captureStart = captureEnd = state.position; + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + if (ch === 0x22/* " */) { + captureSegment(state, captureStart, state.position, true); + state.position++; + return true; + + } else if (ch === 0x5C/* \ */) { + captureSegment(state, captureStart, state.position, true); + ch = state.input.charCodeAt(++state.position); + + if (is_EOL(ch)) { + skipSeparationSpace(state, false, nodeIndent); + + // TODO: rework to inline fn with no type cast? + } else if (ch < 256 && simpleEscapeCheck[ch]) { + state.result += simpleEscapeMap[ch]; + state.position++; + + } else if ((tmp = escapedHexLen(ch)) > 0) { + hexLength = tmp; + hexResult = 0; + + for (; hexLength > 0; hexLength--) { + ch = state.input.charCodeAt(++state.position); + + if ((tmp = fromHexCode(ch)) >= 0) { + hexResult = (hexResult << 4) + tmp; + + } else { + throwError(state, 'expected hexadecimal character'); + } + } + + state.result += charFromCodepoint(hexResult); + + state.position++; + + } else { + throwError(state, 'unknown escape sequence'); + } + + captureStart = captureEnd = state.position; + + } else if (is_EOL(ch)) { + captureSegment(state, captureStart, captureEnd, true); + writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); + captureStart = captureEnd = state.position; + + } else if (state.position === state.lineStart && testDocumentSeparator(state)) { + throwError(state, 'unexpected end of the document within a double quoted scalar'); + + } else { + state.position++; + captureEnd = state.position; + } + } + + throwError(state, 'unexpected end of the stream within a double quoted scalar'); +} + +function readFlowCollection(state, nodeIndent) { + var readNext = true, + _line, + _tag = state.tag, + _result, + _anchor = state.anchor, + following, + terminator, + isPair, + isExplicitPair, + isMapping, + overridableKeys = {}, + keyNode, + keyTag, + valueNode, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x5B/* [ */) { + terminator = 0x5D;/* ] */ + isMapping = false; + _result = []; + } else if (ch === 0x7B/* { */) { + terminator = 0x7D;/* } */ + isMapping = true; + _result = {}; + } else { + return false; + } + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(++state.position); + + while (ch !== 0) { + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if (ch === terminator) { + state.position++; + state.tag = _tag; + state.anchor = _anchor; + state.kind = isMapping ? 'mapping' : 'sequence'; + state.result = _result; + return true; + } else if (!readNext) { + throwError(state, 'missed comma between flow collection entries'); + } + + keyTag = keyNode = valueNode = null; + isPair = isExplicitPair = false; + + if (ch === 0x3F/* ? */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following)) { + isPair = isExplicitPair = true; + state.position++; + skipSeparationSpace(state, true, nodeIndent); + } + } + + _line = state.line; + composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); + keyTag = state.tag; + keyNode = state.result; + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) { + isPair = true; + ch = state.input.charCodeAt(++state.position); + skipSeparationSpace(state, true, nodeIndent); + composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); + valueNode = state.result; + } + + if (isMapping) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode); + } else if (isPair) { + _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode)); + } else { + _result.push(keyNode); + } + + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x2C/* , */) { + readNext = true; + ch = state.input.charCodeAt(++state.position); + } else { + readNext = false; + } + } + + throwError(state, 'unexpected end of the stream within a flow collection'); +} + +function readBlockScalar(state, nodeIndent) { + var captureStart, + folding, + chomping = CHOMPING_CLIP, + detectedIndent = false, + textIndent = nodeIndent, + emptyLines = 0, + atMoreIndented = false, + tmp, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x7C/* | */) { + folding = false; + } else if (ch === 0x3E/* > */) { + folding = true; + } else { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + + while (ch !== 0) { + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { + if (CHOMPING_CLIP === chomping) { + chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP; + } else { + throwError(state, 'repeat of a chomping mode identifier'); + } + + } else if ((tmp = fromDecimalCode(ch)) >= 0) { + if (tmp === 0) { + throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one'); + } else if (!detectedIndent) { + textIndent = nodeIndent + tmp - 1; + detectedIndent = true; + } else { + throwError(state, 'repeat of an indentation width identifier'); + } + + } else { + break; + } + } + + if (is_WHITE_SPACE(ch)) { + do { ch = state.input.charCodeAt(++state.position); } + while (is_WHITE_SPACE(ch)); + + if (ch === 0x23/* # */) { + do { ch = state.input.charCodeAt(++state.position); } + while (!is_EOL(ch) && (ch !== 0)); + } + } + + while (ch !== 0) { + readLineBreak(state); + state.lineIndent = 0; + + ch = state.input.charCodeAt(state.position); + + while ((!detectedIndent || state.lineIndent < textIndent) && + (ch === 0x20/* Space */)) { + state.lineIndent++; + ch = state.input.charCodeAt(++state.position); + } + + if (!detectedIndent && state.lineIndent > textIndent) { + textIndent = state.lineIndent; + } + + if (is_EOL(ch)) { + emptyLines++; + continue; + } + + // End of the scalar. + if (state.lineIndent < textIndent) { + + // Perform the chomping. + if (chomping === CHOMPING_KEEP) { + state.result += common.repeat('\n', emptyLines); + } else if (chomping === CHOMPING_CLIP) { + if (detectedIndent) { // i.e. only if the scalar is not empty. + state.result += '\n'; + } + } + + // Break this `while` cycle and go to the funciton's epilogue. + break; + } + + // Folded style: use fancy rules to handle line breaks. + if (folding) { + + // Lines starting with white space characters (more-indented lines) are not folded. + if (is_WHITE_SPACE(ch)) { + atMoreIndented = true; + state.result += common.repeat('\n', emptyLines + 1); + + // End of more-indented block. + } else if (atMoreIndented) { + atMoreIndented = false; + state.result += common.repeat('\n', emptyLines + 1); + + // Just one line break - perceive as the same line. + } else if (emptyLines === 0) { + if (detectedIndent) { // i.e. only if we have already read some scalar content. + state.result += ' '; + } + + // Several line breaks - perceive as different lines. + } else { + state.result += common.repeat('\n', emptyLines); + } + + // Literal style: just add exact number of line breaks between content lines. + } else if (detectedIndent) { + // If current line isn't the first one - count line break from the last content line. + state.result += common.repeat('\n', emptyLines + 1); + } else { + // In case of the first content line - count only empty lines. + state.result += common.repeat('\n', emptyLines); + } + + detectedIndent = true; + emptyLines = 0; + captureStart = state.position; + + while (!is_EOL(ch) && (ch !== 0)) { + ch = state.input.charCodeAt(++state.position); + } + + captureSegment(state, captureStart, state.position, false); + } + + return true; +} + +function readBlockSequence(state, nodeIndent) { + var _line, + _tag = state.tag, + _anchor = state.anchor, + _result = [], + following, + detected = false, + ch; + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + + if (ch !== 0x2D/* - */) { + break; + } + + following = state.input.charCodeAt(state.position + 1); + + if (!is_WS_OR_EOL(following)) { + break; + } + + detected = true; + state.position++; + + if (skipSeparationSpace(state, true, -1)) { + if (state.lineIndent <= nodeIndent) { + _result.push(null); + ch = state.input.charCodeAt(state.position); + continue; + } + } + + _line = state.line; + composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true); + _result.push(state.result); + skipSeparationSpace(state, true, -1); + + ch = state.input.charCodeAt(state.position); + + if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { + throwError(state, 'bad indentation of a sequence entry'); + } else if (state.lineIndent < nodeIndent) { + break; + } + } + + if (detected) { + state.tag = _tag; + state.anchor = _anchor; + state.kind = 'sequence'; + state.result = _result; + return true; + } + return false; +} + +function readBlockMapping(state, nodeIndent, flowIndent) { + var following, + allowCompact, + _line, + _tag = state.tag, + _anchor = state.anchor, + _result = {}, + overridableKeys = {}, + keyTag = null, + keyNode = null, + valueNode = null, + atExplicitKey = false, + detected = false, + ch; + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + following = state.input.charCodeAt(state.position + 1); + _line = state.line; // Save the current line. + + // + // Explicit notation case. There are two separate blocks: + // first for the key (denoted by "?") and second for the value (denoted by ":") + // + if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) { + + if (ch === 0x3F/* ? */) { + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); + keyTag = keyNode = valueNode = null; + } + + detected = true; + atExplicitKey = true; + allowCompact = true; + + } else if (atExplicitKey) { + // i.e. 0x3A/* : */ === character after the explicit key. + atExplicitKey = false; + allowCompact = true; + + } else { + throwError(state, 'incomplete explicit mapping pair; a key node is missed'); + } + + state.position += 1; + ch = following; + + // + // Implicit notation case. Flow-style node as the key first, then ":", and the value. + // + } else if (composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) { + + if (state.line === _line) { + ch = state.input.charCodeAt(state.position); + + while (is_WHITE_SPACE(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (ch === 0x3A/* : */) { + ch = state.input.charCodeAt(++state.position); + + if (!is_WS_OR_EOL(ch)) { + throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping'); + } + + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); + keyTag = keyNode = valueNode = null; + } + + detected = true; + atExplicitKey = false; + allowCompact = false; + keyTag = state.tag; + keyNode = state.result; + + } else if (detected) { + throwError(state, 'can not read an implicit mapping pair; a colon is missed'); + + } else { + state.tag = _tag; + state.anchor = _anchor; + return true; // Keep the result of `composeNode`. + } + + } else if (detected) { + throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key'); + + } else { + state.tag = _tag; + state.anchor = _anchor; + return true; // Keep the result of `composeNode`. + } + + } else { + break; // Reading is done. Go to the epilogue. + } + + // + // Common reading code for both explicit and implicit notations. + // + if (state.line === _line || state.lineIndent > nodeIndent) { + if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) { + if (atExplicitKey) { + keyNode = state.result; + } else { + valueNode = state.result; + } + } + + if (!atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode); + keyTag = keyNode = valueNode = null; + } + + skipSeparationSpace(state, true, -1); + ch = state.input.charCodeAt(state.position); + } + + if (state.lineIndent > nodeIndent && (ch !== 0)) { + throwError(state, 'bad indentation of a mapping entry'); + } else if (state.lineIndent < nodeIndent) { + break; + } + } + + // + // Epilogue. + // + + // Special case: last mapping's node contains only the key in explicit notation. + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); + } + + // Expose the resulting mapping. + if (detected) { + state.tag = _tag; + state.anchor = _anchor; + state.kind = 'mapping'; + state.result = _result; + } + + return detected; +} + +function readTagProperty(state) { + var _position, + isVerbatim = false, + isNamed = false, + tagHandle, + tagName, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x21/* ! */) return false; + + if (state.tag !== null) { + throwError(state, 'duplication of a tag property'); + } + + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x3C/* < */) { + isVerbatim = true; + ch = state.input.charCodeAt(++state.position); + + } else if (ch === 0x21/* ! */) { + isNamed = true; + tagHandle = '!!'; + ch = state.input.charCodeAt(++state.position); + + } else { + tagHandle = '!'; + } + + _position = state.position; + + if (isVerbatim) { + do { ch = state.input.charCodeAt(++state.position); } + while (ch !== 0 && ch !== 0x3E/* > */); + + if (state.position < state.length) { + tagName = state.input.slice(_position, state.position); + ch = state.input.charCodeAt(++state.position); + } else { + throwError(state, 'unexpected end of the stream within a verbatim tag'); + } + } else { + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + + if (ch === 0x21/* ! */) { + if (!isNamed) { + tagHandle = state.input.slice(_position - 1, state.position + 1); + + if (!PATTERN_TAG_HANDLE.test(tagHandle)) { + throwError(state, 'named tag handle cannot contain such characters'); + } + + isNamed = true; + _position = state.position + 1; + } else { + throwError(state, 'tag suffix cannot contain exclamation marks'); + } + } + + ch = state.input.charCodeAt(++state.position); + } + + tagName = state.input.slice(_position, state.position); + + if (PATTERN_FLOW_INDICATORS.test(tagName)) { + throwError(state, 'tag suffix cannot contain flow indicator characters'); + } + } + + if (tagName && !PATTERN_TAG_URI.test(tagName)) { + throwError(state, 'tag name cannot contain such characters: ' + tagName); + } + + if (isVerbatim) { + state.tag = tagName; + + } else if (_hasOwnProperty.call(state.tagMap, tagHandle)) { + state.tag = state.tagMap[tagHandle] + tagName; + + } else if (tagHandle === '!') { + state.tag = '!' + tagName; + + } else if (tagHandle === '!!') { + state.tag = 'tag:yaml.org,2002:' + tagName; + + } else { + throwError(state, 'undeclared tag handle "' + tagHandle + '"'); + } + + return true; +} + +function readAnchorProperty(state) { + var _position, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x26/* & */) return false; + + if (state.anchor !== null) { + throwError(state, 'duplication of an anchor property'); + } + + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (state.position === _position) { + throwError(state, 'name of an anchor node must contain at least one character'); + } + + state.anchor = state.input.slice(_position, state.position); + return true; +} + +function readAlias(state) { + var _position, alias, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x2A/* * */) return false; + + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (state.position === _position) { + throwError(state, 'name of an alias node must contain at least one character'); + } + + alias = state.input.slice(_position, state.position); + + if (!state.anchorMap.hasOwnProperty(alias)) { + throwError(state, 'unidentified alias "' + alias + '"'); + } + + state.result = state.anchorMap[alias]; + skipSeparationSpace(state, true, -1); + return true; +} + +function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) { + var allowBlockStyles, + allowBlockScalars, + allowBlockCollections, + indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) { + indentStatus = 1; + } else if (state.lineIndent === parentIndent) { + indentStatus = 0; + } else if (state.lineIndent < parentIndent) { + indentStatus = -1; + } + } + } + + if (indentStatus === 1) { + while (readTagProperty(state) || readAnchorProperty(state)) { + if (skipSeparationSpace(state, true, -1)) { + atNewLine = true; + allowBlockCollections = allowBlockStyles; + + if (state.lineIndent > parentIndent) { + indentStatus = 1; + } else if (state.lineIndent === parentIndent) { + indentStatus = 0; + } else if (state.lineIndent < parentIndent) { + indentStatus = -1; + } + } else { + allowBlockCollections = false; + } + } + } + + if (allowBlockCollections) { + allowBlockCollections = atNewLine || allowCompact; + } + + if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) { + if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) { + flowIndent = parentIndent; + } else { + flowIndent = parentIndent + 1; + } + + blockIndent = state.position - state.lineStart; + + if (indentStatus === 1) { + if (allowBlockCollections && + (readBlockSequence(state, blockIndent) || + readBlockMapping(state, blockIndent, flowIndent)) || + readFlowCollection(state, flowIndent)) { + hasContent = true; + } else { + if ((allowBlockScalars && readBlockScalar(state, flowIndent)) || + readSingleQuotedScalar(state, flowIndent) || + readDoubleQuotedScalar(state, flowIndent)) { + hasContent = true; + + } else if (readAlias(state)) { + hasContent = true; + + if (state.tag !== null || state.anchor !== null) { + throwError(state, 'alias node should not have any properties'); + } + + } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) { + hasContent = true; + + if (state.tag === null) { + state.tag = '?'; + } + } + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + } + } else if (indentStatus === 0) { + // Special case: block sequences are allowed to have same indentation level as the parent. + // http://www.yaml.org/spec/1.2/spec.html#id2799784 + hasContent = allowBlockCollections && readBlockSequence(state, blockIndent); + } + } + + if (state.tag !== null && state.tag !== '!') { + if (state.tag === '?') { + for (typeIndex = 0, typeQuantity = state.implicitTypes.length; + typeIndex < typeQuantity; + typeIndex += 1) { + type = state.implicitTypes[typeIndex]; + + // Implicit resolving is not allowed for non-scalar types, and '?' + // non-specific tag is only assigned to plain scalars. So, it isn't + // needed to check for 'kind' conformity. + + if (type.resolve(state.result)) { // `state.result` updated in resolver if matched + state.result = type.construct(state.result); + state.tag = type.tag; + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + break; + } + } + } else if (_hasOwnProperty.call(state.typeMap, state.tag)) { + type = state.typeMap[state.tag]; + + if (state.result !== null && type.kind !== state.kind) { + throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"'); + } + + if (!type.resolve(state.result)) { // `state.result` updated in resolver if matched + throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag'); + } else { + state.result = type.construct(state.result); + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + } + } else { + throwError(state, 'unknown tag !<' + state.tag + '>'); + } + } + + if (state.listener !== null) { + state.listener('close', state); + } + return state.tag !== null || state.anchor !== null || hasContent; +} + +function readDocument(state) { + var documentStart = state.position, + _position, + directiveName, + directiveArgs, + hasDirectives = false, + ch; + + state.version = null; + state.checkLineBreaks = state.legacy; + state.tagMap = {}; + state.anchorMap = {}; + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + skipSeparationSpace(state, true, -1); + + ch = state.input.charCodeAt(state.position); + + if (state.lineIndent > 0 || ch !== 0x25/* % */) { + break; + } + + hasDirectives = true; + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + directiveName = state.input.slice(_position, state.position); + directiveArgs = []; + + if (directiveName.length < 1) { + throwError(state, 'directive name must not be less than one character in length'); + } + + while (ch !== 0) { + while (is_WHITE_SPACE(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (ch === 0x23/* # */) { + do { ch = state.input.charCodeAt(++state.position); } + while (ch !== 0 && !is_EOL(ch)); + break; + } + + if (is_EOL(ch)) break; + + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + directiveArgs.push(state.input.slice(_position, state.position)); + } + + if (ch !== 0) readLineBreak(state); + + if (_hasOwnProperty.call(directiveHandlers, directiveName)) { + directiveHandlers[directiveName](state, directiveName, directiveArgs); + } else { + throwWarning(state, 'unknown document directive "' + directiveName + '"'); + } + } + + skipSeparationSpace(state, true, -1); + + if (state.lineIndent === 0 && + state.input.charCodeAt(state.position) === 0x2D/* - */ && + state.input.charCodeAt(state.position + 1) === 0x2D/* - */ && + state.input.charCodeAt(state.position + 2) === 0x2D/* - */) { + state.position += 3; + skipSeparationSpace(state, true, -1); + + } else if (hasDirectives) { + throwError(state, 'directives end mark is expected'); + } + + composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true); + skipSeparationSpace(state, true, -1); + + if (state.checkLineBreaks && + PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) { + throwWarning(state, 'non-ASCII line breaks are interpreted as content'); + } + + state.documents.push(state.result); + + if (state.position === state.lineStart && testDocumentSeparator(state)) { + + if (state.input.charCodeAt(state.position) === 0x2E/* . */) { + state.position += 3; + skipSeparationSpace(state, true, -1); + } + return; + } + + if (state.position < (state.length - 1)) { + throwError(state, 'end of the stream or a document separator is expected'); + } else { + return; + } +} + + +function loadDocuments(input, options) { + input = String(input); + options = options || {}; + + if (input.length !== 0) { + + // Add tailing `\n` if not exists + if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ && + input.charCodeAt(input.length - 1) !== 0x0D/* CR */) { + input += '\n'; + } + + // Strip BOM + if (input.charCodeAt(0) === 0xFEFF) { + input = input.slice(1); + } + } + + var state = new State(input, options); + + // Use 0 as string terminator. That significantly simplifies bounds check. + state.input += '\0'; + + while (state.input.charCodeAt(state.position) === 0x20/* Space */) { + state.lineIndent += 1; + state.position += 1; + } + + while (state.position < (state.length - 1)) { + readDocument(state); + } + + return state.documents; +} + + +function loadAll(input, iterator, options) { + var documents = loadDocuments(input, options), index, length; + + for (index = 0, length = documents.length; index < length; index += 1) { + iterator(documents[index]); + } +} + + +function load(input, options) { + var documents = loadDocuments(input, options); + + if (documents.length === 0) { + /*eslint-disable no-undefined*/ + return undefined; + } else if (documents.length === 1) { + return documents[0]; + } + throw new YAMLException('expected a single document in the stream, but found more'); +} + + +function safeLoadAll(input, output, options) { + loadAll(input, output, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); +} + + +function safeLoad(input, options) { + return load(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); +} + + +module.exports.loadAll = loadAll; +module.exports.load = load; +module.exports.safeLoadAll = safeLoadAll; +module.exports.safeLoad = safeLoad; + +},{"./common":2,"./exception":4,"./mark":6,"./schema/default_full":9,"./schema/default_safe":10}],6:[function(require,module,exports){ +'use strict'; + + +var common = require('./common'); + + +function Mark(name, buffer, position, line, column) { + this.name = name; + this.buffer = buffer; + this.position = position; + this.line = line; + this.column = column; +} + + +Mark.prototype.getSnippet = function getSnippet(indent, maxLength) { + var head, start, tail, end, snippet; + + if (!this.buffer) return null; + + indent = indent || 4; + maxLength = maxLength || 75; + + head = ''; + start = this.position; + + while (start > 0 && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(start - 1)) === -1) { + start -= 1; + if (this.position - start > (maxLength / 2 - 1)) { + head = ' ... '; + start += 5; + break; + } + } + + tail = ''; + end = this.position; + + while (end < this.buffer.length && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(end)) === -1) { + end += 1; + if (end - this.position > (maxLength / 2 - 1)) { + tail = ' ... '; + end -= 5; + break; + } + } + + snippet = this.buffer.slice(start, end); + + return common.repeat(' ', indent) + head + snippet + tail + '\n' + + common.repeat(' ', indent + this.position - start + head.length) + '^'; +}; + + +Mark.prototype.toString = function toString(compact) { + var snippet, where = ''; + + if (this.name) { + where += 'in "' + this.name + '" '; + } + + where += 'at line ' + (this.line + 1) + ', column ' + (this.column + 1); + + if (!compact) { + snippet = this.getSnippet(); + + if (snippet) { + where += ':\n' + snippet; + } + } + + return where; +}; + + +module.exports = Mark; + +},{"./common":2}],7:[function(require,module,exports){ +'use strict'; + +/*eslint-disable max-len*/ + +var common = require('./common'); +var YAMLException = require('./exception'); +var Type = require('./type'); + + +function compileList(schema, name, result) { + var exclude = []; + + schema.include.forEach(function (includedSchema) { + result = compileList(includedSchema, name, result); + }); + + schema[name].forEach(function (currentType) { + result.forEach(function (previousType, previousIndex) { + if (previousType.tag === currentType.tag) { + exclude.push(previousIndex); + } + }); + + result.push(currentType); + }); + + return result.filter(function (type, index) { + return exclude.indexOf(index) === -1; + }); +} + + +function compileMap(/* lists... */) { + var result = {}, index, length; + + function collectType(type) { + result[type.tag] = type; + } + + for (index = 0, length = arguments.length; index < length; index += 1) { + arguments[index].forEach(collectType); + } + + return result; +} + + +function Schema(definition) { + this.include = definition.include || []; + this.implicit = definition.implicit || []; + this.explicit = definition.explicit || []; + + this.implicit.forEach(function (type) { + if (type.loadKind && type.loadKind !== 'scalar') { + throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.'); + } + }); + + this.compiledImplicit = compileList(this, 'implicit', []); + this.compiledExplicit = compileList(this, 'explicit', []); + this.compiledTypeMap = compileMap(this.compiledImplicit, this.compiledExplicit); +} + + +Schema.DEFAULT = null; + + +Schema.create = function createSchema() { + var schemas, types; + + switch (arguments.length) { + case 1: + schemas = Schema.DEFAULT; + types = arguments[0]; + break; + + case 2: + schemas = arguments[0]; + types = arguments[1]; + break; + + default: + throw new YAMLException('Wrong number of arguments for Schema.create function'); + } + + schemas = common.toArray(schemas); + types = common.toArray(types); + + if (!schemas.every(function (schema) { return schema instanceof Schema; })) { + throw new YAMLException('Specified list of super schemas (or a single Schema object) contains a non-Schema object.'); + } + + if (!types.every(function (type) { return type instanceof Type; })) { + throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.'); + } + + return new Schema({ + include: schemas, + explicit: types + }); +}; + + +module.exports = Schema; + +},{"./common":2,"./exception":4,"./type":13}],8:[function(require,module,exports){ +// Standard YAML's Core schema. +// http://www.yaml.org/spec/1.2/spec.html#id2804923 +// +// NOTE: JS-YAML does not support schema-specific tag resolution restrictions. +// So, Core schema has no distinctions from JSON schema is JS-YAML. + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + include: [ + require('./json') + ] +}); + +},{"../schema":7,"./json":12}],9:[function(require,module,exports){ +// JS-YAML's default schema for `load` function. +// It is not described in the YAML specification. +// +// This schema is based on JS-YAML's default safe schema and includes +// JavaScript-specific types: !!js/undefined, !!js/regexp and !!js/function. +// +// Also this schema is used as default base schema at `Schema.create` function. + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = Schema.DEFAULT = new Schema({ + include: [ + require('./default_safe') + ], + explicit: [ + require('../type/js/undefined'), + require('../type/js/regexp'), + require('../type/js/function') + ] +}); + +},{"../schema":7,"../type/js/function":18,"../type/js/regexp":19,"../type/js/undefined":20,"./default_safe":10}],10:[function(require,module,exports){ +// JS-YAML's default schema for `safeLoad` function. +// It is not described in the YAML specification. +// +// This schema is based on standard YAML's Core schema and includes most of +// extra types described at YAML tag repository. (http://yaml.org/type/) + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + include: [ + require('./core') + ], + implicit: [ + require('../type/timestamp'), + require('../type/merge') + ], + explicit: [ + require('../type/binary'), + require('../type/omap'), + require('../type/pairs'), + require('../type/set') + ] +}); + +},{"../schema":7,"../type/binary":14,"../type/merge":22,"../type/omap":24,"../type/pairs":25,"../type/set":27,"../type/timestamp":29,"./core":8}],11:[function(require,module,exports){ +// Standard YAML's Failsafe schema. +// http://www.yaml.org/spec/1.2/spec.html#id2802346 + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + explicit: [ + require('../type/str'), + require('../type/seq'), + require('../type/map') + ] +}); + +},{"../schema":7,"../type/map":21,"../type/seq":26,"../type/str":28}],12:[function(require,module,exports){ +// Standard YAML's JSON schema. +// http://www.yaml.org/spec/1.2/spec.html#id2803231 +// +// NOTE: JS-YAML does not support schema-specific tag resolution restrictions. +// So, this schema is not such strict as defined in the YAML specification. +// It allows numbers in binary notaion, use `Null` and `NULL` as `null`, etc. + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + include: [ + require('./failsafe') + ], + implicit: [ + require('../type/null'), + require('../type/bool'), + require('../type/int'), + require('../type/float') + ] +}); + +},{"../schema":7,"../type/bool":15,"../type/float":16,"../type/int":17,"../type/null":23,"./failsafe":11}],13:[function(require,module,exports){ +'use strict'; + +var YAMLException = require('./exception'); + +var TYPE_CONSTRUCTOR_OPTIONS = [ + 'kind', + 'resolve', + 'construct', + 'instanceOf', + 'predicate', + 'represent', + 'defaultStyle', + 'styleAliases' +]; + +var YAML_NODE_KINDS = [ + 'scalar', + 'sequence', + 'mapping' +]; + +function compileStyleAliases(map) { + var result = {}; + + if (map !== null) { + Object.keys(map).forEach(function (style) { + map[style].forEach(function (alias) { + result[String(alias)] = style; + }); + }); + } + + return result; +} + +function Type(tag, options) { + options = options || {}; + + Object.keys(options).forEach(function (name) { + if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) { + throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.'); + } + }); + + // TODO: Add tag format check. + this.tag = tag; + this.kind = options['kind'] || null; + this.resolve = options['resolve'] || function () { return true; }; + this.construct = options['construct'] || function (data) { return data; }; + this.instanceOf = options['instanceOf'] || null; + this.predicate = options['predicate'] || null; + this.represent = options['represent'] || null; + this.defaultStyle = options['defaultStyle'] || null; + this.styleAliases = compileStyleAliases(options['styleAliases'] || null); + + if (YAML_NODE_KINDS.indexOf(this.kind) === -1) { + throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.'); + } +} + +module.exports = Type; + +},{"./exception":4}],14:[function(require,module,exports){ +'use strict'; + +/*eslint-disable no-bitwise*/ + +// A trick for browserified version. +// Since we make browserifier to ignore `buffer` module, NodeBuffer will be undefined +var NodeBuffer = require('buffer').Buffer; +var Type = require('../type'); + + +// [ 64, 65, 66 ] -> [ padding, CR, LF ] +var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r'; + + +function resolveYamlBinary(data) { + if (data === null) return false; + + var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP; + + // Convert one by one. + for (idx = 0; idx < max; idx++) { + code = map.indexOf(data.charAt(idx)); + + // Skip CR/LF + if (code > 64) continue; + + // Fail on illegal characters + if (code < 0) return false; + + bitlen += 6; + } + + // If there are any bits left, source was corrupted + return (bitlen % 8) === 0; +} + +function constructYamlBinary(data) { + var idx, tailbits, + input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan + max = input.length, + map = BASE64_MAP, + bits = 0, + result = []; + + // Collect by 6*4 bits (3 bytes) + + for (idx = 0; idx < max; idx++) { + if ((idx % 4 === 0) && idx) { + result.push((bits >> 16) & 0xFF); + result.push((bits >> 8) & 0xFF); + result.push(bits & 0xFF); + } + + bits = (bits << 6) | map.indexOf(input.charAt(idx)); + } + + // Dump tail + + tailbits = (max % 4) * 6; + + if (tailbits === 0) { + result.push((bits >> 16) & 0xFF); + result.push((bits >> 8) & 0xFF); + result.push(bits & 0xFF); + } else if (tailbits === 18) { + result.push((bits >> 10) & 0xFF); + result.push((bits >> 2) & 0xFF); + } else if (tailbits === 12) { + result.push((bits >> 4) & 0xFF); + } + + // Wrap into Buffer for NodeJS and leave Array for browser + if (NodeBuffer) return new NodeBuffer(result); + + return result; +} + +function representYamlBinary(object /*, style*/) { + var result = '', bits = 0, idx, tail, + max = object.length, + map = BASE64_MAP; + + // Convert every three bytes to 4 ASCII characters. + + for (idx = 0; idx < max; idx++) { + if ((idx % 3 === 0) && idx) { + result += map[(bits >> 18) & 0x3F]; + result += map[(bits >> 12) & 0x3F]; + result += map[(bits >> 6) & 0x3F]; + result += map[bits & 0x3F]; + } + + bits = (bits << 8) + object[idx]; + } + + // Dump tail + + tail = max % 3; + + if (tail === 0) { + result += map[(bits >> 18) & 0x3F]; + result += map[(bits >> 12) & 0x3F]; + result += map[(bits >> 6) & 0x3F]; + result += map[bits & 0x3F]; + } else if (tail === 2) { + result += map[(bits >> 10) & 0x3F]; + result += map[(bits >> 4) & 0x3F]; + result += map[(bits << 2) & 0x3F]; + result += map[64]; + } else if (tail === 1) { + result += map[(bits >> 2) & 0x3F]; + result += map[(bits << 4) & 0x3F]; + result += map[64]; + result += map[64]; + } + + return result; +} + +function isBinary(object) { + return NodeBuffer && NodeBuffer.isBuffer(object); +} + +module.exports = new Type('tag:yaml.org,2002:binary', { + kind: 'scalar', + resolve: resolveYamlBinary, + construct: constructYamlBinary, + predicate: isBinary, + represent: representYamlBinary +}); + +},{"../type":13,"buffer":30}],15:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +function resolveYamlBoolean(data) { + if (data === null) return false; + + var max = data.length; + + return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) || + (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE')); +} + +function constructYamlBoolean(data) { + return data === 'true' || + data === 'True' || + data === 'TRUE'; +} + +function isBoolean(object) { + return Object.prototype.toString.call(object) === '[object Boolean]'; +} + +module.exports = new Type('tag:yaml.org,2002:bool', { + kind: 'scalar', + resolve: resolveYamlBoolean, + construct: constructYamlBoolean, + predicate: isBoolean, + represent: { + lowercase: function (object) { return object ? 'true' : 'false'; }, + uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; }, + camelcase: function (object) { return object ? 'True' : 'False'; } + }, + defaultStyle: 'lowercase' +}); + +},{"../type":13}],16:[function(require,module,exports){ +'use strict'; + +var common = require('../common'); +var Type = require('../type'); + +var YAML_FLOAT_PATTERN = new RegExp( + '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' + + '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' + + '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' + + '|[-+]?\\.(?:inf|Inf|INF)' + + '|\\.(?:nan|NaN|NAN))$'); + +function resolveYamlFloat(data) { + if (data === null) return false; + + if (!YAML_FLOAT_PATTERN.test(data)) return false; + + return true; +} + +function constructYamlFloat(data) { + var value, sign, base, digits; + + value = data.replace(/_/g, '').toLowerCase(); + sign = value[0] === '-' ? -1 : 1; + digits = []; + + if ('+-'.indexOf(value[0]) >= 0) { + value = value.slice(1); + } + + if (value === '.inf') { + return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; + + } else if (value === '.nan') { + return NaN; + + } else if (value.indexOf(':') >= 0) { + value.split(':').forEach(function (v) { + digits.unshift(parseFloat(v, 10)); + }); + + value = 0.0; + base = 1; + + digits.forEach(function (d) { + value += d * base; + base *= 60; + }); + + return sign * value; + + } + return sign * parseFloat(value, 10); +} + + +var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/; + +function representYamlFloat(object, style) { + var res; + + if (isNaN(object)) { + switch (style) { + case 'lowercase': return '.nan'; + case 'uppercase': return '.NAN'; + case 'camelcase': return '.NaN'; + } + } else if (Number.POSITIVE_INFINITY === object) { + switch (style) { + case 'lowercase': return '.inf'; + case 'uppercase': return '.INF'; + case 'camelcase': return '.Inf'; + } + } else if (Number.NEGATIVE_INFINITY === object) { + switch (style) { + case 'lowercase': return '-.inf'; + case 'uppercase': return '-.INF'; + case 'camelcase': return '-.Inf'; + } + } else if (common.isNegativeZero(object)) { + return '-0.0'; + } + + res = object.toString(10); + + // JS stringifier can build scientific format without dots: 5e-100, + // while YAML requres dot: 5.e-100. Fix it with simple hack + + return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res; +} + +function isFloat(object) { + return (Object.prototype.toString.call(object) === '[object Number]') && + (object % 1 !== 0 || common.isNegativeZero(object)); +} + +module.exports = new Type('tag:yaml.org,2002:float', { + kind: 'scalar', + resolve: resolveYamlFloat, + construct: constructYamlFloat, + predicate: isFloat, + represent: representYamlFloat, + defaultStyle: 'lowercase' +}); + +},{"../common":2,"../type":13}],17:[function(require,module,exports){ +'use strict'; + +var common = require('../common'); +var Type = require('../type'); + +function isHexCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) || + ((0x41/* A */ <= c) && (c <= 0x46/* F */)) || + ((0x61/* a */ <= c) && (c <= 0x66/* f */)); +} + +function isOctCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */)); +} + +function isDecCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)); +} + +function resolveYamlInteger(data) { + if (data === null) return false; + + var max = data.length, + index = 0, + hasDigits = false, + ch; + + if (!max) return false; + + ch = data[index]; + + // sign + if (ch === '-' || ch === '+') { + ch = data[++index]; + } + + if (ch === '0') { + // 0 + if (index + 1 === max) return true; + ch = data[++index]; + + // base 2, base 8, base 16 + + if (ch === 'b') { + // base 2 + index++; + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (ch !== '0' && ch !== '1') return false; + hasDigits = true; + } + return hasDigits; + } + + + if (ch === 'x') { + // base 16 + index++; + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (!isHexCode(data.charCodeAt(index))) return false; + hasDigits = true; + } + return hasDigits; + } + + // base 8 + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (!isOctCode(data.charCodeAt(index))) return false; + hasDigits = true; + } + return hasDigits; + } + + // base 10 (except 0) or base 60 + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (ch === ':') break; + if (!isDecCode(data.charCodeAt(index))) { + return false; + } + hasDigits = true; + } + + if (!hasDigits) return false; + + // if !base60 - done; + if (ch !== ':') return true; + + // base60 almost not used, no needs to optimize + return /^(:[0-5]?[0-9])+$/.test(data.slice(index)); +} + +function constructYamlInteger(data) { + var value = data, sign = 1, ch, base, digits = []; + + if (value.indexOf('_') !== -1) { + value = value.replace(/_/g, ''); + } + + ch = value[0]; + + if (ch === '-' || ch === '+') { + if (ch === '-') sign = -1; + value = value.slice(1); + ch = value[0]; + } + + if (value === '0') return 0; + + if (ch === '0') { + if (value[1] === 'b') return sign * parseInt(value.slice(2), 2); + if (value[1] === 'x') return sign * parseInt(value, 16); + return sign * parseInt(value, 8); + } + + if (value.indexOf(':') !== -1) { + value.split(':').forEach(function (v) { + digits.unshift(parseInt(v, 10)); + }); + + value = 0; + base = 1; + + digits.forEach(function (d) { + value += (d * base); + base *= 60; + }); + + return sign * value; + + } + + return sign * parseInt(value, 10); +} + +function isInteger(object) { + return (Object.prototype.toString.call(object)) === '[object Number]' && + (object % 1 === 0 && !common.isNegativeZero(object)); +} + +module.exports = new Type('tag:yaml.org,2002:int', { + kind: 'scalar', + resolve: resolveYamlInteger, + construct: constructYamlInteger, + predicate: isInteger, + represent: { + binary: function (object) { return '0b' + object.toString(2); }, + octal: function (object) { return '0' + object.toString(8); }, + decimal: function (object) { return object.toString(10); }, + hexadecimal: function (object) { return '0x' + object.toString(16).toUpperCase(); } + }, + defaultStyle: 'decimal', + styleAliases: { + binary: [ 2, 'bin' ], + octal: [ 8, 'oct' ], + decimal: [ 10, 'dec' ], + hexadecimal: [ 16, 'hex' ] + } +}); + +},{"../common":2,"../type":13}],18:[function(require,module,exports){ +'use strict'; + +var esprima; + +// Browserified version does not have esprima +// +// 1. For node.js just require module as deps +// 2. For browser try to require mudule via external AMD system. +// If not found - try to fallback to window.esprima. If not +// found too - then fail to parse. +// +try { + // workaround to exclude package from browserify list. + var _require = require; + esprima = _require('esprima'); +} catch (_) { + /*global window */ + if (typeof window !== 'undefined') esprima = window.esprima; +} + +var Type = require('../../type'); + +function resolveJavascriptFunction(data) { + if (data === null) return false; + + try { + var source = '(' + data + ')', + ast = esprima.parse(source, { range: true }); + + if (ast.type !== 'Program' || + ast.body.length !== 1 || + ast.body[0].type !== 'ExpressionStatement' || + ast.body[0].expression.type !== 'FunctionExpression') { + return false; + } + + return true; + } catch (err) { + return false; + } +} + +function constructJavascriptFunction(data) { + /*jslint evil:true*/ + + var source = '(' + data + ')', + ast = esprima.parse(source, { range: true }), + params = [], + body; + + if (ast.type !== 'Program' || + ast.body.length !== 1 || + ast.body[0].type !== 'ExpressionStatement' || + ast.body[0].expression.type !== 'FunctionExpression') { + throw new Error('Failed to resolve function'); + } + + ast.body[0].expression.params.forEach(function (param) { + params.push(param.name); + }); + + body = ast.body[0].expression.body.range; + + // Esprima's ranges include the first '{' and the last '}' characters on + // function expressions. So cut them out. + /*eslint-disable no-new-func*/ + return new Function(params, source.slice(body[0] + 1, body[1] - 1)); +} + +function representJavascriptFunction(object /*, style*/) { + return object.toString(); +} + +function isFunction(object) { + return Object.prototype.toString.call(object) === '[object Function]'; +} + +module.exports = new Type('tag:yaml.org,2002:js/function', { + kind: 'scalar', + resolve: resolveJavascriptFunction, + construct: constructJavascriptFunction, + predicate: isFunction, + represent: representJavascriptFunction +}); + +},{"../../type":13}],19:[function(require,module,exports){ +'use strict'; + +var Type = require('../../type'); + +function resolveJavascriptRegExp(data) { + if (data === null) return false; + if (data.length === 0) return false; + + var regexp = data, + tail = /\/([gim]*)$/.exec(data), + modifiers = ''; + + // if regexp starts with '/' it can have modifiers and must be properly closed + // `/foo/gim` - modifiers tail can be maximum 3 chars + if (regexp[0] === '/') { + if (tail) modifiers = tail[1]; + + if (modifiers.length > 3) return false; + // if expression starts with /, is should be properly terminated + if (regexp[regexp.length - modifiers.length - 1] !== '/') return false; + } + + return true; +} + +function constructJavascriptRegExp(data) { + var regexp = data, + tail = /\/([gim]*)$/.exec(data), + modifiers = ''; + + // `/foo/gim` - tail can be maximum 4 chars + if (regexp[0] === '/') { + if (tail) modifiers = tail[1]; + regexp = regexp.slice(1, regexp.length - modifiers.length - 1); + } + + return new RegExp(regexp, modifiers); +} + +function representJavascriptRegExp(object /*, style*/) { + var result = '/' + object.source + '/'; + + if (object.global) result += 'g'; + if (object.multiline) result += 'm'; + if (object.ignoreCase) result += 'i'; + + return result; +} + +function isRegExp(object) { + return Object.prototype.toString.call(object) === '[object RegExp]'; +} + +module.exports = new Type('tag:yaml.org,2002:js/regexp', { + kind: 'scalar', + resolve: resolveJavascriptRegExp, + construct: constructJavascriptRegExp, + predicate: isRegExp, + represent: representJavascriptRegExp +}); + +},{"../../type":13}],20:[function(require,module,exports){ +'use strict'; + +var Type = require('../../type'); + +function resolveJavascriptUndefined() { + return true; +} + +function constructJavascriptUndefined() { + /*eslint-disable no-undefined*/ + return undefined; +} + +function representJavascriptUndefined() { + return ''; +} + +function isUndefined(object) { + return typeof object === 'undefined'; +} + +module.exports = new Type('tag:yaml.org,2002:js/undefined', { + kind: 'scalar', + resolve: resolveJavascriptUndefined, + construct: constructJavascriptUndefined, + predicate: isUndefined, + represent: representJavascriptUndefined +}); + +},{"../../type":13}],21:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +module.exports = new Type('tag:yaml.org,2002:map', { + kind: 'mapping', + construct: function (data) { return data !== null ? data : {}; } +}); + +},{"../type":13}],22:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +function resolveYamlMerge(data) { + return data === '<<' || data === null; +} + +module.exports = new Type('tag:yaml.org,2002:merge', { + kind: 'scalar', + resolve: resolveYamlMerge +}); + +},{"../type":13}],23:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +function resolveYamlNull(data) { + if (data === null) return true; + + var max = data.length; + + return (max === 1 && data === '~') || + (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL')); +} + +function constructYamlNull() { + return null; +} + +function isNull(object) { + return object === null; +} + +module.exports = new Type('tag:yaml.org,2002:null', { + kind: 'scalar', + resolve: resolveYamlNull, + construct: constructYamlNull, + predicate: isNull, + represent: { + canonical: function () { return '~'; }, + lowercase: function () { return 'null'; }, + uppercase: function () { return 'NULL'; }, + camelcase: function () { return 'Null'; } + }, + defaultStyle: 'lowercase' +}); + +},{"../type":13}],24:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +var _hasOwnProperty = Object.prototype.hasOwnProperty; +var _toString = Object.prototype.toString; + +function resolveYamlOmap(data) { + if (data === null) return true; + + var objectKeys = [], index, length, pair, pairKey, pairHasKey, + object = data; + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + pairHasKey = false; + + if (_toString.call(pair) !== '[object Object]') return false; + + for (pairKey in pair) { + if (_hasOwnProperty.call(pair, pairKey)) { + if (!pairHasKey) pairHasKey = true; + else return false; + } + } + + if (!pairHasKey) return false; + + if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey); + else return false; + } + + return true; +} + +function constructYamlOmap(data) { + return data !== null ? data : []; +} + +module.exports = new Type('tag:yaml.org,2002:omap', { + kind: 'sequence', + resolve: resolveYamlOmap, + construct: constructYamlOmap +}); + +},{"../type":13}],25:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +var _toString = Object.prototype.toString; + +function resolveYamlPairs(data) { + if (data === null) return true; + + var index, length, pair, keys, result, + object = data; + + result = new Array(object.length); + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + + if (_toString.call(pair) !== '[object Object]') return false; + + keys = Object.keys(pair); + + if (keys.length !== 1) return false; + + result[index] = [ keys[0], pair[keys[0]] ]; + } + + return true; +} + +function constructYamlPairs(data) { + if (data === null) return []; + + var index, length, pair, keys, result, + object = data; + + result = new Array(object.length); + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + + keys = Object.keys(pair); + + result[index] = [ keys[0], pair[keys[0]] ]; + } + + return result; +} + +module.exports = new Type('tag:yaml.org,2002:pairs', { + kind: 'sequence', + resolve: resolveYamlPairs, + construct: constructYamlPairs +}); + +},{"../type":13}],26:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +module.exports = new Type('tag:yaml.org,2002:seq', { + kind: 'sequence', + construct: function (data) { return data !== null ? data : []; } +}); + +},{"../type":13}],27:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +var _hasOwnProperty = Object.prototype.hasOwnProperty; + +function resolveYamlSet(data) { + if (data === null) return true; + + var key, object = data; + + for (key in object) { + if (_hasOwnProperty.call(object, key)) { + if (object[key] !== null) return false; + } + } + + return true; +} + +function constructYamlSet(data) { + return data !== null ? data : {}; +} + +module.exports = new Type('tag:yaml.org,2002:set', { + kind: 'mapping', + resolve: resolveYamlSet, + construct: constructYamlSet +}); + +},{"../type":13}],28:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +module.exports = new Type('tag:yaml.org,2002:str', { + kind: 'scalar', + construct: function (data) { return data !== null ? data : ''; } +}); + +},{"../type":13}],29:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +var YAML_DATE_REGEXP = new RegExp( + '^([0-9][0-9][0-9][0-9])' + // [1] year + '-([0-9][0-9])' + // [2] month + '-([0-9][0-9])$'); // [3] day + +var YAML_TIMESTAMP_REGEXP = new RegExp( + '^([0-9][0-9][0-9][0-9])' + // [1] year + '-([0-9][0-9]?)' + // [2] month + '-([0-9][0-9]?)' + // [3] day + '(?:[Tt]|[ \\t]+)' + // ... + '([0-9][0-9]?)' + // [4] hour + ':([0-9][0-9])' + // [5] minute + ':([0-9][0-9])' + // [6] second + '(?:\\.([0-9]*))?' + // [7] fraction + '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour + '(?::([0-9][0-9]))?))?$'); // [11] tz_minute + +function resolveYamlTimestamp(data) { + if (data === null) return false; + if (YAML_DATE_REGEXP.exec(data) !== null) return true; + if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true; + return false; +} + +function constructYamlTimestamp(data) { + var match, year, month, day, hour, minute, second, fraction = 0, + delta = null, tz_hour, tz_minute, date; + + match = YAML_DATE_REGEXP.exec(data); + if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data); + + if (match === null) throw new Error('Date resolve error'); + + // match: [1] year [2] month [3] day + + year = +(match[1]); + month = +(match[2]) - 1; // JS month starts with 0 + day = +(match[3]); + + if (!match[4]) { // no hour + return new Date(Date.UTC(year, month, day)); + } + + // match: [4] hour [5] minute [6] second [7] fraction + + hour = +(match[4]); + minute = +(match[5]); + second = +(match[6]); + + if (match[7]) { + fraction = match[7].slice(0, 3); + while (fraction.length < 3) { // milli-seconds + fraction += '0'; + } + fraction = +fraction; + } + + // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute + + if (match[9]) { + tz_hour = +(match[10]); + tz_minute = +(match[11] || 0); + delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds + if (match[9] === '-') delta = -delta; + } + + date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction)); + + if (delta) date.setTime(date.getTime() - delta); + + return date; +} + +function representYamlTimestamp(object /*, style*/) { + return object.toISOString(); +} + +module.exports = new Type('tag:yaml.org,2002:timestamp', { + kind: 'scalar', + resolve: resolveYamlTimestamp, + construct: constructYamlTimestamp, + instanceOf: Date, + represent: representYamlTimestamp +}); + +},{"../type":13}],30:[function(require,module,exports){ + +},{}],"/":[function(require,module,exports){ +'use strict'; + + +var yaml = require('./lib/js-yaml.js'); + + +module.exports = yaml; + +},{"./lib/js-yaml.js":1}]},{},[])("/") +}); \ No newline at end of file diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/dist/js-yaml.min.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/dist/js-yaml.min.js new file mode 100644 index 0000000..c2ada83 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/dist/js-yaml.min.js @@ -0,0 +1,3 @@ +/* js-yaml 3.5.5 https://github.com/nodeca/js-yaml */ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.jsyaml=e()}}(function(){return function e(t,n,i){function r(a,s){if(!n[a]){if(!t[a]){var c="function"==typeof require&&require;if(!s&&c)return c(a,!0);if(o)return o(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var l=n[a]={exports:{}};t[a][0].call(l.exports,function(e){var n=t[a][1][e];return r(n?n:e)},l,l.exports,e,t,n,i)}return n[a].exports}for(var o="function"==typeof require&&require,a=0;an;n+=1)r=o[n],e[r]=t[r];return e}function s(e,t){var n,i="";for(n=0;t>n;n+=1)i+=e;return i}function c(e){return 0===e&&Number.NEGATIVE_INFINITY===1/e}t.exports.isNothing=i,t.exports.isObject=r,t.exports.toArray=o,t.exports.repeat=s,t.exports.isNegativeZero=c,t.exports.extend=a},{}],3:[function(e,t,n){"use strict";function i(e,t){var n,i,r,o,a,s,c;if(null===t)return{};for(n={},i=Object.keys(t),r=0,o=i.length;o>r;r+=1)a=i[r],s=String(t[a]),"!!"===a.slice(0,2)&&(a="tag:yaml.org,2002:"+a.slice(2)),c=e.compiledTypeMap[a],c&&F.call(c.styleAliases,s)&&(s=c.styleAliases[s]),n[a]=s;return n}function r(e){var t,n,i;if(t=e.toString(16).toUpperCase(),255>=e)n="x",i=2;else if(65535>=e)n="u",i=4;else{if(!(4294967295>=e))throw new I("code point within a string may not be greater than 0xFFFFFFFF");n="U",i=8}return"\\"+n+j.repeat("0",i-t.length)+t}function o(e){this.schema=e.schema||S,this.indent=Math.max(1,e.indent||2),this.skipInvalid=e.skipInvalid||!1,this.flowLevel=j.isNothing(e.flowLevel)?-1:e.flowLevel,this.styleMap=i(this.schema,e.styles||null),this.sortKeys=e.sortKeys||!1,this.lineWidth=e.lineWidth||80,this.noRefs=e.noRefs||!1,this.noCompatMode=e.noCompatMode||!1,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function a(e,t){for(var n,i=j.repeat(" ",t),r=0,o=-1,a="",s=e.length;s>r;)o=e.indexOf("\n",r),-1===o?(n=e.slice(r),r=s):(n=e.slice(r,o+1),r=o+1),n.length&&"\n"!==n&&(a+=i),a+=n;return a}function s(e,t){return"\n"+j.repeat(" ",e.indent*t)}function c(e,t){var n,i,r;for(n=0,i=e.implicitTypes.length;i>n;n+=1)if(r=e.implicitTypes[n],r.resolve(t))return!0;return!1}function u(e){this.source=e,this.result="",this.checkpoint=0}function l(e,t,n,i){var r,o,s,l,f,m,g,y,x,v,A,b,w,C,k,j,I,S,E,O,F;if(0===t.length)return void(e.dump="''");if(!e.noCompatMode&&-1!==te.indexOf(t))return void(e.dump="'"+t+"'");for(r=!0,o=t.length?t.charCodeAt(0):0,s=M===o||M===t.charCodeAt(t.length-1),P!==o&&W!==o&&G!==o&&z!==o||(r=!1),s||e.flowLevel>-1&&e.flowLevel<=n?(s&&(r=!1),l=!1,f=!1):(l=!i,f=!i),m=!0,g=new u(t),y=!1,x=0,v=0,A=e.indent*n,b=e.lineWidth,-1===b&&(b=9007199254740991),40>A?b-=A:b=40,C=0;C0&&(I=t.charCodeAt(C-1),I===M&&(f=!1,l=!1)),l&&(S=C-x,x=C,S>v&&(v=S))),w!==D&&(m=!1),g.takeUpTo(C),g.escapeChar())}if(r&&c(e,t)&&(r=!1),E="",(l||f)&&(O=0,t.charCodeAt(t.length-1)===T&&(O+=1,t.charCodeAt(t.length-2)===T&&(O+=1)),0===O?E="-":2===O&&(E="+")),(f&&b>v||null!==e.tag)&&(l=!1),y||(f=!1),r)e.dump=t;else if(m)e.dump="'"+t+"'";else if(l)F=p(t,b),e.dump=">"+E+"\n"+a(F,A);else if(f)E||(t=t.replace(/\n$/,"")),e.dump="|"+E+"\n"+a(t,A);else{if(!g)throw new Error("Failed to dump scalar value");g.finish(),e.dump='"'+g.result+'"'}}function p(e,t){var n,i="",r=0,o=e.length,a=/\n+$/.exec(e);for(a&&(o=a.index+1);o>r;)n=e.indexOf("\n",r),n>o||-1===n?(i&&(i+="\n\n"),i+=f(e.slice(r,o),t),r=o):(i&&(i+="\n\n"),i+=f(e.slice(r,n),t),r=n+1);return a&&"\n"!==a[0]&&(i+=a[0]),i}function f(e,t){if(""===e)return e;for(var n,i,r,o=/[^\s] [^\s]/g,a="",s=0,c=0,u=o.exec(e);u;)n=u.index,n-c>t&&(i=s!==c?s:n,a&&(a+="\n"),r=e.slice(c,i),a+=r,c=i+1),s=n+1,u=o.exec(e);return a&&(a+="\n"),a+=c!==s&&e.length-c>t?e.slice(c,s)+"\n"+e.slice(s+1):e.slice(c)}function h(e){return N!==e&&T!==e&&_!==e&&B!==e&&V!==e&&Z!==e&&J!==e&&X!==e&&U!==e&&Y!==e&&$!==e&&L!==e&&Q!==e&&H!==e&&R!==e&&D!==e&&q!==e&&K!==e&&!ee[e]&&!d(e)}function d(e){return!(e>=32&&126>=e||133===e||e>=160&&55295>=e||e>=57344&&65533>=e||e>=65536&&1114111>=e)}function m(e,t,n){var i,r,o="",a=e.tag;for(i=0,r=n.length;r>i;i+=1)A(e,t,n[i],!1,!1)&&(0!==i&&(o+=", "),o+=e.dump);e.tag=a,e.dump="["+o+"]"}function g(e,t,n,i){var r,o,a="",c=e.tag;for(r=0,o=n.length;o>r;r+=1)A(e,t+1,n[r],!0,!0)&&(i&&0===r||(a+=s(e,t)),a+="- "+e.dump);e.tag=c,e.dump=a||"[]"}function y(e,t,n){var i,r,o,a,s,c="",u=e.tag,l=Object.keys(n);for(i=0,r=l.length;r>i;i+=1)s="",0!==i&&(s+=", "),o=l[i],a=n[o],A(e,t,o,!1,!1)&&(e.dump.length>1024&&(s+="? "),s+=e.dump+": ",A(e,t,a,!1,!1)&&(s+=e.dump,c+=s));e.tag=u,e.dump="{"+c+"}"}function x(e,t,n,i){var r,o,a,c,u,l,p="",f=e.tag,h=Object.keys(n);if(e.sortKeys===!0)h.sort();else if("function"==typeof e.sortKeys)h.sort(e.sortKeys);else if(e.sortKeys)throw new I("sortKeys must be a boolean or a function");for(r=0,o=h.length;o>r;r+=1)l="",i&&0===r||(l+=s(e,t)),a=h[r],c=n[a],A(e,t+1,a,!0,!0,!0)&&(u=null!==e.tag&&"?"!==e.tag||e.dump&&e.dump.length>1024,u&&(l+=e.dump&&T===e.dump.charCodeAt(0)?"?":"? "),l+=e.dump,u&&(l+=s(e,t)),A(e,t+1,c,!0,u)&&(l+=e.dump&&T===e.dump.charCodeAt(0)?":":": ",l+=e.dump,p+=l));e.tag=f,e.dump=p||"{}"}function v(e,t,n){var i,r,o,a,s,c;for(r=n?e.explicitTypes:e.implicitTypes,o=0,a=r.length;a>o;o+=1)if(s=r[o],(s.instanceOf||s.predicate)&&(!s.instanceOf||"object"==typeof t&&t instanceof s.instanceOf)&&(!s.predicate||s.predicate(t))){if(e.tag=n?s.tag:"?",s.represent){if(c=e.styleMap[s.tag]||s.defaultStyle,"[object Function]"===O.call(s.represent))i=s.represent(t,c);else{if(!F.call(s.represent,c))throw new I("!<"+s.tag+'> tag resolver accepts not "'+c+'" style');i=s.represent[c](t,c)}e.dump=i}return!0}return!1}function A(e,t,n,i,r,o){e.tag=null,e.dump=n,v(e,n,!1)||v(e,n,!0);var a=O.call(e.dump);i&&(i=e.flowLevel<0||e.flowLevel>t);var s,c,u="[object Object]"===a||"[object Array]"===a;if(u&&(s=e.duplicates.indexOf(n),c=-1!==s),(null!==e.tag&&"?"!==e.tag||c||2!==e.indent&&t>0)&&(r=!1),c&&e.usedDuplicates[s])e.dump="*ref_"+s;else{if(u&&c&&!e.usedDuplicates[s]&&(e.usedDuplicates[s]=!0),"[object Object]"===a)i&&0!==Object.keys(e.dump).length?(x(e,t,e.dump,r),c&&(e.dump="&ref_"+s+e.dump)):(y(e,t,e.dump),c&&(e.dump="&ref_"+s+" "+e.dump));else if("[object Array]"===a)i&&0!==e.dump.length?(g(e,t,e.dump,r),c&&(e.dump="&ref_"+s+e.dump)):(m(e,t,e.dump),c&&(e.dump="&ref_"+s+" "+e.dump));else{if("[object String]"!==a){if(e.skipInvalid)return!1;throw new I("unacceptable kind of an object to dump "+a)}"?"!==e.tag&&l(e,e.dump,t,o)}null!==e.tag&&"?"!==e.tag&&(e.dump="!<"+e.tag+"> "+e.dump)}return!0}function b(e,t){var n,i,r=[],o=[];for(w(e,r,o),n=0,i=o.length;i>n;n+=1)t.duplicates.push(r[o[n]]);t.usedDuplicates=new Array(i)}function w(e,t,n){var i,r,o;if(null!==e&&"object"==typeof e)if(r=t.indexOf(e),-1!==r)-1===n.indexOf(r)&&n.push(r);else if(t.push(e),Array.isArray(e))for(r=0,o=e.length;o>r;r+=1)w(e[r],t,n);else for(i=Object.keys(e),r=0,o=i.length;o>r;r+=1)w(e[i[r]],t,n)}function C(e,t){t=t||{};var n=new o(t);return n.noRefs||b(e,n),A(n,0,e,!0,!0)?n.dump+"\n":""}function k(e,t){return C(e,j.extend({schema:E},t))}var j=e("./common"),I=e("./exception"),S=e("./schema/default_full"),E=e("./schema/default_safe"),O=Object.prototype.toString,F=Object.prototype.hasOwnProperty,N=9,T=10,_=13,M=32,L=33,D=34,U=35,q=37,Y=38,R=39,$=42,B=44,P=45,K=58,H=62,W=63,G=64,V=91,Z=93,z=96,J=123,Q=124,X=125,ee={};ee[0]="\\0",ee[7]="\\a",ee[8]="\\b",ee[9]="\\t",ee[10]="\\n",ee[11]="\\v",ee[12]="\\f",ee[13]="\\r",ee[27]="\\e",ee[34]='\\"',ee[92]="\\\\",ee[133]="\\N",ee[160]="\\_",ee[8232]="\\L",ee[8233]="\\P";var te=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"];u.prototype.takeUpTo=function(e){var t;if(e checkpoint"),t.position=e,t.checkpoint=this.checkpoint,t;return this.result+=this.source.slice(this.checkpoint,e),this.checkpoint=e,this},u.prototype.escapeChar=function(){var e,t;return e=this.source.charCodeAt(this.checkpoint),t=ee[e]||r(e),this.result+=t,this.checkpoint+=1,this},u.prototype.finish=function(){this.source.length>this.checkpoint&&this.takeUpTo(this.source.length)},t.exports.dump=C,t.exports.safeDump=k},{"./common":2,"./exception":4,"./schema/default_full":9,"./schema/default_safe":10}],4:[function(e,t,n){"use strict";function i(e,t){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||"",this.name="YAMLException",this.reason=e,this.mark=t,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():"")}i.prototype=Object.create(Error.prototype),i.prototype.constructor=i,i.prototype.toString=function(e){var t=this.name+": ";return t+=this.reason||"(unknown reason)",!e&&this.mark&&(t+=" "+this.mark.toString()),t},t.exports=i},{}],5:[function(e,t,n){"use strict";function i(e){return 10===e||13===e}function r(e){return 9===e||32===e}function o(e){return 9===e||32===e||10===e||13===e}function a(e){return 44===e||91===e||93===e||123===e||125===e}function s(e){var t;return e>=48&&57>=e?e-48:(t=32|e,t>=97&&102>=t?t-97+10:-1)}function c(e){return 120===e?2:117===e?4:85===e?8:0}function u(e){return e>=48&&57>=e?e-48:-1}function l(e){return 48===e?"\x00":97===e?"":98===e?"\b":116===e?" ":9===e?" ":110===e?"\n":118===e?"\x0B":102===e?"\f":114===e?"\r":101===e?"":32===e?" ":34===e?'"':47===e?"/":92===e?"\\":78===e?"…":95===e?" ":76===e?"\u2028":80===e?"\u2029":""}function p(e){return 65535>=e?String.fromCharCode(e):String.fromCharCode((e-65536>>10)+55296,(e-65536&1023)+56320)}function f(e,t){this.input=e,this.filename=t.filename||null,this.schema=t.schema||K,this.onWarning=t.onWarning||null,this.legacy=t.legacy||!1,this.json=t.json||!1,this.listener=t.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=e.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function h(e,t){return new $(t,new B(e.filename,e.input,e.position,e.line,e.position-e.lineStart))}function d(e,t){throw h(e,t)}function m(e,t){e.onWarning&&e.onWarning.call(null,h(e,t))}function g(e,t,n,i){var r,o,a,s;if(n>t){if(s=e.input.slice(t,n),i)for(r=0,o=s.length;o>r;r+=1)a=s.charCodeAt(r),9===a||a>=32&&1114111>=a||d(e,"expected valid JSON character");else X.test(s)&&d(e,"the stream contains non-printable characters");e.result+=s}}function y(e,t,n,i){var r,o,a,s;for(R.isObject(n)||d(e,"cannot merge mappings; the provided source object is unacceptable"),r=Object.keys(n),a=0,s=r.length;s>a;a+=1)o=r[a],H.call(t,o)||(t[o]=n[o],i[o]=!0)}function x(e,t,n,i,r,o){var a,s;if(r=String(r),null===t&&(t={}),"tag:yaml.org,2002:merge"===i)if(Array.isArray(o))for(a=0,s=o.length;s>a;a+=1)y(e,t,o[a],n);else y(e,t,o,n);else e.json||H.call(n,r)||!H.call(t,r)||d(e,"duplicated mapping key"),t[r]=o,delete n[r];return t}function v(e){var t;t=e.input.charCodeAt(e.position),10===t?e.position++:13===t?(e.position++,10===e.input.charCodeAt(e.position)&&e.position++):d(e,"a line break is expected"),e.line+=1,e.lineStart=e.position}function A(e,t,n){for(var o=0,a=e.input.charCodeAt(e.position);0!==a;){for(;r(a);)a=e.input.charCodeAt(++e.position);if(t&&35===a)do a=e.input.charCodeAt(++e.position);while(10!==a&&13!==a&&0!==a);if(!i(a))break;for(v(e),a=e.input.charCodeAt(e.position),o++,e.lineIndent=0;32===a;)e.lineIndent++,a=e.input.charCodeAt(++e.position)}return-1!==n&&0!==o&&e.lineIndent1&&(e.result+=R.repeat("\n",t-1))}function C(e,t,n){var s,c,u,l,p,f,h,d,m,y=e.kind,x=e.result;if(m=e.input.charCodeAt(e.position),o(m)||a(m)||35===m||38===m||42===m||33===m||124===m||62===m||39===m||34===m||37===m||64===m||96===m)return!1;if((63===m||45===m)&&(c=e.input.charCodeAt(e.position+1),o(c)||n&&a(c)))return!1;for(e.kind="scalar",e.result="",u=l=e.position,p=!1;0!==m;){if(58===m){if(c=e.input.charCodeAt(e.position+1),o(c)||n&&a(c))break}else if(35===m){if(s=e.input.charCodeAt(e.position-1),o(s))break}else{if(e.position===e.lineStart&&b(e)||n&&a(m))break;if(i(m)){if(f=e.line,h=e.lineStart,d=e.lineIndent,A(e,!1,-1),e.lineIndent>=t){p=!0,m=e.input.charCodeAt(e.position);continue}e.position=l,e.line=f,e.lineStart=h,e.lineIndent=d;break}}p&&(g(e,u,l,!1),w(e,e.line-f),u=l=e.position,p=!1),r(m)||(l=e.position+1),m=e.input.charCodeAt(++e.position)}return g(e,u,l,!1),e.result?!0:(e.kind=y,e.result=x,!1)}function k(e,t){var n,r,o;if(n=e.input.charCodeAt(e.position),39!==n)return!1;for(e.kind="scalar",e.result="",e.position++,r=o=e.position;0!==(n=e.input.charCodeAt(e.position));)if(39===n){if(g(e,r,e.position,!0),n=e.input.charCodeAt(++e.position),39!==n)return!0;r=o=e.position,e.position++}else i(n)?(g(e,r,o,!0),w(e,A(e,!1,t)),r=o=e.position):e.position===e.lineStart&&b(e)?d(e,"unexpected end of the document within a single quoted scalar"):(e.position++,o=e.position);d(e,"unexpected end of the stream within a single quoted scalar")}function j(e,t){var n,r,o,a,u,l;if(l=e.input.charCodeAt(e.position),34!==l)return!1;for(e.kind="scalar",e.result="",e.position++,n=r=e.position;0!==(l=e.input.charCodeAt(e.position));){if(34===l)return g(e,n,e.position,!0),e.position++,!0;if(92===l){if(g(e,n,e.position,!0),l=e.input.charCodeAt(++e.position),i(l))A(e,!1,t);else if(256>l&&re[l])e.result+=oe[l],e.position++;else if((u=c(l))>0){for(o=u,a=0;o>0;o--)l=e.input.charCodeAt(++e.position),(u=s(l))>=0?a=(a<<4)+u:d(e,"expected hexadecimal character");e.result+=p(a),e.position++}else d(e,"unknown escape sequence");n=r=e.position}else i(l)?(g(e,n,r,!0),w(e,A(e,!1,t)),n=r=e.position):e.position===e.lineStart&&b(e)?d(e,"unexpected end of the document within a double quoted scalar"):(e.position++,r=e.position)}d(e,"unexpected end of the stream within a double quoted scalar")}function I(e,t){var n,i,r,a,s,c,u,l,p,f,h,m=!0,g=e.tag,y=e.anchor,v={};if(h=e.input.charCodeAt(e.position),91===h)a=93,u=!1,i=[];else{if(123!==h)return!1;a=125,u=!0,i={}}for(null!==e.anchor&&(e.anchorMap[e.anchor]=i),h=e.input.charCodeAt(++e.position);0!==h;){if(A(e,!0,t),h=e.input.charCodeAt(e.position),h===a)return e.position++,e.tag=g,e.anchor=y,e.kind=u?"mapping":"sequence",e.result=i,!0;m||d(e,"missed comma between flow collection entries"),p=l=f=null,s=c=!1,63===h&&(r=e.input.charCodeAt(e.position+1),o(r)&&(s=c=!0,e.position++,A(e,!0,t))),n=e.line,_(e,t,W,!1,!0),p=e.tag,l=e.result,A(e,!0,t),h=e.input.charCodeAt(e.position),!c&&e.line!==n||58!==h||(s=!0,h=e.input.charCodeAt(++e.position),A(e,!0,t),_(e,t,W,!1,!0),f=e.result),u?x(e,i,v,p,l,f):s?i.push(x(e,null,v,p,l,f)):i.push(l),A(e,!0,t),h=e.input.charCodeAt(e.position),44===h?(m=!0,h=e.input.charCodeAt(++e.position)):m=!1}d(e,"unexpected end of the stream within a flow collection")}function S(e,t){var n,o,a,s,c=z,l=!1,p=t,f=0,h=!1;if(s=e.input.charCodeAt(e.position),124===s)o=!1;else{if(62!==s)return!1;o=!0}for(e.kind="scalar",e.result="";0!==s;)if(s=e.input.charCodeAt(++e.position),43===s||45===s)z===c?c=43===s?Q:J:d(e,"repeat of a chomping mode identifier");else{if(!((a=u(s))>=0))break;0===a?d(e,"bad explicit indentation width of a block scalar; it cannot be less than one"):l?d(e,"repeat of an indentation width identifier"):(p=t+a-1,l=!0)}if(r(s)){do s=e.input.charCodeAt(++e.position);while(r(s));if(35===s)do s=e.input.charCodeAt(++e.position);while(!i(s)&&0!==s)}for(;0!==s;){for(v(e),e.lineIndent=0,s=e.input.charCodeAt(e.position);(!l||e.lineIndentp&&(p=e.lineIndent),i(s))f++;else{if(e.lineIndentt)&&0!==r)d(e,"bad indentation of a sequence entry");else if(e.lineIndentt)&&(_(e,t,Z,!0,a)&&(y?m=e.result:g=e.result),y||(x(e,p,f,h,m,g),h=m=g=null),A(e,!0,-1),c=e.input.charCodeAt(e.position)),e.lineIndent>t&&0!==c)d(e,"bad indentation of a mapping entry");else if(e.lineIndentt?h=1:e.lineIndent===t?h=0:e.lineIndentt?h=1:e.lineIndent===t?h=0:e.lineIndentc;c+=1)if(l=e.implicitTypes[c],l.resolve(e.result)){e.result=l.construct(e.result),e.tag=l.tag,null!==e.anchor&&(e.anchorMap[e.anchor]=e.result);break}}else H.call(e.typeMap,e.tag)?(l=e.typeMap[e.tag],null!==e.result&&l.kind!==e.kind&&d(e,"unacceptable node kind for !<"+e.tag+'> tag; it should be "'+l.kind+'", not "'+e.kind+'"'),l.resolve(e.result)?(e.result=l.construct(e.result),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):d(e,"cannot resolve a node with !<"+e.tag+"> explicit tag")):d(e,"unknown tag !<"+e.tag+">");return null!==e.listener&&e.listener("close",e),null!==e.tag||null!==e.anchor||g}function M(e){var t,n,a,s,c=e.position,u=!1;for(e.version=null,e.checkLineBreaks=e.legacy,e.tagMap={},e.anchorMap={};0!==(s=e.input.charCodeAt(e.position))&&(A(e,!0,-1),s=e.input.charCodeAt(e.position),!(e.lineIndent>0||37!==s));){for(u=!0,s=e.input.charCodeAt(++e.position),t=e.position;0!==s&&!o(s);)s=e.input.charCodeAt(++e.position);for(n=e.input.slice(t,e.position),a=[],n.length<1&&d(e,"directive name must not be less than one character in length");0!==s;){for(;r(s);)s=e.input.charCodeAt(++e.position);if(35===s){do s=e.input.charCodeAt(++e.position);while(0!==s&&!i(s));break}if(i(s))break;for(t=e.position;0!==s&&!o(s);)s=e.input.charCodeAt(++e.position);a.push(e.input.slice(t,e.position))}0!==s&&v(e),H.call(se,n)?se[n](e,n,a):m(e,'unknown document directive "'+n+'"')}return A(e,!0,-1),0===e.lineIndent&&45===e.input.charCodeAt(e.position)&&45===e.input.charCodeAt(e.position+1)&&45===e.input.charCodeAt(e.position+2)?(e.position+=3,A(e,!0,-1)):u&&d(e,"directives end mark is expected"),_(e,e.lineIndent-1,Z,!1,!0),A(e,!0,-1),e.checkLineBreaks&&ee.test(e.input.slice(c,e.position))&&m(e,"non-ASCII line breaks are interpreted as content"),e.documents.push(e.result),e.position===e.lineStart&&b(e)?void(46===e.input.charCodeAt(e.position)&&(e.position+=3,A(e,!0,-1))):void(e.positioni;i+=1)t(o[i])}function U(e,t){var n=L(e,t);if(0!==n.length){if(1===n.length)return n[0];throw new $("expected a single document in the stream, but found more")}}function q(e,t,n){D(e,t,R.extend({schema:P},n))}function Y(e,t){return U(e,R.extend({schema:P},t))}for(var R=e("./common"),$=e("./exception"),B=e("./mark"),P=e("./schema/default_safe"),K=e("./schema/default_full"),H=Object.prototype.hasOwnProperty,W=1,G=2,V=3,Z=4,z=1,J=2,Q=3,X=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,ee=/[\x85\u2028\u2029]/,te=/[,\[\]\{\}]/,ne=/^(?:!|!!|![a-z\-]+!)$/i,ie=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i,re=new Array(256),oe=new Array(256),ae=0;256>ae;ae++)re[ae]=l(ae)?1:0,oe[ae]=l(ae);var se={YAML:function(e,t,n){var i,r,o;null!==e.version&&d(e,"duplication of %YAML directive"),1!==n.length&&d(e,"YAML directive accepts exactly one argument"),i=/^([0-9]+)\.([0-9]+)$/.exec(n[0]),null===i&&d(e,"ill-formed argument of the YAML directive"),r=parseInt(i[1],10),o=parseInt(i[2],10),1!==r&&d(e,"unacceptable YAML version of the document"),e.version=n[0],e.checkLineBreaks=2>o,1!==o&&2!==o&&m(e,"unsupported YAML version of the document")},TAG:function(e,t,n){var i,r;2!==n.length&&d(e,"TAG directive accepts exactly two arguments"),i=n[0],r=n[1],ne.test(i)||d(e,"ill-formed tag handle (first argument) of the TAG directive"),H.call(e.tagMap,i)&&d(e,'there is a previously declared suffix for "'+i+'" tag handle'),ie.test(r)||d(e,"ill-formed tag prefix (second argument) of the TAG directive"),e.tagMap[i]=r}};t.exports.loadAll=D,t.exports.load=U,t.exports.safeLoadAll=q,t.exports.safeLoad=Y},{"./common":2,"./exception":4,"./mark":6,"./schema/default_full":9,"./schema/default_safe":10}],6:[function(e,t,n){"use strict";function i(e,t,n,i,r){this.name=e,this.buffer=t,this.position=n,this.line=i,this.column=r}var r=e("./common");i.prototype.getSnippet=function(e,t){var n,i,o,a,s;if(!this.buffer)return null;for(e=e||4,t=t||75,n="",i=this.position;i>0&&-1==="\x00\r\n…\u2028\u2029".indexOf(this.buffer.charAt(i-1));)if(i-=1,this.position-i>t/2-1){n=" ... ",i+=5;break}for(o="",a=this.position;at/2-1){o=" ... ",a-=5;break}return s=this.buffer.slice(i,a),r.repeat(" ",e)+n+s+o+"\n"+r.repeat(" ",e+this.position-i+n.length)+"^"},i.prototype.toString=function(e){var t,n="";return this.name&&(n+='in "'+this.name+'" '),n+="at line "+(this.line+1)+", column "+(this.column+1),e||(t=this.getSnippet(),t&&(n+=":\n"+t)),n},t.exports=i},{"./common":2}],7:[function(e,t,n){"use strict";function i(e,t,n){var r=[];return e.include.forEach(function(e){n=i(e,t,n)}),e[t].forEach(function(e){n.forEach(function(t,n){t.tag===e.tag&&r.push(n)}),n.push(e)}),n.filter(function(e,t){return-1===r.indexOf(t)})}function r(){function e(e){i[e.tag]=e}var t,n,i={};for(t=0,n=arguments.length;n>t;t+=1)arguments[t].forEach(e);return i}function o(e){this.include=e.include||[],this.implicit=e.implicit||[],this.explicit=e.explicit||[],this.implicit.forEach(function(e){if(e.loadKind&&"scalar"!==e.loadKind)throw new s("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.")}),this.compiledImplicit=i(this,"implicit",[]),this.compiledExplicit=i(this,"explicit",[]),this.compiledTypeMap=r(this.compiledImplicit,this.compiledExplicit)}var a=e("./common"),s=e("./exception"),c=e("./type");o.DEFAULT=null,o.create=function(){var e,t;switch(arguments.length){case 1:e=o.DEFAULT,t=arguments[0];break;case 2:e=arguments[0],t=arguments[1];break;default:throw new s("Wrong number of arguments for Schema.create function")}if(e=a.toArray(e),t=a.toArray(t),!e.every(function(e){return e instanceof o}))throw new s("Specified list of super schemas (or a single Schema object) contains a non-Schema object.");if(!t.every(function(e){return e instanceof c}))throw new s("Specified list of YAML types (or a single Type object) contains a non-Type object.");return new o({include:e,explicit:t})},t.exports=o},{"./common":2,"./exception":4,"./type":13}],8:[function(e,t,n){"use strict";var i=e("../schema");t.exports=new i({include:[e("./json")]})},{"../schema":7,"./json":12}],9:[function(e,t,n){"use strict";var i=e("../schema");t.exports=i.DEFAULT=new i({include:[e("./default_safe")],explicit:[e("../type/js/undefined"),e("../type/js/regexp"),e("../type/js/function")]})},{"../schema":7,"../type/js/function":18,"../type/js/regexp":19,"../type/js/undefined":20,"./default_safe":10}],10:[function(e,t,n){"use strict";var i=e("../schema");t.exports=new i({include:[e("./core")],implicit:[e("../type/timestamp"),e("../type/merge")],explicit:[e("../type/binary"),e("../type/omap"),e("../type/pairs"),e("../type/set")]})},{"../schema":7,"../type/binary":14,"../type/merge":22,"../type/omap":24,"../type/pairs":25,"../type/set":27,"../type/timestamp":29,"./core":8}],11:[function(e,t,n){"use strict";var i=e("../schema");t.exports=new i({explicit:[e("../type/str"),e("../type/seq"),e("../type/map")]})},{"../schema":7,"../type/map":21,"../type/seq":26,"../type/str":28}],12:[function(e,t,n){"use strict";var i=e("../schema");t.exports=new i({include:[e("./failsafe")],implicit:[e("../type/null"),e("../type/bool"),e("../type/int"),e("../type/float")]})},{"../schema":7,"../type/bool":15,"../type/float":16,"../type/int":17,"../type/null":23,"./failsafe":11}],13:[function(e,t,n){"use strict";function i(e){var t={};return null!==e&&Object.keys(e).forEach(function(n){e[n].forEach(function(e){t[String(e)]=n})}),t}function r(e,t){if(t=t||{},Object.keys(t).forEach(function(t){if(-1===a.indexOf(t))throw new o('Unknown option "'+t+'" is met in definition of "'+e+'" YAML type.')}),this.tag=e,this.kind=t.kind||null,this.resolve=t.resolve||function(){return!0},this.construct=t.construct||function(e){return e},this.instanceOf=t.instanceOf||null,this.predicate=t.predicate||null,this.represent=t.represent||null,this.defaultStyle=t.defaultStyle||null,this.styleAliases=i(t.styleAliases||null),-1===s.indexOf(this.kind))throw new o('Unknown kind "'+this.kind+'" is specified for "'+e+'" YAML type.')}var o=e("./exception"),a=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],s=["scalar","sequence","mapping"];t.exports=r},{"./exception":4}],14:[function(e,t,n){"use strict";function i(e){if(null===e)return!1;var t,n,i=0,r=e.length,o=u;for(n=0;r>n;n++)if(t=o.indexOf(e.charAt(n)),!(t>64)){if(0>t)return!1;i+=6}return i%8===0}function r(e){var t,n,i=e.replace(/[\r\n=]/g,""),r=i.length,o=u,a=0,c=[];for(t=0;r>t;t++)t%4===0&&t&&(c.push(a>>16&255),c.push(a>>8&255),c.push(255&a)),a=a<<6|o.indexOf(i.charAt(t));return n=r%4*6,0===n?(c.push(a>>16&255),c.push(a>>8&255),c.push(255&a)):18===n?(c.push(a>>10&255),c.push(a>>2&255)):12===n&&c.push(a>>4&255),s?new s(c):c}function o(e){var t,n,i="",r=0,o=e.length,a=u;for(t=0;o>t;t++)t%3===0&&t&&(i+=a[r>>18&63],i+=a[r>>12&63],i+=a[r>>6&63],i+=a[63&r]),r=(r<<8)+e[t];return n=o%3, +0===n?(i+=a[r>>18&63],i+=a[r>>12&63],i+=a[r>>6&63],i+=a[63&r]):2===n?(i+=a[r>>10&63],i+=a[r>>4&63],i+=a[r<<2&63],i+=a[64]):1===n&&(i+=a[r>>2&63],i+=a[r<<4&63],i+=a[64],i+=a[64]),i}function a(e){return s&&s.isBuffer(e)}var s=e("buffer").Buffer,c=e("../type"),u="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";t.exports=new c("tag:yaml.org,2002:binary",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../type":13,buffer:30}],15:[function(e,t,n){"use strict";function i(e){if(null===e)return!1;var t=e.length;return 4===t&&("true"===e||"True"===e||"TRUE"===e)||5===t&&("false"===e||"False"===e||"FALSE"===e)}function r(e){return"true"===e||"True"===e||"TRUE"===e}function o(e){return"[object Boolean]"===Object.prototype.toString.call(e)}var a=e("../type");t.exports=new a("tag:yaml.org,2002:bool",{kind:"scalar",resolve:i,construct:r,predicate:o,represent:{lowercase:function(e){return e?"true":"false"},uppercase:function(e){return e?"TRUE":"FALSE"},camelcase:function(e){return e?"True":"False"}},defaultStyle:"lowercase"})},{"../type":13}],16:[function(e,t,n){"use strict";function i(e){return null===e?!1:!!u.test(e)}function r(e){var t,n,i,r;return t=e.replace(/_/g,"").toLowerCase(),n="-"===t[0]?-1:1,r=[],"+-".indexOf(t[0])>=0&&(t=t.slice(1)),".inf"===t?1===n?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===t?NaN:t.indexOf(":")>=0?(t.split(":").forEach(function(e){r.unshift(parseFloat(e,10))}),t=0,i=1,r.forEach(function(e){t+=e*i,i*=60}),n*t):n*parseFloat(t,10)}function o(e,t){var n;if(isNaN(e))switch(t){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===e)switch(t){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===e)switch(t){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(s.isNegativeZero(e))return"-0.0";return n=e.toString(10),l.test(n)?n.replace("e",".e"):n}function a(e){return"[object Number]"===Object.prototype.toString.call(e)&&(e%1!==0||s.isNegativeZero(e))}var s=e("../common"),c=e("../type"),u=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?|\\.[0-9_]+(?:[eE][-+][0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"),l=/^[-+]?[0-9]+e/;t.exports=new c("tag:yaml.org,2002:float",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o,defaultStyle:"lowercase"})},{"../common":2,"../type":13}],17:[function(e,t,n){"use strict";function i(e){return e>=48&&57>=e||e>=65&&70>=e||e>=97&&102>=e}function r(e){return e>=48&&55>=e}function o(e){return e>=48&&57>=e}function a(e){if(null===e)return!1;var t,n=e.length,a=0,s=!1;if(!n)return!1;if(t=e[a],"-"!==t&&"+"!==t||(t=e[++a]),"0"===t){if(a+1===n)return!0;if(t=e[++a],"b"===t){for(a++;n>a;a++)if(t=e[a],"_"!==t){if("0"!==t&&"1"!==t)return!1;s=!0}return s}if("x"===t){for(a++;n>a;a++)if(t=e[a],"_"!==t){if(!i(e.charCodeAt(a)))return!1;s=!0}return s}for(;n>a;a++)if(t=e[a],"_"!==t){if(!r(e.charCodeAt(a)))return!1;s=!0}return s}for(;n>a;a++)if(t=e[a],"_"!==t){if(":"===t)break;if(!o(e.charCodeAt(a)))return!1;s=!0}return s?":"!==t?!0:/^(:[0-5]?[0-9])+$/.test(e.slice(a)):!1}function s(e){var t,n,i=e,r=1,o=[];return-1!==i.indexOf("_")&&(i=i.replace(/_/g,"")),t=i[0],"-"!==t&&"+"!==t||("-"===t&&(r=-1),i=i.slice(1),t=i[0]),"0"===i?0:"0"===t?"b"===i[1]?r*parseInt(i.slice(2),2):"x"===i[1]?r*parseInt(i,16):r*parseInt(i,8):-1!==i.indexOf(":")?(i.split(":").forEach(function(e){o.unshift(parseInt(e,10))}),i=0,n=1,o.forEach(function(e){i+=e*n,n*=60}),r*i):r*parseInt(i,10)}function c(e){return"[object Number]"===Object.prototype.toString.call(e)&&e%1===0&&!u.isNegativeZero(e)}var u=e("../common"),l=e("../type");t.exports=new l("tag:yaml.org,2002:int",{kind:"scalar",resolve:a,construct:s,predicate:c,represent:{binary:function(e){return"0b"+e.toString(2)},octal:function(e){return"0"+e.toString(8)},decimal:function(e){return e.toString(10)},hexadecimal:function(e){return"0x"+e.toString(16).toUpperCase()}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})},{"../common":2,"../type":13}],18:[function(e,t,n){"use strict";function i(e){if(null===e)return!1;try{var t="("+e+")",n=s.parse(t,{range:!0});return"Program"===n.type&&1===n.body.length&&"ExpressionStatement"===n.body[0].type&&"FunctionExpression"===n.body[0].expression.type}catch(i){return!1}}function r(e){var t,n="("+e+")",i=s.parse(n,{range:!0}),r=[];if("Program"!==i.type||1!==i.body.length||"ExpressionStatement"!==i.body[0].type||"FunctionExpression"!==i.body[0].expression.type)throw new Error("Failed to resolve function");return i.body[0].expression.params.forEach(function(e){r.push(e.name)}),t=i.body[0].expression.body.range,new Function(r,n.slice(t[0]+1,t[1]-1))}function o(e){return e.toString()}function a(e){return"[object Function]"===Object.prototype.toString.call(e)}var s;try{var c=e;s=c("esprima")}catch(u){"undefined"!=typeof window&&(s=window.esprima)}var l=e("../../type");t.exports=new l("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../../type":13}],19:[function(e,t,n){"use strict";function i(e){if(null===e)return!1;if(0===e.length)return!1;var t=e,n=/\/([gim]*)$/.exec(e),i="";if("/"===t[0]){if(n&&(i=n[1]),i.length>3)return!1;if("/"!==t[t.length-i.length-1])return!1}return!0}function r(e){var t=e,n=/\/([gim]*)$/.exec(e),i="";return"/"===t[0]&&(n&&(i=n[1]),t=t.slice(1,t.length-i.length-1)),new RegExp(t,i)}function o(e){var t="/"+e.source+"/";return e.global&&(t+="g"),e.multiline&&(t+="m"),e.ignoreCase&&(t+="i"),t}function a(e){return"[object RegExp]"===Object.prototype.toString.call(e)}var s=e("../../type");t.exports=new s("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../../type":13}],20:[function(e,t,n){"use strict";function i(){return!0}function r(){}function o(){return""}function a(e){return"undefined"==typeof e}var s=e("../../type");t.exports=new s("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../../type":13}],21:[function(e,t,n){"use strict";var i=e("../type");t.exports=new i("tag:yaml.org,2002:map",{kind:"mapping",construct:function(e){return null!==e?e:{}}})},{"../type":13}],22:[function(e,t,n){"use strict";function i(e){return"<<"===e||null===e}var r=e("../type");t.exports=new r("tag:yaml.org,2002:merge",{kind:"scalar",resolve:i})},{"../type":13}],23:[function(e,t,n){"use strict";function i(e){if(null===e)return!0;var t=e.length;return 1===t&&"~"===e||4===t&&("null"===e||"Null"===e||"NULL"===e)}function r(){return null}function o(e){return null===e}var a=e("../type");t.exports=new a("tag:yaml.org,2002:null",{kind:"scalar",resolve:i,construct:r,predicate:o,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})},{"../type":13}],24:[function(e,t,n){"use strict";function i(e){if(null===e)return!0;var t,n,i,r,o,c=[],u=e;for(t=0,n=u.length;n>t;t+=1){if(i=u[t],o=!1,"[object Object]"!==s.call(i))return!1;for(r in i)if(a.call(i,r)){if(o)return!1;o=!0}if(!o)return!1;if(-1!==c.indexOf(r))return!1;c.push(r)}return!0}function r(e){return null!==e?e:[]}var o=e("../type"),a=Object.prototype.hasOwnProperty,s=Object.prototype.toString;t.exports=new o("tag:yaml.org,2002:omap",{kind:"sequence",resolve:i,construct:r})},{"../type":13}],25:[function(e,t,n){"use strict";function i(e){if(null===e)return!0;var t,n,i,r,o,s=e;for(o=new Array(s.length),t=0,n=s.length;n>t;t+=1){if(i=s[t],"[object Object]"!==a.call(i))return!1;if(r=Object.keys(i),1!==r.length)return!1;o[t]=[r[0],i[r[0]]]}return!0}function r(e){if(null===e)return[];var t,n,i,r,o,a=e;for(o=new Array(a.length),t=0,n=a.length;n>t;t+=1)i=a[t],r=Object.keys(i),o[t]=[r[0],i[r[0]]];return o}var o=e("../type"),a=Object.prototype.toString;t.exports=new o("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:i,construct:r})},{"../type":13}],26:[function(e,t,n){"use strict";var i=e("../type");t.exports=new i("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(e){return null!==e?e:[]}})},{"../type":13}],27:[function(e,t,n){"use strict";function i(e){if(null===e)return!0;var t,n=e;for(t in n)if(a.call(n,t)&&null!==n[t])return!1;return!0}function r(e){return null!==e?e:{}}var o=e("../type"),a=Object.prototype.hasOwnProperty;t.exports=new o("tag:yaml.org,2002:set",{kind:"mapping",resolve:i,construct:r})},{"../type":13}],28:[function(e,t,n){"use strict";var i=e("../type");t.exports=new i("tag:yaml.org,2002:str",{kind:"scalar",construct:function(e){return null!==e?e:""}})},{"../type":13}],29:[function(e,t,n){"use strict";function i(e){return null===e?!1:null!==s.exec(e)?!0:null!==c.exec(e)}function r(e){var t,n,i,r,o,a,u,l,p,f,h=0,d=null;if(t=s.exec(e),null===t&&(t=c.exec(e)),null===t)throw new Error("Date resolve error");if(n=+t[1],i=+t[2]-1,r=+t[3],!t[4])return new Date(Date.UTC(n,i,r));if(o=+t[4],a=+t[5],u=+t[6],t[7]){for(h=t[7].slice(0,3);h.length<3;)h+="0";h=+h}return t[9]&&(l=+t[10],p=+(t[11]||0),d=6e4*(60*l+p),"-"===t[9]&&(d=-d)),f=new Date(Date.UTC(n,i,r,o,a,u,h)),d&&f.setTime(f.getTime()-d),f}function o(e){return e.toISOString()}var a=e("../type"),s=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),c=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");t.exports=new a("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:i,construct:r,instanceOf:Date,represent:o})},{"../type":13}],30:[function(e,t,n){},{}],"/":[function(e,t,n){"use strict";var i=e("./lib/js-yaml.js");t.exports=i},{"./lib/js-yaml.js":1}]},{},[])("/")}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/index.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/index.js new file mode 100644 index 0000000..1374435 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/index.js @@ -0,0 +1,7 @@ +'use strict'; + + +var yaml = require('./lib/js-yaml.js'); + + +module.exports = yaml; diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml.js new file mode 100644 index 0000000..f0e9281 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml.js @@ -0,0 +1,39 @@ +'use strict'; + + +var loader = require('./js-yaml/loader'); +var dumper = require('./js-yaml/dumper'); + + +function deprecated(name) { + return function () { + throw new Error('Function ' + name + ' is deprecated and cannot be used.'); + }; +} + + +module.exports.Type = require('./js-yaml/type'); +module.exports.Schema = require('./js-yaml/schema'); +module.exports.FAILSAFE_SCHEMA = require('./js-yaml/schema/failsafe'); +module.exports.JSON_SCHEMA = require('./js-yaml/schema/json'); +module.exports.CORE_SCHEMA = require('./js-yaml/schema/core'); +module.exports.DEFAULT_SAFE_SCHEMA = require('./js-yaml/schema/default_safe'); +module.exports.DEFAULT_FULL_SCHEMA = require('./js-yaml/schema/default_full'); +module.exports.load = loader.load; +module.exports.loadAll = loader.loadAll; +module.exports.safeLoad = loader.safeLoad; +module.exports.safeLoadAll = loader.safeLoadAll; +module.exports.dump = dumper.dump; +module.exports.safeDump = dumper.safeDump; +module.exports.YAMLException = require('./js-yaml/exception'); + +// Deprecated schema names from JS-YAML 2.0.x +module.exports.MINIMAL_SCHEMA = require('./js-yaml/schema/failsafe'); +module.exports.SAFE_SCHEMA = require('./js-yaml/schema/default_safe'); +module.exports.DEFAULT_SCHEMA = require('./js-yaml/schema/default_full'); + +// Deprecated functions from JS-YAML 1.x.x +module.exports.scan = deprecated('scan'); +module.exports.parse = deprecated('parse'); +module.exports.compose = deprecated('compose'); +module.exports.addConstructor = deprecated('addConstructor'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/common.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/common.js new file mode 100644 index 0000000..25ef7d8 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/common.js @@ -0,0 +1,59 @@ +'use strict'; + + +function isNothing(subject) { + return (typeof subject === 'undefined') || (subject === null); +} + + +function isObject(subject) { + return (typeof subject === 'object') && (subject !== null); +} + + +function toArray(sequence) { + if (Array.isArray(sequence)) return sequence; + else if (isNothing(sequence)) return []; + + return [ sequence ]; +} + + +function extend(target, source) { + var index, length, key, sourceKeys; + + if (source) { + sourceKeys = Object.keys(source); + + for (index = 0, length = sourceKeys.length; index < length; index += 1) { + key = sourceKeys[index]; + target[key] = source[key]; + } + } + + return target; +} + + +function repeat(string, count) { + var result = '', cycle; + + for (cycle = 0; cycle < count; cycle += 1) { + result += string; + } + + return result; +} + + +function isNegativeZero(number) { + return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number); +} + + +module.exports.isNothing = isNothing; +module.exports.isObject = isObject; +module.exports.toArray = toArray; +module.exports.repeat = repeat; +module.exports.isNegativeZero = isNegativeZero; +module.exports.extend = extend; diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/dumper.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/dumper.js new file mode 100644 index 0000000..855edfc --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/dumper.js @@ -0,0 +1,812 @@ +'use strict'; + +/*eslint-disable no-use-before-define*/ + +var common = require('./common'); +var YAMLException = require('./exception'); +var DEFAULT_FULL_SCHEMA = require('./schema/default_full'); +var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe'); + +var _toString = Object.prototype.toString; +var _hasOwnProperty = Object.prototype.hasOwnProperty; + +var CHAR_TAB = 0x09; /* Tab */ +var CHAR_LINE_FEED = 0x0A; /* LF */ +var CHAR_CARRIAGE_RETURN = 0x0D; /* CR */ +var CHAR_SPACE = 0x20; /* Space */ +var CHAR_EXCLAMATION = 0x21; /* ! */ +var CHAR_DOUBLE_QUOTE = 0x22; /* " */ +var CHAR_SHARP = 0x23; /* # */ +var CHAR_PERCENT = 0x25; /* % */ +var CHAR_AMPERSAND = 0x26; /* & */ +var CHAR_SINGLE_QUOTE = 0x27; /* ' */ +var CHAR_ASTERISK = 0x2A; /* * */ +var CHAR_COMMA = 0x2C; /* , */ +var CHAR_MINUS = 0x2D; /* - */ +var CHAR_COLON = 0x3A; /* : */ +var CHAR_GREATER_THAN = 0x3E; /* > */ +var CHAR_QUESTION = 0x3F; /* ? */ +var CHAR_COMMERCIAL_AT = 0x40; /* @ */ +var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ +var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ +var CHAR_GRAVE_ACCENT = 0x60; /* ` */ +var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ +var CHAR_VERTICAL_LINE = 0x7C; /* | */ +var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ + +var ESCAPE_SEQUENCES = {}; + +ESCAPE_SEQUENCES[0x00] = '\\0'; +ESCAPE_SEQUENCES[0x07] = '\\a'; +ESCAPE_SEQUENCES[0x08] = '\\b'; +ESCAPE_SEQUENCES[0x09] = '\\t'; +ESCAPE_SEQUENCES[0x0A] = '\\n'; +ESCAPE_SEQUENCES[0x0B] = '\\v'; +ESCAPE_SEQUENCES[0x0C] = '\\f'; +ESCAPE_SEQUENCES[0x0D] = '\\r'; +ESCAPE_SEQUENCES[0x1B] = '\\e'; +ESCAPE_SEQUENCES[0x22] = '\\"'; +ESCAPE_SEQUENCES[0x5C] = '\\\\'; +ESCAPE_SEQUENCES[0x85] = '\\N'; +ESCAPE_SEQUENCES[0xA0] = '\\_'; +ESCAPE_SEQUENCES[0x2028] = '\\L'; +ESCAPE_SEQUENCES[0x2029] = '\\P'; + +var DEPRECATED_BOOLEANS_SYNTAX = [ + 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON', + 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF' +]; + +function compileStyleMap(schema, map) { + var result, keys, index, length, tag, style, type; + + if (map === null) return {}; + + result = {}; + keys = Object.keys(map); + + for (index = 0, length = keys.length; index < length; index += 1) { + tag = keys[index]; + style = String(map[tag]); + + if (tag.slice(0, 2) === '!!') { + tag = 'tag:yaml.org,2002:' + tag.slice(2); + } + + type = schema.compiledTypeMap[tag]; + + if (type && _hasOwnProperty.call(type.styleAliases, style)) { + style = type.styleAliases[style]; + } + + result[tag] = style; + } + + return result; +} + +function encodeHex(character) { + var string, handle, length; + + string = character.toString(16).toUpperCase(); + + if (character <= 0xFF) { + handle = 'x'; + length = 2; + } else if (character <= 0xFFFF) { + handle = 'u'; + length = 4; + } else if (character <= 0xFFFFFFFF) { + handle = 'U'; + length = 8; + } else { + throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF'); + } + + return '\\' + handle + common.repeat('0', length - string.length) + string; +} + +function State(options) { + this.schema = options['schema'] || DEFAULT_FULL_SCHEMA; + this.indent = Math.max(1, (options['indent'] || 2)); + this.skipInvalid = options['skipInvalid'] || false; + this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']); + this.styleMap = compileStyleMap(this.schema, options['styles'] || null); + this.sortKeys = options['sortKeys'] || false; + this.lineWidth = options['lineWidth'] || 80; + this.noRefs = options['noRefs'] || false; + this.noCompatMode = options['noCompatMode'] || false; + + this.implicitTypes = this.schema.compiledImplicit; + this.explicitTypes = this.schema.compiledExplicit; + + this.tag = null; + this.result = ''; + + this.duplicates = []; + this.usedDuplicates = null; +} + +function indentString(string, spaces) { + var ind = common.repeat(' ', spaces), + position = 0, + next = -1, + result = '', + line, + length = string.length; + + while (position < length) { + next = string.indexOf('\n', position); + if (next === -1) { + line = string.slice(position); + position = length; + } else { + line = string.slice(position, next + 1); + position = next + 1; + } + + if (line.length && line !== '\n') result += ind; + + result += line; + } + + return result; +} + +function generateNextLine(state, level) { + return '\n' + common.repeat(' ', state.indent * level); +} + +function testImplicitResolving(state, str) { + var index, length, type; + + for (index = 0, length = state.implicitTypes.length; index < length; index += 1) { + type = state.implicitTypes[index]; + + if (type.resolve(str)) { + return true; + } + } + + return false; +} + +function StringBuilder(source) { + this.source = source; + this.result = ''; + this.checkpoint = 0; +} + +StringBuilder.prototype.takeUpTo = function (position) { + var er; + + if (position < this.checkpoint) { + er = new Error('position should be > checkpoint'); + er.position = position; + er.checkpoint = this.checkpoint; + throw er; + } + + this.result += this.source.slice(this.checkpoint, position); + this.checkpoint = position; + return this; +}; + +StringBuilder.prototype.escapeChar = function () { + var character, esc; + + character = this.source.charCodeAt(this.checkpoint); + esc = ESCAPE_SEQUENCES[character] || encodeHex(character); + this.result += esc; + this.checkpoint += 1; + + return this; +}; + +StringBuilder.prototype.finish = function () { + if (this.source.length > this.checkpoint) { + this.takeUpTo(this.source.length); + } +}; + +function writeScalar(state, object, level, iskey) { + var simple, first, spaceWrap, folded, literal, single, double, + sawLineFeed, linePosition, longestLine, indent, max, character, + position, escapeSeq, hexEsc, previous, lineLength, modifier, + trailingLineBreaks, result; + + if (object.length === 0) { + state.dump = "''"; + return; + } + + if (!state.noCompatMode && + DEPRECATED_BOOLEANS_SYNTAX.indexOf(object) !== -1) { + state.dump = "'" + object + "'"; + return; + } + + simple = true; + first = object.length ? object.charCodeAt(0) : 0; + spaceWrap = (CHAR_SPACE === first || + CHAR_SPACE === object.charCodeAt(object.length - 1)); + + // Simplified check for restricted first characters + // http://www.yaml.org/spec/1.2/spec.html#ns-plain-first%28c%29 + if (CHAR_MINUS === first || + CHAR_QUESTION === first || + CHAR_COMMERCIAL_AT === first || + CHAR_GRAVE_ACCENT === first) { + simple = false; + } + + // Can only use > and | if not wrapped in spaces or is not a key. + // Also, don't use if in flow mode. + if (spaceWrap || (state.flowLevel > -1 && state.flowLevel <= level)) { + if (spaceWrap) simple = false; + + folded = false; + literal = false; + } else { + folded = !iskey; + literal = !iskey; + } + + single = true; + double = new StringBuilder(object); + + sawLineFeed = false; + linePosition = 0; + longestLine = 0; + + indent = state.indent * level; + max = state.lineWidth; + + // Replace -1 with biggest ingeger number according to + // http://ecma262-5.com/ELS5_HTML.htm#Section_8.5 + if (max === -1) max = 9007199254740991; + + if (indent < 40) max -= indent; + else max = 40; + + for (position = 0; position < object.length; position++) { + character = object.charCodeAt(position); + if (simple) { + // Characters that can never appear in the simple scalar + if (!simpleChar(character)) { + simple = false; + } else { + // Still simple. If we make it all the way through like + // this, then we can just dump the string as-is. + continue; + } + } + + if (single && character === CHAR_SINGLE_QUOTE) { + single = false; + } + + escapeSeq = ESCAPE_SEQUENCES[character]; + hexEsc = needsHexEscape(character); + + if (!escapeSeq && !hexEsc) { + continue; + } + + if (character !== CHAR_LINE_FEED && + character !== CHAR_DOUBLE_QUOTE && + character !== CHAR_SINGLE_QUOTE) { + folded = false; + literal = false; + } else if (character === CHAR_LINE_FEED) { + sawLineFeed = true; + single = false; + if (position > 0) { + previous = object.charCodeAt(position - 1); + if (previous === CHAR_SPACE) { + literal = false; + folded = false; + } + } + if (folded) { + lineLength = position - linePosition; + linePosition = position; + if (lineLength > longestLine) longestLine = lineLength; + } + } + + if (character !== CHAR_DOUBLE_QUOTE) single = false; + + double.takeUpTo(position); + double.escapeChar(); + } + + if (simple && testImplicitResolving(state, object)) simple = false; + + modifier = ''; + if (folded || literal) { + trailingLineBreaks = 0; + if (object.charCodeAt(object.length - 1) === CHAR_LINE_FEED) { + trailingLineBreaks += 1; + if (object.charCodeAt(object.length - 2) === CHAR_LINE_FEED) { + trailingLineBreaks += 1; + } + } + + if (trailingLineBreaks === 0) modifier = '-'; + else if (trailingLineBreaks === 2) modifier = '+'; + } + + if (literal && longestLine < max || state.tag !== null) { + folded = false; + } + + // If it's literally one line, then don't bother with the literal. + // We may still want to do a fold, though, if it's a super long line. + if (!sawLineFeed) literal = false; + + if (simple) { + state.dump = object; + } else if (single) { + state.dump = '\'' + object + '\''; + } else if (folded) { + result = fold(object, max); + state.dump = '>' + modifier + '\n' + indentString(result, indent); + } else if (literal) { + if (!modifier) object = object.replace(/\n$/, ''); + state.dump = '|' + modifier + '\n' + indentString(object, indent); + } else if (double) { + double.finish(); + state.dump = '"' + double.result + '"'; + } else { + throw new Error('Failed to dump scalar value'); + } + + return; +} + +// The `trailing` var is a regexp match of any trailing `\n` characters. +// +// There are three cases we care about: +// +// 1. One trailing `\n` on the string. Just use `|` or `>`. +// This is the assumed default. (trailing = null) +// 2. No trailing `\n` on the string. Use `|-` or `>-` to "chomp" the end. +// 3. More than one trailing `\n` on the string. Use `|+` or `>+`. +// +// In the case of `>+`, these line breaks are *not* doubled (like the line +// breaks within the string), so it's important to only end with the exact +// same number as we started. +function fold(object, max) { + var result = '', + position = 0, + length = object.length, + trailing = /\n+$/.exec(object), + newLine; + + if (trailing) { + length = trailing.index + 1; + } + + while (position < length) { + newLine = object.indexOf('\n', position); + if (newLine > length || newLine === -1) { + if (result) result += '\n\n'; + result += foldLine(object.slice(position, length), max); + position = length; + + } else { + if (result) result += '\n\n'; + result += foldLine(object.slice(position, newLine), max); + position = newLine + 1; + } + } + + if (trailing && trailing[0] !== '\n') result += trailing[0]; + + return result; +} + +function foldLine(line, max) { + if (line === '') return line; + + var foldRe = /[^\s] [^\s]/g, + result = '', + prevMatch = 0, + foldStart = 0, + match = foldRe.exec(line), + index, + foldEnd, + folded; + + while (match) { + index = match.index; + + // when we cross the max len, if the previous match would've + // been ok, use that one, and carry on. If there was no previous + // match on this fold section, then just have a long line. + if (index - foldStart > max) { + if (prevMatch !== foldStart) foldEnd = prevMatch; + else foldEnd = index; + + if (result) result += '\n'; + folded = line.slice(foldStart, foldEnd); + result += folded; + foldStart = foldEnd + 1; + } + prevMatch = index + 1; + match = foldRe.exec(line); + } + + if (result) result += '\n'; + + // if we end up with one last word at the end, then the last bit might + // be slightly bigger than we wanted, because we exited out of the loop. + if (foldStart !== prevMatch && line.length - foldStart > max) { + result += line.slice(foldStart, prevMatch) + '\n' + + line.slice(prevMatch + 1); + } else { + result += line.slice(foldStart); + } + + return result; +} + +// Returns true if character can be found in a simple scalar +function simpleChar(character) { + return CHAR_TAB !== character && + CHAR_LINE_FEED !== character && + CHAR_CARRIAGE_RETURN !== character && + CHAR_COMMA !== character && + CHAR_LEFT_SQUARE_BRACKET !== character && + CHAR_RIGHT_SQUARE_BRACKET !== character && + CHAR_LEFT_CURLY_BRACKET !== character && + CHAR_RIGHT_CURLY_BRACKET !== character && + CHAR_SHARP !== character && + CHAR_AMPERSAND !== character && + CHAR_ASTERISK !== character && + CHAR_EXCLAMATION !== character && + CHAR_VERTICAL_LINE !== character && + CHAR_GREATER_THAN !== character && + CHAR_SINGLE_QUOTE !== character && + CHAR_DOUBLE_QUOTE !== character && + CHAR_PERCENT !== character && + CHAR_COLON !== character && + !ESCAPE_SEQUENCES[character] && + !needsHexEscape(character); +} + +// Returns true if the character code needs to be escaped. +function needsHexEscape(character) { + return !((0x00020 <= character && character <= 0x00007E) || + (character === 0x00085) || + (0x000A0 <= character && character <= 0x00D7FF) || + (0x0E000 <= character && character <= 0x00FFFD) || + (0x10000 <= character && character <= 0x10FFFF)); +} + +function writeFlowSequence(state, level, object) { + var _result = '', + _tag = state.tag, + index, + length; + + for (index = 0, length = object.length; index < length; index += 1) { + // Write only valid elements. + if (writeNode(state, level, object[index], false, false)) { + if (index !== 0) _result += ', '; + _result += state.dump; + } + } + + state.tag = _tag; + state.dump = '[' + _result + ']'; +} + +function writeBlockSequence(state, level, object, compact) { + var _result = '', + _tag = state.tag, + index, + length; + + for (index = 0, length = object.length; index < length; index += 1) { + // Write only valid elements. + if (writeNode(state, level + 1, object[index], true, true)) { + if (!compact || index !== 0) { + _result += generateNextLine(state, level); + } + _result += '- ' + state.dump; + } + } + + state.tag = _tag; + state.dump = _result || '[]'; // Empty sequence if no valid values. +} + +function writeFlowMapping(state, level, object) { + var _result = '', + _tag = state.tag, + objectKeyList = Object.keys(object), + index, + length, + objectKey, + objectValue, + pairBuffer; + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + pairBuffer = ''; + + if (index !== 0) pairBuffer += ', '; + + objectKey = objectKeyList[index]; + objectValue = object[objectKey]; + + if (!writeNode(state, level, objectKey, false, false)) { + continue; // Skip this pair because of invalid key; + } + + if (state.dump.length > 1024) pairBuffer += '? '; + + pairBuffer += state.dump + ': '; + + if (!writeNode(state, level, objectValue, false, false)) { + continue; // Skip this pair because of invalid value. + } + + pairBuffer += state.dump; + + // Both key and value are valid. + _result += pairBuffer; + } + + state.tag = _tag; + state.dump = '{' + _result + '}'; +} + +function writeBlockMapping(state, level, object, compact) { + var _result = '', + _tag = state.tag, + objectKeyList = Object.keys(object), + index, + length, + objectKey, + objectValue, + explicitPair, + pairBuffer; + + // Allow sorting keys so that the output file is deterministic + if (state.sortKeys === true) { + // Default sorting + objectKeyList.sort(); + } else if (typeof state.sortKeys === 'function') { + // Custom sort function + objectKeyList.sort(state.sortKeys); + } else if (state.sortKeys) { + // Something is wrong + throw new YAMLException('sortKeys must be a boolean or a function'); + } + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + pairBuffer = ''; + + if (!compact || index !== 0) { + pairBuffer += generateNextLine(state, level); + } + + objectKey = objectKeyList[index]; + objectValue = object[objectKey]; + + if (!writeNode(state, level + 1, objectKey, true, true, true)) { + continue; // Skip this pair because of invalid key. + } + + explicitPair = (state.tag !== null && state.tag !== '?') || + (state.dump && state.dump.length > 1024); + + if (explicitPair) { + if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { + pairBuffer += '?'; + } else { + pairBuffer += '? '; + } + } + + pairBuffer += state.dump; + + if (explicitPair) { + pairBuffer += generateNextLine(state, level); + } + + if (!writeNode(state, level + 1, objectValue, true, explicitPair)) { + continue; // Skip this pair because of invalid value. + } + + if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { + pairBuffer += ':'; + } else { + pairBuffer += ': '; + } + + pairBuffer += state.dump; + + // Both key and value are valid. + _result += pairBuffer; + } + + state.tag = _tag; + state.dump = _result || '{}'; // Empty mapping if no valid pairs. +} + +function detectType(state, object, explicit) { + var _result, typeList, index, length, type, style; + + typeList = explicit ? state.explicitTypes : state.implicitTypes; + + for (index = 0, length = typeList.length; index < length; index += 1) { + type = typeList[index]; + + if ((type.instanceOf || type.predicate) && + (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) && + (!type.predicate || type.predicate(object))) { + + state.tag = explicit ? type.tag : '?'; + + if (type.represent) { + style = state.styleMap[type.tag] || type.defaultStyle; + + if (_toString.call(type.represent) === '[object Function]') { + _result = type.represent(object, style); + } else if (_hasOwnProperty.call(type.represent, style)) { + _result = type.represent[style](object, style); + } else { + throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style'); + } + + state.dump = _result; + } + + return true; + } + } + + return false; +} + +// Serializes `object` and writes it to global `result`. +// Returns true on success, or false on invalid object. +// +function writeNode(state, level, object, block, compact, iskey) { + state.tag = null; + state.dump = object; + + if (!detectType(state, object, false)) { + detectType(state, object, true); + } + + var type = _toString.call(state.dump); + + if (block) { + block = (state.flowLevel < 0 || state.flowLevel > level); + } + + var objectOrArray = type === '[object Object]' || type === '[object Array]', + duplicateIndex, + duplicate; + + if (objectOrArray) { + duplicateIndex = state.duplicates.indexOf(object); + duplicate = duplicateIndex !== -1; + } + + if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) { + compact = false; + } + + if (duplicate && state.usedDuplicates[duplicateIndex]) { + state.dump = '*ref_' + duplicateIndex; + } else { + if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) { + state.usedDuplicates[duplicateIndex] = true; + } + if (type === '[object Object]') { + if (block && (Object.keys(state.dump).length !== 0)) { + writeBlockMapping(state, level, state.dump, compact); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + state.dump; + } + } else { + writeFlowMapping(state, level, state.dump); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; + } + } + } else if (type === '[object Array]') { + if (block && (state.dump.length !== 0)) { + writeBlockSequence(state, level, state.dump, compact); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + state.dump; + } + } else { + writeFlowSequence(state, level, state.dump); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; + } + } + } else if (type === '[object String]') { + if (state.tag !== '?') { + writeScalar(state, state.dump, level, iskey); + } + } else { + if (state.skipInvalid) return false; + throw new YAMLException('unacceptable kind of an object to dump ' + type); + } + + if (state.tag !== null && state.tag !== '?') { + state.dump = '!<' + state.tag + '> ' + state.dump; + } + } + + return true; +} + +function getDuplicateReferences(object, state) { + var objects = [], + duplicatesIndexes = [], + index, + length; + + inspectNode(object, objects, duplicatesIndexes); + + for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) { + state.duplicates.push(objects[duplicatesIndexes[index]]); + } + state.usedDuplicates = new Array(length); +} + +function inspectNode(object, objects, duplicatesIndexes) { + var objectKeyList, + index, + length; + + if (object !== null && typeof object === 'object') { + index = objects.indexOf(object); + if (index !== -1) { + if (duplicatesIndexes.indexOf(index) === -1) { + duplicatesIndexes.push(index); + } + } else { + objects.push(object); + + if (Array.isArray(object)) { + for (index = 0, length = object.length; index < length; index += 1) { + inspectNode(object[index], objects, duplicatesIndexes); + } + } else { + objectKeyList = Object.keys(object); + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes); + } + } + } + } +} + +function dump(input, options) { + options = options || {}; + + var state = new State(options); + + if (!state.noRefs) getDuplicateReferences(input, state); + + if (writeNode(state, 0, input, true, true)) return state.dump + '\n'; + + return ''; +} + +function safeDump(input, options) { + return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); +} + +module.exports.dump = dump; +module.exports.safeDump = safeDump; diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/exception.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/exception.js new file mode 100644 index 0000000..cf4e625 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/exception.js @@ -0,0 +1,43 @@ +// YAML error class. http://stackoverflow.com/questions/8458984 +// +'use strict'; + +function YAMLException(reason, mark) { + // Super constructor + Error.call(this); + + // Include stack trace in error object + if (Error.captureStackTrace) { + // Chrome and NodeJS + Error.captureStackTrace(this, this.constructor); + } else { + // FF, IE 10+ and Safari 6+. Fallback for others + this.stack = (new Error()).stack || ''; + } + + this.name = 'YAMLException'; + this.reason = reason; + this.mark = mark; + this.message = (this.reason || '(unknown reason)') + (this.mark ? ' ' + this.mark.toString() : ''); +} + + +// Inherit from Error +YAMLException.prototype = Object.create(Error.prototype); +YAMLException.prototype.constructor = YAMLException; + + +YAMLException.prototype.toString = function toString(compact) { + var result = this.name + ': '; + + result += this.reason || '(unknown reason)'; + + if (!compact && this.mark) { + result += ' ' + this.mark.toString(); + } + + return result; +}; + + +module.exports = YAMLException; diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/loader.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/loader.js new file mode 100644 index 0000000..1714022 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/loader.js @@ -0,0 +1,1586 @@ +'use strict'; + +/*eslint-disable max-len,no-use-before-define*/ + +var common = require('./common'); +var YAMLException = require('./exception'); +var Mark = require('./mark'); +var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe'); +var DEFAULT_FULL_SCHEMA = require('./schema/default_full'); + + +var _hasOwnProperty = Object.prototype.hasOwnProperty; + + +var CONTEXT_FLOW_IN = 1; +var CONTEXT_FLOW_OUT = 2; +var CONTEXT_BLOCK_IN = 3; +var CONTEXT_BLOCK_OUT = 4; + + +var CHOMPING_CLIP = 1; +var CHOMPING_STRIP = 2; +var CHOMPING_KEEP = 3; + + +var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; +var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/; +var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/; +var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i; +var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; + + +function is_EOL(c) { + return (c === 0x0A/* LF */) || (c === 0x0D/* CR */); +} + +function is_WHITE_SPACE(c) { + return (c === 0x09/* Tab */) || (c === 0x20/* Space */); +} + +function is_WS_OR_EOL(c) { + return (c === 0x09/* Tab */) || + (c === 0x20/* Space */) || + (c === 0x0A/* LF */) || + (c === 0x0D/* CR */); +} + +function is_FLOW_INDICATOR(c) { + return c === 0x2C/* , */ || + c === 0x5B/* [ */ || + c === 0x5D/* ] */ || + c === 0x7B/* { */ || + c === 0x7D/* } */; +} + +function fromHexCode(c) { + var lc; + + if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { + return c - 0x30; + } + + /*eslint-disable no-bitwise*/ + lc = c | 0x20; + + if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) { + return lc - 0x61 + 10; + } + + return -1; +} + +function escapedHexLen(c) { + if (c === 0x78/* x */) { return 2; } + if (c === 0x75/* u */) { return 4; } + if (c === 0x55/* U */) { return 8; } + return 0; +} + +function fromDecimalCode(c) { + if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { + return c - 0x30; + } + + return -1; +} + +function simpleEscapeSequence(c) { + return (c === 0x30/* 0 */) ? '\x00' : + (c === 0x61/* a */) ? '\x07' : + (c === 0x62/* b */) ? '\x08' : + (c === 0x74/* t */) ? '\x09' : + (c === 0x09/* Tab */) ? '\x09' : + (c === 0x6E/* n */) ? '\x0A' : + (c === 0x76/* v */) ? '\x0B' : + (c === 0x66/* f */) ? '\x0C' : + (c === 0x72/* r */) ? '\x0D' : + (c === 0x65/* e */) ? '\x1B' : + (c === 0x20/* Space */) ? ' ' : + (c === 0x22/* " */) ? '\x22' : + (c === 0x2F/* / */) ? '/' : + (c === 0x5C/* \ */) ? '\x5C' : + (c === 0x4E/* N */) ? '\x85' : + (c === 0x5F/* _ */) ? '\xA0' : + (c === 0x4C/* L */) ? '\u2028' : + (c === 0x50/* P */) ? '\u2029' : ''; +} + +function charFromCodepoint(c) { + if (c <= 0xFFFF) { + return String.fromCharCode(c); + } + // Encode UTF-16 surrogate pair + // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF + return String.fromCharCode(((c - 0x010000) >> 10) + 0xD800, + ((c - 0x010000) & 0x03FF) + 0xDC00); +} + +var simpleEscapeCheck = new Array(256); // integer, for fast access +var simpleEscapeMap = new Array(256); +for (var i = 0; i < 256; i++) { + simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0; + simpleEscapeMap[i] = simpleEscapeSequence(i); +} + + +function State(input, options) { + this.input = input; + + this.filename = options['filename'] || null; + this.schema = options['schema'] || DEFAULT_FULL_SCHEMA; + this.onWarning = options['onWarning'] || null; + this.legacy = options['legacy'] || false; + this.json = options['json'] || false; + this.listener = options['listener'] || null; + + this.implicitTypes = this.schema.compiledImplicit; + this.typeMap = this.schema.compiledTypeMap; + + this.length = input.length; + this.position = 0; + this.line = 0; + this.lineStart = 0; + this.lineIndent = 0; + + this.documents = []; + + /* + this.version; + this.checkLineBreaks; + this.tagMap; + this.anchorMap; + this.tag; + this.anchor; + this.kind; + this.result;*/ + +} + + +function generateError(state, message) { + return new YAMLException( + message, + new Mark(state.filename, state.input, state.position, state.line, (state.position - state.lineStart))); +} + +function throwError(state, message) { + throw generateError(state, message); +} + +function throwWarning(state, message) { + if (state.onWarning) { + state.onWarning.call(null, generateError(state, message)); + } +} + + +var directiveHandlers = { + + YAML: function handleYamlDirective(state, name, args) { + + var match, major, minor; + + if (state.version !== null) { + throwError(state, 'duplication of %YAML directive'); + } + + if (args.length !== 1) { + throwError(state, 'YAML directive accepts exactly one argument'); + } + + match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]); + + if (match === null) { + throwError(state, 'ill-formed argument of the YAML directive'); + } + + major = parseInt(match[1], 10); + minor = parseInt(match[2], 10); + + if (major !== 1) { + throwError(state, 'unacceptable YAML version of the document'); + } + + state.version = args[0]; + state.checkLineBreaks = (minor < 2); + + if (minor !== 1 && minor !== 2) { + throwWarning(state, 'unsupported YAML version of the document'); + } + }, + + TAG: function handleTagDirective(state, name, args) { + + var handle, prefix; + + if (args.length !== 2) { + throwError(state, 'TAG directive accepts exactly two arguments'); + } + + handle = args[0]; + prefix = args[1]; + + if (!PATTERN_TAG_HANDLE.test(handle)) { + throwError(state, 'ill-formed tag handle (first argument) of the TAG directive'); + } + + if (_hasOwnProperty.call(state.tagMap, handle)) { + throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle'); + } + + if (!PATTERN_TAG_URI.test(prefix)) { + throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive'); + } + + state.tagMap[handle] = prefix; + } +}; + + +function captureSegment(state, start, end, checkJson) { + var _position, _length, _character, _result; + + if (start < end) { + _result = state.input.slice(start, end); + + if (checkJson) { + for (_position = 0, _length = _result.length; + _position < _length; + _position += 1) { + _character = _result.charCodeAt(_position); + if (!(_character === 0x09 || + (0x20 <= _character && _character <= 0x10FFFF))) { + throwError(state, 'expected valid JSON character'); + } + } + } else if (PATTERN_NON_PRINTABLE.test(_result)) { + throwError(state, 'the stream contains non-printable characters'); + } + + state.result += _result; + } +} + +function mergeMappings(state, destination, source, overridableKeys) { + var sourceKeys, key, index, quantity; + + if (!common.isObject(source)) { + throwError(state, 'cannot merge mappings; the provided source object is unacceptable'); + } + + sourceKeys = Object.keys(source); + + for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) { + key = sourceKeys[index]; + + if (!_hasOwnProperty.call(destination, key)) { + destination[key] = source[key]; + overridableKeys[key] = true; + } + } +} + +function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode) { + var index, quantity; + + keyNode = String(keyNode); + + if (_result === null) { + _result = {}; + } + + if (keyTag === 'tag:yaml.org,2002:merge') { + if (Array.isArray(valueNode)) { + for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { + mergeMappings(state, _result, valueNode[index], overridableKeys); + } + } else { + mergeMappings(state, _result, valueNode, overridableKeys); + } + } else { + if (!state.json && + !_hasOwnProperty.call(overridableKeys, keyNode) && + _hasOwnProperty.call(_result, keyNode)) { + throwError(state, 'duplicated mapping key'); + } + _result[keyNode] = valueNode; + delete overridableKeys[keyNode]; + } + + return _result; +} + +function readLineBreak(state) { + var ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x0A/* LF */) { + state.position++; + } else if (ch === 0x0D/* CR */) { + state.position++; + if (state.input.charCodeAt(state.position) === 0x0A/* LF */) { + state.position++; + } + } else { + throwError(state, 'a line break is expected'); + } + + state.line += 1; + state.lineStart = state.position; +} + +function skipSeparationSpace(state, allowComments, checkIndent) { + var lineBreaks = 0, + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + while (is_WHITE_SPACE(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (allowComments && ch === 0x23/* # */) { + do { + ch = state.input.charCodeAt(++state.position); + } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0); + } + + if (is_EOL(ch)) { + readLineBreak(state); + + ch = state.input.charCodeAt(state.position); + lineBreaks++; + state.lineIndent = 0; + + while (ch === 0x20/* Space */) { + state.lineIndent++; + ch = state.input.charCodeAt(++state.position); + } + } else { + break; + } + } + + if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) { + throwWarning(state, 'deficient indentation'); + } + + return lineBreaks; +} + +function testDocumentSeparator(state) { + var _position = state.position, + ch; + + ch = state.input.charCodeAt(_position); + + // Condition state.position === state.lineStart is tested + // in parent on each call, for efficiency. No needs to test here again. + if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) && + ch === state.input.charCodeAt(_position + 1) && + ch === state.input.charCodeAt(_position + 2)) { + + _position += 3; + + ch = state.input.charCodeAt(_position); + + if (ch === 0 || is_WS_OR_EOL(ch)) { + return true; + } + } + + return false; +} + +function writeFoldedLines(state, count) { + if (count === 1) { + state.result += ' '; + } else if (count > 1) { + state.result += common.repeat('\n', count - 1); + } +} + + +function readPlainScalar(state, nodeIndent, withinFlowCollection) { + var preceding, + following, + captureStart, + captureEnd, + hasPendingContent, + _line, + _lineStart, + _lineIndent, + _kind = state.kind, + _result = state.result, + ch; + + ch = state.input.charCodeAt(state.position); + + if (is_WS_OR_EOL(ch) || + is_FLOW_INDICATOR(ch) || + ch === 0x23/* # */ || + ch === 0x26/* & */ || + ch === 0x2A/* * */ || + ch === 0x21/* ! */ || + ch === 0x7C/* | */ || + ch === 0x3E/* > */ || + ch === 0x27/* ' */ || + ch === 0x22/* " */ || + ch === 0x25/* % */ || + ch === 0x40/* @ */ || + ch === 0x60/* ` */) { + return false; + } + + if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following) || + withinFlowCollection && is_FLOW_INDICATOR(following)) { + return false; + } + } + + state.kind = 'scalar'; + state.result = ''; + captureStart = captureEnd = state.position; + hasPendingContent = false; + + while (ch !== 0) { + if (ch === 0x3A/* : */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following) || + withinFlowCollection && is_FLOW_INDICATOR(following)) { + break; + } + + } else if (ch === 0x23/* # */) { + preceding = state.input.charCodeAt(state.position - 1); + + if (is_WS_OR_EOL(preceding)) { + break; + } + + } else if ((state.position === state.lineStart && testDocumentSeparator(state)) || + withinFlowCollection && is_FLOW_INDICATOR(ch)) { + break; + + } else if (is_EOL(ch)) { + _line = state.line; + _lineStart = state.lineStart; + _lineIndent = state.lineIndent; + skipSeparationSpace(state, false, -1); + + if (state.lineIndent >= nodeIndent) { + hasPendingContent = true; + ch = state.input.charCodeAt(state.position); + continue; + } else { + state.position = captureEnd; + state.line = _line; + state.lineStart = _lineStart; + state.lineIndent = _lineIndent; + break; + } + } + + if (hasPendingContent) { + captureSegment(state, captureStart, captureEnd, false); + writeFoldedLines(state, state.line - _line); + captureStart = captureEnd = state.position; + hasPendingContent = false; + } + + if (!is_WHITE_SPACE(ch)) { + captureEnd = state.position + 1; + } + + ch = state.input.charCodeAt(++state.position); + } + + captureSegment(state, captureStart, captureEnd, false); + + if (state.result) { + return true; + } + + state.kind = _kind; + state.result = _result; + return false; +} + +function readSingleQuotedScalar(state, nodeIndent) { + var ch, + captureStart, captureEnd; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x27/* ' */) { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + state.position++; + captureStart = captureEnd = state.position; + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + if (ch === 0x27/* ' */) { + captureSegment(state, captureStart, state.position, true); + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x27/* ' */) { + captureStart = captureEnd = state.position; + state.position++; + } else { + return true; + } + + } else if (is_EOL(ch)) { + captureSegment(state, captureStart, captureEnd, true); + writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); + captureStart = captureEnd = state.position; + + } else if (state.position === state.lineStart && testDocumentSeparator(state)) { + throwError(state, 'unexpected end of the document within a single quoted scalar'); + + } else { + state.position++; + captureEnd = state.position; + } + } + + throwError(state, 'unexpected end of the stream within a single quoted scalar'); +} + +function readDoubleQuotedScalar(state, nodeIndent) { + var captureStart, + captureEnd, + hexLength, + hexResult, + tmp, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x22/* " */) { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + state.position++; + captureStart = captureEnd = state.position; + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + if (ch === 0x22/* " */) { + captureSegment(state, captureStart, state.position, true); + state.position++; + return true; + + } else if (ch === 0x5C/* \ */) { + captureSegment(state, captureStart, state.position, true); + ch = state.input.charCodeAt(++state.position); + + if (is_EOL(ch)) { + skipSeparationSpace(state, false, nodeIndent); + + // TODO: rework to inline fn with no type cast? + } else if (ch < 256 && simpleEscapeCheck[ch]) { + state.result += simpleEscapeMap[ch]; + state.position++; + + } else if ((tmp = escapedHexLen(ch)) > 0) { + hexLength = tmp; + hexResult = 0; + + for (; hexLength > 0; hexLength--) { + ch = state.input.charCodeAt(++state.position); + + if ((tmp = fromHexCode(ch)) >= 0) { + hexResult = (hexResult << 4) + tmp; + + } else { + throwError(state, 'expected hexadecimal character'); + } + } + + state.result += charFromCodepoint(hexResult); + + state.position++; + + } else { + throwError(state, 'unknown escape sequence'); + } + + captureStart = captureEnd = state.position; + + } else if (is_EOL(ch)) { + captureSegment(state, captureStart, captureEnd, true); + writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); + captureStart = captureEnd = state.position; + + } else if (state.position === state.lineStart && testDocumentSeparator(state)) { + throwError(state, 'unexpected end of the document within a double quoted scalar'); + + } else { + state.position++; + captureEnd = state.position; + } + } + + throwError(state, 'unexpected end of the stream within a double quoted scalar'); +} + +function readFlowCollection(state, nodeIndent) { + var readNext = true, + _line, + _tag = state.tag, + _result, + _anchor = state.anchor, + following, + terminator, + isPair, + isExplicitPair, + isMapping, + overridableKeys = {}, + keyNode, + keyTag, + valueNode, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x5B/* [ */) { + terminator = 0x5D;/* ] */ + isMapping = false; + _result = []; + } else if (ch === 0x7B/* { */) { + terminator = 0x7D;/* } */ + isMapping = true; + _result = {}; + } else { + return false; + } + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(++state.position); + + while (ch !== 0) { + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if (ch === terminator) { + state.position++; + state.tag = _tag; + state.anchor = _anchor; + state.kind = isMapping ? 'mapping' : 'sequence'; + state.result = _result; + return true; + } else if (!readNext) { + throwError(state, 'missed comma between flow collection entries'); + } + + keyTag = keyNode = valueNode = null; + isPair = isExplicitPair = false; + + if (ch === 0x3F/* ? */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following)) { + isPair = isExplicitPair = true; + state.position++; + skipSeparationSpace(state, true, nodeIndent); + } + } + + _line = state.line; + composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); + keyTag = state.tag; + keyNode = state.result; + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) { + isPair = true; + ch = state.input.charCodeAt(++state.position); + skipSeparationSpace(state, true, nodeIndent); + composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); + valueNode = state.result; + } + + if (isMapping) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode); + } else if (isPair) { + _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode)); + } else { + _result.push(keyNode); + } + + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x2C/* , */) { + readNext = true; + ch = state.input.charCodeAt(++state.position); + } else { + readNext = false; + } + } + + throwError(state, 'unexpected end of the stream within a flow collection'); +} + +function readBlockScalar(state, nodeIndent) { + var captureStart, + folding, + chomping = CHOMPING_CLIP, + detectedIndent = false, + textIndent = nodeIndent, + emptyLines = 0, + atMoreIndented = false, + tmp, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x7C/* | */) { + folding = false; + } else if (ch === 0x3E/* > */) { + folding = true; + } else { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + + while (ch !== 0) { + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { + if (CHOMPING_CLIP === chomping) { + chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP; + } else { + throwError(state, 'repeat of a chomping mode identifier'); + } + + } else if ((tmp = fromDecimalCode(ch)) >= 0) { + if (tmp === 0) { + throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one'); + } else if (!detectedIndent) { + textIndent = nodeIndent + tmp - 1; + detectedIndent = true; + } else { + throwError(state, 'repeat of an indentation width identifier'); + } + + } else { + break; + } + } + + if (is_WHITE_SPACE(ch)) { + do { ch = state.input.charCodeAt(++state.position); } + while (is_WHITE_SPACE(ch)); + + if (ch === 0x23/* # */) { + do { ch = state.input.charCodeAt(++state.position); } + while (!is_EOL(ch) && (ch !== 0)); + } + } + + while (ch !== 0) { + readLineBreak(state); + state.lineIndent = 0; + + ch = state.input.charCodeAt(state.position); + + while ((!detectedIndent || state.lineIndent < textIndent) && + (ch === 0x20/* Space */)) { + state.lineIndent++; + ch = state.input.charCodeAt(++state.position); + } + + if (!detectedIndent && state.lineIndent > textIndent) { + textIndent = state.lineIndent; + } + + if (is_EOL(ch)) { + emptyLines++; + continue; + } + + // End of the scalar. + if (state.lineIndent < textIndent) { + + // Perform the chomping. + if (chomping === CHOMPING_KEEP) { + state.result += common.repeat('\n', emptyLines); + } else if (chomping === CHOMPING_CLIP) { + if (detectedIndent) { // i.e. only if the scalar is not empty. + state.result += '\n'; + } + } + + // Break this `while` cycle and go to the funciton's epilogue. + break; + } + + // Folded style: use fancy rules to handle line breaks. + if (folding) { + + // Lines starting with white space characters (more-indented lines) are not folded. + if (is_WHITE_SPACE(ch)) { + atMoreIndented = true; + state.result += common.repeat('\n', emptyLines + 1); + + // End of more-indented block. + } else if (atMoreIndented) { + atMoreIndented = false; + state.result += common.repeat('\n', emptyLines + 1); + + // Just one line break - perceive as the same line. + } else if (emptyLines === 0) { + if (detectedIndent) { // i.e. only if we have already read some scalar content. + state.result += ' '; + } + + // Several line breaks - perceive as different lines. + } else { + state.result += common.repeat('\n', emptyLines); + } + + // Literal style: just add exact number of line breaks between content lines. + } else if (detectedIndent) { + // If current line isn't the first one - count line break from the last content line. + state.result += common.repeat('\n', emptyLines + 1); + } else { + // In case of the first content line - count only empty lines. + state.result += common.repeat('\n', emptyLines); + } + + detectedIndent = true; + emptyLines = 0; + captureStart = state.position; + + while (!is_EOL(ch) && (ch !== 0)) { + ch = state.input.charCodeAt(++state.position); + } + + captureSegment(state, captureStart, state.position, false); + } + + return true; +} + +function readBlockSequence(state, nodeIndent) { + var _line, + _tag = state.tag, + _anchor = state.anchor, + _result = [], + following, + detected = false, + ch; + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + + if (ch !== 0x2D/* - */) { + break; + } + + following = state.input.charCodeAt(state.position + 1); + + if (!is_WS_OR_EOL(following)) { + break; + } + + detected = true; + state.position++; + + if (skipSeparationSpace(state, true, -1)) { + if (state.lineIndent <= nodeIndent) { + _result.push(null); + ch = state.input.charCodeAt(state.position); + continue; + } + } + + _line = state.line; + composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true); + _result.push(state.result); + skipSeparationSpace(state, true, -1); + + ch = state.input.charCodeAt(state.position); + + if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { + throwError(state, 'bad indentation of a sequence entry'); + } else if (state.lineIndent < nodeIndent) { + break; + } + } + + if (detected) { + state.tag = _tag; + state.anchor = _anchor; + state.kind = 'sequence'; + state.result = _result; + return true; + } + return false; +} + +function readBlockMapping(state, nodeIndent, flowIndent) { + var following, + allowCompact, + _line, + _tag = state.tag, + _anchor = state.anchor, + _result = {}, + overridableKeys = {}, + keyTag = null, + keyNode = null, + valueNode = null, + atExplicitKey = false, + detected = false, + ch; + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + following = state.input.charCodeAt(state.position + 1); + _line = state.line; // Save the current line. + + // + // Explicit notation case. There are two separate blocks: + // first for the key (denoted by "?") and second for the value (denoted by ":") + // + if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) { + + if (ch === 0x3F/* ? */) { + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); + keyTag = keyNode = valueNode = null; + } + + detected = true; + atExplicitKey = true; + allowCompact = true; + + } else if (atExplicitKey) { + // i.e. 0x3A/* : */ === character after the explicit key. + atExplicitKey = false; + allowCompact = true; + + } else { + throwError(state, 'incomplete explicit mapping pair; a key node is missed'); + } + + state.position += 1; + ch = following; + + // + // Implicit notation case. Flow-style node as the key first, then ":", and the value. + // + } else if (composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) { + + if (state.line === _line) { + ch = state.input.charCodeAt(state.position); + + while (is_WHITE_SPACE(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (ch === 0x3A/* : */) { + ch = state.input.charCodeAt(++state.position); + + if (!is_WS_OR_EOL(ch)) { + throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping'); + } + + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); + keyTag = keyNode = valueNode = null; + } + + detected = true; + atExplicitKey = false; + allowCompact = false; + keyTag = state.tag; + keyNode = state.result; + + } else if (detected) { + throwError(state, 'can not read an implicit mapping pair; a colon is missed'); + + } else { + state.tag = _tag; + state.anchor = _anchor; + return true; // Keep the result of `composeNode`. + } + + } else if (detected) { + throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key'); + + } else { + state.tag = _tag; + state.anchor = _anchor; + return true; // Keep the result of `composeNode`. + } + + } else { + break; // Reading is done. Go to the epilogue. + } + + // + // Common reading code for both explicit and implicit notations. + // + if (state.line === _line || state.lineIndent > nodeIndent) { + if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) { + if (atExplicitKey) { + keyNode = state.result; + } else { + valueNode = state.result; + } + } + + if (!atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode); + keyTag = keyNode = valueNode = null; + } + + skipSeparationSpace(state, true, -1); + ch = state.input.charCodeAt(state.position); + } + + if (state.lineIndent > nodeIndent && (ch !== 0)) { + throwError(state, 'bad indentation of a mapping entry'); + } else if (state.lineIndent < nodeIndent) { + break; + } + } + + // + // Epilogue. + // + + // Special case: last mapping's node contains only the key in explicit notation. + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); + } + + // Expose the resulting mapping. + if (detected) { + state.tag = _tag; + state.anchor = _anchor; + state.kind = 'mapping'; + state.result = _result; + } + + return detected; +} + +function readTagProperty(state) { + var _position, + isVerbatim = false, + isNamed = false, + tagHandle, + tagName, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x21/* ! */) return false; + + if (state.tag !== null) { + throwError(state, 'duplication of a tag property'); + } + + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x3C/* < */) { + isVerbatim = true; + ch = state.input.charCodeAt(++state.position); + + } else if (ch === 0x21/* ! */) { + isNamed = true; + tagHandle = '!!'; + ch = state.input.charCodeAt(++state.position); + + } else { + tagHandle = '!'; + } + + _position = state.position; + + if (isVerbatim) { + do { ch = state.input.charCodeAt(++state.position); } + while (ch !== 0 && ch !== 0x3E/* > */); + + if (state.position < state.length) { + tagName = state.input.slice(_position, state.position); + ch = state.input.charCodeAt(++state.position); + } else { + throwError(state, 'unexpected end of the stream within a verbatim tag'); + } + } else { + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + + if (ch === 0x21/* ! */) { + if (!isNamed) { + tagHandle = state.input.slice(_position - 1, state.position + 1); + + if (!PATTERN_TAG_HANDLE.test(tagHandle)) { + throwError(state, 'named tag handle cannot contain such characters'); + } + + isNamed = true; + _position = state.position + 1; + } else { + throwError(state, 'tag suffix cannot contain exclamation marks'); + } + } + + ch = state.input.charCodeAt(++state.position); + } + + tagName = state.input.slice(_position, state.position); + + if (PATTERN_FLOW_INDICATORS.test(tagName)) { + throwError(state, 'tag suffix cannot contain flow indicator characters'); + } + } + + if (tagName && !PATTERN_TAG_URI.test(tagName)) { + throwError(state, 'tag name cannot contain such characters: ' + tagName); + } + + if (isVerbatim) { + state.tag = tagName; + + } else if (_hasOwnProperty.call(state.tagMap, tagHandle)) { + state.tag = state.tagMap[tagHandle] + tagName; + + } else if (tagHandle === '!') { + state.tag = '!' + tagName; + + } else if (tagHandle === '!!') { + state.tag = 'tag:yaml.org,2002:' + tagName; + + } else { + throwError(state, 'undeclared tag handle "' + tagHandle + '"'); + } + + return true; +} + +function readAnchorProperty(state) { + var _position, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x26/* & */) return false; + + if (state.anchor !== null) { + throwError(state, 'duplication of an anchor property'); + } + + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (state.position === _position) { + throwError(state, 'name of an anchor node must contain at least one character'); + } + + state.anchor = state.input.slice(_position, state.position); + return true; +} + +function readAlias(state) { + var _position, alias, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x2A/* * */) return false; + + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (state.position === _position) { + throwError(state, 'name of an alias node must contain at least one character'); + } + + alias = state.input.slice(_position, state.position); + + if (!state.anchorMap.hasOwnProperty(alias)) { + throwError(state, 'unidentified alias "' + alias + '"'); + } + + state.result = state.anchorMap[alias]; + skipSeparationSpace(state, true, -1); + return true; +} + +function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) { + var allowBlockStyles, + allowBlockScalars, + allowBlockCollections, + indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) { + indentStatus = 1; + } else if (state.lineIndent === parentIndent) { + indentStatus = 0; + } else if (state.lineIndent < parentIndent) { + indentStatus = -1; + } + } + } + + if (indentStatus === 1) { + while (readTagProperty(state) || readAnchorProperty(state)) { + if (skipSeparationSpace(state, true, -1)) { + atNewLine = true; + allowBlockCollections = allowBlockStyles; + + if (state.lineIndent > parentIndent) { + indentStatus = 1; + } else if (state.lineIndent === parentIndent) { + indentStatus = 0; + } else if (state.lineIndent < parentIndent) { + indentStatus = -1; + } + } else { + allowBlockCollections = false; + } + } + } + + if (allowBlockCollections) { + allowBlockCollections = atNewLine || allowCompact; + } + + if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) { + if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) { + flowIndent = parentIndent; + } else { + flowIndent = parentIndent + 1; + } + + blockIndent = state.position - state.lineStart; + + if (indentStatus === 1) { + if (allowBlockCollections && + (readBlockSequence(state, blockIndent) || + readBlockMapping(state, blockIndent, flowIndent)) || + readFlowCollection(state, flowIndent)) { + hasContent = true; + } else { + if ((allowBlockScalars && readBlockScalar(state, flowIndent)) || + readSingleQuotedScalar(state, flowIndent) || + readDoubleQuotedScalar(state, flowIndent)) { + hasContent = true; + + } else if (readAlias(state)) { + hasContent = true; + + if (state.tag !== null || state.anchor !== null) { + throwError(state, 'alias node should not have any properties'); + } + + } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) { + hasContent = true; + + if (state.tag === null) { + state.tag = '?'; + } + } + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + } + } else if (indentStatus === 0) { + // Special case: block sequences are allowed to have same indentation level as the parent. + // http://www.yaml.org/spec/1.2/spec.html#id2799784 + hasContent = allowBlockCollections && readBlockSequence(state, blockIndent); + } + } + + if (state.tag !== null && state.tag !== '!') { + if (state.tag === '?') { + for (typeIndex = 0, typeQuantity = state.implicitTypes.length; + typeIndex < typeQuantity; + typeIndex += 1) { + type = state.implicitTypes[typeIndex]; + + // Implicit resolving is not allowed for non-scalar types, and '?' + // non-specific tag is only assigned to plain scalars. So, it isn't + // needed to check for 'kind' conformity. + + if (type.resolve(state.result)) { // `state.result` updated in resolver if matched + state.result = type.construct(state.result); + state.tag = type.tag; + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + break; + } + } + } else if (_hasOwnProperty.call(state.typeMap, state.tag)) { + type = state.typeMap[state.tag]; + + if (state.result !== null && type.kind !== state.kind) { + throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"'); + } + + if (!type.resolve(state.result)) { // `state.result` updated in resolver if matched + throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag'); + } else { + state.result = type.construct(state.result); + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + } + } else { + throwError(state, 'unknown tag !<' + state.tag + '>'); + } + } + + if (state.listener !== null) { + state.listener('close', state); + } + return state.tag !== null || state.anchor !== null || hasContent; +} + +function readDocument(state) { + var documentStart = state.position, + _position, + directiveName, + directiveArgs, + hasDirectives = false, + ch; + + state.version = null; + state.checkLineBreaks = state.legacy; + state.tagMap = {}; + state.anchorMap = {}; + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + skipSeparationSpace(state, true, -1); + + ch = state.input.charCodeAt(state.position); + + if (state.lineIndent > 0 || ch !== 0x25/* % */) { + break; + } + + hasDirectives = true; + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + directiveName = state.input.slice(_position, state.position); + directiveArgs = []; + + if (directiveName.length < 1) { + throwError(state, 'directive name must not be less than one character in length'); + } + + while (ch !== 0) { + while (is_WHITE_SPACE(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (ch === 0x23/* # */) { + do { ch = state.input.charCodeAt(++state.position); } + while (ch !== 0 && !is_EOL(ch)); + break; + } + + if (is_EOL(ch)) break; + + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + directiveArgs.push(state.input.slice(_position, state.position)); + } + + if (ch !== 0) readLineBreak(state); + + if (_hasOwnProperty.call(directiveHandlers, directiveName)) { + directiveHandlers[directiveName](state, directiveName, directiveArgs); + } else { + throwWarning(state, 'unknown document directive "' + directiveName + '"'); + } + } + + skipSeparationSpace(state, true, -1); + + if (state.lineIndent === 0 && + state.input.charCodeAt(state.position) === 0x2D/* - */ && + state.input.charCodeAt(state.position + 1) === 0x2D/* - */ && + state.input.charCodeAt(state.position + 2) === 0x2D/* - */) { + state.position += 3; + skipSeparationSpace(state, true, -1); + + } else if (hasDirectives) { + throwError(state, 'directives end mark is expected'); + } + + composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true); + skipSeparationSpace(state, true, -1); + + if (state.checkLineBreaks && + PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) { + throwWarning(state, 'non-ASCII line breaks are interpreted as content'); + } + + state.documents.push(state.result); + + if (state.position === state.lineStart && testDocumentSeparator(state)) { + + if (state.input.charCodeAt(state.position) === 0x2E/* . */) { + state.position += 3; + skipSeparationSpace(state, true, -1); + } + return; + } + + if (state.position < (state.length - 1)) { + throwError(state, 'end of the stream or a document separator is expected'); + } else { + return; + } +} + + +function loadDocuments(input, options) { + input = String(input); + options = options || {}; + + if (input.length !== 0) { + + // Add tailing `\n` if not exists + if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ && + input.charCodeAt(input.length - 1) !== 0x0D/* CR */) { + input += '\n'; + } + + // Strip BOM + if (input.charCodeAt(0) === 0xFEFF) { + input = input.slice(1); + } + } + + var state = new State(input, options); + + // Use 0 as string terminator. That significantly simplifies bounds check. + state.input += '\0'; + + while (state.input.charCodeAt(state.position) === 0x20/* Space */) { + state.lineIndent += 1; + state.position += 1; + } + + while (state.position < (state.length - 1)) { + readDocument(state); + } + + return state.documents; +} + + +function loadAll(input, iterator, options) { + var documents = loadDocuments(input, options), index, length; + + for (index = 0, length = documents.length; index < length; index += 1) { + iterator(documents[index]); + } +} + + +function load(input, options) { + var documents = loadDocuments(input, options); + + if (documents.length === 0) { + /*eslint-disable no-undefined*/ + return undefined; + } else if (documents.length === 1) { + return documents[0]; + } + throw new YAMLException('expected a single document in the stream, but found more'); +} + + +function safeLoadAll(input, output, options) { + loadAll(input, output, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); +} + + +function safeLoad(input, options) { + return load(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); +} + + +module.exports.loadAll = loadAll; +module.exports.load = load; +module.exports.safeLoadAll = safeLoadAll; +module.exports.safeLoad = safeLoad; diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/mark.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/mark.js new file mode 100644 index 0000000..47b265c --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/mark.js @@ -0,0 +1,76 @@ +'use strict'; + + +var common = require('./common'); + + +function Mark(name, buffer, position, line, column) { + this.name = name; + this.buffer = buffer; + this.position = position; + this.line = line; + this.column = column; +} + + +Mark.prototype.getSnippet = function getSnippet(indent, maxLength) { + var head, start, tail, end, snippet; + + if (!this.buffer) return null; + + indent = indent || 4; + maxLength = maxLength || 75; + + head = ''; + start = this.position; + + while (start > 0 && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(start - 1)) === -1) { + start -= 1; + if (this.position - start > (maxLength / 2 - 1)) { + head = ' ... '; + start += 5; + break; + } + } + + tail = ''; + end = this.position; + + while (end < this.buffer.length && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(end)) === -1) { + end += 1; + if (end - this.position > (maxLength / 2 - 1)) { + tail = ' ... '; + end -= 5; + break; + } + } + + snippet = this.buffer.slice(start, end); + + return common.repeat(' ', indent) + head + snippet + tail + '\n' + + common.repeat(' ', indent + this.position - start + head.length) + '^'; +}; + + +Mark.prototype.toString = function toString(compact) { + var snippet, where = ''; + + if (this.name) { + where += 'in "' + this.name + '" '; + } + + where += 'at line ' + (this.line + 1) + ', column ' + (this.column + 1); + + if (!compact) { + snippet = this.getSnippet(); + + if (snippet) { + where += ':\n' + snippet; + } + } + + return where; +}; + + +module.exports = Mark; diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema.js new file mode 100644 index 0000000..32803ff --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema.js @@ -0,0 +1,104 @@ +'use strict'; + +/*eslint-disable max-len*/ + +var common = require('./common'); +var YAMLException = require('./exception'); +var Type = require('./type'); + + +function compileList(schema, name, result) { + var exclude = []; + + schema.include.forEach(function (includedSchema) { + result = compileList(includedSchema, name, result); + }); + + schema[name].forEach(function (currentType) { + result.forEach(function (previousType, previousIndex) { + if (previousType.tag === currentType.tag) { + exclude.push(previousIndex); + } + }); + + result.push(currentType); + }); + + return result.filter(function (type, index) { + return exclude.indexOf(index) === -1; + }); +} + + +function compileMap(/* lists... */) { + var result = {}, index, length; + + function collectType(type) { + result[type.tag] = type; + } + + for (index = 0, length = arguments.length; index < length; index += 1) { + arguments[index].forEach(collectType); + } + + return result; +} + + +function Schema(definition) { + this.include = definition.include || []; + this.implicit = definition.implicit || []; + this.explicit = definition.explicit || []; + + this.implicit.forEach(function (type) { + if (type.loadKind && type.loadKind !== 'scalar') { + throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.'); + } + }); + + this.compiledImplicit = compileList(this, 'implicit', []); + this.compiledExplicit = compileList(this, 'explicit', []); + this.compiledTypeMap = compileMap(this.compiledImplicit, this.compiledExplicit); +} + + +Schema.DEFAULT = null; + + +Schema.create = function createSchema() { + var schemas, types; + + switch (arguments.length) { + case 1: + schemas = Schema.DEFAULT; + types = arguments[0]; + break; + + case 2: + schemas = arguments[0]; + types = arguments[1]; + break; + + default: + throw new YAMLException('Wrong number of arguments for Schema.create function'); + } + + schemas = common.toArray(schemas); + types = common.toArray(types); + + if (!schemas.every(function (schema) { return schema instanceof Schema; })) { + throw new YAMLException('Specified list of super schemas (or a single Schema object) contains a non-Schema object.'); + } + + if (!types.every(function (type) { return type instanceof Type; })) { + throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.'); + } + + return new Schema({ + include: schemas, + explicit: types + }); +}; + + +module.exports = Schema; diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema/core.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema/core.js new file mode 100644 index 0000000..206daab --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema/core.js @@ -0,0 +1,18 @@ +// Standard YAML's Core schema. +// http://www.yaml.org/spec/1.2/spec.html#id2804923 +// +// NOTE: JS-YAML does not support schema-specific tag resolution restrictions. +// So, Core schema has no distinctions from JSON schema is JS-YAML. + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + include: [ + require('./json') + ] +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema/default_full.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema/default_full.js new file mode 100644 index 0000000..a55ef42 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema/default_full.js @@ -0,0 +1,25 @@ +// JS-YAML's default schema for `load` function. +// It is not described in the YAML specification. +// +// This schema is based on JS-YAML's default safe schema and includes +// JavaScript-specific types: !!js/undefined, !!js/regexp and !!js/function. +// +// Also this schema is used as default base schema at `Schema.create` function. + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = Schema.DEFAULT = new Schema({ + include: [ + require('./default_safe') + ], + explicit: [ + require('../type/js/undefined'), + require('../type/js/regexp'), + require('../type/js/function') + ] +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema/default_safe.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema/default_safe.js new file mode 100644 index 0000000..11d89bb --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema/default_safe.js @@ -0,0 +1,28 @@ +// JS-YAML's default schema for `safeLoad` function. +// It is not described in the YAML specification. +// +// This schema is based on standard YAML's Core schema and includes most of +// extra types described at YAML tag repository. (http://yaml.org/type/) + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + include: [ + require('./core') + ], + implicit: [ + require('../type/timestamp'), + require('../type/merge') + ], + explicit: [ + require('../type/binary'), + require('../type/omap'), + require('../type/pairs'), + require('../type/set') + ] +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema/failsafe.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema/failsafe.js new file mode 100644 index 0000000..b7a33eb --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema/failsafe.js @@ -0,0 +1,17 @@ +// Standard YAML's Failsafe schema. +// http://www.yaml.org/spec/1.2/spec.html#id2802346 + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + explicit: [ + require('../type/str'), + require('../type/seq'), + require('../type/map') + ] +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema/json.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema/json.js new file mode 100644 index 0000000..5be3dbf --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/schema/json.js @@ -0,0 +1,25 @@ +// Standard YAML's JSON schema. +// http://www.yaml.org/spec/1.2/spec.html#id2803231 +// +// NOTE: JS-YAML does not support schema-specific tag resolution restrictions. +// So, this schema is not such strict as defined in the YAML specification. +// It allows numbers in binary notaion, use `Null` and `NULL` as `null`, etc. + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + include: [ + require('./failsafe') + ], + implicit: [ + require('../type/null'), + require('../type/bool'), + require('../type/int'), + require('../type/float') + ] +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type.js new file mode 100644 index 0000000..90b702a --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type.js @@ -0,0 +1,61 @@ +'use strict'; + +var YAMLException = require('./exception'); + +var TYPE_CONSTRUCTOR_OPTIONS = [ + 'kind', + 'resolve', + 'construct', + 'instanceOf', + 'predicate', + 'represent', + 'defaultStyle', + 'styleAliases' +]; + +var YAML_NODE_KINDS = [ + 'scalar', + 'sequence', + 'mapping' +]; + +function compileStyleAliases(map) { + var result = {}; + + if (map !== null) { + Object.keys(map).forEach(function (style) { + map[style].forEach(function (alias) { + result[String(alias)] = style; + }); + }); + } + + return result; +} + +function Type(tag, options) { + options = options || {}; + + Object.keys(options).forEach(function (name) { + if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) { + throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.'); + } + }); + + // TODO: Add tag format check. + this.tag = tag; + this.kind = options['kind'] || null; + this.resolve = options['resolve'] || function () { return true; }; + this.construct = options['construct'] || function (data) { return data; }; + this.instanceOf = options['instanceOf'] || null; + this.predicate = options['predicate'] || null; + this.represent = options['represent'] || null; + this.defaultStyle = options['defaultStyle'] || null; + this.styleAliases = compileStyleAliases(options['styleAliases'] || null); + + if (YAML_NODE_KINDS.indexOf(this.kind) === -1) { + throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.'); + } +} + +module.exports = Type; diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/binary.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/binary.js new file mode 100644 index 0000000..b2c32d9 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/binary.js @@ -0,0 +1,130 @@ +'use strict'; + +/*eslint-disable no-bitwise*/ + +// A trick for browserified version. +// Since we make browserifier to ignore `buffer` module, NodeBuffer will be undefined +var NodeBuffer = require('buffer').Buffer; +var Type = require('../type'); + + +// [ 64, 65, 66 ] -> [ padding, CR, LF ] +var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r'; + + +function resolveYamlBinary(data) { + if (data === null) return false; + + var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP; + + // Convert one by one. + for (idx = 0; idx < max; idx++) { + code = map.indexOf(data.charAt(idx)); + + // Skip CR/LF + if (code > 64) continue; + + // Fail on illegal characters + if (code < 0) return false; + + bitlen += 6; + } + + // If there are any bits left, source was corrupted + return (bitlen % 8) === 0; +} + +function constructYamlBinary(data) { + var idx, tailbits, + input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan + max = input.length, + map = BASE64_MAP, + bits = 0, + result = []; + + // Collect by 6*4 bits (3 bytes) + + for (idx = 0; idx < max; idx++) { + if ((idx % 4 === 0) && idx) { + result.push((bits >> 16) & 0xFF); + result.push((bits >> 8) & 0xFF); + result.push(bits & 0xFF); + } + + bits = (bits << 6) | map.indexOf(input.charAt(idx)); + } + + // Dump tail + + tailbits = (max % 4) * 6; + + if (tailbits === 0) { + result.push((bits >> 16) & 0xFF); + result.push((bits >> 8) & 0xFF); + result.push(bits & 0xFF); + } else if (tailbits === 18) { + result.push((bits >> 10) & 0xFF); + result.push((bits >> 2) & 0xFF); + } else if (tailbits === 12) { + result.push((bits >> 4) & 0xFF); + } + + // Wrap into Buffer for NodeJS and leave Array for browser + if (NodeBuffer) return new NodeBuffer(result); + + return result; +} + +function representYamlBinary(object /*, style*/) { + var result = '', bits = 0, idx, tail, + max = object.length, + map = BASE64_MAP; + + // Convert every three bytes to 4 ASCII characters. + + for (idx = 0; idx < max; idx++) { + if ((idx % 3 === 0) && idx) { + result += map[(bits >> 18) & 0x3F]; + result += map[(bits >> 12) & 0x3F]; + result += map[(bits >> 6) & 0x3F]; + result += map[bits & 0x3F]; + } + + bits = (bits << 8) + object[idx]; + } + + // Dump tail + + tail = max % 3; + + if (tail === 0) { + result += map[(bits >> 18) & 0x3F]; + result += map[(bits >> 12) & 0x3F]; + result += map[(bits >> 6) & 0x3F]; + result += map[bits & 0x3F]; + } else if (tail === 2) { + result += map[(bits >> 10) & 0x3F]; + result += map[(bits >> 4) & 0x3F]; + result += map[(bits << 2) & 0x3F]; + result += map[64]; + } else if (tail === 1) { + result += map[(bits >> 2) & 0x3F]; + result += map[(bits << 4) & 0x3F]; + result += map[64]; + result += map[64]; + } + + return result; +} + +function isBinary(object) { + return NodeBuffer && NodeBuffer.isBuffer(object); +} + +module.exports = new Type('tag:yaml.org,2002:binary', { + kind: 'scalar', + resolve: resolveYamlBinary, + construct: constructYamlBinary, + predicate: isBinary, + represent: representYamlBinary +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/bool.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/bool.js new file mode 100644 index 0000000..cb77459 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/bool.js @@ -0,0 +1,35 @@ +'use strict'; + +var Type = require('../type'); + +function resolveYamlBoolean(data) { + if (data === null) return false; + + var max = data.length; + + return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) || + (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE')); +} + +function constructYamlBoolean(data) { + return data === 'true' || + data === 'True' || + data === 'TRUE'; +} + +function isBoolean(object) { + return Object.prototype.toString.call(object) === '[object Boolean]'; +} + +module.exports = new Type('tag:yaml.org,2002:bool', { + kind: 'scalar', + resolve: resolveYamlBoolean, + construct: constructYamlBoolean, + predicate: isBoolean, + represent: { + lowercase: function (object) { return object ? 'true' : 'false'; }, + uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; }, + camelcase: function (object) { return object ? 'True' : 'False'; } + }, + defaultStyle: 'lowercase' +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/float.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/float.js new file mode 100644 index 0000000..7687154 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/float.js @@ -0,0 +1,105 @@ +'use strict'; + +var common = require('../common'); +var Type = require('../type'); + +var YAML_FLOAT_PATTERN = new RegExp( + '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' + + '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' + + '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' + + '|[-+]?\\.(?:inf|Inf|INF)' + + '|\\.(?:nan|NaN|NAN))$'); + +function resolveYamlFloat(data) { + if (data === null) return false; + + if (!YAML_FLOAT_PATTERN.test(data)) return false; + + return true; +} + +function constructYamlFloat(data) { + var value, sign, base, digits; + + value = data.replace(/_/g, '').toLowerCase(); + sign = value[0] === '-' ? -1 : 1; + digits = []; + + if ('+-'.indexOf(value[0]) >= 0) { + value = value.slice(1); + } + + if (value === '.inf') { + return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; + + } else if (value === '.nan') { + return NaN; + + } else if (value.indexOf(':') >= 0) { + value.split(':').forEach(function (v) { + digits.unshift(parseFloat(v, 10)); + }); + + value = 0.0; + base = 1; + + digits.forEach(function (d) { + value += d * base; + base *= 60; + }); + + return sign * value; + + } + return sign * parseFloat(value, 10); +} + + +var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/; + +function representYamlFloat(object, style) { + var res; + + if (isNaN(object)) { + switch (style) { + case 'lowercase': return '.nan'; + case 'uppercase': return '.NAN'; + case 'camelcase': return '.NaN'; + } + } else if (Number.POSITIVE_INFINITY === object) { + switch (style) { + case 'lowercase': return '.inf'; + case 'uppercase': return '.INF'; + case 'camelcase': return '.Inf'; + } + } else if (Number.NEGATIVE_INFINITY === object) { + switch (style) { + case 'lowercase': return '-.inf'; + case 'uppercase': return '-.INF'; + case 'camelcase': return '-.Inf'; + } + } else if (common.isNegativeZero(object)) { + return '-0.0'; + } + + res = object.toString(10); + + // JS stringifier can build scientific format without dots: 5e-100, + // while YAML requres dot: 5.e-100. Fix it with simple hack + + return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res; +} + +function isFloat(object) { + return (Object.prototype.toString.call(object) === '[object Number]') && + (object % 1 !== 0 || common.isNegativeZero(object)); +} + +module.exports = new Type('tag:yaml.org,2002:float', { + kind: 'scalar', + resolve: resolveYamlFloat, + construct: constructYamlFloat, + predicate: isFloat, + represent: representYamlFloat, + defaultStyle: 'lowercase' +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/int.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/int.js new file mode 100644 index 0000000..a3c4965 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/int.js @@ -0,0 +1,168 @@ +'use strict'; + +var common = require('../common'); +var Type = require('../type'); + +function isHexCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) || + ((0x41/* A */ <= c) && (c <= 0x46/* F */)) || + ((0x61/* a */ <= c) && (c <= 0x66/* f */)); +} + +function isOctCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */)); +} + +function isDecCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)); +} + +function resolveYamlInteger(data) { + if (data === null) return false; + + var max = data.length, + index = 0, + hasDigits = false, + ch; + + if (!max) return false; + + ch = data[index]; + + // sign + if (ch === '-' || ch === '+') { + ch = data[++index]; + } + + if (ch === '0') { + // 0 + if (index + 1 === max) return true; + ch = data[++index]; + + // base 2, base 8, base 16 + + if (ch === 'b') { + // base 2 + index++; + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (ch !== '0' && ch !== '1') return false; + hasDigits = true; + } + return hasDigits; + } + + + if (ch === 'x') { + // base 16 + index++; + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (!isHexCode(data.charCodeAt(index))) return false; + hasDigits = true; + } + return hasDigits; + } + + // base 8 + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (!isOctCode(data.charCodeAt(index))) return false; + hasDigits = true; + } + return hasDigits; + } + + // base 10 (except 0) or base 60 + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (ch === ':') break; + if (!isDecCode(data.charCodeAt(index))) { + return false; + } + hasDigits = true; + } + + if (!hasDigits) return false; + + // if !base60 - done; + if (ch !== ':') return true; + + // base60 almost not used, no needs to optimize + return /^(:[0-5]?[0-9])+$/.test(data.slice(index)); +} + +function constructYamlInteger(data) { + var value = data, sign = 1, ch, base, digits = []; + + if (value.indexOf('_') !== -1) { + value = value.replace(/_/g, ''); + } + + ch = value[0]; + + if (ch === '-' || ch === '+') { + if (ch === '-') sign = -1; + value = value.slice(1); + ch = value[0]; + } + + if (value === '0') return 0; + + if (ch === '0') { + if (value[1] === 'b') return sign * parseInt(value.slice(2), 2); + if (value[1] === 'x') return sign * parseInt(value, 16); + return sign * parseInt(value, 8); + } + + if (value.indexOf(':') !== -1) { + value.split(':').forEach(function (v) { + digits.unshift(parseInt(v, 10)); + }); + + value = 0; + base = 1; + + digits.forEach(function (d) { + value += (d * base); + base *= 60; + }); + + return sign * value; + + } + + return sign * parseInt(value, 10); +} + +function isInteger(object) { + return (Object.prototype.toString.call(object)) === '[object Number]' && + (object % 1 === 0 && !common.isNegativeZero(object)); +} + +module.exports = new Type('tag:yaml.org,2002:int', { + kind: 'scalar', + resolve: resolveYamlInteger, + construct: constructYamlInteger, + predicate: isInteger, + represent: { + binary: function (object) { return '0b' + object.toString(2); }, + octal: function (object) { return '0' + object.toString(8); }, + decimal: function (object) { return object.toString(10); }, + hexadecimal: function (object) { return '0x' + object.toString(16).toUpperCase(); } + }, + defaultStyle: 'decimal', + styleAliases: { + binary: [ 2, 'bin' ], + octal: [ 8, 'oct' ], + decimal: [ 10, 'dec' ], + hexadecimal: [ 16, 'hex' ] + } +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/js/function.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/js/function.js new file mode 100644 index 0000000..c6a42d0 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/js/function.js @@ -0,0 +1,84 @@ +'use strict'; + +var esprima; + +// Browserified version does not have esprima +// +// 1. For node.js just require module as deps +// 2. For browser try to require mudule via external AMD system. +// If not found - try to fallback to window.esprima. If not +// found too - then fail to parse. +// +try { + // workaround to exclude package from browserify list. + var _require = require; + esprima = _require('esprima'); +} catch (_) { + /*global window */ + if (typeof window !== 'undefined') esprima = window.esprima; +} + +var Type = require('../../type'); + +function resolveJavascriptFunction(data) { + if (data === null) return false; + + try { + var source = '(' + data + ')', + ast = esprima.parse(source, { range: true }); + + if (ast.type !== 'Program' || + ast.body.length !== 1 || + ast.body[0].type !== 'ExpressionStatement' || + ast.body[0].expression.type !== 'FunctionExpression') { + return false; + } + + return true; + } catch (err) { + return false; + } +} + +function constructJavascriptFunction(data) { + /*jslint evil:true*/ + + var source = '(' + data + ')', + ast = esprima.parse(source, { range: true }), + params = [], + body; + + if (ast.type !== 'Program' || + ast.body.length !== 1 || + ast.body[0].type !== 'ExpressionStatement' || + ast.body[0].expression.type !== 'FunctionExpression') { + throw new Error('Failed to resolve function'); + } + + ast.body[0].expression.params.forEach(function (param) { + params.push(param.name); + }); + + body = ast.body[0].expression.body.range; + + // Esprima's ranges include the first '{' and the last '}' characters on + // function expressions. So cut them out. + /*eslint-disable no-new-func*/ + return new Function(params, source.slice(body[0] + 1, body[1] - 1)); +} + +function representJavascriptFunction(object /*, style*/) { + return object.toString(); +} + +function isFunction(object) { + return Object.prototype.toString.call(object) === '[object Function]'; +} + +module.exports = new Type('tag:yaml.org,2002:js/function', { + kind: 'scalar', + resolve: resolveJavascriptFunction, + construct: constructJavascriptFunction, + predicate: isFunction, + represent: representJavascriptFunction +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js new file mode 100644 index 0000000..43fa470 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js @@ -0,0 +1,60 @@ +'use strict'; + +var Type = require('../../type'); + +function resolveJavascriptRegExp(data) { + if (data === null) return false; + if (data.length === 0) return false; + + var regexp = data, + tail = /\/([gim]*)$/.exec(data), + modifiers = ''; + + // if regexp starts with '/' it can have modifiers and must be properly closed + // `/foo/gim` - modifiers tail can be maximum 3 chars + if (regexp[0] === '/') { + if (tail) modifiers = tail[1]; + + if (modifiers.length > 3) return false; + // if expression starts with /, is should be properly terminated + if (regexp[regexp.length - modifiers.length - 1] !== '/') return false; + } + + return true; +} + +function constructJavascriptRegExp(data) { + var regexp = data, + tail = /\/([gim]*)$/.exec(data), + modifiers = ''; + + // `/foo/gim` - tail can be maximum 4 chars + if (regexp[0] === '/') { + if (tail) modifiers = tail[1]; + regexp = regexp.slice(1, regexp.length - modifiers.length - 1); + } + + return new RegExp(regexp, modifiers); +} + +function representJavascriptRegExp(object /*, style*/) { + var result = '/' + object.source + '/'; + + if (object.global) result += 'g'; + if (object.multiline) result += 'm'; + if (object.ignoreCase) result += 'i'; + + return result; +} + +function isRegExp(object) { + return Object.prototype.toString.call(object) === '[object RegExp]'; +} + +module.exports = new Type('tag:yaml.org,2002:js/regexp', { + kind: 'scalar', + resolve: resolveJavascriptRegExp, + construct: constructJavascriptRegExp, + predicate: isRegExp, + represent: representJavascriptRegExp +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js new file mode 100644 index 0000000..95b5569 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js @@ -0,0 +1,28 @@ +'use strict'; + +var Type = require('../../type'); + +function resolveJavascriptUndefined() { + return true; +} + +function constructJavascriptUndefined() { + /*eslint-disable no-undefined*/ + return undefined; +} + +function representJavascriptUndefined() { + return ''; +} + +function isUndefined(object) { + return typeof object === 'undefined'; +} + +module.exports = new Type('tag:yaml.org,2002:js/undefined', { + kind: 'scalar', + resolve: resolveJavascriptUndefined, + construct: constructJavascriptUndefined, + predicate: isUndefined, + represent: representJavascriptUndefined +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/map.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/map.js new file mode 100644 index 0000000..f327bee --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/map.js @@ -0,0 +1,8 @@ +'use strict'; + +var Type = require('../type'); + +module.exports = new Type('tag:yaml.org,2002:map', { + kind: 'mapping', + construct: function (data) { return data !== null ? data : {}; } +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/merge.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/merge.js new file mode 100644 index 0000000..ae08a86 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/merge.js @@ -0,0 +1,12 @@ +'use strict'; + +var Type = require('../type'); + +function resolveYamlMerge(data) { + return data === '<<' || data === null; +} + +module.exports = new Type('tag:yaml.org,2002:merge', { + kind: 'scalar', + resolve: resolveYamlMerge +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/null.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/null.js new file mode 100644 index 0000000..6874daa --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/null.js @@ -0,0 +1,34 @@ +'use strict'; + +var Type = require('../type'); + +function resolveYamlNull(data) { + if (data === null) return true; + + var max = data.length; + + return (max === 1 && data === '~') || + (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL')); +} + +function constructYamlNull() { + return null; +} + +function isNull(object) { + return object === null; +} + +module.exports = new Type('tag:yaml.org,2002:null', { + kind: 'scalar', + resolve: resolveYamlNull, + construct: constructYamlNull, + predicate: isNull, + represent: { + canonical: function () { return '~'; }, + lowercase: function () { return 'null'; }, + uppercase: function () { return 'NULL'; }, + camelcase: function () { return 'Null'; } + }, + defaultStyle: 'lowercase' +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/omap.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/omap.js new file mode 100644 index 0000000..b2b5323 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/omap.js @@ -0,0 +1,44 @@ +'use strict'; + +var Type = require('../type'); + +var _hasOwnProperty = Object.prototype.hasOwnProperty; +var _toString = Object.prototype.toString; + +function resolveYamlOmap(data) { + if (data === null) return true; + + var objectKeys = [], index, length, pair, pairKey, pairHasKey, + object = data; + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + pairHasKey = false; + + if (_toString.call(pair) !== '[object Object]') return false; + + for (pairKey in pair) { + if (_hasOwnProperty.call(pair, pairKey)) { + if (!pairHasKey) pairHasKey = true; + else return false; + } + } + + if (!pairHasKey) return false; + + if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey); + else return false; + } + + return true; +} + +function constructYamlOmap(data) { + return data !== null ? data : []; +} + +module.exports = new Type('tag:yaml.org,2002:omap', { + kind: 'sequence', + resolve: resolveYamlOmap, + construct: constructYamlOmap +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/pairs.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/pairs.js new file mode 100644 index 0000000..74b5240 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/pairs.js @@ -0,0 +1,53 @@ +'use strict'; + +var Type = require('../type'); + +var _toString = Object.prototype.toString; + +function resolveYamlPairs(data) { + if (data === null) return true; + + var index, length, pair, keys, result, + object = data; + + result = new Array(object.length); + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + + if (_toString.call(pair) !== '[object Object]') return false; + + keys = Object.keys(pair); + + if (keys.length !== 1) return false; + + result[index] = [ keys[0], pair[keys[0]] ]; + } + + return true; +} + +function constructYamlPairs(data) { + if (data === null) return []; + + var index, length, pair, keys, result, + object = data; + + result = new Array(object.length); + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + + keys = Object.keys(pair); + + result[index] = [ keys[0], pair[keys[0]] ]; + } + + return result; +} + +module.exports = new Type('tag:yaml.org,2002:pairs', { + kind: 'sequence', + resolve: resolveYamlPairs, + construct: constructYamlPairs +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/seq.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/seq.js new file mode 100644 index 0000000..be8f77f --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/seq.js @@ -0,0 +1,8 @@ +'use strict'; + +var Type = require('../type'); + +module.exports = new Type('tag:yaml.org,2002:seq', { + kind: 'sequence', + construct: function (data) { return data !== null ? data : []; } +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/set.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/set.js new file mode 100644 index 0000000..f885a32 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/set.js @@ -0,0 +1,29 @@ +'use strict'; + +var Type = require('../type'); + +var _hasOwnProperty = Object.prototype.hasOwnProperty; + +function resolveYamlSet(data) { + if (data === null) return true; + + var key, object = data; + + for (key in object) { + if (_hasOwnProperty.call(object, key)) { + if (object[key] !== null) return false; + } + } + + return true; +} + +function constructYamlSet(data) { + return data !== null ? data : {}; +} + +module.exports = new Type('tag:yaml.org,2002:set', { + kind: 'mapping', + resolve: resolveYamlSet, + construct: constructYamlSet +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/str.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/str.js new file mode 100644 index 0000000..27acc10 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/str.js @@ -0,0 +1,8 @@ +'use strict'; + +var Type = require('../type'); + +module.exports = new Type('tag:yaml.org,2002:str', { + kind: 'scalar', + construct: function (data) { return data !== null ? data : ''; } +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/timestamp.js b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/timestamp.js new file mode 100644 index 0000000..8fa9c58 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/lib/js-yaml/type/timestamp.js @@ -0,0 +1,88 @@ +'use strict'; + +var Type = require('../type'); + +var YAML_DATE_REGEXP = new RegExp( + '^([0-9][0-9][0-9][0-9])' + // [1] year + '-([0-9][0-9])' + // [2] month + '-([0-9][0-9])$'); // [3] day + +var YAML_TIMESTAMP_REGEXP = new RegExp( + '^([0-9][0-9][0-9][0-9])' + // [1] year + '-([0-9][0-9]?)' + // [2] month + '-([0-9][0-9]?)' + // [3] day + '(?:[Tt]|[ \\t]+)' + // ... + '([0-9][0-9]?)' + // [4] hour + ':([0-9][0-9])' + // [5] minute + ':([0-9][0-9])' + // [6] second + '(?:\\.([0-9]*))?' + // [7] fraction + '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour + '(?::([0-9][0-9]))?))?$'); // [11] tz_minute + +function resolveYamlTimestamp(data) { + if (data === null) return false; + if (YAML_DATE_REGEXP.exec(data) !== null) return true; + if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true; + return false; +} + +function constructYamlTimestamp(data) { + var match, year, month, day, hour, minute, second, fraction = 0, + delta = null, tz_hour, tz_minute, date; + + match = YAML_DATE_REGEXP.exec(data); + if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data); + + if (match === null) throw new Error('Date resolve error'); + + // match: [1] year [2] month [3] day + + year = +(match[1]); + month = +(match[2]) - 1; // JS month starts with 0 + day = +(match[3]); + + if (!match[4]) { // no hour + return new Date(Date.UTC(year, month, day)); + } + + // match: [4] hour [5] minute [6] second [7] fraction + + hour = +(match[4]); + minute = +(match[5]); + second = +(match[6]); + + if (match[7]) { + fraction = match[7].slice(0, 3); + while (fraction.length < 3) { // milli-seconds + fraction += '0'; + } + fraction = +fraction; + } + + // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute + + if (match[9]) { + tz_hour = +(match[10]); + tz_minute = +(match[11] || 0); + delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds + if (match[9] === '-') delta = -delta; + } + + date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction)); + + if (delta) date.setTime(date.getTime() - delta); + + return date; +} + +function representYamlTimestamp(object /*, style*/) { + return object.toISOString(); +} + +module.exports = new Type('tag:yaml.org,2002:timestamp', { + kind: 'scalar', + resolve: resolveYamlTimestamp, + construct: constructYamlTimestamp, + instanceOf: Date, + represent: representYamlTimestamp +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/js-yaml/package.json b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/package.json new file mode 100644 index 0000000..0fdfd6a --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/js-yaml/package.json @@ -0,0 +1,130 @@ +{ + "_args": [ + [ + { + "raw": "js-yaml@~3.5.2", + "scope": null, + "escapedName": "js-yaml", + "name": "js-yaml", + "rawSpec": "~3.5.2", + "spec": ">=3.5.2 <3.6.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt-sftp-deploy/node_modules/grunt" + ] + ], + "_from": "js-yaml@>=3.5.2 <3.6.0", + "_id": "js-yaml@3.5.5", + "_inCache": true, + "_location": "/grunt-sftp-deploy/js-yaml", + "_nodeVersion": "4.3.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/js-yaml-3.5.5.tgz_1458226126775_0.5821511475369334" + }, + "_npmUser": { + "name": "vitaly", + "email": "vitaly@rcdesign.ru" + }, + "_npmVersion": "2.14.12", + "_phantomChildren": {}, + "_requested": { + "raw": "js-yaml@~3.5.2", + "scope": null, + "escapedName": "js-yaml", + "name": "js-yaml", + "rawSpec": "~3.5.2", + "spec": ">=3.5.2 <3.6.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt-sftp-deploy/grunt" + ], + "_resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.5.5.tgz", + "_shasum": "0377c38017cabc7322b0d1fbcd25a491641f2fbe", + "_shrinkwrap": null, + "_spec": "js-yaml@~3.5.2", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt-sftp-deploy/node_modules/grunt", + "author": { + "name": "Vladimir Zapparov", + "email": "dervus.grim@gmail.com" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + }, + "browser": { + "buffer": false + }, + "bugs": { + "url": "https://github.com/nodeca/js-yaml/issues" + }, + "contributors": [ + { + "name": "Aleksey V Zapparov", + "email": "ixti@member.fsf.org", + "url": "http://www.ixti.net/" + }, + { + "name": "Vitaly Puzrin", + "email": "vitaly@rcdesign.ru", + "url": "https://github.com/puzrin" + }, + { + "name": "Martin Grenfell", + "email": "martin.grenfell@gmail.com", + "url": "http://got-ravings.blogspot.com" + } + ], + "dependencies": { + "argparse": "^1.0.2", + "esprima": "^2.6.0" + }, + "description": "YAML 1.2 parser and serializer", + "devDependencies": { + "ansi": "*", + "benchmark": "*", + "browserify": "^13.0.0", + "codemirror": "^5.10.0", + "eslint": "^2.0.0-rc.1", + "istanbul": "*", + "mocha": "*", + "uglify-js": "^2.6.1" + }, + "directories": {}, + "dist": { + "shasum": "0377c38017cabc7322b0d1fbcd25a491641f2fbe", + "tarball": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.5.5.tgz" + }, + "files": [ + "index.js", + "lib/", + "bin/", + "dist/" + ], + "gitHead": "fdd205e5a1175a62868c0efb28a77493e5e34e3f", + "homepage": "https://github.com/nodeca/js-yaml", + "keywords": [ + "yaml", + "parser", + "serializer", + "pyyaml" + ], + "license": "MIT", + "maintainers": [ + { + "name": "vitaly", + "email": "vitaly@rcdesign.ru" + } + ], + "name": "js-yaml", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/nodeca/js-yaml.git" + }, + "scripts": { + "test": "make test" + }, + "version": "3.5.5" +} diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/LICENSE b/node_modules/grunt-sftp-deploy/node_modules/lodash/LICENSE new file mode 100644 index 0000000..9cd87e5 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/LICENSE @@ -0,0 +1,22 @@ +Copyright 2012-2015 The Dojo Foundation +Based on Underscore.js, copyright 2009-2015 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/README.md b/node_modules/grunt-sftp-deploy/node_modules/lodash/README.md new file mode 100644 index 0000000..fd98e5c --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/README.md @@ -0,0 +1,121 @@ +# lodash v3.10.1 + +The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash](https://lodash.com/) exported as [Node.js](http://nodejs.org/)/[io.js](https://iojs.org/) modules. + +Generated using [lodash-cli](https://www.npmjs.com/package/lodash-cli): +```bash +$ lodash modularize modern exports=node -o ./ +$ lodash modern -d -o ./index.js +``` + +## Installation + +Using npm: + +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash +``` + +In Node.js/io.js: + +```js +// load the modern build +var _ = require('lodash'); +// or a method category +var array = require('lodash/array'); +// or a method (great for smaller builds with browserify/webpack) +var chunk = require('lodash/array/chunk'); +``` + +See the [package source](https://github.com/lodash/lodash/tree/3.10.1-npm) for more details. + +**Note:**
          +Don’t assign values to the [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL.
          +Install [n_](https://www.npmjs.com/package/n_) for a REPL that includes lodash by default. + +## Module formats + +lodash is also available in a variety of other builds & module formats. + + * npm packages for [modern](https://www.npmjs.com/package/lodash), [compatibility](https://www.npmjs.com/package/lodash-compat), & [per method](https://www.npmjs.com/browse/keyword/lodash-modularized) builds + * AMD modules for [modern](https://github.com/lodash/lodash/tree/3.10.1-amd) & [compatibility](https://github.com/lodash/lodash-compat/tree/3.10.1-amd) builds + * ES modules for the [modern](https://github.com/lodash/lodash/tree/3.10.1-es) build + +## Further Reading + + * [API Documentation](https://lodash.com/docs) + * [Build Differences](https://github.com/lodash/lodash/wiki/Build-Differences) + * [Changelog](https://github.com/lodash/lodash/wiki/Changelog) + * [Roadmap](https://github.com/lodash/lodash/wiki/Roadmap) + * [More Resources](https://github.com/lodash/lodash/wiki/Resources) + +## Features + + * ~100% [code coverage](https://coveralls.io/r/lodash) + * Follows [semantic versioning](http://semver.org/) for releases + * [Lazily evaluated](http://filimanjaro.com/blog/2014/introducing-lazy-evaluation/) chaining + * [_(…)](https://lodash.com/docs#_) supports implicit chaining + * [_.ary](https://lodash.com/docs#ary) & [_.rearg](https://lodash.com/docs#rearg) to change function argument limits & order + * [_.at](https://lodash.com/docs#at) for cherry-picking collection values + * [_.attempt](https://lodash.com/docs#attempt) to execute functions which may error without a try-catch + * [_.before](https://lodash.com/docs#before) to complement [_.after](https://lodash.com/docs#after) + * [_.bindKey](https://lodash.com/docs#bindKey) for binding [*“lazy”*](http://michaux.ca/articles/lazy-function-definition-pattern) defined methods + * [_.chunk](https://lodash.com/docs#chunk) for splitting an array into chunks of a given size + * [_.clone](https://lodash.com/docs#clone) supports shallow cloning of `Date` & `RegExp` objects + * [_.cloneDeep](https://lodash.com/docs#cloneDeep) for deep cloning arrays & objects + * [_.curry](https://lodash.com/docs#curry) & [_.curryRight](https://lodash.com/docs#curryRight) for creating [curried](http://hughfdjackson.com/javascript/why-curry-helps/) functions + * [_.debounce](https://lodash.com/docs#debounce) & [_.throttle](https://lodash.com/docs#throttle) are cancelable & accept options for more control + * [_.defaultsDeep](https://lodash.com/docs#defaultsDeep) for recursively assigning default properties + * [_.fill](https://lodash.com/docs#fill) to fill arrays with values + * [_.findKey](https://lodash.com/docs#findKey) for finding keys + * [_.flow](https://lodash.com/docs#flow) to complement [_.flowRight](https://lodash.com/docs#flowRight) (a.k.a `_.compose`) + * [_.forEach](https://lodash.com/docs#forEach) supports exiting early + * [_.forIn](https://lodash.com/docs#forIn) for iterating all enumerable properties + * [_.forOwn](https://lodash.com/docs#forOwn) for iterating own properties + * [_.get](https://lodash.com/docs#get) & [_.set](https://lodash.com/docs#set) for deep property getting & setting + * [_.gt](https://lodash.com/docs#gt), [_.gte](https://lodash.com/docs#gte), [_.lt](https://lodash.com/docs#lt), & [_.lte](https://lodash.com/docs#lte) relational methods + * [_.inRange](https://lodash.com/docs#inRange) for checking whether a number is within a given range + * [_.isNative](https://lodash.com/docs#isNative) to check for native functions + * [_.isPlainObject](https://lodash.com/docs#isPlainObject) & [_.toPlainObject](https://lodash.com/docs#toPlainObject) to check for & convert to `Object` objects + * [_.isTypedArray](https://lodash.com/docs#isTypedArray) to check for typed arrays + * [_.mapKeys](https://lodash.com/docs#mapKeys) for mapping keys to an object + * [_.matches](https://lodash.com/docs#matches) supports deep object comparisons + * [_.matchesProperty](https://lodash.com/docs#matchesProperty) to complement [_.matches](https://lodash.com/docs#matches) & [_.property](https://lodash.com/docs#property) + * [_.merge](https://lodash.com/docs#merge) for a deep [_.extend](https://lodash.com/docs#extend) + * [_.method](https://lodash.com/docs#method) & [_.methodOf](https://lodash.com/docs#methodOf) to create functions that invoke methods + * [_.modArgs](https://lodash.com/docs#modArgs) for more advanced functional composition + * [_.parseInt](https://lodash.com/docs#parseInt) for consistent cross-environment behavior + * [_.pull](https://lodash.com/docs#pull), [_.pullAt](https://lodash.com/docs#pullAt), & [_.remove](https://lodash.com/docs#remove) for mutating arrays + * [_.random](https://lodash.com/docs#random) supports returning floating-point numbers + * [_.restParam](https://lodash.com/docs#restParam) & [_.spread](https://lodash.com/docs#spread) for applying rest parameters & spreading arguments to functions + * [_.runInContext](https://lodash.com/docs#runInContext) for collisionless mixins & easier mocking + * [_.slice](https://lodash.com/docs#slice) for creating subsets of array-like values + * [_.sortByAll](https://lodash.com/docs#sortByAll) & [_.sortByOrder](https://lodash.com/docs#sortByOrder) for sorting by multiple properties & orders + * [_.support](https://lodash.com/docs#support) for flagging environment features + * [_.template](https://lodash.com/docs#template) supports [*“imports”*](https://lodash.com/docs#templateSettings-imports) options & [ES template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components) + * [_.transform](https://lodash.com/docs#transform) as a powerful alternative to [_.reduce](https://lodash.com/docs#reduce) for transforming objects + * [_.unzipWith](https://lodash.com/docs#unzipWith) & [_.zipWith](https://lodash.com/docs#zipWith) to specify how grouped values should be combined + * [_.valuesIn](https://lodash.com/docs#valuesIn) for getting values of all enumerable properties + * [_.xor](https://lodash.com/docs#xor) to complement [_.difference](https://lodash.com/docs#difference), [_.intersection](https://lodash.com/docs#intersection), & [_.union](https://lodash.com/docs#union) + * [_.add](https://lodash.com/docs#add), [_.round](https://lodash.com/docs#round), [_.sum](https://lodash.com/docs#sum), & + [more](https://lodash.com/docs "_.ceil & _.floor") math methods + * [_.bind](https://lodash.com/docs#bind), [_.curry](https://lodash.com/docs#curry), [_.partial](https://lodash.com/docs#partial), & + [more](https://lodash.com/docs "_.bindKey, _.curryRight, _.partialRight") support customizable argument placeholders + * [_.capitalize](https://lodash.com/docs#capitalize), [_.trim](https://lodash.com/docs#trim), & + [more](https://lodash.com/docs "_.camelCase, _.deburr, _.endsWith, _.escapeRegExp, _.kebabCase, _.pad, _.padLeft, _.padRight, _.repeat, _.snakeCase, _.startCase, _.startsWith, _.trimLeft, _.trimRight, _.trunc, _.words") string methods + * [_.clone](https://lodash.com/docs#clone), [_.isEqual](https://lodash.com/docs#isEqual), & + [more](https://lodash.com/docs "_.assign, _.cloneDeep, _.merge") accept customizer callbacks + * [_.dropWhile](https://lodash.com/docs#dropWhile), [_.takeWhile](https://lodash.com/docs#takeWhile), & + [more](https://lodash.com/docs "_.drop, _.dropRight, _.dropRightWhile, _.take, _.takeRight, _.takeRightWhile") to complement [_.first](https://lodash.com/docs#first), [_.initial](https://lodash.com/docs#initial), [_.last](https://lodash.com/docs#last), & [_.rest](https://lodash.com/docs#rest) + * [_.findLast](https://lodash.com/docs#findLast), [_.findLastKey](https://lodash.com/docs#findLastKey), & + [more](https://lodash.com/docs "_.curryRight, _.dropRight, _.dropRightWhile, _.flowRight, _.forEachRight, _.forInRight, _.forOwnRight, _.padRight, partialRight, _.takeRight, _.trimRight, _.takeRightWhile") right-associative methods + * [_.includes](https://lodash.com/docs#includes), [_.toArray](https://lodash.com/docs#toArray), & + [more](https://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.findLast, _.findWhere, _.forEach, _.forEachRight, _.groupBy, _.indexBy, _.invoke, _.map, _.max, _.min, _.partition, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.size, _.some, _.sortBy, _.sortByAll, _.sortByOrder, _.sum, _.where") accept strings + * [_#commit](https://lodash.com/docs#prototype-commit) & [_#plant](https://lodash.com/docs#prototype-plant) for working with chain sequences + * [_#thru](https://lodash.com/docs#thru) to pass values thru a chain sequence + +## Support + +Tested in Chrome 43-44, Firefox 38-39, IE 6-11, MS Edge, Safari 5-8, ChakraNode 0.12.2, io.js 2.5.0, Node.js 0.8.28, 0.10.40, & 0.12.7, PhantomJS 1.9.8, RingoJS 0.11, & Rhino 1.7.6. +Automated [browser](https://saucelabs.com/u/lodash) & [CI](https://travis-ci.org/lodash/lodash/) test runs are available. Special thanks to [Sauce Labs](https://saucelabs.com/) for providing automated browser testing. diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array.js new file mode 100644 index 0000000..e5121fa --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array.js @@ -0,0 +1,44 @@ +module.exports = { + 'chunk': require('./array/chunk'), + 'compact': require('./array/compact'), + 'difference': require('./array/difference'), + 'drop': require('./array/drop'), + 'dropRight': require('./array/dropRight'), + 'dropRightWhile': require('./array/dropRightWhile'), + 'dropWhile': require('./array/dropWhile'), + 'fill': require('./array/fill'), + 'findIndex': require('./array/findIndex'), + 'findLastIndex': require('./array/findLastIndex'), + 'first': require('./array/first'), + 'flatten': require('./array/flatten'), + 'flattenDeep': require('./array/flattenDeep'), + 'head': require('./array/head'), + 'indexOf': require('./array/indexOf'), + 'initial': require('./array/initial'), + 'intersection': require('./array/intersection'), + 'last': require('./array/last'), + 'lastIndexOf': require('./array/lastIndexOf'), + 'object': require('./array/object'), + 'pull': require('./array/pull'), + 'pullAt': require('./array/pullAt'), + 'remove': require('./array/remove'), + 'rest': require('./array/rest'), + 'slice': require('./array/slice'), + 'sortedIndex': require('./array/sortedIndex'), + 'sortedLastIndex': require('./array/sortedLastIndex'), + 'tail': require('./array/tail'), + 'take': require('./array/take'), + 'takeRight': require('./array/takeRight'), + 'takeRightWhile': require('./array/takeRightWhile'), + 'takeWhile': require('./array/takeWhile'), + 'union': require('./array/union'), + 'uniq': require('./array/uniq'), + 'unique': require('./array/unique'), + 'unzip': require('./array/unzip'), + 'unzipWith': require('./array/unzipWith'), + 'without': require('./array/without'), + 'xor': require('./array/xor'), + 'zip': require('./array/zip'), + 'zipObject': require('./array/zipObject'), + 'zipWith': require('./array/zipWith') +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/chunk.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/chunk.js new file mode 100644 index 0000000..c8be1fb --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/chunk.js @@ -0,0 +1,46 @@ +var baseSlice = require('../internal/baseSlice'), + isIterateeCall = require('../internal/isIterateeCall'); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeFloor = Math.floor, + nativeMax = Math.max; + +/** + * Creates an array of elements split into groups the length of `size`. + * If `collection` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=1] The length of each chunk. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new array containing chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ +function chunk(array, size, guard) { + if (guard ? isIterateeCall(array, size, guard) : size == null) { + size = 1; + } else { + size = nativeMax(nativeFloor(size) || 1, 1); + } + var index = 0, + length = array ? array.length : 0, + resIndex = -1, + result = Array(nativeCeil(length / size)); + + while (index < length) { + result[++resIndex] = baseSlice(array, index, (index += size)); + } + return result; +} + +module.exports = chunk; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/compact.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/compact.js new file mode 100644 index 0000000..1dc1c55 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/compact.js @@ -0,0 +1,30 @@ +/** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ +function compact(array) { + var index = -1, + length = array ? array.length : 0, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[++resIndex] = value; + } + } + return result; +} + +module.exports = compact; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/difference.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/difference.js new file mode 100644 index 0000000..128932a --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/difference.js @@ -0,0 +1,29 @@ +var baseDifference = require('../internal/baseDifference'), + baseFlatten = require('../internal/baseFlatten'), + isArrayLike = require('../internal/isArrayLike'), + isObjectLike = require('../internal/isObjectLike'), + restParam = require('../function/restParam'); + +/** + * Creates an array of unique `array` values not included in the other + * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.difference([1, 2, 3], [4, 2]); + * // => [1, 3] + */ +var difference = restParam(function(array, values) { + return (isObjectLike(array) && isArrayLike(array)) + ? baseDifference(array, baseFlatten(values, false, true)) + : []; +}); + +module.exports = difference; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/drop.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/drop.js new file mode 100644 index 0000000..039a0b5 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/drop.js @@ -0,0 +1,39 @@ +var baseSlice = require('../internal/baseSlice'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ +function drop(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, n < 0 ? 0 : n); +} + +module.exports = drop; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/dropRight.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/dropRight.js new file mode 100644 index 0000000..14b5eb6 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/dropRight.js @@ -0,0 +1,40 @@ +var baseSlice = require('../internal/baseSlice'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Creates a slice of `array` with `n` elements dropped from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRight([1, 2, 3]); + * // => [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ +function dropRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, 0, n < 0 ? 0 : n); +} + +module.exports = dropRight; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/dropRightWhile.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/dropRightWhile.js new file mode 100644 index 0000000..be158bd --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/dropRightWhile.js @@ -0,0 +1,59 @@ +var baseCallback = require('../internal/baseCallback'), + baseWhile = require('../internal/baseWhile'); + +/** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that match the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [1] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); + * // => ['barney'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ +function dropRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, baseCallback(predicate, thisArg, 3), true, true) + : []; +} + +module.exports = dropRightWhile; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/dropWhile.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/dropWhile.js new file mode 100644 index 0000000..d9eabae --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/dropWhile.js @@ -0,0 +1,59 @@ +var baseCallback = require('../internal/baseCallback'), + baseWhile = require('../internal/baseWhile'); + +/** + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [3] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropWhile(users, 'active', false), 'user'); + * // => ['pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ +function dropWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, baseCallback(predicate, thisArg, 3), true) + : []; +} + +module.exports = dropWhile; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/fill.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/fill.js new file mode 100644 index 0000000..2c8f6da --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/fill.js @@ -0,0 +1,44 @@ +var baseFill = require('../internal/baseFill'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8], '*', 1, 2); + * // => [4, '*', 8] + */ +function fill(array, value, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } + return baseFill(array, value, start, end); +} + +module.exports = fill; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/findIndex.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/findIndex.js new file mode 100644 index 0000000..2a6b8e1 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/findIndex.js @@ -0,0 +1,53 @@ +var createFindIndex = require('../internal/createFindIndex'); + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(chr) { + * return chr.user == 'barney'; + * }); + * // => 0 + * + * // using the `_.matches` callback shorthand + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // using the `_.matchesProperty` callback shorthand + * _.findIndex(users, 'active', false); + * // => 0 + * + * // using the `_.property` callback shorthand + * _.findIndex(users, 'active'); + * // => 2 + */ +var findIndex = createFindIndex(); + +module.exports = findIndex; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/findLastIndex.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/findLastIndex.js new file mode 100644 index 0000000..d6d8eca --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/findLastIndex.js @@ -0,0 +1,53 @@ +var createFindIndex = require('../internal/createFindIndex'); + +/** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(chr) { + * return chr.user == 'pebbles'; + * }); + * // => 2 + * + * // using the `_.matches` callback shorthand + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastIndex(users, 'active', false); + * // => 2 + * + * // using the `_.property` callback shorthand + * _.findLastIndex(users, 'active'); + * // => 0 + */ +var findLastIndex = createFindIndex(true); + +module.exports = findLastIndex; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/first.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/first.js new file mode 100644 index 0000000..b3b9c79 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/first.js @@ -0,0 +1,22 @@ +/** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @alias head + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([]); + * // => undefined + */ +function first(array) { + return array ? array[0] : undefined; +} + +module.exports = first; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/flatten.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/flatten.js new file mode 100644 index 0000000..dc2eff8 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/flatten.js @@ -0,0 +1,32 @@ +var baseFlatten = require('../internal/baseFlatten'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Flattens a nested array. If `isDeep` is `true` the array is recursively + * flattened, otherwise it's only flattened a single level. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @param {boolean} [isDeep] Specify a deep flatten. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, 3, [4]]]); + * // => [1, 2, 3, [4]] + * + * // using `isDeep` + * _.flatten([1, [2, 3, [4]]], true); + * // => [1, 2, 3, 4] + */ +function flatten(array, isDeep, guard) { + var length = array ? array.length : 0; + if (guard && isIterateeCall(array, isDeep, guard)) { + isDeep = false; + } + return length ? baseFlatten(array, isDeep) : []; +} + +module.exports = flatten; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/flattenDeep.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/flattenDeep.js new file mode 100644 index 0000000..9f775fe --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/flattenDeep.js @@ -0,0 +1,21 @@ +var baseFlatten = require('../internal/baseFlatten'); + +/** + * Recursively flattens a nested array. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to recursively flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, 3, [4]]]); + * // => [1, 2, 3, 4] + */ +function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, true) : []; +} + +module.exports = flattenDeep; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/head.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/head.js new file mode 100644 index 0000000..1961b08 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/head.js @@ -0,0 +1 @@ +module.exports = require('./first'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/indexOf.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/indexOf.js new file mode 100644 index 0000000..4cfc682 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/indexOf.js @@ -0,0 +1,53 @@ +var baseIndexOf = require('../internal/baseIndexOf'), + binaryIndex = require('../internal/binaryIndex'); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the offset + * from the end of `array`. If `array` is sorted providing `true` for `fromIndex` + * performs a faster binary search. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // using `fromIndex` + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + * + * // performing a binary search + * _.indexOf([1, 1, 2, 2], 2, true); + * // => 2 + */ +function indexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + if (typeof fromIndex == 'number') { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; + } else if (fromIndex) { + var index = binaryIndex(array, value); + if (index < length && + (value === value ? (value === array[index]) : (array[index] !== array[index]))) { + return index; + } + return -1; + } + return baseIndexOf(array, value, fromIndex || 0); +} + +module.exports = indexOf; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/initial.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/initial.js new file mode 100644 index 0000000..59b7a7d --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/initial.js @@ -0,0 +1,20 @@ +var dropRight = require('./dropRight'); + +/** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ +function initial(array) { + return dropRight(array, 1); +} + +module.exports = initial; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/intersection.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/intersection.js new file mode 100644 index 0000000..f218432 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/intersection.js @@ -0,0 +1,58 @@ +var baseIndexOf = require('../internal/baseIndexOf'), + cacheIndexOf = require('../internal/cacheIndexOf'), + createCache = require('../internal/createCache'), + isArrayLike = require('../internal/isArrayLike'), + restParam = require('../function/restParam'); + +/** + * Creates an array of unique values that are included in all of the provided + * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of shared values. + * @example + * _.intersection([1, 2], [4, 2], [2, 1]); + * // => [2] + */ +var intersection = restParam(function(arrays) { + var othLength = arrays.length, + othIndex = othLength, + caches = Array(length), + indexOf = baseIndexOf, + isCommon = true, + result = []; + + while (othIndex--) { + var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : []; + caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null; + } + var array = arrays[0], + index = -1, + length = array ? array.length : 0, + seen = caches[0]; + + outer: + while (++index < length) { + value = array[index]; + if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) { + var othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) { + continue outer; + } + } + if (seen) { + seen.push(value); + } + result.push(value); + } + } + return result; +}); + +module.exports = intersection; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/last.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/last.js new file mode 100644 index 0000000..299af31 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/last.js @@ -0,0 +1,19 @@ +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; +} + +module.exports = last; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/lastIndexOf.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/lastIndexOf.js new file mode 100644 index 0000000..02b8062 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/lastIndexOf.js @@ -0,0 +1,60 @@ +var binaryIndex = require('../internal/binaryIndex'), + indexOfNaN = require('../internal/indexOfNaN'); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max, + nativeMin = Math.min; + +/** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=array.length-1] The index to search from + * or `true` to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // using `fromIndex` + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + * + * // performing a binary search + * _.lastIndexOf([1, 1, 2, 2], 2, true); + * // => 3 + */ +function lastIndexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + var index = length; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1; + } else if (fromIndex) { + index = binaryIndex(array, value, true) - 1; + var other = array[index]; + if (value === value ? (value === other) : (other !== other)) { + return index; + } + return -1; + } + if (value !== value) { + return indexOfNaN(array, index, true); + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +module.exports = lastIndexOf; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/object.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/object.js new file mode 100644 index 0000000..f4a3453 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/object.js @@ -0,0 +1 @@ +module.exports = require('./zipObject'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/pull.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/pull.js new file mode 100644 index 0000000..7bcbb4a --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/pull.js @@ -0,0 +1,52 @@ +var baseIndexOf = require('../internal/baseIndexOf'); + +/** Used for native method references. */ +var arrayProto = Array.prototype; + +/** Native method references. */ +var splice = arrayProto.splice; + +/** + * Removes all provided values from `array` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.without`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...*} [values] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ +function pull() { + var args = arguments, + array = args[0]; + + if (!(array && array.length)) { + return array; + } + var index = 0, + indexOf = baseIndexOf, + length = args.length; + + while (++index < length) { + var fromIndex = 0, + value = args[index]; + + while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { + splice.call(array, fromIndex, 1); + } + } + return array; +} + +module.exports = pull; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/pullAt.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/pullAt.js new file mode 100644 index 0000000..4ca2476 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/pullAt.js @@ -0,0 +1,40 @@ +var baseAt = require('../internal/baseAt'), + baseCompareAscending = require('../internal/baseCompareAscending'), + baseFlatten = require('../internal/baseFlatten'), + basePullAt = require('../internal/basePullAt'), + restParam = require('../function/restParam'); + +/** + * Removes elements from `array` corresponding to the given indexes and returns + * an array of the removed elements. Indexes may be specified as an array of + * indexes or as individual arguments. + * + * **Note:** Unlike `_.at`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...(number|number[])} [indexes] The indexes of elements to remove, + * specified as individual indexes or arrays of indexes. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [5, 10, 15, 20]; + * var evens = _.pullAt(array, 1, 3); + * + * console.log(array); + * // => [5, 15] + * + * console.log(evens); + * // => [10, 20] + */ +var pullAt = restParam(function(array, indexes) { + indexes = baseFlatten(indexes); + + var result = baseAt(array, indexes); + basePullAt(array, indexes.sort(baseCompareAscending)); + return result; +}); + +module.exports = pullAt; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/remove.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/remove.js new file mode 100644 index 0000000..0cf979b --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/remove.js @@ -0,0 +1,64 @@ +var baseCallback = require('../internal/baseCallback'), + basePullAt = require('../internal/basePullAt'); + +/** + * Removes all elements from `array` that `predicate` returns truthy for + * and returns an array of the removed elements. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * **Note:** Unlike `_.filter`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4]; + * var evens = _.remove(array, function(n) { + * return n % 2 == 0; + * }); + * + * console.log(array); + * // => [1, 3] + * + * console.log(evens); + * // => [2, 4] + */ +function remove(array, predicate, thisArg) { + var result = []; + if (!(array && array.length)) { + return result; + } + var index = -1, + indexes = [], + length = array.length; + + predicate = baseCallback(predicate, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result.push(value); + indexes.push(index); + } + } + basePullAt(array, indexes); + return result; +} + +module.exports = remove; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/rest.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/rest.js new file mode 100644 index 0000000..9bfb734 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/rest.js @@ -0,0 +1,21 @@ +var drop = require('./drop'); + +/** + * Gets all but the first element of `array`. + * + * @static + * @memberOf _ + * @alias tail + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + */ +function rest(array) { + return drop(array, 1); +} + +module.exports = rest; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/slice.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/slice.js new file mode 100644 index 0000000..48ef1a1 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/slice.js @@ -0,0 +1,30 @@ +var baseSlice = require('../internal/baseSlice'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of `Array#slice` to support node + * lists in IE < 9 and to ensure dense arrays are returned. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ +function slice(array, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; + } + return baseSlice(array, start, end); +} + +module.exports = slice; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/sortedIndex.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/sortedIndex.js new file mode 100644 index 0000000..6903bca --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/sortedIndex.js @@ -0,0 +1,53 @@ +var createSortedIndex = require('../internal/createSortedIndex'); + +/** + * Uses a binary search to determine the lowest index at which `value` should + * be inserted into `array` in order to maintain its sort order. If an iteratee + * function is provided it's invoked for `value` and each element of `array` + * to compute their sort ranking. The iteratee is bound to `thisArg` and + * invoked with one argument; (value). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + * + * _.sortedIndex([4, 4, 5, 5], 5); + * // => 2 + * + * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; + * + * // using an iteratee function + * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { + * return this.data[word]; + * }, dict); + * // => 1 + * + * // using the `_.property` callback shorthand + * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 1 + */ +var sortedIndex = createSortedIndex(); + +module.exports = sortedIndex; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/sortedLastIndex.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/sortedLastIndex.js new file mode 100644 index 0000000..81a4a86 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/sortedLastIndex.js @@ -0,0 +1,25 @@ +var createSortedIndex = require('../internal/createSortedIndex'); + +/** + * This method is like `_.sortedIndex` except that it returns the highest + * index at which `value` should be inserted into `array` in order to + * maintain its sort order. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedLastIndex([4, 4, 5, 5], 5); + * // => 4 + */ +var sortedLastIndex = createSortedIndex(true); + +module.exports = sortedLastIndex; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/tail.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/tail.js new file mode 100644 index 0000000..c5dfe77 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/tail.js @@ -0,0 +1 @@ +module.exports = require('./rest'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/take.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/take.js new file mode 100644 index 0000000..875917a --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/take.js @@ -0,0 +1,39 @@ +var baseSlice = require('../internal/baseSlice'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Creates a slice of `array` with `n` elements taken from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.take([1, 2, 3]); + * // => [1] + * + * _.take([1, 2, 3], 2); + * // => [1, 2] + * + * _.take([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.take([1, 2, 3], 0); + * // => [] + */ +function take(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, 0, n < 0 ? 0 : n); +} + +module.exports = take; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/takeRight.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/takeRight.js new file mode 100644 index 0000000..6e89c87 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/takeRight.js @@ -0,0 +1,40 @@ +var baseSlice = require('../internal/baseSlice'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Creates a slice of `array` with `n` elements taken from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRight([1, 2, 3]); + * // => [3] + * + * _.takeRight([1, 2, 3], 2); + * // => [2, 3] + * + * _.takeRight([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.takeRight([1, 2, 3], 0); + * // => [] + */ +function takeRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, n < 0 ? 0 : n); +} + +module.exports = takeRight; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/takeRightWhile.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/takeRightWhile.js new file mode 100644 index 0000000..5464d13 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/takeRightWhile.js @@ -0,0 +1,59 @@ +var baseCallback = require('../internal/baseCallback'), + baseWhile = require('../internal/baseWhile'); + +/** + * Creates a slice of `array` with elements taken from the end. Elements are + * taken until `predicate` returns falsey. The predicate is bound to `thisArg` + * and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [2, 3] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active'), 'user'); + * // => [] + */ +function takeRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, baseCallback(predicate, thisArg, 3), false, true) + : []; +} + +module.exports = takeRightWhile; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/takeWhile.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/takeWhile.js new file mode 100644 index 0000000..f7e28a1 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/takeWhile.js @@ -0,0 +1,59 @@ +var baseCallback = require('../internal/baseCallback'), + baseWhile = require('../internal/baseWhile'); + +/** + * Creates a slice of `array` with elements taken from the beginning. Elements + * are taken until `predicate` returns falsey. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [1, 2] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false}, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeWhile(users, 'active', false), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeWhile(users, 'active'), 'user'); + * // => [] + */ +function takeWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, baseCallback(predicate, thisArg, 3)) + : []; +} + +module.exports = takeWhile; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/union.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/union.js new file mode 100644 index 0000000..53cefe4 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/union.js @@ -0,0 +1,24 @@ +var baseFlatten = require('../internal/baseFlatten'), + baseUniq = require('../internal/baseUniq'), + restParam = require('../function/restParam'); + +/** + * Creates an array of unique values, in order, from all of the provided arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([1, 2], [4, 2], [2, 1]); + * // => [1, 2, 4] + */ +var union = restParam(function(arrays) { + return baseUniq(baseFlatten(arrays, false, true)); +}); + +module.exports = union; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/uniq.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/uniq.js new file mode 100644 index 0000000..ae937ef --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/uniq.js @@ -0,0 +1,71 @@ +var baseCallback = require('../internal/baseCallback'), + baseUniq = require('../internal/baseUniq'), + isIterateeCall = require('../internal/isIterateeCall'), + sortedUniq = require('../internal/sortedUniq'); + +/** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurence of each element + * is kept. Providing `true` for `isSorted` performs a faster search algorithm + * for sorted arrays. If an iteratee function is provided it's invoked for + * each element in the array to generate the criterion by which uniqueness + * is computed. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index, array). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Array + * @param {Array} array The array to inspect. + * @param {boolean} [isSorted] Specify the array is sorted. + * @param {Function|Object|string} [iteratee] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new duplicate-value-free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + * + * // using `isSorted` + * _.uniq([1, 1, 2], true); + * // => [1, 2] + * + * // using an iteratee function + * _.uniq([1, 2.5, 1.5, 2], function(n) { + * return this.floor(n); + * }, Math); + * // => [1, 2.5] + * + * // using the `_.property` callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ +function uniq(array, isSorted, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (isSorted != null && typeof isSorted != 'boolean') { + thisArg = iteratee; + iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted; + isSorted = false; + } + iteratee = iteratee == null ? iteratee : baseCallback(iteratee, thisArg, 3); + return (isSorted) + ? sortedUniq(array, iteratee) + : baseUniq(array, iteratee); +} + +module.exports = uniq; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/unique.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/unique.js new file mode 100644 index 0000000..396de1b --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/unique.js @@ -0,0 +1 @@ +module.exports = require('./uniq'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/unzip.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/unzip.js new file mode 100644 index 0000000..0a539fa --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/unzip.js @@ -0,0 +1,47 @@ +var arrayFilter = require('../internal/arrayFilter'), + arrayMap = require('../internal/arrayMap'), + baseProperty = require('../internal/baseProperty'), + isArrayLike = require('../internal/isArrayLike'); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-zip + * configuration. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + * + * _.unzip(zipped); + * // => [['fred', 'barney'], [30, 40], [true, false]] + */ +function unzip(array) { + if (!(array && array.length)) { + return []; + } + var index = -1, + length = 0; + + array = arrayFilter(array, function(group) { + if (isArrayLike(group)) { + length = nativeMax(group.length, length); + return true; + } + }); + var result = Array(length); + while (++index < length) { + result[index] = arrayMap(array, baseProperty(index)); + } + return result; +} + +module.exports = unzip; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/unzipWith.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/unzipWith.js new file mode 100644 index 0000000..324a2b1 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/unzipWith.js @@ -0,0 +1,41 @@ +var arrayMap = require('../internal/arrayMap'), + arrayReduce = require('../internal/arrayReduce'), + bindCallback = require('../internal/bindCallback'), + unzip = require('./unzip'); + +/** + * This method is like `_.unzip` except that it accepts an iteratee to specify + * how regrouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @param {Function} [iteratee] The function to combine regrouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip([1, 2], [10, 20], [100, 200]); + * // => [[1, 10, 100], [2, 20, 200]] + * + * _.unzipWith(zipped, _.add); + * // => [3, 30, 300] + */ +function unzipWith(array, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + var result = unzip(array); + if (iteratee == null) { + return result; + } + iteratee = bindCallback(iteratee, thisArg, 4); + return arrayMap(result, function(group) { + return arrayReduce(group, iteratee, undefined, true); + }); +} + +module.exports = unzipWith; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/without.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/without.js new file mode 100644 index 0000000..2ac3d11 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/without.js @@ -0,0 +1,27 @@ +var baseDifference = require('../internal/baseDifference'), + isArrayLike = require('../internal/isArrayLike'), + restParam = require('../function/restParam'); + +/** + * Creates an array excluding all provided values using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to filter. + * @param {...*} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.without([1, 2, 1, 3], 1, 2); + * // => [3] + */ +var without = restParam(function(array, values) { + return isArrayLike(array) + ? baseDifference(array, values) + : []; +}); + +module.exports = without; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/xor.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/xor.js new file mode 100644 index 0000000..04ef32a --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/xor.js @@ -0,0 +1,35 @@ +var arrayPush = require('../internal/arrayPush'), + baseDifference = require('../internal/baseDifference'), + baseUniq = require('../internal/baseUniq'), + isArrayLike = require('../internal/isArrayLike'); + +/** + * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) + * of the provided arrays. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of values. + * @example + * + * _.xor([1, 2], [4, 2]); + * // => [1, 4] + */ +function xor() { + var index = -1, + length = arguments.length; + + while (++index < length) { + var array = arguments[index]; + if (isArrayLike(array)) { + var result = result + ? arrayPush(baseDifference(result, array), baseDifference(array, result)) + : array; + } + } + return result ? baseUniq(result) : []; +} + +module.exports = xor; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/zip.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/zip.js new file mode 100644 index 0000000..53a6f69 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/zip.js @@ -0,0 +1,21 @@ +var restParam = require('../function/restParam'), + unzip = require('./unzip'); + +/** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second elements + * of the given arrays, and so on. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ +var zip = restParam(unzip); + +module.exports = zip; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/zipObject.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/zipObject.js new file mode 100644 index 0000000..dec7a21 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/zipObject.js @@ -0,0 +1,43 @@ +var isArray = require('../lang/isArray'); + +/** + * The inverse of `_.pairs`; this method returns an object composed from arrays + * of property names and values. Provide either a single two dimensional array, + * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names + * and one of corresponding values. + * + * @static + * @memberOf _ + * @alias object + * @category Array + * @param {Array} props The property names. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject([['fred', 30], ['barney', 40]]); + * // => { 'fred': 30, 'barney': 40 } + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ +function zipObject(props, values) { + var index = -1, + length = props ? props.length : 0, + result = {}; + + if (length && !values && !isArray(props[0])) { + values = []; + } + while (++index < length) { + var key = props[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; +} + +module.exports = zipObject; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/array/zipWith.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/zipWith.js new file mode 100644 index 0000000..ad10374 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/array/zipWith.js @@ -0,0 +1,36 @@ +var restParam = require('../function/restParam'), + unzipWith = require('./unzipWith'); + +/** + * This method is like `_.zip` except that it accepts an iteratee to specify + * how grouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @param {Function} [iteratee] The function to combine grouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zipWith([1, 2], [10, 20], [100, 200], _.add); + * // => [111, 222] + */ +var zipWith = restParam(function(arrays) { + var length = arrays.length, + iteratee = length > 2 ? arrays[length - 2] : undefined, + thisArg = length > 1 ? arrays[length - 1] : undefined; + + if (length > 2 && typeof iteratee == 'function') { + length -= 2; + } else { + iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined; + thisArg = undefined; + } + arrays.length = length; + return unzipWith(arrays, iteratee, thisArg); +}); + +module.exports = zipWith; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain.js new file mode 100644 index 0000000..6439627 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain.js @@ -0,0 +1,16 @@ +module.exports = { + 'chain': require('./chain/chain'), + 'commit': require('./chain/commit'), + 'concat': require('./chain/concat'), + 'lodash': require('./chain/lodash'), + 'plant': require('./chain/plant'), + 'reverse': require('./chain/reverse'), + 'run': require('./chain/run'), + 'tap': require('./chain/tap'), + 'thru': require('./chain/thru'), + 'toJSON': require('./chain/toJSON'), + 'toString': require('./chain/toString'), + 'value': require('./chain/value'), + 'valueOf': require('./chain/valueOf'), + 'wrapperChain': require('./chain/wrapperChain') +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/chain.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/chain.js new file mode 100644 index 0000000..453ba1e --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/chain.js @@ -0,0 +1,35 @@ +var lodash = require('./lodash'); + +/** + * Creates a `lodash` object that wraps `value` with explicit method + * chaining enabled. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _.chain(users) + * .sortBy('age') + * .map(function(chr) { + * return chr.user + ' is ' + chr.age; + * }) + * .first() + * .value(); + * // => 'pebbles is 1' + */ +function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; +} + +module.exports = chain; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/commit.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/commit.js new file mode 100644 index 0000000..c732d1b --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/commit.js @@ -0,0 +1 @@ +module.exports = require('./wrapperCommit'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/concat.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/concat.js new file mode 100644 index 0000000..90607d1 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/concat.js @@ -0,0 +1 @@ +module.exports = require('./wrapperConcat'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/lodash.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/lodash.js new file mode 100644 index 0000000..1c3467e --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/lodash.js @@ -0,0 +1,125 @@ +var LazyWrapper = require('../internal/LazyWrapper'), + LodashWrapper = require('../internal/LodashWrapper'), + baseLodash = require('../internal/baseLodash'), + isArray = require('../lang/isArray'), + isObjectLike = require('../internal/isObjectLike'), + wrapperClone = require('../internal/wrapperClone'); + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Creates a `lodash` object which wraps `value` to enable implicit chaining. + * Methods that operate on and return arrays, collections, and functions can + * be chained together. Methods that retrieve a single value or may return a + * primitive value will automatically end the chain returning the unwrapped + * value. Explicit chaining may be enabled using `_.chain`. The execution of + * chained methods is lazy, that is, execution is deferred until `_#value` + * is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. Shortcut + * fusion is an optimization strategy which merge iteratee calls; this can help + * to avoid the creation of intermediate data structures and greatly reduce the + * number of iteratee executions. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, + * `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, + * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, + * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, + * and `where` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, + * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, + * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`, + * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`, + * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, + * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, + * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, + * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, + * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, + * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, + * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, + * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, + * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, + * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, + * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, + * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, + * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`, + * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, + * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, + * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, + * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, + * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, + * `unescape`, `uniqueId`, `value`, and `words` + * + * The wrapper method `sample` will return a wrapped value when `n` is provided, + * otherwise an unwrapped value is returned. + * + * @name _ + * @constructor + * @category Chain + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(total, n) { + * return total + n; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(n) { + * return n * n; + * }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ +function lodash(value) { + if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); +} + +// Ensure wrappers are instances of `baseLodash`. +lodash.prototype = baseLodash.prototype; + +module.exports = lodash; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/plant.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/plant.js new file mode 100644 index 0000000..04099f2 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/plant.js @@ -0,0 +1 @@ +module.exports = require('./wrapperPlant'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/reverse.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/reverse.js new file mode 100644 index 0000000..f72a64a --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/reverse.js @@ -0,0 +1 @@ +module.exports = require('./wrapperReverse'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/run.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/run.js new file mode 100644 index 0000000..5e751a2 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/run.js @@ -0,0 +1 @@ +module.exports = require('./wrapperValue'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/tap.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/tap.js new file mode 100644 index 0000000..3d0257e --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/tap.js @@ -0,0 +1,29 @@ +/** + * This method invokes `interceptor` and returns `value`. The interceptor is + * bound to `thisArg` and invoked with one argument; (value). The purpose of + * this method is to "tap into" a method chain in order to perform operations + * on intermediate results within the chain. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ +function tap(value, interceptor, thisArg) { + interceptor.call(thisArg, value); + return value; +} + +module.exports = tap; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/thru.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/thru.js new file mode 100644 index 0000000..a715780 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/thru.js @@ -0,0 +1,26 @@ +/** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ +function thru(value, interceptor, thisArg) { + return interceptor.call(thisArg, value); +} + +module.exports = thru; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/toJSON.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/toJSON.js new file mode 100644 index 0000000..5e751a2 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/toJSON.js @@ -0,0 +1 @@ +module.exports = require('./wrapperValue'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/toString.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/toString.js new file mode 100644 index 0000000..c7bcbf9 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/toString.js @@ -0,0 +1 @@ +module.exports = require('./wrapperToString'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/value.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/value.js new file mode 100644 index 0000000..5e751a2 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/value.js @@ -0,0 +1 @@ +module.exports = require('./wrapperValue'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/valueOf.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/valueOf.js new file mode 100644 index 0000000..5e751a2 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/valueOf.js @@ -0,0 +1 @@ +module.exports = require('./wrapperValue'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperChain.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperChain.js new file mode 100644 index 0000000..3823481 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperChain.js @@ -0,0 +1,32 @@ +var chain = require('./chain'); + +/** + * Enables explicit method chaining on the wrapper object. + * + * @name chain + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // without explicit chaining + * _(users).first(); + * // => { 'user': 'barney', 'age': 36 } + * + * // with explicit chaining + * _(users).chain() + * .first() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ +function wrapperChain() { + return chain(this); +} + +module.exports = wrapperChain; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperCommit.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperCommit.js new file mode 100644 index 0000000..c3d2898 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperCommit.js @@ -0,0 +1,32 @@ +var LodashWrapper = require('../internal/LodashWrapper'); + +/** + * Executes the chained sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ +function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); +} + +module.exports = wrapperCommit; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperConcat.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperConcat.js new file mode 100644 index 0000000..799156c --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperConcat.js @@ -0,0 +1,34 @@ +var arrayConcat = require('../internal/arrayConcat'), + baseFlatten = require('../internal/baseFlatten'), + isArray = require('../lang/isArray'), + restParam = require('../function/restParam'), + toObject = require('../internal/toObject'); + +/** + * Creates a new array joining a wrapped array with any additional arrays + * and/or values. + * + * @name concat + * @memberOf _ + * @category Chain + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var wrapped = _(array).concat(2, [3], [[4]]); + * + * console.log(wrapped.value()); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ +var wrapperConcat = restParam(function(values) { + values = baseFlatten(values); + return this.thru(function(array) { + return arrayConcat(isArray(array) ? array : [toObject(array)], values); + }); +}); + +module.exports = wrapperConcat; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperPlant.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperPlant.js new file mode 100644 index 0000000..234fe41 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperPlant.js @@ -0,0 +1,45 @@ +var baseLodash = require('../internal/baseLodash'), + wrapperClone = require('../internal/wrapperClone'); + +/** + * Creates a clone of the chained sequence planting `value` as the wrapped value. + * + * @name plant + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).map(function(value) { + * return Math.pow(value, 2); + * }); + * + * var other = [3, 4]; + * var otherWrapped = wrapped.plant(other); + * + * otherWrapped.value(); + * // => [9, 16] + * + * wrapped.value(); + * // => [1, 4] + */ +function wrapperPlant(value) { + var result, + parent = this; + + while (parent instanceof baseLodash) { + var clone = wrapperClone(parent); + if (result) { + previous.__wrapped__ = clone; + } else { + result = clone; + } + var previous = clone; + parent = parent.__wrapped__; + } + previous.__wrapped__ = value; + return result; +} + +module.exports = wrapperPlant; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperReverse.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperReverse.js new file mode 100644 index 0000000..6ba546d --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperReverse.js @@ -0,0 +1,43 @@ +var LazyWrapper = require('../internal/LazyWrapper'), + LodashWrapper = require('../internal/LodashWrapper'), + thru = require('./thru'); + +/** + * Reverses the wrapped array so the first element becomes the last, the + * second element becomes the second to last, and so on. + * + * **Note:** This method mutates the wrapped array. + * + * @name reverse + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new reversed `lodash` wrapper instance. + * @example + * + * var array = [1, 2, 3]; + * + * _(array).reverse().value() + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ +function wrapperReverse() { + var value = this.__wrapped__; + + var interceptor = function(value) { + return value.reverse(); + }; + if (value instanceof LazyWrapper) { + var wrapped = value; + if (this.__actions__.length) { + wrapped = new LazyWrapper(this); + } + wrapped = wrapped.reverse(); + wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); + return new LodashWrapper(wrapped, this.__chain__); + } + return this.thru(interceptor); +} + +module.exports = wrapperReverse; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperToString.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperToString.js new file mode 100644 index 0000000..db975a5 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperToString.js @@ -0,0 +1,17 @@ +/** + * Produces the result of coercing the unwrapped value to a string. + * + * @name toString + * @memberOf _ + * @category Chain + * @returns {string} Returns the coerced string value. + * @example + * + * _([1, 2, 3]).toString(); + * // => '1,2,3' + */ +function wrapperToString() { + return (this.value() + ''); +} + +module.exports = wrapperToString; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperValue.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperValue.js new file mode 100644 index 0000000..2734e41 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/chain/wrapperValue.js @@ -0,0 +1,20 @@ +var baseWrapperValue = require('../internal/baseWrapperValue'); + +/** + * Executes the chained sequence to extract the unwrapped value. + * + * @name value + * @memberOf _ + * @alias run, toJSON, valueOf + * @category Chain + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ +function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); +} + +module.exports = wrapperValue; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection.js new file mode 100644 index 0000000..0338857 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection.js @@ -0,0 +1,44 @@ +module.exports = { + 'all': require('./collection/all'), + 'any': require('./collection/any'), + 'at': require('./collection/at'), + 'collect': require('./collection/collect'), + 'contains': require('./collection/contains'), + 'countBy': require('./collection/countBy'), + 'detect': require('./collection/detect'), + 'each': require('./collection/each'), + 'eachRight': require('./collection/eachRight'), + 'every': require('./collection/every'), + 'filter': require('./collection/filter'), + 'find': require('./collection/find'), + 'findLast': require('./collection/findLast'), + 'findWhere': require('./collection/findWhere'), + 'foldl': require('./collection/foldl'), + 'foldr': require('./collection/foldr'), + 'forEach': require('./collection/forEach'), + 'forEachRight': require('./collection/forEachRight'), + 'groupBy': require('./collection/groupBy'), + 'include': require('./collection/include'), + 'includes': require('./collection/includes'), + 'indexBy': require('./collection/indexBy'), + 'inject': require('./collection/inject'), + 'invoke': require('./collection/invoke'), + 'map': require('./collection/map'), + 'max': require('./math/max'), + 'min': require('./math/min'), + 'partition': require('./collection/partition'), + 'pluck': require('./collection/pluck'), + 'reduce': require('./collection/reduce'), + 'reduceRight': require('./collection/reduceRight'), + 'reject': require('./collection/reject'), + 'sample': require('./collection/sample'), + 'select': require('./collection/select'), + 'shuffle': require('./collection/shuffle'), + 'size': require('./collection/size'), + 'some': require('./collection/some'), + 'sortBy': require('./collection/sortBy'), + 'sortByAll': require('./collection/sortByAll'), + 'sortByOrder': require('./collection/sortByOrder'), + 'sum': require('./math/sum'), + 'where': require('./collection/where') +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/all.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/all.js new file mode 100644 index 0000000..d0839f7 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/all.js @@ -0,0 +1 @@ +module.exports = require('./every'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/any.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/any.js new file mode 100644 index 0000000..900ac25 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/any.js @@ -0,0 +1 @@ +module.exports = require('./some'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/at.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/at.js new file mode 100644 index 0000000..29236e5 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/at.js @@ -0,0 +1,29 @@ +var baseAt = require('../internal/baseAt'), + baseFlatten = require('../internal/baseFlatten'), + restParam = require('../function/restParam'); + +/** + * Creates an array of elements corresponding to the given keys, or indexes, + * of `collection`. Keys may be specified as individual arguments or as arrays + * of keys. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [props] The property names + * or indexes of elements to pick, specified individually or in arrays. + * @returns {Array} Returns the new array of picked elements. + * @example + * + * _.at(['a', 'b', 'c'], [0, 2]); + * // => ['a', 'c'] + * + * _.at(['barney', 'fred', 'pebbles'], 0, 2); + * // => ['barney', 'pebbles'] + */ +var at = restParam(function(collection, props) { + return baseAt(collection, baseFlatten(props)); +}); + +module.exports = at; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/collect.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/collect.js new file mode 100644 index 0000000..0d1e1ab --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/collect.js @@ -0,0 +1 @@ +module.exports = require('./map'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/contains.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/contains.js new file mode 100644 index 0000000..594722a --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/contains.js @@ -0,0 +1 @@ +module.exports = require('./includes'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/countBy.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/countBy.js new file mode 100644 index 0000000..e97dbb7 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/countBy.js @@ -0,0 +1,54 @@ +var createAggregator = require('../internal/createAggregator'); + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the number of times the key was returned by `iteratee`. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return Math.floor(n); + * }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ +var countBy = createAggregator(function(result, value, key) { + hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); +}); + +module.exports = countBy; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/detect.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/detect.js new file mode 100644 index 0000000..2fb6303 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/detect.js @@ -0,0 +1 @@ +module.exports = require('./find'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/each.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/each.js new file mode 100644 index 0000000..8800f42 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/each.js @@ -0,0 +1 @@ +module.exports = require('./forEach'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/eachRight.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/eachRight.js new file mode 100644 index 0000000..3252b2a --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/eachRight.js @@ -0,0 +1 @@ +module.exports = require('./forEachRight'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/every.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/every.js new file mode 100644 index 0000000..5a2d0f5 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/every.js @@ -0,0 +1,66 @@ +var arrayEvery = require('../internal/arrayEvery'), + baseCallback = require('../internal/baseCallback'), + baseEvery = require('../internal/baseEvery'), + isArray = require('../lang/isArray'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * The predicate is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.every(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.every(users, 'active'); + * // => false + */ +function every(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = baseCallback(predicate, thisArg, 3); + } + return func(collection, predicate); +} + +module.exports = every; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/filter.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/filter.js new file mode 100644 index 0000000..7620aa7 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/filter.js @@ -0,0 +1,61 @@ +var arrayFilter = require('../internal/arrayFilter'), + baseCallback = require('../internal/baseCallback'), + baseFilter = require('../internal/baseFilter'), + isArray = require('../lang/isArray'); + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.filter([4, 5, 6], function(n) { + * return n % 2 == 0; + * }); + * // => [4, 6] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.filter(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.filter(users, 'active'), 'user'); + * // => ['barney'] + */ +function filter(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = baseCallback(predicate, thisArg, 3); + return func(collection, predicate); +} + +module.exports = filter; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/find.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/find.js new file mode 100644 index 0000000..7358cfe --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/find.js @@ -0,0 +1,56 @@ +var baseEach = require('../internal/baseEach'), + createFind = require('../internal/createFind'); + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias detect + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.result(_.find(users, function(chr) { + * return chr.age < 40; + * }), 'user'); + * // => 'barney' + * + * // using the `_.matches` callback shorthand + * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); + * // => 'pebbles' + * + * // using the `_.matchesProperty` callback shorthand + * _.result(_.find(users, 'active', false), 'user'); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.result(_.find(users, 'active'), 'user'); + * // => 'barney' + */ +var find = createFind(baseEach); + +module.exports = find; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/findLast.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/findLast.js new file mode 100644 index 0000000..75dbadc --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/findLast.js @@ -0,0 +1,25 @@ +var baseEachRight = require('../internal/baseEachRight'), + createFind = require('../internal/createFind'); + +/** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 + */ +var findLast = createFind(baseEachRight, true); + +module.exports = findLast; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/findWhere.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/findWhere.js new file mode 100644 index 0000000..2d62065 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/findWhere.js @@ -0,0 +1,37 @@ +var baseMatches = require('../internal/baseMatches'), + find = require('./find'); + +/** + * Performs a deep comparison between each element in `collection` and the + * source object, returning the first element that has equivalent property + * values. + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); + * // => 'barney' + * + * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); + * // => 'fred' + */ +function findWhere(collection, source) { + return find(collection, baseMatches(source)); +} + +module.exports = findWhere; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/foldl.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/foldl.js new file mode 100644 index 0000000..26f53cf --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/foldl.js @@ -0,0 +1 @@ +module.exports = require('./reduce'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/foldr.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/foldr.js new file mode 100644 index 0000000..8fb199e --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/foldr.js @@ -0,0 +1 @@ +module.exports = require('./reduceRight'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/forEach.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/forEach.js new file mode 100644 index 0000000..05a8e21 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/forEach.js @@ -0,0 +1,37 @@ +var arrayEach = require('../internal/arrayEach'), + baseEach = require('../internal/baseEach'), + createForEach = require('../internal/createForEach'); + +/** + * Iterates over elements of `collection` invoking `iteratee` for each element. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). Iteratee functions may exit iteration early + * by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2]).forEach(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from left to right and returns the array + * + * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { + * console.log(n, key); + * }); + * // => logs each value-key pair and returns the object (iteration order is not guaranteed) + */ +var forEach = createForEach(arrayEach, baseEach); + +module.exports = forEach; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/forEachRight.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/forEachRight.js new file mode 100644 index 0000000..3499711 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/forEachRight.js @@ -0,0 +1,26 @@ +var arrayEachRight = require('../internal/arrayEachRight'), + baseEachRight = require('../internal/baseEachRight'), + createForEach = require('../internal/createForEach'); + +/** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2]).forEachRight(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from right to left and returns the array + */ +var forEachRight = createForEach(arrayEachRight, baseEachRight); + +module.exports = forEachRight; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/groupBy.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/groupBy.js new file mode 100644 index 0000000..a925c89 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/groupBy.js @@ -0,0 +1,59 @@ +var createAggregator = require('../internal/createAggregator'); + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return Math.floor(n); + * }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using the `_.property` callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ +var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + result[key] = [value]; + } +}); + +module.exports = groupBy; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/include.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/include.js new file mode 100644 index 0000000..594722a --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/include.js @@ -0,0 +1 @@ +module.exports = require('./includes'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/includes.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/includes.js new file mode 100644 index 0000000..329486a --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/includes.js @@ -0,0 +1,57 @@ +var baseIndexOf = require('../internal/baseIndexOf'), + getLength = require('../internal/getLength'), + isArray = require('../lang/isArray'), + isIterateeCall = require('../internal/isIterateeCall'), + isLength = require('../internal/isLength'), + isString = require('../lang/isString'), + values = require('../object/values'); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Checks if `target` is in `collection` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the offset + * from the end of `collection`. + * + * @static + * @memberOf _ + * @alias contains, include + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {*} target The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {boolean} Returns `true` if a matching element is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.includes('pebbles', 'eb'); + * // => true + */ +function includes(collection, target, fromIndex, guard) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + collection = values(collection); + length = collection.length; + } + if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { + fromIndex = 0; + } else { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); + } + return (typeof collection == 'string' || !isArray(collection) && isString(collection)) + ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) + : (!!length && baseIndexOf(collection, target, fromIndex) > -1); +} + +module.exports = includes; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/indexBy.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/indexBy.js new file mode 100644 index 0000000..34a941e --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/indexBy.js @@ -0,0 +1,53 @@ +var createAggregator = require('../internal/createAggregator'); + +/** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the last element responsible for generating the key. The + * iteratee function is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keyData = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keyData, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return String.fromCharCode(object.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return this.fromCharCode(object.code); + * }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ +var indexBy = createAggregator(function(result, value, key) { + result[key] = value; +}); + +module.exports = indexBy; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/inject.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/inject.js new file mode 100644 index 0000000..26f53cf --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/inject.js @@ -0,0 +1 @@ +module.exports = require('./reduce'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/invoke.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/invoke.js new file mode 100644 index 0000000..6e71721 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/invoke.js @@ -0,0 +1,42 @@ +var baseEach = require('../internal/baseEach'), + invokePath = require('../internal/invokePath'), + isArrayLike = require('../internal/isArrayLike'), + isKey = require('../internal/isKey'), + restParam = require('../function/restParam'); + +/** + * Invokes the method at `path` of each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `methodName` is a function it's + * invoked for, and `this` bound to, each element in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|string} path The path of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ +var invoke = restParam(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + isProp = isKey(path), + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value) { + var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); + result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); + }); + return result; +}); + +module.exports = invoke; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/map.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/map.js new file mode 100644 index 0000000..5381110 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/map.js @@ -0,0 +1,68 @@ +var arrayMap = require('../internal/arrayMap'), + baseCallback = require('../internal/baseCallback'), + baseMap = require('../internal/baseMap'), + isArray = require('../lang/isArray'); + +/** + * Creates an array of values by running each element in `collection` through + * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, + * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, + * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, + * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, + * `sum`, `uniq`, and `words` + * + * @static + * @memberOf _ + * @alias collect + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new mapped array. + * @example + * + * function timesThree(n) { + * return n * 3; + * } + * + * _.map([1, 2], timesThree); + * // => [3, 6] + * + * _.map({ 'a': 1, 'b': 2 }, timesThree); + * // => [3, 6] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // using the `_.property` callback shorthand + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee, thisArg) { + var func = isArray(collection) ? arrayMap : baseMap; + iteratee = baseCallback(iteratee, thisArg, 3); + return func(collection, iteratee); +} + +module.exports = map; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/max.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/max.js new file mode 100644 index 0000000..bb1d213 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/max.js @@ -0,0 +1 @@ +module.exports = require('../math/max'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/min.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/min.js new file mode 100644 index 0000000..eef13d0 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/min.js @@ -0,0 +1 @@ +module.exports = require('../math/min'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/partition.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/partition.js new file mode 100644 index 0000000..ee35f27 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/partition.js @@ -0,0 +1,66 @@ +var createAggregator = require('../internal/createAggregator'); + +/** + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, while the second of which + * contains elements `predicate` returns falsey for. The predicate is bound + * to `thisArg` and invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the array of grouped elements. + * @example + * + * _.partition([1, 2, 3], function(n) { + * return n % 2; + * }); + * // => [[1, 3], [2]] + * + * _.partition([1.2, 2.3, 3.4], function(n) { + * return this.floor(n) % 2; + * }, Math); + * // => [[1.2, 3.4], [2.3]] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * var mapper = function(array) { + * return _.pluck(array, 'user'); + * }; + * + * // using the `_.matches` callback shorthand + * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper); + * // => [['pebbles'], ['barney', 'fred']] + * + * // using the `_.matchesProperty` callback shorthand + * _.map(_.partition(users, 'active', false), mapper); + * // => [['barney', 'pebbles'], ['fred']] + * + * // using the `_.property` callback shorthand + * _.map(_.partition(users, 'active'), mapper); + * // => [['fred'], ['barney', 'pebbles']] + */ +var partition = createAggregator(function(result, value, key) { + result[key ? 0 : 1].push(value); +}, function() { return [[], []]; }); + +module.exports = partition; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/pluck.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/pluck.js new file mode 100644 index 0000000..5ee1ec8 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/pluck.js @@ -0,0 +1,31 @@ +var map = require('./map'), + property = require('../utility/property'); + +/** + * Gets the property value of `path` from all elements in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|string} path The path of the property to pluck. + * @returns {Array} Returns the property values. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * _.pluck(users, 'user'); + * // => ['barney', 'fred'] + * + * var userIndex = _.indexBy(users, 'user'); + * _.pluck(userIndex, 'age'); + * // => [36, 40] (iteration order is not guaranteed) + */ +function pluck(collection, path) { + return map(collection, property(path)); +} + +module.exports = pluck; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/reduce.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/reduce.js new file mode 100644 index 0000000..5d5e8c9 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/reduce.js @@ -0,0 +1,44 @@ +var arrayReduce = require('../internal/arrayReduce'), + baseEach = require('../internal/baseEach'), + createReduce = require('../internal/createReduce'); + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` through `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not provided the first element of `collection` is used as the initial + * value. The `iteratee` is bound to `thisArg` and invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`, + * and `sortByOrder` + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * _.reduce([1, 2], function(total, n) { + * return total + n; + * }); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { + * result[key] = n * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) + */ +var reduce = createReduce(arrayReduce, baseEach); + +module.exports = reduce; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/reduceRight.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/reduceRight.js new file mode 100644 index 0000000..5a5753b --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/reduceRight.js @@ -0,0 +1,29 @@ +var arrayReduceRight = require('../internal/arrayReduceRight'), + baseEachRight = require('../internal/baseEachRight'), + createReduce = require('../internal/createReduce'); + +/** + * This method is like `_.reduce` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * var array = [[0, 1], [2, 3], [4, 5]]; + * + * _.reduceRight(array, function(flattened, other) { + * return flattened.concat(other); + * }, []); + * // => [4, 5, 2, 3, 0, 1] + */ +var reduceRight = createReduce(arrayReduceRight, baseEachRight); + +module.exports = reduceRight; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/reject.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/reject.js new file mode 100644 index 0000000..5592453 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/reject.js @@ -0,0 +1,50 @@ +var arrayFilter = require('../internal/arrayFilter'), + baseCallback = require('../internal/baseCallback'), + baseFilter = require('../internal/baseFilter'), + isArray = require('../lang/isArray'); + +/** + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.reject([1, 2, 3, 4], function(n) { + * return n % 2 == 0; + * }); + * // => [1, 3] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.reject(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.reject(users, 'active'), 'user'); + * // => ['barney'] + */ +function reject(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = baseCallback(predicate, thisArg, 3); + return func(collection, function(value, index, collection) { + return !predicate(value, index, collection); + }); +} + +module.exports = reject; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/sample.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/sample.js new file mode 100644 index 0000000..8e01533 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/sample.js @@ -0,0 +1,50 @@ +var baseRandom = require('../internal/baseRandom'), + isIterateeCall = require('../internal/isIterateeCall'), + toArray = require('../lang/toArray'), + toIterable = require('../internal/toIterable'); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; + +/** + * Gets a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {*} Returns the random sample(s). + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ +function sample(collection, n, guard) { + if (guard ? isIterateeCall(collection, n, guard) : n == null) { + collection = toIterable(collection); + var length = collection.length; + return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; + } + var index = -1, + result = toArray(collection), + length = result.length, + lastIndex = length - 1; + + n = nativeMin(n < 0 ? 0 : (+n || 0), length); + while (++index < n) { + var rand = baseRandom(index, lastIndex), + value = result[rand]; + + result[rand] = result[index]; + result[index] = value; + } + result.length = n; + return result; +} + +module.exports = sample; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/select.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/select.js new file mode 100644 index 0000000..ade80f6 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/select.js @@ -0,0 +1 @@ +module.exports = require('./filter'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/shuffle.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/shuffle.js new file mode 100644 index 0000000..949689c --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/shuffle.js @@ -0,0 +1,24 @@ +var sample = require('./sample'); + +/** Used as references for `-Infinity` and `Infinity`. */ +var POSITIVE_INFINITY = Number.POSITIVE_INFINITY; + +/** + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + * @example + * + * _.shuffle([1, 2, 3, 4]); + * // => [4, 1, 3, 2] + */ +function shuffle(collection) { + return sample(collection, POSITIVE_INFINITY); +} + +module.exports = shuffle; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/size.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/size.js new file mode 100644 index 0000000..78dcf4c --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/size.js @@ -0,0 +1,30 @@ +var getLength = require('../internal/getLength'), + isLength = require('../internal/isLength'), + keys = require('../object/keys'); + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the size of `collection`. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + var length = collection ? getLength(collection) : 0; + return isLength(length) ? length : keys(collection).length; +} + +module.exports = size; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/some.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/some.js new file mode 100644 index 0000000..d0b09a4 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/some.js @@ -0,0 +1,67 @@ +var arraySome = require('../internal/arraySome'), + baseCallback = require('../internal/baseCallback'), + baseSome = require('../internal/baseSome'), + isArray = require('../lang/isArray'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * The function returns as soon as it finds a passing value and does not iterate + * over the entire collection. The predicate is bound to `thisArg` and invoked + * with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.some(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.some(users, 'active'); + * // => true + */ +function some(collection, predicate, thisArg) { + var func = isArray(collection) ? arraySome : baseSome; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = baseCallback(predicate, thisArg, 3); + } + return func(collection, predicate); +} + +module.exports = some; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/sortBy.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/sortBy.js new file mode 100644 index 0000000..4401c77 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/sortBy.js @@ -0,0 +1,71 @@ +var baseCallback = require('../internal/baseCallback'), + baseMap = require('../internal/baseMap'), + baseSortBy = require('../internal/baseSortBy'), + compareAscending = require('../internal/compareAscending'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through `iteratee`. This method performs + * a stable sort, that is, it preserves the original sort order of equal elements. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new sorted array. + * @example + * + * _.sortBy([1, 2, 3], function(n) { + * return Math.sin(n); + * }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(n) { + * return this.sin(n); + * }, Math); + * // => [3, 1, 2] + * + * var users = [ + * { 'user': 'fred' }, + * { 'user': 'pebbles' }, + * { 'user': 'barney' } + * ]; + * + * // using the `_.property` callback shorthand + * _.pluck(_.sortBy(users, 'user'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ +function sortBy(collection, iteratee, thisArg) { + if (collection == null) { + return []; + } + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = undefined; + } + var index = -1; + iteratee = baseCallback(iteratee, thisArg, 3); + + var result = baseMap(collection, function(value, key, collection) { + return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value }; + }); + return baseSortBy(result, compareAscending); +} + +module.exports = sortBy; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/sortByAll.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/sortByAll.js new file mode 100644 index 0000000..4766c20 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/sortByAll.js @@ -0,0 +1,52 @@ +var baseFlatten = require('../internal/baseFlatten'), + baseSortByOrder = require('../internal/baseSortByOrder'), + isIterateeCall = require('../internal/isIterateeCall'), + restParam = require('../function/restParam'); + +/** + * This method is like `_.sortBy` except that it can sort by multiple iteratees + * or property names. + * + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees + * The iteratees to sort by, specified as individual values or arrays of values. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.map(_.sortByAll(users, ['user', 'age']), _.values); + * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * + * _.map(_.sortByAll(users, 'user', function(chr) { + * return Math.floor(chr.age / 10); + * }), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ +var sortByAll = restParam(function(collection, iteratees) { + if (collection == null) { + return []; + } + var guard = iteratees[2]; + if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) { + iteratees.length = 1; + } + return baseSortByOrder(collection, baseFlatten(iteratees), []); +}); + +module.exports = sortByAll; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/sortByOrder.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/sortByOrder.js new file mode 100644 index 0000000..8b4fc19 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/sortByOrder.js @@ -0,0 +1,55 @@ +var baseSortByOrder = require('../internal/baseSortByOrder'), + isArray = require('../lang/isArray'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * This method is like `_.sortByAll` except that it allows specifying the + * sort orders of the iteratees to sort by. If `orders` is unspecified, all + * values are sorted in ascending order. Otherwise, a value is sorted in + * ascending order if its corresponding order is "asc", and descending if "desc". + * + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {boolean[]} [orders] The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 36 } + * ]; + * + * // sort by `user` in ascending order and by `age` in descending order + * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ +function sortByOrder(collection, iteratees, orders, guard) { + if (collection == null) { + return []; + } + if (guard && isIterateeCall(iteratees, orders, guard)) { + orders = undefined; + } + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; + } + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; + } + return baseSortByOrder(collection, iteratees, orders); +} + +module.exports = sortByOrder; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/sum.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/sum.js new file mode 100644 index 0000000..a2e9380 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/sum.js @@ -0,0 +1 @@ +module.exports = require('../math/sum'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/where.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/where.js new file mode 100644 index 0000000..f603bf8 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/collection/where.js @@ -0,0 +1,37 @@ +var baseMatches = require('../internal/baseMatches'), + filter = require('./filter'); + +/** + * Performs a deep comparison between each element in `collection` and the + * source object, returning an array of all elements that have equivalent + * property values. + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] }, + * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); + * // => ['barney'] + * + * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); + * // => ['fred'] + */ +function where(collection, source) { + return filter(collection, baseMatches(source)); +} + +module.exports = where; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/date.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/date.js new file mode 100644 index 0000000..195366e --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/date.js @@ -0,0 +1,3 @@ +module.exports = { + 'now': require('./date/now') +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/date/now.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/date/now.js new file mode 100644 index 0000000..ffe3060 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/date/now.js @@ -0,0 +1,24 @@ +var getNative = require('../internal/getNative'); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeNow = getNative(Date, 'now'); + +/** + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @category Date + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => logs the number of milliseconds it took for the deferred function to be invoked + */ +var now = nativeNow || function() { + return new Date().getTime(); +}; + +module.exports = now; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function.js new file mode 100644 index 0000000..71f8ebe --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function.js @@ -0,0 +1,28 @@ +module.exports = { + 'after': require('./function/after'), + 'ary': require('./function/ary'), + 'backflow': require('./function/backflow'), + 'before': require('./function/before'), + 'bind': require('./function/bind'), + 'bindAll': require('./function/bindAll'), + 'bindKey': require('./function/bindKey'), + 'compose': require('./function/compose'), + 'curry': require('./function/curry'), + 'curryRight': require('./function/curryRight'), + 'debounce': require('./function/debounce'), + 'defer': require('./function/defer'), + 'delay': require('./function/delay'), + 'flow': require('./function/flow'), + 'flowRight': require('./function/flowRight'), + 'memoize': require('./function/memoize'), + 'modArgs': require('./function/modArgs'), + 'negate': require('./function/negate'), + 'once': require('./function/once'), + 'partial': require('./function/partial'), + 'partialRight': require('./function/partialRight'), + 'rearg': require('./function/rearg'), + 'restParam': require('./function/restParam'), + 'spread': require('./function/spread'), + 'throttle': require('./function/throttle'), + 'wrap': require('./function/wrap') +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/after.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/after.js new file mode 100644 index 0000000..96a51fd --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/after.js @@ -0,0 +1,48 @@ +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeIsFinite = global.isFinite; + +/** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it's called `n` or more times. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'done saving!' after the two async saves have completed + */ +function after(n, func) { + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } + } + n = nativeIsFinite(n = +n) ? n : 0; + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; +} + +module.exports = after; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/ary.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/ary.js new file mode 100644 index 0000000..53a6913 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/ary.js @@ -0,0 +1,34 @@ +var createWrapper = require('../internal/createWrapper'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** Used to compose bitmasks for wrapper metadata. */ +var ARY_FLAG = 128; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Creates a function that accepts up to `n` arguments ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] + */ +function ary(func, n, guard) { + if (guard && isIterateeCall(func, n, guard)) { + n = undefined; + } + n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); + return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); +} + +module.exports = ary; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/backflow.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/backflow.js new file mode 100644 index 0000000..1954e94 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/backflow.js @@ -0,0 +1 @@ +module.exports = require('./flowRight'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/before.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/before.js new file mode 100644 index 0000000..3d94216 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/before.js @@ -0,0 +1,42 @@ +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it's called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery('#add').on('click', _.before(5, addContactToList)); + * // => allows adding up to 4 contacts to the list + */ +function before(n, func) { + var result; + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } + } + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; +} + +module.exports = before; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/bind.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/bind.js new file mode 100644 index 0000000..0de126a --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/bind.js @@ -0,0 +1,56 @@ +var createWrapper = require('../internal/createWrapper'), + replaceHolders = require('../internal/replaceHolders'), + restParam = require('./restParam'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1, + PARTIAL_FLAG = 32; + +/** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and prepends any additional `_.bind` arguments to those provided to the + * bound function. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind` this method does not set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var greet = function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * }; + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // using placeholders + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ +var bind = restParam(function(func, thisArg, partials) { + var bitmask = BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bind.placeholder); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(func, bitmask, thisArg, partials, holders); +}); + +// Assign default placeholders. +bind.placeholder = {}; + +module.exports = bind; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/bindAll.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/bindAll.js new file mode 100644 index 0000000..a09e948 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/bindAll.js @@ -0,0 +1,50 @@ +var baseFlatten = require('../internal/baseFlatten'), + createWrapper = require('../internal/createWrapper'), + functions = require('../object/functions'), + restParam = require('./restParam'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1; + +/** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all enumerable function + * properties, own and inherited, of `object` are bound. + * + * **Note:** This method does not set the "length" property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...(string|string[])} [methodNames] The object method names to bind, + * specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { + * console.log('clicked ' + this.label); + * } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs' when the element is clicked + */ +var bindAll = restParam(function(object, methodNames) { + methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object); + + var index = -1, + length = methodNames.length; + + while (++index < length) { + var key = methodNames[index]; + object[key] = createWrapper(object[key], BIND_FLAG, object); + } + return object; +}); + +module.exports = bindAll; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/bindKey.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/bindKey.js new file mode 100644 index 0000000..b787fe7 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/bindKey.js @@ -0,0 +1,66 @@ +var createWrapper = require('../internal/createWrapper'), + replaceHolders = require('../internal/replaceHolders'), + restParam = require('./restParam'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + PARTIAL_FLAG = 32; + +/** + * Creates a function that invokes the method at `object[key]` and prepends + * any additional `_.bindKey` arguments to those provided to the bound function. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. + * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // using placeholders + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ +var bindKey = restParam(function(object, key, partials) { + var bitmask = BIND_FLAG | BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bindKey.placeholder); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(key, bitmask, object, partials, holders); +}); + +// Assign default placeholders. +bindKey.placeholder = {}; + +module.exports = bindKey; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/compose.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/compose.js new file mode 100644 index 0000000..1954e94 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/compose.js @@ -0,0 +1 @@ +module.exports = require('./flowRight'); diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/curry.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/curry.js new file mode 100644 index 0000000..b7db3fd --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/curry.js @@ -0,0 +1,51 @@ +var createCurry = require('../internal/createCurry'); + +/** Used to compose bitmasks for wrapper metadata. */ +var CURRY_FLAG = 8; + +/** + * Creates a function that accepts one or more arguments of `func` that when + * called either invokes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` may be specified + * if `func.length` is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(1)(_, 3)(2); + * // => [1, 2, 3] + */ +var curry = createCurry(CURRY_FLAG); + +// Assign default placeholders. +curry.placeholder = {}; + +module.exports = curry; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/curryRight.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/curryRight.js new file mode 100644 index 0000000..11c5403 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/curryRight.js @@ -0,0 +1,48 @@ +var createCurry = require('../internal/createCurry'); + +/** Used to compose bitmasks for wrapper metadata. */ +var CURRY_RIGHT_FLAG = 16; + +/** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(3)(1, _)(2); + * // => [1, 2, 3] + */ +var curryRight = createCurry(CURRY_RIGHT_FLAG); + +// Assign default placeholders. +curryRight.placeholder = {}; + +module.exports = curryRight; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/debounce.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/debounce.js new file mode 100644 index 0000000..163af90 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/debounce.js @@ -0,0 +1,181 @@ +var isObject = require('../lang/isObject'), + now = require('../date/now'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed invocations. Provide an options object to indicate that `func` + * should be invoked on the leading and/or trailing edge of the `wait` timeout. + * Subsequent calls to the debounced function return the result of the last + * `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify invoking on the leading + * edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be + * delayed before it's invoked. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // invoke `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // ensure `batchLog` is invoked once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * jQuery(source).on('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * })); + * + * // cancel a debounced call + * var todoChanges = _.debounce(batchLog, 1000); + * Object.observe(models.todo, todoChanges); + * + * Object.observe(models, function(changes) { + * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { + * todoChanges.cancel(); + * } + * }, ['delete']); + * + * // ...at some point `models.todo` is changed + * models.todo.completed = true; + * + * // ...before 1 second has passed `models.todo` is deleted + * // which cancels the debounced `todoChanges` call + * delete models.todo; + */ +function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = wait < 0 ? 0 : (+wait || 0); + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = !!options.leading; + maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function cancel() { + if (timeoutId) { + clearTimeout(timeoutId); + } + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + lastCalled = 0; + maxTimeoutId = timeoutId = trailingCall = undefined; + } + + function complete(isCalled, id) { + if (id) { + clearTimeout(id); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + } + } + + function delayed() { + var remaining = wait - (now() - stamp); + if (remaining <= 0 || remaining > wait) { + complete(trailingCall, maxTimeoutId); + } else { + timeoutId = setTimeout(delayed, remaining); + } + } + + function maxDelayed() { + complete(trailing, timeoutId); + } + + function debounced() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0 || remaining > maxWait; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + return result; + } + debounced.cancel = cancel; + return debounced; +} + +module.exports = debounce; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/defer.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/defer.js new file mode 100644 index 0000000..3accbf9 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/defer.js @@ -0,0 +1,25 @@ +var baseDelay = require('../internal/baseDelay'), + restParam = require('./restParam'); + +/** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // logs 'deferred' after one or more milliseconds + */ +var defer = restParam(function(func, args) { + return baseDelay(func, 1, args); +}); + +module.exports = defer; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/delay.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/delay.js new file mode 100644 index 0000000..d5eef27 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/delay.js @@ -0,0 +1,26 @@ +var baseDelay = require('../internal/baseDelay'), + restParam = require('./restParam'); + +/** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => logs 'later' after one second + */ +var delay = restParam(function(func, wait, args) { + return baseDelay(func, wait, args); +}); + +module.exports = delay; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/flow.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/flow.js new file mode 100644 index 0000000..a435a3d --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/flow.js @@ -0,0 +1,25 @@ +var createFlow = require('../internal/createFlow'); + +/** + * Creates a function that returns the result of invoking the provided + * functions with the `this` binding of the created function, where each + * successive invocation is supplied the return value of the previous. + * + * @static + * @memberOf _ + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flow(_.add, square); + * addSquare(1, 2); + * // => 9 + */ +var flow = createFlow(); + +module.exports = flow; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/flowRight.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/flowRight.js new file mode 100644 index 0000000..23b9d76 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/flowRight.js @@ -0,0 +1,25 @@ +var createFlow = require('../internal/createFlow'); + +/** + * This method is like `_.flow` except that it creates a function that + * invokes the provided functions from right to left. + * + * @static + * @memberOf _ + * @alias backflow, compose + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flowRight(square, _.add); + * addSquare(1, 2); + * // => 9 + */ +var flowRight = createFlow(true); + +module.exports = flowRight; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/memoize.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/memoize.js new file mode 100644 index 0000000..f3b8d69 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/memoize.js @@ -0,0 +1,80 @@ +var MapCache = require('../internal/MapCache'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is coerced to a string and used as the + * cache key. The `func` is invoked with the `this` binding of the memoized + * function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) + * method interface of `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var upperCase = _.memoize(function(string) { + * return string.toUpperCase(); + * }); + * + * upperCase('fred'); + * // => 'FRED' + * + * // modifying the result cache + * upperCase.cache.set('fred', 'BARNEY'); + * upperCase('fred'); + * // => 'BARNEY' + * + * // replacing `_.memoize.Cache` + * var object = { 'user': 'fred' }; + * var other = { 'user': 'barney' }; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'fred' } + * + * _.memoize.Cache = WeakMap; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'barney' } + */ +function memoize(func, resolver) { + if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result); + return result; + }; + memoized.cache = new memoize.Cache; + return memoized; +} + +// Assign cache to `_.memoize`. +memoize.Cache = MapCache; + +module.exports = memoize; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/modArgs.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/modArgs.js new file mode 100644 index 0000000..49b9b5e --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/modArgs.js @@ -0,0 +1,58 @@ +var arrayEvery = require('../internal/arrayEvery'), + baseFlatten = require('../internal/baseFlatten'), + baseIsFunction = require('../internal/baseIsFunction'), + restParam = require('./restParam'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; + +/** + * Creates a function that runs each argument through a corresponding + * transform function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to wrap. + * @param {...(Function|Function[])} [transforms] The functions to transform + * arguments, specified as individual functions or arrays of functions. + * @returns {Function} Returns the new function. + * @example + * + * function doubled(n) { + * return n * 2; + * } + * + * function square(n) { + * return n * n; + * } + * + * var modded = _.modArgs(function(x, y) { + * return [x, y]; + * }, square, doubled); + * + * modded(1, 2); + * // => [1, 4] + * + * modded(5, 10); + * // => [25, 20] + */ +var modArgs = restParam(function(func, transforms) { + transforms = baseFlatten(transforms); + if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = transforms.length; + return restParam(function(args) { + var index = nativeMin(args.length, length); + while (index--) { + args[index] = transforms[index](args[index]); + } + return func.apply(this, args); + }); +}); + +module.exports = modArgs; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/negate.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/negate.js new file mode 100644 index 0000000..8247939 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/negate.js @@ -0,0 +1,32 @@ +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ +function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + return !predicate.apply(this, arguments); + }; +} + +module.exports = negate; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/once.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/once.js new file mode 100644 index 0000000..0b5bd85 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/once.js @@ -0,0 +1,24 @@ +var before = require('./before'); + +/** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first call. The `func` is invoked + * with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` invokes `createApplication` once + */ +function once(func) { + return before(2, func); +} + +module.exports = once; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/partial.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/partial.js new file mode 100644 index 0000000..fb1d04f --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/partial.js @@ -0,0 +1,43 @@ +var createPartial = require('../internal/createPartial'); + +/** Used to compose bitmasks for wrapper metadata. */ +var PARTIAL_FLAG = 32; + +/** + * Creates a function that invokes `func` with `partial` arguments prepended + * to those provided to the new function. This method is like `_.bind` except + * it does **not** alter the `this` binding. + * + * The `_.partial.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method does not set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var sayHelloTo = _.partial(greet, 'hello'); + * sayHelloTo('fred'); + * // => 'hello fred' + * + * // using placeholders + * var greetFred = _.partial(greet, _, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + */ +var partial = createPartial(PARTIAL_FLAG); + +// Assign default placeholders. +partial.placeholder = {}; + +module.exports = partial; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/partialRight.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/partialRight.js new file mode 100644 index 0000000..634e6a4 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/partialRight.js @@ -0,0 +1,42 @@ +var createPartial = require('../internal/createPartial'); + +/** Used to compose bitmasks for wrapper metadata. */ +var PARTIAL_RIGHT_FLAG = 64; + +/** + * This method is like `_.partial` except that partially applied arguments + * are appended to those provided to the new function. + * + * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method does not set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var greetFred = _.partialRight(greet, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + * + * // using placeholders + * var sayHelloTo = _.partialRight(greet, 'hello', _); + * sayHelloTo('fred'); + * // => 'hello fred' + */ +var partialRight = createPartial(PARTIAL_RIGHT_FLAG); + +// Assign default placeholders. +partialRight.placeholder = {}; + +module.exports = partialRight; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/rearg.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/rearg.js new file mode 100644 index 0000000..f2bd9c4 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/rearg.js @@ -0,0 +1,40 @@ +var baseFlatten = require('../internal/baseFlatten'), + createWrapper = require('../internal/createWrapper'), + restParam = require('./restParam'); + +/** Used to compose bitmasks for wrapper metadata. */ +var REARG_FLAG = 256; + +/** + * Creates a function that invokes `func` with arguments arranged according + * to the specified indexes where the argument value at the first index is + * provided as the first argument, the argument value at the second index is + * provided as the second argument, and so on. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to rearrange arguments for. + * @param {...(number|number[])} indexes The arranged argument indexes, + * specified as individual indexes or arrays of indexes. + * @returns {Function} Returns the new function. + * @example + * + * var rearged = _.rearg(function(a, b, c) { + * return [a, b, c]; + * }, 2, 0, 1); + * + * rearged('b', 'c', 'a') + * // => ['a', 'b', 'c'] + * + * var map = _.rearg(_.map, [1, 0]); + * map(function(n) { + * return n * 3; + * }, [1, 2, 3]); + * // => [3, 6, 9] + */ +var rearg = restParam(function(func, indexes) { + return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes)); +}); + +module.exports = rearg; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/restParam.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/restParam.js new file mode 100644 index 0000000..8852286 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/restParam.js @@ -0,0 +1,58 @@ +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as an array. + * + * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.restParam(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ +function restParam(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + rest = Array(length); + + while (++index < length) { + rest[index] = args[start + index]; + } + switch (start) { + case 0: return func.call(this, rest); + case 1: return func.call(this, args[0], rest); + case 2: return func.call(this, args[0], args[1], rest); + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = rest; + return func.apply(this, otherArgs); + }; +} + +module.exports = restParam; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/spread.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/spread.js new file mode 100644 index 0000000..780f504 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/spread.js @@ -0,0 +1,44 @@ +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a function that invokes `func` with the `this` binding of the created + * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). + * + * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/Web/JavaScript/Reference/Operators/Spread_operator). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to spread arguments over. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.spread(function(who, what) { + * return who + ' says ' + what; + * }); + * + * say(['fred', 'hello']); + * // => 'fred says hello' + * + * // with a Promise + * var numbers = Promise.all([ + * Promise.resolve(40), + * Promise.resolve(36) + * ]); + * + * numbers.then(_.spread(function(x, y) { + * return x + y; + * })); + * // => a Promise of 76 + */ +function spread(func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function(array) { + return func.apply(this, array); + }; +} + +module.exports = spread; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/throttle.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/throttle.js new file mode 100644 index 0000000..1dd00ea --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/throttle.js @@ -0,0 +1,62 @@ +var debounce = require('./debounce'), + isObject = require('../lang/isObject'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed invocations. Provide an options object to indicate + * that `func` should be invoked on the leading and/or trailing edge of the + * `wait` timeout. Subsequent calls to the throttled function return the + * result of the last `func` call. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify invoking on the leading + * edge of the timeout. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // avoid excessively updating the position while scrolling + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + * + * // cancel a trailing throttled call + * jQuery(window).on('popstate', throttled.cancel); + */ +function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing }); +} + +module.exports = throttle; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/function/wrap.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/wrap.js new file mode 100644 index 0000000..6a33c5e --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/function/wrap.js @@ -0,0 +1,33 @@ +var createWrapper = require('../internal/createWrapper'), + identity = require('../utility/identity'); + +/** Used to compose bitmasks for wrapper metadata. */ +var PARTIAL_FLAG = 32; + +/** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Any additional arguments provided to the function are + * appended to those provided to the wrapper function. The wrapper is invoked + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

          ' + func(text) + '

          '; + * }); + * + * p('fred, barney, & pebbles'); + * // => '

          fred, barney, & pebbles

          ' + */ +function wrap(value, wrapper) { + wrapper = wrapper == null ? identity : wrapper; + return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []); +} + +module.exports = wrap; diff --git a/node_modules/grunt-sftp-deploy/node_modules/lodash/index.js b/node_modules/grunt-sftp-deploy/node_modules/lodash/index.js new file mode 100644 index 0000000..5f17319 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/lodash/index.js @@ -0,0 +1,12351 @@ +/** + * @license + * lodash 3.10.1 (Custom Build) + * Build: `lodash modern -d -o ./index.js` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; + + /** Used as the semantic version number. */ + var VERSION = '3.10.1'; + + /** Used to compose bitmasks for wrapper metadata. */ + var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_BOUND_FLAG = 4, + CURRY_FLAG = 8, + CURRY_RIGHT_FLAG = 16, + PARTIAL_FLAG = 32, + PARTIAL_RIGHT_FLAG = 64, + ARY_FLAG = 128, + REARG_FLAG = 256; + + /** Used as default options for `_.trunc`. */ + var DEFAULT_TRUNC_LENGTH = 30, + DEFAULT_TRUNC_OMISSION = '...'; + + /** Used to detect when a function becomes hot. */ + var HOT_COUNT = 150, + HOT_SPAN = 16; + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Used to indicate the type of lazy iteratees. */ + var LAZY_FILTER_FLAG = 1, + LAZY_MAP_FLAG = 2; + + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used as the internal argument placeholder. */ + var PLACEHOLDER = '__lodash_placeholder__'; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to match empty string literals in compiled template source. */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** Used to match HTML entities and HTML characters. */ + var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g, + reUnescapedHtml = /[&<>"'`]/g, + reHasEscapedHtml = RegExp(reEscapedHtml.source), + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** Used to match template delimiters. */ + var reEscape = /<%-([\s\S]+?)%>/g, + reEvaluate = /<%([\s\S]+?)%>/g, + reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; + + /** + * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns) + * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern). + */ + var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g, + reHasRegExpChars = RegExp(reRegExpChars.source); + + /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */ + var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect hexadecimal string values. */ + var reHasHexPrefix = /^0[xX]/; + + /** Used to detect host constructors (Safari > 5). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^\d+$/; + + /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ + var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; + + /** Used to ensure capturing order of template delimiters. */ + var reNoMatch = /($^)/; + + /** Used to match unescaped characters in compiled string literals. */ + var reUnescapedString = /['\n\r\u2028\u2029\\]/g; + + /** Used to match words to create compound words. */ + var reWords = (function() { + var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]', + lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+'; + + return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'); + }()); + + /** Used to assign default `context` object properties. */ + var contextProps = [ + 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array', + 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number', + 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite', + 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', + 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap' + ]; + + /** Used to make template sourceURLs easier to identify. */ + var templateCounter = -1; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = + typedArrayTags[dateTag] = typedArrayTags[errorTag] = + typedArrayTags[funcTag] = typedArrayTags[mapTag] = + typedArrayTags[numberTag] = typedArrayTags[objectTag] = + typedArrayTags[regexpTag] = typedArrayTags[setTag] = + typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = + cloneableTags[dateTag] = cloneableTags[float32Tag] = + cloneableTags[float64Tag] = cloneableTags[int8Tag] = + cloneableTags[int16Tag] = cloneableTags[int32Tag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[stringTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[mapTag] = cloneableTags[setTag] = + cloneableTags[weakMapTag] = false; + + /** Used to map latin-1 supplementary letters to basic latin letters. */ + var deburredLetters = { + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss' + }; + + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + + /** Used to map HTML entities to characters. */ + var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'", + '`': '`' + }; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; + + /** Used to escape characters for inclusion in compiled regexes. */ + var regexpEscapes = { + '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34', + '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39', + 'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46', + 'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66', + 'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78' + }; + + /** Used to escape characters for inclusion in compiled string literals. */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Detect free variable `exports`. */ + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global; + + /** Detect free variable `self`. */ + var freeSelf = objectTypes[typeof self] && self && self.Object && self; + + /** Detect free variable `window`. */ + var freeWindow = objectTypes[typeof window] && window && window.Object && window; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + + /** + * Used as a reference to the global object. + * + * The `this` value is used if it's the global object to avoid Greasemonkey's + * restricted `window` object, otherwise the `window` object is used. + */ + var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this; + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `compareAscending` which compares values and + * sorts them in ascending order without guaranteeing a stable sort. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ + function baseCompareAscending(value, other) { + if (value !== other) { + var valIsNull = value === null, + valIsUndef = value === undefined, + valIsReflexive = value === value; + + var othIsNull = other === null, + othIsUndef = other === undefined, + othIsReflexive = other === other; + + if ((value > other && !othIsNull) || !valIsReflexive || + (valIsNull && !othIsUndef && othIsReflexive) || + (valIsUndef && othIsReflexive)) { + return 1; + } + if ((value < other && !valIsNull) || !othIsReflexive || + (othIsNull && !valIsUndef && valIsReflexive) || + (othIsUndef && valIsReflexive)) { + return -1; + } + } + return 0; + } + + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to search. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.indexOf` without support for binary searches. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + if (value !== value) { + return indexOfNaN(array, fromIndex); + } + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.isFunction` without support for environments + * with incorrect `typeof` results. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + */ + function baseIsFunction(value) { + // Avoid a Chakra JIT bug in compatibility modes of IE 11. + // See https://github.com/jashkenas/underscore/issues/1621 for more details. + return typeof value == 'function' || false; + } + + /** + * Converts `value` to a string if it's not one. An empty string is returned + * for `null` or `undefined` values. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + return value == null ? '' : (value + ''); + } + + /** + * Used by `_.trim` and `_.trimLeft` to get the index of the first character + * of `string` that is not found in `chars`. + * + * @private + * @param {string} string The string to inspect. + * @param {string} chars The characters to find. + * @returns {number} Returns the index of the first character not found in `chars`. + */ + function charsLeftIndex(string, chars) { + var index = -1, + length = string.length; + + while (++index < length && chars.indexOf(string.charAt(index)) > -1) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimRight` to get the index of the last character + * of `string` that is not found in `chars`. + * + * @private + * @param {string} string The string to inspect. + * @param {string} chars The characters to find. + * @returns {number} Returns the index of the last character not found in `chars`. + */ + function charsRightIndex(string, chars) { + var index = string.length; + + while (index-- && chars.indexOf(string.charAt(index)) > -1) {} + return index; + } + + /** + * Used by `_.sortBy` to compare transformed elements of a collection and stable + * sort them in ascending order. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareAscending(object, other) { + return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index); + } + + /** + * Used by `_.sortByOrder` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise, + * a value is sorted in ascending order if its corresponding order is "asc", and + * descending if "desc". + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = baseCompareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * ((order === 'asc' || order === true) ? 1 : -1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://code.google.com/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; + } + + /** + * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ + function deburrLetter(letter) { + return deburredLetters[letter]; + } + + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(chr) { + return htmlEscapes[chr]; + } + + /** + * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes. + * + * @private + * @param {string} chr The matched character to escape. + * @param {string} leadingChar The capture group for a leading character. + * @param {string} whitespaceChar The capture group for a whitespace character. + * @returns {string} Returns the escaped character. + */ + function escapeRegExpChar(chr, leadingChar, whitespaceChar) { + if (leadingChar) { + chr = regexpEscapes[chr]; + } else if (whitespaceChar) { + chr = stringEscapes[chr]; + } + return '\\' + chr; + } + + /** + * Used by `_.template` to escape characters for inclusion in compiled string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; + } + + /** + * Gets the index at which the first occurrence of `NaN` is found in `array`. + * + * @private + * @param {Array} array The array to search. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched `NaN`, else `-1`. + */ + function indexOfNaN(array, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 0 : -1); + + while ((fromRight ? index-- : ++index < length)) { + var other = array[index]; + if (other !== other) { + return index; + } + } + return -1; + } + + /** + * Checks if `value` is object-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a + * character code is whitespace. + * + * @private + * @param {number} charCode The character code to inspect. + * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`. + */ + function isSpace(charCode) { + return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 || + (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279))); + } + + /** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ + function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + if (array[index] === placeholder) { + array[index] = PLACEHOLDER; + result[++resIndex] = index; + } + } + return result; + } + + /** + * An implementation of `_.uniq` optimized for sorted arrays without support + * for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function sortedUniq(array, iteratee) { + var seen, + index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; + + if (!index || seen !== computed) { + seen = computed; + result[++resIndex] = value; + } + } + return result; + } + + /** + * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the first non-whitespace character. + */ + function trimmedLeftIndex(string) { + var index = -1, + length = string.length; + + while (++index < length && isSpace(string.charCodeAt(index))) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ + function trimmedRightIndex(string) { + var index = string.length; + + while (index-- && isSpace(string.charCodeAt(index))) {} + return index; + } + + /** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(chr) { + return htmlUnescapes[chr]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new pristine `lodash` function using the given `context` object. + * + * @static + * @memberOf _ + * @category Utility + * @param {Object} [context=root] The context object. + * @returns {Function} Returns a new `lodash` function. + * @example + * + * _.mixin({ 'foo': _.constant('foo') }); + * + * var lodash = _.runInContext(); + * lodash.mixin({ 'bar': lodash.constant('bar') }); + * + * _.isFunction(_.foo); + * // => true + * _.isFunction(_.bar); + * // => false + * + * lodash.isFunction(lodash.foo); + * // => false + * lodash.isFunction(lodash.bar); + * // => true + * + * // using `context` to mock `Date#getTime` use in `_.now` + * var mock = _.runInContext({ + * 'Date': function() { + * return { 'getTime': getTimeMock }; + * } + * }); + * + * // or creating a suped-up `defer` in Node.js + * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; + */ + function runInContext(context) { + // Avoid issues with some ES3 environments that attempt to use values, named + // after built-in constructors like `Object`, for the creation of literals. + // ES5 clears this up by stating that literals must use built-in constructors. + // See https://es5.github.io/#x11.1.5 for more details. + context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; + + /** Native constructor references. */ + var Array = context.Array, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Number = context.Number, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** Used for native method references. */ + var arrayProto = Array.prototype, + objectProto = Object.prototype, + stringProto = String.prototype; + + /** Used to resolve the decompiled source of functions. */ + var fnToString = Function.prototype.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to generate unique IDs. */ + var idCounter = 0; + + /** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ + var objToString = objectProto.toString; + + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = root._; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Native method references. */ + var ArrayBuffer = context.ArrayBuffer, + clearTimeout = context.clearTimeout, + parseFloat = context.parseFloat, + pow = Math.pow, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + Set = getNative(context, 'Set'), + setTimeout = context.setTimeout, + splice = arrayProto.splice, + Uint8Array = context.Uint8Array, + WeakMap = getNative(context, 'WeakMap'); + + /* Native method references for those with the same name as other `lodash` methods. */ + var nativeCeil = Math.ceil, + nativeCreate = getNative(Object, 'create'), + nativeFloor = Math.floor, + nativeIsArray = getNative(Array, 'isArray'), + nativeIsFinite = context.isFinite, + nativeKeys = getNative(Object, 'keys'), + nativeMax = Math.max, + nativeMin = Math.min, + nativeNow = getNative(Date, 'now'), + nativeParseInt = context.parseInt, + nativeRandom = Math.random; + + /** Used as references for `-Infinity` and `Infinity`. */ + var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY, + POSITIVE_INFINITY = Number.POSITIVE_INFINITY; + + /** Used as references for the maximum length and index of an array. */ + var MAX_ARRAY_LENGTH = 4294967295, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + + /** + * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) + * of an array-like value. + */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** Used to store function metadata. */ + var metaMap = WeakMap && new WeakMap; + + /** Used to lookup unminified function names. */ + var realNames = {}; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps `value` to enable implicit chaining. + * Methods that operate on and return arrays, collections, and functions can + * be chained together. Methods that retrieve a single value or may return a + * primitive value will automatically end the chain returning the unwrapped + * value. Explicit chaining may be enabled using `_.chain`. The execution of + * chained methods is lazy, that is, execution is deferred until `_#value` + * is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. Shortcut + * fusion is an optimization strategy which merge iteratee calls; this can help + * to avoid the creation of intermediate data structures and greatly reduce the + * number of iteratee executions. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, + * `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, + * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, + * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, + * and `where` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, + * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, + * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`, + * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`, + * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, + * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, + * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, + * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, + * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, + * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, + * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, + * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, + * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, + * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, + * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, + * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, + * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`, + * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, + * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, + * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, + * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, + * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, + * `unescape`, `uniqueId`, `value`, and `words` + * + * The wrapper method `sample` will return a wrapped value when `n` is provided, + * otherwise an unwrapped value is returned. + * + * @name _ + * @constructor + * @category Chain + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(total, n) { + * return total + n; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(n) { + * return n * n; + * }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); + } + + /** + * The function whose prototype all chaining wrappers inherit from. + * + * @private + */ + function baseLodash() { + // No operation performed. + } + + /** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable chaining for all wrapper methods. + * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value. + */ + function LodashWrapper(value, chainAll, actions) { + this.__wrapped__ = value; + this.__actions__ = actions || []; + this.__chain__ = !!chainAll; + } + + /** + * An object environment feature flags. + * + * @static + * @memberOf _ + * @type Object + */ + var support = lodash.support = {}; + + /** + * By default, the template delimiters used by lodash are like those in + * embedded Ruby (ERB). Change the following template settings to use + * alternative delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': reEscape, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': reEvaluate, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type Object + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type Function + */ + '_': lodash + } + }; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @param {*} value The value to wrap. + */ + function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__dir__ = 1; + this.__filtered__ = false; + this.__iteratees__ = []; + this.__takeCount__ = POSITIVE_INFINITY; + this.__views__ = []; + } + + /** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ + function lazyClone() { + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = arrayCopy(this.__actions__); + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = arrayCopy(this.__iteratees__); + result.__takeCount__ = this.__takeCount__; + result.__views__ = arrayCopy(this.__views__); + return result; + } + + /** + * Reverses the direction of lazy iteration. + * + * @private + * @name reverse + * @memberOf LazyWrapper + * @returns {Object} Returns the new reversed `LazyWrapper` object. + */ + function lazyReverse() { + if (this.__filtered__) { + var result = new LazyWrapper(this); + result.__dir__ = -1; + result.__filtered__ = true; + } else { + result = this.clone(); + result.__dir__ *= -1; + } + return result; + } + + /** + * Extracts the unwrapped value from its lazy wrapper. + * + * @private + * @name value + * @memberOf LazyWrapper + * @returns {*} Returns the unwrapped value. + */ + function lazyValue() { + var array = this.__wrapped__.value(), + dir = this.__dir__, + isArr = isArray(array), + isRight = dir < 0, + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : (start - 1), + iteratees = this.__iteratees__, + iterLength = iteratees.length, + resIndex = 0, + takeCount = nativeMin(length, this.__takeCount__); + + if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) { + return baseWrapperValue((isRight && isArr) ? array.reverse() : array, this.__actions__); + } + var result = []; + + outer: + while (length-- && resIndex < takeCount) { + index += dir; + + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type, + computed = iteratee(value); + + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } + } + } + result[resIndex++] = value; + } + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a cache object to store key/value pairs. + * + * @private + * @static + * @name Cache + * @memberOf _.memoize + */ + function MapCache() { + this.__data__ = {}; + } + + /** + * Removes `key` and its value from the cache. + * + * @private + * @name delete + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`. + */ + function mapDelete(key) { + return this.has(key) && delete this.__data__[key]; + } + + /** + * Gets the cached value for `key`. + * + * @private + * @name get + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to get. + * @returns {*} Returns the cached value. + */ + function mapGet(key) { + return key == '__proto__' ? undefined : this.__data__[key]; + } + + /** + * Checks if a cached value for `key` exists. + * + * @private + * @name has + * @memberOf _.memoize.Cache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapHas(key) { + return key != '__proto__' && hasOwnProperty.call(this.__data__, key); + } + + /** + * Sets `value` to `key` of the cache. + * + * @private + * @name set + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to cache. + * @param {*} value The value to cache. + * @returns {Object} Returns the cache object. + */ + function mapSet(key, value) { + if (key != '__proto__') { + this.__data__[key] = value; + } + return this; + } + + /*------------------------------------------------------------------------*/ + + /** + * + * Creates a cache object to store unique values. + * + * @private + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var length = values ? values.length : 0; + + this.data = { 'hash': nativeCreate(null), 'set': new Set }; + while (length--) { + this.push(values[length]); + } + } + + /** + * Checks if `value` is in `cache` mimicking the return signature of + * `_.indexOf` by returning `0` if the value is found, else `-1`. + * + * @private + * @param {Object} cache The cache to search. + * @param {*} value The value to search for. + * @returns {number} Returns `0` if `value` is found, else `-1`. + */ + function cacheIndexOf(cache, value) { + var data = cache.data, + result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value]; + + return result ? 0 : -1; + } + + /** + * Adds `value` to the cache. + * + * @private + * @name push + * @memberOf SetCache + * @param {*} value The value to cache. + */ + function cachePush(value) { + var data = this.data; + if (typeof value == 'string' || isObject(value)) { + data.set.add(value); + } else { + data.hash[value] = true; + } + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a new array joining `array` with `other`. + * + * @private + * @param {Array} array The array to join. + * @param {Array} other The other array to join. + * @returns {Array} Returns the new concatenated array. + */ + function arrayConcat(array, other) { + var index = -1, + length = array.length, + othIndex = -1, + othLength = other.length, + result = Array(length + othLength); + + while (++index < length) { + result[index] = array[index]; + } + while (++othIndex < othLength) { + result[index++] = other[othIndex]; + } + return result; + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function arrayCopy(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * A specialized version of `_.forEach` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.forEachRight` for arrays without support for + * callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEachRight(array, iteratee) { + var length = array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.every` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + */ + function arrayEvery(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; + } + + /** + * A specialized version of `baseExtremum` for arrays which invokes `iteratee` + * with one argument: (value). + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {*} Returns the extremum value. + */ + function arrayExtremum(array, iteratee, comparator, exValue) { + var index = -1, + length = array.length, + computed = exValue, + result = computed; + + while (++index < length) { + var value = array[index], + current = +iteratee(value); + + if (comparator(current, computed)) { + computed = current; + result = value; + } + } + return result; + } + + /** + * A specialized version of `_.filter` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * A specialized version of `_.map` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray] Specify using the first element of `array` + * as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initFromArray) { + var index = -1, + length = array.length; + + if (initFromArray && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * A specialized version of `_.reduceRight` for arrays without support for + * callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray] Specify using the last element of `array` + * as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduceRight(array, iteratee, accumulator, initFromArray) { + var length = array.length; + if (initFromArray && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; + } + + /** + * A specialized version of `_.some` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * A specialized version of `_.sum` for arrays without support for callback + * shorthands and `this` binding.. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function arraySum(array, iteratee) { + var length = array.length, + result = 0; + + while (length--) { + result += +iteratee(array[length]) || 0; + } + return result; + } + + /** + * Used by `_.defaults` to customize its `_.assign` use. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @returns {*} Returns the value to assign to the destination object. + */ + function assignDefaults(objectValue, sourceValue) { + return objectValue === undefined ? sourceValue : objectValue; + } + + /** + * Used by `_.template` to customize its `_.assign` use. + * + * **Note:** This function is like `assignDefaults` except that it ignores + * inherited property values when checking if a property is `undefined`. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @param {string} key The key associated with the object and source values. + * @param {Object} object The destination object. + * @returns {*} Returns the value to assign to the destination object. + */ + function assignOwnDefaults(objectValue, sourceValue, key, object) { + return (objectValue === undefined || !hasOwnProperty.call(object, key)) + ? sourceValue + : objectValue; + } + + /** + * A specialized version of `_.assign` for customizing assigned values without + * support for argument juggling, multiple sources, and `this` binding `customizer` + * functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + */ + function assignWith(object, source, customizer) { + var index = -1, + props = keys(source), + length = props.length; + + while (++index < length) { + var key = props[index], + value = object[key], + result = customizer(value, source[key], key, object, source); + + if ((result === result ? (result !== value) : (value === value)) || + (value === undefined && !(key in object))) { + object[key] = result; + } + } + return object; + } + + /** + * The base implementation of `_.assign` without support for argument juggling, + * multiple sources, and `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return source == null + ? object + : baseCopy(source, keys(source), object); + } + + /** + * The base implementation of `_.at` without support for string collections + * and individual key arguments. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {number[]|string[]} props The property names or indexes of elements to pick. + * @returns {Array} Returns the new array of picked elements. + */ + function baseAt(collection, props) { + var index = -1, + isNil = collection == null, + isArr = !isNil && isArrayLike(collection), + length = isArr ? collection.length : 0, + propsLength = props.length, + result = Array(propsLength); + + while(++index < propsLength) { + var key = props[index]; + if (isArr) { + result[index] = isIndex(key, length) ? collection[key] : undefined; + } else { + result[index] = isNil ? undefined : collection[key]; + } + } + return result; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ + function baseCopy(source, props, object) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + object[key] = source[key]; + } + return object; + } + + /** + * The base implementation of `_.callback` which supports specifying the + * number of arguments to provide to `func`. + * + * @private + * @param {*} [func=_.identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ + function baseCallback(func, thisArg, argCount) { + var type = typeof func; + if (type == 'function') { + return thisArg === undefined + ? func + : bindCallback(func, thisArg, argCount); + } + if (func == null) { + return identity; + } + if (type == 'object') { + return baseMatches(func); + } + return thisArg === undefined + ? property(func) + : baseMatchesProperty(func, thisArg); + } + + /** + * The base implementation of `_.clone` without support for argument juggling + * and `this` binding `customizer` functions. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The object `value` belongs to. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates clones with source counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { + var result; + if (customizer) { + result = object ? customizer(value, key, object) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return arrayCopy(value, result); + } + } else { + var tag = objToString.call(value), + isFunc = tag == funcTag; + + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return baseAssign(result, value); + } + } else { + return cloneableTags[tag] + ? initCloneByTag(value, tag, isDeep) + : (object ? value : {}); + } + } + // Check for circular references and return its corresponding clone. + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + // Add the source value to the stack of traversed objects and associate it with its clone. + stackA.push(value); + stackB.push(result); + + // Recursively populate clone (susceptible to call stack limits). + (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { + result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB); + }); + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function() { + function object() {} + return function(prototype) { + if (isObject(prototype)) { + object.prototype = prototype; + var result = new object; + object.prototype = undefined; + } + return result || {}; + }; + }()); + + /** + * The base implementation of `_.delay` and `_.defer` which accepts an index + * of where to slice the arguments to provide to `func`. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Object} args The arguments provide to `func`. + * @returns {number} Returns the timer id. + */ + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * The base implementation of `_.difference` which accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @returns {Array} Returns the new array of filtered values. + */ + function baseDifference(array, values) { + var length = array ? array.length : 0, + result = []; + + if (!length) { + return result; + } + var index = -1, + indexOf = getIndexOf(), + isCommon = indexOf == baseIndexOf, + cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null, + valuesLength = values.length; + + if (cache) { + indexOf = cacheIndexOf; + isCommon = false; + values = cache; + } + outer: + while (++index < length) { + var value = array[index]; + + if (isCommon && value === value) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === value) { + continue outer; + } + } + result.push(value); + } + else if (indexOf(values, value, 0) < 0) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.forEach` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEach = createBaseEach(baseForOwn); + + /** + * The base implementation of `_.forEachRight` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEachRight = createBaseEach(baseForOwnRight, true); + + /** + * The base implementation of `_.every` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false` + */ + function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } + + /** + * Gets the extremum value of `collection` invoking `iteratee` for each value + * in `collection` to generate the criterion by which the value is ranked. + * The `iteratee` is invoked with three arguments: (value, index|key, collection). + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {*} Returns the extremum value. + */ + function baseExtremum(collection, iteratee, comparator, exValue) { + var computed = exValue, + result = computed; + + baseEach(collection, function(value, index, collection) { + var current = +iteratee(value, index, collection); + if (comparator(current, computed) || (current === exValue && current === result)) { + computed = current; + result = value; + } + }); + return result; + } + + /** + * The base implementation of `_.fill` without an iteratee call guard. + * + * @private + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + */ + function baseFill(array, value, start, end) { + var length = array.length; + + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : (end >>> 0); + start >>>= 0; + + while (start < length) { + array[start++] = value; + } + return array; + } + + /** + * The base implementation of `_.filter` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; + } + + /** + * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`, + * without support for callback shorthands and `this` binding, which iterates + * over `collection` using the provided `eachFunc`. + * + * @private + * @param {Array|Object|string} collection The collection to search. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @param {boolean} [retKey] Specify returning the key of the found element + * instead of the element itself. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFind(collection, predicate, eachFunc, retKey) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = retKey ? key : value; + return false; + } + }); + return result; + } + + /** + * The base implementation of `_.flatten` with added support for restricting + * flattening and specifying the start index. + * + * @private + * @param {Array} array The array to flatten. + * @param {boolean} [isDeep] Specify a deep flatten. + * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ + function baseFlatten(array, isDeep, isStrict, result) { + result || (result = []); + + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index]; + if (isObjectLike(value) && isArrayLike(value) && + (isStrict || isArray(value) || isArguments(value))) { + if (isDeep) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, isDeep, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; + } + + /** + * The base implementation of `baseForIn` and `baseForOwn` which iterates + * over `object` properties returned by `keysFunc` invoking `iteratee` for + * each property. Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * This function is like `baseFor` except that it iterates over properties + * in the opposite order. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseForRight = createBaseFor(true); + + /** + * The base implementation of `_.forIn` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForIn(object, iteratee) { + return baseFor(object, iteratee, keysIn); + } + + /** + * The base implementation of `_.forOwn` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return baseFor(object, iteratee, keys); + } + + /** + * The base implementation of `_.forOwnRight` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwnRight(object, iteratee) { + return baseForRight(object, iteratee, keys); + } + + /** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from those provided. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the new array of filtered property names. + */ + function baseFunctions(object, props) { + var index = -1, + length = props.length, + resIndex = -1, + result = []; + + while (++index < length) { + var key = props[index]; + if (isFunction(object[key])) { + result[++resIndex] = key; + } + } + return result; + } + + /** + * The base implementation of `get` without support for string paths + * and default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path of the property to get. + * @param {string} [pathKey] The key representation of path. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path, pathKey) { + if (object == null) { + return; + } + if (pathKey !== undefined && pathKey in toObject(object)) { + path = [pathKey]; + } + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[path[index++]]; + } + return (index && index == length) ? object : undefined; + } + + /** + * The base implementation of `_.isEqual` without support for `this` binding + * `customizer` functions. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); + } + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing objects. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `value` objects. + * @param {Array} [stackB=[]] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = arrayTag, + othTag = arrayTag; + + if (!objIsArr) { + objTag = objToString.call(object); + if (objTag == argsTag) { + objTag = objectTag; + } else if (objTag != objectTag) { + objIsArr = isTypedArray(object); + } + } + if (!othIsArr) { + othTag = objToString.call(other); + if (othTag == argsTag) { + othTag = objectTag; + } else if (othTag != objectTag) { + othIsArr = isTypedArray(other); + } + } + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && !(objIsArr || objIsObj)) { + return equalByTag(object, other, objTag); + } + if (!isLoose) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); + } + } + if (!isSameTag) { + return false; + } + // Assume cyclic values are equal. + // For more information on detecting circular references see https://es5.github.io/#JO. + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == object) { + return stackB[length] == other; + } + } + // Add `object` and `other` to the stack of traversed objects. + stackA.push(object); + stackB.push(other); + + var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); + + stackA.pop(); + stackB.pop(); + + return result; + } + + /** + * The base implementation of `_.isMatch` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} matchData The propery names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparing objects. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = toObject(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var result = customizer ? customizer(objValue, srcValue, key) : undefined; + if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) { + return false; + } + } + } + return true; + } + + /** + * The base implementation of `_.map` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; + } + + /** + * The base implementation of `_.matches` which does not clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + */ + function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + var key = matchData[0][0], + value = matchData[0][1]; + + return function(object) { + if (object == null) { + return false; + } + return object[key] === value && (value !== undefined || (key in toObject(object))); + }; + } + return function(object) { + return baseIsMatch(object, matchData); + }; + } + + /** + * The base implementation of `_.matchesProperty` which does not clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to compare. + * @returns {Function} Returns the new function. + */ + function baseMatchesProperty(path, srcValue) { + var isArr = isArray(path), + isCommon = isKey(path) && isStrictComparable(srcValue), + pathKey = (path + ''); + + path = toPath(path); + return function(object) { + if (object == null) { + return false; + } + var key = pathKey; + object = toObject(object); + if ((isArr || !isCommon) && !(key in object)) { + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + if (object == null) { + return false; + } + key = last(path); + object = toObject(object); + } + return object[key] === srcValue + ? (srcValue !== undefined || (key in object)) + : baseIsEqual(srcValue, object[key], undefined, true); + }; + } + + /** + * The base implementation of `_.merge` without support for argument juggling, + * multiple sources, and `this` binding `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} [customizer] The function to customize merged values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + * @returns {Object} Returns `object`. + */ + function baseMerge(object, source, customizer, stackA, stackB) { + if (!isObject(object)) { + return object; + } + var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)), + props = isSrcArr ? undefined : keys(source); + + arrayEach(props || source, function(srcValue, key) { + if (props) { + key = srcValue; + srcValue = source[key]; + } + if (isObjectLike(srcValue)) { + stackA || (stackA = []); + stackB || (stackB = []); + baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); + } + else { + var value = object[key], + result = customizer ? customizer(value, srcValue, key, object, source) : undefined, + isCommon = result === undefined; + + if (isCommon) { + result = srcValue; + } + if ((result !== undefined || (isSrcArr && !(key in object))) && + (isCommon || (result === result ? (result !== value) : (value === value)))) { + object[key] = result; + } + } + }); + return object; + } + + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize merged values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) { + var length = stackA.length, + srcValue = source[key]; + + while (length--) { + if (stackA[length] == srcValue) { + object[key] = stackB[length]; + return; + } + } + var value = object[key], + result = customizer ? customizer(value, srcValue, key, object, source) : undefined, + isCommon = result === undefined; + + if (isCommon) { + result = srcValue; + if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) { + result = isArray(value) + ? value + : (isArrayLike(value) ? arrayCopy(value) : []); + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + result = isArguments(value) + ? toPlainObject(value) + : (isPlainObject(value) ? value : {}); + } + else { + isCommon = false; + } + } + // Add the source value to the stack of traversed objects and associate + // it with its merged value. + stackA.push(srcValue); + stackB.push(result); + + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB); + } else if (result === result ? (result !== value) : (value === value)) { + object[key] = result; + } + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new function. + */ + function basePropertyDeep(path) { + var pathKey = (path + ''); + path = toPath(path); + return function(object) { + return baseGet(object, path, pathKey); + }; + } + + /** + * The base implementation of `_.pullAt` without support for individual + * index arguments and capturing the removed elements. + * + * @private + * @param {Array} array The array to modify. + * @param {number[]} indexes The indexes of elements to remove. + * @returns {Array} Returns `array`. + */ + function basePullAt(array, indexes) { + var length = array ? indexes.length : 0; + while (length--) { + var index = indexes[length]; + if (index != previous && isIndex(index)) { + var previous = index; + splice.call(array, index, 1); + } + } + return array; + } + + /** + * The base implementation of `_.random` without support for argument juggling + * and returning floating-point numbers. + * + * @private + * @param {number} min The minimum possible value. + * @param {number} max The maximum possible value. + * @returns {number} Returns the random number. + */ + function baseRandom(min, max) { + return min + nativeFloor(nativeRandom() * (max - min + 1)); + } + + /** + * The base implementation of `_.reduce` and `_.reduceRight` without support + * for callback shorthands and `this` binding, which iterates over `collection` + * using the provided `eachFunc`. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initFromCollection Specify using the first or last element + * of `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initFromCollection + ? (initFromCollection = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The base implementation of `setData` without support for hot loop detection. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var baseSetData = !metaMap ? identity : function(func, data) { + metaMap.set(func, data); + return func; + }; + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * The base implementation of `_.some` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } + + /** + * The base implementation of `_.sortBy` which uses `comparer` to define + * the sort order of `array` and replaces criteria objects with their + * corresponding values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ + function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; + } + + /** + * The base implementation of `_.sortByOrder` without param guards. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {boolean[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ + function baseSortByOrder(collection, iteratees, orders) { + var callback = getCallback(), + index = -1; + + iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); }); + + var result = baseMap(collection, function(value) { + var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); + } + + /** + * The base implementation of `_.sum` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function baseSum(collection, iteratee) { + var result = 0; + baseEach(collection, function(value, index, collection) { + result += +iteratee(value, index, collection) || 0; + }); + return result; + } + + /** + * The base implementation of `_.uniq` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function baseUniq(array, iteratee) { + var index = -1, + indexOf = getIndexOf(), + length = array.length, + isCommon = indexOf == baseIndexOf, + isLarge = isCommon && length >= LARGE_ARRAY_SIZE, + seen = isLarge ? createCache() : null, + result = []; + + if (seen) { + indexOf = cacheIndexOf; + isCommon = false; + } else { + isLarge = false; + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; + + if (isCommon && value === value) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (indexOf(seen, computed, 0) < 0) { + if (iteratee || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + var index = -1, + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } + + /** + * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`, + * and `_.takeWhile` without support for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to query. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [isDrop] Specify dropping elements instead of taking them. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the slice of `array`. + */ + function baseWhile(array, predicate, isDrop, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {} + return isDrop + ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) + : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); + } + + /** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to peform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ + function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + var index = -1, + length = actions.length; + + while (++index < length) { + var action = actions[index]; + result = action.func.apply(action.thisArg, arrayPush([result], action.args)); + } + return result; + } + + /** + * Performs a binary search of `array` to determine the index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function binaryIndex(array, value, retHighest) { + var low = 0, + high = array ? array.length : low; + + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; + + if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { + low = mid + 1; + } else { + high = mid; + } + } + return high; + } + return binaryIndexBy(array, value, identity, retHighest); + } + + /** + * This function is like `binaryIndex` except that it invokes `iteratee` for + * `value` and each element of `array` to compute their sort ranking. The + * iteratee is invoked with one argument; (value). + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} iteratee The function invoked per iteration. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function binaryIndexBy(array, value, iteratee, retHighest) { + value = iteratee(value); + + var low = 0, + high = array ? array.length : 0, + valIsNaN = value !== value, + valIsNull = value === null, + valIsUndef = value === undefined; + + while (low < high) { + var mid = nativeFloor((low + high) / 2), + computed = iteratee(array[mid]), + isDef = computed !== undefined, + isReflexive = computed === computed; + + if (valIsNaN) { + var setLow = isReflexive || retHighest; + } else if (valIsNull) { + setLow = isReflexive && isDef && (retHighest || computed != null); + } else if (valIsUndef) { + setLow = isReflexive && (retHighest || isDef); + } else if (computed == null) { + setLow = false; + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); + } + + /** + * A specialized version of `baseCallback` which only supports `this` binding + * and specifying the number of arguments to provide to `func`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ + function bindCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + if (thisArg === undefined) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + case 5: return function(value, other, key, object, source) { + return func.call(thisArg, value, other, key, object, source); + }; + } + return function() { + return func.apply(thisArg, arguments); + }; + } + + /** + * Creates a clone of the given array buffer. + * + * @private + * @param {ArrayBuffer} buffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function bufferClone(buffer) { + var result = new ArrayBuffer(buffer.byteLength), + view = new Uint8Array(result); + + view.set(new Uint8Array(buffer)); + return result; + } + + /** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgs(args, partials, holders) { + var holdersLength = holders.length, + argsIndex = -1, + argsLength = nativeMax(args.length - holdersLength, 0), + leftIndex = -1, + leftLength = partials.length, + result = Array(leftLength + argsLength); + + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + while (argsLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; + } + + /** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgsRight(args, partials, holders) { + var holdersIndex = -1, + holdersLength = holders.length, + argsIndex = -1, + argsLength = nativeMax(args.length - holdersLength, 0), + rightIndex = -1, + rightLength = partials.length, + result = Array(argsLength + rightLength); + + while (++argsIndex < argsLength) { + result[argsIndex] = args[argsIndex]; + } + var offset = argsIndex; + while (++rightIndex < rightLength) { + result[offset + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; + } + return result; + } + + /** + * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function. + * + * @private + * @param {Function} setter The function to set keys and values of the accumulator object. + * @param {Function} [initializer] The function to initialize the accumulator object. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter, initializer) { + return function(collection, iteratee, thisArg) { + var result = initializer ? initializer() : {}; + iteratee = getCallback(iteratee, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + setter(result, value, iteratee(value, index, collection), collection); + } + } else { + baseEach(collection, function(value, key, collection) { + setter(result, value, iteratee(value, key, collection), collection); + }); + } + return result; + }; + } + + /** + * Creates a `_.assign`, `_.defaults`, or `_.merge` function. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return restParam(function(object, sources) { + var index = -1, + length = object == null ? 0 : sources.length, + customizer = length > 2 ? sources[length - 2] : undefined, + guard = length > 2 ? sources[2] : undefined, + thisArg = length > 1 ? sources[length - 1] : undefined; + + if (typeof customizer == 'function') { + customizer = bindCallback(customizer, thisArg, 5); + length -= 2; + } else { + customizer = typeof thisArg == 'function' ? thisArg : undefined; + length -= (customizer ? 1 : 0); + } + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, customizer); + } + } + return object; + }); + } + + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + return eachFunc(collection, iteratee); + } + var index = fromRight ? length : -1, + iterable = toObject(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } + + /** + * Creates a base function for `_.forIn` or `_.forInRight`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var iterable = toObject(object), + props = keysFunc(object), + length = props.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + var key = props[index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * Creates a function that wraps `func` and invokes it with the `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new bound function. + */ + function createBindWrapper(func, thisArg) { + var Ctor = createCtorWrapper(func); + + function wrapper() { + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(thisArg, arguments); + } + return wrapper; + } + + /** + * Creates a `Set` cache object to optimize linear searches of large arrays. + * + * @private + * @param {Array} [values] The values to cache. + * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`. + */ + function createCache(values) { + return (nativeCreate && Set) ? new SetCache(values) : null; + } + + /** + * Creates a function that produces compound words out of the words in a + * given string. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ + function createCompounder(callback) { + return function(string) { + var index = -1, + array = words(deburr(string)), + length = array.length, + result = ''; + + while (++index < length) { + result = callback(result, array[index], index); + } + return result; + }; + } + + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ + function createCtorWrapper(Ctor) { + return function() { + // Use a `switch` statement to work with class constructors. + // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + switch (args.length) { + case 0: return new Ctor; + case 1: return new Ctor(args[0]); + case 2: return new Ctor(args[0], args[1]); + case 3: return new Ctor(args[0], args[1], args[2]); + case 4: return new Ctor(args[0], args[1], args[2], args[3]); + case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + } + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } + + /** + * Creates a `_.curry` or `_.curryRight` function. + * + * @private + * @param {boolean} flag The curry bit flag. + * @returns {Function} Returns the new curry function. + */ + function createCurry(flag) { + function curryFunc(func, arity, guard) { + if (guard && isIterateeCall(func, arity, guard)) { + arity = undefined; + } + var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curryFunc.placeholder; + return result; + } + return curryFunc; + } + + /** + * Creates a `_.defaults` or `_.defaultsDeep` function. + * + * @private + * @param {Function} assigner The function to assign values. + * @param {Function} customizer The function to customize assigned values. + * @returns {Function} Returns the new defaults function. + */ + function createDefaults(assigner, customizer) { + return restParam(function(args) { + var object = args[0]; + if (object == null) { + return object; + } + args.push(customizer); + return assigner.apply(undefined, args); + }); + } + + /** + * Creates a `_.max` or `_.min` function. + * + * @private + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {Function} Returns the new extremum function. + */ + function createExtremum(comparator, exValue) { + return function(collection, iteratee, thisArg) { + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = undefined; + } + iteratee = getCallback(iteratee, thisArg, 3); + if (iteratee.length == 1) { + collection = isArray(collection) ? collection : toIterable(collection); + var result = arrayExtremum(collection, iteratee, comparator, exValue); + if (!(collection.length && result === exValue)) { + return result; + } + } + return baseExtremum(collection, iteratee, comparator, exValue); + }; + } + + /** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new find function. + */ + function createFind(eachFunc, fromRight) { + return function(collection, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate, fromRight); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, eachFunc); + }; + } + + /** + * Creates a `_.findIndex` or `_.findLastIndex` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new find function. + */ + function createFindIndex(fromRight) { + return function(array, predicate, thisArg) { + if (!(array && array.length)) { + return -1; + } + predicate = getCallback(predicate, thisArg, 3); + return baseFindIndex(array, predicate, fromRight); + }; + } + + /** + * Creates a `_.findKey` or `_.findLastKey` function. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new find function. + */ + function createFindKey(objectFunc) { + return function(object, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + return baseFind(object, predicate, objectFunc, true); + }; + } + + /** + * Creates a `_.flow` or `_.flowRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new flow function. + */ + function createFlow(fromRight) { + return function() { + var wrapper, + length = arguments.length, + index = fromRight ? length : -1, + leftIndex = 0, + funcs = Array(length); + + while ((fromRight ? index-- : ++index < length)) { + var func = funcs[leftIndex++] = arguments[index]; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') { + wrapper = new LodashWrapper([], true); + } + } + index = wrapper ? -1 : length; + while (++index < length) { + func = funcs[index]; + + var funcName = getFuncName(func), + data = funcName == 'wrapper' ? getData(func) : undefined; + + if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); + } + } + return function() { + var args = arguments, + value = args[0]; + + if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) { + return wrapper.plant(value).value(); + } + var index = 0, + result = length ? funcs[index].apply(this, args) : value; + + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }; + } + + /** + * Creates a function for `_.forEach` or `_.forEachRight`. + * + * @private + * @param {Function} arrayFunc The function to iterate over an array. + * @param {Function} eachFunc The function to iterate over a collection. + * @returns {Function} Returns the new each function. + */ + function createForEach(arrayFunc, eachFunc) { + return function(collection, iteratee, thisArg) { + return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) + ? arrayFunc(collection, iteratee) + : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); + }; + } + + /** + * Creates a function for `_.forIn` or `_.forInRight`. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new each function. + */ + function createForIn(objectFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || thisArg !== undefined) { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee, keysIn); + }; + } + + /** + * Creates a function for `_.forOwn` or `_.forOwnRight`. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new each function. + */ + function createForOwn(objectFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || thisArg !== undefined) { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee); + }; + } + + /** + * Creates a function for `_.mapKeys` or `_.mapValues`. + * + * @private + * @param {boolean} [isMapKeys] Specify mapping keys instead of values. + * @returns {Function} Returns the new map function. + */ + function createObjectMapper(isMapKeys) { + return function(object, iteratee, thisArg) { + var result = {}; + iteratee = getCallback(iteratee, thisArg, 3); + + baseForOwn(object, function(value, key, object) { + var mapped = iteratee(value, key, object); + key = isMapKeys ? mapped : key; + value = isMapKeys ? value : mapped; + result[key] = value; + }); + return result; + }; + } + + /** + * Creates a function for `_.padLeft` or `_.padRight`. + * + * @private + * @param {boolean} [fromRight] Specify padding from the right. + * @returns {Function} Returns the new pad function. + */ + function createPadDir(fromRight) { + return function(string, length, chars) { + string = baseToString(string); + return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string); + }; + } + + /** + * Creates a `_.partial` or `_.partialRight` function. + * + * @private + * @param {boolean} flag The partial bit flag. + * @returns {Function} Returns the new partial function. + */ + function createPartial(flag) { + var partialFunc = restParam(function(func, partials) { + var holders = replaceHolders(partials, partialFunc.placeholder); + return createWrapper(func, flag, undefined, partials, holders); + }); + return partialFunc; + } + + /** + * Creates a function for `_.reduce` or `_.reduceRight`. + * + * @private + * @param {Function} arrayFunc The function to iterate over an array. + * @param {Function} eachFunc The function to iterate over a collection. + * @returns {Function} Returns the new each function. + */ + function createReduce(arrayFunc, eachFunc) { + return function(collection, iteratee, accumulator, thisArg) { + var initFromArray = arguments.length < 3; + return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) + ? arrayFunc(collection, iteratee, accumulator, initFromArray) + : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc); + }; + } + + /** + * Creates a function that wraps `func` and invokes it with optional `this` + * binding of, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [partialsRight] The arguments to append to those provided to the new function. + * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & ARY_FLAG, + isBind = bitmask & BIND_FLAG, + isBindKey = bitmask & BIND_KEY_FLAG, + isCurry = bitmask & CURRY_FLAG, + isCurryBound = bitmask & CURRY_BOUND_FLAG, + isCurryRight = bitmask & CURRY_RIGHT_FLAG, + Ctor = isBindKey ? undefined : createCtorWrapper(func); + + function wrapper() { + // Avoid `arguments` object use disqualifying optimizations by + // converting it to an array before providing it to other functions. + var length = arguments.length, + index = length, + args = Array(length); + + while (index--) { + args[index] = arguments[index]; + } + if (partials) { + args = composeArgs(args, partials, holders); + } + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight); + } + if (isCurry || isCurryRight) { + var placeholder = wrapper.placeholder, + argsHolders = replaceHolders(args, placeholder); + + length -= argsHolders.length; + if (length < arity) { + var newArgPos = argPos ? arrayCopy(argPos) : undefined, + newArity = nativeMax(arity - length, 0), + newsHolders = isCurry ? argsHolders : undefined, + newHoldersRight = isCurry ? undefined : argsHolders, + newPartials = isCurry ? args : undefined, + newPartialsRight = isCurry ? undefined : args; + + bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); + + if (!isCurryBound) { + bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); + } + var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], + result = createHybridWrapper.apply(undefined, newData); + + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return result; + } + } + var thisBinding = isBind ? thisArg : this, + fn = isBindKey ? thisBinding[func] : func; + + if (argPos) { + args = reorder(args, argPos); + } + if (isAry && ary < args.length) { + args.length = ary; + } + if (this && this !== root && this instanceof wrapper) { + fn = Ctor || createCtorWrapper(func); + } + return fn.apply(thisBinding, args); + } + return wrapper; + } + + /** + * Creates the padding required for `string` based on the given `length`. + * The `chars` string is truncated if the number of characters exceeds `length`. + * + * @private + * @param {string} string The string to create padding for. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the pad for `string`. + */ + function createPadding(string, length, chars) { + var strLength = string.length; + length = +length; + + if (strLength >= length || !nativeIsFinite(length)) { + return ''; + } + var padLength = length - strLength; + chars = chars == null ? ' ' : (chars + ''); + return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength); + } + + /** + * Creates a function that wraps `func` and invokes it with the optional `this` + * binding of `thisArg` and the `partials` prepended to those provided to + * the wrapper. + * + * @private + * @param {Function} func The function to partially apply arguments to. + * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to the new function. + * @returns {Function} Returns the new bound function. + */ + function createPartialWrapper(func, bitmask, thisArg, partials) { + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + // Avoid `arguments` object use disqualifying optimizations by + // converting it to an array before providing it `func`. + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength); + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(isBind ? thisArg : this, args); + } + return wrapper; + } + + /** + * Creates a `_.ceil`, `_.floor`, or `_.round` function. + * + * @private + * @param {string} methodName The name of the `Math` method to use when rounding. + * @returns {Function} Returns the new round function. + */ + function createRound(methodName) { + var func = Math[methodName]; + return function(number, precision) { + precision = precision === undefined ? 0 : (+precision || 0); + if (precision) { + precision = pow(10, precision); + return func(number * precision) / precision; + } + return func(number); + }; + } + + /** + * Creates a `_.sortedIndex` or `_.sortedLastIndex` function. + * + * @private + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {Function} Returns the new index function. + */ + function createSortedIndex(retHighest) { + return function(array, value, iteratee, thisArg) { + var callback = getCallback(iteratee); + return (iteratee == null && callback === baseCallback) + ? binaryIndex(array, value, retHighest) + : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighest); + }; + } + + /** + * Creates a function that either curries or invokes `func` with optional + * `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of flags. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to be partially applied. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & BIND_KEY_FLAG; + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); + partials = holders = undefined; + } + length -= (holders ? holders.length : 0); + if (bitmask & PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; + + partials = holders = undefined; + } + var data = isBindKey ? undefined : getData(func), + newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; + + if (data) { + mergeData(newData, data); + bitmask = newData[1]; + arity = newData[9]; + } + newData[9] = arity == null + ? (isBindKey ? 0 : func.length) + : (nativeMax(arity - length, 0) || 0); + + if (bitmask == BIND_FLAG) { + var result = createBindWrapper(newData[0], newData[2]); + } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) { + result = createPartialWrapper.apply(undefined, newData); + } else { + result = createHybridWrapper.apply(undefined, newData); + } + var setter = data ? baseSetData : setData; + return setter(result, newData); + } + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing arrays. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { + var index = -1, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isLoose && othLength > arrLength)) { + return false; + } + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index], + result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined; + + if (result !== undefined) { + if (result) { + continue; + } + return false; + } + // Recursively compare arrays (susceptible to call stack limits). + if (isLoose) { + if (!arraySome(other, function(othValue) { + return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); + })) { + return false; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) { + return false; + } + } + return true; + } + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag) { + switch (tag) { + case boolTag: + case dateTag: + // Coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. + return +object == +other; + + case errorTag: + return object.name == other.name && object.message == other.message; + + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) + ? other != +other + : object == +other; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings primitives and string + // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. + return object == (other + ''); + } + return false; + } + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; + + if (objLength != othLength && !isLoose) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + var skipCtor = isLoose; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key], + result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined; + + // Recursively compare objects (susceptible to call stack limits). + if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) { + return false; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (!skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + return false; + } + } + return true; + } + + /** + * Gets the appropriate "callback" function. If the `_.callback` method is + * customized this function returns the custom method, otherwise it returns + * the `baseCallback` function. If arguments are provided the chosen function + * is invoked with them and its result is returned. + * + * @private + * @returns {Function} Returns the chosen function or its result. + */ + function getCallback(func, thisArg, argCount) { + var result = lodash.callback || callback; + result = result === callback ? baseCallback : result; + return argCount ? result(func, thisArg, argCount) : result; + } + + /** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ + var getData = !metaMap ? noop : function(func) { + return metaMap.get(func); + }; + + /** + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ + function getFuncName(func) { + var result = func.name, + array = realNames[result], + length = array ? array.length : 0; + + while (length--) { + var data = array[length], + otherFunc = data.func; + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; + } + + /** + * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * customized this function returns the custom method, otherwise it returns + * the `baseIndexOf` function. If arguments are provided the chosen function + * is invoked with them and its result is returned. + * + * @private + * @returns {Function|number} Returns the chosen function or its result. + */ + function getIndexOf(collection, target, fromIndex) { + var result = lodash.indexOf || indexOf; + result = result === indexOf ? baseIndexOf : result; + return collection ? result(collection, target, fromIndex) : result; + } + + /** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ + var getLength = baseProperty('length'); + + /** + * Gets the propery names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ + function getMatchData(object) { + var result = pairs(object), + length = result.length; + + while (length--) { + result[length][2] = isStrictComparable(result[length][1]); + } + return result; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = object == null ? undefined : object[key]; + return isNative(value) ? value : undefined; + } + + /** + * Gets the view, applying any `transforms` to the `start` and `end` positions. + * + * @private + * @param {number} start The start of the view. + * @param {number} end The end of the view. + * @param {Array} transforms The transformations to apply to the view. + * @returns {Object} Returns an object containing the `start` and `end` + * positions of the view. + */ + function getView(start, end, transforms) { + var index = -1, + length = transforms.length; + + while (++index < length) { + var data = transforms[index], + size = data.size; + + switch (data.type) { + case 'drop': start += size; break; + case 'dropRight': end -= size; break; + case 'take': end = nativeMin(end, start + size); break; + case 'takeRight': start = nativeMax(start, end - size); break; + } + } + return { 'start': start, 'end': end }; + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add array properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + var Ctor = object.constructor; + if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { + Ctor = Object; + } + return new Ctor; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return bufferClone(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + var buffer = object.buffer; + return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + var result = new Ctor(object.source, reFlags.exec(object)); + result.lastIndex = object.lastIndex; + } + return result; + } + + /** + * Invokes the method at `path` on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ + function invokePath(object, path, args) { + if (object != null && !isKey(path, object)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + path = last(path); + } + var func = object == null ? object : object[path]; + return func == null ? undefined : func.apply(object, args); + } + + /** + * Checks if `value` is array-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + */ + function isArrayLike(value) { + return value != null && isLength(getLength(value)); + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; + } + + /** + * Checks if the provided arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object)) { + var other = object[index]; + return value === value ? (value === other) : (other !== other); + } + return false; + } + + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + var type = typeof value; + if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { + return true; + } + if (isArray(value)) { + return false; + } + var result = !reIsDeepProp.test(value); + return result || (object != null && value in toObject(object)); + } + + /** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. + */ + function isLaziable(func) { + var funcName = getFuncName(func); + if (!(funcName in LazyWrapper.prototype)) { + return false; + } + var other = lodash[funcName]; + if (func === other) { + return true; + } + var data = getData(other); + return !!data && func === data[0]; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ + function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ + function isStrictComparable(value) { + return value === value && !isObject(value); + } + + /** + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers required to invoke a function. + * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` + * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` + * augment function arguments, making the order in which they are executed important, + * preventing the merging of metadata. However, we make an exception for a safe + * common case where curried functions have `_.ary` and or `_.rearg` applied. + * + * @private + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. + */ + function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < ARY_FLAG; + + var isCombo = + (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || + (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) || + (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; + } + // Use source `thisArg` if available. + if (srcBitmask & BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; + } + // Compose partial arguments. + var value = source[3]; + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value); + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]); + } + // Compose partial right arguments. + value = source[5]; + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value); + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]); + } + // Use source `argPos` if available. + value = source[7]; + if (value) { + data[7] = arrayCopy(value); + } + // Use source `ary` if it's smaller. + if (srcBitmask & ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } + // Use source `arity` if one is not provided. + if (data[9] == null) { + data[9] = source[9]; + } + // Use source `func` and merge bitmasks. + data[0] = source[0]; + data[1] = newBitmask; + + return data; + } + + /** + * Used by `_.defaultsDeep` to customize its `_.merge` use. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @returns {*} Returns the value to assign to the destination object. + */ + function mergeDefaults(objectValue, sourceValue) { + return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults); + } + + /** + * A specialized version of `_.pick` which picks `object` properties specified + * by `props`. + * + * @private + * @param {Object} object The source object. + * @param {string[]} props The property names to pick. + * @returns {Object} Returns the new object. + */ + function pickByArray(object, props) { + object = toObject(object); + + var index = -1, + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + return result; + } + + /** + * A specialized version of `_.pick` which picks `object` properties `predicate` + * returns truthy for. + * + * @private + * @param {Object} object The source object. + * @param {Function} predicate The function invoked per iteration. + * @returns {Object} Returns the new object. + */ + function pickByCallback(object, predicate) { + var result = {}; + baseForIn(object, function(value, key, object) { + if (predicate(value, key, object)) { + result[key] = value; + } + }); + return result; + } + + /** + * Reorder `array` according to the specified indexes where the element at + * the first index is assigned as the first element, the element at + * the second index is assigned as the second element, and so on. + * + * @private + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. + */ + function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = arrayCopy(array); + + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; + } + return array; + } + + /** + * Sets metadata for `func`. + * + * **Note:** If this function becomes hot, i.e. is invoked a lot in a short + * period of time, it will trip its breaker and transition to an identity function + * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) + * for more details. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var setData = (function() { + var count = 0, + lastCalled = 0; + + return function(key, value) { + var stamp = now(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return key; + } + } else { + count = 0; + } + return baseSetData(key, value); + }; + }()); + + /** + * A fallback implementation of `Object.keys` which creates an array of the + * own enumerable property names of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function shimKeys(object) { + var props = keysIn(object), + propsLength = props.length, + length = propsLength && object.length; + + var allowIndexes = !!length && isLength(length) && + (isArray(object) || isArguments(object)); + + var index = -1, + result = []; + + while (++index < propsLength) { + var key = props[index]; + if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { + result.push(key); + } + } + return result; + } + + /** + * Converts `value` to an array-like object if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Array|Object} Returns the array-like object. + */ + function toIterable(value) { + if (value == null) { + return []; + } + if (!isArrayLike(value)) { + return values(value); + } + return isObject(value) ? value : Object(value); + } + + /** + * Converts `value` to an object if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Object} Returns the object. + */ + function toObject(value) { + return isObject(value) ? value : Object(value); + } + + /** + * Converts `value` to property path array if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Array} Returns the property path array. + */ + function toPath(value) { + if (isArray(value)) { + return value; + } + var result = []; + baseToString(value).replace(rePropName, function(match, number, quote, string) { + result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + } + + /** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ + function wrapperClone(wrapper) { + return wrapper instanceof LazyWrapper + ? wrapper.clone() + : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements split into groups the length of `size`. + * If `collection` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=1] The length of each chunk. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new array containing chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ + function chunk(array, size, guard) { + if (guard ? isIterateeCall(array, size, guard) : size == null) { + size = 1; + } else { + size = nativeMax(nativeFloor(size) || 1, 1); + } + var index = 0, + length = array ? array.length : 0, + resIndex = -1, + result = Array(nativeCeil(length / size)); + + while (index < length) { + result[++resIndex] = baseSlice(array, index, (index += size)); + } + return result; + } + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * Creates an array of unique `array` values not included in the other + * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.difference([1, 2, 3], [4, 2]); + * // => [1, 3] + */ + var difference = restParam(function(array, values) { + return (isObjectLike(array) && isArrayLike(array)) + ? baseDifference(array, baseFlatten(values, false, true)) + : []; + }); + + /** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function drop(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements dropped from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRight([1, 2, 3]); + * // => [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function dropRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that match the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [1] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); + * // => ['barney'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function dropRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true) + : []; + } + + /** + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [3] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropWhile(users, 'active', false), 'user'); + * // => ['pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function dropWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true) + : []; + } + + /** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8], '*', 1, 2); + * // => [4, '*', 8] + */ + function fill(array, value, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } + return baseFill(array, value, start, end); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(chr) { + * return chr.user == 'barney'; + * }); + * // => 0 + * + * // using the `_.matches` callback shorthand + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // using the `_.matchesProperty` callback shorthand + * _.findIndex(users, 'active', false); + * // => 0 + * + * // using the `_.property` callback shorthand + * _.findIndex(users, 'active'); + * // => 2 + */ + var findIndex = createFindIndex(); + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(chr) { + * return chr.user == 'pebbles'; + * }); + * // => 2 + * + * // using the `_.matches` callback shorthand + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastIndex(users, 'active', false); + * // => 2 + * + * // using the `_.property` callback shorthand + * _.findLastIndex(users, 'active'); + * // => 0 + */ + var findLastIndex = createFindIndex(true); + + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @alias head + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([]); + * // => undefined + */ + function first(array) { + return array ? array[0] : undefined; + } + + /** + * Flattens a nested array. If `isDeep` is `true` the array is recursively + * flattened, otherwise it is only flattened a single level. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @param {boolean} [isDeep] Specify a deep flatten. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, 3, [4]]]); + * // => [1, 2, 3, [4]] + * + * // using `isDeep` + * _.flatten([1, [2, 3, [4]]], true); + * // => [1, 2, 3, 4] + */ + function flatten(array, isDeep, guard) { + var length = array ? array.length : 0; + if (guard && isIterateeCall(array, isDeep, guard)) { + isDeep = false; + } + return length ? baseFlatten(array, isDeep) : []; + } + + /** + * Recursively flattens a nested array. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to recursively flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, 3, [4]]]); + * // => [1, 2, 3, 4] + */ + function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, true) : []; + } + + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it is used as the offset + * from the end of `array`. If `array` is sorted providing `true` for `fromIndex` + * performs a faster binary search. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // using `fromIndex` + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + * + * // performing a binary search + * _.indexOf([1, 1, 2, 2], 2, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + if (typeof fromIndex == 'number') { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; + } else if (fromIndex) { + var index = binaryIndex(array, value); + if (index < length && + (value === value ? (value === array[index]) : (array[index] !== array[index]))) { + return index; + } + return -1; + } + return baseIndexOf(array, value, fromIndex || 0); + } + + /** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ + function initial(array) { + return dropRight(array, 1); + } + + /** + * Creates an array of unique values that are included in all of the provided + * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of shared values. + * @example + * _.intersection([1, 2], [4, 2], [2, 1]); + * // => [2] + */ + var intersection = restParam(function(arrays) { + var othLength = arrays.length, + othIndex = othLength, + caches = Array(length), + indexOf = getIndexOf(), + isCommon = indexOf == baseIndexOf, + result = []; + + while (othIndex--) { + var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : []; + caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null; + } + var array = arrays[0], + index = -1, + length = array ? array.length : 0, + seen = caches[0]; + + outer: + while (++index < length) { + value = array[index]; + if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) { + var othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) { + continue outer; + } + } + if (seen) { + seen.push(value); + } + result.push(value); + } + } + return result; + }); + + /** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ + function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; + } + + /** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=array.length-1] The index to search from + * or `true` to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // using `fromIndex` + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + * + * // performing a binary search + * _.lastIndexOf([1, 1, 2, 2], 2, true); + * // => 3 + */ + function lastIndexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + var index = length; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1; + } else if (fromIndex) { + index = binaryIndex(array, value, true) - 1; + var other = array[index]; + if (value === value ? (value === other) : (other !== other)) { + return index; + } + return -1; + } + if (value !== value) { + return indexOfNaN(array, index, true); + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Removes all provided values from `array` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.without`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...*} [values] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ + function pull() { + var args = arguments, + array = args[0]; + + if (!(array && array.length)) { + return array; + } + var index = 0, + indexOf = getIndexOf(), + length = args.length; + + while (++index < length) { + var fromIndex = 0, + value = args[index]; + + while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { + splice.call(array, fromIndex, 1); + } + } + return array; + } + + /** + * Removes elements from `array` corresponding to the given indexes and returns + * an array of the removed elements. Indexes may be specified as an array of + * indexes or as individual arguments. + * + * **Note:** Unlike `_.at`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...(number|number[])} [indexes] The indexes of elements to remove, + * specified as individual indexes or arrays of indexes. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [5, 10, 15, 20]; + * var evens = _.pullAt(array, 1, 3); + * + * console.log(array); + * // => [5, 15] + * + * console.log(evens); + * // => [10, 20] + */ + var pullAt = restParam(function(array, indexes) { + indexes = baseFlatten(indexes); + + var result = baseAt(array, indexes); + basePullAt(array, indexes.sort(baseCompareAscending)); + return result; + }); + + /** + * Removes all elements from `array` that `predicate` returns truthy for + * and returns an array of the removed elements. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * **Note:** Unlike `_.filter`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4]; + * var evens = _.remove(array, function(n) { + * return n % 2 == 0; + * }); + * + * console.log(array); + * // => [1, 3] + * + * console.log(evens); + * // => [2, 4] + */ + function remove(array, predicate, thisArg) { + var result = []; + if (!(array && array.length)) { + return result; + } + var index = -1, + indexes = [], + length = array.length; + + predicate = getCallback(predicate, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result.push(value); + indexes.push(index); + } + } + basePullAt(array, indexes); + return result; + } + + /** + * Gets all but the first element of `array`. + * + * @static + * @memberOf _ + * @alias tail + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + */ + function rest(array) { + return drop(array, 1); + } + + /** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of `Array#slice` to support node + * lists in IE < 9 and to ensure dense arrays are returned. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function slice(array, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; + } + return baseSlice(array, start, end); + } + + /** + * Uses a binary search to determine the lowest index at which `value` should + * be inserted into `array` in order to maintain its sort order. If an iteratee + * function is provided it is invoked for `value` and each element of `array` + * to compute their sort ranking. The iteratee is bound to `thisArg` and + * invoked with one argument; (value). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + * + * _.sortedIndex([4, 4, 5, 5], 5); + * // => 2 + * + * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; + * + * // using an iteratee function + * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { + * return this.data[word]; + * }, dict); + * // => 1 + * + * // using the `_.property` callback shorthand + * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 1 + */ + var sortedIndex = createSortedIndex(); + + /** + * This method is like `_.sortedIndex` except that it returns the highest + * index at which `value` should be inserted into `array` in order to + * maintain its sort order. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedLastIndex([4, 4, 5, 5], 5); + * // => 4 + */ + var sortedLastIndex = createSortedIndex(true); + + /** + * Creates a slice of `array` with `n` elements taken from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.take([1, 2, 3]); + * // => [1] + * + * _.take([1, 2, 3], 2); + * // => [1, 2] + * + * _.take([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.take([1, 2, 3], 0); + * // => [] + */ + function take(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements taken from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRight([1, 2, 3]); + * // => [3] + * + * _.takeRight([1, 2, 3], 2); + * // => [2, 3] + * + * _.takeRight([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.takeRight([1, 2, 3], 0); + * // => [] + */ + function takeRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with elements taken from the end. Elements are + * taken until `predicate` returns falsey. The predicate is bound to `thisArg` + * and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [2, 3] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active'), 'user'); + * // => [] + */ + function takeRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true) + : []; + } + + /** + * Creates a slice of `array` with elements taken from the beginning. Elements + * are taken until `predicate` returns falsey. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [1, 2] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false}, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeWhile(users, 'active', false), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeWhile(users, 'active'), 'user'); + * // => [] + */ + function takeWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3)) + : []; + } + + /** + * Creates an array of unique values, in order, from all of the provided arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([1, 2], [4, 2], [2, 1]); + * // => [1, 2, 4] + */ + var union = restParam(function(arrays) { + return baseUniq(baseFlatten(arrays, false, true)); + }); + + /** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurence of each element + * is kept. Providing `true` for `isSorted` performs a faster search algorithm + * for sorted arrays. If an iteratee function is provided it is invoked for + * each element in the array to generate the criterion by which uniqueness + * is computed. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index, array). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Array + * @param {Array} array The array to inspect. + * @param {boolean} [isSorted] Specify the array is sorted. + * @param {Function|Object|string} [iteratee] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new duplicate-value-free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + * + * // using `isSorted` + * _.uniq([1, 1, 2], true); + * // => [1, 2] + * + * // using an iteratee function + * _.uniq([1, 2.5, 1.5, 2], function(n) { + * return this.floor(n); + * }, Math); + * // => [1, 2.5] + * + * // using the `_.property` callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniq(array, isSorted, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (isSorted != null && typeof isSorted != 'boolean') { + thisArg = iteratee; + iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted; + isSorted = false; + } + var callback = getCallback(); + if (!(iteratee == null && callback === baseCallback)) { + iteratee = callback(iteratee, thisArg, 3); + } + return (isSorted && getIndexOf() == baseIndexOf) + ? sortedUniq(array, iteratee) + : baseUniq(array, iteratee); + } + + /** + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-zip + * configuration. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + * + * _.unzip(zipped); + * // => [['fred', 'barney'], [30, 40], [true, false]] + */ + function unzip(array) { + if (!(array && array.length)) { + return []; + } + var index = -1, + length = 0; + + array = arrayFilter(array, function(group) { + if (isArrayLike(group)) { + length = nativeMax(group.length, length); + return true; + } + }); + var result = Array(length); + while (++index < length) { + result[index] = arrayMap(array, baseProperty(index)); + } + return result; + } + + /** + * This method is like `_.unzip` except that it accepts an iteratee to specify + * how regrouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @param {Function} [iteratee] The function to combine regrouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip([1, 2], [10, 20], [100, 200]); + * // => [[1, 10, 100], [2, 20, 200]] + * + * _.unzipWith(zipped, _.add); + * // => [3, 30, 300] + */ + function unzipWith(array, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + var result = unzip(array); + if (iteratee == null) { + return result; + } + iteratee = bindCallback(iteratee, thisArg, 4); + return arrayMap(result, function(group) { + return arrayReduce(group, iteratee, undefined, true); + }); + } + + /** + * Creates an array excluding all provided values using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to filter. + * @param {...*} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.without([1, 2, 1, 3], 1, 2); + * // => [3] + */ + var without = restParam(function(array, values) { + return isArrayLike(array) + ? baseDifference(array, values) + : []; + }); + + /** + * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) + * of the provided arrays. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of values. + * @example + * + * _.xor([1, 2], [4, 2]); + * // => [1, 4] + */ + function xor() { + var index = -1, + length = arguments.length; + + while (++index < length) { + var array = arguments[index]; + if (isArrayLike(array)) { + var result = result + ? arrayPush(baseDifference(result, array), baseDifference(array, result)) + : array; + } + } + return result ? baseUniq(result) : []; + } + + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second elements + * of the given arrays, and so on. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + var zip = restParam(unzip); + + /** + * The inverse of `_.pairs`; this method returns an object composed from arrays + * of property names and values. Provide either a single two dimensional array, + * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names + * and one of corresponding values. + * + * @static + * @memberOf _ + * @alias object + * @category Array + * @param {Array} props The property names. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject([['fred', 30], ['barney', 40]]); + * // => { 'fred': 30, 'barney': 40 } + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ + function zipObject(props, values) { + var index = -1, + length = props ? props.length : 0, + result = {}; + + if (length && !values && !isArray(props[0])) { + values = []; + } + while (++index < length) { + var key = props[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; + } + + /** + * This method is like `_.zip` except that it accepts an iteratee to specify + * how grouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @param {Function} [iteratee] The function to combine grouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zipWith([1, 2], [10, 20], [100, 200], _.add); + * // => [111, 222] + */ + var zipWith = restParam(function(arrays) { + var length = arrays.length, + iteratee = length > 2 ? arrays[length - 2] : undefined, + thisArg = length > 1 ? arrays[length - 1] : undefined; + + if (length > 2 && typeof iteratee == 'function') { + length -= 2; + } else { + iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined; + thisArg = undefined; + } + arrays.length = length; + return unzipWith(arrays, iteratee, thisArg); + }); + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object that wraps `value` with explicit method + * chaining enabled. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _.chain(users) + * .sortBy('age') + * .map(function(chr) { + * return chr.user + ' is ' + chr.age; + * }) + * .first() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; + } + + /** + * This method invokes `interceptor` and returns `value`. The interceptor is + * bound to `thisArg` and invoked with one argument; (value). The purpose of + * this method is to "tap into" a method chain in order to perform operations + * on intermediate results within the chain. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ + function tap(value, interceptor, thisArg) { + interceptor.call(thisArg, value); + return value; + } + + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ + function thru(value, interceptor, thisArg) { + return interceptor.call(thisArg, value); + } + + /** + * Enables explicit method chaining on the wrapper object. + * + * @name chain + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // without explicit chaining + * _(users).first(); + * // => { 'user': 'barney', 'age': 36 } + * + * // with explicit chaining + * _(users).chain() + * .first() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ + function wrapperChain() { + return chain(this); + } + + /** + * Executes the chained sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ + function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); + } + + /** + * Creates a new array joining a wrapped array with any additional arrays + * and/or values. + * + * @name concat + * @memberOf _ + * @category Chain + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var wrapped = _(array).concat(2, [3], [[4]]); + * + * console.log(wrapped.value()); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + var wrapperConcat = restParam(function(values) { + values = baseFlatten(values); + return this.thru(function(array) { + return arrayConcat(isArray(array) ? array : [toObject(array)], values); + }); + }); + + /** + * Creates a clone of the chained sequence planting `value` as the wrapped value. + * + * @name plant + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).map(function(value) { + * return Math.pow(value, 2); + * }); + * + * var other = [3, 4]; + * var otherWrapped = wrapped.plant(other); + * + * otherWrapped.value(); + * // => [9, 16] + * + * wrapped.value(); + * // => [1, 4] + */ + function wrapperPlant(value) { + var result, + parent = this; + + while (parent instanceof baseLodash) { + var clone = wrapperClone(parent); + if (result) { + previous.__wrapped__ = clone; + } else { + result = clone; + } + var previous = clone; + parent = parent.__wrapped__; + } + previous.__wrapped__ = value; + return result; + } + + /** + * Reverses the wrapped array so the first element becomes the last, the + * second element becomes the second to last, and so on. + * + * **Note:** This method mutates the wrapped array. + * + * @name reverse + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new reversed `lodash` wrapper instance. + * @example + * + * var array = [1, 2, 3]; + * + * _(array).reverse().value() + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function wrapperReverse() { + var value = this.__wrapped__; + + var interceptor = function(value) { + return (wrapped && wrapped.__dir__ < 0) ? value : value.reverse(); + }; + if (value instanceof LazyWrapper) { + var wrapped = value; + if (this.__actions__.length) { + wrapped = new LazyWrapper(this); + } + wrapped = wrapped.reverse(); + wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); + return new LodashWrapper(wrapped, this.__chain__); + } + return this.thru(interceptor); + } + + /** + * Produces the result of coercing the unwrapped value to a string. + * + * @name toString + * @memberOf _ + * @category Chain + * @returns {string} Returns the coerced string value. + * @example + * + * _([1, 2, 3]).toString(); + * // => '1,2,3' + */ + function wrapperToString() { + return (this.value() + ''); + } + + /** + * Executes the chained sequence to extract the unwrapped value. + * + * @name value + * @memberOf _ + * @alias run, toJSON, valueOf + * @category Chain + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements corresponding to the given keys, or indexes, + * of `collection`. Keys may be specified as individual arguments or as arrays + * of keys. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [props] The property names + * or indexes of elements to pick, specified individually or in arrays. + * @returns {Array} Returns the new array of picked elements. + * @example + * + * _.at(['a', 'b', 'c'], [0, 2]); + * // => ['a', 'c'] + * + * _.at(['barney', 'fred', 'pebbles'], 0, 2); + * // => ['barney', 'pebbles'] + */ + var at = restParam(function(collection, props) { + return baseAt(collection, baseFlatten(props)); + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the number of times the key was returned by `iteratee`. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return Math.floor(n); + * }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); + }); + + /** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * The predicate is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.every(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.every(users, 'active'); + * // => false + */ + function every(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = getCallback(predicate, thisArg, 3); + } + return func(collection, predicate); + } + + /** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.filter([4, 5, 6], function(n) { + * return n % 2 == 0; + * }); + * // => [4, 6] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.filter(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.filter(users, 'active'), 'user'); + * // => ['barney'] + */ + function filter(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getCallback(predicate, thisArg, 3); + return func(collection, predicate); + } + + /** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias detect + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.result(_.find(users, function(chr) { + * return chr.age < 40; + * }), 'user'); + * // => 'barney' + * + * // using the `_.matches` callback shorthand + * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); + * // => 'pebbles' + * + * // using the `_.matchesProperty` callback shorthand + * _.result(_.find(users, 'active', false), 'user'); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.result(_.find(users, 'active'), 'user'); + * // => 'barney' + */ + var find = createFind(baseEach); + + /** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 + */ + var findLast = createFind(baseEachRight, true); + + /** + * Performs a deep comparison between each element in `collection` and the + * source object, returning the first element that has equivalent property + * values. + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); + * // => 'barney' + * + * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); + * // => 'fred' + */ + function findWhere(collection, source) { + return find(collection, baseMatches(source)); + } + + /** + * Iterates over elements of `collection` invoking `iteratee` for each element. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). Iteratee functions may exit iteration early + * by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2]).forEach(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from left to right and returns the array + * + * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { + * console.log(n, key); + * }); + * // => logs each value-key pair and returns the object (iteration order is not guaranteed) + */ + var forEach = createForEach(arrayEach, baseEach); + + /** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2]).forEachRight(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from right to left and returns the array + */ + var forEachRight = createForEach(arrayEachRight, baseEachRight); + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return Math.floor(n); + * }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using the `_.property` callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + result[key] = [value]; + } + }); + + /** + * Checks if `value` is in `collection` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it is used as the offset + * from the end of `collection`. + * + * @static + * @memberOf _ + * @alias contains, include + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {*} target The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {boolean} Returns `true` if a matching element is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.includes('pebbles', 'eb'); + * // => true + */ + function includes(collection, target, fromIndex, guard) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + collection = values(collection); + length = collection.length; + } + if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { + fromIndex = 0; + } else { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); + } + return (typeof collection == 'string' || !isArray(collection) && isString(collection)) + ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) + : (!!length && getIndexOf(collection, target, fromIndex) > -1); + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the last element responsible for generating the key. The + * iteratee function is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keyData = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keyData, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return String.fromCharCode(object.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return this.fromCharCode(object.code); + * }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Invokes the method at `path` of each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `methodName` is a function it is + * invoked for, and `this` bound to, each element in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|string} path The path of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + var invoke = restParam(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + isProp = isKey(path), + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value) { + var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); + result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); + }); + return result; + }); + + /** + * Creates an array of values by running each element in `collection` through + * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, + * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, + * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, + * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, + * `sum`, `uniq`, and `words` + * + * @static + * @memberOf _ + * @alias collect + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new mapped array. + * @example + * + * function timesThree(n) { + * return n * 3; + * } + * + * _.map([1, 2], timesThree); + * // => [3, 6] + * + * _.map({ 'a': 1, 'b': 2 }, timesThree); + * // => [3, 6] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // using the `_.property` callback shorthand + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ + function map(collection, iteratee, thisArg) { + var func = isArray(collection) ? arrayMap : baseMap; + iteratee = getCallback(iteratee, thisArg, 3); + return func(collection, iteratee); + } + + /** + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, while the second of which + * contains elements `predicate` returns falsey for. The predicate is bound + * to `thisArg` and invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the array of grouped elements. + * @example + * + * _.partition([1, 2, 3], function(n) { + * return n % 2; + * }); + * // => [[1, 3], [2]] + * + * _.partition([1.2, 2.3, 3.4], function(n) { + * return this.floor(n) % 2; + * }, Math); + * // => [[1.2, 3.4], [2.3]] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * var mapper = function(array) { + * return _.pluck(array, 'user'); + * }; + * + * // using the `_.matches` callback shorthand + * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper); + * // => [['pebbles'], ['barney', 'fred']] + * + * // using the `_.matchesProperty` callback shorthand + * _.map(_.partition(users, 'active', false), mapper); + * // => [['barney', 'pebbles'], ['fred']] + * + * // using the `_.property` callback shorthand + * _.map(_.partition(users, 'active'), mapper); + * // => [['fred'], ['barney', 'pebbles']] + */ + var partition = createAggregator(function(result, value, key) { + result[key ? 0 : 1].push(value); + }, function() { return [[], []]; }); + + /** + * Gets the property value of `path` from all elements in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|string} path The path of the property to pluck. + * @returns {Array} Returns the property values. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * _.pluck(users, 'user'); + * // => ['barney', 'fred'] + * + * var userIndex = _.indexBy(users, 'user'); + * _.pluck(userIndex, 'age'); + * // => [36, 40] (iteration order is not guaranteed) + */ + function pluck(collection, path) { + return map(collection, property(path)); + } + + /** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` through `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not provided the first element of `collection` is used as the initial + * value. The `iteratee` is bound to `thisArg` and invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`, + * and `sortByOrder` + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * _.reduce([1, 2], function(total, n) { + * return total + n; + * }); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { + * result[key] = n * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) + */ + var reduce = createReduce(arrayReduce, baseEach); + + /** + * This method is like `_.reduce` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * var array = [[0, 1], [2, 3], [4, 5]]; + * + * _.reduceRight(array, function(flattened, other) { + * return flattened.concat(other); + * }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + var reduceRight = createReduce(arrayReduceRight, baseEachRight); + + /** + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.reject([1, 2, 3, 4], function(n) { + * return n % 2 == 0; + * }); + * // => [1, 3] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.reject(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.reject(users, 'active'), 'user'); + * // => ['barney'] + */ + function reject(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getCallback(predicate, thisArg, 3); + return func(collection, function(value, index, collection) { + return !predicate(value, index, collection); + }); + } + + /** + * Gets a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {*} Returns the random sample(s). + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ + function sample(collection, n, guard) { + if (guard ? isIterateeCall(collection, n, guard) : n == null) { + collection = toIterable(collection); + var length = collection.length; + return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; + } + var index = -1, + result = toArray(collection), + length = result.length, + lastIndex = length - 1; + + n = nativeMin(n < 0 ? 0 : (+n || 0), length); + while (++index < n) { + var rand = baseRandom(index, lastIndex), + value = result[rand]; + + result[rand] = result[index]; + result[index] = value; + } + result.length = n; + return result; + } + + /** + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + * @example + * + * _.shuffle([1, 2, 3, 4]); + * // => [4, 1, 3, 2] + */ + function shuffle(collection) { + return sample(collection, POSITIVE_INFINITY); + } + + /** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the size of `collection`. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + var length = collection ? getLength(collection) : 0; + return isLength(length) ? length : keys(collection).length; + } + + /** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * The function returns as soon as it finds a passing value and does not iterate + * over the entire collection. The predicate is bound to `thisArg` and invoked + * with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.some(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.some(users, 'active'); + * // => true + */ + function some(collection, predicate, thisArg) { + var func = isArray(collection) ? arraySome : baseSome; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = getCallback(predicate, thisArg, 3); + } + return func(collection, predicate); + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through `iteratee`. This method performs + * a stable sort, that is, it preserves the original sort order of equal elements. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new sorted array. + * @example + * + * _.sortBy([1, 2, 3], function(n) { + * return Math.sin(n); + * }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(n) { + * return this.sin(n); + * }, Math); + * // => [3, 1, 2] + * + * var users = [ + * { 'user': 'fred' }, + * { 'user': 'pebbles' }, + * { 'user': 'barney' } + * ]; + * + * // using the `_.property` callback shorthand + * _.pluck(_.sortBy(users, 'user'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function sortBy(collection, iteratee, thisArg) { + if (collection == null) { + return []; + } + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = undefined; + } + var index = -1; + iteratee = getCallback(iteratee, thisArg, 3); + + var result = baseMap(collection, function(value, key, collection) { + return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value }; + }); + return baseSortBy(result, compareAscending); + } + + /** + * This method is like `_.sortBy` except that it can sort by multiple iteratees + * or property names. + * + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees + * The iteratees to sort by, specified as individual values or arrays of values. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.map(_.sortByAll(users, ['user', 'age']), _.values); + * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * + * _.map(_.sortByAll(users, 'user', function(chr) { + * return Math.floor(chr.age / 10); + * }), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + var sortByAll = restParam(function(collection, iteratees) { + if (collection == null) { + return []; + } + var guard = iteratees[2]; + if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) { + iteratees.length = 1; + } + return baseSortByOrder(collection, baseFlatten(iteratees), []); + }); + + /** + * This method is like `_.sortByAll` except that it allows specifying the + * sort orders of the iteratees to sort by. If `orders` is unspecified, all + * values are sorted in ascending order. Otherwise, a value is sorted in + * ascending order if its corresponding order is "asc", and descending if "desc". + * + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {boolean[]} [orders] The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 36 } + * ]; + * + * // sort by `user` in ascending order and by `age` in descending order + * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + function sortByOrder(collection, iteratees, orders, guard) { + if (collection == null) { + return []; + } + if (guard && isIterateeCall(iteratees, orders, guard)) { + orders = undefined; + } + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; + } + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; + } + return baseSortByOrder(collection, iteratees, orders); + } + + /** + * Performs a deep comparison between each element in `collection` and the + * source object, returning an array of all elements that have equivalent + * property values. + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] }, + * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); + * // => ['barney'] + * + * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); + * // => ['fred'] + */ + function where(collection, source) { + return filter(collection, baseMatches(source)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @category Date + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => logs the number of milliseconds it took for the deferred function to be invoked + */ + var now = nativeNow || function() { + return new Date().getTime(); + }; + + /*------------------------------------------------------------------------*/ + + /** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it is called `n` or more times. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'done saving!' after the two async saves have completed + */ + function after(n, func) { + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } + } + n = nativeIsFinite(n = +n) ? n : 0; + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that accepts up to `n` arguments ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] + */ + function ary(func, n, guard) { + if (guard && isIterateeCall(func, n, guard)) { + n = undefined; + } + n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); + return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); + } + + /** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it is called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery('#add').on('click', _.before(5, addContactToList)); + * // => allows adding up to 4 contacts to the list + */ + function before(n, func) { + var result; + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } + } + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and prepends any additional `_.bind` arguments to those provided to the + * bound function. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind` this method does not set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var greet = function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * }; + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // using placeholders + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ + var bind = restParam(function(func, thisArg, partials) { + var bitmask = BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bind.placeholder); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(func, bitmask, thisArg, partials, holders); + }); + + /** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all enumerable function + * properties, own and inherited, of `object` are bound. + * + * **Note:** This method does not set the "length" property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...(string|string[])} [methodNames] The object method names to bind, + * specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { + * console.log('clicked ' + this.label); + * } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs' when the element is clicked + */ + var bindAll = restParam(function(object, methodNames) { + methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object); + + var index = -1, + length = methodNames.length; + + while (++index < length) { + var key = methodNames[index]; + object[key] = createWrapper(object[key], BIND_FLAG, object); + } + return object; + }); + + /** + * Creates a function that invokes the method at `object[key]` and prepends + * any additional `_.bindKey` arguments to those provided to the bound function. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. + * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // using placeholders + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ + var bindKey = restParam(function(object, key, partials) { + var bitmask = BIND_FLAG | BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bindKey.placeholder); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(key, bitmask, object, partials, holders); + }); + + /** + * Creates a function that accepts one or more arguments of `func` that when + * called either invokes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` may be specified + * if `func.length` is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(1)(_, 3)(2); + * // => [1, 2, 3] + */ + var curry = createCurry(CURRY_FLAG); + + /** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(3)(1, _)(2); + * // => [1, 2, 3] + */ + var curryRight = createCurry(CURRY_RIGHT_FLAG); + + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed invocations. Provide an options object to indicate that `func` + * should be invoked on the leading and/or trailing edge of the `wait` timeout. + * Subsequent calls to the debounced function return the result of the last + * `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify invoking on the leading + * edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be + * delayed before it is invoked. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // invoke `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // ensure `batchLog` is invoked once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * jQuery(source).on('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * })); + * + * // cancel a debounced call + * var todoChanges = _.debounce(batchLog, 1000); + * Object.observe(models.todo, todoChanges); + * + * Object.observe(models, function(changes) { + * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { + * todoChanges.cancel(); + * } + * }, ['delete']); + * + * // ...at some point `models.todo` is changed + * models.todo.completed = true; + * + * // ...before 1 second has passed `models.todo` is deleted + * // which cancels the debounced `todoChanges` call + * delete models.todo; + */ + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = wait < 0 ? 0 : (+wait || 0); + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = !!options.leading; + maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function cancel() { + if (timeoutId) { + clearTimeout(timeoutId); + } + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + lastCalled = 0; + maxTimeoutId = timeoutId = trailingCall = undefined; + } + + function complete(isCalled, id) { + if (id) { + clearTimeout(id); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + } + } + + function delayed() { + var remaining = wait - (now() - stamp); + if (remaining <= 0 || remaining > wait) { + complete(trailingCall, maxTimeoutId); + } else { + timeoutId = setTimeout(delayed, remaining); + } + } + + function maxDelayed() { + complete(trailing, timeoutId); + } + + function debounced() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0 || remaining > maxWait; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + return result; + } + debounced.cancel = cancel; + return debounced; + } + + /** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // logs 'deferred' after one or more milliseconds + */ + var defer = restParam(function(func, args) { + return baseDelay(func, 1, args); + }); + + /** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => logs 'later' after one second + */ + var delay = restParam(function(func, wait, args) { + return baseDelay(func, wait, args); + }); + + /** + * Creates a function that returns the result of invoking the provided + * functions with the `this` binding of the created function, where each + * successive invocation is supplied the return value of the previous. + * + * @static + * @memberOf _ + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flow(_.add, square); + * addSquare(1, 2); + * // => 9 + */ + var flow = createFlow(); + + /** + * This method is like `_.flow` except that it creates a function that + * invokes the provided functions from right to left. + * + * @static + * @memberOf _ + * @alias backflow, compose + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flowRight(square, _.add); + * addSquare(1, 2); + * // => 9 + */ + var flowRight = createFlow(true); + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is coerced to a string and used as the + * cache key. The `func` is invoked with the `this` binding of the memoized + * function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) + * method interface of `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var upperCase = _.memoize(function(string) { + * return string.toUpperCase(); + * }); + * + * upperCase('fred'); + * // => 'FRED' + * + * // modifying the result cache + * upperCase.cache.set('fred', 'BARNEY'); + * upperCase('fred'); + * // => 'BARNEY' + * + * // replacing `_.memoize.Cache` + * var object = { 'user': 'fred' }; + * var other = { 'user': 'barney' }; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'fred' } + * + * _.memoize.Cache = WeakMap; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'barney' } + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result); + return result; + }; + memoized.cache = new memoize.Cache; + return memoized; + } + + /** + * Creates a function that runs each argument through a corresponding + * transform function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to wrap. + * @param {...(Function|Function[])} [transforms] The functions to transform + * arguments, specified as individual functions or arrays of functions. + * @returns {Function} Returns the new function. + * @example + * + * function doubled(n) { + * return n * 2; + * } + * + * function square(n) { + * return n * n; + * } + * + * var modded = _.modArgs(function(x, y) { + * return [x, y]; + * }, square, doubled); + * + * modded(1, 2); + * // => [1, 4] + * + * modded(5, 10); + * // => [25, 20] + */ + var modArgs = restParam(function(func, transforms) { + transforms = baseFlatten(transforms); + if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = transforms.length; + return restParam(function(args) { + var index = nativeMin(args.length, length); + while (index--) { + args[index] = transforms[index](args[index]); + } + return func.apply(this, args); + }); + }); + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + return !predicate.apply(this, arguments); + }; + } + + /** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first call. The `func` is invoked + * with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` invokes `createApplication` once + */ + function once(func) { + return before(2, func); + } + + /** + * Creates a function that invokes `func` with `partial` arguments prepended + * to those provided to the new function. This method is like `_.bind` except + * it does **not** alter the `this` binding. + * + * The `_.partial.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method does not set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var sayHelloTo = _.partial(greet, 'hello'); + * sayHelloTo('fred'); + * // => 'hello fred' + * + * // using placeholders + * var greetFred = _.partial(greet, _, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + */ + var partial = createPartial(PARTIAL_FLAG); + + /** + * This method is like `_.partial` except that partially applied arguments + * are appended to those provided to the new function. + * + * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method does not set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var greetFred = _.partialRight(greet, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + * + * // using placeholders + * var sayHelloTo = _.partialRight(greet, 'hello', _); + * sayHelloTo('fred'); + * // => 'hello fred' + */ + var partialRight = createPartial(PARTIAL_RIGHT_FLAG); + + /** + * Creates a function that invokes `func` with arguments arranged according + * to the specified indexes where the argument value at the first index is + * provided as the first argument, the argument value at the second index is + * provided as the second argument, and so on. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to rearrange arguments for. + * @param {...(number|number[])} indexes The arranged argument indexes, + * specified as individual indexes or arrays of indexes. + * @returns {Function} Returns the new function. + * @example + * + * var rearged = _.rearg(function(a, b, c) { + * return [a, b, c]; + * }, 2, 0, 1); + * + * rearged('b', 'c', 'a') + * // => ['a', 'b', 'c'] + * + * var map = _.rearg(_.map, [1, 0]); + * map(function(n) { + * return n * 3; + * }, [1, 2, 3]); + * // => [3, 6, 9] + */ + var rearg = restParam(function(func, indexes) { + return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes)); + }); + + /** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as an array. + * + * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.restParam(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ + function restParam(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + rest = Array(length); + + while (++index < length) { + rest[index] = args[start + index]; + } + switch (start) { + case 0: return func.call(this, rest); + case 1: return func.call(this, args[0], rest); + case 2: return func.call(this, args[0], args[1], rest); + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = rest; + return func.apply(this, otherArgs); + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of the created + * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). + * + * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to spread arguments over. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.spread(function(who, what) { + * return who + ' says ' + what; + * }); + * + * say(['fred', 'hello']); + * // => 'fred says hello' + * + * // with a Promise + * var numbers = Promise.all([ + * Promise.resolve(40), + * Promise.resolve(36) + * ]); + * + * numbers.then(_.spread(function(x, y) { + * return x + y; + * })); + * // => a Promise of 76 + */ + function spread(func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function(array) { + return func.apply(this, array); + }; + } + + /** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed invocations. Provide an options object to indicate + * that `func` should be invoked on the leading and/or trailing edge of the + * `wait` timeout. Subsequent calls to the throttled function return the + * result of the last `func` call. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify invoking on the leading + * edge of the timeout. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // avoid excessively updating the position while scrolling + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + * + * // cancel a trailing throttled call + * jQuery(window).on('popstate', throttled.cancel); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing }); + } + + /** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Any additional arguments provided to the function are + * appended to those provided to the wrapper function. The wrapper is invoked + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

          ' + func(text) + '

          '; + * }); + * + * p('fred, barney, & pebbles'); + * // => '

          fred, barney, & pebbles

          ' + */ + function wrap(value, wrapper) { + wrapper = wrapper == null ? identity : wrapper; + return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned, + * otherwise they are assigned by reference. If `customizer` is provided it is + * invoked to produce the cloned values. If `customizer` returns `undefined` + * cloning is handled by the method instead. The `customizer` is bound to + * `thisArg` and invoked with two argument; (value [, index|key, object]). + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). + * The enumerable properties of `arguments` objects and objects created by + * constructors other than `Object` are cloned to plain `Object` objects. An + * empty object is returned for uncloneable values such as functions, DOM nodes, + * Maps, Sets, and WeakMaps. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {*} Returns the cloned value. + * @example + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * var shallow = _.clone(users); + * shallow[0] === users[0]; + * // => true + * + * var deep = _.clone(users, true); + * deep[0] === users[0]; + * // => false + * + * // using a customizer callback + * var el = _.clone(document.body, function(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * }); + * + * el === document.body + * // => false + * el.nodeName + * // => BODY + * el.childNodes.length; + * // => 0 + */ + function clone(value, isDeep, customizer, thisArg) { + if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) { + isDeep = false; + } + else if (typeof isDeep == 'function') { + thisArg = customizer; + customizer = isDeep; + isDeep = false; + } + return typeof customizer == 'function' + ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 1)) + : baseClone(value, isDeep); + } + + /** + * Creates a deep clone of `value`. If `customizer` is provided it is invoked + * to produce the cloned values. If `customizer` returns `undefined` cloning + * is handled by the method instead. The `customizer` is bound to `thisArg` + * and invoked with two argument; (value [, index|key, object]). + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). + * The enumerable properties of `arguments` objects and objects created by + * constructors other than `Object` are cloned to plain `Object` objects. An + * empty object is returned for uncloneable values such as functions, DOM nodes, + * Maps, Sets, and WeakMaps. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {*} Returns the deep cloned value. + * @example + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * var deep = _.cloneDeep(users); + * deep[0] === users[0]; + * // => false + * + * // using a customizer callback + * var el = _.cloneDeep(document.body, function(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * }); + * + * el === document.body + * // => false + * el.nodeName + * // => BODY + * el.childNodes.length; + * // => 20 + */ + function cloneDeep(value, customizer, thisArg) { + return typeof customizer == 'function' + ? baseClone(value, true, bindCallback(customizer, thisArg, 1)) + : baseClone(value, true); + } + + /** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`. + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ + function gt(value, other) { + return value > other; + } + + /** + * Checks if `value` is greater than or equal to `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`. + * @example + * + * _.gte(3, 1); + * // => true + * + * _.gte(3, 3); + * // => true + * + * _.gte(1, 3); + * // => false + */ + function gte(value, other) { + return value >= other; + } + + /** + * Checks if `value` is classified as an `arguments` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + return isObjectLike(value) && isArrayLike(value) && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(function() { return arguments; }()); + * // => false + */ + var isArray = nativeIsArray || function(value) { + return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; + }; + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag); + } + + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ + function isDate(value) { + return isObjectLike(value) && objToString.call(value) == dateTag; + } + + /** + * Checks if `value` is a DOM element. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false + */ + function isElement(value) { + return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); + } + + /** + * Checks if `value` is empty. A value is considered empty unless it is an + * `arguments` object, array, string, or jQuery-like collection with a length + * greater than `0` or an object with own enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ + function isEmpty(value) { + if (value == null) { + return true; + } + if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) || + (isObjectLike(value) && isFunction(value.splice)))) { + return !value.length; + } + return !keys(value).length; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. If `customizer` is provided it is invoked to compare values. + * If `customizer` returns `undefined` comparisons are handled by the method + * instead. The `customizer` is bound to `thisArg` and invoked with three + * arguments: (value, other [, index|key]). + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. Functions and DOM nodes + * are **not** supported. Provide a customizer function to extend support + * for comparing other values. + * + * @static + * @memberOf _ + * @alias eq + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize value comparisons. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * object == other; + * // => false + * + * _.isEqual(object, other); + * // => true + * + * // using a customizer callback + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqual(array, other, function(value, other) { + * if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) { + * return true; + * } + * }); + * // => true + */ + function isEqual(value, other, customizer, thisArg) { + customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; + var result = customizer ? customizer(value, other) : undefined; + return result === undefined ? baseIsEqual(value, other, customizer) : !!result; + } + + /** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ + function isError(value) { + return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag; + } + + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(10); + * // => true + * + * _.isFinite('10'); + * // => false + * + * _.isFinite(true); + * // => false + * + * _.isFinite(Object(10)); + * // => false + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in older versions of Chrome and Safari which return 'function' for regexes + // and Safari 8 equivalents which return 'object' for typed array constructors. + return isObject(value) && objToString.call(value) == funcTag; + } + + /** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ + function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Performs a deep comparison between `object` and `source` to determine if + * `object` contains equivalent property values. If `customizer` is provided + * it is invoked to compare values. If `customizer` returns `undefined` + * comparisons are handled by the method instead. The `customizer` is bound + * to `thisArg` and invoked with three arguments: (value, other, index|key). + * + * **Note:** This method supports comparing properties of arrays, booleans, + * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions + * and DOM nodes are **not** supported. Provide a customizer function to extend + * support for comparing other values. + * + * @static + * @memberOf _ + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize value comparisons. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.isMatch(object, { 'age': 40 }); + * // => true + * + * _.isMatch(object, { 'age': 36 }); + * // => false + * + * // using a customizer callback + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatch(object, source, function(value, other) { + * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; + * }); + * // => true + */ + function isMatch(object, source, customizer, thisArg) { + customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; + return baseIsMatch(object, getMatchData(source), customizer); + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) + * which returns `true` for `undefined` and other non-numeric values. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some host objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is a native function. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ + function isNative(value) { + if (value == null) { + return false; + } + if (isFunction(value)) { + return reIsNative.test(fnToString.call(value)); + } + return isObjectLike(value) && reIsHostCtor.test(value); + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified + * as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isNumber(8.4); + * // => true + * + * _.isNumber(NaN); + * // => true + * + * _.isNumber('8.4'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag); + } + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * **Note:** This method assumes objects created by the `Object` constructor + * have no inherited enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + var Ctor; + + // Exit early for non `Object` objects. + if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) || + (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { + return false; + } + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + var result; + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + baseForIn(value, function(subValue, key) { + result = key; + }); + return result === undefined || hasOwnProperty.call(value, result); + } + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + function isRegExp(value) { + return isObject(value) && objToString.call(value) == regexpTag; + } + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); + } + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + function isTypedArray(value) { + return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * Checks if `value` is less than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`. + * @example + * + * _.lt(1, 3); + * // => true + * + * _.lt(3, 3); + * // => false + * + * _.lt(3, 1); + * // => false + */ + function lt(value, other) { + return value < other; + } + + /** + * Checks if `value` is less than or equal to `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`. + * @example + * + * _.lte(1, 3); + * // => true + * + * _.lte(3, 3); + * // => true + * + * _.lte(3, 1); + * // => false + */ + function lte(value, other) { + return value <= other; + } + + /** + * Converts `value` to an array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * (function() { + * return _.toArray(arguments).slice(1); + * }(1, 2, 3)); + * // => [2, 3] + */ + function toArray(value) { + var length = value ? getLength(value) : 0; + if (!isLength(length)) { + return values(value); + } + if (!length) { + return []; + } + return arrayCopy(value); + } + + /** + * Converts `value` to a plain object flattening inherited enumerable + * properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return baseCopy(value, keysIn(value)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * overwrite property assignments of previous sources. If `customizer` is + * provided it is invoked to produce the merged values of the destination and + * source properties. If `customizer` returns `undefined` merging is handled + * by the method instead. The `customizer` is bound to `thisArg` and invoked + * with five arguments: (objectValue, sourceValue, key, object, source). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. + * @example + * + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] + * }; + * + * var ages = { + * 'data': [{ 'age': 36 }, { 'age': 40 }] + * }; + * + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } + * + * // using a customizer callback + * var object = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var other = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(object, other, function(a, b) { + * if (_.isArray(a)) { + * return a.concat(b); + * } + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } + */ + var merge = createAssigner(baseMerge); + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources overwrite property assignments of previous sources. + * If `customizer` is provided it is invoked to produce the assigned values. + * The `customizer` is bound to `thisArg` and invoked with five arguments: + * (objectValue, sourceValue, key, object, source). + * + * **Note:** This method mutates `object` and is based on + * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign). + * + * @static + * @memberOf _ + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. + * @example + * + * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); + * // => { 'user': 'fred', 'age': 40 } + * + * // using a customizer callback + * var defaults = _.partialRight(_.assign, function(value, other) { + * return _.isUndefined(value) ? other : value; + * }); + * + * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var assign = createAssigner(function(object, source, customizer) { + return customizer + ? assignWith(object, source, customizer) + : baseAssign(object, source); + }); + + /** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties, guard) { + var result = baseCreate(prototype); + if (guard && isIterateeCall(prototype, properties, guard)) { + properties = undefined; + } + return properties ? baseAssign(result, properties) : result; + } + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var defaults = createDefaults(assign, assignDefaults); + + /** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } }); + * // => { 'user': { 'name': 'barney', 'age': 36 } } + * + */ + var defaultsDeep = createDefaults(merge, mergeDefaults); + + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(chr) { + * return chr.age < 40; + * }); + * // => 'barney' (iteration order is not guaranteed) + * + * // using the `_.matches` callback shorthand + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // using the `_.matchesProperty` callback shorthand + * _.findKey(users, 'active', false); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.findKey(users, 'active'); + * // => 'barney' + */ + var findKey = createFindKey(baseForOwn); + + /** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(chr) { + * return chr.age < 40; + * }); + * // => returns `pebbles` assuming `_.findKey` returns `barney` + * + * // using the `_.matches` callback shorthand + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastKey(users, 'active', false); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ + var findLastKey = createFindKey(baseForOwnRight); + + /** + * Iterates over own and inherited enumerable properties of an object invoking + * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed) + */ + var forIn = createForIn(baseFor); + + /** + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c' + */ + var forInRight = createForIn(baseForRight); + + /** + * Iterates over own enumerable properties of an object invoking `iteratee` + * for each property. The `iteratee` is bound to `thisArg` and invoked with + * three arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' and 'b' (iteration order is not guaranteed) + */ + var forOwn = createForOwn(baseForOwn); + + /** + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b' + */ + var forOwnRight = createForOwn(baseForOwnRight); + + /** + * Creates an array of function property names from all enumerable properties, + * own and inherited, of `object`. + * + * @static + * @memberOf _ + * @alias methods + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. + * @example + * + * _.functions(_); + * // => ['after', 'ary', 'assign', ...] + */ + function functions(object) { + return baseFunctions(object, keysIn(object)); + } + + /** + * Gets the property value at `path` of `object`. If the resolved value is + * `undefined` the `defaultValue` is used in its place. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, toPath(path), path + ''); + return result === undefined ? defaultValue : result; + } + + /** + * Checks if `path` is a direct property. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` is a direct property, else `false`. + * @example + * + * var object = { 'a': { 'b': { 'c': 3 } } }; + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b.c'); + * // => true + * + * _.has(object, ['a', 'b', 'c']); + * // => true + */ + function has(object, path) { + if (object == null) { + return false; + } + var result = hasOwnProperty.call(object, path); + if (!result && !isKey(path)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + if (object == null) { + return false; + } + path = last(path); + result = hasOwnProperty.call(object, path); + } + return result || (isLength(object.length) && isIndex(path, object.length) && + (isArray(object) || isArguments(object))); + } + + /** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite property + * assignments of previous values unless `multiValue` is `true`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to invert. + * @param {boolean} [multiValue] Allow multiple values per key. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + * + * // with `multiValue` + * _.invert(object, true); + * // => { '1': ['a', 'c'], '2': ['b'] } + */ + function invert(object, multiValue, guard) { + if (guard && isIterateeCall(object, multiValue, guard)) { + multiValue = undefined; + } + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index], + value = object[key]; + + if (multiValue) { + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + } + else { + result[value] = key; + } + } + return result; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + var keys = !nativeKeys ? shimKeys : function(object) { + var Ctor = object == null ? undefined : object.constructor; + if ((typeof Ctor == 'function' && Ctor.prototype === object) || + (typeof object != 'function' && isArrayLike(object))) { + return shimKeys(object); + } + return isObject(object) ? nativeKeys(object) : []; + }; + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + if (object == null) { + return []; + } + if (!isObject(object)) { + object = Object(object); + } + var length = object.length; + length = (length && isLength(length) && + (isArray(object) || isArguments(object)) && length) || 0; + + var Ctor = object.constructor, + index = -1, + isProto = typeof Ctor == 'function' && Ctor.prototype === object, + result = Array(length), + skipIndexes = length > 0; + + while (++index < length) { + result[index] = (index + ''); + } + for (var key in object) { + if (!(skipIndexes && isIndex(key, length)) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * property of `object` through `iteratee`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the new mapped object. + * @example + * + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } + */ + var mapKeys = createObjectMapper(true); + + /** + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through `iteratee`. The + * iteratee function is bound to `thisArg` and invoked with three arguments: + * (value, key, object). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the new mapped object. + * @example + * + * _.mapValues({ 'a': 1, 'b': 2 }, function(n) { + * return n * 3; + * }); + * // => { 'a': 3, 'b': 6 } + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * // using the `_.property` callback shorthand + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ + var mapValues = createObjectMapper(); + + /** + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable properties of `object` that are not omitted. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {Function|...(string|string[])} [predicate] The function invoked per + * iteration or property names to omit, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.omit(object, 'age'); + * // => { 'user': 'fred' } + * + * _.omit(object, _.isNumber); + * // => { 'user': 'fred' } + */ + var omit = restParam(function(object, props) { + if (object == null) { + return {}; + } + if (typeof props[0] != 'function') { + var props = arrayMap(baseFlatten(props), String); + return pickByArray(object, baseDifference(keysIn(object), props)); + } + var predicate = bindCallback(props[0], props[1], 3); + return pickByCallback(object, function(value, key, object) { + return !predicate(value, key, object); + }); + }); + + /** + * Creates a two dimensional array of the key-value pairs for `object`, + * e.g. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the new array of key-value pairs. + * @example + * + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) + */ + function pairs(object) { + object = toObject(object); + + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; + } + + /** + * Creates an object composed of the picked `object` properties. Property + * names may be specified as individual arguments or as arrays of property + * names. If `predicate` is provided it is invoked for each property of `object` + * picking the properties `predicate` returns truthy for. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {Function|...(string|string[])} [predicate] The function invoked per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.pick(object, 'user'); + * // => { 'user': 'fred' } + * + * _.pick(object, _.isString); + * // => { 'user': 'fred' } + */ + var pick = restParam(function(object, props) { + if (object == null) { + return {}; + } + return typeof props[0] == 'function' + ? pickByCallback(object, bindCallback(props[0], props[1], 3)) + : pickByArray(object, baseFlatten(props)); + }); + + /** + * This method is like `_.get` except that if the resolved value is a function + * it is invoked with the `this` binding of its parent object and its result + * is returned. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a.b.c', 'default'); + * // => 'default' + * + * _.result(object, 'a.b.c', _.constant('default')); + * // => 'default' + */ + function result(object, path, defaultValue) { + var result = object == null ? undefined : object[path]; + if (result === undefined) { + if (object != null && !isKey(path, object)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + result = object == null ? undefined : object[last(path)]; + } + result = result === undefined ? defaultValue : result; + } + return isFunction(result) ? result.call(object) : result; + } + + /** + * Sets the property value of `path` on `object`. If a portion of `path` + * does not exist it is created. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to augment. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 + * + * _.set(object, 'x[0].y.z', 5); + * console.log(object.x[0].y.z); + * // => 5 + */ + function set(object, path, value) { + if (object == null) { + return object; + } + var pathKey = (path + ''); + path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = path[index]; + if (isObject(nested)) { + if (index == lastIndex) { + nested[key] = value; + } else if (nested[key] == null) { + nested[key] = isIndex(path[index + 1]) ? [] : {}; + } + } + nested = nested[key]; + } + return object; + } + + /** + * An alternative to `_.reduce`; this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own enumerable + * properties through `iteratee`, with each invocation potentially mutating + * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked + * with four arguments: (accumulator, value, key, object). Iteratee functions + * may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Array|Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * _.transform([2, 3, 4], function(result, n) { + * result.push(n *= n); + * return n % 2 == 0; + * }); + * // => [4, 9] + * + * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) { + * result[key] = n * 3; + * }); + * // => { 'a': 3, 'b': 6 } + */ + function transform(object, iteratee, accumulator, thisArg) { + var isArr = isArray(object) || isTypedArray(object); + iteratee = getCallback(iteratee, thisArg, 4); + + if (accumulator == null) { + if (isArr || isObject(object)) { + var Ctor = object.constructor; + if (isArr) { + accumulator = isArray(object) ? new Ctor : []; + } else { + accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined); + } + } else { + accumulator = {}; + } + } + (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { + return iteratee(accumulator, value, index, object); + }); + return accumulator; + } + + /** + * Creates an array of the own enumerable property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return baseValues(object, keys(object)); + } + + /** + * Creates an array of the own and inherited enumerable property values + * of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.valuesIn(new Foo); + * // => [1, 2, 3] (iteration order is not guaranteed) + */ + function valuesIn(object) { + return baseValues(object, keysIn(object)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Checks if `n` is between `start` and up to but not including, `end`. If + * `end` is not specified it is set to `start` with `start` then set to `0`. + * + * @static + * @memberOf _ + * @category Number + * @param {number} n The number to check. + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `n` is in the range, else `false`. + * @example + * + * _.inRange(3, 2, 4); + * // => true + * + * _.inRange(4, 8); + * // => true + * + * _.inRange(4, 2); + * // => false + * + * _.inRange(2, 2); + * // => false + * + * _.inRange(1.2, 2); + * // => true + * + * _.inRange(5.2, 4); + * // => false + */ + function inRange(value, start, end) { + start = +start || 0; + if (end === undefined) { + end = start; + start = 0; + } else { + end = +end || 0; + } + return value >= nativeMin(start, end) && value < nativeMax(start, end); + } + + /** + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is provided a number between `0` and the given number is returned. + * If `floating` is `true`, or either `min` or `max` are floats, a floating-point + * number is returned instead of an integer. + * + * @static + * @memberOf _ + * @category Number + * @param {number} [min=0] The minimum possible value. + * @param {number} [max=1] The maximum possible value. + * @param {boolean} [floating] Specify returning a floating-point number. + * @returns {number} Returns the random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(min, max, floating) { + if (floating && isIterateeCall(min, max, floating)) { + max = floating = undefined; + } + var noMin = min == null, + noMax = max == null; + + if (floating == null) { + if (noMax && typeof min == 'boolean') { + floating = min; + min = 1; + } + else if (typeof max == 'boolean') { + floating = max; + noMax = true; + } + } + if (noMin && noMax) { + max = 1; + noMax = false; + } + min = +min || 0; + if (noMax) { + max = min; + min = 0; + } else { + max = +max || 0; + } + if (floating || min % 1 || max % 1) { + var rand = nativeRandom(); + return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max); + } + return baseRandom(min, max); + } + + /*------------------------------------------------------------------------*/ + + /** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar'); + * // => 'fooBar' + * + * _.camelCase('__foo_bar__'); + * // => 'fooBar' + */ + var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word); + }); + + /** + * Capitalizes the first character of `string`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('fred'); + * // => 'Fred' + */ + function capitalize(string) { + string = baseToString(string); + return string && (string.charAt(0).toUpperCase() + string.slice(1)); + } + + /** + * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ + function deburr(string) { + string = baseToString(string); + return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, ''); + } + + /** + * Checks if `string` ends with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search from. + * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`. + * @example + * + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true + */ + function endsWith(string, target, position) { + string = baseToString(string); + target = (target + ''); + + var length = string.length; + position = position === undefined + ? length + : nativeMin(position < 0 ? 0 : (+position || 0), length); + + position -= target.length; + return position >= 0 && string.indexOf(target, position) == position; + } + + /** + * Converts the characters "&", "<", ">", '"', "'", and "\`", in `string` to + * their corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional characters + * use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. + * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * Backticks are escaped because in Internet Explorer < 9, they can break out + * of attribute values or HTML comments. See [#59](https://html5sec.org/#59), + * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and + * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) + * for more details. + * + * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) + * to reduce XSS vectors. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function escape(string) { + // Reset `lastIndex` because in IE < 9 `String#replace` does not. + string = baseToString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; + } + + /** + * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?", + * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https:\/\/lodash\.com\/\)' + */ + function escapeRegExp(string) { + string = baseToString(string); + return (string && reHasRegExpChars.test(string)) + ? string.replace(reRegExpChars, escapeRegExpChar) + : (string || '(?:)'); + } + + /** + * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__foo_bar__'); + * // => 'foo-bar' + */ + var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); + }); + + /** + * Pads `string` on the left and right sides if it's shorter than `length`. + * Padding characters are truncated if they can't be evenly divided by `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.pad('abc', 8); + * // => ' abc ' + * + * _.pad('abc', 8, '_-'); + * // => '_-abc_-_' + * + * _.pad('abc', 3); + * // => 'abc' + */ + function pad(string, length, chars) { + string = baseToString(string); + length = +length; + + var strLength = string.length; + if (strLength >= length || !nativeIsFinite(length)) { + return string; + } + var mid = (length - strLength) / 2, + leftLength = nativeFloor(mid), + rightLength = nativeCeil(mid); + + chars = createPadding('', rightLength, chars); + return chars.slice(0, leftLength) + string + chars; + } + + /** + * Pads `string` on the left side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padLeft('abc', 6); + * // => ' abc' + * + * _.padLeft('abc', 6, '_-'); + * // => '_-_abc' + * + * _.padLeft('abc', 3); + * // => 'abc' + */ + var padLeft = createPadDir(); + + /** + * Pads `string` on the right side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padRight('abc', 6); + * // => 'abc ' + * + * _.padRight('abc', 6, '_-'); + * // => 'abc_-_' + * + * _.padRight('abc', 3); + * // => 'abc' + */ + var padRight = createPadDir(true); + + /** + * Converts `string` to an integer of the specified radix. If `radix` is + * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal, + * in which case a `radix` of `16` is used. + * + * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E) + * of `parseInt`. + * + * @static + * @memberOf _ + * @category String + * @param {string} string The string to convert. + * @param {number} [radix] The radix to interpret `value` by. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {number} Returns the converted integer. + * @example + * + * _.parseInt('08'); + * // => 8 + * + * _.map(['6', '08', '10'], _.parseInt); + * // => [6, 8, 10] + */ + function parseInt(string, radix, guard) { + // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`. + // Chrome fails to trim leading whitespace characters. + // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. + if (guard ? isIterateeCall(string, radix, guard) : radix == null) { + radix = 0; + } else if (radix) { + radix = +radix; + } + string = trim(string); + return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); + } + + /** + * Repeats the given string `n` times. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to repeat. + * @param {number} [n=0] The number of times to repeat the string. + * @returns {string} Returns the repeated string. + * @example + * + * _.repeat('*', 3); + * // => '***' + * + * _.repeat('abc', 2); + * // => 'abcabc' + * + * _.repeat('abc', 0); + * // => '' + */ + function repeat(string, n) { + var result = ''; + string = baseToString(string); + n = +n; + if (n < 1 || !string || !nativeIsFinite(n)) { + return result; + } + // Leverage the exponentiation by squaring algorithm for a faster repeat. + // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. + do { + if (n % 2) { + result += string; + } + n = nativeFloor(n / 2); + string += string; + } while (n); + + return result; + } + + /** + * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the snake cased string. + * @example + * + * _.snakeCase('Foo Bar'); + * // => 'foo_bar' + * + * _.snakeCase('fooBar'); + * // => 'foo_bar' + * + * _.snakeCase('--foo-bar'); + * // => 'foo_bar' + */ + var snakeCase = createCompounder(function(result, word, index) { + return result + (index ? '_' : '') + word.toLowerCase(); + }); + + /** + * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. + * @example + * + * _.startCase('--foo-bar'); + * // => 'Foo Bar' + * + * _.startCase('fooBar'); + * // => 'Foo Bar' + * + * _.startCase('__foo_bar__'); + * // => 'Foo Bar' + */ + var startCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1)); + }); + + /** + * Checks if `string` starts with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=0] The position to search from. + * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`. + * @example + * + * _.startsWith('abc', 'a'); + * // => true + * + * _.startsWith('abc', 'b'); + * // => false + * + * _.startsWith('abc', 'b', 1); + * // => true + */ + function startsWith(string, target, position) { + string = baseToString(string); + position = position == null + ? 0 + : nativeMin(position < 0 ? 0 : (+position || 0), string.length); + + return string.lastIndexOf(target, position) == position; + } + + /** + * Creates a compiled template function that can interpolate data properties + * in "interpolate" delimiters, HTML-escape interpolated data properties in + * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data + * properties may be accessed as free variables in the template. If a setting + * object is provided it takes precedence over `_.templateSettings` values. + * + * **Note:** In the development build `_.template` utilizes + * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * for easier debugging. + * + * For more information on precompiling templates see + * [lodash's custom builds documentation](https://lodash.com/custom-builds). + * + * For more information on Chrome extension sandboxes see + * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The template string. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The HTML "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as free variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [options.sourceURL] The sourceURL of the template's compiled source. + * @param {string} [options.variable] The data object variable name. + * @param- {Object} [otherOptions] Enables the legacy `options` param signature. + * @returns {Function} Returns the compiled template function. + * @example + * + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' + * + * // using the HTML "escape" delimiter to escape data property values + * var compiled = _.template('<%- value %>'); + * compiled({ 'value': '"); +// => "a linkalert("hello world!")" +``` + +#### toSentence(array, [delimiter, lastDelimiter]) => string + +Join an array into a human readable sentence. + +```javascript +toSentence(["jQuery", "Mootools", "Prototype"]); +// => "jQuery, Mootools and Prototype"; + +toSentence(["jQuery", "Mootools", "Prototype"], ", ", " unt "); +// => "jQuery, Mootools unt Prototype"; +``` + +#### toSentenceSerial(array, [delimiter, lastDelimiter]) => string + +The same as `toSentence`, but adjusts delimeters to use [Serial comma](http://en.wikipedia.org/wiki/Serial_comma). + +```javascript +toSentenceSerial(["jQuery", "Mootools"]); +// => "jQuery and Mootools" + +toSentenceSerial(["jQuery", "Mootools", "Prototype"]); +// => "jQuery, Mootools, and Prototype" + +toSentenceSerial(["jQuery", "Mootools", "Prototype"], ", ", " unt "); +// => "jQuery, Mootools, unt Prototype" +``` + +#### repeat(string, count, [separator]) => string + +Repeats a string count times. + +```javascript +repeat("foo", 3); +// => "foofoofoo" + +repeat("foo", 3, "bar"); +// => "foobarfoobarfoo" +``` + +#### surround(string, wrap) => string + +Surround a string with another string. + +```javascript +surround("foo", "ab"); +// => "abfooab" +``` + +#### quote(string, quoteChar) or q(string, quoteChar) => string + +Quotes a string. `quoteChar` defaults to `"`. + +```javascript +quote("foo", '"'); +// => '"foo"'; +``` +#### unquote(string, quoteChar) => string + +Unquotes a string. `quoteChar` defaults to `"`. + +```javascript +unquote('"foo"'); +// => "foo" + +unquote("'foo'", "'"); +// => "foo" +``` + + +#### slugify(string) => string + +Transform text into an ascii slug which can be used in safely in URLs. Replaces whitespaces, accentuated, and special characters with a dash. Limited set of non-ascii characters are transformed to similar versions in the ascii character set such as `ä` to `a`. + +```javascript +slugify("Un éléphant à l\'orée du bois"); +// => "un-elephant-a-l-oree-du-bois" +``` + +***Caution: this function is charset dependent*** + +#### naturalCmp(string1, string2) => number + +Naturally sort strings like humans would do. None numbers are compared by their [ASCII values](http://www.asciitable.com/). Note: this means "a" > "A". Use `.toLowerCase` if this isn't to be desired. + +Just past it to `Array#sort`. + +```javascript +["foo20", "foo5"].sort(naturalCmp); +// => ["foo5", "foo20"] +``` + +#### toBoolean(string) => boolean + +Turn strings that can be commonly considered as booleas to real booleans. Such as "true", "false", "1" and "0". This function is case insensitive. + +```javascript +toBoolean("true"); +// => true + +toBoolean("FALSE"); +// => false + +toBoolean("random"); +// => undefined +``` + +It can be customized by giving arrays of truth and falsy value matcher as parameters. Matchers can be also RegExp objects. + +```javascript +toBoolean("truthy", ["truthy"], ["falsy"]); +// => true + +toBoolean("true only at start", [/^true/]); +// => true +``` + +#### map(string, function) => string + +Creates a new string with the results of calling a provided function on every character of the given string. + +```javascript +map("Hello world", function(x) { + return x; +}); +// => "Hello world" + +map(12345, function(x) { + return x; +}); +// => "12345" + +map("Hello world", function(x) { + if (x === 'o') x = 'O'; + return x; +}); +// => "HellO wOrld" +``` + +### Library functions + +If you require the full library you can use chaining and aliases + +#### s(string) => chain + +Start a chain. Returns an immutable chain object with the string functions as +methods which return a new chain object instead of the plain string value. + +The chain object includes also following native Javascript string methods: + + - [toUpperCase](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) + - [toLowerCase](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase) + - [split](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) + - [replace](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) + - [slice](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice) + - [substring](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/substring) + - [substr](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr) + - [concat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat) + +#### chain.value() + +Return the string value from the chain + +```javascript +s(" foo ").trim().capitalize().value(); +// => "Foo" +``` + +When calling a method which does not return a string the resulting value is +immediately returned + +```javascript +s(" foobar ").trim().startsWith("foo"); +// => true +``` + +#### chain.tap(function) => chain + +Tap into the chain with a custom function + +```javascript +s("foo").tap(function(value){ + return value + "bar"; +}).value(); +// => "foobar" +``` + + +#### Aliases + +```javascript +strip = trim +lstrip = ltrim +rstrip = rtrim +center = lrpad +rjust = lpad +ljust = rpad +contains = include +q = quote +toBool = toBoolean +camelcase = camelize +``` + +## Maintainers ## + +This library is maintained by + + - Esa-Matti Suuronen – ***[@epeli](https://github.com/epeli)*** + - Christoph Hermann – ***[@stoeffel](https://github.com/stoeffel)*** + +## Licence ## + +The MIT License + +Copyright (c) 2011 Esa-Matti Suuronen esa-matti@suuronen.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +[d]: http://www.diveintojavascript.com/core-javascript-reference/the-string-object diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/bower.json b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/bower.json new file mode 100644 index 0000000..ae5df05 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/bower.json @@ -0,0 +1,34 @@ +{ + "name": "underscore.string", + "version": "3.2.3", + "description": "String manipulation extensions for Underscore.js javascript library.", + "homepage": "http://epeli.github.com/underscore.string/", + "contributors": [ + "Esa-Matti Suuronen (http://esa-matti.suuronen.org/)", + "Edward Tsech ", + "Pavel Pravosud ()", + "Sasha Koss (http://koss.nocorp.me/)", + "Vladimir Dronnikov ", + "Pete Kruckenberg ()", + "Paul Chavard ()", + "Ed Finkler ()" + ], + "keywords": [ + "underscore", + "string" + ], + "main": "./dist/underscore.string.js", + "ignore": [], + "repository": { + "type": "git", + "url": "https://github.com/epeli/underscore.string.git" + }, + "bugs": { + "url": "https://github.com/epeli/underscore.string/issues" + }, + "licenses": [ + { + "type": "MIT" + } + ] +} diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/camelize.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/camelize.js new file mode 100644 index 0000000..ac09e81 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/camelize.js @@ -0,0 +1,14 @@ +var trim = require('./trim'); +var decap = require('./decapitalize'); + +module.exports = function camelize(str, decapitalize) { + str = trim(str).replace(/[-_\s]+(.)?/g, function(match, c) { + return c ? c.toUpperCase() : ""; + }); + + if (decapitalize === true) { + return decap(str); + } else { + return str; + } +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/capitalize.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/capitalize.js new file mode 100644 index 0000000..2693376 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/capitalize.js @@ -0,0 +1,8 @@ +var makeString = require('./helper/makeString'); + +module.exports = function capitalize(str, lowercaseRest) { + str = makeString(str); + var remainingChars = !lowercaseRest ? str.slice(1) : str.slice(1).toLowerCase(); + + return str.charAt(0).toUpperCase() + remainingChars; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/chars.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/chars.js new file mode 100644 index 0000000..d94a901 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/chars.js @@ -0,0 +1,5 @@ +var makeString = require('./helper/makeString'); + +module.exports = function chars(str) { + return makeString(str).split(''); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/chop.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/chop.js new file mode 100644 index 0000000..73e17eb --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/chop.js @@ -0,0 +1,6 @@ +module.exports = function chop(str, step) { + if (str == null) return []; + str = String(str); + step = ~~step; + return step > 0 ? str.match(new RegExp('.{1,' + step + '}', 'g')) : [str]; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/classify.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/classify.js new file mode 100644 index 0000000..08547e0 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/classify.js @@ -0,0 +1,8 @@ +var capitalize = require('./capitalize'); +var camelize = require('./camelize'); +var makeString = require('./helper/makeString'); + +module.exports = function classify(str) { + str = makeString(str); + return capitalize(camelize(str.replace(/[\W_]/g, ' ')).replace(/\s/g, '')); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/clean.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/clean.js new file mode 100644 index 0000000..16a09d0 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/clean.js @@ -0,0 +1,5 @@ +var trim = require('./trim'); + +module.exports = function clean(str) { + return trim(str).replace(/\s\s+/g, ' '); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/cleanDiacritics.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/cleanDiacritics.js new file mode 100644 index 0000000..6293633 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/cleanDiacritics.js @@ -0,0 +1,22 @@ + +var makeString = require('./helper/makeString'); + +var from = "ąàáäâãåæăćčĉęèéëêĝĥìíïîĵłľńňòóöőôõðøśșşšŝťțţŭùúüűûñÿýçżźž", + to = "aaaaaaaaaccceeeeeghiiiijllnnoooooooossssstttuuuuuunyyczzz"; + +from += from.toUpperCase(); +to += to.toUpperCase(); + +to = to.split(""); + +// for tokens requireing multitoken output +from += "ß"; +to.push('ss'); + + +module.exports = function cleanDiacritics(str) { + return makeString(str).replace(/.{1}/g, function(c){ + var index = from.indexOf(c); + return index === -1 ? c : to[index]; + }); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/component.json b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/component.json new file mode 100644 index 0000000..be6eae6 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/component.json @@ -0,0 +1,16 @@ +{ + "name": "underscore.string", + "repo": "epeli/underscore.string", + "description": "String manipulation extensions for Underscore.js javascript library", + "version": "3.2.3", + "keywords": [ + "underscore", + "string" + ], + "dependencies": {}, + "development": {}, + "main": "index.js", + "scripts": [ + "*.js" + ] +} diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/count.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/count.js new file mode 100644 index 0000000..2207d70 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/count.js @@ -0,0 +1,10 @@ +var makeString = require('./helper/makeString'); + +module.exports = function(str, substr) { + str = makeString(str); + substr = makeString(substr); + + if (str.length === 0 || substr.length === 0) return 0; + + return str.split(substr).length - 1; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/dasherize.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/dasherize.js new file mode 100644 index 0000000..544ae0c --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/dasherize.js @@ -0,0 +1,5 @@ +var trim = require('./trim'); + +module.exports = function dasherize(str) { + return trim(str).replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase(); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/decapitalize.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/decapitalize.js new file mode 100644 index 0000000..6aa2673 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/decapitalize.js @@ -0,0 +1,6 @@ +var makeString = require('./helper/makeString'); + +module.exports = function decapitalize(str) { + str = makeString(str); + return str.charAt(0).toLowerCase() + str.slice(1); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/dedent.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/dedent.js new file mode 100644 index 0000000..41b4f07 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/dedent.js @@ -0,0 +1,28 @@ +var makeString = require('./helper/makeString'); + +function getIndent(str) { + var matches = str.match(/^[\s\\t]*/gm); + var indent = matches[0].length; + + for (var i = 1; i < matches.length; i++) { + indent = Math.min(matches[i].length, indent); + } + + return indent; +} + +module.exports = function dedent(str, pattern) { + str = makeString(str); + var indent = getIndent(str); + var reg; + + if (indent === 0) return str; + + if (typeof pattern === 'string') { + reg = new RegExp('^' + pattern, 'gm'); + } else { + reg = new RegExp('^[ \\t]{' + indent + '}', 'gm'); + } + + return str.replace(reg, ''); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/dist/underscore.string.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/dist/underscore.string.js new file mode 100644 index 0000000..36b6acc --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/dist/underscore.string.js @@ -0,0 +1,1200 @@ +/* underscore.string 3.2.2 | MIT licensed | http://epeli.github.com/underscore.string/ */ + +!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.s=e()}}(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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0 ? str.match(new RegExp('.{1,' + step + '}', 'g')) : [str]; +}; + +},{}],5:[function(_dereq_,module,exports){ +var capitalize = _dereq_('./capitalize'); +var camelize = _dereq_('./camelize'); +var makeString = _dereq_('./helper/makeString'); + +module.exports = function classify(str) { + str = makeString(str); + return capitalize(camelize(str.replace(/[\W_]/g, ' ')).replace(/\s/g, '')); +}; + +},{"./camelize":1,"./capitalize":2,"./helper/makeString":21}],6:[function(_dereq_,module,exports){ +var trim = _dereq_('./trim'); + +module.exports = function clean(str) { + return trim(str).replace(/\s\s+/g, ' '); +}; + +},{"./trim":63}],7:[function(_dereq_,module,exports){ + +var makeString = _dereq_('./helper/makeString'); + +var from = "ąàáäâãåæăćčĉęèéëêĝĥìíïîĵłľńňòóöőôõðøśșşšŝťțţŭùúüűûñÿýçżźž", + to = "aaaaaaaaaccceeeeeghiiiijllnnoooooooossssstttuuuuuunyyczzz"; + +from += from.toUpperCase(); +to += to.toUpperCase(); + +to = to.split(""); + +// for tokens requireing multitoken output +from += "ß"; +to.push('ss'); + + +module.exports = function cleanDiacritics(str) { + return makeString(str).replace(/.{1}/g, function(c){ + var index = from.indexOf(c); + return index === -1 ? c : to[index]; + }); +}; + +},{"./helper/makeString":21}],8:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); + +module.exports = function(str, substr) { + str = makeString(str); + substr = makeString(substr); + + if (str.length === 0 || substr.length === 0) return 0; + + return str.split(substr).length - 1; +}; + +},{"./helper/makeString":21}],9:[function(_dereq_,module,exports){ +var trim = _dereq_('./trim'); + +module.exports = function dasherize(str) { + return trim(str).replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase(); +}; + +},{"./trim":63}],10:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); + +module.exports = function decapitalize(str) { + str = makeString(str); + return str.charAt(0).toLowerCase() + str.slice(1); +}; + +},{"./helper/makeString":21}],11:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); + +function getIndent(str) { + var matches = str.match(/^[\s\\t]*/gm); + var indent = matches[0].length; + + for (var i = 1; i < matches.length; i++) { + indent = Math.min(matches[i].length, indent); + } + + return indent; +} + +module.exports = function dedent(str, pattern) { + str = makeString(str); + var indent = getIndent(str); + var reg; + + if (indent === 0) return str; + + if (typeof pattern === 'string') { + reg = new RegExp('^' + pattern, 'gm'); + } else { + reg = new RegExp('^[ \\t]{' + indent + '}', 'gm'); + } + + return str.replace(reg, ''); +}; + +},{"./helper/makeString":21}],12:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); +var toPositive = _dereq_('./helper/toPositive'); + +module.exports = function endsWith(str, ends, position) { + str = makeString(str); + ends = '' + ends; + if (typeof position == 'undefined') { + position = str.length - ends.length; + } else { + position = Math.min(toPositive(position), str.length) - ends.length; + } + return position >= 0 && str.indexOf(ends, position) === position; +}; + +},{"./helper/makeString":21,"./helper/toPositive":23}],13:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); +var escapeChars = _dereq_('./helper/escapeChars'); + +var regexString = "["; +for(var key in escapeChars) { + regexString += key; +} +regexString += "]"; + +var regex = new RegExp( regexString, 'g'); + +module.exports = function escapeHTML(str) { + + return makeString(str).replace(regex, function(m) { + return '&' + escapeChars[m] + ';'; + }); +}; + +},{"./helper/escapeChars":18,"./helper/makeString":21}],14:[function(_dereq_,module,exports){ +module.exports = function() { + var result = {}; + + for (var prop in this) { + if (!this.hasOwnProperty(prop) || prop.match(/^(?:include|contains|reverse|join|map)$/)) continue; + result[prop] = this[prop]; + } + + return result; +}; + +},{}],15:[function(_dereq_,module,exports){ +// Underscore.string +// (c) 2010 Esa-Matti Suuronen +// Underscore.string is freely distributable under the terms of the MIT license. +// Documentation: https://github.com/epeli/underscore.string +// Some code is borrowed from MooTools and Alexandru Marasteanu. +// Version '3.2.2' + +'use strict'; + +function s(value) { + /* jshint validthis: true */ + if (!(this instanceof s)) return new s(value); + this._wrapped = value; +} + +s.VERSION = '3.2.2'; + +s.isBlank = _dereq_('./isBlank'); +s.stripTags = _dereq_('./stripTags'); +s.capitalize = _dereq_('./capitalize'); +s.decapitalize = _dereq_('./decapitalize'); +s.chop = _dereq_('./chop'); +s.trim = _dereq_('./trim'); +s.clean = _dereq_('./clean'); +s.cleanDiacritics = _dereq_('./cleanDiacritics'); +s.count = _dereq_('./count'); +s.chars = _dereq_('./chars'); +s.swapCase = _dereq_('./swapCase'); +s.escapeHTML = _dereq_('./escapeHTML'); +s.unescapeHTML = _dereq_('./unescapeHTML'); +s.splice = _dereq_('./splice'); +s.insert = _dereq_('./insert'); +s.replaceAll = _dereq_('./replaceAll'); +s.include = _dereq_('./include'); +s.join = _dereq_('./join'); +s.lines = _dereq_('./lines'); +s.dedent = _dereq_('./dedent'); +s.reverse = _dereq_('./reverse'); +s.startsWith = _dereq_('./startsWith'); +s.endsWith = _dereq_('./endsWith'); +s.pred = _dereq_('./pred'); +s.succ = _dereq_('./succ'); +s.titleize = _dereq_('./titleize'); +s.camelize = _dereq_('./camelize'); +s.underscored = _dereq_('./underscored'); +s.dasherize = _dereq_('./dasherize'); +s.classify = _dereq_('./classify'); +s.humanize = _dereq_('./humanize'); +s.ltrim = _dereq_('./ltrim'); +s.rtrim = _dereq_('./rtrim'); +s.truncate = _dereq_('./truncate'); +s.prune = _dereq_('./prune'); +s.words = _dereq_('./words'); +s.pad = _dereq_('./pad'); +s.lpad = _dereq_('./lpad'); +s.rpad = _dereq_('./rpad'); +s.lrpad = _dereq_('./lrpad'); +s.sprintf = _dereq_('./sprintf'); +s.vsprintf = _dereq_('./vsprintf'); +s.toNumber = _dereq_('./toNumber'); +s.numberFormat = _dereq_('./numberFormat'); +s.strRight = _dereq_('./strRight'); +s.strRightBack = _dereq_('./strRightBack'); +s.strLeft = _dereq_('./strLeft'); +s.strLeftBack = _dereq_('./strLeftBack'); +s.toSentence = _dereq_('./toSentence'); +s.toSentenceSerial = _dereq_('./toSentenceSerial'); +s.slugify = _dereq_('./slugify'); +s.surround = _dereq_('./surround'); +s.quote = _dereq_('./quote'); +s.unquote = _dereq_('./unquote'); +s.repeat = _dereq_('./repeat'); +s.naturalCmp = _dereq_('./naturalCmp'); +s.levenshtein = _dereq_('./levenshtein'); +s.toBoolean = _dereq_('./toBoolean'); +s.exports = _dereq_('./exports'); +s.escapeRegExp = _dereq_('./helper/escapeRegExp'); +s.wrap = _dereq_('./wrap'); +s.map = _dereq_('./map'); + +// Aliases +s.strip = s.trim; +s.lstrip = s.ltrim; +s.rstrip = s.rtrim; +s.center = s.lrpad; +s.rjust = s.lpad; +s.ljust = s.rpad; +s.contains = s.include; +s.q = s.quote; +s.toBool = s.toBoolean; +s.camelcase = s.camelize; +s.mapChars = s.map; + + +// Implement chaining +s.prototype = { + value: function value() { + return this._wrapped; + } +}; + +function fn2method(key, fn) { + if (typeof fn !== "function") return; + s.prototype[key] = function() { + var args = [this._wrapped].concat(Array.prototype.slice.call(arguments)); + var res = fn.apply(null, args); + // if the result is non-string stop the chain and return the value + return typeof res === 'string' ? new s(res) : res; + }; +} + +// Copy functions to instance methods for chaining +for (var key in s) fn2method(key, s[key]); + +fn2method("tap", function tap(string, fn) { + return fn(string); +}); + +function prototype2method(methodName) { + fn2method(methodName, function(context) { + var args = Array.prototype.slice.call(arguments, 1); + return String.prototype[methodName].apply(context, args); + }); +} + +var prototypeMethods = [ + "toUpperCase", + "toLowerCase", + "split", + "replace", + "slice", + "substring", + "substr", + "concat" +]; + +for (var method in prototypeMethods) prototype2method(prototypeMethods[method]); + + +module.exports = s; + +},{"./camelize":1,"./capitalize":2,"./chars":3,"./chop":4,"./classify":5,"./clean":6,"./cleanDiacritics":7,"./count":8,"./dasherize":9,"./decapitalize":10,"./dedent":11,"./endsWith":12,"./escapeHTML":13,"./exports":14,"./helper/escapeRegExp":19,"./humanize":24,"./include":25,"./insert":26,"./isBlank":27,"./join":28,"./levenshtein":29,"./lines":30,"./lpad":31,"./lrpad":32,"./ltrim":33,"./map":34,"./naturalCmp":35,"./numberFormat":36,"./pad":37,"./pred":38,"./prune":39,"./quote":40,"./repeat":41,"./replaceAll":42,"./reverse":43,"./rpad":44,"./rtrim":45,"./slugify":46,"./splice":47,"./sprintf":48,"./startsWith":49,"./strLeft":50,"./strLeftBack":51,"./strRight":52,"./strRightBack":53,"./stripTags":54,"./succ":55,"./surround":56,"./swapCase":57,"./titleize":58,"./toBoolean":59,"./toNumber":60,"./toSentence":61,"./toSentenceSerial":62,"./trim":63,"./truncate":64,"./underscored":65,"./unescapeHTML":66,"./unquote":67,"./vsprintf":68,"./words":69,"./wrap":70}],16:[function(_dereq_,module,exports){ +var makeString = _dereq_('./makeString'); + +module.exports = function adjacent(str, direction) { + str = makeString(str); + if (str.length === 0) { + return ''; + } + return str.slice(0, -1) + String.fromCharCode(str.charCodeAt(str.length - 1) + direction); +}; + +},{"./makeString":21}],17:[function(_dereq_,module,exports){ +var escapeRegExp = _dereq_('./escapeRegExp'); + +module.exports = function defaultToWhiteSpace(characters) { + if (characters == null) + return '\\s'; + else if (characters.source) + return characters.source; + else + return '[' + escapeRegExp(characters) + ']'; +}; + +},{"./escapeRegExp":19}],18:[function(_dereq_,module,exports){ +/* We're explicitly defining the list of entities we want to escape. +nbsp is an HTML entity, but we don't want to escape all space characters in a string, hence its omission in this map. + +*/ +var escapeChars = { + '¢' : 'cent', + '£' : 'pound', + '¥' : 'yen', + '€': 'euro', + '©' :'copy', + '®' : 'reg', + '<' : 'lt', + '>' : 'gt', + '"' : 'quot', + '&' : 'amp', + "'" : '#39' +}; + +module.exports = escapeChars; + +},{}],19:[function(_dereq_,module,exports){ +var makeString = _dereq_('./makeString'); + +module.exports = function escapeRegExp(str) { + return makeString(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); +}; + +},{"./makeString":21}],20:[function(_dereq_,module,exports){ +/* +We're explicitly defining the list of entities that might see in escape HTML strings +*/ +var htmlEntities = { + nbsp: ' ', + cent: '¢', + pound: '£', + yen: '¥', + euro: '€', + copy: '©', + reg: '®', + lt: '<', + gt: '>', + quot: '"', + amp: '&', + apos: "'" +}; + +module.exports = htmlEntities; + +},{}],21:[function(_dereq_,module,exports){ +/** + * Ensure some object is a coerced to a string + **/ +module.exports = function makeString(object) { + if (object == null) return ''; + return '' + object; +}; + +},{}],22:[function(_dereq_,module,exports){ +module.exports = function strRepeat(str, qty){ + if (qty < 1) return ''; + var result = ''; + while (qty > 0) { + if (qty & 1) result += str; + qty >>= 1, str += str; + } + return result; +}; + +},{}],23:[function(_dereq_,module,exports){ +module.exports = function toPositive(number) { + return number < 0 ? 0 : (+number || 0); +}; + +},{}],24:[function(_dereq_,module,exports){ +var capitalize = _dereq_('./capitalize'); +var underscored = _dereq_('./underscored'); +var trim = _dereq_('./trim'); + +module.exports = function humanize(str) { + return capitalize(trim(underscored(str).replace(/_id$/, '').replace(/_/g, ' '))); +}; + +},{"./capitalize":2,"./trim":63,"./underscored":65}],25:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); + +module.exports = function include(str, needle) { + if (needle === '') return true; + return makeString(str).indexOf(needle) !== -1; +}; + +},{"./helper/makeString":21}],26:[function(_dereq_,module,exports){ +var splice = _dereq_('./splice'); + +module.exports = function insert(str, i, substr) { + return splice(str, i, 0, substr); +}; + +},{"./splice":47}],27:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); + +module.exports = function isBlank(str) { + return (/^\s*$/).test(makeString(str)); +}; + +},{"./helper/makeString":21}],28:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); +var slice = [].slice; + +module.exports = function join() { + var args = slice.call(arguments), + separator = args.shift(); + + return args.join(makeString(separator)); +}; + +},{"./helper/makeString":21}],29:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); + +/** + * Based on the implementation here: https://github.com/hiddentao/fast-levenshtein + */ +module.exports = function levenshtein(str1, str2) { + 'use strict'; + str1 = makeString(str1); + str2 = makeString(str2); + + // Short cut cases + if (str1 === str2) return 0; + if (!str1 || !str2) return Math.max(str1.length, str2.length); + + // two rows + var prevRow = new Array(str2.length + 1); + + // initialise previous row + for (var i = 0; i < prevRow.length; ++i) { + prevRow[i] = i; + } + + // calculate current row distance from previous row + for (i = 0; i < str1.length; ++i) { + var nextCol = i + 1; + + for (var j = 0; j < str2.length; ++j) { + var curCol = nextCol; + + // substution + nextCol = prevRow[j] + ( (str1.charAt(i) === str2.charAt(j)) ? 0 : 1 ); + // insertion + var tmp = curCol + 1; + if (nextCol > 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; +}; + +},{"./helper/makeString":21}],30:[function(_dereq_,module,exports){ +module.exports = function lines(str) { + if (str == null) return []; + return String(str).split(/\r\n?|\n/); +}; + +},{}],31:[function(_dereq_,module,exports){ +var pad = _dereq_('./pad'); + +module.exports = function lpad(str, length, padStr) { + return pad(str, length, padStr); +}; + +},{"./pad":37}],32:[function(_dereq_,module,exports){ +var pad = _dereq_('./pad'); + +module.exports = function lrpad(str, length, padStr) { + return pad(str, length, padStr, 'both'); +}; + +},{"./pad":37}],33:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); +var defaultToWhiteSpace = _dereq_('./helper/defaultToWhiteSpace'); +var nativeTrimLeft = String.prototype.trimLeft; + +module.exports = function ltrim(str, characters) { + str = makeString(str); + if (!characters && nativeTrimLeft) return nativeTrimLeft.call(str); + characters = defaultToWhiteSpace(characters); + return str.replace(new RegExp('^' + characters + '+'), ''); +}; + +},{"./helper/defaultToWhiteSpace":17,"./helper/makeString":21}],34:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); + +module.exports = function(str, callback) { + str = makeString(str); + + if (str.length === 0 || typeof callback !== 'function') return str; + + return str.replace(/./g, callback); +}; + +},{"./helper/makeString":21}],35:[function(_dereq_,module,exports){ +module.exports = function naturalCmp(str1, str2) { + if (str1 == str2) return 0; + if (!str1) return -1; + if (!str2) return 1; + + var cmpRegex = /(\.\d+|\d+|\D+)/g, + tokens1 = String(str1).match(cmpRegex), + tokens2 = String(str2).match(cmpRegex), + count = Math.min(tokens1.length, tokens2.length); + + for (var i = 0; i < count; i++) { + var a = tokens1[i], + b = tokens2[i]; + + if (a !== b) { + var num1 = +a; + var num2 = +b; + if (num1 === num1 && num2 === num2) { + return num1 > num2 ? 1 : -1; + } + return a < b ? -1 : 1; + } + } + + if (tokens1.length != tokens2.length) + return tokens1.length - tokens2.length; + + return str1 < str2 ? -1 : 1; +}; + +},{}],36:[function(_dereq_,module,exports){ +module.exports = function numberFormat(number, dec, dsep, tsep) { + if (isNaN(number) || number == null) return ''; + + number = number.toFixed(~~dec); + tsep = typeof tsep == 'string' ? tsep : ','; + + var parts = number.split('.'), + fnums = parts[0], + decimals = parts[1] ? (dsep || '.') + parts[1] : ''; + + return fnums.replace(/(\d)(?=(?:\d{3})+$)/g, '$1' + tsep) + decimals; +}; + +},{}],37:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); +var strRepeat = _dereq_('./helper/strRepeat'); + +module.exports = function pad(str, length, padStr, type) { + str = makeString(str); + length = ~~length; + + var padlen = 0; + + if (!padStr) + padStr = ' '; + else if (padStr.length > 1) + padStr = padStr.charAt(0); + + switch (type) { + case 'right': + padlen = length - str.length; + return str + strRepeat(padStr, padlen); + case 'both': + padlen = length - str.length; + return strRepeat(padStr, Math.ceil(padlen / 2)) + str + strRepeat(padStr, Math.floor(padlen / 2)); + default: // 'left' + padlen = length - str.length; + return strRepeat(padStr, padlen) + str; + } +}; + +},{"./helper/makeString":21,"./helper/strRepeat":22}],38:[function(_dereq_,module,exports){ +var adjacent = _dereq_('./helper/adjacent'); + +module.exports = function succ(str) { + return adjacent(str, -1); +}; + +},{"./helper/adjacent":16}],39:[function(_dereq_,module,exports){ +/** + * _s.prune: a more elegant version of truncate + * prune extra chars, never leaving a half-chopped word. + * @author github.com/rwz + */ +var makeString = _dereq_('./helper/makeString'); +var rtrim = _dereq_('./rtrim'); + +module.exports = function prune(str, length, pruneStr) { + str = makeString(str); + length = ~~length; + pruneStr = pruneStr != null ? String(pruneStr) : '...'; + + if (str.length <= length) return str; + + var tmpl = function(c) { + return c.toUpperCase() !== c.toLowerCase() ? 'A' : ' '; + }, + template = str.slice(0, length + 1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA' + + if (template.slice(template.length - 2).match(/\w\w/)) + template = template.replace(/\s*\S+$/, ''); + else + template = rtrim(template.slice(0, template.length - 1)); + + return (template + pruneStr).length > str.length ? str : str.slice(0, template.length) + pruneStr; +}; + +},{"./helper/makeString":21,"./rtrim":45}],40:[function(_dereq_,module,exports){ +var surround = _dereq_('./surround'); + +module.exports = function quote(str, quoteChar) { + return surround(str, quoteChar || '"'); +}; + +},{"./surround":56}],41:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); +var strRepeat = _dereq_('./helper/strRepeat'); + +module.exports = function repeat(str, qty, separator) { + str = makeString(str); + + qty = ~~qty; + + // using faster implementation if separator is not needed; + if (separator == null) return strRepeat(str, qty); + + // this one is about 300x slower in Google Chrome + /*eslint no-empty: 0*/ + for (var repeat = []; qty > 0; repeat[--qty] = str) {} + return repeat.join(separator); +}; + +},{"./helper/makeString":21,"./helper/strRepeat":22}],42:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); + +module.exports = function replaceAll(str, find, replace, ignorecase) { + var flags = (ignorecase === true)?'gi':'g'; + var reg = new RegExp(find, flags); + + return makeString(str).replace(reg, replace); +}; + +},{"./helper/makeString":21}],43:[function(_dereq_,module,exports){ +var chars = _dereq_('./chars'); + +module.exports = function reverse(str) { + return chars(str).reverse().join(''); +}; + +},{"./chars":3}],44:[function(_dereq_,module,exports){ +var pad = _dereq_('./pad'); + +module.exports = function rpad(str, length, padStr) { + return pad(str, length, padStr, 'right'); +}; + +},{"./pad":37}],45:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); +var defaultToWhiteSpace = _dereq_('./helper/defaultToWhiteSpace'); +var nativeTrimRight = String.prototype.trimRight; + +module.exports = function rtrim(str, characters) { + str = makeString(str); + if (!characters && nativeTrimRight) return nativeTrimRight.call(str); + characters = defaultToWhiteSpace(characters); + return str.replace(new RegExp(characters + '+$'), ''); +}; + +},{"./helper/defaultToWhiteSpace":17,"./helper/makeString":21}],46:[function(_dereq_,module,exports){ +var trim = _dereq_('./trim'); +var dasherize = _dereq_('./dasherize'); +var cleanDiacritics = _dereq_("./cleanDiacritics"); + +module.exports = function slugify(str) { + return trim(dasherize(cleanDiacritics(str).replace(/[^\w\s-]/g, '-').toLowerCase()), '-'); +}; + +},{"./cleanDiacritics":7,"./dasherize":9,"./trim":63}],47:[function(_dereq_,module,exports){ +var chars = _dereq_('./chars'); + +module.exports = function splice(str, i, howmany, substr) { + var arr = chars(str); + arr.splice(~~i, ~~howmany, substr); + return arr.join(''); +}; + +},{"./chars":3}],48:[function(_dereq_,module,exports){ +// sprintf() for JavaScript 0.7-beta1 +// http://www.diveintojavascript.com/projects/javascript-sprintf +// +// Copyright (c) Alexandru Marasteanu +// All rights reserved. +var strRepeat = _dereq_('./helper/strRepeat'); +var toString = Object.prototype.toString; +var sprintf = (function() { + function get_type(variable) { + return toString.call(variable).slice(8, -1).toLowerCase(); + } + + var str_repeat = strRepeat; + + var str_format = function() { + if (!str_format.cache.hasOwnProperty(arguments[0])) { + str_format.cache[arguments[0]] = str_format.parse(arguments[0]); + } + return str_format.format.call(null, str_format.cache[arguments[0]], arguments); + }; + + str_format.format = function(parse_tree, argv) { + var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length; + for (i = 0; i < tree_length; i++) { + node_type = get_type(parse_tree[i]); + if (node_type === 'string') { + output.push(parse_tree[i]); + } + else if (node_type === 'array') { + match = parse_tree[i]; // convenience purposes only + if (match[2]) { // keyword argument + arg = argv[cursor]; + for (k = 0; k < match[2].length; k++) { + if (!arg.hasOwnProperty(match[2][k])) { + throw new Error(sprintf('[_.sprintf] property "%s" does not exist', match[2][k])); + } + arg = arg[match[2][k]]; + } + } else if (match[1]) { // positional argument (explicit) + arg = argv[match[1]]; + } + else { // positional argument (implicit) + arg = argv[cursor++]; + } + + if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) { + throw new Error(sprintf('[_.sprintf] expecting number but found %s', get_type(arg))); + } + switch (match[8]) { + case 'b': arg = arg.toString(2); break; + case 'c': arg = String.fromCharCode(arg); break; + case 'd': arg = parseInt(arg, 10); break; + case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; + case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; + case 'o': arg = arg.toString(8); break; + case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break; + case 'u': arg = Math.abs(arg); break; + case 'x': arg = arg.toString(16); break; + case 'X': arg = arg.toString(16).toUpperCase(); break; + } + arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); + pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' '; + pad_length = match[6] - String(arg).length; + pad = match[6] ? str_repeat(pad_character, pad_length) : ''; + output.push(match[5] ? arg + pad : pad + arg); + } + } + return output.join(''); + }; + + str_format.cache = {}; + + str_format.parse = function(fmt) { + var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; + while (_fmt) { + if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { + parse_tree.push(match[0]); + } + else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { + parse_tree.push('%'); + } + else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { + if (match[2]) { + arg_names |= 1; + var field_list = [], replacement_field = match[2], field_match = []; + if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { + if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + } + else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + } + else { + throw new Error('[_.sprintf] huh?'); + } + } + } + else { + throw new Error('[_.sprintf] huh?'); + } + match[2] = field_list; + } + else { + arg_names |= 2; + } + if (arg_names === 3) { + throw new Error('[_.sprintf] mixing positional and named placeholders is not (yet) supported'); + } + parse_tree.push(match); + } + else { + throw new Error('[_.sprintf] huh?'); + } + _fmt = _fmt.substring(match[0].length); + } + return parse_tree; + }; + + return str_format; +})(); + +module.exports = sprintf; + +},{"./helper/strRepeat":22}],49:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); +var toPositive = _dereq_('./helper/toPositive'); + +module.exports = function startsWith(str, starts, position) { + str = makeString(str); + starts = '' + starts; + position = position == null ? 0 : Math.min(toPositive(position), str.length); + return str.lastIndexOf(starts, position) === position; +}; + +},{"./helper/makeString":21,"./helper/toPositive":23}],50:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); + +module.exports = function strLeft(str, sep) { + str = makeString(str); + sep = makeString(sep); + var pos = !sep ? -1 : str.indexOf(sep); + return~ pos ? str.slice(0, pos) : str; +}; + +},{"./helper/makeString":21}],51:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); + +module.exports = function strLeftBack(str, sep) { + str = makeString(str); + sep = makeString(sep); + var pos = str.lastIndexOf(sep); + return~ pos ? str.slice(0, pos) : str; +}; + +},{"./helper/makeString":21}],52:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); + +module.exports = function strRight(str, sep) { + str = makeString(str); + sep = makeString(sep); + var pos = !sep ? -1 : str.indexOf(sep); + return~ pos ? str.slice(pos + sep.length, str.length) : str; +}; + +},{"./helper/makeString":21}],53:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); + +module.exports = function strRightBack(str, sep) { + str = makeString(str); + sep = makeString(sep); + var pos = !sep ? -1 : str.lastIndexOf(sep); + return~ pos ? str.slice(pos + sep.length, str.length) : str; +}; + +},{"./helper/makeString":21}],54:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); + +module.exports = function stripTags(str) { + return makeString(str).replace(/<\/?[^>]+>/g, ''); +}; + +},{"./helper/makeString":21}],55:[function(_dereq_,module,exports){ +var adjacent = _dereq_('./helper/adjacent'); + +module.exports = function succ(str) { + return adjacent(str, 1); +}; + +},{"./helper/adjacent":16}],56:[function(_dereq_,module,exports){ +module.exports = function surround(str, wrapper) { + return [wrapper, str, wrapper].join(''); +}; + +},{}],57:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); + +module.exports = function swapCase(str) { + return makeString(str).replace(/\S/g, function(c) { + return c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase(); + }); +}; + +},{"./helper/makeString":21}],58:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); + +module.exports = function titleize(str) { + return makeString(str).toLowerCase().replace(/(?:^|\s|-)\S/g, function(c) { + return c.toUpperCase(); + }); +}; + +},{"./helper/makeString":21}],59:[function(_dereq_,module,exports){ +var trim = _dereq_('./trim'); + +function boolMatch(s, matchers) { + var i, matcher, down = s.toLowerCase(); + matchers = [].concat(matchers); + for (i = 0; i < matchers.length; i += 1) { + matcher = matchers[i]; + if (!matcher) continue; + if (matcher.test && matcher.test(s)) return true; + if (matcher.toLowerCase() === down) return true; + } +} + +module.exports = function toBoolean(str, trueValues, falseValues) { + if (typeof str === "number") str = "" + str; + if (typeof str !== "string") return !!str; + str = trim(str); + if (boolMatch(str, trueValues || ["true", "1"])) return true; + if (boolMatch(str, falseValues || ["false", "0"])) return false; +}; + +},{"./trim":63}],60:[function(_dereq_,module,exports){ +module.exports = function toNumber(num, precision) { + if (num == null) return 0; + var factor = Math.pow(10, isFinite(precision) ? precision : 0); + return Math.round(num * factor) / factor; +}; + +},{}],61:[function(_dereq_,module,exports){ +var rtrim = _dereq_('./rtrim'); + +module.exports = function toSentence(array, separator, lastSeparator, serial) { + separator = separator || ', '; + lastSeparator = lastSeparator || ' and '; + var a = array.slice(), + lastMember = a.pop(); + + if (array.length > 2 && serial) lastSeparator = rtrim(separator) + lastSeparator; + + return a.length ? a.join(separator) + lastSeparator + lastMember : lastMember; +}; + +},{"./rtrim":45}],62:[function(_dereq_,module,exports){ +var toSentence = _dereq_('./toSentence'); + +module.exports = function toSentenceSerial(array, sep, lastSep) { + return toSentence(array, sep, lastSep, true); +}; + +},{"./toSentence":61}],63:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); +var defaultToWhiteSpace = _dereq_('./helper/defaultToWhiteSpace'); +var nativeTrim = String.prototype.trim; + +module.exports = function trim(str, characters) { + str = makeString(str); + if (!characters && nativeTrim) return nativeTrim.call(str); + characters = defaultToWhiteSpace(characters); + return str.replace(new RegExp('^' + characters + '+|' + characters + '+$', 'g'), ''); +}; + +},{"./helper/defaultToWhiteSpace":17,"./helper/makeString":21}],64:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); + +module.exports = function truncate(str, length, truncateStr) { + str = makeString(str); + truncateStr = truncateStr || '...'; + length = ~~length; + return str.length > length ? str.slice(0, length) + truncateStr : str; +}; + +},{"./helper/makeString":21}],65:[function(_dereq_,module,exports){ +var trim = _dereq_('./trim'); + +module.exports = function underscored(str) { + return trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase(); +}; + +},{"./trim":63}],66:[function(_dereq_,module,exports){ +var makeString = _dereq_('./helper/makeString'); +var htmlEntities = _dereq_('./helper/htmlEntities'); + +module.exports = function unescapeHTML(str) { + return makeString(str).replace(/\&([^;]+);/g, function(entity, entityCode) { + var match; + + if (entityCode in htmlEntities) { + return htmlEntities[entityCode]; + /*eslint no-cond-assign: 0*/ + } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) { + return String.fromCharCode(parseInt(match[1], 16)); + /*eslint no-cond-assign: 0*/ + } else if (match = entityCode.match(/^#(\d+)$/)) { + return String.fromCharCode(~~match[1]); + } else { + return entity; + } + }); +}; + +},{"./helper/htmlEntities":20,"./helper/makeString":21}],67:[function(_dereq_,module,exports){ +module.exports = function unquote(str, quoteChar) { + quoteChar = quoteChar || '"'; + if (str[0] === quoteChar && str[str.length - 1] === quoteChar) + return str.slice(1, str.length - 1); + else return str; +}; + +},{}],68:[function(_dereq_,module,exports){ +var sprintf = _dereq_('./sprintf'); + +module.exports = function vsprintf(fmt, argv) { + argv.unshift(fmt); + return sprintf.apply(null, argv); +}; + +},{"./sprintf":48}],69:[function(_dereq_,module,exports){ +var isBlank = _dereq_('./isBlank'); +var trim = _dereq_('./trim'); + +module.exports = function words(str, delimiter) { + if (isBlank(str)) return []; + return trim(str, delimiter).split(delimiter || /\s+/); +}; + +},{"./isBlank":27,"./trim":63}],70:[function(_dereq_,module,exports){ +// Wrap +// wraps a string by a certain width + +var makeString = _dereq_('./helper/makeString'); + +module.exports = function wrap(str, options){ + str = makeString(str); + + options = options || {}; + + var width = options.width || 75; + var seperator = options.seperator || '\n'; + var cut = options.cut || false; + var preserveSpaces = options.preserveSpaces || false; + var trailingSpaces = options.trailingSpaces || false; + + var result; + + if(width <= 0){ + return str; + } + + else if(!cut){ + + var words = str.split(" "); + var current_column = 0; + result = ""; + + while(words.length > 0){ + + // if adding a space and the next word would cause this line to be longer than width... + if(1 + words[0].length + current_column > width){ + //start a new line if this line is not already empty + if(current_column > 0){ + // add a space at the end of the line is preserveSpaces is true + if (preserveSpaces){ + result += ' '; + current_column++; + } + // fill the rest of the line with spaces if trailingSpaces option is true + else if(trailingSpaces){ + while(current_column < width){ + result += ' '; + current_column++; + } + } + //start new line + result += seperator; + current_column = 0; + } + } + + // if not at the begining of the line, add a space in front of the word + if(current_column > 0){ + result += " "; + current_column++; + } + + // tack on the next word, update current column, a pop words array + result += words[0]; + current_column += words[0].length; + words.shift(); + + } + + // fill the rest of the line with spaces if trailingSpaces option is true + if(trailingSpaces){ + while(current_column < width){ + result += ' '; + current_column++; + } + } + + return result; + + } + + else { + + var index = 0; + result = ""; + + // walk through each character and add seperators where appropriate + while(index < str.length){ + if(index % width == 0 && index > 0){ + result += seperator; + } + result += str.charAt(index); + index++; + } + + // fill the rest of the line with spaces if trailingSpaces option is true + if(trailingSpaces){ + while(index % width > 0){ + result += ' '; + index++; + } + } + + return result; + } +}; + +},{"./helper/makeString":21}]},{},[15]) +(15) +}); \ No newline at end of file diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/dist/underscore.string.min.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/dist/underscore.string.min.js new file mode 100644 index 0000000..2f2a41a --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/dist/underscore.string.min.js @@ -0,0 +1,3 @@ +/* underscore.string 3.2.2 | MIT licensed | http://epeli.github.com/underscore.string/ */ + +!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var r;"undefined"!=typeof window?r=window:"undefined"!=typeof global?r=global:"undefined"!=typeof self&&(r=self),r.s=e()}}(function(){return function e(r,t,n){function i(o,p){if(!t[o]){if(!r[o]){var u="function"==typeof require&&require;if(!p&&u)return u(o,!0);if(a)return a(o,!0);throw new Error("Cannot find module '"+o+"'")}var c=t[o]={exports:{}};r[o][0].call(c.exports,function(e){var t=r[o][1][e];return i(t?t:e)},c,c.exports,e,r,t,n)}return t[o].exports}for(var a="function"==typeof require&&require,o=0;o0?e.match(new RegExp(".{1,"+r+"}","g")):[e])}},{}],5:[function(e,r){var t=e("./capitalize"),n=e("./camelize"),i=e("./helper/makeString");r.exports=function(e){return e=i(e),t(n(e.replace(/[\W_]/g," ")).replace(/\s/g,""))}},{"./camelize":1,"./capitalize":2,"./helper/makeString":21}],6:[function(e,r){var t=e("./trim");r.exports=function(e){return t(e).replace(/\s\s+/g," ")}},{"./trim":63}],7:[function(e,r){var t=e("./helper/makeString"),n="ąàáäâãåæăćčĉęèéëêĝĥìíïîĵłľńňòóöőôõðøśșşšŝťțţŭùúüűûñÿýçżźž",i="aaaaaaaaaccceeeeeghiiiijllnnoooooooossssstttuuuuuunyyczzz";n+=n.toUpperCase(),i+=i.toUpperCase(),i=i.split(""),n+="ß",i.push("ss"),r.exports=function(e){return t(e).replace(/.{1}/g,function(e){var r=n.indexOf(e);return-1===r?e:i[r]})}},{"./helper/makeString":21}],8:[function(e,r){var t=e("./helper/makeString");r.exports=function(e,r){return e=t(e),r=t(r),0===e.length||0===r.length?0:e.split(r).length-1}},{"./helper/makeString":21}],9:[function(e,r){var t=e("./trim");r.exports=function(e){return t(e).replace(/([A-Z])/g,"-$1").replace(/[-_\s]+/g,"-").toLowerCase()}},{"./trim":63}],10:[function(e,r){var t=e("./helper/makeString");r.exports=function(e){return e=t(e),e.charAt(0).toLowerCase()+e.slice(1)}},{"./helper/makeString":21}],11:[function(e,r){function t(e){for(var r=e.match(/^[\s\\t]*/gm),t=r[0].length,n=1;n=0&&e.indexOf(r,i)===i}},{"./helper/makeString":21,"./helper/toPositive":23}],13:[function(e,r){var t=e("./helper/makeString"),n=e("./helper/escapeChars"),i="[";for(var a in n)i+=a;i+="]";var o=new RegExp(i,"g");r.exports=function(e){return t(e).replace(o,function(e){return"&"+n[e]+";"})}},{"./helper/escapeChars":18,"./helper/makeString":21}],14:[function(e,r){r.exports=function(){var e={};for(var r in this)this.hasOwnProperty(r)&&!r.match(/^(?:include|contains|reverse|join|map)$/)&&(e[r]=this[r]);return e}},{}],15:[function(e,r){"use strict";function t(e){return this instanceof t?void(this._wrapped=e):new t(e)}function n(e,r){"function"==typeof r&&(t.prototype[e]=function(){var e=[this._wrapped].concat(Array.prototype.slice.call(arguments)),n=r.apply(null,e);return"string"==typeof n?new t(n):n})}function i(e){n(e,function(r){var t=Array.prototype.slice.call(arguments,1);return String.prototype[e].apply(r,t)})}t.VERSION="3.2.2",t.isBlank=e("./isBlank"),t.stripTags=e("./stripTags"),t.capitalize=e("./capitalize"),t.decapitalize=e("./decapitalize"),t.chop=e("./chop"),t.trim=e("./trim"),t.clean=e("./clean"),t.cleanDiacritics=e("./cleanDiacritics"),t.count=e("./count"),t.chars=e("./chars"),t.swapCase=e("./swapCase"),t.escapeHTML=e("./escapeHTML"),t.unescapeHTML=e("./unescapeHTML"),t.splice=e("./splice"),t.insert=e("./insert"),t.replaceAll=e("./replaceAll"),t.include=e("./include"),t.join=e("./join"),t.lines=e("./lines"),t.dedent=e("./dedent"),t.reverse=e("./reverse"),t.startsWith=e("./startsWith"),t.endsWith=e("./endsWith"),t.pred=e("./pred"),t.succ=e("./succ"),t.titleize=e("./titleize"),t.camelize=e("./camelize"),t.underscored=e("./underscored"),t.dasherize=e("./dasherize"),t.classify=e("./classify"),t.humanize=e("./humanize"),t.ltrim=e("./ltrim"),t.rtrim=e("./rtrim"),t.truncate=e("./truncate"),t.prune=e("./prune"),t.words=e("./words"),t.pad=e("./pad"),t.lpad=e("./lpad"),t.rpad=e("./rpad"),t.lrpad=e("./lrpad"),t.sprintf=e("./sprintf"),t.vsprintf=e("./vsprintf"),t.toNumber=e("./toNumber"),t.numberFormat=e("./numberFormat"),t.strRight=e("./strRight"),t.strRightBack=e("./strRightBack"),t.strLeft=e("./strLeft"),t.strLeftBack=e("./strLeftBack"),t.toSentence=e("./toSentence"),t.toSentenceSerial=e("./toSentenceSerial"),t.slugify=e("./slugify"),t.surround=e("./surround"),t.quote=e("./quote"),t.unquote=e("./unquote"),t.repeat=e("./repeat"),t.naturalCmp=e("./naturalCmp"),t.levenshtein=e("./levenshtein"),t.toBoolean=e("./toBoolean"),t.exports=e("./exports"),t.escapeRegExp=e("./helper/escapeRegExp"),t.wrap=e("./wrap"),t.map=e("./map"),t.strip=t.trim,t.lstrip=t.ltrim,t.rstrip=t.rtrim,t.center=t.lrpad,t.rjust=t.lpad,t.ljust=t.rpad,t.contains=t.include,t.q=t.quote,t.toBool=t.toBoolean,t.camelcase=t.camelize,t.mapChars=t.map,t.prototype={value:function(){return this._wrapped}};for(var a in t)n(a,t[a]);n("tap",function(e,r){return r(e)});var o=["toUpperCase","toLowerCase","split","replace","slice","substring","substr","concat"];for(var p in o)i(o[p]);r.exports=t},{"./camelize":1,"./capitalize":2,"./chars":3,"./chop":4,"./classify":5,"./clean":6,"./cleanDiacritics":7,"./count":8,"./dasherize":9,"./decapitalize":10,"./dedent":11,"./endsWith":12,"./escapeHTML":13,"./exports":14,"./helper/escapeRegExp":19,"./humanize":24,"./include":25,"./insert":26,"./isBlank":27,"./join":28,"./levenshtein":29,"./lines":30,"./lpad":31,"./lrpad":32,"./ltrim":33,"./map":34,"./naturalCmp":35,"./numberFormat":36,"./pad":37,"./pred":38,"./prune":39,"./quote":40,"./repeat":41,"./replaceAll":42,"./reverse":43,"./rpad":44,"./rtrim":45,"./slugify":46,"./splice":47,"./sprintf":48,"./startsWith":49,"./strLeft":50,"./strLeftBack":51,"./strRight":52,"./strRightBack":53,"./stripTags":54,"./succ":55,"./surround":56,"./swapCase":57,"./titleize":58,"./toBoolean":59,"./toNumber":60,"./toSentence":61,"./toSentenceSerial":62,"./trim":63,"./truncate":64,"./underscored":65,"./unescapeHTML":66,"./unquote":67,"./vsprintf":68,"./words":69,"./wrap":70}],16:[function(e,r){var t=e("./makeString");r.exports=function(e,r){return e=t(e),0===e.length?"":e.slice(0,-1)+String.fromCharCode(e.charCodeAt(e.length-1)+r)}},{"./makeString":21}],17:[function(e,r){var t=e("./escapeRegExp");r.exports=function(e){return null==e?"\\s":e.source?e.source:"["+t(e)+"]"}},{"./escapeRegExp":19}],18:[function(e,r){var t={"¢":"cent","£":"pound","¥":"yen","€":"euro","©":"copy","®":"reg","<":"lt",">":"gt",'"':"quot","&":"amp","'":"#39"};r.exports=t},{}],19:[function(e,r){var t=e("./makeString");r.exports=function(e){return t(e).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")}},{"./makeString":21}],20:[function(e,r){var t={nbsp:" ",cent:"¢",pound:"£",yen:"¥",euro:"€",copy:"©",reg:"®",lt:"<",gt:">",quot:'"',amp:"&",apos:"'"};r.exports=t},{}],21:[function(e,r){r.exports=function(e){return null==e?"":""+e}},{}],22:[function(e,r){r.exports=function(e,r){if(1>r)return"";for(var t="";r>0;)1&r&&(t+=e),r>>=1,e+=e;return t}},{}],23:[function(e,r){r.exports=function(e){return 0>e?0:+e||0}},{}],24:[function(e,r){var t=e("./capitalize"),n=e("./underscored"),i=e("./trim");r.exports=function(e){return t(i(n(e).replace(/_id$/,"").replace(/_/g," ")))}},{"./capitalize":2,"./trim":63,"./underscored":65}],25:[function(e,r){var t=e("./helper/makeString");r.exports=function(e,r){return""===r?!0:-1!==t(e).indexOf(r)}},{"./helper/makeString":21}],26:[function(e,r){var t=e("./splice");r.exports=function(e,r,n){return t(e,r,0,n)}},{"./splice":47}],27:[function(e,r){var t=e("./helper/makeString");r.exports=function(e){return/^\s*$/.test(t(e))}},{"./helper/makeString":21}],28:[function(e,r){var t=e("./helper/makeString"),n=[].slice;r.exports=function(){var e=n.call(arguments),r=e.shift();return e.join(t(r))}},{"./helper/makeString":21}],29:[function(e,r){var t=e("./helper/makeString");r.exports=function(e,r){"use strict";if(e=t(e),r=t(r),e===r)return 0;if(!e||!r)return Math.max(e.length,r.length);for(var n=new Array(r.length+1),i=0;iu&&(a=u),u=n[o+1]+1,a>u&&(a=u),n[o]=p}n[o]=a}return a}},{"./helper/makeString":21}],30:[function(e,r){r.exports=function(e){return null==e?[]:String(e).split(/\r\n?|\n/)}},{}],31:[function(e,r){var t=e("./pad");r.exports=function(e,r,n){return t(e,r,n)}},{"./pad":37}],32:[function(e,r){var t=e("./pad");r.exports=function(e,r,n){return t(e,r,n,"both")}},{"./pad":37}],33:[function(e,r){var t=e("./helper/makeString"),n=e("./helper/defaultToWhiteSpace"),i=String.prototype.trimLeft;r.exports=function(e,r){return e=t(e),!r&&i?i.call(e):(r=n(r),e.replace(new RegExp("^"+r+"+"),""))}},{"./helper/defaultToWhiteSpace":17,"./helper/makeString":21}],34:[function(e,r){var t=e("./helper/makeString");r.exports=function(e,r){return e=t(e),0===e.length||"function"!=typeof r?e:e.replace(/./g,r)}},{"./helper/makeString":21}],35:[function(e,r){r.exports=function(e,r){if(e==r)return 0;if(!e)return-1;if(!r)return 1;for(var t=/(\.\d+|\d+|\D+)/g,n=String(e).match(t),i=String(r).match(t),a=Math.min(n.length,i.length),o=0;a>o;o++){var p=n[o],u=i[o];if(p!==u){var c=+p,s=+u;return c===c&&s===s?c>s?1:-1:u>p?-1:1}}return n.length!=i.length?n.length-i.length:r>e?-1:1}},{}],36:[function(e,r){r.exports=function(e,r,t,n){if(isNaN(e)||null==e)return"";e=e.toFixed(~~r),n="string"==typeof n?n:",";var i=e.split("."),a=i[0],o=i[1]?(t||".")+i[1]:"";return a.replace(/(\d)(?=(?:\d{3})+$)/g,"$1"+n)+o}},{}],37:[function(e,r){var t=e("./helper/makeString"),n=e("./helper/strRepeat");r.exports=function(e,r,i,a){e=t(e),r=~~r;var o=0;switch(i?i.length>1&&(i=i.charAt(0)):i=" ",a){case"right":return o=r-e.length,e+n(i,o);case"both":return o=r-e.length,n(i,Math.ceil(o/2))+e+n(i,Math.floor(o/2));default:return o=r-e.length,n(i,o)+e}}},{"./helper/makeString":21,"./helper/strRepeat":22}],38:[function(e,r){var t=e("./helper/adjacent");r.exports=function(e){return t(e,-1)}},{"./helper/adjacent":16}],39:[function(e,r){var t=e("./helper/makeString"),n=e("./rtrim");r.exports=function(e,r,i){if(e=t(e),r=~~r,i=null!=i?String(i):"...",e.length<=r)return e;var a=function(e){return e.toUpperCase()!==e.toLowerCase()?"A":" "},o=e.slice(0,r+1).replace(/.(?=\W*\w*$)/g,a);return o=o.slice(o.length-2).match(/\w\w/)?o.replace(/\s*\S+$/,""):n(o.slice(0,o.length-1)),(o+i).length>e.length?e:e.slice(0,o.length)+i}},{"./helper/makeString":21,"./rtrim":45}],40:[function(e,r){var t=e("./surround");r.exports=function(e,r){return t(e,r||'"')}},{"./surround":56}],41:[function(e,r){var t=e("./helper/makeString"),n=e("./helper/strRepeat");r.exports=function i(e,r,a){if(e=t(e),r=~~r,null==a)return n(e,r);for(var i=[];r>0;i[--r]=e);return i.join(a)}},{"./helper/makeString":21,"./helper/strRepeat":22}],42:[function(e,r){var t=e("./helper/makeString");r.exports=function(e,r,n,i){var a=i===!0?"gi":"g",o=new RegExp(r,a);return t(e).replace(o,n)}},{"./helper/makeString":21}],43:[function(e,r){var t=e("./chars");r.exports=function(e){return t(e).reverse().join("")}},{"./chars":3}],44:[function(e,r){var t=e("./pad");r.exports=function(e,r,n){return t(e,r,n,"right")}},{"./pad":37}],45:[function(e,r){var t=e("./helper/makeString"),n=e("./helper/defaultToWhiteSpace"),i=String.prototype.trimRight;r.exports=function(e,r){return e=t(e),!r&&i?i.call(e):(r=n(r),e.replace(new RegExp(r+"+$"),""))}},{"./helper/defaultToWhiteSpace":17,"./helper/makeString":21}],46:[function(e,r){var t=e("./trim"),n=e("./dasherize"),i=e("./cleanDiacritics");r.exports=function(e){return t(n(i(e).replace(/[^\w\s-]/g,"-").toLowerCase()),"-")}},{"./cleanDiacritics":7,"./dasherize":9,"./trim":63}],47:[function(e,r){var t=e("./chars");r.exports=function(e,r,n,i){var a=t(e);return a.splice(~~r,~~n,i),a.join("")}},{"./chars":3}],48:[function(e,r){var t=e("./helper/strRepeat"),n=Object.prototype.toString,i=function(){function e(e){return n.call(e).slice(8,-1).toLowerCase()}var r=t,a=function(){return a.cache.hasOwnProperty(arguments[0])||(a.cache[arguments[0]]=a.parse(arguments[0])),a.format.call(null,a.cache[arguments[0]],arguments)};return a.format=function(t,n){var a,o,p,u,c,s,l,f=1,h=t.length,g="",m=[];for(o=0;h>o;o++)if(g=e(t[o]),"string"===g)m.push(t[o]);else if("array"===g){if(u=t[o],u[2])for(a=n[f],p=0;p=0?"+"+a:a,s=u[4]?"0"==u[4]?"0":u[4].charAt(1):" ",l=u[6]-String(a).length,c=u[6]?r(s,l):"",m.push(u[5]?a+c:c+a)}return m.join("")},a.cache={},a.parse=function(e){for(var r=e,t=[],n=[],i=0;r;){if(null!==(t=/^[^\x25]+/.exec(r)))n.push(t[0]);else if(null!==(t=/^\x25{2}/.exec(r)))n.push("%");else{if(null===(t=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(r)))throw new Error("[_.sprintf] huh?");if(t[2]){i|=1;var a=[],o=t[2],p=[];if(null===(p=/^([a-z_][a-z_\d]*)/i.exec(o)))throw new Error("[_.sprintf] huh?");for(a.push(p[1]);""!==(o=o.substring(p[0].length));)if(null!==(p=/^\.([a-z_][a-z_\d]*)/i.exec(o)))a.push(p[1]);else{if(null===(p=/^\[(\d+)\]/.exec(o)))throw new Error("[_.sprintf] huh?");a.push(p[1])}t[2]=a}else i|=2;if(3===i)throw new Error("[_.sprintf] mixing positional and named placeholders is not (yet) supported");n.push(t)}r=r.substring(t[0].length)}return n},a}();r.exports=i},{"./helper/strRepeat":22}],49:[function(e,r){var t=e("./helper/makeString"),n=e("./helper/toPositive");r.exports=function(e,r,i){return e=t(e),r=""+r,i=null==i?0:Math.min(n(i),e.length),e.lastIndexOf(r,i)===i}},{"./helper/makeString":21,"./helper/toPositive":23}],50:[function(e,r){var t=e("./helper/makeString");r.exports=function(e,r){e=t(e),r=t(r);var n=r?e.indexOf(r):-1;return~n?e.slice(0,n):e}},{"./helper/makeString":21}],51:[function(e,r){var t=e("./helper/makeString");r.exports=function(e,r){e=t(e),r=t(r);var n=e.lastIndexOf(r);return~n?e.slice(0,n):e}},{"./helper/makeString":21}],52:[function(e,r){var t=e("./helper/makeString");r.exports=function(e,r){e=t(e),r=t(r);var n=r?e.indexOf(r):-1;return~n?e.slice(n+r.length,e.length):e}},{"./helper/makeString":21}],53:[function(e,r){var t=e("./helper/makeString");r.exports=function(e,r){e=t(e),r=t(r);var n=r?e.lastIndexOf(r):-1;return~n?e.slice(n+r.length,e.length):e}},{"./helper/makeString":21}],54:[function(e,r){var t=e("./helper/makeString");r.exports=function(e){return t(e).replace(/<\/?[^>]+>/g,"")}},{"./helper/makeString":21}],55:[function(e,r){var t=e("./helper/adjacent");r.exports=function(e){return t(e,1)}},{"./helper/adjacent":16}],56:[function(e,r){r.exports=function(e,r){return[r,e,r].join("")}},{}],57:[function(e,r){var t=e("./helper/makeString");r.exports=function(e){return t(e).replace(/\S/g,function(e){return e===e.toUpperCase()?e.toLowerCase():e.toUpperCase()})}},{"./helper/makeString":21}],58:[function(e,r){var t=e("./helper/makeString");r.exports=function(e){return t(e).toLowerCase().replace(/(?:^|\s|-)\S/g,function(e){return e.toUpperCase()})}},{"./helper/makeString":21}],59:[function(e,r){function t(e,r){var t,n,i=e.toLowerCase();for(r=[].concat(r),t=0;t2&&i&&(n=t(r)+n),a.length?a.join(r)+n+o:o}},{"./rtrim":45}],62:[function(e,r){var t=e("./toSentence");r.exports=function(e,r,n){return t(e,r,n,!0)}},{"./toSentence":61}],63:[function(e,r){var t=e("./helper/makeString"),n=e("./helper/defaultToWhiteSpace"),i=String.prototype.trim;r.exports=function(e,r){return e=t(e),!r&&i?i.call(e):(r=n(r),e.replace(new RegExp("^"+r+"+|"+r+"+$","g"),""))}},{"./helper/defaultToWhiteSpace":17,"./helper/makeString":21}],64:[function(e,r){var t=e("./helper/makeString");r.exports=function(e,r,n){return e=t(e),n=n||"...",r=~~r,e.length>r?e.slice(0,r)+n:e}},{"./helper/makeString":21}],65:[function(e,r){var t=e("./trim");r.exports=function(e){return t(e).replace(/([a-z\d])([A-Z]+)/g,"$1_$2").replace(/[-\s]+/g,"_").toLowerCase()}},{"./trim":63}],66:[function(e,r){var t=e("./helper/makeString"),n=e("./helper/htmlEntities");r.exports=function(e){return t(e).replace(/\&([^;]+);/g,function(e,r){var t;return r in n?n[r]:(t=r.match(/^#x([\da-fA-F]+)$/))?String.fromCharCode(parseInt(t[1],16)):(t=r.match(/^#(\d+)$/))?String.fromCharCode(~~t[1]):e})}},{"./helper/htmlEntities":20,"./helper/makeString":21}],67:[function(e,r){r.exports=function(e,r){return r=r||'"',e[0]===r&&e[e.length-1]===r?e.slice(1,e.length-1):e}},{}],68:[function(e,r){var t=e("./sprintf");r.exports=function(e,r){return r.unshift(e),t.apply(null,r)}},{"./sprintf":48}],69:[function(e,r){var t=e("./isBlank"),n=e("./trim");r.exports=function(e,r){return t(e)?[]:n(e,r).split(r||/\s+/)}},{"./isBlank":27,"./trim":63}],70:[function(e,r){var t=e("./helper/makeString");r.exports=function(e,r){e=t(e),r=r||{};var n,i=r.width||75,a=r.seperator||"\n",o=r.cut||!1,p=r.preserveSpaces||!1,u=r.trailingSpaces||!1;if(0>=i)return e;if(o){var c=0;for(n="";c0&&(n+=a),n+=e.charAt(c),c++;if(u)for(;c%i>0;)n+=" ",c++;return n}var s=e.split(" "),l=0;for(n="";s.length>0;){if(1+s[0].length+l>i&&l>0){if(p)n+=" ",l++;else if(u)for(;i>l;)n+=" ",l++;n+=a,l=0}l>0&&(n+=" ",l++),n+=s[0],l+=s[0].length,s.shift()}if(u)for(;i>l;)n+=" ",l++;return n}},{"./helper/makeString":21}]},{},[15])(15)}); \ No newline at end of file diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/endsWith.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/endsWith.js new file mode 100644 index 0000000..c452603 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/endsWith.js @@ -0,0 +1,13 @@ +var makeString = require('./helper/makeString'); +var toPositive = require('./helper/toPositive'); + +module.exports = function endsWith(str, ends, position) { + str = makeString(str); + ends = '' + ends; + if (typeof position == 'undefined') { + position = str.length - ends.length; + } else { + position = Math.min(toPositive(position), str.length) - ends.length; + } + return position >= 0 && str.indexOf(ends, position) === position; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/escapeHTML.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/escapeHTML.js new file mode 100644 index 0000000..7761bf2 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/escapeHTML.js @@ -0,0 +1,17 @@ +var makeString = require('./helper/makeString'); +var escapeChars = require('./helper/escapeChars'); + +var regexString = "["; +for(var key in escapeChars) { + regexString += key; +} +regexString += "]"; + +var regex = new RegExp( regexString, 'g'); + +module.exports = function escapeHTML(str) { + + return makeString(str).replace(regex, function(m) { + return '&' + escapeChars[m] + ';'; + }); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/exports.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/exports.js new file mode 100644 index 0000000..501010b --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/exports.js @@ -0,0 +1,10 @@ +module.exports = function() { + var result = {}; + + for (var prop in this) { + if (!this.hasOwnProperty(prop) || prop.match(/^(?:include|contains|reverse|join|map)$/)) continue; + result[prop] = this[prop]; + } + + return result; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/gulpfile.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/gulpfile.js new file mode 100644 index 0000000..244bc01 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/gulpfile.js @@ -0,0 +1,112 @@ +var gulp = require('gulp-param')(require('gulp'), process.argv), + mocha = require("gulp-mocha"), + eslint = require('gulp-eslint'), + istanbul = require('gulp-istanbul'), + bench = require('gulp-bench'), + uglify = require('gulp-uglify'), + rimraf = require('gulp-rimraf'), + bump = require('gulp-bump'), + replace = require('gulp-replace'), + rename = require('gulp-rename'), + browserify = require('gulp-browserify'), + header = require('gulp-header'), + SRC = 'index.js', + DEST = 'dist', + SRC_COMPILED = 'underscore.string.js', + MIN_FILE = 'underscore.string.min.js', + VERSION_FILES = ['./package.json', './component.json', './bower.json'], + VERSION_FILES_JS = [SRC, 'package.js'], + package = require('./package.json'), + headerText = '/* ' + package.name + ' ' + package.version + ' | ' + + package.license + ' licensed | ' + package.homepage + ' */\n\n'; + +gulp.task('test', ['lint', 'browserify'], function(cov) { + var reporters = ['html']; + + if (cov) { + reporters.push('text'); + } else { + reporters.push('text-summary'); + } + + return gulp.src(['*.js', 'helper/*.js']) + .pipe(istanbul()) + .pipe(istanbul.hookRequire()) + .on('finish', function () { + return gulp.src(['tests/*.js']) + .pipe(mocha({ + ui: 'qunit', + reporter: 'dot' + })) + .pipe(istanbul.writeReports({ + reporters: reporters + })); + }); +}); + +gulp.task('lint', function() { + var toLint = [ + '**/*.js', + '!gulpfile.js', + '!meteor-*.js', + '!package.js', + '!dist/**', + '!coverage/**', + '!node_modules/**' + ]; + return gulp.src(toLint) + .pipe(eslint({ fix: true })) + .pipe(eslint.format()) + .pipe(eslint.failAfterError()); +}); + +gulp.task('bench', ['browserify'], function(func) { + func = func || '*'; + return gulp.src('bench/'+ func + '.js') + .pipe(bench()); +}); + +gulp.task('browserify', function() { + return gulp.src(SRC) + .pipe(browserify({ + detectGlobals: true, + standalone: 's' + })) + .pipe(header(headerText)) + .pipe(rename('underscore.string.js')) + .pipe(gulp.dest(DEST)); +}); + +gulp.task('clean', function() { + return gulp.src(DEST) + .pipe(rimraf()); +}); + +gulp.task('bump-in-js', function(semver) { + return gulp.src(VERSION_FILES_JS) + .pipe(replace(/(version?\s?=?\:?\s\')([\d\.]*)\'/gi, '$1' + semver + "'")) + .pipe(gulp.dest('./')); +}); + +// usage: gulp bump -s <% Version %> +// usage: gulp bump --semver <% Version %> +gulp.task('bump', ['bump-in-js'], function(semver) { + if (typeof semver !== 'string' || semver.length <= 0) { + console.error('pass a new version `gulp bump --semver 2.4.1`'); + process.exit(1); + } + + return gulp.src(VERSION_FILES) + .pipe(bump({ + version: semver + })) + .pipe(gulp.dest('./')); +}); + +gulp.task('build', ['test', 'clean'], function() { + gulp.src(DEST + '/' + SRC_COMPILED) + .pipe(uglify()) + .pipe(header(headerText)) + .pipe(rename(MIN_FILE)) + .pipe(gulp.dest(DEST)); +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/adjacent.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/adjacent.js new file mode 100644 index 0000000..bd26013 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/adjacent.js @@ -0,0 +1,9 @@ +var makeString = require('./makeString'); + +module.exports = function adjacent(str, direction) { + str = makeString(str); + if (str.length === 0) { + return ''; + } + return str.slice(0, -1) + String.fromCharCode(str.charCodeAt(str.length - 1) + direction); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/defaultToWhiteSpace.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/defaultToWhiteSpace.js new file mode 100644 index 0000000..0cd9f06 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/defaultToWhiteSpace.js @@ -0,0 +1,10 @@ +var escapeRegExp = require('./escapeRegExp'); + +module.exports = function defaultToWhiteSpace(characters) { + if (characters == null) + return '\\s'; + else if (characters.source) + return characters.source; + else + return '[' + escapeRegExp(characters) + ']'; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/escapeChars.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/escapeChars.js new file mode 100644 index 0000000..25f4a9a --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/escapeChars.js @@ -0,0 +1,19 @@ +/* We're explicitly defining the list of entities we want to escape. +nbsp is an HTML entity, but we don't want to escape all space characters in a string, hence its omission in this map. + +*/ +var escapeChars = { + '¢' : 'cent', + '£' : 'pound', + '¥' : 'yen', + '€': 'euro', + '©' :'copy', + '®' : 'reg', + '<' : 'lt', + '>' : 'gt', + '"' : 'quot', + '&' : 'amp', + "'" : '#39' +}; + +module.exports = escapeChars; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/escapeRegExp.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/escapeRegExp.js new file mode 100644 index 0000000..01097fb --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/escapeRegExp.js @@ -0,0 +1,5 @@ +var makeString = require('./makeString'); + +module.exports = function escapeRegExp(str) { + return makeString(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/htmlEntities.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/htmlEntities.js new file mode 100644 index 0000000..7bd74cb --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/htmlEntities.js @@ -0,0 +1,19 @@ +/* +We're explicitly defining the list of entities that might see in escape HTML strings +*/ +var htmlEntities = { + nbsp: ' ', + cent: '¢', + pound: '£', + yen: '¥', + euro: '€', + copy: '©', + reg: '®', + lt: '<', + gt: '>', + quot: '"', + amp: '&', + apos: "'" +}; + +module.exports = htmlEntities; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/makeString.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/makeString.js new file mode 100644 index 0000000..3b279ab --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/makeString.js @@ -0,0 +1,7 @@ +/** + * Ensure some object is a coerced to a string + **/ +module.exports = function makeString(object) { + if (object == null) return ''; + return '' + object; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/strRepeat.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/strRepeat.js new file mode 100644 index 0000000..b60d876 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/strRepeat.js @@ -0,0 +1,9 @@ +module.exports = function strRepeat(str, qty){ + if (qty < 1) return ''; + var result = ''; + while (qty > 0) { + if (qty & 1) result += str; + qty >>= 1, str += str; + } + return result; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/toPositive.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/toPositive.js new file mode 100644 index 0000000..6dda0a3 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/helper/toPositive.js @@ -0,0 +1,3 @@ +module.exports = function toPositive(number) { + return number < 0 ? 0 : (+number || 0); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/humanize.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/humanize.js new file mode 100644 index 0000000..8f82d07 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/humanize.js @@ -0,0 +1,7 @@ +var capitalize = require('./capitalize'); +var underscored = require('./underscored'); +var trim = require('./trim'); + +module.exports = function humanize(str) { + return capitalize(trim(underscored(str).replace(/_id$/, '').replace(/_/g, ' '))); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/include.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/include.js new file mode 100644 index 0000000..a2e910f --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/include.js @@ -0,0 +1,6 @@ +var makeString = require('./helper/makeString'); + +module.exports = function include(str, needle) { + if (needle === '') return true; + return makeString(str).indexOf(needle) !== -1; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/index.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/index.js new file mode 100644 index 0000000..3cafb4f --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/index.js @@ -0,0 +1,140 @@ +// Underscore.string +// (c) 2010 Esa-Matti Suuronen +// Underscore.string is freely distributable under the terms of the MIT license. +// Documentation: https://github.com/epeli/underscore.string +// Some code is borrowed from MooTools and Alexandru Marasteanu. +// Version '3.2.3' + +'use strict'; + +function s(value) { + /* jshint validthis: true */ + if (!(this instanceof s)) return new s(value); + this._wrapped = value; +} + +s.VERSION = '3.2.3'; + +s.isBlank = require('./isBlank'); +s.stripTags = require('./stripTags'); +s.capitalize = require('./capitalize'); +s.decapitalize = require('./decapitalize'); +s.chop = require('./chop'); +s.trim = require('./trim'); +s.clean = require('./clean'); +s.cleanDiacritics = require('./cleanDiacritics'); +s.count = require('./count'); +s.chars = require('./chars'); +s.swapCase = require('./swapCase'); +s.escapeHTML = require('./escapeHTML'); +s.unescapeHTML = require('./unescapeHTML'); +s.splice = require('./splice'); +s.insert = require('./insert'); +s.replaceAll = require('./replaceAll'); +s.include = require('./include'); +s.join = require('./join'); +s.lines = require('./lines'); +s.dedent = require('./dedent'); +s.reverse = require('./reverse'); +s.startsWith = require('./startsWith'); +s.endsWith = require('./endsWith'); +s.pred = require('./pred'); +s.succ = require('./succ'); +s.titleize = require('./titleize'); +s.camelize = require('./camelize'); +s.underscored = require('./underscored'); +s.dasherize = require('./dasherize'); +s.classify = require('./classify'); +s.humanize = require('./humanize'); +s.ltrim = require('./ltrim'); +s.rtrim = require('./rtrim'); +s.truncate = require('./truncate'); +s.prune = require('./prune'); +s.words = require('./words'); +s.pad = require('./pad'); +s.lpad = require('./lpad'); +s.rpad = require('./rpad'); +s.lrpad = require('./lrpad'); +s.sprintf = require('./sprintf'); +s.vsprintf = require('./vsprintf'); +s.toNumber = require('./toNumber'); +s.numberFormat = require('./numberFormat'); +s.strRight = require('./strRight'); +s.strRightBack = require('./strRightBack'); +s.strLeft = require('./strLeft'); +s.strLeftBack = require('./strLeftBack'); +s.toSentence = require('./toSentence'); +s.toSentenceSerial = require('./toSentenceSerial'); +s.slugify = require('./slugify'); +s.surround = require('./surround'); +s.quote = require('./quote'); +s.unquote = require('./unquote'); +s.repeat = require('./repeat'); +s.naturalCmp = require('./naturalCmp'); +s.levenshtein = require('./levenshtein'); +s.toBoolean = require('./toBoolean'); +s.exports = require('./exports'); +s.escapeRegExp = require('./helper/escapeRegExp'); +s.wrap = require('./wrap'); +s.map = require('./map'); + +// Aliases +s.strip = s.trim; +s.lstrip = s.ltrim; +s.rstrip = s.rtrim; +s.center = s.lrpad; +s.rjust = s.lpad; +s.ljust = s.rpad; +s.contains = s.include; +s.q = s.quote; +s.toBool = s.toBoolean; +s.camelcase = s.camelize; +s.mapChars = s.map; + + +// Implement chaining +s.prototype = { + value: function value() { + return this._wrapped; + } +}; + +function fn2method(key, fn) { + if (typeof fn !== "function") return; + s.prototype[key] = function() { + var args = [this._wrapped].concat(Array.prototype.slice.call(arguments)); + var res = fn.apply(null, args); + // if the result is non-string stop the chain and return the value + return typeof res === 'string' ? new s(res) : res; + }; +} + +// Copy functions to instance methods for chaining +for (var key in s) fn2method(key, s[key]); + +fn2method("tap", function tap(string, fn) { + return fn(string); +}); + +function prototype2method(methodName) { + fn2method(methodName, function(context) { + var args = Array.prototype.slice.call(arguments, 1); + return String.prototype[methodName].apply(context, args); + }); +} + +var prototypeMethods = [ + "toUpperCase", + "toLowerCase", + "split", + "replace", + "slice", + "substring", + "substr", + "concat" +]; + +for (var method in prototypeMethods) prototype2method(prototypeMethods[method]); + + +module.exports = s; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/insert.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/insert.js new file mode 100644 index 0000000..1c99c3b --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/insert.js @@ -0,0 +1,5 @@ +var splice = require('./splice'); + +module.exports = function insert(str, i, substr) { + return splice(str, i, 0, substr); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/isBlank.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/isBlank.js new file mode 100644 index 0000000..386e819 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/isBlank.js @@ -0,0 +1,5 @@ +var makeString = require('./helper/makeString'); + +module.exports = function isBlank(str) { + return (/^\s*$/).test(makeString(str)); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/join.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/join.js new file mode 100644 index 0000000..b1a18ca --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/join.js @@ -0,0 +1,9 @@ +var makeString = require('./helper/makeString'); +var slice = [].slice; + +module.exports = function join() { + var args = slice.call(arguments), + separator = args.shift(); + + return args.join(makeString(separator)); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/levenshtein.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/levenshtein.js new file mode 100644 index 0000000..85f220c --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/levenshtein.js @@ -0,0 +1,52 @@ +var makeString = require('./helper/makeString'); + +/** + * Based on the implementation here: https://github.com/hiddentao/fast-levenshtein + */ +module.exports = function levenshtein(str1, str2) { + 'use strict'; + str1 = makeString(str1); + str2 = makeString(str2); + + // Short cut cases + if (str1 === str2) return 0; + if (!str1 || !str2) return Math.max(str1.length, str2.length); + + // two rows + var prevRow = new Array(str2.length + 1); + + // initialise previous row + for (var i = 0; i < prevRow.length; ++i) { + prevRow[i] = i; + } + + // calculate current row distance from previous row + for (i = 0; i < str1.length; ++i) { + var nextCol = i + 1; + + for (var j = 0; j < str2.length; ++j) { + var curCol = nextCol; + + // substution + nextCol = prevRow[j] + ( (str1.charAt(i) === str2.charAt(j)) ? 0 : 1 ); + // insertion + var tmp = curCol + 1; + if (nextCol > 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; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/lines.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/lines.js new file mode 100644 index 0000000..40b11cc --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/lines.js @@ -0,0 +1,4 @@ +module.exports = function lines(str) { + if (str == null) return []; + return String(str).split(/\r\n?|\n/); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/lpad.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/lpad.js new file mode 100644 index 0000000..ada8c7e --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/lpad.js @@ -0,0 +1,5 @@ +var pad = require('./pad'); + +module.exports = function lpad(str, length, padStr) { + return pad(str, length, padStr); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/lrpad.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/lrpad.js new file mode 100644 index 0000000..e3162b0 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/lrpad.js @@ -0,0 +1,5 @@ +var pad = require('./pad'); + +module.exports = function lrpad(str, length, padStr) { + return pad(str, length, padStr, 'both'); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/ltrim.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/ltrim.js new file mode 100644 index 0000000..858936e --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/ltrim.js @@ -0,0 +1,10 @@ +var makeString = require('./helper/makeString'); +var defaultToWhiteSpace = require('./helper/defaultToWhiteSpace'); +var nativeTrimLeft = String.prototype.trimLeft; + +module.exports = function ltrim(str, characters) { + str = makeString(str); + if (!characters && nativeTrimLeft) return nativeTrimLeft.call(str); + characters = defaultToWhiteSpace(characters); + return str.replace(new RegExp('^' + characters + '+'), ''); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/map.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/map.js new file mode 100644 index 0000000..c2910ae --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/map.js @@ -0,0 +1,9 @@ +var makeString = require('./helper/makeString'); + +module.exports = function(str, callback) { + str = makeString(str); + + if (str.length === 0 || typeof callback !== 'function') return str; + + return str.replace(/./g, callback); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/meteor-post.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/meteor-post.js new file mode 100644 index 0000000..3f38d8d --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/meteor-post.js @@ -0,0 +1,2 @@ +// s will be picked up by Meteor and exported +s = module.exports; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/meteor-pre.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/meteor-pre.js new file mode 100644 index 0000000..e692bc3 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/meteor-pre.js @@ -0,0 +1,6 @@ +// Defining this will trick dist/underscore.string.js into putting its exports into module.exports +// Credit to Tim Heckel for this trick - see https://github.com/TimHeckel/meteor-underscore-string +module = {}; + +// This also needed, otherwise above doesn't work??? +exports = {}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/naturalCmp.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/naturalCmp.js new file mode 100644 index 0000000..7cb94e6 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/naturalCmp.js @@ -0,0 +1,29 @@ +module.exports = function naturalCmp(str1, str2) { + if (str1 == str2) return 0; + if (!str1) return -1; + if (!str2) return 1; + + var cmpRegex = /(\.\d+|\d+|\D+)/g, + tokens1 = String(str1).match(cmpRegex), + tokens2 = String(str2).match(cmpRegex), + count = Math.min(tokens1.length, tokens2.length); + + for (var i = 0; i < count; i++) { + var a = tokens1[i], + b = tokens2[i]; + + if (a !== b) { + var num1 = +a; + var num2 = +b; + if (num1 === num1 && num2 === num2) { + return num1 > num2 ? 1 : -1; + } + return a < b ? -1 : 1; + } + } + + if (tokens1.length != tokens2.length) + return tokens1.length - tokens2.length; + + return str1 < str2 ? -1 : 1; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/numberFormat.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/numberFormat.js new file mode 100644 index 0000000..6a681fe --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/numberFormat.js @@ -0,0 +1,12 @@ +module.exports = function numberFormat(number, dec, dsep, tsep) { + if (isNaN(number) || number == null) return ''; + + number = number.toFixed(~~dec); + tsep = typeof tsep == 'string' ? tsep : ','; + + var parts = number.split('.'), + fnums = parts[0], + decimals = parts[1] ? (dsep || '.') + parts[1] : ''; + + return fnums.replace(/(\d)(?=(?:\d{3})+$)/g, '$1' + tsep) + decimals; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/package.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/package.js new file mode 100644 index 0000000..84816df --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/package.js @@ -0,0 +1,16 @@ +// package metadata file for Meteor.js + +Package.describe({ + name: 'underscorestring:underscore.string', + summary: 'underscore.string (official): String manipulation extensions for Underscore.js javascript library.', + version: '3.2.3', + git: 'https://github.com/epeli/underscore.string.git', + documentation: 'README.markdown' +}); + + +Package.onUse(function (api) { + api.versionsFrom('METEOR@1.0'); + api.addFiles(['meteor-pre.js','dist/underscore.string.js','meteor-post.js']); + api.export("s"); +}); diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/package.json b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/package.json new file mode 100644 index 0000000..d604856 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/package.json @@ -0,0 +1,162 @@ +{ + "_args": [ + [ + { + "raw": "underscore.string@~3.2.3", + "scope": null, + "escapedName": "underscore.string", + "name": "underscore.string", + "rawSpec": "~3.2.3", + "spec": ">=3.2.3 <3.3.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt-sftp-deploy/node_modules/grunt-legacy-log" + ] + ], + "_from": "underscore.string@>=3.2.3 <3.3.0", + "_id": "underscore.string@3.2.3", + "_inCache": true, + "_location": "/grunt-sftp-deploy/underscore.string", + "_nodeVersion": "5.4.1", + "_npmUser": { + "name": "epeli", + "email": "esa-matti@suuronen.org" + }, + "_npmVersion": "3.3.12", + "_phantomChildren": {}, + "_requested": { + "raw": "underscore.string@~3.2.3", + "scope": null, + "escapedName": "underscore.string", + "name": "underscore.string", + "rawSpec": "~3.2.3", + "spec": ">=3.2.3 <3.3.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt-sftp-deploy/grunt-legacy-log", + "/grunt-sftp-deploy/grunt-legacy-util" + ], + "_resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.2.3.tgz", + "_shasum": "806992633665d5e5fcb4db1fb3a862eb68e9e6da", + "_shrinkwrap": null, + "_spec": "underscore.string@~3.2.3", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt-sftp-deploy/node_modules/grunt-legacy-log", + "bugs": { + "url": "https://github.com/epeli/underscore.string/issues" + }, + "contributors": [ + { + "name": "Esa-Matti Suuronen", + "email": "esa-matti@suuronen.org", + "url": "http://esa-matti.suuronen.org/" + }, + { + "name": "Edward Tsech", + "email": "edtsech@gmail.com" + }, + { + "name": "Pavel Pravosud", + "email": "pavel@pravosud.com", + "url": "" + }, + { + "name": "Sasha Koss", + "email": "kossnocorp@gmail.com", + "url": "http://koss.nocorp.me/" + }, + { + "name": "Vladimir Dronnikov", + "email": "dronnikov@gmail.com" + }, + { + "name": "Pete Kruckenberg", + "email": "https://github.com/kruckenb", + "url": "" + }, + { + "name": "Paul Chavard", + "email": "paul@chavard.net", + "url": "" + }, + { + "name": "Ed Finkler", + "email": "coj@funkatron.com", + "url": "" + } + ], + "dependencies": {}, + "description": "String manipulation extensions for Underscore.js javascript library.", + "devDependencies": { + "gulp": "^3.8.11", + "gulp-bench": "^1.1.0", + "gulp-browserify": "~0.5.0", + "gulp-bump": "~0.1.11", + "gulp-eslint": "^1.1.1", + "gulp-header": "^1.2.2", + "gulp-istanbul": "^0.6.0", + "gulp-mocha": "^2.0.0", + "gulp-param": "~0.6.3", + "gulp-rename": "~1.2.0", + "gulp-replace": "~0.5.0", + "gulp-rimraf": "^0.1.1", + "gulp-uglify": "~1.0.1", + "mocha": "^2.1.0", + "underscore": "^1.7.0" + }, + "directories": { + "lib": "./" + }, + "dist": { + "shasum": "806992633665d5e5fcb4db1fb3a862eb68e9e6da", + "tarball": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.2.3.tgz" + }, + "engines": { + "node": "*" + }, + "gitHead": "b22908f697817e8234b8f779622d155f16651c23", + "homepage": "http://epeli.github.com/underscore.string/", + "jshintConfig": { + "node": true, + "browser": true, + "qunit": true, + "globals": { + "s": true + } + }, + "keywords": [ + "underscore", + "string" + ], + "license": "MIT", + "main": "./index.js", + "maintainers": [ + { + "name": "edtsech", + "email": "edtsech@gmail.com" + }, + { + "name": "rwz", + "email": "rwz@duckroll.ru" + }, + { + "name": "epeli", + "email": "esa-matti@suuronen.org" + }, + { + "name": "schtoeffel", + "email": "schtoeffel@gmail.com" + } + ], + "name": "underscore.string", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/epeli/underscore.string.git" + }, + "scripts": { + "test": "gulp test" + }, + "version": "3.2.3" +} diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/pad.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/pad.js new file mode 100644 index 0000000..ae853e0 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/pad.js @@ -0,0 +1,26 @@ +var makeString = require('./helper/makeString'); +var strRepeat = require('./helper/strRepeat'); + +module.exports = function pad(str, length, padStr, type) { + str = makeString(str); + length = ~~length; + + var padlen = 0; + + if (!padStr) + padStr = ' '; + else if (padStr.length > 1) + padStr = padStr.charAt(0); + + switch (type) { + case 'right': + padlen = length - str.length; + return str + strRepeat(padStr, padlen); + case 'both': + padlen = length - str.length; + return strRepeat(padStr, Math.ceil(padlen / 2)) + str + strRepeat(padStr, Math.floor(padlen / 2)); + default: // 'left' + padlen = length - str.length; + return strRepeat(padStr, padlen) + str; + } +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/pred.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/pred.js new file mode 100644 index 0000000..a123701 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/pred.js @@ -0,0 +1,5 @@ +var adjacent = require('./helper/adjacent'); + +module.exports = function succ(str) { + return adjacent(str, -1); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/prune.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/prune.js new file mode 100644 index 0000000..8f2d0cb --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/prune.js @@ -0,0 +1,27 @@ +/** + * _s.prune: a more elegant version of truncate + * prune extra chars, never leaving a half-chopped word. + * @author github.com/rwz + */ +var makeString = require('./helper/makeString'); +var rtrim = require('./rtrim'); + +module.exports = function prune(str, length, pruneStr) { + str = makeString(str); + length = ~~length; + pruneStr = pruneStr != null ? String(pruneStr) : '...'; + + if (str.length <= length) return str; + + var tmpl = function(c) { + return c.toUpperCase() !== c.toLowerCase() ? 'A' : ' '; + }, + template = str.slice(0, length + 1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA' + + if (template.slice(template.length - 2).match(/\w\w/)) + template = template.replace(/\s*\S+$/, ''); + else + template = rtrim(template.slice(0, template.length - 1)); + + return (template + pruneStr).length > str.length ? str : str.slice(0, template.length) + pruneStr; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/quote.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/quote.js new file mode 100644 index 0000000..1e90f63 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/quote.js @@ -0,0 +1,5 @@ +var surround = require('./surround'); + +module.exports = function quote(str, quoteChar) { + return surround(str, quoteChar || '"'); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/repeat.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/repeat.js new file mode 100644 index 0000000..71228ed --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/repeat.js @@ -0,0 +1,16 @@ +var makeString = require('./helper/makeString'); +var strRepeat = require('./helper/strRepeat'); + +module.exports = function repeat(str, qty, separator) { + str = makeString(str); + + qty = ~~qty; + + // using faster implementation if separator is not needed; + if (separator == null) return strRepeat(str, qty); + + // this one is about 300x slower in Google Chrome + /*eslint no-empty: 0*/ + for (var repeat = []; qty > 0; repeat[--qty] = str) {} + return repeat.join(separator); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/replaceAll.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/replaceAll.js new file mode 100644 index 0000000..93f6c0d --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/replaceAll.js @@ -0,0 +1,8 @@ +var makeString = require('./helper/makeString'); + +module.exports = function replaceAll(str, find, replace, ignorecase) { + var flags = (ignorecase === true)?'gi':'g'; + var reg = new RegExp(find, flags); + + return makeString(str).replace(reg, replace); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/reverse.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/reverse.js new file mode 100644 index 0000000..b9ef2e6 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/reverse.js @@ -0,0 +1,5 @@ +var chars = require('./chars'); + +module.exports = function reverse(str) { + return chars(str).reverse().join(''); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/rpad.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/rpad.js new file mode 100644 index 0000000..b37d386 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/rpad.js @@ -0,0 +1,5 @@ +var pad = require('./pad'); + +module.exports = function rpad(str, length, padStr) { + return pad(str, length, padStr, 'right'); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/rtrim.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/rtrim.js new file mode 100644 index 0000000..e6be2ed --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/rtrim.js @@ -0,0 +1,10 @@ +var makeString = require('./helper/makeString'); +var defaultToWhiteSpace = require('./helper/defaultToWhiteSpace'); +var nativeTrimRight = String.prototype.trimRight; + +module.exports = function rtrim(str, characters) { + str = makeString(str); + if (!characters && nativeTrimRight) return nativeTrimRight.call(str); + characters = defaultToWhiteSpace(characters); + return str.replace(new RegExp(characters + '+$'), ''); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/slugify.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/slugify.js new file mode 100644 index 0000000..36dc73a --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/slugify.js @@ -0,0 +1,7 @@ +var trim = require('./trim'); +var dasherize = require('./dasherize'); +var cleanDiacritics = require("./cleanDiacritics"); + +module.exports = function slugify(str) { + return trim(dasherize(cleanDiacritics(str).replace(/[^\w\s-]/g, '-').toLowerCase()), '-'); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/splice.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/splice.js new file mode 100644 index 0000000..34c0410 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/splice.js @@ -0,0 +1,7 @@ +var chars = require('./chars'); + +module.exports = function splice(str, i, howmany, substr) { + var arr = chars(str); + arr.splice(~~i, ~~howmany, substr); + return arr.join(''); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/sprintf.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/sprintf.js new file mode 100644 index 0000000..c6da4e3 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/sprintf.js @@ -0,0 +1,124 @@ +// sprintf() for JavaScript 0.7-beta1 +// http://www.diveintojavascript.com/projects/javascript-sprintf +// +// Copyright (c) Alexandru Marasteanu +// All rights reserved. +var strRepeat = require('./helper/strRepeat'); +var toString = Object.prototype.toString; +var sprintf = (function() { + function get_type(variable) { + return toString.call(variable).slice(8, -1).toLowerCase(); + } + + var str_repeat = strRepeat; + + var str_format = function() { + if (!str_format.cache.hasOwnProperty(arguments[0])) { + str_format.cache[arguments[0]] = str_format.parse(arguments[0]); + } + return str_format.format.call(null, str_format.cache[arguments[0]], arguments); + }; + + str_format.format = function(parse_tree, argv) { + var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length; + for (i = 0; i < tree_length; i++) { + node_type = get_type(parse_tree[i]); + if (node_type === 'string') { + output.push(parse_tree[i]); + } + else if (node_type === 'array') { + match = parse_tree[i]; // convenience purposes only + if (match[2]) { // keyword argument + arg = argv[cursor]; + for (k = 0; k < match[2].length; k++) { + if (!arg.hasOwnProperty(match[2][k])) { + throw new Error(sprintf('[_.sprintf] property "%s" does not exist', match[2][k])); + } + arg = arg[match[2][k]]; + } + } else if (match[1]) { // positional argument (explicit) + arg = argv[match[1]]; + } + else { // positional argument (implicit) + arg = argv[cursor++]; + } + + if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) { + throw new Error(sprintf('[_.sprintf] expecting number but found %s', get_type(arg))); + } + switch (match[8]) { + case 'b': arg = arg.toString(2); break; + case 'c': arg = String.fromCharCode(arg); break; + case 'd': arg = parseInt(arg, 10); break; + case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; + case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; + case 'o': arg = arg.toString(8); break; + case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break; + case 'u': arg = Math.abs(arg); break; + case 'x': arg = arg.toString(16); break; + case 'X': arg = arg.toString(16).toUpperCase(); break; + } + arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); + pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' '; + pad_length = match[6] - String(arg).length; + pad = match[6] ? str_repeat(pad_character, pad_length) : ''; + output.push(match[5] ? arg + pad : pad + arg); + } + } + return output.join(''); + }; + + str_format.cache = {}; + + str_format.parse = function(fmt) { + var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; + while (_fmt) { + if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { + parse_tree.push(match[0]); + } + else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { + parse_tree.push('%'); + } + else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { + if (match[2]) { + arg_names |= 1; + var field_list = [], replacement_field = match[2], field_match = []; + if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { + if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + } + else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + } + else { + throw new Error('[_.sprintf] huh?'); + } + } + } + else { + throw new Error('[_.sprintf] huh?'); + } + match[2] = field_list; + } + else { + arg_names |= 2; + } + if (arg_names === 3) { + throw new Error('[_.sprintf] mixing positional and named placeholders is not (yet) supported'); + } + parse_tree.push(match); + } + else { + throw new Error('[_.sprintf] huh?'); + } + _fmt = _fmt.substring(match[0].length); + } + return parse_tree; + }; + + return str_format; +})(); + +module.exports = sprintf; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/startsWith.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/startsWith.js new file mode 100644 index 0000000..a9f4790 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/startsWith.js @@ -0,0 +1,9 @@ +var makeString = require('./helper/makeString'); +var toPositive = require('./helper/toPositive'); + +module.exports = function startsWith(str, starts, position) { + str = makeString(str); + starts = '' + starts; + position = position == null ? 0 : Math.min(toPositive(position), str.length); + return str.lastIndexOf(starts, position) === position; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/strLeft.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/strLeft.js new file mode 100644 index 0000000..0602984 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/strLeft.js @@ -0,0 +1,8 @@ +var makeString = require('./helper/makeString'); + +module.exports = function strLeft(str, sep) { + str = makeString(str); + sep = makeString(sep); + var pos = !sep ? -1 : str.indexOf(sep); + return~ pos ? str.slice(0, pos) : str; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/strLeftBack.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/strLeftBack.js new file mode 100644 index 0000000..0136e20 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/strLeftBack.js @@ -0,0 +1,8 @@ +var makeString = require('./helper/makeString'); + +module.exports = function strLeftBack(str, sep) { + str = makeString(str); + sep = makeString(sep); + var pos = str.lastIndexOf(sep); + return~ pos ? str.slice(0, pos) : str; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/strRight.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/strRight.js new file mode 100644 index 0000000..67b45b5 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/strRight.js @@ -0,0 +1,8 @@ +var makeString = require('./helper/makeString'); + +module.exports = function strRight(str, sep) { + str = makeString(str); + sep = makeString(sep); + var pos = !sep ? -1 : str.indexOf(sep); + return~ pos ? str.slice(pos + sep.length, str.length) : str; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/strRightBack.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/strRightBack.js new file mode 100644 index 0000000..43de0e9 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/strRightBack.js @@ -0,0 +1,8 @@ +var makeString = require('./helper/makeString'); + +module.exports = function strRightBack(str, sep) { + str = makeString(str); + sep = makeString(sep); + var pos = !sep ? -1 : str.lastIndexOf(sep); + return~ pos ? str.slice(pos + sep.length, str.length) : str; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/stripTags.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/stripTags.js new file mode 100644 index 0000000..8948d36 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/stripTags.js @@ -0,0 +1,5 @@ +var makeString = require('./helper/makeString'); + +module.exports = function stripTags(str) { + return makeString(str).replace(/<\/?[^>]+>/g, ''); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/succ.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/succ.js new file mode 100644 index 0000000..313c8e8 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/succ.js @@ -0,0 +1,5 @@ +var adjacent = require('./helper/adjacent'); + +module.exports = function succ(str) { + return adjacent(str, 1); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/surround.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/surround.js new file mode 100644 index 0000000..9cb7f7e --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/surround.js @@ -0,0 +1,3 @@ +module.exports = function surround(str, wrapper) { + return [wrapper, str, wrapper].join(''); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/swapCase.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/swapCase.js new file mode 100644 index 0000000..0857262 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/swapCase.js @@ -0,0 +1,7 @@ +var makeString = require('./helper/makeString'); + +module.exports = function swapCase(str) { + return makeString(str).replace(/\S/g, function(c) { + return c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase(); + }); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/titleize.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/titleize.js new file mode 100644 index 0000000..c4a8a47 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/titleize.js @@ -0,0 +1,7 @@ +var makeString = require('./helper/makeString'); + +module.exports = function titleize(str) { + return makeString(str).toLowerCase().replace(/(?:^|\s|-)\S/g, function(c) { + return c.toUpperCase(); + }); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/toBoolean.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/toBoolean.js new file mode 100644 index 0000000..ba82db6 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/toBoolean.js @@ -0,0 +1,20 @@ +var trim = require('./trim'); + +function boolMatch(s, matchers) { + var i, matcher, down = s.toLowerCase(); + matchers = [].concat(matchers); + for (i = 0; i < matchers.length; i += 1) { + matcher = matchers[i]; + if (!matcher) continue; + if (matcher.test && matcher.test(s)) return true; + if (matcher.toLowerCase() === down) return true; + } +} + +module.exports = function toBoolean(str, trueValues, falseValues) { + if (typeof str === "number") str = "" + str; + if (typeof str !== "string") return !!str; + str = trim(str); + if (boolMatch(str, trueValues || ["true", "1"])) return true; + if (boolMatch(str, falseValues || ["false", "0"])) return false; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/toNumber.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/toNumber.js new file mode 100644 index 0000000..92d47dd --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/toNumber.js @@ -0,0 +1,5 @@ +module.exports = function toNumber(num, precision) { + if (num == null) return 0; + var factor = Math.pow(10, isFinite(precision) ? precision : 0); + return Math.round(num * factor) / factor; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/toSentence.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/toSentence.js new file mode 100644 index 0000000..2284bd9 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/toSentence.js @@ -0,0 +1,12 @@ +var rtrim = require('./rtrim'); + +module.exports = function toSentence(array, separator, lastSeparator, serial) { + separator = separator || ', '; + lastSeparator = lastSeparator || ' and '; + var a = array.slice(), + lastMember = a.pop(); + + if (array.length > 2 && serial) lastSeparator = rtrim(separator) + lastSeparator; + + return a.length ? a.join(separator) + lastSeparator + lastMember : lastMember; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/toSentenceSerial.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/toSentenceSerial.js new file mode 100644 index 0000000..2b8d350 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/toSentenceSerial.js @@ -0,0 +1,5 @@ +var toSentence = require('./toSentence'); + +module.exports = function toSentenceSerial(array, sep, lastSep) { + return toSentence(array, sep, lastSep, true); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/trim.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/trim.js new file mode 100644 index 0000000..0f2a33d --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/trim.js @@ -0,0 +1,10 @@ +var makeString = require('./helper/makeString'); +var defaultToWhiteSpace = require('./helper/defaultToWhiteSpace'); +var nativeTrim = String.prototype.trim; + +module.exports = function trim(str, characters) { + str = makeString(str); + if (!characters && nativeTrim) return nativeTrim.call(str); + characters = defaultToWhiteSpace(characters); + return str.replace(new RegExp('^' + characters + '+|' + characters + '+$', 'g'), ''); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/truncate.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/truncate.js new file mode 100644 index 0000000..dbb8fd7 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/truncate.js @@ -0,0 +1,8 @@ +var makeString = require('./helper/makeString'); + +module.exports = function truncate(str, length, truncateStr) { + str = makeString(str); + truncateStr = truncateStr || '...'; + length = ~~length; + return str.length > length ? str.slice(0, length) + truncateStr : str; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/underscored.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/underscored.js new file mode 100644 index 0000000..b9d1628 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/underscored.js @@ -0,0 +1,5 @@ +var trim = require('./trim'); + +module.exports = function underscored(str) { + return trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase(); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/unescapeHTML.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/unescapeHTML.js new file mode 100644 index 0000000..78b59c2 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/unescapeHTML.js @@ -0,0 +1,20 @@ +var makeString = require('./helper/makeString'); +var htmlEntities = require('./helper/htmlEntities'); + +module.exports = function unescapeHTML(str) { + return makeString(str).replace(/\&([^;]+);/g, function(entity, entityCode) { + var match; + + if (entityCode in htmlEntities) { + return htmlEntities[entityCode]; + /*eslint no-cond-assign: 0*/ + } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) { + return String.fromCharCode(parseInt(match[1], 16)); + /*eslint no-cond-assign: 0*/ + } else if (match = entityCode.match(/^#(\d+)$/)) { + return String.fromCharCode(~~match[1]); + } else { + return entity; + } + }); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/unquote.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/unquote.js new file mode 100644 index 0000000..fefba49 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/unquote.js @@ -0,0 +1,6 @@ +module.exports = function unquote(str, quoteChar) { + quoteChar = quoteChar || '"'; + if (str[0] === quoteChar && str[str.length - 1] === quoteChar) + return str.slice(1, str.length - 1); + else return str; +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/vsprintf.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/vsprintf.js new file mode 100644 index 0000000..b68178d --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/vsprintf.js @@ -0,0 +1,6 @@ +var sprintf = require('./sprintf'); + +module.exports = function vsprintf(fmt, argv) { + argv.unshift(fmt); + return sprintf.apply(null, argv); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/words.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/words.js new file mode 100644 index 0000000..be55c9c --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/words.js @@ -0,0 +1,7 @@ +var isBlank = require('./isBlank'); +var trim = require('./trim'); + +module.exports = function words(str, delimiter) { + if (isBlank(str)) return []; + return trim(str, delimiter).split(delimiter || /\s+/); +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/underscore.string/wrap.js b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/wrap.js new file mode 100644 index 0000000..dcdc9a1 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/underscore.string/wrap.js @@ -0,0 +1,102 @@ +// Wrap +// wraps a string by a certain width + +var makeString = require('./helper/makeString'); + +module.exports = function wrap(str, options){ + str = makeString(str); + + options = options || {}; + + var width = options.width || 75; + var seperator = options.seperator || '\n'; + var cut = options.cut || false; + var preserveSpaces = options.preserveSpaces || false; + var trailingSpaces = options.trailingSpaces || false; + + var result; + + if(width <= 0){ + return str; + } + + else if(!cut){ + + var words = str.split(" "); + var current_column = 0; + result = ""; + + while(words.length > 0){ + + // if adding a space and the next word would cause this line to be longer than width... + if(1 + words[0].length + current_column > width){ + //start a new line if this line is not already empty + if(current_column > 0){ + // add a space at the end of the line is preserveSpaces is true + if (preserveSpaces){ + result += ' '; + current_column++; + } + // fill the rest of the line with spaces if trailingSpaces option is true + else if(trailingSpaces){ + while(current_column < width){ + result += ' '; + current_column++; + } + } + //start new line + result += seperator; + current_column = 0; + } + } + + // if not at the begining of the line, add a space in front of the word + if(current_column > 0){ + result += " "; + current_column++; + } + + // tack on the next word, update current column, a pop words array + result += words[0]; + current_column += words[0].length; + words.shift(); + + } + + // fill the rest of the line with spaces if trailingSpaces option is true + if(trailingSpaces){ + while(current_column < width){ + result += ' '; + current_column++; + } + } + + return result; + + } + + else { + + var index = 0; + result = ""; + + // walk through each character and add seperators where appropriate + while(index < str.length){ + if(index % width == 0 && index > 0){ + result += seperator; + } + result += str.charAt(index); + index++; + } + + // fill the rest of the line with spaces if trailingSpaces option is true + if(trailingSpaces){ + while(index % width > 0){ + result += ' '; + index++; + } + } + + return result; + } +}; diff --git a/node_modules/grunt-sftp-deploy/node_modules/which/CHANGELOG.md b/node_modules/grunt-sftp-deploy/node_modules/which/CHANGELOG.md new file mode 100644 index 0000000..698e8ed --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/which/CHANGELOG.md @@ -0,0 +1,130 @@ +# Changes + + +## v1.2.12 + +* Removed unused require + +## v1.2.11 + +* Prevent changelog script from being included in package + +## v1.2.10 + +* Use env.PATH only, not env.Path + +## v1.2.9 + +* fix for paths starting with ../ +* Remove unused `is-absolute` module + +## v1.2.8 + +* bullet items in changelog that contain (but don't start with) # + +## v1.2.7 + +* strip 'update changelog' changelog entries out of changelog + +## v1.2.6 + +* make the changelog bulleted + +## v1.2.5 + +* make a changelog, and keep it up to date +* don't include tests in package +* Properly handle relative-path executables +* appveyor +* Attach error code to Not Found error +* Make tests pass on Windows + +## v1.2.4 + +* Fix typo + +## v1.2.3 + +* update isexe, fix regression in pathExt handling + +## v1.2.2 + +* update deps, use isexe module, test windows + +## v1.2.1 + +* Sometimes windows PATH entries are quoted +* Fixed a bug in the check for group and user mode bits. This bug was introduced during refactoring for supporting strict mode. +* doc cli + +## v1.2.0 + +* Add support for opt.all and -as cli flags +* test the bin +* update travis +* Allow checking for multiple programs in bin/which +* tap 2 + +## v1.1.2 + +* travis +* Refactored and fixed undefined error on Windows +* Support strict mode + +## v1.1.1 + +* test +g exes against secondary groups, if available +* Use windows exe semantics on cygwin & msys +* cwd should be first in path on win32, not last +* Handle lower-case 'env.Path' on Windows +* Update docs +* use single-quotes + +## v1.1.0 + +* Add tests, depend on is-absolute + +## v1.0.9 + +* which.js: root is allowed to execute files owned by anyone + +## v1.0.8 + +* don't use graceful-fs + +## v1.0.7 + +* add license to package.json + +## v1.0.6 + +* isc license + +## 1.0.5 + +* Awful typo + +## 1.0.4 + +* Test for path absoluteness properly +* win: Allow '' as a pathext if cmd has a . in it + +## 1.0.3 + +* Remove references to execPath +* Make `which.sync()` work on Windows by honoring the PATHEXT variable. +* Make `isExe()` always return true on Windows. +* MIT + +## 1.0.2 + +* Only files can be exes + +## 1.0.1 + +* Respect the PATHEXT env for win32 support +* should 0755 the bin +* binary +* guts +* package +* 1st diff --git a/node_modules/grunt-sftp-deploy/node_modules/which/LICENSE b/node_modules/grunt-sftp-deploy/node_modules/which/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/which/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/grunt-sftp-deploy/node_modules/which/README.md b/node_modules/grunt-sftp-deploy/node_modules/which/README.md new file mode 100644 index 0000000..7f679d5 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/which/README.md @@ -0,0 +1,48 @@ +# which + +Like the unix `which` utility. + +Finds the first instance of a specified executable in the PATH +environment variable. Does not cache the results, so `hash -r` is not +needed when the PATH changes. + +## USAGE + +```javascript +var which = require('which') + +// async usage +which('node', function (er, resolvedPath) { + // er is returned if no "node" is found on the PATH + // if it is found, then the absolute path to the exec is returned +}) + +// sync usage +// throws if not found +var resolved = which.sync('node') + +// Pass options to override the PATH and PATHEXT environment vars. +which('node', { path: someOtherPath }, function (er, resolved) { + if (er) + throw er + console.log('found at %j', resolved) +}) +``` + +## CLI USAGE + +Same as the BSD `which(1)` binary. + +``` +usage: which [-as] program ... +``` + +## OPTIONS + +You may pass an options object as the second argument. + +- `path`: Use instead of the `PATH` environment variable. +- `pathExt`: Use instead of the `PATHEXT` environment variable. +- `all`: Return all matches, instead of just the first one. Note that + this means the function returns an array of strings instead of a + single string. diff --git a/node_modules/grunt-sftp-deploy/node_modules/which/bin/which b/node_modules/grunt-sftp-deploy/node_modules/which/bin/which new file mode 100644 index 0000000..7cee372 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/which/bin/which @@ -0,0 +1,52 @@ +#!/usr/bin/env node +var which = require("../") +if (process.argv.length < 3) + usage() + +function usage () { + console.error('usage: which [-as] program ...') + process.exit(1) +} + +var all = false +var silent = false +var dashdash = false +var args = process.argv.slice(2).filter(function (arg) { + if (dashdash || !/^-/.test(arg)) + return true + + if (arg === '--') { + dashdash = true + return false + } + + var flags = arg.substr(1).split('') + for (var f = 0; f < flags.length; f++) { + var flag = flags[f] + switch (flag) { + case 's': + silent = true + break + case 'a': + all = true + break + default: + console.error('which: illegal option -- ' + flag) + usage() + } + } + return false +}) + +process.exit(args.reduce(function (pv, current) { + try { + var f = which.sync(current, { all: all }) + if (all) + f = f.join('\n') + if (!silent) + console.log(f) + return pv; + } catch (e) { + return 1; + } +}, 0)) diff --git a/node_modules/grunt-sftp-deploy/node_modules/which/package.json b/node_modules/grunt-sftp-deploy/node_modules/which/package.json new file mode 100644 index 0000000..70ec885 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/which/package.json @@ -0,0 +1,100 @@ +{ + "_args": [ + [ + { + "raw": "which@~1.2.1", + "scope": null, + "escapedName": "which", + "name": "which", + "rawSpec": "~1.2.1", + "spec": ">=1.2.1 <1.3.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt-sftp-deploy/node_modules/grunt-legacy-util" + ] + ], + "_from": "which@>=1.2.1 <1.3.0", + "_id": "which@1.2.12", + "_inCache": true, + "_location": "/grunt-sftp-deploy/which", + "_nodeVersion": "6.5.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/which-1.2.12.tgz_1478902859933_0.6313941152766347" + }, + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "3.10.9", + "_phantomChildren": {}, + "_requested": { + "raw": "which@~1.2.1", + "scope": null, + "escapedName": "which", + "name": "which", + "rawSpec": "~1.2.1", + "spec": ">=1.2.1 <1.3.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt-sftp-deploy/grunt-legacy-util" + ], + "_resolved": "https://registry.npmjs.org/which/-/which-1.2.12.tgz", + "_shasum": "de67b5e450269f194909ef23ece4ebe416fa1192", + "_shrinkwrap": null, + "_spec": "which@~1.2.1", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt-sftp-deploy/node_modules/grunt-legacy-util", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me" + }, + "bin": { + "which": "./bin/which" + }, + "bugs": { + "url": "https://github.com/isaacs/node-which/issues" + }, + "dependencies": { + "isexe": "^1.1.1" + }, + "description": "Like which(1) unix command. Find the first instance of an executable in the PATH.", + "devDependencies": { + "mkdirp": "^0.5.0", + "rimraf": "^2.3.3", + "tap": "^5.1.1" + }, + "directories": {}, + "dist": { + "shasum": "de67b5e450269f194909ef23ece4ebe416fa1192", + "tarball": "https://registry.npmjs.org/which/-/which-1.2.12.tgz" + }, + "files": [ + "which.js", + "bin/which" + ], + "gitHead": "5db2078bc2ec50d5c5f3d324e1ffcc2348b9cbbd", + "homepage": "https://github.com/isaacs/node-which#readme", + "license": "ISC", + "main": "which.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "which", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/node-which.git" + }, + "scripts": { + "changelog": "bash gen-changelog.sh", + "postversion": "npm run changelog && git add CHANGELOG.md && git commit -m 'update changelog - '${npm_package_version}", + "test": "tap test/*.js --cov" + }, + "version": "1.2.12" +} diff --git a/node_modules/grunt-sftp-deploy/node_modules/which/which.js b/node_modules/grunt-sftp-deploy/node_modules/which/which.js new file mode 100644 index 0000000..70d974c --- /dev/null +++ b/node_modules/grunt-sftp-deploy/node_modules/which/which.js @@ -0,0 +1,132 @@ +module.exports = which +which.sync = whichSync + +var isWindows = process.platform === 'win32' || + process.env.OSTYPE === 'cygwin' || + process.env.OSTYPE === 'msys' + +var path = require('path') +var COLON = isWindows ? ';' : ':' +var isexe = require('isexe') + +function getNotFoundError (cmd) { + var er = new Error('not found: ' + cmd) + er.code = 'ENOENT' + + return er +} + +function getPathInfo (cmd, opt) { + var colon = opt.colon || COLON + var pathEnv = opt.path || process.env.PATH || '' + var pathExt = [''] + + pathEnv = pathEnv.split(colon) + + var pathExtExe = '' + if (isWindows) { + pathEnv.unshift(process.cwd()) + pathExtExe = (opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM') + pathExt = pathExtExe.split(colon) + + + // Always test the cmd itself first. isexe will check to make sure + // it's found in the pathExt set. + if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') + pathExt.unshift('') + } + + // If it has a slash, then we don't bother searching the pathenv. + // just check the file itself, and that's it. + if (cmd.match(/\//) || isWindows && cmd.match(/\\/)) + pathEnv = [''] + + return { + env: pathEnv, + ext: pathExt, + extExe: pathExtExe + } +} + +function which (cmd, opt, cb) { + if (typeof opt === 'function') { + cb = opt + opt = {} + } + + var info = getPathInfo(cmd, opt) + var pathEnv = info.env + var pathExt = info.ext + var pathExtExe = info.extExe + var found = [] + + ;(function F (i, l) { + if (i === l) { + if (opt.all && found.length) + return cb(null, found) + else + return cb(getNotFoundError(cmd)) + } + + var pathPart = pathEnv[i] + if (pathPart.charAt(0) === '"' && pathPart.slice(-1) === '"') + pathPart = pathPart.slice(1, -1) + + var p = path.join(pathPart, cmd) + if (!pathPart && (/^\.[\\\/]/).test(cmd)) { + p = cmd.slice(0, 2) + p + } + ;(function E (ii, ll) { + if (ii === ll) return F(i + 1, l) + var ext = pathExt[ii] + isexe(p + ext, { pathExt: pathExtExe }, function (er, is) { + if (!er && is) { + if (opt.all) + found.push(p + ext) + else + return cb(null, p + ext) + } + return E(ii + 1, ll) + }) + })(0, pathExt.length) + })(0, pathEnv.length) +} + +function whichSync (cmd, opt) { + opt = opt || {} + + var info = getPathInfo(cmd, opt) + var pathEnv = info.env + var pathExt = info.ext + var pathExtExe = info.extExe + var found = [] + + for (var i = 0, l = pathEnv.length; i < l; i ++) { + var pathPart = pathEnv[i] + if (pathPart.charAt(0) === '"' && pathPart.slice(-1) === '"') + pathPart = pathPart.slice(1, -1) + + var p = path.join(pathPart, cmd) + if (!pathPart && /^\.[\\\/]/.test(cmd)) { + p = cmd.slice(0, 2) + p + } + for (var j = 0, ll = pathExt.length; j < ll; j ++) { + var cur = p + pathExt[j] + var is + try { + is = isexe.sync(cur, { pathExt: pathExtExe }) + if (is) { + if (opt.all) + found.push(cur) + else + return cur + } + } catch (ex) {} + } + } + + if (opt.all && found.length) + return found + + throw getNotFoundError(cmd) +} diff --git a/node_modules/grunt-sftp-deploy/package.json b/node_modules/grunt-sftp-deploy/package.json new file mode 100644 index 0000000..442e213 --- /dev/null +++ b/node_modules/grunt-sftp-deploy/package.json @@ -0,0 +1,118 @@ +{ + "_args": [ + [ + { + "raw": "grunt-sftp-deploy@*", + "scope": null, + "escapedName": "grunt-sftp-deploy", + "name": "grunt-sftp-deploy", + "rawSpec": "*", + "spec": "*", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker" + ] + ], + "_from": "grunt-sftp-deploy@*", + "_id": "grunt-sftp-deploy@0.2.5", + "_inCache": true, + "_location": "/grunt-sftp-deploy", + "_nodeVersion": "6.3.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/grunt-sftp-deploy-0.2.5.tgz_1469311009227_0.017726635793223977" + }, + "_npmUser": { + "name": "thrashr888", + "email": "thrashr888@gmail.com" + }, + "_npmVersion": "3.10.5", + "_phantomChildren": { + "abbrev": "1.0.9", + "brace-expansion": "1.1.6", + "chalk": "1.1.3", + "eventemitter2": "0.4.14", + "exit": "0.1.2", + "fs.realpath": "1.0.0", + "get-stdin": "4.0.1", + "getobject": "0.1.0", + "grunt-known-options": "1.1.0", + "hooker": "0.2.3", + "inflight": "1.0.6", + "inherits": "2.0.3", + "isexe": "1.1.2", + "meow": "3.7.0", + "once": "1.4.0", + "path-is-absolute": "1.0.1", + "resolve": "1.1.7", + "rimraf": "2.2.8", + "sprintf-js": "1.0.3" + }, + "_requested": { + "raw": "grunt-sftp-deploy@*", + "scope": null, + "escapedName": "grunt-sftp-deploy", + "name": "grunt-sftp-deploy", + "rawSpec": "*", + "spec": "*", + "type": "range" + }, + "_requiredBy": [ + "#DEV:/" + ], + "_resolved": "https://registry.npmjs.org/grunt-sftp-deploy/-/grunt-sftp-deploy-0.2.5.tgz", + "_shasum": "bfcd4fd06a4bfce7d551cc3d6c4e88d6f92f82db", + "_shrinkwrap": null, + "_spec": "grunt-sftp-deploy@*", + "_where": "/home/vagrant/projects/legislature-tracker", + "author": { + "name": "Paul Thrasher", + "email": "thrashr888@gmail.com" + }, + "bugs": { + "url": "https://github.com/thrashr888/grunt-sftp-deploy/issues" + }, + "dependencies": { + "grunt": "^1.0.1", + "progress": "^1.1.8", + "ssh2": "^0.5.0" + }, + "description": "Deployment over SFTP", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "bfcd4fd06a4bfce7d551cc3d6c4e88d6f92f82db", + "tarball": "https://registry.npmjs.org/grunt-sftp-deploy/-/grunt-sftp-deploy-0.2.5.tgz" + }, + "engines": { + "node": "*" + }, + "gitHead": "f774ee06f331fa9db2b218ec7e119093229ae46f", + "homepage": "https://github.com/thrashr888/grunt-sftp-deploy", + "keywords": [ + "gruntplugin", + "sftp", + "deployment" + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/thrashr888/grunt-sftp-deploy/blob/master/LICENSE-MIT" + } + ], + "maintainers": [ + { + "name": "thrashr888", + "email": "thrashr888@gmail.com" + } + ], + "name": "grunt-sftp-deploy", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/thrashr888/grunt-sftp-deploy.git" + }, + "scripts": {}, + "version": "0.2.5" +} diff --git a/node_modules/grunt-sftp-deploy/tasks/sftp-deploy.js b/node_modules/grunt-sftp-deploy/tasks/sftp-deploy.js new file mode 100644 index 0000000..7b99e3d --- /dev/null +++ b/node_modules/grunt-sftp-deploy/tasks/sftp-deploy.js @@ -0,0 +1,382 @@ +// +// Grunt Task File +// --------------- +// +// Task: SFTP Deploy +// Description: Deploy code over SFTP +// Dependencies: ssh2 +// + +module.exports = function(grunt) { + + grunt.util = grunt.util || grunt.utils; + + var async = grunt.util.async; + var log = grunt.log; + var _ = grunt.util._; + var file = grunt.file; + var fs = require('fs'); + var path = require('path'); + var util = require('util'); + var SSHConnection = require('ssh2'); + var progress = require('progress'); + + var toTransfer; + var sftpConn; + var sshConn; + var localRoot; + var remoteRoot; + var remoteSep; + var localSep = '/'; + var authVals; + var exclusions; + var progressLogger; + var transferred = 0; + var with_progress = true; + + var cache; + var cacheEnabled; + var cacheFileName; + + // A method for parsing the source location and storing the information into a suitably formated object + function dirParseSync(startDir, result) { + var files; + var i; + var tmpPath; + var currFile; + + // initialize the `result` object if it is the first iteration + if (result === undefined) { + result = {}; + result[localSep] = []; + } + + // check if `startDir` is a valid location + if (!fs.existsSync(startDir)) { + grunt.warn(startDir + ' is not an existing location'); + } + + // iterate throught the contents of the `startDir` location of the current iteration + files = fs.readdirSync(startDir); + for (i = 0; i < files.length; i++) { + currFile = startDir + localSep + files[i]; + if (!file.isMatch({matchBase: true}, exclusions, currFile)) { + if (file.isDir(currFile)) { + tmpPath = path.relative(localRoot, startDir + localSep + files[i]); + if (!_.has(result, tmpPath)) { + result[tmpPath] = []; + } + dirParseSync(currFile, result); + } else { + tmpPath = path.relative(localRoot, startDir); + if (!tmpPath.length) { + tmpPath = localSep; + } + result[tmpPath].push(files[i]); + } + } + } + + return result; + } + + // A method for uploading a single file + function sftpPut(inFilename, cb) { + var fromFile, toFile, from, to; + + fromFile = localRoot + localSep + inFilename; + toFile = remoteRoot + remoteSep + inFilename.split(localSep).join(remoteSep); + + if(localSep != remoteSep) { + toFile = toFile.replace(new RegExp(localSep == '\\' ? '\\\\' : '\\/', 'g'), remoteSep); + } + + grunt.verbose.write(fromFile + ' to ' + toFile); + + var f_size = fs.statSync(fromFile).size; + + var upload = function(fromFile, toFile, cb) { + sftpConn.fastPut( fromFile, toFile, function(err){ + if (err){ + log.write((' Error uploading file: ' + err.message).red + '\n'); + cb(err); + } else { + grunt.verbose.write(' done'.green + '\n' ); + if( with_progress ) progressLogger.tick(); + transferred += parseInt(f_size/1024); + cb(null); + } + }); + }; + + if (cacheEnabled) { + fs.stat(fromFile, function(err, fromFileData){ + if (cache[fromFile] && +new Date(cache[fromFile]) >= +new Date(fromFileData.mtime)) { + cb(null); + } else { + cache[fromFile] = fromFileData.mtime; + upload(fromFile, toFile, cb); + } + } ); + } else { + upload(fromFile, toFile, cb); + } + + } + + // A method that processes a location - changes to a folder and uploads all respective files + function sftpProcessDirectories (inPath, cb) { + if (!toTransfer[inPath]) { + cb(new Error('Data for ' + inPath + ' not found')); + } + var remoteInPath; + + if(inPath.indexOf(localSep) !== -1){ + remoteInPath = inPath.split(localSep).join(remoteSep); + }else{ + remoteInPath = inPath; + } + + var remotePath = remoteRoot + (remoteInPath == remoteSep ? + remoteInPath : + remoteSep + remoteInPath); + + sftpConn.mkdir(remotePath, {mode: 0755}, function(err) { + grunt.verbose.writeln('mkdir ' + remotePath, err ? 'error or dir exists' : 'ok'); + if( with_progress ) progressLogger.tick(); + cb(null); + }); + } + + function getAuthByKey(inKey) { + if (inKey !== null) { + + if (typeof inKey == 'object') { + return inKey; + + } else if (process.env[inKey]) { + return JSON.parse(process.env[inKey]); + + } else if (fs.existsSync(inKey)) { + return JSON.parse(grunt.file.read(inKey)) || null; + + } else if (fs.existsSync('.ftppass')) { + return JSON.parse(grunt.file.read('.ftppass'))[inKey] || null; + } + + } else return null; + } + + function getKeyLocation(customKey) { + var keyLocation = null; + var defaultKeys = [ + process.env.HOME + '/.ssh/id_dsa', + process.env.HOME + '/.ssh/id_rsa' + ]; + + if (customKey) { + if (fs.existsSync(customKey)) { + keyLocation = customKey; + } else if (fs.existsSync(path.join(process.env.HOME, '.ssh', customKey))) { + keyLocation = path.join(process.env.HOME, '.ssh', customKey); + } + } else { + for (var i = 0; i < defaultKeys.length; i++) { + if (fs.existsSync(defaultKeys[i])) keyLocation = defaultKeys[i]; + } + } + + if (keyLocation === null) grunt.warn('Could not find private key.'); + return keyLocation; + } + + function getLength(toTransfer){ + var i = 0; + for(var n in toTransfer ){ + if(!toTransfer[n].substr){ + i+= getLength(toTransfer[n]); + } + i++; + } + return i; + } + function getFiles(toTransfer){ + var ret = []; + for(var n in toTransfer ){ + for( var k in toTransfer[n]){ + ret.push( (n==localSep?"":n+localSep)+toTransfer[n][k]); + } + } + return ret; + } + + + // The main grunt task + grunt.registerMultiTask('sftp-deploy', 'Deploy code over SFTP', function() { + var done = this.async(); + var keyLocation,connection,agentSocket; + + cacheEnabled = !!this.data.cache; + cacheFileName = this.data.cache; + + if (cacheEnabled) { + if (fs.existsSync(cacheFileName)) { + try{ + cache = JSON.parse(fs.readFileSync(cacheFileName) || {}); + } catch(e) { + cache = {}; + } + } else { + fs.writeFileSync(cacheFileName, '{}'); + cache = {}; + } + } + + // Init + sshConn = new SSHConnection(); + + transferred = 0; + localRoot = Array.isArray(this.data.src) ? this.data.src[0] : this.data.src; + remoteRoot = Array.isArray(this.data.dest) ? this.data.dest[0] : this.data.dest; + remoteSep = this.data.serverSep ? this.data.serverSep : "/"; + localSep = this.data.localSep ? this.data.localSep : "/"; + var concurrency = parseInt(this.data.concurrency) || 4; + with_progress = this.data.progress || !grunt.option("verbose"); + + authVals = getAuthByKey(this.data.auth.authKey); + exclusions = this.data.exclusions || []; + + toTransfer = dirParseSync(localRoot); + progressLogger = new progress(' transferred=[:current/:total] elapsed=[:elapseds] overall=[:percent] eta=[:etas] [:bar]', { + complete: '=', + incomplete: ' ', + width: 40, + total: getLength(toTransfer) + }); + + connection = { + host: this.data.auth.host, + port: this.data.auth.port + }; + + // Use either password or key-based login + if (typeof authVals === 'undefined' || authVals === null) { + grunt.warn('.ftppass seems to be missing or incomplete'); + } else { + connection.username = authVals.username; + if (authVals.agent === true) { + agentSocket = process.env.SSH_AUTH_SOCK; + if (agentSocket === undefined) { + log.warn('Could not get the ssh-agent socket. Is the SSH_AUTH_SOCK enviroment variable set?'); + } else { + connection.agent = agentSocket; + log.ok('Logging in with ssh-agent-based authentication'); + } + } else if (typeof authVals.agent === 'string') { + connection.agent = authVals.agent; + log.ok('Logging in with SSH agent "' + connection.agent + '"'); + } else if (authVals.password === undefined) { + keyLocation = getKeyLocation(authVals.keyLocation); + connection.privateKey = fs.readFileSync(keyLocation); + if (authVals.passphrase) connection.passphrase = authVals.passphrase; + log.ok('Logging in with key at ' + keyLocation); + } else { + connection.password = authVals.password; + log.ok('Logging in with username ' + authVals.username); + } + } + + var has_transferred_all_files = false; + var already_done = false; + var done_handler = function(err){ + if( already_done ) return; + already_done = true; + sshConn.end(); + if (cacheEnabled) { + fs.writeFileSync(cacheFileName, JSON.stringify(cache) || {}); + } + grunt.log.ok("Transferred : "+(transferred/1024)+" Mb" ); + if(!has_transferred_all_files || err){ + grunt.log.writeln(err); + grunt.fail.fatal('Transfer did not succeeded'); + } + done(); + }; + + log.ok('Concurrency : ' + concurrency); + sshConn.connect(connection); + + sshConn.on('connect', function () { + grunt.verbose.writeln('Connection :: connect'); + }); + sshConn.on('error', function (e) { + grunt.log.error(e); + grunt.fail.fatal('Connection :: error'); + done_handler(); + }); + sshConn.on('end', function (e) { + grunt.verbose.writeln('Connection :: end', e); + done_handler(); + }); + sshConn.on('close', function (e) { + grunt.verbose.writeln('Connection :: close', e); + done_handler(); + }); + + sshConn.on('ready', function () { + // console.log('Connection :: ready'); + + sshConn.sftp(function (err, sftp) { + if (err) throw err; + + sftpConn = sftp; + + sftp.on('end', function (e) { + grunt.verbose.writeln('SFTP :: SFTP session closed',e); + done_handler(); + }); + sftp.on('close', function (e) { + grunt.verbose.writeln('SFTP :: close',e); + }); + sftp.on('error', function (e) { + grunt.log.error(e); + grunt.fail.fatal('SFTP :: error'); + done_handler(); + }); + sftp.on('open', function () { + grunt.verbose.writeln('SFTP :: open'); + }); + + var locations = _.keys(toTransfer); + // console.dir(locations); + + sftp.mkdir(remoteRoot, {mode: 0755}, function(err) { + // ignore err to not block if dir already exists + // if( err ) return done_handler(err); + + // Iterating through all location from the `localRoot` in parallel + async.forEachSeries(locations, sftpProcessDirectories, function(err) { + grunt.verbose.writeln(' '); + log.ok('Directories done.'); + has_transferred_all_files = false; + + if( err ) done_handler(err); + + // Iterating through all location from the `localRoot` in parallel + async.forEachLimit(getFiles(toTransfer), concurrency, sftpPut, function (err) { + // console.log('callback'); + has_transferred_all_files = true; + done_handler(err); + }); + }); + }); + + }); + + }); + + if (grunt.errors) { + return false; + } + }); +}; diff --git a/node_modules/grunt/.npmignore b/node_modules/grunt/.npmignore new file mode 100644 index 0000000..5032ab2 --- /dev/null +++ b/node_modules/grunt/.npmignore @@ -0,0 +1,7 @@ +docs +test +.travis.yml +AUTHORS +CHANGELOG +custom-gruntfile.js +Gruntfile.js diff --git a/node_modules/grunt/CONTRIBUTING.md b/node_modules/grunt/CONTRIBUTING.md new file mode 100644 index 0000000..5d08cc3 --- /dev/null +++ b/node_modules/grunt/CONTRIBUTING.md @@ -0,0 +1 @@ +Please see the [Contributing to grunt](http://gruntjs.com/contributing) guide for information on contributing to this project. diff --git a/node_modules/grunt/LICENSE-MIT b/node_modules/grunt/LICENSE-MIT new file mode 100644 index 0000000..1056fb5 --- /dev/null +++ b/node_modules/grunt/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) 2014 "Cowboy" Ben Alman + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/grunt/README.md b/node_modules/grunt/README.md new file mode 100644 index 0000000..df3d344 --- /dev/null +++ b/node_modules/grunt/README.md @@ -0,0 +1,20 @@ +# Grunt: The JavaScript Task Runner + +[![Build Status: Linux](https://secure.travis-ci.org/gruntjs/grunt.png?branch=master)](http://travis-ci.org/gruntjs/grunt) +
          Build Status: Windows +[![Built with Grunt](https://cdn.gruntjs.com/builtwith.png)](http://gruntjs.com/) + + + + +### Documentation + +Visit the [gruntjs.com](http://gruntjs.com/) website for all the things. + +### Support / Contributing +Before you make an issue, please read our [Contributing](http://gruntjs.com/contributing) guide. + +You can find the grunt team in [#grunt on irc.freenode.net](http://webchat.freenode.net/?channels=grunt). + +### Release History +See the [CHANGELOG](CHANGELOG). diff --git a/node_modules/grunt/appveyor.yml b/node_modules/grunt/appveyor.yml new file mode 100644 index 0000000..4cbe6d9 --- /dev/null +++ b/node_modules/grunt/appveyor.yml @@ -0,0 +1,43 @@ +# http://www.appveyor.com/docs/appveyor-yml + +# Fix line endings in Windows. (runs before repo cloning) +init: + - git config --global core.autocrlf input + +# Test against these versions of Node.js. +environment: + matrix: + - nodejs_version: "0.10" + - nodejs_version: "0.8" + - nodejs_version: "0.11" + +# Allow failing jobs for bleeding-edge Node.js versions. +matrix: + allow_failures: + - nodejs_version: "0.11" + +# Install scripts. (runs after repo cloning) +install: + # Get the latest stable version of Node 0.STABLE.latest + - ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version) + # Typical npm stuff. + - npm install + # Grunt-specific stuff. + - npm install -g grunt-cli + - npm uninstall grunt # https://github.com/npm/npm/issues/3958 + +# Post-install test scripts. +test_script: + # Output useful info for debugging. + - node --version + - npm --version + # We test multiple Windows shells because of prior stdout buffering issues + # filed against Grunt. https://github.com/joyent/node/issues/3584 + - ps: "npm test # PowerShell" # Pass comment to PS for easier debugging + - cmd: npm test + +# Don't actually build. +build: off + +# Set build version format here instead of in the admin panel. +version: "{build}" diff --git a/node_modules/grunt/internal-tasks/bump.js b/node_modules/grunt/internal-tasks/bump.js new file mode 100644 index 0000000..d690bc4 --- /dev/null +++ b/node_modules/grunt/internal-tasks/bump.js @@ -0,0 +1,151 @@ +/* + * grunt-contrib-bump + * http://gruntjs.com/ + * + * Copyright (c) 2014 "Cowboy" Ben Alman, contributors + * Licensed under the MIT license. + */ + +'use strict'; + +var semver = require('semver'); +var shell = require('shelljs'); + +module.exports = function(grunt) { + + grunt.registerTask('bump', 'Bump the version property of a JSON file.', function() { + // Validate specified semver increment modes. + var valids = ['major', 'minor', 'patch', 'prerelease']; + var modes = []; + this.args.forEach(function(mode) { + var matches = []; + valids.forEach(function(valid) { + if (valid.indexOf(mode) === 0) { matches.push(valid); } + }); + if (matches.length === 0) { + grunt.log.error('Error: mode "' + mode + '" does not match any known modes.'); + } else if (matches.length > 1) { + grunt.log.error('Error: mode "' + mode + '" is ambiguous (possibly: ' + matches.join(', ') + ').'); + } else { + modes.push(matches[0]); + } + }); + if (this.errorCount === 0 && modes.length === 0) { + grunt.log.error('Error: no modes specified.'); + } + if (this.errorCount > 0) { + grunt.log.error('Valid modes are: ' + valids.join(', ') + '.'); + throw new Error('Use valid modes (or unambiguous mode abbreviations).'); + } + // Options. + var options = this.options({ + filepaths: ['package.json'], + syncVersions: false, + commit: true, + commitMessage: 'Bumping version to {%= version %}.', + tag: true, + tagName: 'v{%= version %}', + tagMessage: 'Version {%= version %}', + tagPrerelease: false, + }); + // Normalize filepaths to array. + var filepaths = Array.isArray(options.filepaths) ? options.filepaths : [options.filepaths]; + // Process JSON files, in-order. + var versions = {}; + filepaths.forEach(function(filepath) { + var o = grunt.file.readJSON(filepath); + var origVersion = o.version; + // If syncVersions is enabled, only grab version from the first file, + // guaranteeing new versions will always be in sync. + var firstVersion = Object.keys(versions)[0]; + if (options.syncVersions && firstVersion) { + o.version = firstVersion; + } + modes.forEach(function(mode) { + var orig = o.version; + var s = semver.parse(o.version); + s.inc(mode); + o.version = String(s); + // Workaround for https://github.com/isaacs/node-semver/issues/50 + if (/-/.test(orig) && mode === 'patch') { + o.version = o.version.replace(/\d+$/, function(n) { return n - 1; }); + } + // If prerelease on an un-prerelease version, bump patch version first + if (!/-/.test(orig) && mode === 'prerelease') { + s.inc('patch'); + s.inc('prerelease'); + o.version = String(s); + } + }); + if (versions[origVersion]) { + versions[origVersion].filepaths.push(filepath); + } else { + versions[origVersion] = {version: o.version, filepaths: [filepath]}; + } + // Actually *do* something. + grunt.log.write('Bumping version in ' + filepath + ' from ' + origVersion + ' to ' + o.version + '...'); + grunt.file.write(filepath, JSON.stringify(o, null, 2)); + grunt.log.ok(); + }); + // Commit changed files? + if (options.commit) { + Object.keys(versions).forEach(function(origVersion) { + var o = versions[origVersion]; + commit(o.filepaths, processTemplate(options.commitMessage, { + version: o.version, + origVersion: origVersion + })); + }); + } + // We're only going to create one tag. And it's going to be the new + // version of the first bumped file. Because, sanity. + var newVersion = versions[Object.keys(versions)[0]].version; + if (options.tag) { + if (options.tagPrerelease || modes.indexOf('prerelease') === -1) { + tag( + processTemplate(options.tagName, {version: newVersion}), + processTemplate(options.tagMessage, {version: newVersion}) + ); + } else { + grunt.log.writeln('Not tagging (prerelease version).'); + } + } + if (this.errorCount > 0) { + grunt.warn('There were errors.'); + } + }); + + // Using custom delimiters keeps templates from being auto-processed. + grunt.template.addDelimiters('bump', '{%', '%}'); + + function processTemplate(message, data) { + return grunt.template.process(message, { + delimiters: 'bump', + data: data, + }); + } + + // Kinda borrowed from https://github.com/geddski/grunt-release + function commit(filepaths, message) { + grunt.log.writeln('Committing ' + filepaths.join(', ') + ' with message: ' + message); + run("git commit -m '" + message + "' '" + filepaths.join("' '") + "'"); + } + + function tag(name, message) { + grunt.log.writeln('Tagging ' + name + ' with message: ' + message); + run("git tag '" + name + "' -m '" + message + "'"); + } + + function run(cmd) { + if (grunt.option('no-write')) { + grunt.verbose.writeln('Not actually running: ' + cmd); + } else { + grunt.verbose.writeln('Running: ' + cmd); + var result = shell.exec(cmd, {silent:true}); + if (result.code !== 0) { + grunt.log.error('Error (' + result.code + ') ' + result.output); + } + } + } + +}; \ No newline at end of file diff --git a/node_modules/grunt/internal-tasks/subgrunt.js b/node_modules/grunt/internal-tasks/subgrunt.js new file mode 100644 index 0000000..95b5c67 --- /dev/null +++ b/node_modules/grunt/internal-tasks/subgrunt.js @@ -0,0 +1,34 @@ +/* + * grunt + * http://gruntjs.com/ + * + * Copyright (c) 2014 "Cowboy" Ben Alman + * Licensed under the MIT license. + * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT + */ + +'use strict'; + +module.exports = function(grunt) { + + // Run sub-grunt files, because right now, testing tasks is a pain. + grunt.registerMultiTask('subgrunt', 'Run a sub-gruntfile.', function() { + var path = require('path'); + grunt.util.async.forEachSeries(this.filesSrc, function(gruntfile, next) { + grunt.log.write('Loading ' + gruntfile + '...'); + grunt.util.spawn({ + grunt: true, + args: ['--gruntfile', path.resolve(gruntfile)], + }, function(error, result) { + if (error) { + grunt.log.error().error(result.stdout).writeln(); + next(new Error('Error running sub-gruntfile "' + gruntfile + '".')); + } else { + grunt.log.ok().verbose.ok(result.stdout); + next(); + } + }); + }, this.async()); + }); + +}; diff --git a/node_modules/grunt/lib/grunt.js b/node_modules/grunt/lib/grunt.js new file mode 100644 index 0000000..611799a --- /dev/null +++ b/node_modules/grunt/lib/grunt.js @@ -0,0 +1,165 @@ +/* + * grunt + * http://gruntjs.com/ + * + * Copyright (c) 2014 "Cowboy" Ben Alman + * Licensed under the MIT license. + * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT + */ + +'use strict'; + +// Nodejs libs. +var path = require('path'); + +// This allows grunt to require() .coffee files. +require('coffee-script'); + +// The module to be exported. +var grunt = module.exports = {}; + +// Expose internal grunt libs. +function gRequire(name) { + return grunt[name] = require('./grunt/' + name); +} + +var util = require('grunt-legacy-util'); +grunt.util = util; +grunt.util.task = require('./util/task'); + +var Log = require('grunt-legacy-log').Log; +var log = new Log({grunt: grunt}); +grunt.log = log; + +gRequire('template'); +gRequire('event'); +var fail = gRequire('fail'); +gRequire('file'); +var option = gRequire('option'); +var config = gRequire('config'); +var task = gRequire('task'); +var help = gRequire('help'); +gRequire('cli'); +var verbose = grunt.verbose = log.verbose; + +// Expose some grunt metadata. +grunt.package = require('../package.json'); +grunt.version = grunt.package.version; + +// Expose specific grunt lib methods on grunt. +function gExpose(obj, methodName, newMethodName) { + grunt[newMethodName || methodName] = obj[methodName].bind(obj); +} +gExpose(task, 'registerTask'); +gExpose(task, 'registerMultiTask'); +gExpose(task, 'registerInitTask'); +gExpose(task, 'renameTask'); +gExpose(task, 'loadTasks'); +gExpose(task, 'loadNpmTasks'); +gExpose(config, 'init', 'initConfig'); +gExpose(fail, 'warn'); +gExpose(fail, 'fatal'); + +// Expose the task interface. I've never called this manually, and have no idea +// how it will work. But it might. +grunt.tasks = function(tasks, options, done) { + // Update options with passed-in options. + option.init(options); + + // Display the grunt version and quit if the user did --version. + var _tasks, _options; + if (option('version')) { + // Not --verbose. + log.writeln('grunt v' + grunt.version); + + if (option('verbose')) { + // --verbose + verbose.writeln('Install path: ' + path.resolve(__dirname, '..')); + // Yes, this is a total hack, but we don't want to log all that verbose + // task initialization stuff here. + grunt.log.muted = true; + // Initialize task system so that available tasks can be listed. + grunt.task.init([], {help: true}); + // Re-enable logging. + grunt.log.muted = false; + + // Display available tasks (for shell completion, etc). + _tasks = Object.keys(grunt.task._tasks).sort(); + verbose.writeln('Available tasks: ' + _tasks.join(' ')); + + // Display available options (for shell completion, etc). + _options = []; + Object.keys(grunt.cli.optlist).forEach(function(long) { + var o = grunt.cli.optlist[long]; + _options.push('--' + (o.negate ? 'no-' : '') + long); + if (o.short) { _options.push('-' + o.short); } + }); + verbose.writeln('Available options: ' + _options.join(' ')); + } + + return; + } + + // Init colors. + log.initColors(); + + // Display help and quit if the user did --help. + if (option('help')) { + help.display(); + return; + } + + // A little header stuff. + verbose.header('Initializing').writeflags(option.flags(), 'Command-line options'); + + // Determine and output which tasks will be run. + var tasksSpecified = tasks && tasks.length > 0; + tasks = task.parseArgs([tasksSpecified ? tasks : 'default']); + + // Initialize tasks. + task.init(tasks); + + verbose.writeln(); + if (!tasksSpecified) { + verbose.writeln('No tasks specified, running default tasks.'); + } + verbose.writeflags(tasks, 'Running tasks'); + + // Handle otherwise unhandleable (probably asynchronous) exceptions. + var uncaughtHandler = function(e) { + fail.fatal(e, fail.code.TASK_FAILURE); + }; + process.on('uncaughtException', uncaughtHandler); + + // Report, etc when all tasks have completed. + task.options({ + error: function(e) { + fail.warn(e, fail.code.TASK_FAILURE); + }, + done: function() { + // Stop handling uncaught exceptions so that we don't leave any + // unwanted process-level side effects behind. There is no need to do + // this in the error callback, because fail.warn() will either kill + // the process, or with --force keep on going all the way here. + process.removeListener('uncaughtException', uncaughtHandler); + + // Output a final fail / success report. + fail.report(); + + if (done) { + // Execute "done" function when done (only if passed, of course). + done(); + } else { + // Otherwise, explicitly exit. + util.exit(0); + } + } + }); + + // Execute all tasks, in order. Passing each task individually in a forEach + // allows the error callback to execute multiple times. + tasks.forEach(function(name) { task.run(name); }); + // Run tasks async internally to reduce call-stack, per: + // https://github.com/gruntjs/grunt/pull/1026 + task.start({asyncDone:true}); +}; diff --git a/node_modules/grunt/lib/grunt/cli.js b/node_modules/grunt/lib/grunt/cli.js new file mode 100644 index 0000000..7938cf1 --- /dev/null +++ b/node_modules/grunt/lib/grunt/cli.js @@ -0,0 +1,128 @@ +/* + * grunt + * http://gruntjs.com/ + * + * Copyright (c) 2014 "Cowboy" Ben Alman + * Licensed under the MIT license. + * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT + */ + +'use strict'; + +var grunt = require('../grunt'); + +// Nodejs libs. +var path = require('path'); + +// External libs. +var nopt = require('nopt'); + +// This is only executed when run via command line. +var cli = module.exports = function(options, done) { + // CLI-parsed options override any passed-in "default" options. + if (options) { + // For each default option... + Object.keys(options).forEach(function(key) { + if (!(key in cli.options)) { + // If this option doesn't exist in the parsed cli.options, add it in. + cli.options[key] = options[key]; + } else if (cli.optlist[key].type === Array) { + // If this option's type is Array, append it to any existing array + // (or create a new array). + [].push.apply(cli.options[key], options[key]); + } + }); + } + + // Run tasks. + grunt.tasks(cli.tasks, cli.options, done); +}; + +// Default options. +var optlist = cli.optlist = { + help: { + short: 'h', + info: 'Display this help text.', + type: Boolean + }, + base: { + info: 'Specify an alternate base path. By default, all file paths are relative to the Gruntfile. (grunt.file.setBase) *', + type: path + }, + color: { + info: 'Disable colored output.', + type: Boolean, + negate: true + }, + gruntfile: { + info: 'Specify an alternate Gruntfile. By default, grunt looks in the current or parent directories for the nearest Gruntfile.js or Gruntfile.coffee file.', + type: path + }, + debug: { + short: 'd', + info: 'Enable debugging mode for tasks that support it.', + type: [Number, Boolean] + }, + stack: { + info: 'Print a stack trace when exiting with a warning or fatal error.', + type: Boolean + }, + force: { + short: 'f', + info: 'A way to force your way past warnings. Want a suggestion? Don\'t use this option, fix your code.', + type: Boolean + }, + tasks: { + info: 'Additional directory paths to scan for task and "extra" files. (grunt.loadTasks) *', + type: Array + }, + npm: { + info: 'Npm-installed grunt plugins to scan for task and "extra" files. (grunt.loadNpmTasks) *', + type: Array + }, + write: { + info: 'Disable writing files (dry run).', + type: Boolean, + negate: true + }, + verbose: { + short: 'v', + info: 'Verbose mode. A lot more information output.', + type: Boolean + }, + version: { + short: 'V', + info: 'Print the grunt version. Combine with --verbose for more info.', + type: Boolean + }, + // Even though shell auto-completion is now handled by grunt-cli, leave this + // option here for display in the --help screen. + completion: { + info: 'Output shell auto-completion rules. See the grunt-cli documentation for more information.', + type: String + }, +}; + +// Parse `optlist` into a form that nopt can handle. +var aliases = {}; +var known = {}; + +Object.keys(optlist).forEach(function(key) { + var short = optlist[key].short; + if (short) { + aliases[short] = '--' + key; + } + known[key] = optlist[key].type; +}); + +var parsed = nopt(known, aliases, process.argv, 2); +cli.tasks = parsed.argv.remain; +cli.options = parsed; +delete parsed.argv; + +// Initialize any Array options that weren't initialized. +Object.keys(optlist).forEach(function(key) { + if (optlist[key].type === Array && !(key in cli.options)) { + cli.options[key] = []; + } +}); diff --git a/node_modules/grunt/lib/grunt/config.js b/node_modules/grunt/lib/grunt/config.js new file mode 100644 index 0000000..59b8242 --- /dev/null +++ b/node_modules/grunt/lib/grunt/config.js @@ -0,0 +1,124 @@ +/* + * grunt + * http://gruntjs.com/ + * + * Copyright (c) 2014 "Cowboy" Ben Alman + * Licensed under the MIT license. + * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT + */ + +'use strict'; + +var grunt = require('../grunt'); + +// Get/set config data. If value was passed, set. Otherwise, get. +var config = module.exports = function(prop, value) { + if (arguments.length === 2) { + // Two arguments were passed, set the property's value. + return config.set(prop, value); + } else { + // Get the property's value (or the entire data object). + return config.get(prop); + } +}; + +// The actual config data. +config.data = {}; + +// Escape any . in name with \. so dot-based namespacing works properly. +config.escape = function(str) { + return str.replace(/\./g, '\\.'); +}; + +// Return prop as a string. +config.getPropString = function(prop) { + return Array.isArray(prop) ? prop.map(config.escape).join('.') : prop; +}; + +// Get raw, unprocessed config data. +config.getRaw = function(prop) { + if (prop) { + // Prop was passed, get that specific property's value. + return grunt.util.namespace.get(config.data, config.getPropString(prop)); + } else { + // No prop was passed, return the entire config.data object. + return config.data; + } +}; + +// Match '<%= FOO %>' where FOO is a propString, eg. foo or foo.bar but not +// a method call like foo() or foo.bar(). +var propStringTmplRe = /^<%=\s*([a-z0-9_$]+(?:\.[a-z0-9_$]+)*)\s*%>$/i; + +// Get config data, recursively processing templates. +config.get = function(prop) { + return config.process(config.getRaw(prop)); +}; + +// Expand a config value recursively. Used for post-processing raw values +// already retrieved from the config. +config.process = function(raw) { + return grunt.util.recurse(raw, function(value) { + // If the value is not a string, return it. + if (typeof value !== 'string') { return value; } + // If possible, access the specified property via config.get, in case it + // doesn't refer to a string, but instead refers to an object or array. + var matches = value.match(propStringTmplRe); + var result; + if (matches) { + result = config.get(matches[1]); + // If the result retrieved from the config data wasn't null or undefined, + // return it. + if (result != null) { return result; } + } + // Process the string as a template. + return grunt.template.process(value, {data: config.data}); + }); +}; + +// Set config data. +config.set = function(prop, value) { + return grunt.util.namespace.set(config.data, config.getPropString(prop), value); +}; + +// Deep merge config data. +config.merge = function(obj) { + grunt.util._.merge(config.data, obj); + return config.data; +}; + +// Initialize config data. +config.init = function(obj) { + grunt.verbose.write('Initializing config...').ok(); + // Initialize and return data. + return (config.data = obj || {}); +}; + +// Test to see if required config params have been defined. If not, throw an +// exception (use this inside of a task). +config.requires = function() { + var p = grunt.util.pluralize; + var props = grunt.util.toArray(arguments).map(config.getPropString); + var msg = 'Verifying propert' + p(props.length, 'y/ies') + + ' ' + grunt.log.wordlist(props) + ' exist' + p(props.length, 's') + + ' in config...'; + grunt.verbose.write(msg); + var failProps = config.data && props.filter(function(prop) { + return config.get(prop) == null; + }).map(function(prop) { + return '"' + prop + '"'; + }); + if (config.data && failProps.length === 0) { + grunt.verbose.ok(); + return true; + } else { + grunt.verbose.or.write(msg); + grunt.log.error().error('Unable to process task.'); + if (!config.data) { + throw grunt.util.error('Unable to load config.'); + } else { + throw grunt.util.error('Required config propert' + + p(failProps.length, 'y/ies') + ' ' + failProps.join(', ') + ' missing.'); + } + } +}; diff --git a/node_modules/grunt/lib/grunt/event.js b/node_modules/grunt/lib/grunt/event.js new file mode 100644 index 0000000..f9ed336 --- /dev/null +++ b/node_modules/grunt/lib/grunt/event.js @@ -0,0 +1,16 @@ +/* + * grunt + * http://gruntjs.com/ + * + * Copyright (c) 2014 "Cowboy" Ben Alman + * Licensed under the MIT license. + * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT + */ + +'use strict'; + +// External lib. +var EventEmitter2 = require('eventemitter2').EventEmitter2; + +// Awesome. +module.exports = new EventEmitter2({wildcard: true}); diff --git a/node_modules/grunt/lib/grunt/fail.js b/node_modules/grunt/lib/grunt/fail.js new file mode 100644 index 0000000..f53c65c --- /dev/null +++ b/node_modules/grunt/lib/grunt/fail.js @@ -0,0 +1,84 @@ +/* + * grunt + * http://gruntjs.com/ + * + * Copyright (c) 2014 "Cowboy" Ben Alman + * Licensed under the MIT license. + * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT + */ + +'use strict'; + +var grunt = require('../grunt'); + +// The module to be exported. +var fail = module.exports = {}; + +// Error codes. +fail.code = { + FATAL_ERROR: 1, + MISSING_GRUNTFILE: 2, + TASK_FAILURE: 3, + TEMPLATE_ERROR: 4, + INVALID_AUTOCOMPLETE: 5, + WARNING: 6, +}; + +// DRY it up! +function writeln(e, mode) { + grunt.log.muted = false; + var msg = String(e.message || e); + if (!grunt.option('no-color')) { msg += '\x07'; } // Beep! + if (mode === 'warn') { + msg = 'Warning: ' + msg + ' '; + msg += (grunt.option('force') ? 'Used --force, continuing.'.underline : 'Use --force to continue.'); + msg = msg.yellow; + } else { + msg = ('Fatal error: ' + msg).red; + } + grunt.log.writeln(msg); +} + +// If --stack is enabled, log the appropriate error stack (if it exists). +function dumpStack(e) { + if (grunt.option('stack')) { + if (e.origError && e.origError.stack) { + console.log(e.origError.stack); + } else if (e.stack) { + console.log(e.stack); + } + } +} + +// A fatal error occurred. Abort immediately. +fail.fatal = function(e, errcode) { + writeln(e, 'fatal'); + dumpStack(e); + grunt.util.exit(typeof errcode === 'number' ? errcode : fail.code.FATAL_ERROR); +}; + +// Keep track of error and warning counts. +fail.errorcount = 0; +fail.warncount = 0; + +// A warning occurred. Abort immediately unless -f or --force was used. +fail.warn = function(e, errcode) { + var message = typeof e === 'string' ? e : e.message; + fail.warncount++; + writeln(message, 'warn'); + // If -f or --force aren't used, stop script processing. + if (!grunt.option('force')) { + dumpStack(e); + grunt.log.writeln().fail('Aborted due to warnings.'); + grunt.util.exit(typeof errcode === 'number' ? errcode : fail.code.WARNING); + } +}; + +// This gets called at the very end. +fail.report = function() { + if (fail.warncount > 0) { + grunt.log.writeln().fail('Done, but with warnings.'); + } else { + grunt.log.writeln().success('Done, without errors.'); + } +}; diff --git a/node_modules/grunt/lib/grunt/file.js b/node_modules/grunt/lib/grunt/file.js new file mode 100644 index 0000000..100561d --- /dev/null +++ b/node_modules/grunt/lib/grunt/file.js @@ -0,0 +1,448 @@ +/* + * grunt + * http://gruntjs.com/ + * + * Copyright (c) 2014 "Cowboy" Ben Alman + * Licensed under the MIT license. + * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT + */ + +'use strict'; + +var grunt = require('../grunt'); + +// Nodejs libs. +var fs = require('fs'); +var path = require('path'); + +// The module to be exported. +var file = module.exports = {}; + +// External libs. +file.glob = require('glob'); +file.minimatch = require('minimatch'); +file.findup = require('findup-sync'); +var YAML = require('js-yaml'); +var rimraf = require('rimraf'); +var iconv = require('iconv-lite'); + +// Windows? +var win32 = process.platform === 'win32'; + +// Normalize \\ paths to / paths. +var unixifyPath = function(filepath) { + if (win32) { + return filepath.replace(/\\/g, '/'); + } else { + return filepath; + } +}; + +// Change the current base path (ie, CWD) to the specified path. +file.setBase = function() { + var dirpath = path.join.apply(path, arguments); + process.chdir(dirpath); +}; + +// Process specified wildcard glob patterns or filenames against a +// callback, excluding and uniquing files in the result set. +var processPatterns = function(patterns, fn) { + // Filepaths to return. + var result = []; + // Iterate over flattened patterns array. + grunt.util._.flatten(patterns).forEach(function(pattern) { + // If the first character is ! it should be omitted + var exclusion = pattern.indexOf('!') === 0; + // If the pattern is an exclusion, remove the ! + if (exclusion) { pattern = pattern.slice(1); } + // Find all matching files for this pattern. + var matches = fn(pattern); + if (exclusion) { + // If an exclusion, remove matching files. + result = grunt.util._.difference(result, matches); + } else { + // Otherwise add matching files. + result = grunt.util._.union(result, matches); + } + }); + return result; +}; + +// Match a filepath or filepaths against one or more wildcard patterns. Returns +// all matching filepaths. +file.match = function(options, patterns, filepaths) { + if (grunt.util.kindOf(options) !== 'object') { + filepaths = patterns; + patterns = options; + options = {}; + } + // Return empty set if either patterns or filepaths was omitted. + if (patterns == null || filepaths == null) { return []; } + // Normalize patterns and filepaths to arrays. + if (!Array.isArray(patterns)) { patterns = [patterns]; } + if (!Array.isArray(filepaths)) { filepaths = [filepaths]; } + // Return empty set if there are no patterns or filepaths. + if (patterns.length === 0 || filepaths.length === 0) { return []; } + // Return all matching filepaths. + return processPatterns(patterns, function(pattern) { + return file.minimatch.match(filepaths, pattern, options); + }); +}; + +// Match a filepath or filepaths against one or more wildcard patterns. Returns +// true if any of the patterns match. +file.isMatch = function() { + return file.match.apply(file, arguments).length > 0; +}; + +// Return an array of all file paths that match the given wildcard patterns. +file.expand = function() { + var args = grunt.util.toArray(arguments); + // If the first argument is an options object, save those options to pass + // into the file.glob.sync method. + var options = grunt.util.kindOf(args[0]) === 'object' ? args.shift() : {}; + // Use the first argument if it's an Array, otherwise convert the arguments + // object to an array and use that. + var patterns = Array.isArray(args[0]) ? args[0] : args; + // Return empty set if there are no patterns or filepaths. + if (patterns.length === 0) { return []; } + // Return all matching filepaths. + var matches = processPatterns(patterns, function(pattern) { + // Find all matching files for this pattern. + return file.glob.sync(pattern, options); + }); + // Filter result set? + if (options.filter) { + matches = matches.filter(function(filepath) { + filepath = path.join(options.cwd || '', filepath); + try { + if (typeof options.filter === 'function') { + return options.filter(filepath); + } else { + // If the file is of the right type and exists, this should work. + return fs.statSync(filepath)[options.filter](); + } + } catch(e) { + // Otherwise, it's probably not the right type. + return false; + } + }); + } + return matches; +}; + +var pathSeparatorRe = /[\/\\]/g; + +// The "ext" option refers to either everything after the first dot (default) +// or everything after the last dot. +var extDotRe = { + first: /(\.[^\/]*)?$/, + last: /(\.[^\/\.]*)?$/, +}; + +// Build a multi task "files" object dynamically. +file.expandMapping = function(patterns, destBase, options) { + options = grunt.util._.defaults({}, options, { + extDot: 'first', + rename: function(destBase, destPath) { + return path.join(destBase || '', destPath); + } + }); + var files = []; + var fileByDest = {}; + // Find all files matching pattern, using passed-in options. + file.expand(options, patterns).forEach(function(src) { + var destPath = src; + // Flatten? + if (options.flatten) { + destPath = path.basename(destPath); + } + // Change the extension? + if ('ext' in options) { + destPath = destPath.replace(extDotRe[options.extDot], options.ext); + } + // Generate destination filename. + var dest = options.rename(destBase, destPath, options); + // Prepend cwd to src path if necessary. + if (options.cwd) { src = path.join(options.cwd, src); } + // Normalize filepaths to be unix-style. + dest = dest.replace(pathSeparatorRe, '/'); + src = src.replace(pathSeparatorRe, '/'); + // Map correct src path to dest path. + if (fileByDest[dest]) { + // If dest already exists, push this src onto that dest's src array. + fileByDest[dest].src.push(src); + } else { + // Otherwise create a new src-dest file mapping object. + files.push({ + src: [src], + dest: dest, + }); + // And store a reference for later use. + fileByDest[dest] = files[files.length - 1]; + } + }); + return files; +}; + +// Like mkdir -p. Create a directory and any intermediary directories. +file.mkdir = function(dirpath, mode) { + if (grunt.option('no-write')) { return; } + // Set directory mode in a strict-mode-friendly way. + if (mode == null) { + mode = parseInt('0777', 8) & (~process.umask()); + } + dirpath.split(pathSeparatorRe).reduce(function(parts, part) { + parts += part + '/'; + var subpath = path.resolve(parts); + if (!file.exists(subpath)) { + try { + fs.mkdirSync(subpath, mode); + } catch(e) { + throw grunt.util.error('Unable to create directory "' + subpath + '" (Error code: ' + e.code + ').', e); + } + } + return parts; + }, ''); +}; + +// Recurse into a directory, executing callback for each file. +file.recurse = function recurse(rootdir, callback, subdir) { + var abspath = subdir ? path.join(rootdir, subdir) : rootdir; + fs.readdirSync(abspath).forEach(function(filename) { + var filepath = path.join(abspath, filename); + if (fs.statSync(filepath).isDirectory()) { + recurse(rootdir, callback, unixifyPath(path.join(subdir || '', filename || ''))); + } else { + callback(unixifyPath(filepath), rootdir, subdir, filename); + } + }); +}; + +// The default file encoding to use. +file.defaultEncoding = 'utf8'; +// Whether to preserve the BOM on file.read rather than strip it. +file.preserveBOM = false; + +// Read a file, return its contents. +file.read = function(filepath, options) { + if (!options) { options = {}; } + var contents; + grunt.verbose.write('Reading ' + filepath + '...'); + try { + contents = fs.readFileSync(String(filepath)); + // If encoding is not explicitly null, convert from encoded buffer to a + // string. If no encoding was specified, use the default. + if (options.encoding !== null) { + contents = iconv.decode(contents, options.encoding || file.defaultEncoding); + // Strip any BOM that might exist. + if (!file.preserveBOM && contents.charCodeAt(0) === 0xFEFF) { + contents = contents.substring(1); + } + } + grunt.verbose.ok(); + return contents; + } catch(e) { + grunt.verbose.error(); + throw grunt.util.error('Unable to read "' + filepath + '" file (Error code: ' + e.code + ').', e); + } +}; + +// Read a file, parse its contents, return an object. +file.readJSON = function(filepath, options) { + var src = file.read(filepath, options); + var result; + grunt.verbose.write('Parsing ' + filepath + '...'); + try { + result = JSON.parse(src); + grunt.verbose.ok(); + return result; + } catch(e) { + grunt.verbose.error(); + throw grunt.util.error('Unable to parse "' + filepath + '" file (' + e.message + ').', e); + } +}; + +// Read a YAML file, parse its contents, return an object. +file.readYAML = function(filepath, options) { + var src = file.read(filepath, options); + var result; + grunt.verbose.write('Parsing ' + filepath + '...'); + try { + result = YAML.load(src); + grunt.verbose.ok(); + return result; + } catch(e) { + grunt.verbose.error(); + throw grunt.util.error('Unable to parse "' + filepath + '" file (' + e.problem + ').', e); + } +}; + +// Write a file. +file.write = function(filepath, contents, options) { + if (!options) { options = {}; } + var nowrite = grunt.option('no-write'); + grunt.verbose.write((nowrite ? 'Not actually writing ' : 'Writing ') + filepath + '...'); + // Create path, if necessary. + file.mkdir(path.dirname(filepath)); + try { + // If contents is already a Buffer, don't try to encode it. If no encoding + // was specified, use the default. + if (!Buffer.isBuffer(contents)) { + contents = iconv.encode(contents, options.encoding || file.defaultEncoding); + } + // Actually write file. + if (!nowrite) { + fs.writeFileSync(filepath, contents); + } + grunt.verbose.ok(); + return true; + } catch(e) { + grunt.verbose.error(); + throw grunt.util.error('Unable to write "' + filepath + '" file (Error code: ' + e.code + ').', e); + } +}; + +// Read a file, optionally processing its content, then write the output. +file.copy = function(srcpath, destpath, options) { + if (!options) { options = {}; } + // If a process function was specified, and noProcess isn't true or doesn't + // match the srcpath, process the file's source. + var process = options.process && options.noProcess !== true && + !(options.noProcess && file.isMatch(options.noProcess, srcpath)); + // If the file will be processed, use the encoding as-specified. Otherwise, + // use an encoding of null to force the file to be read/written as a Buffer. + var readWriteOptions = process ? options : {encoding: null}; + // Actually read the file. + var contents = file.read(srcpath, readWriteOptions); + if (process) { + grunt.verbose.write('Processing source...'); + try { + contents = options.process(contents, srcpath); + grunt.verbose.ok(); + } catch(e) { + grunt.verbose.error(); + throw grunt.util.error('Error while processing "' + srcpath + '" file.', e); + } + } + // Abort copy if the process function returns false. + if (contents === false) { + grunt.verbose.writeln('Write aborted.'); + } else { + file.write(destpath, contents, readWriteOptions); + } +}; + +// Delete folders and files recursively +file.delete = function(filepath, options) { + filepath = String(filepath); + + var nowrite = grunt.option('no-write'); + if (!options) { + options = {force: grunt.option('force') || false}; + } + + grunt.verbose.write((nowrite ? 'Not actually deleting ' : 'Deleting ') + filepath + '...'); + + if (!file.exists(filepath)) { + grunt.verbose.error(); + grunt.log.warn('Cannot delete nonexistent file.'); + return false; + } + + // Only delete cwd or outside cwd if --force enabled. Be careful, people! + if (!options.force) { + if (file.isPathCwd(filepath)) { + grunt.verbose.error(); + grunt.fail.warn('Cannot delete the current working directory.'); + return false; + } else if (!file.isPathInCwd(filepath)) { + grunt.verbose.error(); + grunt.fail.warn('Cannot delete files outside the current working directory.'); + return false; + } + } + + try { + // Actually delete. Or not. + if (!nowrite) { + rimraf.sync(filepath); + } + grunt.verbose.ok(); + return true; + } catch(e) { + grunt.verbose.error(); + throw grunt.util.error('Unable to delete "' + filepath + '" file (' + e.message + ').', e); + } +}; + +// True if the file path exists. +file.exists = function() { + var filepath = path.join.apply(path, arguments); + return fs.existsSync(filepath); +}; + +// True if the file is a symbolic link. +file.isLink = function() { + var filepath = path.join.apply(path, arguments); + return file.exists(filepath) && fs.lstatSync(filepath).isSymbolicLink(); +}; + +// True if the path is a directory. +file.isDir = function() { + var filepath = path.join.apply(path, arguments); + return file.exists(filepath) && fs.statSync(filepath).isDirectory(); +}; + +// True if the path is a file. +file.isFile = function() { + var filepath = path.join.apply(path, arguments); + return file.exists(filepath) && fs.statSync(filepath).isFile(); +}; + +// Is a given file path absolute? +file.isPathAbsolute = function() { + var filepath = path.join.apply(path, arguments); + return path.resolve(filepath) === filepath.replace(/[\/\\]+$/, ''); +}; + +// Do all the specified paths refer to the same path? +file.arePathsEquivalent = function(first) { + first = path.resolve(first); + for (var i = 1; i < arguments.length; i++) { + if (first !== path.resolve(arguments[i])) { return false; } + } + return true; +}; + +// Are descendant path(s) contained within ancestor path? Note: does not test +// if paths actually exist. +file.doesPathContain = function(ancestor) { + ancestor = path.resolve(ancestor); + var relative; + for (var i = 1; i < arguments.length; i++) { + relative = path.relative(path.resolve(arguments[i]), ancestor); + if (relative === '' || /\w+/.test(relative)) { return false; } + } + return true; +}; + +// Test to see if a filepath is the CWD. +file.isPathCwd = function() { + var filepath = path.join.apply(path, arguments); + try { + return file.arePathsEquivalent(fs.realpathSync(process.cwd()), fs.realpathSync(filepath)); + } catch(e) { + return false; + } +}; + +// Test to see if a filepath is contained within the CWD. +file.isPathInCwd = function() { + var filepath = path.join.apply(path, arguments); + try { + return file.doesPathContain(fs.realpathSync(process.cwd()), fs.realpathSync(filepath)); + } catch(e) { + return false; + } +}; diff --git a/node_modules/grunt/lib/grunt/help.js b/node_modules/grunt/lib/grunt/help.js new file mode 100644 index 0000000..37b1ad2 --- /dev/null +++ b/node_modules/grunt/lib/grunt/help.js @@ -0,0 +1,129 @@ +/* + * grunt + * http://gruntjs.com/ + * + * Copyright (c) 2014 "Cowboy" Ben Alman + * Licensed under the MIT license. + * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT + */ + +'use strict'; + +var grunt = require('../grunt'); + +// Nodejs libs. +var path = require('path'); + +// Set column widths. +var col1len = 0; +exports.initCol1 = function(str) { + col1len = Math.max(col1len, str.length); +}; +exports.initWidths = function() { + // Widths for options/tasks table output. + exports.widths = [1, col1len, 2, 76 - col1len]; +}; + +// Render an array in table form. +exports.table = function(arr) { + arr.forEach(function(item) { + grunt.log.writetableln(exports.widths, ['', grunt.util._.pad(item[0], col1len), '', item[1]]); + }); +}; + +// Methods to run, in-order. +exports.queue = [ + 'initOptions', + 'initTasks', + 'initWidths', + 'header', + 'usage', + 'options', + 'optionsFooter', + 'tasks', + 'footer', +]; + +// Actually display stuff. +exports.display = function() { + exports.queue.forEach(function(name) { exports[name](); }); +}; + + +// Header. +exports.header = function() { + grunt.log.writeln('Grunt: The JavaScript Task Runner (v' + grunt.version + ')'); +}; + +// Usage info. +exports.usage = function() { + grunt.log.header('Usage'); + grunt.log.writeln(' ' + path.basename(process.argv[1]) + ' [options] [task [task ...]]'); +}; + +// Options. +exports.initOptions = function() { + // Build 2-column array for table view. + exports._options = Object.keys(grunt.cli.optlist).map(function(long) { + var o = grunt.cli.optlist[long]; + var col1 = '--' + (o.negate ? 'no-' : '') + long + (o.short ? ', -' + o.short : ''); + exports.initCol1(col1); + return [col1, o.info]; + }); +}; + +exports.options = function() { + grunt.log.header('Options'); + exports.table(exports._options); +}; + +exports.optionsFooter = function() { + grunt.log.writeln().writelns( + 'Options marked with * have methods exposed via the grunt API and should ' + + 'instead be specified inside the Gruntfile wherever possible.' + ); +}; + +// Tasks. +exports.initTasks = function() { + // Initialize task system so that the tasks can be listed. + grunt.task.init([], {help: true}); + + // Build object of tasks by info (where they were loaded from). + exports._tasks = []; + Object.keys(grunt.task._tasks).forEach(function(name) { + exports.initCol1(name); + var task = grunt.task._tasks[name]; + exports._tasks.push(task); + }); +}; + +exports.tasks = function() { + grunt.log.header('Available tasks'); + if (exports._tasks.length === 0) { + grunt.log.writeln('(no tasks found)'); + } else { + exports.table(exports._tasks.map(function(task) { + var info = task.info; + if (task.multi) { info += ' *'; } + return [task.name, info]; + })); + + grunt.log.writeln().writelns( + 'Tasks run in the order specified. Arguments may be passed to tasks that ' + + 'accept them by using colons, like "lint:files". Tasks marked with * are ' + + '"multi tasks" and will iterate over all sub-targets if no argument is ' + + 'specified.' + ); + } + + grunt.log.writeln().writelns( + 'The list of available tasks may change based on tasks directories or ' + + 'grunt plugins specified in the Gruntfile or via command-line options.' + ); +}; + +// Footer. +exports.footer = function() { + grunt.log.writeln().writeln('For more information, see http://gruntjs.com/'); +}; diff --git a/node_modules/grunt/lib/grunt/option.js b/node_modules/grunt/lib/grunt/option.js new file mode 100644 index 0000000..10eb123 --- /dev/null +++ b/node_modules/grunt/lib/grunt/option.js @@ -0,0 +1,42 @@ +/* + * grunt + * http://gruntjs.com/ + * + * Copyright (c) 2014 "Cowboy" Ben Alman + * Licensed under the MIT license. + * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT + */ + +'use strict'; + +// The actual option data. +var data = {}; + +// Get or set an option value. +var option = module.exports = function(key, value) { + var no = key.match(/^no-(.+)$/); + if (arguments.length === 2) { + return (data[key] = value); + } else if (no) { + return data[no[1]] === false; + } else { + return data[key]; + } +}; + +// Initialize option data. +option.init = function(obj) { + return (data = obj || {}); +}; + +// List of options as flags. +option.flags = function() { + return Object.keys(data).filter(function(key) { + // Don't display empty arrays. + return !(Array.isArray(data[key]) && data[key].length === 0); + }).map(function(key) { + var val = data[key]; + return '--' + (val === false ? 'no-' : '') + key + + (typeof val === 'boolean' ? '' : '=' + val); + }); +}; diff --git a/node_modules/grunt/lib/grunt/task.js b/node_modules/grunt/lib/grunt/task.js new file mode 100644 index 0000000..5d1ac8b --- /dev/null +++ b/node_modules/grunt/lib/grunt/task.js @@ -0,0 +1,458 @@ +/* + * grunt + * http://gruntjs.com/ + * + * Copyright (c) 2014 "Cowboy" Ben Alman + * Licensed under the MIT license. + * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT + */ + +'use strict'; + +var grunt = require('../grunt'); + +// Nodejs libs. +var path = require('path'); + +// Extend generic "task" util lib. +var parent = grunt.util.task.create(); + +// The module to be exported. +var task = module.exports = Object.create(parent); + +// A temporary registry of tasks and metadata. +var registry = {tasks: [], untasks: [], meta: {}}; + +// The last specified tasks message. +var lastInfo; + +// Number of levels of recursion when loading tasks in collections. +var loadTaskDepth = 0; + +// Keep track of the number of log.error() calls. +var errorcount; + +// Override built-in registerTask. +task.registerTask = function(name) { + // Add task to registry. + registry.tasks.push(name); + // Register task. + parent.registerTask.apply(task, arguments); + // This task, now that it's been registered. + var thisTask = task._tasks[name]; + // Metadata about the current task. + thisTask.meta = grunt.util._.clone(registry.meta); + // Override task function. + var _fn = thisTask.fn; + thisTask.fn = function(arg) { + // Guaranteed to always be the actual task name. + var name = thisTask.name; + // Initialize the errorcount for this task. + errorcount = grunt.fail.errorcount; + // Return the number of errors logged during this task. + Object.defineProperty(this, 'errorCount', { + enumerable: true, + get: function() { + return grunt.fail.errorcount - errorcount; + } + }); + // Expose task.requires on `this`. + this.requires = task.requires.bind(task); + // Expose config.requires on `this`. + this.requiresConfig = grunt.config.requires; + // Return an options object with the specified defaults overwritten by task- + // specific overrides, via the "options" property. + this.options = function() { + var args = [{}].concat(grunt.util.toArray(arguments)).concat([ + grunt.config([name, 'options']) + ]); + var options = grunt.util._.extend.apply(null, args); + grunt.verbose.writeflags(options, 'Options'); + return options; + }; + // If this task was an alias or a multi task called without a target, + // only log if in verbose mode. + var logger = _fn.alias || (thisTask.multi && (!arg || arg === '*')) ? 'verbose' : 'log'; + // Actually log. + grunt[logger].header('Running "' + this.nameArgs + '"' + + (this.name !== this.nameArgs ? ' (' + this.name + ')' : '') + ' task'); + // If --debug was specified, log the path to this task's source file. + grunt[logger].debug('Task source: ' + thisTask.meta.filepath); + // Actually run the task. + return _fn.apply(this, arguments); + }; + return task; +}; + +// Multi task targets can't start with _ or be a reserved property (options). +function isValidMultiTaskTarget(target) { + return !/^_|^options$/.test(target); +} + +// Normalize multi task files. +task.normalizeMultiTaskFiles = function(data, target) { + var prop, obj; + var files = []; + if (grunt.util.kindOf(data) === 'object') { + if ('src' in data || 'dest' in data) { + obj = {}; + for (prop in data) { + if (prop !== 'options') { + obj[prop] = data[prop]; + } + } + files.push(obj); + } else if (grunt.util.kindOf(data.files) === 'object') { + for (prop in data.files) { + files.push({src: data.files[prop], dest: grunt.config.process(prop)}); + } + } else if (Array.isArray(data.files)) { + grunt.util._.flatten(data.files).forEach(function(obj) { + var prop; + if ('src' in obj || 'dest' in obj) { + files.push(obj); + } else { + for (prop in obj) { + files.push({src: obj[prop], dest: grunt.config.process(prop)}); + } + } + }); + } + } else { + files.push({src: data, dest: grunt.config.process(target)}); + } + + // If no src/dest or files were specified, return an empty files array. + if (files.length === 0) { + grunt.verbose.writeln('File: ' + '[no files]'.yellow); + return []; + } + + // Process all normalized file objects. + files = grunt.util._(files).chain().forEach(function(obj) { + if (!('src' in obj) || !obj.src) { return; } + // Normalize .src properties to flattened array. + if (Array.isArray(obj.src)) { + obj.src = grunt.util._.flatten(obj.src); + } else { + obj.src = [obj.src]; + } + }).map(function(obj) { + // Build options object, removing unwanted properties. + var expandOptions = grunt.util._.extend({}, obj); + delete expandOptions.src; + delete expandOptions.dest; + + // Expand file mappings. + if (obj.expand) { + return grunt.file.expandMapping(obj.src, obj.dest, expandOptions).map(function(mapObj) { + // Copy obj properties to result. + var result = grunt.util._.extend({}, obj); + // Make a clone of the orig obj available. + result.orig = grunt.util._.extend({}, obj); + // Set .src and .dest, processing both as templates. + result.src = grunt.config.process(mapObj.src); + result.dest = grunt.config.process(mapObj.dest); + // Remove unwanted properties. + ['expand', 'cwd', 'flatten', 'rename', 'ext'].forEach(function(prop) { + delete result[prop]; + }); + return result; + }); + } + + // Copy obj properties to result, adding an .orig property. + var result = grunt.util._.extend({}, obj); + // Make a clone of the orig obj available. + result.orig = grunt.util._.extend({}, obj); + + if ('src' in result) { + // Expose an expand-on-demand getter method as .src. + Object.defineProperty(result, 'src', { + enumerable: true, + get: function fn() { + var src; + if (!('result' in fn)) { + src = obj.src; + // If src is an array, flatten it. Otherwise, make it into an array. + src = Array.isArray(src) ? grunt.util._.flatten(src) : [src]; + // Expand src files, memoizing result. + fn.result = grunt.file.expand(expandOptions, src); + } + return fn.result; + } + }); + } + + if ('dest' in result) { + result.dest = obj.dest; + } + + return result; + }).flatten().value(); + + // Log this.file src and dest properties when --verbose is specified. + if (grunt.option('verbose')) { + files.forEach(function(obj) { + var output = []; + if ('src' in obj) { + output.push(obj.src.length > 0 ? grunt.log.wordlist(obj.src) : '[no src]'.yellow); + } + if ('dest' in obj) { + output.push('-> ' + (obj.dest ? String(obj.dest).cyan : '[no dest]'.yellow)); + } + if (output.length > 0) { + grunt.verbose.writeln('Files: ' + output.join(' ')); + } + }); + } + + return files; +}; + +// This is the most common "multi task" pattern. +task.registerMultiTask = function(name, info, fn) { + // If optional "info" string is omitted, shuffle arguments a bit. + if (fn == null) { + fn = info; + info = 'Custom multi task.'; + } + // Store a reference to the task object, in case the task gets renamed. + var thisTask; + task.registerTask(name, info, function(target) { + // Guaranteed to always be the actual task name. + var name = thisTask.name; + // Arguments (sans target) as an array. + this.args = grunt.util.toArray(arguments).slice(1); + // If a target wasn't specified, run this task once for each target. + if (!target || target === '*') { + return task.runAllTargets(name, this.args); + } else if (!isValidMultiTaskTarget(target)) { + throw new Error('Invalid target "' + target + '" specified.'); + } + // Fail if any required config properties have been omitted. + this.requiresConfig([name, target]); + // Return an options object with the specified defaults overwritten by task- + // and/or target-specific overrides, via the "options" property. + this.options = function() { + var targetObj = grunt.config([name, target]); + var args = [{}].concat(grunt.util.toArray(arguments)).concat([ + grunt.config([name, 'options']), + grunt.util.kindOf(targetObj) === 'object' ? targetObj.options : {} + ]); + var options = grunt.util._.extend.apply(null, args); + grunt.verbose.writeflags(options, 'Options'); + return options; + }; + // Expose the current target. + this.target = target; + // Recreate flags object so that the target isn't set as a flag. + this.flags = {}; + this.args.forEach(function(arg) { this.flags[arg] = true; }, this); + // Expose data on `this` (as well as task.current). + this.data = grunt.config([name, target]); + // Expose normalized files object. + this.files = task.normalizeMultiTaskFiles(this.data, target); + // Expose normalized, flattened, uniqued array of src files. + Object.defineProperty(this, 'filesSrc', { + enumerable: true, + get: function() { + return grunt.util._(this.files).chain().pluck('src').flatten().uniq().value(); + }.bind(this) + }); + // Call original task function, passing in the target and any other args. + return fn.apply(this, this.args); + }); + + thisTask = task._tasks[name]; + thisTask.multi = true; +}; + +// Init tasks don't require properties in config, and as such will preempt +// config loading errors. +task.registerInitTask = function(name, info, fn) { + task.registerTask(name, info, fn); + task._tasks[name].init = true; +}; + +// Override built-in renameTask to use the registry. +task.renameTask = function(oldname, newname) { + var result; + try { + // Actually rename task. + result = parent.renameTask.apply(task, arguments); + // Add and remove task. + registry.untasks.push(oldname); + registry.tasks.push(newname); + // Return result. + return result; + } catch(e) { + grunt.log.error(e.message); + } +}; + +// If a property wasn't passed, run all task targets in turn. +task.runAllTargets = function(taskname, args) { + // Get an array of sub-property keys under the given config object. + var targets = Object.keys(grunt.config.getRaw(taskname) || {}); + // Fail if there are no actual properties to iterate over. + if (targets.length === 0) { + grunt.log.error('No "' + taskname + '" targets found.'); + return false; + } + // Iterate over all valid target properties, running a task for each. + targets.filter(isValidMultiTaskTarget).forEach(function(target) { + // Be sure to pass in any additionally specified args. + task.run([taskname, target].concat(args || []).join(':')); + }); +}; + +// Load tasks and handlers from a given tasks file. +var loadTaskStack = []; +function loadTask(filepath) { + // In case this was called recursively, save registry for later. + loadTaskStack.push(registry); + // Reset registry. + registry = {tasks: [], untasks: [], meta: {info: lastInfo, filepath: filepath}}; + var filename = path.basename(filepath); + var msg = 'Loading "' + filename + '" tasks...'; + var regCount = 0; + var fn; + try { + // Load taskfile. + fn = require(path.resolve(filepath)); + if (typeof fn === 'function') { + fn.call(grunt, grunt); + } + grunt.verbose.write(msg).ok(); + // Log registered/renamed/unregistered tasks. + ['un', ''].forEach(function(prefix) { + var list = grunt.util._.chain(registry[prefix + 'tasks']).uniq().sort().value(); + if (list.length > 0) { + regCount++; + grunt.verbose.writeln((prefix ? '- ' : '+ ') + grunt.log.wordlist(list)); + } + }); + if (regCount === 0) { + grunt.verbose.warn('No tasks were registered or unregistered.'); + } + } catch(e) { + // Something went wrong. + grunt.log.write(msg).error().verbose.error(e.stack).or.error(e); + } + // Restore registry. + registry = loadTaskStack.pop() || {}; +} + +// Log a message when loading tasks. +function loadTasksMessage(info) { + // Only keep track of names of top-level loaded tasks and collections, + // not sub-tasks. + if (loadTaskDepth === 0) { lastInfo = info; } + grunt.verbose.subhead('Registering ' + info + ' tasks.'); +} + +// Load tasks and handlers from a given directory. +function loadTasks(tasksdir) { + try { + var files = grunt.file.glob.sync('*.{js,coffee}', {cwd: tasksdir, maxDepth: 1}); + // Load tasks from files. + files.forEach(function(filename) { + loadTask(path.join(tasksdir, filename)); + }); + } catch(e) { + grunt.log.verbose.error(e.stack).or.error(e); + } +} + +// Load tasks and handlers from a given directory. +task.loadTasks = function(tasksdir) { + loadTasksMessage('"' + tasksdir + '"'); + if (grunt.file.exists(tasksdir)) { + loadTasks(tasksdir); + } else { + grunt.log.error('Tasks directory "' + tasksdir + '" not found.'); + } +}; + +// Load tasks and handlers from a given locally-installed Npm module (installed +// relative to the base dir). +task.loadNpmTasks = function(name) { + loadTasksMessage('"' + name + '" local Npm module'); + var root = path.resolve('node_modules'); + var pkgfile = path.join(root, name, 'package.json'); + var pkg = grunt.file.exists(pkgfile) ? grunt.file.readJSON(pkgfile) : {keywords: []}; + + // Process collection plugins. + if (pkg.keywords && pkg.keywords.indexOf('gruntcollection') !== -1) { + loadTaskDepth++; + Object.keys(pkg.dependencies).forEach(function(depName) { + // Npm sometimes pulls dependencies out if they're shared, so find + // upwards if not found locally. + var filepath = grunt.file.findup('node_modules/' + depName, { + cwd: path.resolve('node_modules', name), + nocase: true + }); + if (filepath) { + // Load this task plugin recursively. + task.loadNpmTasks(path.relative(root, filepath)); + } + }); + loadTaskDepth--; + return; + } + + // Process task plugins. + var tasksdir = path.join(root, name, 'tasks'); + if (grunt.file.exists(tasksdir)) { + loadTasks(tasksdir); + } else { + grunt.log.error('Local Npm module "' + name + '" not found. Is it installed?'); + } +}; + +// Initialize tasks. +task.init = function(tasks, options) { + if (!options) { options = {}; } + + // Were only init tasks specified? + var allInit = tasks.length > 0 && tasks.every(function(name) { + var obj = task._taskPlusArgs(name).task; + return obj && obj.init; + }); + + // Get any local Gruntfile or tasks that might exist. Use --gruntfile override + // if specified, otherwise search the current directory or any parent. + var gruntfile = allInit ? null : grunt.option('gruntfile') || + grunt.file.findup('Gruntfile.{js,coffee}', {nocase: true}); + + var msg = 'Reading "' + (gruntfile ? path.basename(gruntfile) : '???') + '" Gruntfile...'; + if (gruntfile && grunt.file.exists(gruntfile)) { + grunt.verbose.writeln().write(msg).ok(); + // Change working directory so that all paths are relative to the + // Gruntfile's location (or the --base option, if specified). + process.chdir(grunt.option('base') || path.dirname(gruntfile)); + // Load local tasks, if the file exists. + loadTasksMessage('Gruntfile'); + loadTask(gruntfile); + } else if (options.help || allInit) { + // Don't complain about missing Gruntfile. + } else if (grunt.option('gruntfile')) { + // If --config override was specified and it doesn't exist, complain. + grunt.log.writeln().write(msg).error(); + grunt.fatal('Unable to find "' + gruntfile + '" Gruntfile.', grunt.fail.code.MISSING_GRUNTFILE); + } else if (!grunt.option('help')) { + grunt.verbose.writeln().write(msg).error(); + grunt.log.writelns( + 'A valid Gruntfile could not be found. Please see the getting ' + + 'started guide for more information on how to configure grunt: ' + + 'http://gruntjs.com/getting-started' + ); + grunt.fatal('Unable to find Gruntfile.', grunt.fail.code.MISSING_GRUNTFILE); + } + + // Load all user-specified --npm tasks. + (grunt.option('npm') || []).forEach(task.loadNpmTasks); + // Load all user-specified --tasks. + (grunt.option('tasks') || []).forEach(task.loadTasks); +}; diff --git a/node_modules/grunt/lib/grunt/template.js b/node_modules/grunt/lib/grunt/template.js new file mode 100644 index 0000000..5cdc981 --- /dev/null +++ b/node_modules/grunt/lib/grunt/template.js @@ -0,0 +1,95 @@ +/* + * grunt + * http://gruntjs.com/ + * + * Copyright (c) 2014 "Cowboy" Ben Alman + * Licensed under the MIT license. + * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT + */ + +'use strict'; + +var grunt = require('../grunt'); + +// The module to be exported. +var template = module.exports = {}; + +// External libs. +template.date = require('dateformat'); + +// Format today's date. +template.today = function(format) { + return template.date(new Date(), format); +}; + +// Template delimiters. +var allDelimiters = {}; + +// Initialize template delimiters. +template.addDelimiters = function(name, opener, closer) { + var delimiters = allDelimiters[name] = {}; + // Used by grunt. + delimiters.opener = opener; + delimiters.closer = closer; + // Generate RegExp patterns dynamically. + var a = delimiters.opener.replace(/(.)/g, '\\$1'); + var b = '([\\s\\S]+?)' + delimiters.closer.replace(/(.)/g, '\\$1'); + // Used by Lo-Dash. + delimiters.lodash = { + evaluate: new RegExp(a + b, 'g'), + interpolate: new RegExp(a + '=' + b, 'g'), + escape: new RegExp(a + '-' + b, 'g') + }; +}; + +// The underscore default template syntax should be a pretty sane default for +// the config system. +template.addDelimiters('config', '<%', '%>'); + +// Set Lo-Dash template delimiters. +template.setDelimiters = function(name) { + // Get the appropriate delimiters. + var delimiters = allDelimiters[name in allDelimiters ? name : 'config']; + // Tell Lo-Dash which delimiters to use. + grunt.util._.templateSettings = delimiters.lodash; + // Return the delimiters. + return delimiters; +}; + +// Process template + data with Lo-Dash. +template.process = function(tmpl, options) { + if (!options) { options = {}; } + // Set delimiters, and get a opening match character. + var delimiters = template.setDelimiters(options.delimiters); + // Clone data, initializing to config data or empty object if omitted. + var data = Object.create(options.data || grunt.config.data || {}); + // Expose grunt so that grunt utilities can be accessed, but only if it + // doesn't conflict with an existing .grunt property. + if (!('grunt' in data)) { data.grunt = grunt; } + // Keep track of last change. + var last = tmpl; + try { + // As long as tmpl contains template tags, render it and get the result, + // otherwise just use the template string. + while (tmpl.indexOf(delimiters.opener) >= 0) { + tmpl = grunt.util._.template(tmpl, data); + // Abort if template didn't change - nothing left to process! + if (tmpl === last) { break; } + last = tmpl; + } + } catch (e) { + // In upgrading to Lo-Dash (or Underscore.js 1.3.3), \n and \r in template + // tags now causes an exception to be thrown. Warn the user why this is + // happening. https://github.com/documentcloud/underscore/issues/553 + if (String(e) === 'SyntaxError: Unexpected token ILLEGAL' && /\n|\r/.test(tmpl)) { + grunt.log.errorlns('A special character was detected in this template. ' + + 'Inside template tags, the \\n and \\r special characters must be ' + + 'escaped as \\\\n and \\\\r. (grunt 0.4.0+)'); + } + // Slightly better error message. + e.message = 'An error occurred while processing a template (' + e.message + ').'; + grunt.warn(e, grunt.fail.code.TEMPLATE_ERROR); + } + // Normalize linefeeds and return. + return grunt.util.normalizelf(tmpl); +}; diff --git a/node_modules/grunt/lib/util/task.js b/node_modules/grunt/lib/util/task.js new file mode 100644 index 0000000..61a004d --- /dev/null +++ b/node_modules/grunt/lib/util/task.js @@ -0,0 +1,342 @@ +/* + * grunt + * http://gruntjs.com/ + * + * Copyright (c) 2014 "Cowboy" Ben Alman + * Licensed under the MIT license. + * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT + */ + +(function(exports) { + + 'use strict'; + + // Construct-o-rama. + function Task() { + // Information about the currently-running task. + this.current = {}; + // Tasks. + this._tasks = {}; + // Task queue. + this._queue = []; + // Queue placeholder (for dealing with nested tasks). + this._placeholder = {placeholder: true}; + // Queue marker (for clearing the queue programmatically). + this._marker = {marker: true}; + // Options. + this._options = {}; + // Is the queue running? + this._running = false; + // Success status of completed tasks. + this._success = {}; + } + + // Expose the constructor function. + exports.Task = Task; + + // Create a new Task instance. + exports.create = function() { + return new Task(); + }; + + // If the task runner is running or an error handler is not defined, throw + // an exception. Otherwise, call the error handler directly. + Task.prototype._throwIfRunning = function(obj) { + if (this._running || !this._options.error) { + // Throw an exception that the task runner will catch. + throw obj; + } else { + // Not inside the task runner. Call the error handler and abort. + this._options.error.call({name: null}, obj); + } + }; + + // Register a new task. + Task.prototype.registerTask = function(name, info, fn) { + // If optional "info" string is omitted, shuffle arguments a bit. + if (fn == null) { + fn = info; + info = null; + } + // String or array of strings was passed instead of fn. + var tasks; + if (typeof fn !== 'function') { + // Array of task names. + tasks = this.parseArgs([fn]); + // This task function just runs the specified tasks. + fn = this.run.bind(this, fn); + fn.alias = true; + // Generate an info string if one wasn't explicitly passed. + if (!info) { + info = 'Alias for "' + tasks.join('", "') + '" task' + + (tasks.length === 1 ? '' : 's') + '.'; + } + } else if (!info) { + info = 'Custom task.'; + } + // Add task into cache. + this._tasks[name] = {name: name, info: info, fn: fn}; + // Make chainable! + return this; + }; + + // Is the specified task an alias? + Task.prototype.isTaskAlias = function(name) { + return !!this._tasks[name].fn.alias; + }; + + // Has the specified task been registered? + Task.prototype.exists = function(name) { + return name in this._tasks; + }; + + // Rename a task. This might be useful if you want to override the default + // behavior of a task, while retaining the old name. This is a billion times + // easier to implement than some kind of in-task "super" functionality. + Task.prototype.renameTask = function(oldname, newname) { + if (!this._tasks[oldname]) { + throw new Error('Cannot rename missing "' + oldname + '" task.'); + } + // Rename task. + this._tasks[newname] = this._tasks[oldname]; + // Update name property of task. + this._tasks[newname].name = newname; + // Remove old name. + delete this._tasks[oldname]; + // Make chainable! + return this; + }; + + // Argument parsing helper. Supports these signatures: + // fn('foo') // ['foo'] + // fn('foo', 'bar', 'baz') // ['foo', 'bar', 'baz'] + // fn(['foo', 'bar', 'baz']) // ['foo', 'bar', 'baz'] + Task.prototype.parseArgs = function(args) { + // Return the first argument if it's an array, otherwise return an array + // of all arguments. + return Array.isArray(args[0]) ? args[0] : [].slice.call(args); + }; + + // Split a colon-delimited string into an array, unescaping (but not + // splitting on) any \: escaped colons. + Task.prototype.splitArgs = function(str) { + if (!str) { return []; } + // Store placeholder for \\ followed by \: + str = str.replace(/\\\\/g, '\uFFFF').replace(/\\:/g, '\uFFFE'); + // Split on : + return str.split(':').map(function(s) { + // Restore place-held : followed by \\ + return s.replace(/\uFFFE/g, ':').replace(/\uFFFF/g, '\\'); + }); + }; + + // Given a task name, determine which actual task will be called, and what + // arguments will be passed into the task callback. "foo" -> task "foo", no + // args. "foo:bar:baz" -> task "foo:bar:baz" with no args (if "foo:bar:baz" + // task exists), otherwise task "foo:bar" with arg "baz" (if "foo:bar" task + // exists), otherwise task "foo" with args "bar" and "baz". + Task.prototype._taskPlusArgs = function(name) { + // Get task name / argument parts. + var parts = this.splitArgs(name); + // Start from the end, not the beginning! + var i = parts.length; + var task; + do { + // Get a task. + task = this._tasks[parts.slice(0, i).join(':')]; + // If the task doesn't exist, decrement `i`, and if `i` is greater than + // 0, repeat. + } while (!task && --i > 0); + // Just the args. + var args = parts.slice(i); + // Maybe you want to use them as flags instead of as positional args? + var flags = {}; + args.forEach(function(arg) { flags[arg] = true; }); + // The task to run and the args to run it with. + return {task: task, nameArgs: name, args: args, flags: flags}; + }; + + // Append things to queue in the correct spot. + Task.prototype._push = function(things) { + // Get current placeholder index. + var index = this._queue.indexOf(this._placeholder); + if (index === -1) { + // No placeholder, add task+args objects to end of queue. + this._queue = this._queue.concat(things); + } else { + // Placeholder exists, add task+args objects just before placeholder. + [].splice.apply(this._queue, [index, 0].concat(things)); + } + }; + + // Enqueue a task. + Task.prototype.run = function() { + // Parse arguments into an array, returning an array of task+args objects. + var things = this.parseArgs(arguments).map(this._taskPlusArgs, this); + // Throw an exception if any tasks weren't found. + var fails = things.filter(function(thing) { return !thing.task; }); + if (fails.length > 0) { + this._throwIfRunning(new Error('Task "' + fails[0].nameArgs + '" not found.')); + return this; + } + // Append things to queue in the correct spot. + this._push(things); + // Make chainable! + return this; + }; + + // Add a marker to the queue to facilitate clearing it programmatically. + Task.prototype.mark = function() { + this._push(this._marker); + // Make chainable! + return this; + }; + + // Run a task function, handling this.async / return value. + Task.prototype.runTaskFn = function(context, fn, done, asyncDone) { + // Async flag. + var async = false; + + // Update the internal status object and run the next task. + var complete = function(success) { + var err = null; + if (success === false) { + // Since false was passed, the task failed generically. + err = new Error('Task "' + context.nameArgs + '" failed.'); + } else if (success instanceof Error || {}.toString.call(success) === '[object Error]') { + // An error object was passed, so the task failed specifically. + err = success; + success = false; + } else { + // The task succeeded. + success = true; + } + // The task has ended, reset the current task object. + this.current = {}; + // A task has "failed" only if it returns false (async) or if the + // function returned by .async is passed false. + this._success[context.nameArgs] = success; + // If task failed, call error handler. + if (!success && this._options.error) { + this._options.error.call({name: context.name, nameArgs: context.nameArgs}, err); + } + // only call done async if explicitly requested to + // see: https://github.com/gruntjs/grunt/pull/1026 + if (asyncDone) { + process.nextTick(function () { + done(err, success); + }); + } else { + done(err, success); + } + }.bind(this); + + // When called, sets the async flag and returns a function that can + // be used to continue processing the queue. + context.async = function() { + async = true; + // The returned function should execute asynchronously in case + // someone tries to do this.async()(); inside a task (WTF). + return function(success) { + setTimeout(function() { complete(success); }, 1); + }; + }; + + // Expose some information about the currently-running task. + this.current = context; + + try { + // Get the current task and run it, setting `this` inside the task + // function to be something useful. + var success = fn.call(context); + // If the async flag wasn't set, process the next task in the queue. + if (!async) { + complete(success); + } + } catch (err) { + complete(err); + } + }; + + // Begin task queue processing. Ie. run all tasks. + Task.prototype.start = function(opts) { + if (!opts) { + opts = {}; + } + // Abort if already running. + if (this._running) { return false; } + // Actually process the next task. + var nextTask = function() { + // Get next task+args object from queue. + var thing; + // Skip any placeholders or markers. + do { + thing = this._queue.shift(); + } while (thing === this._placeholder || thing === this._marker); + // If queue was empty, we're all done. + if (!thing) { + this._running = false; + if (this._options.done) { + this._options.done(); + } + return; + } + // Add a placeholder to the front of the queue. + this._queue.unshift(this._placeholder); + + // Expose some information about the currently-running task. + var context = { + // The current task name plus args, as-passed. + nameArgs: thing.nameArgs, + // The current task name. + name: thing.task.name, + // The current task arguments. + args: thing.args, + // The current arguments, available as named flags. + flags: thing.flags + }; + + // Actually run the task function (handling this.async, etc) + this.runTaskFn(context, function() { + return thing.task.fn.apply(this, this.args); + }, nextTask, !!opts.asyncDone); + + }.bind(this); + + // Update flag. + this._running = true; + // Process the next task. + nextTask(); + }; + + // Clear remaining tasks from the queue. + Task.prototype.clearQueue = function(options) { + if (!options) { options = {}; } + if (options.untilMarker) { + this._queue.splice(0, this._queue.indexOf(this._marker) + 1); + } else { + this._queue = []; + } + // Make chainable! + return this; + }; + + // Test to see if all of the given tasks have succeeded. + Task.prototype.requires = function() { + this.parseArgs(arguments).forEach(function(name) { + var success = this._success[name]; + if (!success) { + throw new Error('Required task "' + name + + '" ' + (success === false ? 'failed' : 'must be run first') + '.'); + } + }.bind(this)); + }; + + // Override default options. + Task.prototype.options = function(options) { + Object.keys(options).forEach(function(name) { + this._options[name] = options[name]; + }.bind(this)); + }; + +}(typeof exports === 'object' && exports || this)); diff --git a/node_modules/grunt/node_modules/.bin/cake b/node_modules/grunt/node_modules/.bin/cake new file mode 100644 index 0000000..da84bdc --- /dev/null +++ b/node_modules/grunt/node_modules/.bin/cake @@ -0,0 +1,15 @@ +#!/bin/sh +basedir=`dirname "$0"` + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -x "$basedir/node" ]; then + "$basedir/node" "$basedir/../coffee-script/bin/cake" "$@" + ret=$? +else + node "$basedir/../coffee-script/bin/cake" "$@" + ret=$? +fi +exit $ret diff --git a/node_modules/grunt/node_modules/.bin/cake.cmd b/node_modules/grunt/node_modules/.bin/cake.cmd new file mode 100644 index 0000000..6f070a4 --- /dev/null +++ b/node_modules/grunt/node_modules/.bin/cake.cmd @@ -0,0 +1,7 @@ +@IF EXIST "%~dp0\node.exe" ( + "%~dp0\node.exe" "%~dp0\..\coffee-script\bin\cake" %* +) ELSE ( + @SETLOCAL + @SET PATHEXT=%PATHEXT:;.JS;=;% + node "%~dp0\..\coffee-script\bin\cake" %* +) \ No newline at end of file diff --git a/node_modules/grunt/node_modules/.bin/coffee b/node_modules/grunt/node_modules/.bin/coffee new file mode 100644 index 0000000..04d88bf --- /dev/null +++ b/node_modules/grunt/node_modules/.bin/coffee @@ -0,0 +1,15 @@ +#!/bin/sh +basedir=`dirname "$0"` + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -x "$basedir/node" ]; then + "$basedir/node" "$basedir/../coffee-script/bin/coffee" "$@" + ret=$? +else + node "$basedir/../coffee-script/bin/coffee" "$@" + ret=$? +fi +exit $ret diff --git a/node_modules/grunt/node_modules/.bin/coffee.cmd b/node_modules/grunt/node_modules/.bin/coffee.cmd new file mode 100644 index 0000000..9f80352 --- /dev/null +++ b/node_modules/grunt/node_modules/.bin/coffee.cmd @@ -0,0 +1,7 @@ +@IF EXIST "%~dp0\node.exe" ( + "%~dp0\node.exe" "%~dp0\..\coffee-script\bin\coffee" %* +) ELSE ( + @SETLOCAL + @SET PATHEXT=%PATHEXT:;.JS;=;% + node "%~dp0\..\coffee-script\bin\coffee" %* +) \ No newline at end of file diff --git a/node_modules/grunt/node_modules/coffee-script/.npmignore b/node_modules/grunt/node_modules/coffee-script/.npmignore new file mode 100644 index 0000000..21e430d --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/.npmignore @@ -0,0 +1,11 @@ +*.coffee +*.html +.DS_Store +.git* +Cakefile +documentation/ +examples/ +extras/coffee-script.js +raw/ +src/ +test/ diff --git a/node_modules/grunt/node_modules/coffee-script/CNAME b/node_modules/grunt/node_modules/coffee-script/CNAME new file mode 100644 index 0000000..faadabe --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/CNAME @@ -0,0 +1 @@ +coffeescript.org \ No newline at end of file diff --git a/node_modules/grunt/node_modules/coffee-script/LICENSE b/node_modules/grunt/node_modules/coffee-script/LICENSE new file mode 100644 index 0000000..dbe6b4e --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2009-2012 Jeremy Ashkenas + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/grunt/node_modules/coffee-script/README b/node_modules/grunt/node_modules/coffee-script/README new file mode 100644 index 0000000..69ee6f4 --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/README @@ -0,0 +1,51 @@ + + { + } } { + { { } } + } }{ { + { }{ } } _____ __ __ + ( }{ }{ { ) / ____| / _|/ _| + .- { { } { }} -. | | ___ | |_| |_ ___ ___ + ( ( } { } { } } ) | | / _ \| _| _/ _ \/ _ \ + |`-..________ ..-'| | |___| (_) | | | || __/ __/ + | | \_____\___/|_| |_| \___|\___| + | ;--. + | (__ \ _____ _ _ + | | ) ) / ____| (_) | | + | |/ / | (___ ___ _ __ _ _ __ | |_ + | ( / \___ \ / __| '__| | '_ \| __| + | |/ ____) | (__| | | | |_) | |_ + | | |_____/ \___|_| |_| .__/ \__| + `-.._________..-' | | + |_| + + + CoffeeScript is a little language that compiles into JavaScript. + + Install Node.js, and then the CoffeeScript compiler: + sudo bin/cake install + + Or, if you have the Node Package Manager installed: + npm install -g coffee-script + (Leave off the -g if you don't wish to install globally.) + + Execute a script: + coffee /path/to/script.coffee + + Compile a script: + coffee -c /path/to/script.coffee + + For documentation, usage, and examples, see: + http://coffeescript.org/ + + To suggest a feature, report a bug, or general discussion: + http://github.com/jashkenas/coffee-script/issues/ + + If you'd like to chat, drop by #coffeescript on Freenode IRC, + or on webchat.freenode.net. + + The source repository: + git://github.com/jashkenas/coffee-script.git + + All contributors are listed here: + http://github.com/jashkenas/coffee-script/contributors diff --git a/node_modules/grunt/node_modules/coffee-script/Rakefile b/node_modules/grunt/node_modules/coffee-script/Rakefile new file mode 100644 index 0000000..dfb85da --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/Rakefile @@ -0,0 +1,78 @@ +require 'rubygems' +require 'erb' +require 'fileutils' +require 'rake/testtask' +require 'json' + +desc "Build the documentation page" +task :doc do + source = 'documentation/index.html.erb' + child = fork { exec "bin/coffee -bcw -o documentation/js documentation/coffee/*.coffee" } + at_exit { Process.kill("INT", child) } + Signal.trap("INT") { exit } + loop do + mtime = File.stat(source).mtime + if !@mtime || mtime > @mtime + rendered = ERB.new(File.read(source)).result(binding) + File.open('index.html', 'w+') {|f| f.write(rendered) } + end + @mtime = mtime + sleep 1 + end +end + +desc "Build coffee-script-source gem" +task :gem do + require 'rubygems' + require 'rubygems/package' + + gemspec = Gem::Specification.new do |s| + s.name = 'coffee-script-source' + s.version = JSON.parse(File.read('package.json'))["version"] + s.date = Time.now.strftime("%Y-%m-%d") + + s.homepage = "http://jashkenas.github.com/coffee-script/" + s.summary = "The CoffeeScript Compiler" + s.description = <<-EOS + CoffeeScript is a little language that compiles into JavaScript. + Underneath all of those embarrassing braces and semicolons, + JavaScript has always had a gorgeous object model at its heart. + CoffeeScript is an attempt to expose the good parts of JavaScript + in a simple way. + EOS + + s.files = [ + 'lib/coffee_script/coffee-script.js', + 'lib/coffee_script/source.rb' + ] + + s.authors = ['Jeremy Ashkenas'] + s.email = 'jashkenas@gmail.com' + s.rubyforge_project = 'coffee-script-source' + end + + file = File.open("coffee-script-source.gem", "w") + Gem::Package.open(file, 'w') do |pkg| + pkg.metadata = gemspec.to_yaml + + path = "lib/coffee_script/source.rb" + contents = <<-ERUBY +module CoffeeScript + module Source + def self.bundled_path + File.expand_path("../coffee-script.js", __FILE__) + end + end +end + ERUBY + pkg.add_file_simple(path, 0644, contents.size) do |tar_io| + tar_io.write(contents) + end + + contents = File.read("extras/coffee-script.js") + path = "lib/coffee_script/coffee-script.js" + pkg.add_file_simple(path, 0644, contents.size) do |tar_io| + tar_io.write(contents) + end + end +end diff --git a/node_modules/grunt/node_modules/coffee-script/bin/cake b/node_modules/grunt/node_modules/coffee-script/bin/cake new file mode 100644 index 0000000..5965f4e --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/bin/cake @@ -0,0 +1,7 @@ +#!/usr/bin/env node + +var path = require('path'); +var fs = require('fs'); +var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib'); + +require(lib + '/coffee-script/cake').run(); diff --git a/node_modules/grunt/node_modules/coffee-script/bin/coffee b/node_modules/grunt/node_modules/coffee-script/bin/coffee new file mode 100644 index 0000000..3d1d71c --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/bin/coffee @@ -0,0 +1,7 @@ +#!/usr/bin/env node + +var path = require('path'); +var fs = require('fs'); +var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib'); + +require(lib + '/coffee-script/command').run(); diff --git a/node_modules/grunt/node_modules/coffee-script/extras/jsl.conf b/node_modules/grunt/node_modules/coffee-script/extras/jsl.conf new file mode 100644 index 0000000..1190da5 --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/extras/jsl.conf @@ -0,0 +1,44 @@ +# JavaScriptLint configuration file for CoffeeScript. + ++no_return_value # function {0} does not always return a value ++duplicate_formal # duplicate formal argument {0} +-equal_as_assign # test for equality (==) mistyped as assignment (=)?{0} ++var_hides_arg # variable {0} hides argument ++redeclared_var # redeclaration of {0} {1} +-anon_no_return_value # anonymous function does not always return a value ++missing_semicolon # missing semicolon ++meaningless_block # meaningless block; curly braces have no impact +-comma_separated_stmts # multiple statements separated by commas (use semicolons?) ++unreachable_code # unreachable code ++missing_break # missing break statement +-missing_break_for_last_case # missing break statement for last case in switch +-comparison_type_conv # comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==) +-inc_dec_within_stmt # increment (++) and decrement (--) operators used as part of greater statement +-useless_void # use of the void type may be unnecessary (void is always undefined) ++multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs ++use_of_label # use of label +-block_without_braces # block statement without curly braces ++leading_decimal_point # leading decimal point may indicate a number or an object member ++trailing_decimal_point # trailing decimal point may indicate a number or an object member ++octal_number # leading zeros make an octal number ++nested_comment # nested comment ++misplaced_regex # regular expressions should be preceded by a left parenthesis, assignment, colon, or comma ++ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement ++empty_statement # empty statement or extra semicolon +-missing_option_explicit # the "option explicit" control comment is missing ++partial_option_explicit # the "option explicit" control comment, if used, must be in the first script tag ++dup_option_explicit # duplicate "option explicit" control comment ++useless_assign # useless assignment ++ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity ++ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent) +-missing_default_case # missing default case in switch statement ++duplicate_case_in_switch # duplicate case in switch statements ++default_not_at_end # the default case is not at the end of the switch statement ++legacy_cc_not_understood # couldn't understand control comment using /*@keyword@*/ syntax ++jsl_cc_not_understood # couldn't understand control comment using /*jsl:keyword*/ syntax ++useless_comparison # useless comparison; comparing identical expressions ++with_statement # with statement hides undeclared variables; use temporary variable instead ++trailing_comma_in_array # extra comma is not recommended in array initializers ++assign_to_function_call # assignment to a function call ++parseint_missing_radix # parseInt missing radix parameter ++lambda_assign_requires_semicolon diff --git a/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/browser.js b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/browser.js new file mode 100644 index 0000000..825cbf3 --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/browser.js @@ -0,0 +1,92 @@ +// Generated by CoffeeScript 1.3.3 +(function() { + var CoffeeScript, runScripts; + + CoffeeScript = require('./coffee-script'); + + CoffeeScript.require = require; + + CoffeeScript["eval"] = function(code, options) { + var _ref; + if (options == null) { + options = {}; + } + if ((_ref = options.bare) == null) { + options.bare = true; + } + return eval(CoffeeScript.compile(code, options)); + }; + + CoffeeScript.run = function(code, options) { + if (options == null) { + options = {}; + } + options.bare = true; + return Function(CoffeeScript.compile(code, options))(); + }; + + if (typeof window === "undefined" || window === null) { + return; + } + + CoffeeScript.load = function(url, callback) { + var xhr; + xhr = new (window.ActiveXObject || XMLHttpRequest)('Microsoft.XMLHTTP'); + xhr.open('GET', url, true); + if ('overrideMimeType' in xhr) { + xhr.overrideMimeType('text/plain'); + } + xhr.onreadystatechange = function() { + var _ref; + if (xhr.readyState === 4) { + if ((_ref = xhr.status) === 0 || _ref === 200) { + CoffeeScript.run(xhr.responseText); + } else { + throw new Error("Could not load " + url); + } + if (callback) { + return callback(); + } + } + }; + return xhr.send(null); + }; + + runScripts = function() { + var coffees, execute, index, length, s, scripts; + scripts = document.getElementsByTagName('script'); + coffees = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = scripts.length; _i < _len; _i++) { + s = scripts[_i]; + if (s.type === 'text/coffeescript') { + _results.push(s); + } + } + return _results; + })(); + index = 0; + length = coffees.length; + (execute = function() { + var script; + script = coffees[index++]; + if ((script != null ? script.type : void 0) === 'text/coffeescript') { + if (script.src) { + return CoffeeScript.load(script.src, execute); + } else { + CoffeeScript.run(script.innerHTML); + return execute(); + } + } + })(); + return null; + }; + + if (window.addEventListener) { + addEventListener('DOMContentLoaded', runScripts, false); + } else { + attachEvent('onload', runScripts); + } + +}).call(this); diff --git a/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/cake.js b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/cake.js new file mode 100644 index 0000000..1523418 --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/cake.js @@ -0,0 +1,111 @@ +// Generated by CoffeeScript 1.3.3 +(function() { + var CoffeeScript, cakefileDirectory, fatalError, fs, helpers, missingTask, oparse, options, optparse, path, printTasks, switches, tasks; + + fs = require('fs'); + + path = require('path'); + + helpers = require('./helpers'); + + optparse = require('./optparse'); + + CoffeeScript = require('./coffee-script'); + + tasks = {}; + + options = {}; + + switches = []; + + oparse = null; + + helpers.extend(global, { + task: function(name, description, action) { + var _ref; + if (!action) { + _ref = [description, action], action = _ref[0], description = _ref[1]; + } + return tasks[name] = { + name: name, + description: description, + action: action + }; + }, + option: function(letter, flag, description) { + return switches.push([letter, flag, description]); + }, + invoke: function(name) { + if (!tasks[name]) { + missingTask(name); + } + return tasks[name].action(options); + } + }); + + exports.run = function() { + var arg, args, _i, _len, _ref, _results; + global.__originalDirname = fs.realpathSync('.'); + process.chdir(cakefileDirectory(__originalDirname)); + args = process.argv.slice(2); + CoffeeScript.run(fs.readFileSync('Cakefile').toString(), { + filename: 'Cakefile' + }); + oparse = new optparse.OptionParser(switches); + if (!args.length) { + return printTasks(); + } + try { + options = oparse.parse(args); + } catch (e) { + return fatalError("" + e); + } + _ref = options["arguments"]; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + arg = _ref[_i]; + _results.push(invoke(arg)); + } + return _results; + }; + + printTasks = function() { + var cakefilePath, desc, name, relative, spaces, task; + relative = path.relative || path.resolve; + cakefilePath = path.join(relative(__originalDirname, process.cwd()), 'Cakefile'); + console.log("" + cakefilePath + " defines the following tasks:\n"); + for (name in tasks) { + task = tasks[name]; + spaces = 20 - name.length; + spaces = spaces > 0 ? Array(spaces + 1).join(' ') : ''; + desc = task.description ? "# " + task.description : ''; + console.log("cake " + name + spaces + " " + desc); + } + if (switches.length) { + return console.log(oparse.help()); + } + }; + + fatalError = function(message) { + console.error(message + '\n'); + console.log('To see a list of all tasks/options, run "cake"'); + return process.exit(1); + }; + + missingTask = function(task) { + return fatalError("No such task: " + task); + }; + + cakefileDirectory = function(dir) { + var parent; + if (path.existsSync(path.join(dir, 'Cakefile'))) { + return dir; + } + parent = path.normalize(path.join(dir, '..')); + if (parent !== dir) { + return cakefileDirectory(parent); + } + throw new Error("Cakefile not found in " + (process.cwd())); + }; + +}).call(this); diff --git a/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/coffee-script.js b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/coffee-script.js new file mode 100644 index 0000000..c43fa49 --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/coffee-script.js @@ -0,0 +1,167 @@ +// Generated by CoffeeScript 1.3.3 +(function() { + var Lexer, RESERVED, compile, fs, lexer, parser, path, vm, _ref, + __hasProp = {}.hasOwnProperty; + + fs = require('fs'); + + path = require('path'); + + _ref = require('./lexer'), Lexer = _ref.Lexer, RESERVED = _ref.RESERVED; + + parser = require('./parser').parser; + + vm = require('vm'); + + if (require.extensions) { + require.extensions['.coffee'] = function(module, filename) { + var content; + content = compile(fs.readFileSync(filename, 'utf8'), { + filename: filename + }); + return module._compile(content, filename); + }; + } else if (require.registerExtension) { + require.registerExtension('.coffee', function(content) { + return compile(content); + }); + } + + exports.VERSION = '1.3.3'; + + exports.RESERVED = RESERVED; + + exports.helpers = require('./helpers'); + + exports.compile = compile = function(code, options) { + var header, js, merge; + if (options == null) { + options = {}; + } + merge = exports.helpers.merge; + try { + js = (parser.parse(lexer.tokenize(code))).compile(options); + if (!options.header) { + return js; + } + } catch (err) { + if (options.filename) { + err.message = "In " + options.filename + ", " + err.message; + } + throw err; + } + header = "Generated by CoffeeScript " + this.VERSION; + return "// " + header + "\n" + js; + }; + + exports.tokens = function(code, options) { + return lexer.tokenize(code, options); + }; + + exports.nodes = function(source, options) { + if (typeof source === 'string') { + return parser.parse(lexer.tokenize(source, options)); + } else { + return parser.parse(source); + } + }; + + exports.run = function(code, options) { + var mainModule; + if (options == null) { + options = {}; + } + mainModule = require.main; + mainModule.filename = process.argv[1] = options.filename ? fs.realpathSync(options.filename) : '.'; + mainModule.moduleCache && (mainModule.moduleCache = {}); + mainModule.paths = require('module')._nodeModulePaths(path.dirname(fs.realpathSync(options.filename))); + if (path.extname(mainModule.filename) !== '.coffee' || require.extensions) { + return mainModule._compile(compile(code, options), mainModule.filename); + } else { + return mainModule._compile(code, mainModule.filename); + } + }; + + exports["eval"] = function(code, options) { + var Module, Script, js, k, o, r, sandbox, v, _i, _len, _module, _ref1, _ref2, _require; + if (options == null) { + options = {}; + } + if (!(code = code.trim())) { + return; + } + Script = vm.Script; + if (Script) { + if (options.sandbox != null) { + if (options.sandbox instanceof Script.createContext().constructor) { + sandbox = options.sandbox; + } else { + sandbox = Script.createContext(); + _ref1 = options.sandbox; + for (k in _ref1) { + if (!__hasProp.call(_ref1, k)) continue; + v = _ref1[k]; + sandbox[k] = v; + } + } + sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox; + } else { + sandbox = global; + } + sandbox.__filename = options.filename || 'eval'; + sandbox.__dirname = path.dirname(sandbox.__filename); + if (!(sandbox !== global || sandbox.module || sandbox.require)) { + Module = require('module'); + sandbox.module = _module = new Module(options.modulename || 'eval'); + sandbox.require = _require = function(path) { + return Module._load(path, _module, true); + }; + _module.filename = sandbox.__filename; + _ref2 = Object.getOwnPropertyNames(require); + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + r = _ref2[_i]; + if (r !== 'paths') { + _require[r] = require[r]; + } + } + _require.paths = _module.paths = Module._nodeModulePaths(process.cwd()); + _require.resolve = function(request) { + return Module._resolveFilename(request, _module); + }; + } + } + o = {}; + for (k in options) { + if (!__hasProp.call(options, k)) continue; + v = options[k]; + o[k] = v; + } + o.bare = true; + js = compile(code, o); + if (sandbox === global) { + return vm.runInThisContext(js); + } else { + return vm.runInContext(js, sandbox); + } + }; + + lexer = new Lexer; + + parser.lexer = { + lex: function() { + var tag, _ref1; + _ref1 = this.tokens[this.pos++] || [''], tag = _ref1[0], this.yytext = _ref1[1], this.yylineno = _ref1[2]; + return tag; + }, + setInput: function(tokens) { + this.tokens = tokens; + return this.pos = 0; + }, + upcomingInput: function() { + return ""; + } + }; + + parser.yy = require('./nodes'); + +}).call(this); diff --git a/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/command.js b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/command.js new file mode 100644 index 0000000..e02da9f --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/command.js @@ -0,0 +1,500 @@ +// Generated by CoffeeScript 1.3.3 +(function() { + var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, forkNode, fs, helpers, hidden, joinTimeout, lint, loadRequires, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, removeSource, sourceCode, sources, spawn, timeLog, unwatchDir, usage, version, wait, watch, watchDir, watchers, writeJs, _ref; + + fs = require('fs'); + + path = require('path'); + + helpers = require('./helpers'); + + optparse = require('./optparse'); + + CoffeeScript = require('./coffee-script'); + + _ref = require('child_process'), spawn = _ref.spawn, exec = _ref.exec; + + EventEmitter = require('events').EventEmitter; + + helpers.extend(CoffeeScript, new EventEmitter); + + printLine = function(line) { + return process.stdout.write(line + '\n'); + }; + + printWarn = function(line) { + return process.stderr.write(line + '\n'); + }; + + hidden = function(file) { + return /^\.|~$/.test(file); + }; + + BANNER = 'Usage: coffee [options] path/to/script.coffee -- [args]\n\nIf called without options, `coffee` will run your script.'; + + SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-l', '--lint', 'pipe the compiled JavaScript through JavaScript Lint'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-r', '--require [FILE*]', 'require a library before executing your script'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']]; + + opts = {}; + + sources = []; + + sourceCode = []; + + notSources = {}; + + watchers = {}; + + optionParser = null; + + exports.run = function() { + var literals, source, _i, _len, _results; + parseOptions(); + if (opts.nodejs) { + return forkNode(); + } + if (opts.help) { + return usage(); + } + if (opts.version) { + return version(); + } + if (opts.require) { + loadRequires(); + } + if (opts.interactive) { + return require('./repl'); + } + if (opts.watch && !fs.watch) { + return printWarn("The --watch feature depends on Node v0.6.0+. You are running " + process.version + "."); + } + if (opts.stdio) { + return compileStdio(); + } + if (opts["eval"]) { + return compileScript(null, sources[0]); + } + if (!sources.length) { + return require('./repl'); + } + literals = opts.run ? sources.splice(1) : []; + process.argv = process.argv.slice(0, 2).concat(literals); + process.argv[0] = 'coffee'; + process.execPath = require.main.filename; + _results = []; + for (_i = 0, _len = sources.length; _i < _len; _i++) { + source = sources[_i]; + _results.push(compilePath(source, true, path.normalize(source))); + } + return _results; + }; + + compilePath = function(source, topLevel, base) { + return fs.stat(source, function(err, stats) { + if (err && err.code !== 'ENOENT') { + throw err; + } + if ((err != null ? err.code : void 0) === 'ENOENT') { + if (topLevel && source.slice(-7) !== '.coffee') { + source = sources[sources.indexOf(source)] = "" + source + ".coffee"; + return compilePath(source, topLevel, base); + } + if (topLevel) { + console.error("File not found: " + source); + process.exit(1); + } + return; + } + if (stats.isDirectory()) { + if (opts.watch) { + watchDir(source, base); + } + return fs.readdir(source, function(err, files) { + var file, index, _ref1, _ref2; + if (err && err.code !== 'ENOENT') { + throw err; + } + if ((err != null ? err.code : void 0) === 'ENOENT') { + return; + } + index = sources.indexOf(source); + files = files.filter(function(file) { + return !hidden(file); + }); + [].splice.apply(sources, [index, index - index + 1].concat(_ref1 = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + _results.push(path.join(source, file)); + } + return _results; + })())), _ref1; + [].splice.apply(sourceCode, [index, index - index + 1].concat(_ref2 = files.map(function() { + return null; + }))), _ref2; + return files.forEach(function(file) { + return compilePath(path.join(source, file), false, base); + }); + }); + } else if (topLevel || path.extname(source) === '.coffee') { + if (opts.watch) { + watch(source, base); + } + return fs.readFile(source, function(err, code) { + if (err && err.code !== 'ENOENT') { + throw err; + } + if ((err != null ? err.code : void 0) === 'ENOENT') { + return; + } + return compileScript(source, code.toString(), base); + }); + } else { + notSources[source] = true; + return removeSource(source, base); + } + }); + }; + + compileScript = function(file, input, base) { + var o, options, t, task; + o = opts; + options = compileOptions(file); + try { + t = task = { + file: file, + input: input, + options: options + }; + CoffeeScript.emit('compile', task); + if (o.tokens) { + return printTokens(CoffeeScript.tokens(t.input)); + } else if (o.nodes) { + return printLine(CoffeeScript.nodes(t.input).toString().trim()); + } else if (o.run) { + return CoffeeScript.run(t.input, t.options); + } else if (o.join && t.file !== o.join) { + sourceCode[sources.indexOf(t.file)] = t.input; + return compileJoin(); + } else { + t.output = CoffeeScript.compile(t.input, t.options); + CoffeeScript.emit('success', task); + if (o.print) { + return printLine(t.output.trim()); + } else if (o.compile) { + return writeJs(t.file, t.output, base); + } else if (o.lint) { + return lint(t.file, t.output); + } + } + } catch (err) { + CoffeeScript.emit('failure', err, task); + if (CoffeeScript.listeners('failure').length) { + return; + } + if (o.watch) { + return printLine(err.message + '\x07'); + } + printWarn(err instanceof Error && err.stack || ("ERROR: " + err)); + return process.exit(1); + } + }; + + compileStdio = function() { + var code, stdin; + code = ''; + stdin = process.openStdin(); + stdin.on('data', function(buffer) { + if (buffer) { + return code += buffer.toString(); + } + }); + return stdin.on('end', function() { + return compileScript(null, code); + }); + }; + + joinTimeout = null; + + compileJoin = function() { + if (!opts.join) { + return; + } + if (!sourceCode.some(function(code) { + return code === null; + })) { + clearTimeout(joinTimeout); + return joinTimeout = wait(100, function() { + return compileScript(opts.join, sourceCode.join('\n'), opts.join); + }); + } + }; + + loadRequires = function() { + var realFilename, req, _i, _len, _ref1; + realFilename = module.filename; + module.filename = '.'; + _ref1 = opts.require; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + req = _ref1[_i]; + require(req); + } + return module.filename = realFilename; + }; + + watch = function(source, base) { + var compile, compileTimeout, prevStats, rewatch, watchErr, watcher; + prevStats = null; + compileTimeout = null; + watchErr = function(e) { + if (e.code === 'ENOENT') { + if (sources.indexOf(source) === -1) { + return; + } + try { + rewatch(); + return compile(); + } catch (e) { + removeSource(source, base, true); + return compileJoin(); + } + } else { + throw e; + } + }; + compile = function() { + clearTimeout(compileTimeout); + return compileTimeout = wait(25, function() { + return fs.stat(source, function(err, stats) { + if (err) { + return watchErr(err); + } + if (prevStats && stats.size === prevStats.size && stats.mtime.getTime() === prevStats.mtime.getTime()) { + return rewatch(); + } + prevStats = stats; + return fs.readFile(source, function(err, code) { + if (err) { + return watchErr(err); + } + compileScript(source, code.toString(), base); + return rewatch(); + }); + }); + }); + }; + try { + watcher = fs.watch(source, compile); + } catch (e) { + watchErr(e); + } + return rewatch = function() { + if (watcher != null) { + watcher.close(); + } + return watcher = fs.watch(source, compile); + }; + }; + + watchDir = function(source, base) { + var readdirTimeout, watcher; + readdirTimeout = null; + try { + return watcher = fs.watch(source, function() { + clearTimeout(readdirTimeout); + return readdirTimeout = wait(25, function() { + return fs.readdir(source, function(err, files) { + var file, _i, _len, _results; + if (err) { + if (err.code !== 'ENOENT') { + throw err; + } + watcher.close(); + return unwatchDir(source, base); + } + _results = []; + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + if (!(!hidden(file) && !notSources[file])) { + continue; + } + file = path.join(source, file); + if (sources.some(function(s) { + return s.indexOf(file) >= 0; + })) { + continue; + } + sources.push(file); + sourceCode.push(null); + _results.push(compilePath(file, false, base)); + } + return _results; + }); + }); + }); + } catch (e) { + if (e.code !== 'ENOENT') { + throw e; + } + } + }; + + unwatchDir = function(source, base) { + var file, prevSources, toRemove, _i, _len; + prevSources = sources.slice(0); + toRemove = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = sources.length; _i < _len; _i++) { + file = sources[_i]; + if (file.indexOf(source) >= 0) { + _results.push(file); + } + } + return _results; + })(); + for (_i = 0, _len = toRemove.length; _i < _len; _i++) { + file = toRemove[_i]; + removeSource(file, base, true); + } + if (!sources.some(function(s, i) { + return prevSources[i] !== s; + })) { + return; + } + return compileJoin(); + }; + + removeSource = function(source, base, removeJs) { + var index, jsPath; + index = sources.indexOf(source); + sources.splice(index, 1); + sourceCode.splice(index, 1); + if (removeJs && !opts.join) { + jsPath = outputPath(source, base); + return path.exists(jsPath, function(exists) { + if (exists) { + return fs.unlink(jsPath, function(err) { + if (err && err.code !== 'ENOENT') { + throw err; + } + return timeLog("removed " + source); + }); + } + }); + } + }; + + outputPath = function(source, base) { + var baseDir, dir, filename, srcDir; + filename = path.basename(source, path.extname(source)) + '.js'; + srcDir = path.dirname(source); + baseDir = base === '.' ? srcDir : srcDir.substring(base.length); + dir = opts.output ? path.join(opts.output, baseDir) : srcDir; + return path.join(dir, filename); + }; + + writeJs = function(source, js, base) { + var compile, jsDir, jsPath; + jsPath = outputPath(source, base); + jsDir = path.dirname(jsPath); + compile = function() { + if (js.length <= 0) { + js = ' '; + } + return fs.writeFile(jsPath, js, function(err) { + if (err) { + return printLine(err.message); + } else if (opts.compile && opts.watch) { + return timeLog("compiled " + source); + } + }); + }; + return path.exists(jsDir, function(exists) { + if (exists) { + return compile(); + } else { + return exec("mkdir -p " + jsDir, compile); + } + }); + }; + + wait = function(milliseconds, func) { + return setTimeout(func, milliseconds); + }; + + timeLog = function(message) { + return console.log("" + ((new Date).toLocaleTimeString()) + " - " + message); + }; + + lint = function(file, js) { + var conf, jsl, printIt; + printIt = function(buffer) { + return printLine(file + ':\t' + buffer.toString().trim()); + }; + conf = __dirname + '/../../extras/jsl.conf'; + jsl = spawn('jsl', ['-nologo', '-stdin', '-conf', conf]); + jsl.stdout.on('data', printIt); + jsl.stderr.on('data', printIt); + jsl.stdin.write(js); + return jsl.stdin.end(); + }; + + printTokens = function(tokens) { + var strings, tag, token, value; + strings = (function() { + var _i, _len, _ref1, _results; + _results = []; + for (_i = 0, _len = tokens.length; _i < _len; _i++) { + token = tokens[_i]; + _ref1 = [token[0], token[1].toString().replace(/\n/, '\\n')], tag = _ref1[0], value = _ref1[1]; + _results.push("[" + tag + " " + value + "]"); + } + return _results; + })(); + return printLine(strings.join(' ')); + }; + + parseOptions = function() { + var i, o, source, _i, _len; + optionParser = new optparse.OptionParser(SWITCHES, BANNER); + o = opts = optionParser.parse(process.argv.slice(2)); + o.compile || (o.compile = !!o.output); + o.run = !(o.compile || o.print || o.lint); + o.print = !!(o.print || (o["eval"] || o.stdio && o.compile)); + sources = o["arguments"]; + for (i = _i = 0, _len = sources.length; _i < _len; i = ++_i) { + source = sources[i]; + sourceCode[i] = null; + } + }; + + compileOptions = function(filename) { + return { + filename: filename, + bare: opts.bare, + header: opts.compile + }; + }; + + forkNode = function() { + var args, nodeArgs; + nodeArgs = opts.nodejs.split(/\s+/); + args = process.argv.slice(1); + args.splice(args.indexOf('--nodejs'), 2); + return spawn(process.execPath, nodeArgs.concat(args), { + cwd: process.cwd(), + env: process.env, + customFds: [0, 1, 2] + }); + }; + + usage = function() { + return printLine((new optparse.OptionParser(SWITCHES, BANNER)).help()); + }; + + version = function() { + return printLine("CoffeeScript version " + CoffeeScript.VERSION); + }; + +}).call(this); diff --git a/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/grammar.js b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/grammar.js new file mode 100644 index 0000000..5662138 --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/grammar.js @@ -0,0 +1,606 @@ +// Generated by CoffeeScript 1.3.3 +(function() { + var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap; + + Parser = require('jison').Parser; + + unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/; + + o = function(patternString, action, options) { + var match; + patternString = patternString.replace(/\s{2,}/g, ' '); + if (!action) { + return [patternString, '$$ = $1;', options]; + } + action = (match = unwrap.exec(action)) ? match[1] : "(" + action + "())"; + action = action.replace(/\bnew /g, '$&yy.'); + action = action.replace(/\b(?:Block\.wrap|extend)\b/g, 'yy.$&'); + return [patternString, "$$ = " + action + ";", options]; + }; + + grammar = { + Root: [ + o('', function() { + return new Block; + }), o('Body'), o('Block TERMINATOR') + ], + Body: [ + o('Line', function() { + return Block.wrap([$1]); + }), o('Body TERMINATOR Line', function() { + return $1.push($3); + }), o('Body TERMINATOR') + ], + Line: [o('Expression'), o('Statement')], + Statement: [ + o('Return'), o('Comment'), o('STATEMENT', function() { + return new Literal($1); + }) + ], + Expression: [o('Value'), o('Invocation'), o('Code'), o('Operation'), o('Assign'), o('If'), o('Try'), o('While'), o('For'), o('Switch'), o('Class'), o('Throw')], + Block: [ + o('INDENT OUTDENT', function() { + return new Block; + }), o('INDENT Body OUTDENT', function() { + return $2; + }) + ], + Identifier: [ + o('IDENTIFIER', function() { + return new Literal($1); + }) + ], + AlphaNumeric: [ + o('NUMBER', function() { + return new Literal($1); + }), o('STRING', function() { + return new Literal($1); + }) + ], + Literal: [ + o('AlphaNumeric'), o('JS', function() { + return new Literal($1); + }), o('REGEX', function() { + return new Literal($1); + }), o('DEBUGGER', function() { + return new Literal($1); + }), o('UNDEFINED', function() { + return new Undefined; + }), o('NULL', function() { + return new Null; + }), o('BOOL', function() { + return new Bool($1); + }) + ], + Assign: [ + o('Assignable = Expression', function() { + return new Assign($1, $3); + }), o('Assignable = TERMINATOR Expression', function() { + return new Assign($1, $4); + }), o('Assignable = INDENT Expression OUTDENT', function() { + return new Assign($1, $4); + }) + ], + AssignObj: [ + o('ObjAssignable', function() { + return new Value($1); + }), o('ObjAssignable : Expression', function() { + return new Assign(new Value($1), $3, 'object'); + }), o('ObjAssignable :\ + INDENT Expression OUTDENT', function() { + return new Assign(new Value($1), $4, 'object'); + }), o('Comment') + ], + ObjAssignable: [o('Identifier'), o('AlphaNumeric'), o('ThisProperty')], + Return: [ + o('RETURN Expression', function() { + return new Return($2); + }), o('RETURN', function() { + return new Return; + }) + ], + Comment: [ + o('HERECOMMENT', function() { + return new Comment($1); + }) + ], + Code: [ + o('PARAM_START ParamList PARAM_END FuncGlyph Block', function() { + return new Code($2, $5, $4); + }), o('FuncGlyph Block', function() { + return new Code([], $2, $1); + }) + ], + FuncGlyph: [ + o('->', function() { + return 'func'; + }), o('=>', function() { + return 'boundfunc'; + }) + ], + OptComma: [o(''), o(',')], + ParamList: [ + o('', function() { + return []; + }), o('Param', function() { + return [$1]; + }), o('ParamList , Param', function() { + return $1.concat($3); + }), o('ParamList OptComma TERMINATOR Param', function() { + return $1.concat($4); + }), o('ParamList OptComma INDENT ParamList OptComma OUTDENT', function() { + return $1.concat($4); + }) + ], + Param: [ + o('ParamVar', function() { + return new Param($1); + }), o('ParamVar ...', function() { + return new Param($1, null, true); + }), o('ParamVar = Expression', function() { + return new Param($1, $3); + }) + ], + ParamVar: [o('Identifier'), o('ThisProperty'), o('Array'), o('Object')], + Splat: [ + o('Expression ...', function() { + return new Splat($1); + }) + ], + SimpleAssignable: [ + o('Identifier', function() { + return new Value($1); + }), o('Value Accessor', function() { + return $1.add($2); + }), o('Invocation Accessor', function() { + return new Value($1, [].concat($2)); + }), o('ThisProperty') + ], + Assignable: [ + o('SimpleAssignable'), o('Array', function() { + return new Value($1); + }), o('Object', function() { + return new Value($1); + }) + ], + Value: [ + o('Assignable'), o('Literal', function() { + return new Value($1); + }), o('Parenthetical', function() { + return new Value($1); + }), o('Range', function() { + return new Value($1); + }), o('This') + ], + Accessor: [ + o('. Identifier', function() { + return new Access($2); + }), o('?. Identifier', function() { + return new Access($2, 'soak'); + }), o(':: Identifier', function() { + return [new Access(new Literal('prototype')), new Access($2)]; + }), o('::', function() { + return new Access(new Literal('prototype')); + }), o('Index') + ], + Index: [ + o('INDEX_START IndexValue INDEX_END', function() { + return $2; + }), o('INDEX_SOAK Index', function() { + return extend($2, { + soak: true + }); + }) + ], + IndexValue: [ + o('Expression', function() { + return new Index($1); + }), o('Slice', function() { + return new Slice($1); + }) + ], + Object: [ + o('{ AssignList OptComma }', function() { + return new Obj($2, $1.generated); + }) + ], + AssignList: [ + o('', function() { + return []; + }), o('AssignObj', function() { + return [$1]; + }), o('AssignList , AssignObj', function() { + return $1.concat($3); + }), o('AssignList OptComma TERMINATOR AssignObj', function() { + return $1.concat($4); + }), o('AssignList OptComma INDENT AssignList OptComma OUTDENT', function() { + return $1.concat($4); + }) + ], + Class: [ + o('CLASS', function() { + return new Class; + }), o('CLASS Block', function() { + return new Class(null, null, $2); + }), o('CLASS EXTENDS Expression', function() { + return new Class(null, $3); + }), o('CLASS EXTENDS Expression Block', function() { + return new Class(null, $3, $4); + }), o('CLASS SimpleAssignable', function() { + return new Class($2); + }), o('CLASS SimpleAssignable Block', function() { + return new Class($2, null, $3); + }), o('CLASS SimpleAssignable EXTENDS Expression', function() { + return new Class($2, $4); + }), o('CLASS SimpleAssignable EXTENDS Expression Block', function() { + return new Class($2, $4, $5); + }) + ], + Invocation: [ + o('Value OptFuncExist Arguments', function() { + return new Call($1, $3, $2); + }), o('Invocation OptFuncExist Arguments', function() { + return new Call($1, $3, $2); + }), o('SUPER', function() { + return new Call('super', [new Splat(new Literal('arguments'))]); + }), o('SUPER Arguments', function() { + return new Call('super', $2); + }) + ], + OptFuncExist: [ + o('', function() { + return false; + }), o('FUNC_EXIST', function() { + return true; + }) + ], + Arguments: [ + o('CALL_START CALL_END', function() { + return []; + }), o('CALL_START ArgList OptComma CALL_END', function() { + return $2; + }) + ], + This: [ + o('THIS', function() { + return new Value(new Literal('this')); + }), o('@', function() { + return new Value(new Literal('this')); + }) + ], + ThisProperty: [ + o('@ Identifier', function() { + return new Value(new Literal('this'), [new Access($2)], 'this'); + }) + ], + Array: [ + o('[ ]', function() { + return new Arr([]); + }), o('[ ArgList OptComma ]', function() { + return new Arr($2); + }) + ], + RangeDots: [ + o('..', function() { + return 'inclusive'; + }), o('...', function() { + return 'exclusive'; + }) + ], + Range: [ + o('[ Expression RangeDots Expression ]', function() { + return new Range($2, $4, $3); + }) + ], + Slice: [ + o('Expression RangeDots Expression', function() { + return new Range($1, $3, $2); + }), o('Expression RangeDots', function() { + return new Range($1, null, $2); + }), o('RangeDots Expression', function() { + return new Range(null, $2, $1); + }), o('RangeDots', function() { + return new Range(null, null, $1); + }) + ], + ArgList: [ + o('Arg', function() { + return [$1]; + }), o('ArgList , Arg', function() { + return $1.concat($3); + }), o('ArgList OptComma TERMINATOR Arg', function() { + return $1.concat($4); + }), o('INDENT ArgList OptComma OUTDENT', function() { + return $2; + }), o('ArgList OptComma INDENT ArgList OptComma OUTDENT', function() { + return $1.concat($4); + }) + ], + Arg: [o('Expression'), o('Splat')], + SimpleArgs: [ + o('Expression'), o('SimpleArgs , Expression', function() { + return [].concat($1, $3); + }) + ], + Try: [ + o('TRY Block', function() { + return new Try($2); + }), o('TRY Block Catch', function() { + return new Try($2, $3[0], $3[1]); + }), o('TRY Block FINALLY Block', function() { + return new Try($2, null, null, $4); + }), o('TRY Block Catch FINALLY Block', function() { + return new Try($2, $3[0], $3[1], $5); + }) + ], + Catch: [ + o('CATCH Identifier Block', function() { + return [$2, $3]; + }) + ], + Throw: [ + o('THROW Expression', function() { + return new Throw($2); + }) + ], + Parenthetical: [ + o('( Body )', function() { + return new Parens($2); + }), o('( INDENT Body OUTDENT )', function() { + return new Parens($3); + }) + ], + WhileSource: [ + o('WHILE Expression', function() { + return new While($2); + }), o('WHILE Expression WHEN Expression', function() { + return new While($2, { + guard: $4 + }); + }), o('UNTIL Expression', function() { + return new While($2, { + invert: true + }); + }), o('UNTIL Expression WHEN Expression', function() { + return new While($2, { + invert: true, + guard: $4 + }); + }) + ], + While: [ + o('WhileSource Block', function() { + return $1.addBody($2); + }), o('Statement WhileSource', function() { + return $2.addBody(Block.wrap([$1])); + }), o('Expression WhileSource', function() { + return $2.addBody(Block.wrap([$1])); + }), o('Loop', function() { + return $1; + }) + ], + Loop: [ + o('LOOP Block', function() { + return new While(new Literal('true')).addBody($2); + }), o('LOOP Expression', function() { + return new While(new Literal('true')).addBody(Block.wrap([$2])); + }) + ], + For: [ + o('Statement ForBody', function() { + return new For($1, $2); + }), o('Expression ForBody', function() { + return new For($1, $2); + }), o('ForBody Block', function() { + return new For($2, $1); + }) + ], + ForBody: [ + o('FOR Range', function() { + return { + source: new Value($2) + }; + }), o('ForStart ForSource', function() { + $2.own = $1.own; + $2.name = $1[0]; + $2.index = $1[1]; + return $2; + }) + ], + ForStart: [ + o('FOR ForVariables', function() { + return $2; + }), o('FOR OWN ForVariables', function() { + $3.own = true; + return $3; + }) + ], + ForValue: [ + o('Identifier'), o('ThisProperty'), o('Array', function() { + return new Value($1); + }), o('Object', function() { + return new Value($1); + }) + ], + ForVariables: [ + o('ForValue', function() { + return [$1]; + }), o('ForValue , ForValue', function() { + return [$1, $3]; + }) + ], + ForSource: [ + o('FORIN Expression', function() { + return { + source: $2 + }; + }), o('FOROF Expression', function() { + return { + source: $2, + object: true + }; + }), o('FORIN Expression WHEN Expression', function() { + return { + source: $2, + guard: $4 + }; + }), o('FOROF Expression WHEN Expression', function() { + return { + source: $2, + guard: $4, + object: true + }; + }), o('FORIN Expression BY Expression', function() { + return { + source: $2, + step: $4 + }; + }), o('FORIN Expression WHEN Expression BY Expression', function() { + return { + source: $2, + guard: $4, + step: $6 + }; + }), o('FORIN Expression BY Expression WHEN Expression', function() { + return { + source: $2, + step: $4, + guard: $6 + }; + }) + ], + Switch: [ + o('SWITCH Expression INDENT Whens OUTDENT', function() { + return new Switch($2, $4); + }), o('SWITCH Expression INDENT Whens ELSE Block OUTDENT', function() { + return new Switch($2, $4, $6); + }), o('SWITCH INDENT Whens OUTDENT', function() { + return new Switch(null, $3); + }), o('SWITCH INDENT Whens ELSE Block OUTDENT', function() { + return new Switch(null, $3, $5); + }) + ], + Whens: [ + o('When'), o('Whens When', function() { + return $1.concat($2); + }) + ], + When: [ + o('LEADING_WHEN SimpleArgs Block', function() { + return [[$2, $3]]; + }), o('LEADING_WHEN SimpleArgs Block TERMINATOR', function() { + return [[$2, $3]]; + }) + ], + IfBlock: [ + o('IF Expression Block', function() { + return new If($2, $3, { + type: $1 + }); + }), o('IfBlock ELSE IF Expression Block', function() { + return $1.addElse(new If($4, $5, { + type: $3 + })); + }) + ], + If: [ + o('IfBlock'), o('IfBlock ELSE Block', function() { + return $1.addElse($3); + }), o('Statement POST_IF Expression', function() { + return new If($3, Block.wrap([$1]), { + type: $2, + statement: true + }); + }), o('Expression POST_IF Expression', function() { + return new If($3, Block.wrap([$1]), { + type: $2, + statement: true + }); + }) + ], + Operation: [ + o('UNARY Expression', function() { + return new Op($1, $2); + }), o('- Expression', (function() { + return new Op('-', $2); + }), { + prec: 'UNARY' + }), o('+ Expression', (function() { + return new Op('+', $2); + }), { + prec: 'UNARY' + }), o('-- SimpleAssignable', function() { + return new Op('--', $2); + }), o('++ SimpleAssignable', function() { + return new Op('++', $2); + }), o('SimpleAssignable --', function() { + return new Op('--', $1, null, true); + }), o('SimpleAssignable ++', function() { + return new Op('++', $1, null, true); + }), o('Expression ?', function() { + return new Existence($1); + }), o('Expression + Expression', function() { + return new Op('+', $1, $3); + }), o('Expression - Expression', function() { + return new Op('-', $1, $3); + }), o('Expression MATH Expression', function() { + return new Op($2, $1, $3); + }), o('Expression SHIFT Expression', function() { + return new Op($2, $1, $3); + }), o('Expression COMPARE Expression', function() { + return new Op($2, $1, $3); + }), o('Expression LOGIC Expression', function() { + return new Op($2, $1, $3); + }), o('Expression RELATION Expression', function() { + if ($2.charAt(0) === '!') { + return new Op($2.slice(1), $1, $3).invert(); + } else { + return new Op($2, $1, $3); + } + }), o('SimpleAssignable COMPOUND_ASSIGN\ + Expression', function() { + return new Assign($1, $3, $2); + }), o('SimpleAssignable COMPOUND_ASSIGN\ + INDENT Expression OUTDENT', function() { + return new Assign($1, $4, $2); + }), o('SimpleAssignable EXTENDS Expression', function() { + return new Extends($1, $3); + }) + ] + }; + + operators = [['left', '.', '?.', '::'], ['left', 'CALL_START', 'CALL_END'], ['nonassoc', '++', '--'], ['left', '?'], ['right', 'UNARY'], ['left', 'MATH'], ['left', '+', '-'], ['left', 'SHIFT'], ['left', 'RELATION'], ['left', 'COMPARE'], ['left', 'LOGIC'], ['nonassoc', 'INDENT', 'OUTDENT'], ['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS'], ['right', 'FORIN', 'FOROF', 'BY', 'WHEN'], ['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS'], ['right', 'POST_IF']]; + + tokens = []; + + for (name in grammar) { + alternatives = grammar[name]; + grammar[name] = (function() { + var _i, _j, _len, _len1, _ref, _results; + _results = []; + for (_i = 0, _len = alternatives.length; _i < _len; _i++) { + alt = alternatives[_i]; + _ref = alt[0].split(' '); + for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { + token = _ref[_j]; + if (!grammar[token]) { + tokens.push(token); + } + } + if (name === 'Root') { + alt[1] = "return " + alt[1]; + } + _results.push(alt); + } + return _results; + })(); + } + + exports.parser = new Parser({ + tokens: tokens.join(' '), + bnf: grammar, + operators: operators.reverse(), + startSymbol: 'Root' + }); + +}).call(this); diff --git a/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/helpers.js b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/helpers.js new file mode 100644 index 0000000..b0a997b --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/helpers.js @@ -0,0 +1,77 @@ +// Generated by CoffeeScript 1.3.3 +(function() { + var extend, flatten; + + exports.starts = function(string, literal, start) { + return literal === string.substr(start, literal.length); + }; + + exports.ends = function(string, literal, back) { + var len; + len = literal.length; + return literal === string.substr(string.length - len - (back || 0), len); + }; + + exports.compact = function(array) { + var item, _i, _len, _results; + _results = []; + for (_i = 0, _len = array.length; _i < _len; _i++) { + item = array[_i]; + if (item) { + _results.push(item); + } + } + return _results; + }; + + exports.count = function(string, substr) { + var num, pos; + num = pos = 0; + if (!substr.length) { + return 1 / 0; + } + while (pos = 1 + string.indexOf(substr, pos)) { + num++; + } + return num; + }; + + exports.merge = function(options, overrides) { + return extend(extend({}, options), overrides); + }; + + extend = exports.extend = function(object, properties) { + var key, val; + for (key in properties) { + val = properties[key]; + object[key] = val; + } + return object; + }; + + exports.flatten = flatten = function(array) { + var element, flattened, _i, _len; + flattened = []; + for (_i = 0, _len = array.length; _i < _len; _i++) { + element = array[_i]; + if (element instanceof Array) { + flattened = flattened.concat(flatten(element)); + } else { + flattened.push(element); + } + } + return flattened; + }; + + exports.del = function(obj, key) { + var val; + val = obj[key]; + delete obj[key]; + return val; + }; + + exports.last = function(array, back) { + return array[array.length - (back || 0) - 1]; + }; + +}).call(this); diff --git a/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/index.js b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/index.js new file mode 100644 index 0000000..d344c41 --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/index.js @@ -0,0 +1,11 @@ +// Generated by CoffeeScript 1.3.3 +(function() { + var key, val, _ref; + + _ref = require('./coffee-script'); + for (key in _ref) { + val = _ref[key]; + exports[key] = val; + } + +}).call(this); diff --git a/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/lexer.js b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/lexer.js new file mode 100644 index 0000000..f80a443 --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/lexer.js @@ -0,0 +1,788 @@ +// Generated by CoffeeScript 1.3.3 +(function() { + var BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, key, last, starts, _ref, _ref1, + __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + + _ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES; + + _ref1 = require('./helpers'), count = _ref1.count, starts = _ref1.starts, compact = _ref1.compact, last = _ref1.last; + + exports.Lexer = Lexer = (function() { + + function Lexer() {} + + Lexer.prototype.tokenize = function(code, opts) { + var i, tag; + if (opts == null) { + opts = {}; + } + if (WHITESPACE.test(code)) { + code = "\n" + code; + } + code = code.replace(/\r/g, '').replace(TRAILING_SPACES, ''); + this.code = code; + this.line = opts.line || 0; + this.indent = 0; + this.indebt = 0; + this.outdebt = 0; + this.indents = []; + this.ends = []; + this.tokens = []; + i = 0; + while (this.chunk = code.slice(i)) { + i += this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken(); + } + this.closeIndentation(); + if (tag = this.ends.pop()) { + this.error("missing " + tag); + } + if (opts.rewrite === false) { + return this.tokens; + } + return (new Rewriter).rewrite(this.tokens); + }; + + Lexer.prototype.identifierToken = function() { + var colon, forcedIdentifier, id, input, match, prev, tag, _ref2, _ref3; + if (!(match = IDENTIFIER.exec(this.chunk))) { + return 0; + } + input = match[0], id = match[1], colon = match[2]; + if (id === 'own' && this.tag() === 'FOR') { + this.token('OWN', id); + return id.length; + } + forcedIdentifier = colon || (prev = last(this.tokens)) && (((_ref2 = prev[0]) === '.' || _ref2 === '?.' || _ref2 === '::') || !prev.spaced && prev[0] === '@'); + tag = 'IDENTIFIER'; + if (!forcedIdentifier && (__indexOf.call(JS_KEYWORDS, id) >= 0 || __indexOf.call(COFFEE_KEYWORDS, id) >= 0)) { + tag = id.toUpperCase(); + if (tag === 'WHEN' && (_ref3 = this.tag(), __indexOf.call(LINE_BREAK, _ref3) >= 0)) { + tag = 'LEADING_WHEN'; + } else if (tag === 'FOR') { + this.seenFor = true; + } else if (tag === 'UNLESS') { + tag = 'IF'; + } else if (__indexOf.call(UNARY, tag) >= 0) { + tag = 'UNARY'; + } else if (__indexOf.call(RELATION, tag) >= 0) { + if (tag !== 'INSTANCEOF' && this.seenFor) { + tag = 'FOR' + tag; + this.seenFor = false; + } else { + tag = 'RELATION'; + if (this.value() === '!') { + this.tokens.pop(); + id = '!' + id; + } + } + } + } + if (__indexOf.call(JS_FORBIDDEN, id) >= 0) { + if (forcedIdentifier) { + tag = 'IDENTIFIER'; + id = new String(id); + id.reserved = true; + } else if (__indexOf.call(RESERVED, id) >= 0) { + this.error("reserved word \"" + id + "\""); + } + } + if (!forcedIdentifier) { + if (__indexOf.call(COFFEE_ALIASES, id) >= 0) { + id = COFFEE_ALIAS_MAP[id]; + } + tag = (function() { + switch (id) { + case '!': + return 'UNARY'; + case '==': + case '!=': + return 'COMPARE'; + case '&&': + case '||': + return 'LOGIC'; + case 'true': + case 'false': + return 'BOOL'; + case 'break': + case 'continue': + return 'STATEMENT'; + default: + return tag; + } + })(); + } + this.token(tag, id); + if (colon) { + this.token(':', ':'); + } + return input.length; + }; + + Lexer.prototype.numberToken = function() { + var binaryLiteral, lexedLength, match, number, octalLiteral; + if (!(match = NUMBER.exec(this.chunk))) { + return 0; + } + number = match[0]; + if (/^0[BOX]/.test(number)) { + this.error("radix prefix '" + number + "' must be lowercase"); + } else if (/E/.test(number) && !/^0x/.test(number)) { + this.error("exponential notation '" + number + "' must be indicated with a lowercase 'e'"); + } else if (/^0\d*[89]/.test(number)) { + this.error("decimal literal '" + number + "' must not be prefixed with '0'"); + } else if (/^0\d+/.test(number)) { + this.error("octal literal '" + number + "' must be prefixed with '0o'"); + } + lexedLength = number.length; + if (octalLiteral = /^0o([0-7]+)/.exec(number)) { + number = '0x' + (parseInt(octalLiteral[1], 8)).toString(16); + } + if (binaryLiteral = /^0b([01]+)/.exec(number)) { + number = '0x' + (parseInt(binaryLiteral[1], 2)).toString(16); + } + this.token('NUMBER', number); + return lexedLength; + }; + + Lexer.prototype.stringToken = function() { + var match, octalEsc, string; + switch (this.chunk.charAt(0)) { + case "'": + if (!(match = SIMPLESTR.exec(this.chunk))) { + return 0; + } + this.token('STRING', (string = match[0]).replace(MULTILINER, '\\\n')); + break; + case '"': + if (!(string = this.balancedString(this.chunk, '"'))) { + return 0; + } + if (0 < string.indexOf('#{', 1)) { + this.interpolateString(string.slice(1, -1)); + } else { + this.token('STRING', this.escapeLines(string)); + } + break; + default: + return 0; + } + if (octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test(string)) { + this.error("octal escape sequences " + string + " are not allowed"); + } + this.line += count(string, '\n'); + return string.length; + }; + + Lexer.prototype.heredocToken = function() { + var doc, heredoc, match, quote; + if (!(match = HEREDOC.exec(this.chunk))) { + return 0; + } + heredoc = match[0]; + quote = heredoc.charAt(0); + doc = this.sanitizeHeredoc(match[2], { + quote: quote, + indent: null + }); + if (quote === '"' && 0 <= doc.indexOf('#{')) { + this.interpolateString(doc, { + heredoc: true + }); + } else { + this.token('STRING', this.makeString(doc, quote, true)); + } + this.line += count(heredoc, '\n'); + return heredoc.length; + }; + + Lexer.prototype.commentToken = function() { + var comment, here, match; + if (!(match = this.chunk.match(COMMENT))) { + return 0; + } + comment = match[0], here = match[1]; + if (here) { + this.token('HERECOMMENT', this.sanitizeHeredoc(here, { + herecomment: true, + indent: Array(this.indent + 1).join(' ') + })); + } + this.line += count(comment, '\n'); + return comment.length; + }; + + Lexer.prototype.jsToken = function() { + var match, script; + if (!(this.chunk.charAt(0) === '`' && (match = JSTOKEN.exec(this.chunk)))) { + return 0; + } + this.token('JS', (script = match[0]).slice(1, -1)); + return script.length; + }; + + Lexer.prototype.regexToken = function() { + var flags, length, match, prev, regex, _ref2, _ref3; + if (this.chunk.charAt(0) !== '/') { + return 0; + } + if (match = HEREGEX.exec(this.chunk)) { + length = this.heregexToken(match); + this.line += count(match[0], '\n'); + return length; + } + prev = last(this.tokens); + if (prev && (_ref2 = prev[0], __indexOf.call((prev.spaced ? NOT_REGEX : NOT_SPACED_REGEX), _ref2) >= 0)) { + return 0; + } + if (!(match = REGEX.exec(this.chunk))) { + return 0; + } + _ref3 = match, match = _ref3[0], regex = _ref3[1], flags = _ref3[2]; + if (regex.slice(0, 2) === '/*') { + this.error('regular expressions cannot begin with `*`'); + } + if (regex === '//') { + regex = '/(?:)/'; + } + this.token('REGEX', "" + regex + flags); + return match.length; + }; + + Lexer.prototype.heregexToken = function(match) { + var body, flags, heregex, re, tag, tokens, value, _i, _len, _ref2, _ref3, _ref4, _ref5; + heregex = match[0], body = match[1], flags = match[2]; + if (0 > body.indexOf('#{')) { + re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/'); + if (re.match(/^\*/)) { + this.error('regular expressions cannot begin with `*`'); + } + this.token('REGEX', "/" + (re || '(?:)') + "/" + flags); + return heregex.length; + } + this.token('IDENTIFIER', 'RegExp'); + this.tokens.push(['CALL_START', '(']); + tokens = []; + _ref2 = this.interpolateString(body, { + regex: true + }); + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + _ref3 = _ref2[_i], tag = _ref3[0], value = _ref3[1]; + if (tag === 'TOKENS') { + tokens.push.apply(tokens, value); + } else { + if (!(value = value.replace(HEREGEX_OMIT, ''))) { + continue; + } + value = value.replace(/\\/g, '\\\\'); + tokens.push(['STRING', this.makeString(value, '"', true)]); + } + tokens.push(['+', '+']); + } + tokens.pop(); + if (((_ref4 = tokens[0]) != null ? _ref4[0] : void 0) !== 'STRING') { + this.tokens.push(['STRING', '""'], ['+', '+']); + } + (_ref5 = this.tokens).push.apply(_ref5, tokens); + if (flags) { + this.tokens.push([',', ','], ['STRING', '"' + flags + '"']); + } + this.token(')', ')'); + return heregex.length; + }; + + Lexer.prototype.lineToken = function() { + var diff, indent, match, noNewlines, prev, size; + if (!(match = MULTI_DENT.exec(this.chunk))) { + return 0; + } + indent = match[0]; + this.line += count(indent, '\n'); + this.seenFor = false; + prev = last(this.tokens, 1); + size = indent.length - 1 - indent.lastIndexOf('\n'); + noNewlines = this.unfinished(); + if (size - this.indebt === this.indent) { + if (noNewlines) { + this.suppressNewlines(); + } else { + this.newlineToken(); + } + return indent.length; + } + if (size > this.indent) { + if (noNewlines) { + this.indebt = size - this.indent; + this.suppressNewlines(); + return indent.length; + } + diff = size - this.indent + this.outdebt; + this.token('INDENT', diff); + this.indents.push(diff); + this.ends.push('OUTDENT'); + this.outdebt = this.indebt = 0; + } else { + this.indebt = 0; + this.outdentToken(this.indent - size, noNewlines); + } + this.indent = size; + return indent.length; + }; + + Lexer.prototype.outdentToken = function(moveOut, noNewlines) { + var dent, len; + while (moveOut > 0) { + len = this.indents.length - 1; + if (this.indents[len] === void 0) { + moveOut = 0; + } else if (this.indents[len] === this.outdebt) { + moveOut -= this.outdebt; + this.outdebt = 0; + } else if (this.indents[len] < this.outdebt) { + this.outdebt -= this.indents[len]; + moveOut -= this.indents[len]; + } else { + dent = this.indents.pop() - this.outdebt; + moveOut -= dent; + this.outdebt = 0; + this.pair('OUTDENT'); + this.token('OUTDENT', dent); + } + } + if (dent) { + this.outdebt -= moveOut; + } + while (this.value() === ';') { + this.tokens.pop(); + } + if (!(this.tag() === 'TERMINATOR' || noNewlines)) { + this.token('TERMINATOR', '\n'); + } + return this; + }; + + Lexer.prototype.whitespaceToken = function() { + var match, nline, prev; + if (!((match = WHITESPACE.exec(this.chunk)) || (nline = this.chunk.charAt(0) === '\n'))) { + return 0; + } + prev = last(this.tokens); + if (prev) { + prev[match ? 'spaced' : 'newLine'] = true; + } + if (match) { + return match[0].length; + } else { + return 0; + } + }; + + Lexer.prototype.newlineToken = function() { + while (this.value() === ';') { + this.tokens.pop(); + } + if (this.tag() !== 'TERMINATOR') { + this.token('TERMINATOR', '\n'); + } + return this; + }; + + Lexer.prototype.suppressNewlines = function() { + if (this.value() === '\\') { + this.tokens.pop(); + } + return this; + }; + + Lexer.prototype.literalToken = function() { + var match, prev, tag, value, _ref2, _ref3, _ref4, _ref5; + if (match = OPERATOR.exec(this.chunk)) { + value = match[0]; + if (CODE.test(value)) { + this.tagParameters(); + } + } else { + value = this.chunk.charAt(0); + } + tag = value; + prev = last(this.tokens); + if (value === '=' && prev) { + if (!prev[1].reserved && (_ref2 = prev[1], __indexOf.call(JS_FORBIDDEN, _ref2) >= 0)) { + this.error("reserved word \"" + (this.value()) + "\" can't be assigned"); + } + if ((_ref3 = prev[1]) === '||' || _ref3 === '&&') { + prev[0] = 'COMPOUND_ASSIGN'; + prev[1] += '='; + return value.length; + } + } + if (value === ';') { + this.seenFor = false; + tag = 'TERMINATOR'; + } else if (__indexOf.call(MATH, value) >= 0) { + tag = 'MATH'; + } else if (__indexOf.call(COMPARE, value) >= 0) { + tag = 'COMPARE'; + } else if (__indexOf.call(COMPOUND_ASSIGN, value) >= 0) { + tag = 'COMPOUND_ASSIGN'; + } else if (__indexOf.call(UNARY, value) >= 0) { + tag = 'UNARY'; + } else if (__indexOf.call(SHIFT, value) >= 0) { + tag = 'SHIFT'; + } else if (__indexOf.call(LOGIC, value) >= 0 || value === '?' && (prev != null ? prev.spaced : void 0)) { + tag = 'LOGIC'; + } else if (prev && !prev.spaced) { + if (value === '(' && (_ref4 = prev[0], __indexOf.call(CALLABLE, _ref4) >= 0)) { + if (prev[0] === '?') { + prev[0] = 'FUNC_EXIST'; + } + tag = 'CALL_START'; + } else if (value === '[' && (_ref5 = prev[0], __indexOf.call(INDEXABLE, _ref5) >= 0)) { + tag = 'INDEX_START'; + switch (prev[0]) { + case '?': + prev[0] = 'INDEX_SOAK'; + } + } + } + switch (value) { + case '(': + case '{': + case '[': + this.ends.push(INVERSES[value]); + break; + case ')': + case '}': + case ']': + this.pair(value); + } + this.token(tag, value); + return value.length; + }; + + Lexer.prototype.sanitizeHeredoc = function(doc, options) { + var attempt, herecomment, indent, match, _ref2; + indent = options.indent, herecomment = options.herecomment; + if (herecomment) { + if (HEREDOC_ILLEGAL.test(doc)) { + this.error("block comment cannot contain \"*/\", starting"); + } + if (doc.indexOf('\n') <= 0) { + return doc; + } + } else { + while (match = HEREDOC_INDENT.exec(doc)) { + attempt = match[1]; + if (indent === null || (0 < (_ref2 = attempt.length) && _ref2 < indent.length)) { + indent = attempt; + } + } + } + if (indent) { + doc = doc.replace(RegExp("\\n" + indent, "g"), '\n'); + } + if (!herecomment) { + doc = doc.replace(/^\n/, ''); + } + return doc; + }; + + Lexer.prototype.tagParameters = function() { + var i, stack, tok, tokens; + if (this.tag() !== ')') { + return this; + } + stack = []; + tokens = this.tokens; + i = tokens.length; + tokens[--i][0] = 'PARAM_END'; + while (tok = tokens[--i]) { + switch (tok[0]) { + case ')': + stack.push(tok); + break; + case '(': + case 'CALL_START': + if (stack.length) { + stack.pop(); + } else if (tok[0] === '(') { + tok[0] = 'PARAM_START'; + return this; + } else { + return this; + } + } + } + return this; + }; + + Lexer.prototype.closeIndentation = function() { + return this.outdentToken(this.indent); + }; + + Lexer.prototype.balancedString = function(str, end) { + var continueCount, i, letter, match, prev, stack, _i, _ref2; + continueCount = 0; + stack = [end]; + for (i = _i = 1, _ref2 = str.length; 1 <= _ref2 ? _i < _ref2 : _i > _ref2; i = 1 <= _ref2 ? ++_i : --_i) { + if (continueCount) { + --continueCount; + continue; + } + switch (letter = str.charAt(i)) { + case '\\': + ++continueCount; + continue; + case end: + stack.pop(); + if (!stack.length) { + return str.slice(0, i + 1 || 9e9); + } + end = stack[stack.length - 1]; + continue; + } + if (end === '}' && (letter === '"' || letter === "'")) { + stack.push(end = letter); + } else if (end === '}' && letter === '/' && (match = HEREGEX.exec(str.slice(i)) || REGEX.exec(str.slice(i)))) { + continueCount += match[0].length - 1; + } else if (end === '}' && letter === '{') { + stack.push(end = '}'); + } else if (end === '"' && prev === '#' && letter === '{') { + stack.push(end = '}'); + } + prev = letter; + } + return this.error("missing " + (stack.pop()) + ", starting"); + }; + + Lexer.prototype.interpolateString = function(str, options) { + var expr, heredoc, i, inner, interpolated, len, letter, nested, pi, regex, tag, tokens, value, _i, _len, _ref2, _ref3, _ref4; + if (options == null) { + options = {}; + } + heredoc = options.heredoc, regex = options.regex; + tokens = []; + pi = 0; + i = -1; + while (letter = str.charAt(i += 1)) { + if (letter === '\\') { + i += 1; + continue; + } + if (!(letter === '#' && str.charAt(i + 1) === '{' && (expr = this.balancedString(str.slice(i + 1), '}')))) { + continue; + } + if (pi < i) { + tokens.push(['NEOSTRING', str.slice(pi, i)]); + } + inner = expr.slice(1, -1); + if (inner.length) { + nested = new Lexer().tokenize(inner, { + line: this.line, + rewrite: false + }); + nested.pop(); + if (((_ref2 = nested[0]) != null ? _ref2[0] : void 0) === 'TERMINATOR') { + nested.shift(); + } + if (len = nested.length) { + if (len > 1) { + nested.unshift(['(', '(', this.line]); + nested.push([')', ')', this.line]); + } + tokens.push(['TOKENS', nested]); + } + } + i += expr.length; + pi = i + 1; + } + if ((i > pi && pi < str.length)) { + tokens.push(['NEOSTRING', str.slice(pi)]); + } + if (regex) { + return tokens; + } + if (!tokens.length) { + return this.token('STRING', '""'); + } + if (tokens[0][0] !== 'NEOSTRING') { + tokens.unshift(['', '']); + } + if (interpolated = tokens.length > 1) { + this.token('(', '('); + } + for (i = _i = 0, _len = tokens.length; _i < _len; i = ++_i) { + _ref3 = tokens[i], tag = _ref3[0], value = _ref3[1]; + if (i) { + this.token('+', '+'); + } + if (tag === 'TOKENS') { + (_ref4 = this.tokens).push.apply(_ref4, value); + } else { + this.token('STRING', this.makeString(value, '"', heredoc)); + } + } + if (interpolated) { + this.token(')', ')'); + } + return tokens; + }; + + Lexer.prototype.pair = function(tag) { + var size, wanted; + if (tag !== (wanted = last(this.ends))) { + if ('OUTDENT' !== wanted) { + this.error("unmatched " + tag); + } + this.indent -= size = last(this.indents); + this.outdentToken(size, true); + return this.pair(tag); + } + return this.ends.pop(); + }; + + Lexer.prototype.token = function(tag, value) { + return this.tokens.push([tag, value, this.line]); + }; + + Lexer.prototype.tag = function(index, tag) { + var tok; + return (tok = last(this.tokens, index)) && (tag ? tok[0] = tag : tok[0]); + }; + + Lexer.prototype.value = function(index, val) { + var tok; + return (tok = last(this.tokens, index)) && (val ? tok[1] = val : tok[1]); + }; + + Lexer.prototype.unfinished = function() { + var _ref2; + return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS'); + }; + + Lexer.prototype.escapeLines = function(str, heredoc) { + return str.replace(MULTILINER, heredoc ? '\\n' : ''); + }; + + Lexer.prototype.makeString = function(body, quote, heredoc) { + if (!body) { + return quote + quote; + } + body = body.replace(/\\([\s\S])/g, function(match, contents) { + if (contents === '\n' || contents === quote) { + return contents; + } else { + return match; + } + }); + body = body.replace(RegExp("" + quote, "g"), '\\$&'); + return quote + this.escapeLines(body, heredoc) + quote; + }; + + Lexer.prototype.error = function(message) { + throw SyntaxError("" + message + " on line " + (this.line + 1)); + }; + + return Lexer; + + })(); + + JS_KEYWORDS = ['true', 'false', 'null', 'this', 'new', 'delete', 'typeof', 'in', 'instanceof', 'return', 'throw', 'break', 'continue', 'debugger', 'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally', 'class', 'extends', 'super']; + + COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when']; + + COFFEE_ALIAS_MAP = { + and: '&&', + or: '||', + is: '==', + isnt: '!=', + not: '!', + yes: 'true', + no: 'false', + on: 'true', + off: 'false' + }; + + COFFEE_ALIASES = (function() { + var _results; + _results = []; + for (key in COFFEE_ALIAS_MAP) { + _results.push(key); + } + return _results; + })(); + + COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat(COFFEE_ALIASES); + + RESERVED = ['case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind', '__indexOf', 'implements', 'interface', 'let', 'package', 'private', 'protected', 'public', 'static', 'yield']; + + STRICT_PROSCRIBED = ['arguments', 'eval']; + + JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED).concat(STRICT_PROSCRIBED); + + exports.RESERVED = RESERVED.concat(JS_KEYWORDS).concat(COFFEE_KEYWORDS).concat(STRICT_PROSCRIBED); + + exports.STRICT_PROSCRIBED = STRICT_PROSCRIBED; + + IDENTIFIER = /^([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)([^\n\S]*:(?!:))?/; + + NUMBER = /^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i; + + HEREDOC = /^("""|''')([\s\S]*?)(?:\n[^\n\S]*)?\1/; + + OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/; + + WHITESPACE = /^[^\n\S]+/; + + COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|(?:###)?$)|^(?:\s*#(?!##[^#]).*)+/; + + CODE = /^[-=]>/; + + MULTI_DENT = /^(?:\n[^\n\S]*)+/; + + SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/; + + JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/; + + REGEX = /^(\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)([imgy]{0,4})(?!\w)/; + + HEREGEX = /^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?!\w)/; + + HEREGEX_OMIT = /\s+(?:#.*)?/g; + + MULTILINER = /\n/g; + + HEREDOC_INDENT = /\n+([^\n\S]*)/g; + + HEREDOC_ILLEGAL = /\*\//; + + LINE_CONTINUER = /^\s*(?:,|\??\.(?![.\d])|::)/; + + TRAILING_SPACES = /\s+$/; + + COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|=']; + + UNARY = ['!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO']; + + LOGIC = ['&&', '||', '&', '|', '^']; + + SHIFT = ['<<', '>>', '>>>']; + + COMPARE = ['==', '!=', '<', '>', '<=', '>=']; + + MATH = ['*', '/', '%']; + + RELATION = ['IN', 'OF', 'INSTANCEOF']; + + BOOL = ['TRUE', 'FALSE']; + + NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--', ']']; + + NOT_SPACED_REGEX = NOT_REGEX.concat(')', '}', 'THIS', 'IDENTIFIER', 'STRING'); + + CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER']; + + INDEXABLE = CALLABLE.concat('NUMBER', 'BOOL', 'NULL', 'UNDEFINED'); + + LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR']; + +}).call(this); diff --git a/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/nodes.js b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/nodes.js new file mode 100644 index 0000000..799b68e --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/nodes.js @@ -0,0 +1,2986 @@ +// Generated by CoffeeScript 1.3.3 +(function() { + var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, Comment, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, starts, unfoldSoak, utility, _ref, _ref1, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + + Scope = require('./scope').Scope; + + _ref = require('./lexer'), RESERVED = _ref.RESERVED, STRICT_PROSCRIBED = _ref.STRICT_PROSCRIBED; + + _ref1 = require('./helpers'), compact = _ref1.compact, flatten = _ref1.flatten, extend = _ref1.extend, merge = _ref1.merge, del = _ref1.del, starts = _ref1.starts, ends = _ref1.ends, last = _ref1.last; + + exports.extend = extend; + + YES = function() { + return true; + }; + + NO = function() { + return false; + }; + + THIS = function() { + return this; + }; + + NEGATE = function() { + this.negated = !this.negated; + return this; + }; + + exports.Base = Base = (function() { + + function Base() {} + + Base.prototype.compile = function(o, lvl) { + var node; + o = extend({}, o); + if (lvl) { + o.level = lvl; + } + node = this.unfoldSoak(o) || this; + node.tab = o.indent; + if (o.level === LEVEL_TOP || !node.isStatement(o)) { + return node.compileNode(o); + } else { + return node.compileClosure(o); + } + }; + + Base.prototype.compileClosure = function(o) { + if (this.jumps()) { + throw SyntaxError('cannot use a pure statement in an expression.'); + } + o.sharedScope = true; + return Closure.wrap(this).compileNode(o); + }; + + Base.prototype.cache = function(o, level, reused) { + var ref, sub; + if (!this.isComplex()) { + ref = level ? this.compile(o, level) : this; + return [ref, ref]; + } else { + ref = new Literal(reused || o.scope.freeVariable('ref')); + sub = new Assign(ref, this); + if (level) { + return [sub.compile(o, level), ref.value]; + } else { + return [sub, ref]; + } + } + }; + + Base.prototype.compileLoopReference = function(o, name) { + var src, tmp; + src = tmp = this.compile(o, LEVEL_LIST); + if (!((-Infinity < +src && +src < Infinity) || IDENTIFIER.test(src) && o.scope.check(src, true))) { + src = "" + (tmp = o.scope.freeVariable(name)) + " = " + src; + } + return [src, tmp]; + }; + + Base.prototype.makeReturn = function(res) { + var me; + me = this.unwrapAll(); + if (res) { + return new Call(new Literal("" + res + ".push"), [me]); + } else { + return new Return(me); + } + }; + + Base.prototype.contains = function(pred) { + var contains; + contains = false; + this.traverseChildren(false, function(node) { + if (pred(node)) { + contains = true; + return false; + } + }); + return contains; + }; + + Base.prototype.containsType = function(type) { + return this instanceof type || this.contains(function(node) { + return node instanceof type; + }); + }; + + Base.prototype.lastNonComment = function(list) { + var i; + i = list.length; + while (i--) { + if (!(list[i] instanceof Comment)) { + return list[i]; + } + } + return null; + }; + + Base.prototype.toString = function(idt, name) { + var tree; + if (idt == null) { + idt = ''; + } + if (name == null) { + name = this.constructor.name; + } + tree = '\n' + idt + name; + if (this.soak) { + tree += '?'; + } + this.eachChild(function(node) { + return tree += node.toString(idt + TAB); + }); + return tree; + }; + + Base.prototype.eachChild = function(func) { + var attr, child, _i, _j, _len, _len1, _ref2, _ref3; + if (!this.children) { + return this; + } + _ref2 = this.children; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + attr = _ref2[_i]; + if (this[attr]) { + _ref3 = flatten([this[attr]]); + for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { + child = _ref3[_j]; + if (func(child) === false) { + return this; + } + } + } + } + return this; + }; + + Base.prototype.traverseChildren = function(crossScope, func) { + return this.eachChild(function(child) { + if (func(child) === false) { + return false; + } + return child.traverseChildren(crossScope, func); + }); + }; + + Base.prototype.invert = function() { + return new Op('!', this); + }; + + Base.prototype.unwrapAll = function() { + var node; + node = this; + while (node !== (node = node.unwrap())) { + continue; + } + return node; + }; + + Base.prototype.children = []; + + Base.prototype.isStatement = NO; + + Base.prototype.jumps = NO; + + Base.prototype.isComplex = YES; + + Base.prototype.isChainable = NO; + + Base.prototype.isAssignable = NO; + + Base.prototype.unwrap = THIS; + + Base.prototype.unfoldSoak = NO; + + Base.prototype.assigns = NO; + + return Base; + + })(); + + exports.Block = Block = (function(_super) { + + __extends(Block, _super); + + function Block(nodes) { + this.expressions = compact(flatten(nodes || [])); + } + + Block.prototype.children = ['expressions']; + + Block.prototype.push = function(node) { + this.expressions.push(node); + return this; + }; + + Block.prototype.pop = function() { + return this.expressions.pop(); + }; + + Block.prototype.unshift = function(node) { + this.expressions.unshift(node); + return this; + }; + + Block.prototype.unwrap = function() { + if (this.expressions.length === 1) { + return this.expressions[0]; + } else { + return this; + } + }; + + Block.prototype.isEmpty = function() { + return !this.expressions.length; + }; + + Block.prototype.isStatement = function(o) { + var exp, _i, _len, _ref2; + _ref2 = this.expressions; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + exp = _ref2[_i]; + if (exp.isStatement(o)) { + return true; + } + } + return false; + }; + + Block.prototype.jumps = function(o) { + var exp, _i, _len, _ref2; + _ref2 = this.expressions; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + exp = _ref2[_i]; + if (exp.jumps(o)) { + return exp; + } + } + }; + + Block.prototype.makeReturn = function(res) { + var expr, len; + len = this.expressions.length; + while (len--) { + expr = this.expressions[len]; + if (!(expr instanceof Comment)) { + this.expressions[len] = expr.makeReturn(res); + if (expr instanceof Return && !expr.expression) { + this.expressions.splice(len, 1); + } + break; + } + } + return this; + }; + + Block.prototype.compile = function(o, level) { + if (o == null) { + o = {}; + } + if (o.scope) { + return Block.__super__.compile.call(this, o, level); + } else { + return this.compileRoot(o); + } + }; + + Block.prototype.compileNode = function(o) { + var code, codes, node, top, _i, _len, _ref2; + this.tab = o.indent; + top = o.level === LEVEL_TOP; + codes = []; + _ref2 = this.expressions; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + node = _ref2[_i]; + node = node.unwrapAll(); + node = node.unfoldSoak(o) || node; + if (node instanceof Block) { + codes.push(node.compileNode(o)); + } else if (top) { + node.front = true; + code = node.compile(o); + if (!node.isStatement(o)) { + code = "" + this.tab + code + ";"; + if (node instanceof Literal) { + code = "" + code + "\n"; + } + } + codes.push(code); + } else { + codes.push(node.compile(o, LEVEL_LIST)); + } + } + if (top) { + if (this.spaced) { + return "\n" + (codes.join('\n\n')) + "\n"; + } else { + return codes.join('\n'); + } + } + code = codes.join(', ') || 'void 0'; + if (codes.length > 1 && o.level >= LEVEL_LIST) { + return "(" + code + ")"; + } else { + return code; + } + }; + + Block.prototype.compileRoot = function(o) { + var code, exp, i, prelude, preludeExps, rest; + o.indent = o.bare ? '' : TAB; + o.scope = new Scope(null, this, null); + o.level = LEVEL_TOP; + this.spaced = true; + prelude = ""; + if (!o.bare) { + preludeExps = (function() { + var _i, _len, _ref2, _results; + _ref2 = this.expressions; + _results = []; + for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) { + exp = _ref2[i]; + if (!(exp.unwrap() instanceof Comment)) { + break; + } + _results.push(exp); + } + return _results; + }).call(this); + rest = this.expressions.slice(preludeExps.length); + this.expressions = preludeExps; + if (preludeExps.length) { + prelude = "" + (this.compileNode(merge(o, { + indent: '' + }))) + "\n"; + } + this.expressions = rest; + } + code = this.compileWithDeclarations(o); + if (o.bare) { + return code; + } + return "" + prelude + "(function() {\n" + code + "\n}).call(this);\n"; + }; + + Block.prototype.compileWithDeclarations = function(o) { + var assigns, code, declars, exp, i, post, rest, scope, spaced, _i, _len, _ref2, _ref3, _ref4; + code = post = ''; + _ref2 = this.expressions; + for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) { + exp = _ref2[i]; + exp = exp.unwrap(); + if (!(exp instanceof Comment || exp instanceof Literal)) { + break; + } + } + o = merge(o, { + level: LEVEL_TOP + }); + if (i) { + rest = this.expressions.splice(i, 9e9); + _ref3 = [this.spaced, false], spaced = _ref3[0], this.spaced = _ref3[1]; + _ref4 = [this.compileNode(o), spaced], code = _ref4[0], this.spaced = _ref4[1]; + this.expressions = rest; + } + post = this.compileNode(o); + scope = o.scope; + if (scope.expressions === this) { + declars = o.scope.hasDeclarations(); + assigns = scope.hasAssignments; + if (declars || assigns) { + if (i) { + code += '\n'; + } + code += "" + this.tab + "var "; + if (declars) { + code += scope.declaredVariables().join(', '); + } + if (assigns) { + if (declars) { + code += ",\n" + (this.tab + TAB); + } + code += scope.assignedVariables().join(",\n" + (this.tab + TAB)); + } + code += ';\n'; + } + } + return code + post; + }; + + Block.wrap = function(nodes) { + if (nodes.length === 1 && nodes[0] instanceof Block) { + return nodes[0]; + } + return new Block(nodes); + }; + + return Block; + + })(Base); + + exports.Literal = Literal = (function(_super) { + + __extends(Literal, _super); + + function Literal(value) { + this.value = value; + } + + Literal.prototype.makeReturn = function() { + if (this.isStatement()) { + return this; + } else { + return Literal.__super__.makeReturn.apply(this, arguments); + } + }; + + Literal.prototype.isAssignable = function() { + return IDENTIFIER.test(this.value); + }; + + Literal.prototype.isStatement = function() { + var _ref2; + return (_ref2 = this.value) === 'break' || _ref2 === 'continue' || _ref2 === 'debugger'; + }; + + Literal.prototype.isComplex = NO; + + Literal.prototype.assigns = function(name) { + return name === this.value; + }; + + Literal.prototype.jumps = function(o) { + if (this.value === 'break' && !((o != null ? o.loop : void 0) || (o != null ? o.block : void 0))) { + return this; + } + if (this.value === 'continue' && !(o != null ? o.loop : void 0)) { + return this; + } + }; + + Literal.prototype.compileNode = function(o) { + var code, _ref2; + code = this.value === 'this' ? ((_ref2 = o.scope.method) != null ? _ref2.bound : void 0) ? o.scope.method.context : this.value : this.value.reserved ? "\"" + this.value + "\"" : this.value; + if (this.isStatement()) { + return "" + this.tab + code + ";"; + } else { + return code; + } + }; + + Literal.prototype.toString = function() { + return ' "' + this.value + '"'; + }; + + return Literal; + + })(Base); + + exports.Undefined = (function(_super) { + + __extends(Undefined, _super); + + function Undefined() { + return Undefined.__super__.constructor.apply(this, arguments); + } + + Undefined.prototype.isAssignable = NO; + + Undefined.prototype.isComplex = NO; + + Undefined.prototype.compileNode = function(o) { + if (o.level >= LEVEL_ACCESS) { + return '(void 0)'; + } else { + return 'void 0'; + } + }; + + return Undefined; + + })(Base); + + exports.Null = (function(_super) { + + __extends(Null, _super); + + function Null() { + return Null.__super__.constructor.apply(this, arguments); + } + + Null.prototype.isAssignable = NO; + + Null.prototype.isComplex = NO; + + Null.prototype.compileNode = function() { + return "null"; + }; + + return Null; + + })(Base); + + exports.Bool = (function(_super) { + + __extends(Bool, _super); + + Bool.prototype.isAssignable = NO; + + Bool.prototype.isComplex = NO; + + Bool.prototype.compileNode = function() { + return this.val; + }; + + function Bool(val) { + this.val = val; + } + + return Bool; + + })(Base); + + exports.Return = Return = (function(_super) { + + __extends(Return, _super); + + function Return(expr) { + if (expr && !expr.unwrap().isUndefined) { + this.expression = expr; + } + } + + Return.prototype.children = ['expression']; + + Return.prototype.isStatement = YES; + + Return.prototype.makeReturn = THIS; + + Return.prototype.jumps = THIS; + + Return.prototype.compile = function(o, level) { + var expr, _ref2; + expr = (_ref2 = this.expression) != null ? _ref2.makeReturn() : void 0; + if (expr && !(expr instanceof Return)) { + return expr.compile(o, level); + } else { + return Return.__super__.compile.call(this, o, level); + } + }; + + Return.prototype.compileNode = function(o) { + return this.tab + ("return" + [this.expression ? " " + (this.expression.compile(o, LEVEL_PAREN)) : void 0] + ";"); + }; + + return Return; + + })(Base); + + exports.Value = Value = (function(_super) { + + __extends(Value, _super); + + function Value(base, props, tag) { + if (!props && base instanceof Value) { + return base; + } + this.base = base; + this.properties = props || []; + if (tag) { + this[tag] = true; + } + return this; + } + + Value.prototype.children = ['base', 'properties']; + + Value.prototype.add = function(props) { + this.properties = this.properties.concat(props); + return this; + }; + + Value.prototype.hasProperties = function() { + return !!this.properties.length; + }; + + Value.prototype.isArray = function() { + return !this.properties.length && this.base instanceof Arr; + }; + + Value.prototype.isComplex = function() { + return this.hasProperties() || this.base.isComplex(); + }; + + Value.prototype.isAssignable = function() { + return this.hasProperties() || this.base.isAssignable(); + }; + + Value.prototype.isSimpleNumber = function() { + return this.base instanceof Literal && SIMPLENUM.test(this.base.value); + }; + + Value.prototype.isString = function() { + return this.base instanceof Literal && IS_STRING.test(this.base.value); + }; + + Value.prototype.isAtomic = function() { + var node, _i, _len, _ref2; + _ref2 = this.properties.concat(this.base); + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + node = _ref2[_i]; + if (node.soak || node instanceof Call) { + return false; + } + } + return true; + }; + + Value.prototype.isStatement = function(o) { + return !this.properties.length && this.base.isStatement(o); + }; + + Value.prototype.assigns = function(name) { + return !this.properties.length && this.base.assigns(name); + }; + + Value.prototype.jumps = function(o) { + return !this.properties.length && this.base.jumps(o); + }; + + Value.prototype.isObject = function(onlyGenerated) { + if (this.properties.length) { + return false; + } + return (this.base instanceof Obj) && (!onlyGenerated || this.base.generated); + }; + + Value.prototype.isSplice = function() { + return last(this.properties) instanceof Slice; + }; + + Value.prototype.unwrap = function() { + if (this.properties.length) { + return this; + } else { + return this.base; + } + }; + + Value.prototype.cacheReference = function(o) { + var base, bref, name, nref; + name = last(this.properties); + if (this.properties.length < 2 && !this.base.isComplex() && !(name != null ? name.isComplex() : void 0)) { + return [this, this]; + } + base = new Value(this.base, this.properties.slice(0, -1)); + if (base.isComplex()) { + bref = new Literal(o.scope.freeVariable('base')); + base = new Value(new Parens(new Assign(bref, base))); + } + if (!name) { + return [base, bref]; + } + if (name.isComplex()) { + nref = new Literal(o.scope.freeVariable('name')); + name = new Index(new Assign(nref, name.index)); + nref = new Index(nref); + } + return [base.add(name), new Value(bref || base.base, [nref || name])]; + }; + + Value.prototype.compileNode = function(o) { + var code, prop, props, _i, _len; + this.base.front = this.front; + props = this.properties; + code = this.base.compile(o, props.length ? LEVEL_ACCESS : null); + if ((this.base instanceof Parens || props.length) && SIMPLENUM.test(code)) { + code = "" + code + "."; + } + for (_i = 0, _len = props.length; _i < _len; _i++) { + prop = props[_i]; + code += prop.compile(o); + } + return code; + }; + + Value.prototype.unfoldSoak = function(o) { + var result, + _this = this; + if (this.unfoldedSoak != null) { + return this.unfoldedSoak; + } + result = (function() { + var fst, i, ifn, prop, ref, snd, _i, _len, _ref2; + if (ifn = _this.base.unfoldSoak(o)) { + Array.prototype.push.apply(ifn.body.properties, _this.properties); + return ifn; + } + _ref2 = _this.properties; + for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) { + prop = _ref2[i]; + if (!prop.soak) { + continue; + } + prop.soak = false; + fst = new Value(_this.base, _this.properties.slice(0, i)); + snd = new Value(_this.base, _this.properties.slice(i)); + if (fst.isComplex()) { + ref = new Literal(o.scope.freeVariable('ref')); + fst = new Parens(new Assign(ref, fst)); + snd.base = ref; + } + return new If(new Existence(fst), snd, { + soak: true + }); + } + return null; + })(); + return this.unfoldedSoak = result || false; + }; + + return Value; + + })(Base); + + exports.Comment = Comment = (function(_super) { + + __extends(Comment, _super); + + function Comment(comment) { + this.comment = comment; + } + + Comment.prototype.isStatement = YES; + + Comment.prototype.makeReturn = THIS; + + Comment.prototype.compileNode = function(o, level) { + var code; + code = '/*' + multident(this.comment, this.tab) + ("\n" + this.tab + "*/\n"); + if ((level || o.level) === LEVEL_TOP) { + code = o.indent + code; + } + return code; + }; + + return Comment; + + })(Base); + + exports.Call = Call = (function(_super) { + + __extends(Call, _super); + + function Call(variable, args, soak) { + this.args = args != null ? args : []; + this.soak = soak; + this.isNew = false; + this.isSuper = variable === 'super'; + this.variable = this.isSuper ? null : variable; + } + + Call.prototype.children = ['variable', 'args']; + + Call.prototype.newInstance = function() { + var base, _ref2; + base = ((_ref2 = this.variable) != null ? _ref2.base : void 0) || this.variable; + if (base instanceof Call && !base.isNew) { + base.newInstance(); + } else { + this.isNew = true; + } + return this; + }; + + Call.prototype.superReference = function(o) { + var accesses, method, name; + method = o.scope.namedMethod(); + if (!method) { + throw SyntaxError('cannot call super outside of a function.'); + } + name = method.name; + if (name == null) { + throw SyntaxError('cannot call super on an anonymous function.'); + } + if (method.klass) { + accesses = [new Access(new Literal('__super__'))]; + if (method["static"]) { + accesses.push(new Access(new Literal('constructor'))); + } + accesses.push(new Access(new Literal(name))); + return (new Value(new Literal(method.klass), accesses)).compile(o); + } else { + return "" + name + ".__super__.constructor"; + } + }; + + Call.prototype.superThis = function(o) { + var method; + method = o.scope.method; + return (method && !method.klass && method.context) || "this"; + }; + + Call.prototype.unfoldSoak = function(o) { + var call, ifn, left, list, rite, _i, _len, _ref2, _ref3; + if (this.soak) { + if (this.variable) { + if (ifn = unfoldSoak(o, this, 'variable')) { + return ifn; + } + _ref2 = new Value(this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1]; + } else { + left = new Literal(this.superReference(o)); + rite = new Value(left); + } + rite = new Call(rite, this.args); + rite.isNew = this.isNew; + left = new Literal("typeof " + (left.compile(o)) + " === \"function\""); + return new If(left, new Value(rite), { + soak: true + }); + } + call = this; + list = []; + while (true) { + if (call.variable instanceof Call) { + list.push(call); + call = call.variable; + continue; + } + if (!(call.variable instanceof Value)) { + break; + } + list.push(call); + if (!((call = call.variable.base) instanceof Call)) { + break; + } + } + _ref3 = list.reverse(); + for (_i = 0, _len = _ref3.length; _i < _len; _i++) { + call = _ref3[_i]; + if (ifn) { + if (call.variable instanceof Call) { + call.variable = ifn; + } else { + call.variable.base = ifn; + } + } + ifn = unfoldSoak(o, call, 'variable'); + } + return ifn; + }; + + Call.prototype.filterImplicitObjects = function(list) { + var node, nodes, obj, prop, properties, _i, _j, _len, _len1, _ref2; + nodes = []; + for (_i = 0, _len = list.length; _i < _len; _i++) { + node = list[_i]; + if (!((typeof node.isObject === "function" ? node.isObject() : void 0) && node.base.generated)) { + nodes.push(node); + continue; + } + obj = null; + _ref2 = node.base.properties; + for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { + prop = _ref2[_j]; + if (prop instanceof Assign || prop instanceof Comment) { + if (!obj) { + nodes.push(obj = new Obj(properties = [], true)); + } + properties.push(prop); + } else { + nodes.push(prop); + obj = null; + } + } + } + return nodes; + }; + + Call.prototype.compileNode = function(o) { + var arg, args, code, _ref2; + if ((_ref2 = this.variable) != null) { + _ref2.front = this.front; + } + if (code = Splat.compileSplattedArray(o, this.args, true)) { + return this.compileSplat(o, code); + } + args = this.filterImplicitObjects(this.args); + args = ((function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = args.length; _i < _len; _i++) { + arg = args[_i]; + _results.push(arg.compile(o, LEVEL_LIST)); + } + return _results; + })()).join(', '); + if (this.isSuper) { + return this.superReference(o) + (".call(" + (this.superThis(o)) + (args && ', ' + args) + ")"); + } else { + return (this.isNew ? 'new ' : '') + this.variable.compile(o, LEVEL_ACCESS) + ("(" + args + ")"); + } + }; + + Call.prototype.compileSuper = function(args, o) { + return "" + (this.superReference(o)) + ".call(" + (this.superThis(o)) + (args.length ? ', ' : '') + args + ")"; + }; + + Call.prototype.compileSplat = function(o, splatArgs) { + var base, fun, idt, name, ref; + if (this.isSuper) { + return "" + (this.superReference(o)) + ".apply(" + (this.superThis(o)) + ", " + splatArgs + ")"; + } + if (this.isNew) { + idt = this.tab + TAB; + return "(function(func, args, ctor) {\n" + idt + "ctor.prototype = func.prototype;\n" + idt + "var child = new ctor, result = func.apply(child, args), t = typeof result;\n" + idt + "return t == \"object\" || t == \"function\" ? result || child : child;\n" + this.tab + "})(" + (this.variable.compile(o, LEVEL_LIST)) + ", " + splatArgs + ", function(){})"; + } + base = new Value(this.variable); + if ((name = base.properties.pop()) && base.isComplex()) { + ref = o.scope.freeVariable('ref'); + fun = "(" + ref + " = " + (base.compile(o, LEVEL_LIST)) + ")" + (name.compile(o)); + } else { + fun = base.compile(o, LEVEL_ACCESS); + if (SIMPLENUM.test(fun)) { + fun = "(" + fun + ")"; + } + if (name) { + ref = fun; + fun += name.compile(o); + } else { + ref = 'null'; + } + } + return "" + fun + ".apply(" + ref + ", " + splatArgs + ")"; + }; + + return Call; + + })(Base); + + exports.Extends = Extends = (function(_super) { + + __extends(Extends, _super); + + function Extends(child, parent) { + this.child = child; + this.parent = parent; + } + + Extends.prototype.children = ['child', 'parent']; + + Extends.prototype.compile = function(o) { + return new Call(new Value(new Literal(utility('extends'))), [this.child, this.parent]).compile(o); + }; + + return Extends; + + })(Base); + + exports.Access = Access = (function(_super) { + + __extends(Access, _super); + + function Access(name, tag) { + this.name = name; + this.name.asKey = true; + this.soak = tag === 'soak'; + } + + Access.prototype.children = ['name']; + + Access.prototype.compile = function(o) { + var name; + name = this.name.compile(o); + if (IDENTIFIER.test(name)) { + return "." + name; + } else { + return "[" + name + "]"; + } + }; + + Access.prototype.isComplex = NO; + + return Access; + + })(Base); + + exports.Index = Index = (function(_super) { + + __extends(Index, _super); + + function Index(index) { + this.index = index; + } + + Index.prototype.children = ['index']; + + Index.prototype.compile = function(o) { + return "[" + (this.index.compile(o, LEVEL_PAREN)) + "]"; + }; + + Index.prototype.isComplex = function() { + return this.index.isComplex(); + }; + + return Index; + + })(Base); + + exports.Range = Range = (function(_super) { + + __extends(Range, _super); + + Range.prototype.children = ['from', 'to']; + + function Range(from, to, tag) { + this.from = from; + this.to = to; + this.exclusive = tag === 'exclusive'; + this.equals = this.exclusive ? '' : '='; + } + + Range.prototype.compileVariables = function(o) { + var step, _ref2, _ref3, _ref4, _ref5; + o = merge(o, { + top: true + }); + _ref2 = this.from.cache(o, LEVEL_LIST), this.fromC = _ref2[0], this.fromVar = _ref2[1]; + _ref3 = this.to.cache(o, LEVEL_LIST), this.toC = _ref3[0], this.toVar = _ref3[1]; + if (step = del(o, 'step')) { + _ref4 = step.cache(o, LEVEL_LIST), this.step = _ref4[0], this.stepVar = _ref4[1]; + } + _ref5 = [this.fromVar.match(SIMPLENUM), this.toVar.match(SIMPLENUM)], this.fromNum = _ref5[0], this.toNum = _ref5[1]; + if (this.stepVar) { + return this.stepNum = this.stepVar.match(SIMPLENUM); + } + }; + + Range.prototype.compileNode = function(o) { + var cond, condPart, from, gt, idx, idxName, known, lt, namedIndex, stepPart, to, varPart, _ref2, _ref3; + if (!this.fromVar) { + this.compileVariables(o); + } + if (!o.index) { + return this.compileArray(o); + } + known = this.fromNum && this.toNum; + idx = del(o, 'index'); + idxName = del(o, 'name'); + namedIndex = idxName && idxName !== idx; + varPart = "" + idx + " = " + this.fromC; + if (this.toC !== this.toVar) { + varPart += ", " + this.toC; + } + if (this.step !== this.stepVar) { + varPart += ", " + this.step; + } + _ref2 = ["" + idx + " <" + this.equals, "" + idx + " >" + this.equals], lt = _ref2[0], gt = _ref2[1]; + condPart = this.stepNum ? +this.stepNum > 0 ? "" + lt + " " + this.toVar : "" + gt + " " + this.toVar : known ? ((_ref3 = [+this.fromNum, +this.toNum], from = _ref3[0], to = _ref3[1], _ref3), from <= to ? "" + lt + " " + to : "" + gt + " " + to) : (cond = "" + this.fromVar + " <= " + this.toVar, "" + cond + " ? " + lt + " " + this.toVar + " : " + gt + " " + this.toVar); + stepPart = this.stepVar ? "" + idx + " += " + this.stepVar : known ? namedIndex ? from <= to ? "++" + idx : "--" + idx : from <= to ? "" + idx + "++" : "" + idx + "--" : namedIndex ? "" + cond + " ? ++" + idx + " : --" + idx : "" + cond + " ? " + idx + "++ : " + idx + "--"; + if (namedIndex) { + varPart = "" + idxName + " = " + varPart; + } + if (namedIndex) { + stepPart = "" + idxName + " = " + stepPart; + } + return "" + varPart + "; " + condPart + "; " + stepPart; + }; + + Range.prototype.compileArray = function(o) { + var args, body, cond, hasArgs, i, idt, post, pre, range, result, vars, _i, _ref2, _ref3, _results; + if (this.fromNum && this.toNum && Math.abs(this.fromNum - this.toNum) <= 20) { + range = (function() { + _results = []; + for (var _i = _ref2 = +this.fromNum, _ref3 = +this.toNum; _ref2 <= _ref3 ? _i <= _ref3 : _i >= _ref3; _ref2 <= _ref3 ? _i++ : _i--){ _results.push(_i); } + return _results; + }).apply(this); + if (this.exclusive) { + range.pop(); + } + return "[" + (range.join(', ')) + "]"; + } + idt = this.tab + TAB; + i = o.scope.freeVariable('i'); + result = o.scope.freeVariable('results'); + pre = "\n" + idt + result + " = [];"; + if (this.fromNum && this.toNum) { + o.index = i; + body = this.compileNode(o); + } else { + vars = ("" + i + " = " + this.fromC) + (this.toC !== this.toVar ? ", " + this.toC : ''); + cond = "" + this.fromVar + " <= " + this.toVar; + body = "var " + vars + "; " + cond + " ? " + i + " <" + this.equals + " " + this.toVar + " : " + i + " >" + this.equals + " " + this.toVar + "; " + cond + " ? " + i + "++ : " + i + "--"; + } + post = "{ " + result + ".push(" + i + "); }\n" + idt + "return " + result + ";\n" + o.indent; + hasArgs = function(node) { + return node != null ? node.contains(function(n) { + return n instanceof Literal && n.value === 'arguments' && !n.asKey; + }) : void 0; + }; + if (hasArgs(this.from) || hasArgs(this.to)) { + args = ', arguments'; + } + return "(function() {" + pre + "\n" + idt + "for (" + body + ")" + post + "}).apply(this" + (args != null ? args : '') + ")"; + }; + + return Range; + + })(Base); + + exports.Slice = Slice = (function(_super) { + + __extends(Slice, _super); + + Slice.prototype.children = ['range']; + + function Slice(range) { + this.range = range; + Slice.__super__.constructor.call(this); + } + + Slice.prototype.compileNode = function(o) { + var compiled, from, fromStr, to, toStr, _ref2; + _ref2 = this.range, to = _ref2.to, from = _ref2.from; + fromStr = from && from.compile(o, LEVEL_PAREN) || '0'; + compiled = to && to.compile(o, LEVEL_PAREN); + if (to && !(!this.range.exclusive && +compiled === -1)) { + toStr = ', ' + (this.range.exclusive ? compiled : SIMPLENUM.test(compiled) ? "" + (+compiled + 1) : (compiled = to.compile(o, LEVEL_ACCESS), "" + compiled + " + 1 || 9e9")); + } + return ".slice(" + fromStr + (toStr || '') + ")"; + }; + + return Slice; + + })(Base); + + exports.Obj = Obj = (function(_super) { + + __extends(Obj, _super); + + function Obj(props, generated) { + this.generated = generated != null ? generated : false; + this.objects = this.properties = props || []; + } + + Obj.prototype.children = ['properties']; + + Obj.prototype.compileNode = function(o) { + var i, idt, indent, join, lastNoncom, node, obj, prop, propName, propNames, props, _i, _j, _len, _len1, _ref2; + props = this.properties; + propNames = []; + _ref2 = this.properties; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + prop = _ref2[_i]; + if (prop.isComplex()) { + prop = prop.variable; + } + if (prop != null) { + propName = prop.unwrapAll().value.toString(); + if (__indexOf.call(propNames, propName) >= 0) { + throw SyntaxError("multiple object literal properties named \"" + propName + "\""); + } + propNames.push(propName); + } + } + if (!props.length) { + return (this.front ? '({})' : '{}'); + } + if (this.generated) { + for (_j = 0, _len1 = props.length; _j < _len1; _j++) { + node = props[_j]; + if (node instanceof Value) { + throw new Error('cannot have an implicit value in an implicit object'); + } + } + } + idt = o.indent += TAB; + lastNoncom = this.lastNonComment(this.properties); + props = (function() { + var _k, _len2, _results; + _results = []; + for (i = _k = 0, _len2 = props.length; _k < _len2; i = ++_k) { + prop = props[i]; + join = i === props.length - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n'; + indent = prop instanceof Comment ? '' : idt; + if (prop instanceof Value && prop["this"]) { + prop = new Assign(prop.properties[0].name, prop, 'object'); + } + if (!(prop instanceof Comment)) { + if (!(prop instanceof Assign)) { + prop = new Assign(prop, prop, 'object'); + } + (prop.variable.base || prop.variable).asKey = true; + } + _results.push(indent + prop.compile(o, LEVEL_TOP) + join); + } + return _results; + })(); + props = props.join(''); + obj = "{" + (props && '\n' + props + '\n' + this.tab) + "}"; + if (this.front) { + return "(" + obj + ")"; + } else { + return obj; + } + }; + + Obj.prototype.assigns = function(name) { + var prop, _i, _len, _ref2; + _ref2 = this.properties; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + prop = _ref2[_i]; + if (prop.assigns(name)) { + return true; + } + } + return false; + }; + + return Obj; + + })(Base); + + exports.Arr = Arr = (function(_super) { + + __extends(Arr, _super); + + function Arr(objs) { + this.objects = objs || []; + } + + Arr.prototype.children = ['objects']; + + Arr.prototype.filterImplicitObjects = Call.prototype.filterImplicitObjects; + + Arr.prototype.compileNode = function(o) { + var code, obj, objs; + if (!this.objects.length) { + return '[]'; + } + o.indent += TAB; + objs = this.filterImplicitObjects(this.objects); + if (code = Splat.compileSplattedArray(o, objs)) { + return code; + } + code = ((function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = objs.length; _i < _len; _i++) { + obj = objs[_i]; + _results.push(obj.compile(o, LEVEL_LIST)); + } + return _results; + })()).join(', '); + if (code.indexOf('\n') >= 0) { + return "[\n" + o.indent + code + "\n" + this.tab + "]"; + } else { + return "[" + code + "]"; + } + }; + + Arr.prototype.assigns = function(name) { + var obj, _i, _len, _ref2; + _ref2 = this.objects; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + obj = _ref2[_i]; + if (obj.assigns(name)) { + return true; + } + } + return false; + }; + + return Arr; + + })(Base); + + exports.Class = Class = (function(_super) { + + __extends(Class, _super); + + function Class(variable, parent, body) { + this.variable = variable; + this.parent = parent; + this.body = body != null ? body : new Block; + this.boundFuncs = []; + this.body.classBody = true; + } + + Class.prototype.children = ['variable', 'parent', 'body']; + + Class.prototype.determineName = function() { + var decl, tail; + if (!this.variable) { + return null; + } + decl = (tail = last(this.variable.properties)) ? tail instanceof Access && tail.name.value : this.variable.base.value; + if (__indexOf.call(STRICT_PROSCRIBED, decl) >= 0) { + throw SyntaxError("variable name may not be " + decl); + } + return decl && (decl = IDENTIFIER.test(decl) && decl); + }; + + Class.prototype.setContext = function(name) { + return this.body.traverseChildren(false, function(node) { + if (node.classBody) { + return false; + } + if (node instanceof Literal && node.value === 'this') { + return node.value = name; + } else if (node instanceof Code) { + node.klass = name; + if (node.bound) { + return node.context = name; + } + } + }); + }; + + Class.prototype.addBoundFunctions = function(o) { + var bvar, lhs, _i, _len, _ref2, _results; + if (this.boundFuncs.length) { + _ref2 = this.boundFuncs; + _results = []; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + bvar = _ref2[_i]; + lhs = (new Value(new Literal("this"), [new Access(bvar)])).compile(o); + _results.push(this.ctor.body.unshift(new Literal("" + lhs + " = " + (utility('bind')) + "(" + lhs + ", this)"))); + } + return _results; + } + }; + + Class.prototype.addProperties = function(node, name, o) { + var assign, base, exprs, func, props; + props = node.base.properties.slice(0); + exprs = (function() { + var _results; + _results = []; + while (assign = props.shift()) { + if (assign instanceof Assign) { + base = assign.variable.base; + delete assign.context; + func = assign.value; + if (base.value === 'constructor') { + if (this.ctor) { + throw new Error('cannot define more than one constructor in a class'); + } + if (func.bound) { + throw new Error('cannot define a constructor as a bound function'); + } + if (func instanceof Code) { + assign = this.ctor = func; + } else { + this.externalCtor = o.scope.freeVariable('class'); + assign = new Assign(new Literal(this.externalCtor), func); + } + } else { + if (assign.variable["this"]) { + func["static"] = true; + if (func.bound) { + func.context = name; + } + } else { + assign.variable = new Value(new Literal(name), [new Access(new Literal('prototype')), new Access(base)]); + if (func instanceof Code && func.bound) { + this.boundFuncs.push(base); + func.bound = false; + } + } + } + } + _results.push(assign); + } + return _results; + }).call(this); + return compact(exprs); + }; + + Class.prototype.walkBody = function(name, o) { + var _this = this; + return this.traverseChildren(false, function(child) { + var exps, i, node, _i, _len, _ref2; + if (child instanceof Class) { + return false; + } + if (child instanceof Block) { + _ref2 = exps = child.expressions; + for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) { + node = _ref2[i]; + if (node instanceof Value && node.isObject(true)) { + exps[i] = _this.addProperties(node, name, o); + } + } + return child.expressions = exps = flatten(exps); + } + }); + }; + + Class.prototype.hoistDirectivePrologue = function() { + var expressions, index, node; + index = 0; + expressions = this.body.expressions; + while ((node = expressions[index]) && node instanceof Comment || node instanceof Value && node.isString()) { + ++index; + } + return this.directives = expressions.splice(0, index); + }; + + Class.prototype.ensureConstructor = function(name) { + if (!this.ctor) { + this.ctor = new Code; + if (this.parent) { + this.ctor.body.push(new Literal("" + name + ".__super__.constructor.apply(this, arguments)")); + } + if (this.externalCtor) { + this.ctor.body.push(new Literal("" + this.externalCtor + ".apply(this, arguments)")); + } + this.ctor.body.makeReturn(); + this.body.expressions.unshift(this.ctor); + } + this.ctor.ctor = this.ctor.name = name; + this.ctor.klass = null; + return this.ctor.noReturn = true; + }; + + Class.prototype.compileNode = function(o) { + var call, decl, klass, lname, name, params, _ref2; + decl = this.determineName(); + name = decl || '_Class'; + if (name.reserved) { + name = "_" + name; + } + lname = new Literal(name); + this.hoistDirectivePrologue(); + this.setContext(name); + this.walkBody(name, o); + this.ensureConstructor(name); + this.body.spaced = true; + if (!(this.ctor instanceof Code)) { + this.body.expressions.unshift(this.ctor); + } + this.body.expressions.push(lname); + (_ref2 = this.body.expressions).unshift.apply(_ref2, this.directives); + this.addBoundFunctions(o); + call = Closure.wrap(this.body); + if (this.parent) { + this.superClass = new Literal(o.scope.freeVariable('super', false)); + this.body.expressions.unshift(new Extends(lname, this.superClass)); + call.args.push(this.parent); + params = call.variable.params || call.variable.base.params; + params.push(new Param(this.superClass)); + } + klass = new Parens(call, true); + if (this.variable) { + klass = new Assign(this.variable, klass); + } + return klass.compile(o); + }; + + return Class; + + })(Base); + + exports.Assign = Assign = (function(_super) { + + __extends(Assign, _super); + + function Assign(variable, value, context, options) { + var forbidden, name, _ref2; + this.variable = variable; + this.value = value; + this.context = context; + this.param = options && options.param; + this.subpattern = options && options.subpattern; + forbidden = (_ref2 = (name = this.variable.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0); + if (forbidden && this.context !== 'object') { + throw SyntaxError("variable name may not be \"" + name + "\""); + } + } + + Assign.prototype.children = ['variable', 'value']; + + Assign.prototype.isStatement = function(o) { + return (o != null ? o.level : void 0) === LEVEL_TOP && (this.context != null) && __indexOf.call(this.context, "?") >= 0; + }; + + Assign.prototype.assigns = function(name) { + return this[this.context === 'object' ? 'value' : 'variable'].assigns(name); + }; + + Assign.prototype.unfoldSoak = function(o) { + return unfoldSoak(o, this, 'variable'); + }; + + Assign.prototype.compileNode = function(o) { + var isValue, match, name, val, varBase, _ref2, _ref3, _ref4, _ref5; + if (isValue = this.variable instanceof Value) { + if (this.variable.isArray() || this.variable.isObject()) { + return this.compilePatternMatch(o); + } + if (this.variable.isSplice()) { + return this.compileSplice(o); + } + if ((_ref2 = this.context) === '||=' || _ref2 === '&&=' || _ref2 === '?=') { + return this.compileConditional(o); + } + } + name = this.variable.compile(o, LEVEL_LIST); + if (!this.context) { + if (!(varBase = this.variable.unwrapAll()).isAssignable()) { + throw SyntaxError("\"" + (this.variable.compile(o)) + "\" cannot be assigned."); + } + if (!(typeof varBase.hasProperties === "function" ? varBase.hasProperties() : void 0)) { + if (this.param) { + o.scope.add(name, 'var'); + } else { + o.scope.find(name); + } + } + } + if (this.value instanceof Code && (match = METHOD_DEF.exec(name))) { + if (match[1]) { + this.value.klass = match[1]; + } + this.value.name = (_ref3 = (_ref4 = (_ref5 = match[2]) != null ? _ref5 : match[3]) != null ? _ref4 : match[4]) != null ? _ref3 : match[5]; + } + val = this.value.compile(o, LEVEL_LIST); + if (this.context === 'object') { + return "" + name + ": " + val; + } + val = name + (" " + (this.context || '=') + " ") + val; + if (o.level <= LEVEL_LIST) { + return val; + } else { + return "(" + val + ")"; + } + }; + + Assign.prototype.compilePatternMatch = function(o) { + var acc, assigns, code, i, idx, isObject, ivar, name, obj, objects, olen, ref, rest, splat, top, val, value, vvar, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8; + top = o.level === LEVEL_TOP; + value = this.value; + objects = this.variable.base.objects; + if (!(olen = objects.length)) { + code = value.compile(o); + if (o.level >= LEVEL_OP) { + return "(" + code + ")"; + } else { + return code; + } + } + isObject = this.variable.isObject(); + if (top && olen === 1 && !((obj = objects[0]) instanceof Splat)) { + if (obj instanceof Assign) { + _ref2 = obj, (_ref3 = _ref2.variable, idx = _ref3.base), obj = _ref2.value; + } else { + if (obj.base instanceof Parens) { + _ref4 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref4[0], idx = _ref4[1]; + } else { + idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0); + } + } + acc = IDENTIFIER.test(idx.unwrap().value || 0); + value = new Value(value); + value.properties.push(new (acc ? Access : Index)(idx)); + if (_ref5 = obj.unwrap().value, __indexOf.call(RESERVED, _ref5) >= 0) { + throw new SyntaxError("assignment to a reserved word: " + (obj.compile(o)) + " = " + (value.compile(o))); + } + return new Assign(obj, value, null, { + param: this.param + }).compile(o, LEVEL_TOP); + } + vvar = value.compile(o, LEVEL_LIST); + assigns = []; + splat = false; + if (!IDENTIFIER.test(vvar) || this.variable.assigns(vvar)) { + assigns.push("" + (ref = o.scope.freeVariable('ref')) + " = " + vvar); + vvar = ref; + } + for (i = _i = 0, _len = objects.length; _i < _len; i = ++_i) { + obj = objects[i]; + idx = i; + if (isObject) { + if (obj instanceof Assign) { + _ref6 = obj, (_ref7 = _ref6.variable, idx = _ref7.base), obj = _ref6.value; + } else { + if (obj.base instanceof Parens) { + _ref8 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref8[0], idx = _ref8[1]; + } else { + idx = obj["this"] ? obj.properties[0].name : obj; + } + } + } + if (!splat && obj instanceof Splat) { + name = obj.name.unwrap().value; + obj = obj.unwrap(); + val = "" + olen + " <= " + vvar + ".length ? " + (utility('slice')) + ".call(" + vvar + ", " + i; + if (rest = olen - i - 1) { + ivar = o.scope.freeVariable('i'); + val += ", " + ivar + " = " + vvar + ".length - " + rest + ") : (" + ivar + " = " + i + ", [])"; + } else { + val += ") : []"; + } + val = new Literal(val); + splat = "" + ivar + "++"; + } else { + name = obj.unwrap().value; + if (obj instanceof Splat) { + obj = obj.name.compile(o); + throw new SyntaxError("multiple splats are disallowed in an assignment: " + obj + "..."); + } + if (typeof idx === 'number') { + idx = new Literal(splat || idx); + acc = false; + } else { + acc = isObject && IDENTIFIER.test(idx.unwrap().value || 0); + } + val = new Value(new Literal(vvar), [new (acc ? Access : Index)(idx)]); + } + if ((name != null) && __indexOf.call(RESERVED, name) >= 0) { + throw new SyntaxError("assignment to a reserved word: " + (obj.compile(o)) + " = " + (val.compile(o))); + } + assigns.push(new Assign(obj, val, null, { + param: this.param, + subpattern: true + }).compile(o, LEVEL_LIST)); + } + if (!(top || this.subpattern)) { + assigns.push(vvar); + } + code = assigns.join(', '); + if (o.level < LEVEL_LIST) { + return code; + } else { + return "(" + code + ")"; + } + }; + + Assign.prototype.compileConditional = function(o) { + var left, right, _ref2; + _ref2 = this.variable.cacheReference(o), left = _ref2[0], right = _ref2[1]; + if (!left.properties.length && left.base instanceof Literal && left.base.value !== "this" && !o.scope.check(left.base.value)) { + throw new Error("the variable \"" + left.base.value + "\" can't be assigned with " + this.context + " because it has not been defined."); + } + if (__indexOf.call(this.context, "?") >= 0) { + o.isExistentialEquals = true; + } + return new Op(this.context.slice(0, -1), left, new Assign(right, this.value, '=')).compile(o); + }; + + Assign.prototype.compileSplice = function(o) { + var code, exclusive, from, fromDecl, fromRef, name, to, valDef, valRef, _ref2, _ref3, _ref4; + _ref2 = this.variable.properties.pop().range, from = _ref2.from, to = _ref2.to, exclusive = _ref2.exclusive; + name = this.variable.compile(o); + _ref3 = (from != null ? from.cache(o, LEVEL_OP) : void 0) || ['0', '0'], fromDecl = _ref3[0], fromRef = _ref3[1]; + if (to) { + if ((from != null ? from.isSimpleNumber() : void 0) && to.isSimpleNumber()) { + to = +to.compile(o) - +fromRef; + if (!exclusive) { + to += 1; + } + } else { + to = to.compile(o, LEVEL_ACCESS) + ' - ' + fromRef; + if (!exclusive) { + to += ' + 1'; + } + } + } else { + to = "9e9"; + } + _ref4 = this.value.cache(o, LEVEL_LIST), valDef = _ref4[0], valRef = _ref4[1]; + code = "[].splice.apply(" + name + ", [" + fromDecl + ", " + to + "].concat(" + valDef + ")), " + valRef; + if (o.level > LEVEL_TOP) { + return "(" + code + ")"; + } else { + return code; + } + }; + + return Assign; + + })(Base); + + exports.Code = Code = (function(_super) { + + __extends(Code, _super); + + function Code(params, body, tag) { + this.params = params || []; + this.body = body || new Block; + this.bound = tag === 'boundfunc'; + if (this.bound) { + this.context = '_this'; + } + } + + Code.prototype.children = ['params', 'body']; + + Code.prototype.isStatement = function() { + return !!this.ctor; + }; + + Code.prototype.jumps = NO; + + Code.prototype.compileNode = function(o) { + var code, exprs, i, idt, lit, name, p, param, params, ref, splats, uniqs, val, wasEmpty, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _m, _n, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8; + o.scope = new Scope(o.scope, this.body, this); + o.scope.shared = del(o, 'sharedScope'); + o.indent += TAB; + delete o.bare; + delete o.isExistentialEquals; + params = []; + exprs = []; + _ref2 = this.paramNames(); + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + name = _ref2[_i]; + if (!o.scope.check(name)) { + o.scope.parameter(name); + } + } + _ref3 = this.params; + for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { + param = _ref3[_j]; + if (!param.splat) { + continue; + } + _ref4 = this.params; + for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) { + p = _ref4[_k].name; + if (p["this"]) { + p = p.properties[0].name; + } + if (p.value) { + o.scope.add(p.value, 'var', true); + } + } + splats = new Assign(new Value(new Arr((function() { + var _l, _len3, _ref5, _results; + _ref5 = this.params; + _results = []; + for (_l = 0, _len3 = _ref5.length; _l < _len3; _l++) { + p = _ref5[_l]; + _results.push(p.asReference(o)); + } + return _results; + }).call(this))), new Value(new Literal('arguments'))); + break; + } + _ref5 = this.params; + for (_l = 0, _len3 = _ref5.length; _l < _len3; _l++) { + param = _ref5[_l]; + if (param.isComplex()) { + val = ref = param.asReference(o); + if (param.value) { + val = new Op('?', ref, param.value); + } + exprs.push(new Assign(new Value(param.name), val, '=', { + param: true + })); + } else { + ref = param; + if (param.value) { + lit = new Literal(ref.name.value + ' == null'); + val = new Assign(new Value(param.name), param.value, '='); + exprs.push(new If(lit, val)); + } + } + if (!splats) { + params.push(ref); + } + } + wasEmpty = this.body.isEmpty(); + if (splats) { + exprs.unshift(splats); + } + if (exprs.length) { + (_ref6 = this.body.expressions).unshift.apply(_ref6, exprs); + } + for (i = _m = 0, _len4 = params.length; _m < _len4; i = ++_m) { + p = params[i]; + o.scope.parameter(params[i] = p.compile(o)); + } + uniqs = []; + _ref7 = this.paramNames(); + for (_n = 0, _len5 = _ref7.length; _n < _len5; _n++) { + name = _ref7[_n]; + if (__indexOf.call(uniqs, name) >= 0) { + throw SyntaxError("multiple parameters named '" + name + "'"); + } + uniqs.push(name); + } + if (!(wasEmpty || this.noReturn)) { + this.body.makeReturn(); + } + if (this.bound) { + if ((_ref8 = o.scope.parent.method) != null ? _ref8.bound : void 0) { + this.bound = this.context = o.scope.parent.method.context; + } else if (!this["static"]) { + o.scope.parent.assign('_this', 'this'); + } + } + idt = o.indent; + code = 'function'; + if (this.ctor) { + code += ' ' + this.name; + } + code += '(' + params.join(', ') + ') {'; + if (!this.body.isEmpty()) { + code += "\n" + (this.body.compileWithDeclarations(o)) + "\n" + this.tab; + } + code += '}'; + if (this.ctor) { + return this.tab + code; + } + if (this.front || (o.level >= LEVEL_ACCESS)) { + return "(" + code + ")"; + } else { + return code; + } + }; + + Code.prototype.paramNames = function() { + var names, param, _i, _len, _ref2; + names = []; + _ref2 = this.params; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + param = _ref2[_i]; + names.push.apply(names, param.names()); + } + return names; + }; + + Code.prototype.traverseChildren = function(crossScope, func) { + if (crossScope) { + return Code.__super__.traverseChildren.call(this, crossScope, func); + } + }; + + return Code; + + })(Base); + + exports.Param = Param = (function(_super) { + + __extends(Param, _super); + + function Param(name, value, splat) { + var _ref2; + this.name = name; + this.value = value; + this.splat = splat; + if (_ref2 = (name = this.name.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0) { + throw SyntaxError("parameter name \"" + name + "\" is not allowed"); + } + } + + Param.prototype.children = ['name', 'value']; + + Param.prototype.compile = function(o) { + return this.name.compile(o, LEVEL_LIST); + }; + + Param.prototype.asReference = function(o) { + var node; + if (this.reference) { + return this.reference; + } + node = this.name; + if (node["this"]) { + node = node.properties[0].name; + if (node.value.reserved) { + node = new Literal(o.scope.freeVariable(node.value)); + } + } else if (node.isComplex()) { + node = new Literal(o.scope.freeVariable('arg')); + } + node = new Value(node); + if (this.splat) { + node = new Splat(node); + } + return this.reference = node; + }; + + Param.prototype.isComplex = function() { + return this.name.isComplex(); + }; + + Param.prototype.names = function(name) { + var atParam, names, obj, _i, _len, _ref2; + if (name == null) { + name = this.name; + } + atParam = function(obj) { + var value; + value = obj.properties[0].name.value; + if (value.reserved) { + return []; + } else { + return [value]; + } + }; + if (name instanceof Literal) { + return [name.value]; + } + if (name instanceof Value) { + return atParam(name); + } + names = []; + _ref2 = name.objects; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + obj = _ref2[_i]; + if (obj instanceof Assign) { + names.push(obj.value.unwrap().value); + } else if (obj instanceof Splat) { + names.push(obj.name.unwrap().value); + } else if (obj instanceof Value) { + if (obj.isArray() || obj.isObject()) { + names.push.apply(names, this.names(obj.base)); + } else if (obj["this"]) { + names.push.apply(names, atParam(obj)); + } else { + names.push(obj.base.value); + } + } else { + throw SyntaxError("illegal parameter " + (obj.compile())); + } + } + return names; + }; + + return Param; + + })(Base); + + exports.Splat = Splat = (function(_super) { + + __extends(Splat, _super); + + Splat.prototype.children = ['name']; + + Splat.prototype.isAssignable = YES; + + function Splat(name) { + this.name = name.compile ? name : new Literal(name); + } + + Splat.prototype.assigns = function(name) { + return this.name.assigns(name); + }; + + Splat.prototype.compile = function(o) { + if (this.index != null) { + return this.compileParam(o); + } else { + return this.name.compile(o); + } + }; + + Splat.prototype.unwrap = function() { + return this.name; + }; + + Splat.compileSplattedArray = function(o, list, apply) { + var args, base, code, i, index, node, _i, _len; + index = -1; + while ((node = list[++index]) && !(node instanceof Splat)) { + continue; + } + if (index >= list.length) { + return ''; + } + if (list.length === 1) { + code = list[0].compile(o, LEVEL_LIST); + if (apply) { + return code; + } + return "" + (utility('slice')) + ".call(" + code + ")"; + } + args = list.slice(index); + for (i = _i = 0, _len = args.length; _i < _len; i = ++_i) { + node = args[i]; + code = node.compile(o, LEVEL_LIST); + args[i] = node instanceof Splat ? "" + (utility('slice')) + ".call(" + code + ")" : "[" + code + "]"; + } + if (index === 0) { + return args[0] + (".concat(" + (args.slice(1).join(', ')) + ")"); + } + base = (function() { + var _j, _len1, _ref2, _results; + _ref2 = list.slice(0, index); + _results = []; + for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { + node = _ref2[_j]; + _results.push(node.compile(o, LEVEL_LIST)); + } + return _results; + })(); + return "[" + (base.join(', ')) + "].concat(" + (args.join(', ')) + ")"; + }; + + return Splat; + + })(Base); + + exports.While = While = (function(_super) { + + __extends(While, _super); + + function While(condition, options) { + this.condition = (options != null ? options.invert : void 0) ? condition.invert() : condition; + this.guard = options != null ? options.guard : void 0; + } + + While.prototype.children = ['condition', 'guard', 'body']; + + While.prototype.isStatement = YES; + + While.prototype.makeReturn = function(res) { + if (res) { + return While.__super__.makeReturn.apply(this, arguments); + } else { + this.returns = !this.jumps({ + loop: true + }); + return this; + } + }; + + While.prototype.addBody = function(body) { + this.body = body; + return this; + }; + + While.prototype.jumps = function() { + var expressions, node, _i, _len; + expressions = this.body.expressions; + if (!expressions.length) { + return false; + } + for (_i = 0, _len = expressions.length; _i < _len; _i++) { + node = expressions[_i]; + if (node.jumps({ + loop: true + })) { + return node; + } + } + return false; + }; + + While.prototype.compileNode = function(o) { + var body, code, rvar, set; + o.indent += TAB; + set = ''; + body = this.body; + if (body.isEmpty()) { + body = ''; + } else { + if (this.returns) { + body.makeReturn(rvar = o.scope.freeVariable('results')); + set = "" + this.tab + rvar + " = [];\n"; + } + if (this.guard) { + if (body.expressions.length > 1) { + body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue"))); + } else { + if (this.guard) { + body = Block.wrap([new If(this.guard, body)]); + } + } + } + body = "\n" + (body.compile(o, LEVEL_TOP)) + "\n" + this.tab; + } + code = set + this.tab + ("while (" + (this.condition.compile(o, LEVEL_PAREN)) + ") {" + body + "}"); + if (this.returns) { + code += "\n" + this.tab + "return " + rvar + ";"; + } + return code; + }; + + return While; + + })(Base); + + exports.Op = Op = (function(_super) { + var CONVERSIONS, INVERSIONS; + + __extends(Op, _super); + + function Op(op, first, second, flip) { + if (op === 'in') { + return new In(first, second); + } + if (op === 'do') { + return this.generateDo(first); + } + if (op === 'new') { + if (first instanceof Call && !first["do"] && !first.isNew) { + return first.newInstance(); + } + if (first instanceof Code && first.bound || first["do"]) { + first = new Parens(first); + } + } + this.operator = CONVERSIONS[op] || op; + this.first = first; + this.second = second; + this.flip = !!flip; + return this; + } + + CONVERSIONS = { + '==': '===', + '!=': '!==', + 'of': 'in' + }; + + INVERSIONS = { + '!==': '===', + '===': '!==' + }; + + Op.prototype.children = ['first', 'second']; + + Op.prototype.isSimpleNumber = NO; + + Op.prototype.isUnary = function() { + return !this.second; + }; + + Op.prototype.isComplex = function() { + var _ref2; + return !(this.isUnary() && ((_ref2 = this.operator) === '+' || _ref2 === '-')) || this.first.isComplex(); + }; + + Op.prototype.isChainable = function() { + var _ref2; + return (_ref2 = this.operator) === '<' || _ref2 === '>' || _ref2 === '>=' || _ref2 === '<=' || _ref2 === '===' || _ref2 === '!=='; + }; + + Op.prototype.invert = function() { + var allInvertable, curr, fst, op, _ref2; + if (this.isChainable() && this.first.isChainable()) { + allInvertable = true; + curr = this; + while (curr && curr.operator) { + allInvertable && (allInvertable = curr.operator in INVERSIONS); + curr = curr.first; + } + if (!allInvertable) { + return new Parens(this).invert(); + } + curr = this; + while (curr && curr.operator) { + curr.invert = !curr.invert; + curr.operator = INVERSIONS[curr.operator]; + curr = curr.first; + } + return this; + } else if (op = INVERSIONS[this.operator]) { + this.operator = op; + if (this.first.unwrap() instanceof Op) { + this.first.invert(); + } + return this; + } else if (this.second) { + return new Parens(this).invert(); + } else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((_ref2 = fst.operator) === '!' || _ref2 === 'in' || _ref2 === 'instanceof')) { + return fst; + } else { + return new Op('!', this); + } + }; + + Op.prototype.unfoldSoak = function(o) { + var _ref2; + return ((_ref2 = this.operator) === '++' || _ref2 === '--' || _ref2 === 'delete') && unfoldSoak(o, this, 'first'); + }; + + Op.prototype.generateDo = function(exp) { + var call, func, param, passedParams, ref, _i, _len, _ref2; + passedParams = []; + func = exp instanceof Assign && (ref = exp.value.unwrap()) instanceof Code ? ref : exp; + _ref2 = func.params || []; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + param = _ref2[_i]; + if (param.value) { + passedParams.push(param.value); + delete param.value; + } else { + passedParams.push(param); + } + } + call = new Call(exp, passedParams); + call["do"] = true; + return call; + }; + + Op.prototype.compileNode = function(o) { + var code, isChain, _ref2, _ref3; + isChain = this.isChainable() && this.first.isChainable(); + if (!isChain) { + this.first.front = this.front; + } + if (this.operator === 'delete' && o.scope.check(this.first.unwrapAll().value)) { + throw SyntaxError('delete operand may not be argument or var'); + } + if (((_ref2 = this.operator) === '--' || _ref2 === '++') && (_ref3 = this.first.unwrapAll().value, __indexOf.call(STRICT_PROSCRIBED, _ref3) >= 0)) { + throw SyntaxError('prefix increment/decrement may not have eval or arguments operand'); + } + if (this.isUnary()) { + return this.compileUnary(o); + } + if (isChain) { + return this.compileChain(o); + } + if (this.operator === '?') { + return this.compileExistence(o); + } + code = this.first.compile(o, LEVEL_OP) + ' ' + this.operator + ' ' + this.second.compile(o, LEVEL_OP); + if (o.level <= LEVEL_OP) { + return code; + } else { + return "(" + code + ")"; + } + }; + + Op.prototype.compileChain = function(o) { + var code, fst, shared, _ref2; + _ref2 = this.first.second.cache(o), this.first.second = _ref2[0], shared = _ref2[1]; + fst = this.first.compile(o, LEVEL_OP); + code = "" + fst + " " + (this.invert ? '&&' : '||') + " " + (shared.compile(o)) + " " + this.operator + " " + (this.second.compile(o, LEVEL_OP)); + return "(" + code + ")"; + }; + + Op.prototype.compileExistence = function(o) { + var fst, ref; + if (this.first.isComplex()) { + ref = new Literal(o.scope.freeVariable('ref')); + fst = new Parens(new Assign(ref, this.first)); + } else { + fst = this.first; + ref = fst; + } + return new If(new Existence(fst), ref, { + type: 'if' + }).addElse(this.second).compile(o); + }; + + Op.prototype.compileUnary = function(o) { + var op, parts, plusMinus; + if (o.level >= LEVEL_ACCESS) { + return (new Parens(this)).compile(o); + } + parts = [op = this.operator]; + plusMinus = op === '+' || op === '-'; + if ((op === 'new' || op === 'typeof' || op === 'delete') || plusMinus && this.first instanceof Op && this.first.operator === op) { + parts.push(' '); + } + if ((plusMinus && this.first instanceof Op) || (op === 'new' && this.first.isStatement(o))) { + this.first = new Parens(this.first); + } + parts.push(this.first.compile(o, LEVEL_OP)); + if (this.flip) { + parts.reverse(); + } + return parts.join(''); + }; + + Op.prototype.toString = function(idt) { + return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator); + }; + + return Op; + + })(Base); + + exports.In = In = (function(_super) { + + __extends(In, _super); + + function In(object, array) { + this.object = object; + this.array = array; + } + + In.prototype.children = ['object', 'array']; + + In.prototype.invert = NEGATE; + + In.prototype.compileNode = function(o) { + var hasSplat, obj, _i, _len, _ref2; + if (this.array instanceof Value && this.array.isArray()) { + _ref2 = this.array.base.objects; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + obj = _ref2[_i]; + if (!(obj instanceof Splat)) { + continue; + } + hasSplat = true; + break; + } + if (!hasSplat) { + return this.compileOrTest(o); + } + } + return this.compileLoopTest(o); + }; + + In.prototype.compileOrTest = function(o) { + var cmp, cnj, i, item, ref, sub, tests, _ref2, _ref3; + if (this.array.base.objects.length === 0) { + return "" + (!!this.negated); + } + _ref2 = this.object.cache(o, LEVEL_OP), sub = _ref2[0], ref = _ref2[1]; + _ref3 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = _ref3[0], cnj = _ref3[1]; + tests = (function() { + var _i, _len, _ref4, _results; + _ref4 = this.array.base.objects; + _results = []; + for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) { + item = _ref4[i]; + _results.push((i ? ref : sub) + cmp + item.compile(o, LEVEL_ACCESS)); + } + return _results; + }).call(this); + tests = tests.join(cnj); + if (o.level < LEVEL_OP) { + return tests; + } else { + return "(" + tests + ")"; + } + }; + + In.prototype.compileLoopTest = function(o) { + var code, ref, sub, _ref2; + _ref2 = this.object.cache(o, LEVEL_LIST), sub = _ref2[0], ref = _ref2[1]; + code = utility('indexOf') + (".call(" + (this.array.compile(o, LEVEL_LIST)) + ", " + ref + ") ") + (this.negated ? '< 0' : '>= 0'); + if (sub === ref) { + return code; + } + code = sub + ', ' + code; + if (o.level < LEVEL_LIST) { + return code; + } else { + return "(" + code + ")"; + } + }; + + In.prototype.toString = function(idt) { + return In.__super__.toString.call(this, idt, this.constructor.name + (this.negated ? '!' : '')); + }; + + return In; + + })(Base); + + exports.Try = Try = (function(_super) { + + __extends(Try, _super); + + function Try(attempt, error, recovery, ensure) { + this.attempt = attempt; + this.error = error; + this.recovery = recovery; + this.ensure = ensure; + } + + Try.prototype.children = ['attempt', 'recovery', 'ensure']; + + Try.prototype.isStatement = YES; + + Try.prototype.jumps = function(o) { + var _ref2; + return this.attempt.jumps(o) || ((_ref2 = this.recovery) != null ? _ref2.jumps(o) : void 0); + }; + + Try.prototype.makeReturn = function(res) { + if (this.attempt) { + this.attempt = this.attempt.makeReturn(res); + } + if (this.recovery) { + this.recovery = this.recovery.makeReturn(res); + } + return this; + }; + + Try.prototype.compileNode = function(o) { + var catchPart, ensurePart, errorPart, tryPart; + o.indent += TAB; + errorPart = this.error ? " (" + (this.error.compile(o)) + ") " : ' '; + tryPart = this.attempt.compile(o, LEVEL_TOP); + catchPart = (function() { + var _ref2; + if (this.recovery) { + if (_ref2 = this.error.value, __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0) { + throw SyntaxError("catch variable may not be \"" + this.error.value + "\""); + } + if (!o.scope.check(this.error.value)) { + o.scope.add(this.error.value, 'param'); + } + return " catch" + errorPart + "{\n" + (this.recovery.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}"; + } else if (!(this.ensure || this.recovery)) { + return ' catch (_error) {}'; + } + }).call(this); + ensurePart = this.ensure ? " finally {\n" + (this.ensure.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}" : ''; + return "" + this.tab + "try {\n" + tryPart + "\n" + this.tab + "}" + (catchPart || '') + ensurePart; + }; + + return Try; + + })(Base); + + exports.Throw = Throw = (function(_super) { + + __extends(Throw, _super); + + function Throw(expression) { + this.expression = expression; + } + + Throw.prototype.children = ['expression']; + + Throw.prototype.isStatement = YES; + + Throw.prototype.jumps = NO; + + Throw.prototype.makeReturn = THIS; + + Throw.prototype.compileNode = function(o) { + return this.tab + ("throw " + (this.expression.compile(o)) + ";"); + }; + + return Throw; + + })(Base); + + exports.Existence = Existence = (function(_super) { + + __extends(Existence, _super); + + function Existence(expression) { + this.expression = expression; + } + + Existence.prototype.children = ['expression']; + + Existence.prototype.invert = NEGATE; + + Existence.prototype.compileNode = function(o) { + var cmp, cnj, code, _ref2; + this.expression.front = this.front; + code = this.expression.compile(o, LEVEL_OP); + if (IDENTIFIER.test(code) && !o.scope.check(code)) { + _ref2 = this.negated ? ['===', '||'] : ['!==', '&&'], cmp = _ref2[0], cnj = _ref2[1]; + code = "typeof " + code + " " + cmp + " \"undefined\" " + cnj + " " + code + " " + cmp + " null"; + } else { + code = "" + code + " " + (this.negated ? '==' : '!=') + " null"; + } + if (o.level <= LEVEL_COND) { + return code; + } else { + return "(" + code + ")"; + } + }; + + return Existence; + + })(Base); + + exports.Parens = Parens = (function(_super) { + + __extends(Parens, _super); + + function Parens(body) { + this.body = body; + } + + Parens.prototype.children = ['body']; + + Parens.prototype.unwrap = function() { + return this.body; + }; + + Parens.prototype.isComplex = function() { + return this.body.isComplex(); + }; + + Parens.prototype.compileNode = function(o) { + var bare, code, expr; + expr = this.body.unwrap(); + if (expr instanceof Value && expr.isAtomic()) { + expr.front = this.front; + return expr.compile(o); + } + code = expr.compile(o, LEVEL_PAREN); + bare = o.level < LEVEL_OP && (expr instanceof Op || expr instanceof Call || (expr instanceof For && expr.returns)); + if (bare) { + return code; + } else { + return "(" + code + ")"; + } + }; + + return Parens; + + })(Base); + + exports.For = For = (function(_super) { + + __extends(For, _super); + + function For(body, source) { + var _ref2; + this.source = source.source, this.guard = source.guard, this.step = source.step, this.name = source.name, this.index = source.index; + this.body = Block.wrap([body]); + this.own = !!source.own; + this.object = !!source.object; + if (this.object) { + _ref2 = [this.index, this.name], this.name = _ref2[0], this.index = _ref2[1]; + } + if (this.index instanceof Value) { + throw SyntaxError('index cannot be a pattern matching expression'); + } + this.range = this.source instanceof Value && this.source.base instanceof Range && !this.source.properties.length; + this.pattern = this.name instanceof Value; + if (this.range && this.index) { + throw SyntaxError('indexes do not apply to range loops'); + } + if (this.range && this.pattern) { + throw SyntaxError('cannot pattern match over range loops'); + } + this.returns = false; + } + + For.prototype.children = ['body', 'source', 'guard', 'step']; + + For.prototype.compileNode = function(o) { + var body, defPart, forPart, forVarPart, guardPart, idt1, index, ivar, kvar, kvarAssign, lastJumps, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, stepPart, stepvar, svar, varPart, _ref2; + body = Block.wrap([this.body]); + lastJumps = (_ref2 = last(body.expressions)) != null ? _ref2.jumps() : void 0; + if (lastJumps && lastJumps instanceof Return) { + this.returns = false; + } + source = this.range ? this.source.base : this.source; + scope = o.scope; + name = this.name && this.name.compile(o, LEVEL_LIST); + index = this.index && this.index.compile(o, LEVEL_LIST); + if (name && !this.pattern) { + scope.find(name); + } + if (index) { + scope.find(index); + } + if (this.returns) { + rvar = scope.freeVariable('results'); + } + ivar = (this.object && index) || scope.freeVariable('i'); + kvar = (this.range && name) || index || ivar; + kvarAssign = kvar !== ivar ? "" + kvar + " = " : ""; + if (this.step && !this.range) { + stepvar = scope.freeVariable("step"); + } + if (this.pattern) { + name = ivar; + } + varPart = ''; + guardPart = ''; + defPart = ''; + idt1 = this.tab + TAB; + if (this.range) { + forPart = source.compile(merge(o, { + index: ivar, + name: name, + step: this.step + })); + } else { + svar = this.source.compile(o, LEVEL_LIST); + if ((name || this.own) && !IDENTIFIER.test(svar)) { + defPart = "" + this.tab + (ref = scope.freeVariable('ref')) + " = " + svar + ";\n"; + svar = ref; + } + if (name && !this.pattern) { + namePart = "" + name + " = " + svar + "[" + kvar + "]"; + } + if (!this.object) { + lvar = scope.freeVariable('len'); + forVarPart = "" + kvarAssign + ivar + " = 0, " + lvar + " = " + svar + ".length"; + if (this.step) { + forVarPart += ", " + stepvar + " = " + (this.step.compile(o, LEVEL_OP)); + } + stepPart = "" + kvarAssign + (this.step ? "" + ivar + " += " + stepvar : (kvar !== ivar ? "++" + ivar : "" + ivar + "++")); + forPart = "" + forVarPart + "; " + ivar + " < " + lvar + "; " + stepPart; + } + } + if (this.returns) { + resultPart = "" + this.tab + rvar + " = [];\n"; + returnResult = "\n" + this.tab + "return " + rvar + ";"; + body.makeReturn(rvar); + } + if (this.guard) { + if (body.expressions.length > 1) { + body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue"))); + } else { + if (this.guard) { + body = Block.wrap([new If(this.guard, body)]); + } + } + } + if (this.pattern) { + body.expressions.unshift(new Assign(this.name, new Literal("" + svar + "[" + kvar + "]"))); + } + defPart += this.pluckDirectCall(o, body); + if (namePart) { + varPart = "\n" + idt1 + namePart + ";"; + } + if (this.object) { + forPart = "" + kvar + " in " + svar; + if (this.own) { + guardPart = "\n" + idt1 + "if (!" + (utility('hasProp')) + ".call(" + svar + ", " + kvar + ")) continue;"; + } + } + body = body.compile(merge(o, { + indent: idt1 + }), LEVEL_TOP); + if (body) { + body = '\n' + body + '\n'; + } + return "" + defPart + (resultPart || '') + this.tab + "for (" + forPart + ") {" + guardPart + varPart + body + this.tab + "}" + (returnResult || ''); + }; + + For.prototype.pluckDirectCall = function(o, body) { + var base, defs, expr, fn, idx, ref, val, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7; + defs = ''; + _ref2 = body.expressions; + for (idx = _i = 0, _len = _ref2.length; _i < _len; idx = ++_i) { + expr = _ref2[idx]; + expr = expr.unwrapAll(); + if (!(expr instanceof Call)) { + continue; + } + val = expr.variable.unwrapAll(); + if (!((val instanceof Code) || (val instanceof Value && ((_ref3 = val.base) != null ? _ref3.unwrapAll() : void 0) instanceof Code && val.properties.length === 1 && ((_ref4 = (_ref5 = val.properties[0].name) != null ? _ref5.value : void 0) === 'call' || _ref4 === 'apply')))) { + continue; + } + fn = ((_ref6 = val.base) != null ? _ref6.unwrapAll() : void 0) || val; + ref = new Literal(o.scope.freeVariable('fn')); + base = new Value(ref); + if (val.base) { + _ref7 = [base, val], val.base = _ref7[0], base = _ref7[1]; + } + body.expressions[idx] = new Call(base, expr.args); + defs += this.tab + new Assign(ref, fn).compile(o, LEVEL_TOP) + ';\n'; + } + return defs; + }; + + return For; + + })(While); + + exports.Switch = Switch = (function(_super) { + + __extends(Switch, _super); + + function Switch(subject, cases, otherwise) { + this.subject = subject; + this.cases = cases; + this.otherwise = otherwise; + } + + Switch.prototype.children = ['subject', 'cases', 'otherwise']; + + Switch.prototype.isStatement = YES; + + Switch.prototype.jumps = function(o) { + var block, conds, _i, _len, _ref2, _ref3, _ref4; + if (o == null) { + o = { + block: true + }; + } + _ref2 = this.cases; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + _ref3 = _ref2[_i], conds = _ref3[0], block = _ref3[1]; + if (block.jumps(o)) { + return block; + } + } + return (_ref4 = this.otherwise) != null ? _ref4.jumps(o) : void 0; + }; + + Switch.prototype.makeReturn = function(res) { + var pair, _i, _len, _ref2, _ref3; + _ref2 = this.cases; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + pair = _ref2[_i]; + pair[1].makeReturn(res); + } + if (res) { + this.otherwise || (this.otherwise = new Block([new Literal('void 0')])); + } + if ((_ref3 = this.otherwise) != null) { + _ref3.makeReturn(res); + } + return this; + }; + + Switch.prototype.compileNode = function(o) { + var block, body, code, cond, conditions, expr, i, idt1, idt2, _i, _j, _len, _len1, _ref2, _ref3, _ref4, _ref5; + idt1 = o.indent + TAB; + idt2 = o.indent = idt1 + TAB; + code = this.tab + ("switch (" + (((_ref2 = this.subject) != null ? _ref2.compile(o, LEVEL_PAREN) : void 0) || false) + ") {\n"); + _ref3 = this.cases; + for (i = _i = 0, _len = _ref3.length; _i < _len; i = ++_i) { + _ref4 = _ref3[i], conditions = _ref4[0], block = _ref4[1]; + _ref5 = flatten([conditions]); + for (_j = 0, _len1 = _ref5.length; _j < _len1; _j++) { + cond = _ref5[_j]; + if (!this.subject) { + cond = cond.invert(); + } + code += idt1 + ("case " + (cond.compile(o, LEVEL_PAREN)) + ":\n"); + } + if (body = block.compile(o, LEVEL_TOP)) { + code += body + '\n'; + } + if (i === this.cases.length - 1 && !this.otherwise) { + break; + } + expr = this.lastNonComment(block.expressions); + if (expr instanceof Return || (expr instanceof Literal && expr.jumps() && expr.value !== 'debugger')) { + continue; + } + code += idt2 + 'break;\n'; + } + if (this.otherwise && this.otherwise.expressions.length) { + code += idt1 + ("default:\n" + (this.otherwise.compile(o, LEVEL_TOP)) + "\n"); + } + return code + this.tab + '}'; + }; + + return Switch; + + })(Base); + + exports.If = If = (function(_super) { + + __extends(If, _super); + + function If(condition, body, options) { + this.body = body; + if (options == null) { + options = {}; + } + this.condition = options.type === 'unless' ? condition.invert() : condition; + this.elseBody = null; + this.isChain = false; + this.soak = options.soak; + } + + If.prototype.children = ['condition', 'body', 'elseBody']; + + If.prototype.bodyNode = function() { + var _ref2; + return (_ref2 = this.body) != null ? _ref2.unwrap() : void 0; + }; + + If.prototype.elseBodyNode = function() { + var _ref2; + return (_ref2 = this.elseBody) != null ? _ref2.unwrap() : void 0; + }; + + If.prototype.addElse = function(elseBody) { + if (this.isChain) { + this.elseBodyNode().addElse(elseBody); + } else { + this.isChain = elseBody instanceof If; + this.elseBody = this.ensureBlock(elseBody); + } + return this; + }; + + If.prototype.isStatement = function(o) { + var _ref2; + return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((_ref2 = this.elseBodyNode()) != null ? _ref2.isStatement(o) : void 0); + }; + + If.prototype.jumps = function(o) { + var _ref2; + return this.body.jumps(o) || ((_ref2 = this.elseBody) != null ? _ref2.jumps(o) : void 0); + }; + + If.prototype.compileNode = function(o) { + if (this.isStatement(o)) { + return this.compileStatement(o); + } else { + return this.compileExpression(o); + } + }; + + If.prototype.makeReturn = function(res) { + if (res) { + this.elseBody || (this.elseBody = new Block([new Literal('void 0')])); + } + this.body && (this.body = new Block([this.body.makeReturn(res)])); + this.elseBody && (this.elseBody = new Block([this.elseBody.makeReturn(res)])); + return this; + }; + + If.prototype.ensureBlock = function(node) { + if (node instanceof Block) { + return node; + } else { + return new Block([node]); + } + }; + + If.prototype.compileStatement = function(o) { + var body, child, cond, exeq, ifPart; + child = del(o, 'chainChild'); + exeq = del(o, 'isExistentialEquals'); + if (exeq) { + return new If(this.condition.invert(), this.elseBodyNode(), { + type: 'if' + }).compile(o); + } + cond = this.condition.compile(o, LEVEL_PAREN); + o.indent += TAB; + body = this.ensureBlock(this.body); + ifPart = "if (" + cond + ") {\n" + (body.compile(o)) + "\n" + this.tab + "}"; + if (!child) { + ifPart = this.tab + ifPart; + } + if (!this.elseBody) { + return ifPart; + } + return ifPart + ' else ' + (this.isChain ? (o.indent = this.tab, o.chainChild = true, this.elseBody.unwrap().compile(o, LEVEL_TOP)) : "{\n" + (this.elseBody.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}"); + }; + + If.prototype.compileExpression = function(o) { + var alt, body, code, cond; + cond = this.condition.compile(o, LEVEL_COND); + body = this.bodyNode().compile(o, LEVEL_LIST); + alt = this.elseBodyNode() ? this.elseBodyNode().compile(o, LEVEL_LIST) : 'void 0'; + code = "" + cond + " ? " + body + " : " + alt; + if (o.level >= LEVEL_COND) { + return "(" + code + ")"; + } else { + return code; + } + }; + + If.prototype.unfoldSoak = function() { + return this.soak && this; + }; + + return If; + + })(Base); + + Closure = { + wrap: function(expressions, statement, noReturn) { + var args, call, func, mentionsArgs, meth; + if (expressions.jumps()) { + return expressions; + } + func = new Code([], Block.wrap([expressions])); + args = []; + if ((mentionsArgs = expressions.contains(this.literalArgs)) || expressions.contains(this.literalThis)) { + meth = new Literal(mentionsArgs ? 'apply' : 'call'); + args = [new Literal('this')]; + if (mentionsArgs) { + args.push(new Literal('arguments')); + } + func = new Value(func, [new Access(meth)]); + } + func.noReturn = noReturn; + call = new Call(func, args); + if (statement) { + return Block.wrap([call]); + } else { + return call; + } + }, + literalArgs: function(node) { + return node instanceof Literal && node.value === 'arguments' && !node.asKey; + }, + literalThis: function(node) { + return (node instanceof Literal && node.value === 'this' && !node.asKey) || (node instanceof Code && node.bound) || (node instanceof Call && node.isSuper); + } + }; + + unfoldSoak = function(o, parent, name) { + var ifn; + if (!(ifn = parent[name].unfoldSoak(o))) { + return; + } + parent[name] = ifn.body; + ifn.body = new Value(parent); + return ifn; + }; + + UTILITIES = { + "extends": function() { + return "function(child, parent) { for (var key in parent) { if (" + (utility('hasProp')) + ".call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }"; + }, + bind: function() { + return 'function(fn, me){ return function(){ return fn.apply(me, arguments); }; }'; + }, + indexOf: function() { + return "[].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }"; + }, + hasProp: function() { + return '{}.hasOwnProperty'; + }, + slice: function() { + return '[].slice'; + } + }; + + LEVEL_TOP = 1; + + LEVEL_PAREN = 2; + + LEVEL_LIST = 3; + + LEVEL_COND = 4; + + LEVEL_OP = 5; + + LEVEL_ACCESS = 6; + + TAB = ' '; + + IDENTIFIER_STR = "[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*"; + + IDENTIFIER = RegExp("^" + IDENTIFIER_STR + "$"); + + SIMPLENUM = /^[+-]?\d+$/; + + METHOD_DEF = RegExp("^(?:(" + IDENTIFIER_STR + ")\\.prototype(?:\\.(" + IDENTIFIER_STR + ")|\\[(\"(?:[^\\\\\"\\r\\n]|\\\\.)*\"|'(?:[^\\\\'\\r\\n]|\\\\.)*')\\]|\\[(0x[\\da-fA-F]+|\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\]))|(" + IDENTIFIER_STR + ")$"); + + IS_STRING = /^['"]/; + + utility = function(name) { + var ref; + ref = "__" + name; + Scope.root.assign(ref, UTILITIES[name]()); + return ref; + }; + + multident = function(code, tab) { + code = code.replace(/\n/g, '$&' + tab); + return code.replace(/\s+$/, ''); + }; + +}).call(this); diff --git a/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/optparse.js b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/optparse.js new file mode 100644 index 0000000..d7fda40 --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/optparse.js @@ -0,0 +1,138 @@ +// Generated by CoffeeScript 1.3.3 +(function() { + var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments; + + exports.OptionParser = OptionParser = (function() { + + function OptionParser(rules, banner) { + this.banner = banner; + this.rules = buildRules(rules); + } + + OptionParser.prototype.parse = function(args) { + var arg, i, isOption, matchedRule, options, originalArgs, pos, rule, seenNonOptionArg, skippingArgument, value, _i, _j, _len, _len1, _ref; + options = { + "arguments": [] + }; + skippingArgument = false; + originalArgs = args; + args = normalizeArguments(args); + for (i = _i = 0, _len = args.length; _i < _len; i = ++_i) { + arg = args[i]; + if (skippingArgument) { + skippingArgument = false; + continue; + } + if (arg === '--') { + pos = originalArgs.indexOf('--'); + options["arguments"] = options["arguments"].concat(originalArgs.slice(pos + 1)); + break; + } + isOption = !!(arg.match(LONG_FLAG) || arg.match(SHORT_FLAG)); + seenNonOptionArg = options["arguments"].length > 0; + if (!seenNonOptionArg) { + matchedRule = false; + _ref = this.rules; + for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { + rule = _ref[_j]; + if (rule.shortFlag === arg || rule.longFlag === arg) { + value = true; + if (rule.hasArgument) { + skippingArgument = true; + value = args[i + 1]; + } + options[rule.name] = rule.isList ? (options[rule.name] || []).concat(value) : value; + matchedRule = true; + break; + } + } + if (isOption && !matchedRule) { + throw new Error("unrecognized option: " + arg); + } + } + if (seenNonOptionArg || !isOption) { + options["arguments"].push(arg); + } + } + return options; + }; + + OptionParser.prototype.help = function() { + var letPart, lines, rule, spaces, _i, _len, _ref; + lines = []; + if (this.banner) { + lines.unshift("" + this.banner + "\n"); + } + _ref = this.rules; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + rule = _ref[_i]; + spaces = 15 - rule.longFlag.length; + spaces = spaces > 0 ? Array(spaces + 1).join(' ') : ''; + letPart = rule.shortFlag ? rule.shortFlag + ', ' : ' '; + lines.push(' ' + letPart + rule.longFlag + spaces + rule.description); + } + return "\n" + (lines.join('\n')) + "\n"; + }; + + return OptionParser; + + })(); + + LONG_FLAG = /^(--\w[\w\-]*)/; + + SHORT_FLAG = /^(-\w)$/; + + MULTI_FLAG = /^-(\w{2,})/; + + OPTIONAL = /\[(\w+(\*?))\]/; + + buildRules = function(rules) { + var tuple, _i, _len, _results; + _results = []; + for (_i = 0, _len = rules.length; _i < _len; _i++) { + tuple = rules[_i]; + if (tuple.length < 3) { + tuple.unshift(null); + } + _results.push(buildRule.apply(null, tuple)); + } + return _results; + }; + + buildRule = function(shortFlag, longFlag, description, options) { + var match; + if (options == null) { + options = {}; + } + match = longFlag.match(OPTIONAL); + longFlag = longFlag.match(LONG_FLAG)[1]; + return { + name: longFlag.substr(2), + shortFlag: shortFlag, + longFlag: longFlag, + description: description, + hasArgument: !!(match && match[1]), + isList: !!(match && match[2]) + }; + }; + + normalizeArguments = function(args) { + var arg, l, match, result, _i, _j, _len, _len1, _ref; + args = args.slice(0); + result = []; + for (_i = 0, _len = args.length; _i < _len; _i++) { + arg = args[_i]; + if (match = arg.match(MULTI_FLAG)) { + _ref = match[1].split(''); + for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { + l = _ref[_j]; + result.push('-' + l); + } + } else { + result.push(arg); + } + } + return result; + }; + +}).call(this); diff --git a/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/parser.js b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/parser.js new file mode 100644 index 0000000..f049903 --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/parser.js @@ -0,0 +1,683 @@ +/* Jison generated parser */ +var parser = (function(){ +var parser = {trace: function trace() { }, +yy: {}, +symbols_: {"error":2,"Root":3,"Body":4,"Block":5,"TERMINATOR":6,"Line":7,"Expression":8,"Statement":9,"Return":10,"Comment":11,"STATEMENT":12,"Value":13,"Invocation":14,"Code":15,"Operation":16,"Assign":17,"If":18,"Try":19,"While":20,"For":21,"Switch":22,"Class":23,"Throw":24,"INDENT":25,"OUTDENT":26,"Identifier":27,"IDENTIFIER":28,"AlphaNumeric":29,"NUMBER":30,"STRING":31,"Literal":32,"JS":33,"REGEX":34,"DEBUGGER":35,"UNDEFINED":36,"NULL":37,"BOOL":38,"Assignable":39,"=":40,"AssignObj":41,"ObjAssignable":42,":":43,"ThisProperty":44,"RETURN":45,"HERECOMMENT":46,"PARAM_START":47,"ParamList":48,"PARAM_END":49,"FuncGlyph":50,"->":51,"=>":52,"OptComma":53,",":54,"Param":55,"ParamVar":56,"...":57,"Array":58,"Object":59,"Splat":60,"SimpleAssignable":61,"Accessor":62,"Parenthetical":63,"Range":64,"This":65,".":66,"?.":67,"::":68,"Index":69,"INDEX_START":70,"IndexValue":71,"INDEX_END":72,"INDEX_SOAK":73,"Slice":74,"{":75,"AssignList":76,"}":77,"CLASS":78,"EXTENDS":79,"OptFuncExist":80,"Arguments":81,"SUPER":82,"FUNC_EXIST":83,"CALL_START":84,"CALL_END":85,"ArgList":86,"THIS":87,"@":88,"[":89,"]":90,"RangeDots":91,"..":92,"Arg":93,"SimpleArgs":94,"TRY":95,"Catch":96,"FINALLY":97,"CATCH":98,"THROW":99,"(":100,")":101,"WhileSource":102,"WHILE":103,"WHEN":104,"UNTIL":105,"Loop":106,"LOOP":107,"ForBody":108,"FOR":109,"ForStart":110,"ForSource":111,"ForVariables":112,"OWN":113,"ForValue":114,"FORIN":115,"FOROF":116,"BY":117,"SWITCH":118,"Whens":119,"ELSE":120,"When":121,"LEADING_WHEN":122,"IfBlock":123,"IF":124,"POST_IF":125,"UNARY":126,"-":127,"+":128,"--":129,"++":130,"?":131,"MATH":132,"SHIFT":133,"COMPARE":134,"LOGIC":135,"RELATION":136,"COMPOUND_ASSIGN":137,"$accept":0,"$end":1}, +terminals_: {2:"error",6:"TERMINATOR",12:"STATEMENT",25:"INDENT",26:"OUTDENT",28:"IDENTIFIER",30:"NUMBER",31:"STRING",33:"JS",34:"REGEX",35:"DEBUGGER",36:"UNDEFINED",37:"NULL",38:"BOOL",40:"=",43:":",45:"RETURN",46:"HERECOMMENT",47:"PARAM_START",49:"PARAM_END",51:"->",52:"=>",54:",",57:"...",66:".",67:"?.",68:"::",70:"INDEX_START",72:"INDEX_END",73:"INDEX_SOAK",75:"{",77:"}",78:"CLASS",79:"EXTENDS",82:"SUPER",83:"FUNC_EXIST",84:"CALL_START",85:"CALL_END",87:"THIS",88:"@",89:"[",90:"]",92:"..",95:"TRY",97:"FINALLY",98:"CATCH",99:"THROW",100:"(",101:")",103:"WHILE",104:"WHEN",105:"UNTIL",107:"LOOP",109:"FOR",113:"OWN",115:"FORIN",116:"FOROF",117:"BY",118:"SWITCH",120:"ELSE",122:"LEADING_WHEN",124:"IF",125:"POST_IF",126:"UNARY",127:"-",128:"+",129:"--",130:"++",131:"?",132:"MATH",133:"SHIFT",134:"COMPARE",135:"LOGIC",136:"RELATION",137:"COMPOUND_ASSIGN"}, +productions_: [0,[3,0],[3,1],[3,2],[4,1],[4,3],[4,2],[7,1],[7,1],[9,1],[9,1],[9,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[5,2],[5,3],[27,1],[29,1],[29,1],[32,1],[32,1],[32,1],[32,1],[32,1],[32,1],[32,1],[17,3],[17,4],[17,5],[41,1],[41,3],[41,5],[41,1],[42,1],[42,1],[42,1],[10,2],[10,1],[11,1],[15,5],[15,2],[50,1],[50,1],[53,0],[53,1],[48,0],[48,1],[48,3],[48,4],[48,6],[55,1],[55,2],[55,3],[56,1],[56,1],[56,1],[56,1],[60,2],[61,1],[61,2],[61,2],[61,1],[39,1],[39,1],[39,1],[13,1],[13,1],[13,1],[13,1],[13,1],[62,2],[62,2],[62,2],[62,1],[62,1],[69,3],[69,2],[71,1],[71,1],[59,4],[76,0],[76,1],[76,3],[76,4],[76,6],[23,1],[23,2],[23,3],[23,4],[23,2],[23,3],[23,4],[23,5],[14,3],[14,3],[14,1],[14,2],[80,0],[80,1],[81,2],[81,4],[65,1],[65,1],[44,2],[58,2],[58,4],[91,1],[91,1],[64,5],[74,3],[74,2],[74,2],[74,1],[86,1],[86,3],[86,4],[86,4],[86,6],[93,1],[93,1],[94,1],[94,3],[19,2],[19,3],[19,4],[19,5],[96,3],[24,2],[63,3],[63,5],[102,2],[102,4],[102,2],[102,4],[20,2],[20,2],[20,2],[20,1],[106,2],[106,2],[21,2],[21,2],[21,2],[108,2],[108,2],[110,2],[110,3],[114,1],[114,1],[114,1],[114,1],[112,1],[112,3],[111,2],[111,2],[111,4],[111,4],[111,4],[111,6],[111,6],[22,5],[22,7],[22,4],[22,6],[119,1],[119,2],[121,3],[121,4],[123,3],[123,5],[18,1],[18,3],[18,3],[18,3],[16,2],[16,2],[16,2],[16,2],[16,2],[16,2],[16,2],[16,2],[16,3],[16,3],[16,3],[16,3],[16,3],[16,3],[16,3],[16,3],[16,5],[16,3]], +performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) { + +var $0 = $$.length - 1; +switch (yystate) { +case 1:return this.$ = new yy.Block; +break; +case 2:return this.$ = $$[$0]; +break; +case 3:return this.$ = $$[$0-1]; +break; +case 4:this.$ = yy.Block.wrap([$$[$0]]); +break; +case 5:this.$ = $$[$0-2].push($$[$0]); +break; +case 6:this.$ = $$[$0-1]; +break; +case 7:this.$ = $$[$0]; +break; +case 8:this.$ = $$[$0]; +break; +case 9:this.$ = $$[$0]; +break; +case 10:this.$ = $$[$0]; +break; +case 11:this.$ = new yy.Literal($$[$0]); +break; +case 12:this.$ = $$[$0]; +break; +case 13:this.$ = $$[$0]; +break; +case 14:this.$ = $$[$0]; +break; +case 15:this.$ = $$[$0]; +break; +case 16:this.$ = $$[$0]; +break; +case 17:this.$ = $$[$0]; +break; +case 18:this.$ = $$[$0]; +break; +case 19:this.$ = $$[$0]; +break; +case 20:this.$ = $$[$0]; +break; +case 21:this.$ = $$[$0]; +break; +case 22:this.$ = $$[$0]; +break; +case 23:this.$ = $$[$0]; +break; +case 24:this.$ = new yy.Block; +break; +case 25:this.$ = $$[$0-1]; +break; +case 26:this.$ = new yy.Literal($$[$0]); +break; +case 27:this.$ = new yy.Literal($$[$0]); +break; +case 28:this.$ = new yy.Literal($$[$0]); +break; +case 29:this.$ = $$[$0]; +break; +case 30:this.$ = new yy.Literal($$[$0]); +break; +case 31:this.$ = new yy.Literal($$[$0]); +break; +case 32:this.$ = new yy.Literal($$[$0]); +break; +case 33:this.$ = new yy.Undefined; +break; +case 34:this.$ = new yy.Null; +break; +case 35:this.$ = new yy.Bool($$[$0]); +break; +case 36:this.$ = new yy.Assign($$[$0-2], $$[$0]); +break; +case 37:this.$ = new yy.Assign($$[$0-3], $$[$0]); +break; +case 38:this.$ = new yy.Assign($$[$0-4], $$[$0-1]); +break; +case 39:this.$ = new yy.Value($$[$0]); +break; +case 40:this.$ = new yy.Assign(new yy.Value($$[$0-2]), $$[$0], 'object'); +break; +case 41:this.$ = new yy.Assign(new yy.Value($$[$0-4]), $$[$0-1], 'object'); +break; +case 42:this.$ = $$[$0]; +break; +case 43:this.$ = $$[$0]; +break; +case 44:this.$ = $$[$0]; +break; +case 45:this.$ = $$[$0]; +break; +case 46:this.$ = new yy.Return($$[$0]); +break; +case 47:this.$ = new yy.Return; +break; +case 48:this.$ = new yy.Comment($$[$0]); +break; +case 49:this.$ = new yy.Code($$[$0-3], $$[$0], $$[$0-1]); +break; +case 50:this.$ = new yy.Code([], $$[$0], $$[$0-1]); +break; +case 51:this.$ = 'func'; +break; +case 52:this.$ = 'boundfunc'; +break; +case 53:this.$ = $$[$0]; +break; +case 54:this.$ = $$[$0]; +break; +case 55:this.$ = []; +break; +case 56:this.$ = [$$[$0]]; +break; +case 57:this.$ = $$[$0-2].concat($$[$0]); +break; +case 58:this.$ = $$[$0-3].concat($$[$0]); +break; +case 59:this.$ = $$[$0-5].concat($$[$0-2]); +break; +case 60:this.$ = new yy.Param($$[$0]); +break; +case 61:this.$ = new yy.Param($$[$0-1], null, true); +break; +case 62:this.$ = new yy.Param($$[$0-2], $$[$0]); +break; +case 63:this.$ = $$[$0]; +break; +case 64:this.$ = $$[$0]; +break; +case 65:this.$ = $$[$0]; +break; +case 66:this.$ = $$[$0]; +break; +case 67:this.$ = new yy.Splat($$[$0-1]); +break; +case 68:this.$ = new yy.Value($$[$0]); +break; +case 69:this.$ = $$[$0-1].add($$[$0]); +break; +case 70:this.$ = new yy.Value($$[$0-1], [].concat($$[$0])); +break; +case 71:this.$ = $$[$0]; +break; +case 72:this.$ = $$[$0]; +break; +case 73:this.$ = new yy.Value($$[$0]); +break; +case 74:this.$ = new yy.Value($$[$0]); +break; +case 75:this.$ = $$[$0]; +break; +case 76:this.$ = new yy.Value($$[$0]); +break; +case 77:this.$ = new yy.Value($$[$0]); +break; +case 78:this.$ = new yy.Value($$[$0]); +break; +case 79:this.$ = $$[$0]; +break; +case 80:this.$ = new yy.Access($$[$0]); +break; +case 81:this.$ = new yy.Access($$[$0], 'soak'); +break; +case 82:this.$ = [new yy.Access(new yy.Literal('prototype')), new yy.Access($$[$0])]; +break; +case 83:this.$ = new yy.Access(new yy.Literal('prototype')); +break; +case 84:this.$ = $$[$0]; +break; +case 85:this.$ = $$[$0-1]; +break; +case 86:this.$ = yy.extend($$[$0], { + soak: true + }); +break; +case 87:this.$ = new yy.Index($$[$0]); +break; +case 88:this.$ = new yy.Slice($$[$0]); +break; +case 89:this.$ = new yy.Obj($$[$0-2], $$[$0-3].generated); +break; +case 90:this.$ = []; +break; +case 91:this.$ = [$$[$0]]; +break; +case 92:this.$ = $$[$0-2].concat($$[$0]); +break; +case 93:this.$ = $$[$0-3].concat($$[$0]); +break; +case 94:this.$ = $$[$0-5].concat($$[$0-2]); +break; +case 95:this.$ = new yy.Class; +break; +case 96:this.$ = new yy.Class(null, null, $$[$0]); +break; +case 97:this.$ = new yy.Class(null, $$[$0]); +break; +case 98:this.$ = new yy.Class(null, $$[$0-1], $$[$0]); +break; +case 99:this.$ = new yy.Class($$[$0]); +break; +case 100:this.$ = new yy.Class($$[$0-1], null, $$[$0]); +break; +case 101:this.$ = new yy.Class($$[$0-2], $$[$0]); +break; +case 102:this.$ = new yy.Class($$[$0-3], $$[$0-1], $$[$0]); +break; +case 103:this.$ = new yy.Call($$[$0-2], $$[$0], $$[$0-1]); +break; +case 104:this.$ = new yy.Call($$[$0-2], $$[$0], $$[$0-1]); +break; +case 105:this.$ = new yy.Call('super', [new yy.Splat(new yy.Literal('arguments'))]); +break; +case 106:this.$ = new yy.Call('super', $$[$0]); +break; +case 107:this.$ = false; +break; +case 108:this.$ = true; +break; +case 109:this.$ = []; +break; +case 110:this.$ = $$[$0-2]; +break; +case 111:this.$ = new yy.Value(new yy.Literal('this')); +break; +case 112:this.$ = new yy.Value(new yy.Literal('this')); +break; +case 113:this.$ = new yy.Value(new yy.Literal('this'), [new yy.Access($$[$0])], 'this'); +break; +case 114:this.$ = new yy.Arr([]); +break; +case 115:this.$ = new yy.Arr($$[$0-2]); +break; +case 116:this.$ = 'inclusive'; +break; +case 117:this.$ = 'exclusive'; +break; +case 118:this.$ = new yy.Range($$[$0-3], $$[$0-1], $$[$0-2]); +break; +case 119:this.$ = new yy.Range($$[$0-2], $$[$0], $$[$0-1]); +break; +case 120:this.$ = new yy.Range($$[$0-1], null, $$[$0]); +break; +case 121:this.$ = new yy.Range(null, $$[$0], $$[$0-1]); +break; +case 122:this.$ = new yy.Range(null, null, $$[$0]); +break; +case 123:this.$ = [$$[$0]]; +break; +case 124:this.$ = $$[$0-2].concat($$[$0]); +break; +case 125:this.$ = $$[$0-3].concat($$[$0]); +break; +case 126:this.$ = $$[$0-2]; +break; +case 127:this.$ = $$[$0-5].concat($$[$0-2]); +break; +case 128:this.$ = $$[$0]; +break; +case 129:this.$ = $$[$0]; +break; +case 130:this.$ = $$[$0]; +break; +case 131:this.$ = [].concat($$[$0-2], $$[$0]); +break; +case 132:this.$ = new yy.Try($$[$0]); +break; +case 133:this.$ = new yy.Try($$[$0-1], $$[$0][0], $$[$0][1]); +break; +case 134:this.$ = new yy.Try($$[$0-2], null, null, $$[$0]); +break; +case 135:this.$ = new yy.Try($$[$0-3], $$[$0-2][0], $$[$0-2][1], $$[$0]); +break; +case 136:this.$ = [$$[$0-1], $$[$0]]; +break; +case 137:this.$ = new yy.Throw($$[$0]); +break; +case 138:this.$ = new yy.Parens($$[$0-1]); +break; +case 139:this.$ = new yy.Parens($$[$0-2]); +break; +case 140:this.$ = new yy.While($$[$0]); +break; +case 141:this.$ = new yy.While($$[$0-2], { + guard: $$[$0] + }); +break; +case 142:this.$ = new yy.While($$[$0], { + invert: true + }); +break; +case 143:this.$ = new yy.While($$[$0-2], { + invert: true, + guard: $$[$0] + }); +break; +case 144:this.$ = $$[$0-1].addBody($$[$0]); +break; +case 145:this.$ = $$[$0].addBody(yy.Block.wrap([$$[$0-1]])); +break; +case 146:this.$ = $$[$0].addBody(yy.Block.wrap([$$[$0-1]])); +break; +case 147:this.$ = $$[$0]; +break; +case 148:this.$ = new yy.While(new yy.Literal('true')).addBody($$[$0]); +break; +case 149:this.$ = new yy.While(new yy.Literal('true')).addBody(yy.Block.wrap([$$[$0]])); +break; +case 150:this.$ = new yy.For($$[$0-1], $$[$0]); +break; +case 151:this.$ = new yy.For($$[$0-1], $$[$0]); +break; +case 152:this.$ = new yy.For($$[$0], $$[$0-1]); +break; +case 153:this.$ = { + source: new yy.Value($$[$0]) + }; +break; +case 154:this.$ = (function () { + $$[$0].own = $$[$0-1].own; + $$[$0].name = $$[$0-1][0]; + $$[$0].index = $$[$0-1][1]; + return $$[$0]; + }()); +break; +case 155:this.$ = $$[$0]; +break; +case 156:this.$ = (function () { + $$[$0].own = true; + return $$[$0]; + }()); +break; +case 157:this.$ = $$[$0]; +break; +case 158:this.$ = $$[$0]; +break; +case 159:this.$ = new yy.Value($$[$0]); +break; +case 160:this.$ = new yy.Value($$[$0]); +break; +case 161:this.$ = [$$[$0]]; +break; +case 162:this.$ = [$$[$0-2], $$[$0]]; +break; +case 163:this.$ = { + source: $$[$0] + }; +break; +case 164:this.$ = { + source: $$[$0], + object: true + }; +break; +case 165:this.$ = { + source: $$[$0-2], + guard: $$[$0] + }; +break; +case 166:this.$ = { + source: $$[$0-2], + guard: $$[$0], + object: true + }; +break; +case 167:this.$ = { + source: $$[$0-2], + step: $$[$0] + }; +break; +case 168:this.$ = { + source: $$[$0-4], + guard: $$[$0-2], + step: $$[$0] + }; +break; +case 169:this.$ = { + source: $$[$0-4], + step: $$[$0-2], + guard: $$[$0] + }; +break; +case 170:this.$ = new yy.Switch($$[$0-3], $$[$0-1]); +break; +case 171:this.$ = new yy.Switch($$[$0-5], $$[$0-3], $$[$0-1]); +break; +case 172:this.$ = new yy.Switch(null, $$[$0-1]); +break; +case 173:this.$ = new yy.Switch(null, $$[$0-3], $$[$0-1]); +break; +case 174:this.$ = $$[$0]; +break; +case 175:this.$ = $$[$0-1].concat($$[$0]); +break; +case 176:this.$ = [[$$[$0-1], $$[$0]]]; +break; +case 177:this.$ = [[$$[$0-2], $$[$0-1]]]; +break; +case 178:this.$ = new yy.If($$[$0-1], $$[$0], { + type: $$[$0-2] + }); +break; +case 179:this.$ = $$[$0-4].addElse(new yy.If($$[$0-1], $$[$0], { + type: $$[$0-2] + })); +break; +case 180:this.$ = $$[$0]; +break; +case 181:this.$ = $$[$0-2].addElse($$[$0]); +break; +case 182:this.$ = new yy.If($$[$0], yy.Block.wrap([$$[$0-2]]), { + type: $$[$0-1], + statement: true + }); +break; +case 183:this.$ = new yy.If($$[$0], yy.Block.wrap([$$[$0-2]]), { + type: $$[$0-1], + statement: true + }); +break; +case 184:this.$ = new yy.Op($$[$0-1], $$[$0]); +break; +case 185:this.$ = new yy.Op('-', $$[$0]); +break; +case 186:this.$ = new yy.Op('+', $$[$0]); +break; +case 187:this.$ = new yy.Op('--', $$[$0]); +break; +case 188:this.$ = new yy.Op('++', $$[$0]); +break; +case 189:this.$ = new yy.Op('--', $$[$0-1], null, true); +break; +case 190:this.$ = new yy.Op('++', $$[$0-1], null, true); +break; +case 191:this.$ = new yy.Existence($$[$0-1]); +break; +case 192:this.$ = new yy.Op('+', $$[$0-2], $$[$0]); +break; +case 193:this.$ = new yy.Op('-', $$[$0-2], $$[$0]); +break; +case 194:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]); +break; +case 195:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]); +break; +case 196:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]); +break; +case 197:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]); +break; +case 198:this.$ = (function () { + if ($$[$0-1].charAt(0) === '!') { + return new yy.Op($$[$0-1].slice(1), $$[$0-2], $$[$0]).invert(); + } else { + return new yy.Op($$[$0-1], $$[$0-2], $$[$0]); + } + }()); +break; +case 199:this.$ = new yy.Assign($$[$0-2], $$[$0], $$[$0-1]); +break; +case 200:this.$ = new yy.Assign($$[$0-4], $$[$0-1], $$[$0-3]); +break; +case 201:this.$ = new yy.Extends($$[$0-2], $$[$0]); +break; +} +}, +table: [{1:[2,1],3:1,4:2,5:3,7:4,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,5],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[3]},{1:[2,2],6:[1,74]},{6:[1,75]},{1:[2,4],6:[2,4],26:[2,4],101:[2,4]},{4:77,7:4,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,26:[1,76],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,7],6:[2,7],26:[2,7],101:[2,7],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,8],6:[2,8],26:[2,8],101:[2,8],102:90,103:[1,65],105:[1,66],108:91,109:[1,68],110:69,125:[1,89]},{1:[2,12],6:[2,12],25:[2,12],26:[2,12],49:[2,12],54:[2,12],57:[2,12],62:93,66:[1,95],67:[1,96],68:[1,97],69:98,70:[1,99],72:[2,12],73:[1,100],77:[2,12],80:92,83:[1,94],84:[2,107],85:[2,12],90:[2,12],92:[2,12],101:[2,12],103:[2,12],104:[2,12],105:[2,12],109:[2,12],117:[2,12],125:[2,12],127:[2,12],128:[2,12],131:[2,12],132:[2,12],133:[2,12],134:[2,12],135:[2,12],136:[2,12]},{1:[2,13],6:[2,13],25:[2,13],26:[2,13],49:[2,13],54:[2,13],57:[2,13],62:102,66:[1,95],67:[1,96],68:[1,97],69:98,70:[1,99],72:[2,13],73:[1,100],77:[2,13],80:101,83:[1,94],84:[2,107],85:[2,13],90:[2,13],92:[2,13],101:[2,13],103:[2,13],104:[2,13],105:[2,13],109:[2,13],117:[2,13],125:[2,13],127:[2,13],128:[2,13],131:[2,13],132:[2,13],133:[2,13],134:[2,13],135:[2,13],136:[2,13]},{1:[2,14],6:[2,14],25:[2,14],26:[2,14],49:[2,14],54:[2,14],57:[2,14],72:[2,14],77:[2,14],85:[2,14],90:[2,14],92:[2,14],101:[2,14],103:[2,14],104:[2,14],105:[2,14],109:[2,14],117:[2,14],125:[2,14],127:[2,14],128:[2,14],131:[2,14],132:[2,14],133:[2,14],134:[2,14],135:[2,14],136:[2,14]},{1:[2,15],6:[2,15],25:[2,15],26:[2,15],49:[2,15],54:[2,15],57:[2,15],72:[2,15],77:[2,15],85:[2,15],90:[2,15],92:[2,15],101:[2,15],103:[2,15],104:[2,15],105:[2,15],109:[2,15],117:[2,15],125:[2,15],127:[2,15],128:[2,15],131:[2,15],132:[2,15],133:[2,15],134:[2,15],135:[2,15],136:[2,15]},{1:[2,16],6:[2,16],25:[2,16],26:[2,16],49:[2,16],54:[2,16],57:[2,16],72:[2,16],77:[2,16],85:[2,16],90:[2,16],92:[2,16],101:[2,16],103:[2,16],104:[2,16],105:[2,16],109:[2,16],117:[2,16],125:[2,16],127:[2,16],128:[2,16],131:[2,16],132:[2,16],133:[2,16],134:[2,16],135:[2,16],136:[2,16]},{1:[2,17],6:[2,17],25:[2,17],26:[2,17],49:[2,17],54:[2,17],57:[2,17],72:[2,17],77:[2,17],85:[2,17],90:[2,17],92:[2,17],101:[2,17],103:[2,17],104:[2,17],105:[2,17],109:[2,17],117:[2,17],125:[2,17],127:[2,17],128:[2,17],131:[2,17],132:[2,17],133:[2,17],134:[2,17],135:[2,17],136:[2,17]},{1:[2,18],6:[2,18],25:[2,18],26:[2,18],49:[2,18],54:[2,18],57:[2,18],72:[2,18],77:[2,18],85:[2,18],90:[2,18],92:[2,18],101:[2,18],103:[2,18],104:[2,18],105:[2,18],109:[2,18],117:[2,18],125:[2,18],127:[2,18],128:[2,18],131:[2,18],132:[2,18],133:[2,18],134:[2,18],135:[2,18],136:[2,18]},{1:[2,19],6:[2,19],25:[2,19],26:[2,19],49:[2,19],54:[2,19],57:[2,19],72:[2,19],77:[2,19],85:[2,19],90:[2,19],92:[2,19],101:[2,19],103:[2,19],104:[2,19],105:[2,19],109:[2,19],117:[2,19],125:[2,19],127:[2,19],128:[2,19],131:[2,19],132:[2,19],133:[2,19],134:[2,19],135:[2,19],136:[2,19]},{1:[2,20],6:[2,20],25:[2,20],26:[2,20],49:[2,20],54:[2,20],57:[2,20],72:[2,20],77:[2,20],85:[2,20],90:[2,20],92:[2,20],101:[2,20],103:[2,20],104:[2,20],105:[2,20],109:[2,20],117:[2,20],125:[2,20],127:[2,20],128:[2,20],131:[2,20],132:[2,20],133:[2,20],134:[2,20],135:[2,20],136:[2,20]},{1:[2,21],6:[2,21],25:[2,21],26:[2,21],49:[2,21],54:[2,21],57:[2,21],72:[2,21],77:[2,21],85:[2,21],90:[2,21],92:[2,21],101:[2,21],103:[2,21],104:[2,21],105:[2,21],109:[2,21],117:[2,21],125:[2,21],127:[2,21],128:[2,21],131:[2,21],132:[2,21],133:[2,21],134:[2,21],135:[2,21],136:[2,21]},{1:[2,22],6:[2,22],25:[2,22],26:[2,22],49:[2,22],54:[2,22],57:[2,22],72:[2,22],77:[2,22],85:[2,22],90:[2,22],92:[2,22],101:[2,22],103:[2,22],104:[2,22],105:[2,22],109:[2,22],117:[2,22],125:[2,22],127:[2,22],128:[2,22],131:[2,22],132:[2,22],133:[2,22],134:[2,22],135:[2,22],136:[2,22]},{1:[2,23],6:[2,23],25:[2,23],26:[2,23],49:[2,23],54:[2,23],57:[2,23],72:[2,23],77:[2,23],85:[2,23],90:[2,23],92:[2,23],101:[2,23],103:[2,23],104:[2,23],105:[2,23],109:[2,23],117:[2,23],125:[2,23],127:[2,23],128:[2,23],131:[2,23],132:[2,23],133:[2,23],134:[2,23],135:[2,23],136:[2,23]},{1:[2,9],6:[2,9],26:[2,9],101:[2,9],103:[2,9],105:[2,9],109:[2,9],125:[2,9]},{1:[2,10],6:[2,10],26:[2,10],101:[2,10],103:[2,10],105:[2,10],109:[2,10],125:[2,10]},{1:[2,11],6:[2,11],26:[2,11],101:[2,11],103:[2,11],105:[2,11],109:[2,11],125:[2,11]},{1:[2,75],6:[2,75],25:[2,75],26:[2,75],40:[1,103],49:[2,75],54:[2,75],57:[2,75],66:[2,75],67:[2,75],68:[2,75],70:[2,75],72:[2,75],73:[2,75],77:[2,75],83:[2,75],84:[2,75],85:[2,75],90:[2,75],92:[2,75],101:[2,75],103:[2,75],104:[2,75],105:[2,75],109:[2,75],117:[2,75],125:[2,75],127:[2,75],128:[2,75],131:[2,75],132:[2,75],133:[2,75],134:[2,75],135:[2,75],136:[2,75]},{1:[2,76],6:[2,76],25:[2,76],26:[2,76],49:[2,76],54:[2,76],57:[2,76],66:[2,76],67:[2,76],68:[2,76],70:[2,76],72:[2,76],73:[2,76],77:[2,76],83:[2,76],84:[2,76],85:[2,76],90:[2,76],92:[2,76],101:[2,76],103:[2,76],104:[2,76],105:[2,76],109:[2,76],117:[2,76],125:[2,76],127:[2,76],128:[2,76],131:[2,76],132:[2,76],133:[2,76],134:[2,76],135:[2,76],136:[2,76]},{1:[2,77],6:[2,77],25:[2,77],26:[2,77],49:[2,77],54:[2,77],57:[2,77],66:[2,77],67:[2,77],68:[2,77],70:[2,77],72:[2,77],73:[2,77],77:[2,77],83:[2,77],84:[2,77],85:[2,77],90:[2,77],92:[2,77],101:[2,77],103:[2,77],104:[2,77],105:[2,77],109:[2,77],117:[2,77],125:[2,77],127:[2,77],128:[2,77],131:[2,77],132:[2,77],133:[2,77],134:[2,77],135:[2,77],136:[2,77]},{1:[2,78],6:[2,78],25:[2,78],26:[2,78],49:[2,78],54:[2,78],57:[2,78],66:[2,78],67:[2,78],68:[2,78],70:[2,78],72:[2,78],73:[2,78],77:[2,78],83:[2,78],84:[2,78],85:[2,78],90:[2,78],92:[2,78],101:[2,78],103:[2,78],104:[2,78],105:[2,78],109:[2,78],117:[2,78],125:[2,78],127:[2,78],128:[2,78],131:[2,78],132:[2,78],133:[2,78],134:[2,78],135:[2,78],136:[2,78]},{1:[2,79],6:[2,79],25:[2,79],26:[2,79],49:[2,79],54:[2,79],57:[2,79],66:[2,79],67:[2,79],68:[2,79],70:[2,79],72:[2,79],73:[2,79],77:[2,79],83:[2,79],84:[2,79],85:[2,79],90:[2,79],92:[2,79],101:[2,79],103:[2,79],104:[2,79],105:[2,79],109:[2,79],117:[2,79],125:[2,79],127:[2,79],128:[2,79],131:[2,79],132:[2,79],133:[2,79],134:[2,79],135:[2,79],136:[2,79]},{1:[2,105],6:[2,105],25:[2,105],26:[2,105],49:[2,105],54:[2,105],57:[2,105],66:[2,105],67:[2,105],68:[2,105],70:[2,105],72:[2,105],73:[2,105],77:[2,105],81:104,83:[2,105],84:[1,105],85:[2,105],90:[2,105],92:[2,105],101:[2,105],103:[2,105],104:[2,105],105:[2,105],109:[2,105],117:[2,105],125:[2,105],127:[2,105],128:[2,105],131:[2,105],132:[2,105],133:[2,105],134:[2,105],135:[2,105],136:[2,105]},{6:[2,55],25:[2,55],27:109,28:[1,73],44:110,48:106,49:[2,55],54:[2,55],55:107,56:108,58:111,59:112,75:[1,70],88:[1,113],89:[1,114]},{5:115,25:[1,5]},{8:116,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:118,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:119,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{13:121,14:122,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:123,44:63,58:47,59:48,61:120,63:25,64:26,65:27,75:[1,70],82:[1,28],87:[1,58],88:[1,59],89:[1,57],100:[1,56]},{13:121,14:122,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:123,44:63,58:47,59:48,61:124,63:25,64:26,65:27,75:[1,70],82:[1,28],87:[1,58],88:[1,59],89:[1,57],100:[1,56]},{1:[2,72],6:[2,72],25:[2,72],26:[2,72],40:[2,72],49:[2,72],54:[2,72],57:[2,72],66:[2,72],67:[2,72],68:[2,72],70:[2,72],72:[2,72],73:[2,72],77:[2,72],79:[1,128],83:[2,72],84:[2,72],85:[2,72],90:[2,72],92:[2,72],101:[2,72],103:[2,72],104:[2,72],105:[2,72],109:[2,72],117:[2,72],125:[2,72],127:[2,72],128:[2,72],129:[1,125],130:[1,126],131:[2,72],132:[2,72],133:[2,72],134:[2,72],135:[2,72],136:[2,72],137:[1,127]},{1:[2,180],6:[2,180],25:[2,180],26:[2,180],49:[2,180],54:[2,180],57:[2,180],72:[2,180],77:[2,180],85:[2,180],90:[2,180],92:[2,180],101:[2,180],103:[2,180],104:[2,180],105:[2,180],109:[2,180],117:[2,180],120:[1,129],125:[2,180],127:[2,180],128:[2,180],131:[2,180],132:[2,180],133:[2,180],134:[2,180],135:[2,180],136:[2,180]},{5:130,25:[1,5]},{5:131,25:[1,5]},{1:[2,147],6:[2,147],25:[2,147],26:[2,147],49:[2,147],54:[2,147],57:[2,147],72:[2,147],77:[2,147],85:[2,147],90:[2,147],92:[2,147],101:[2,147],103:[2,147],104:[2,147],105:[2,147],109:[2,147],117:[2,147],125:[2,147],127:[2,147],128:[2,147],131:[2,147],132:[2,147],133:[2,147],134:[2,147],135:[2,147],136:[2,147]},{5:132,25:[1,5]},{8:133,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,134],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,95],5:135,6:[2,95],13:121,14:122,25:[1,5],26:[2,95],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:123,44:63,49:[2,95],54:[2,95],57:[2,95],58:47,59:48,61:137,63:25,64:26,65:27,72:[2,95],75:[1,70],77:[2,95],79:[1,136],82:[1,28],85:[2,95],87:[1,58],88:[1,59],89:[1,57],90:[2,95],92:[2,95],100:[1,56],101:[2,95],103:[2,95],104:[2,95],105:[2,95],109:[2,95],117:[2,95],125:[2,95],127:[2,95],128:[2,95],131:[2,95],132:[2,95],133:[2,95],134:[2,95],135:[2,95],136:[2,95]},{8:138,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,47],6:[2,47],8:139,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,26:[2,47],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],101:[2,47],102:39,103:[2,47],105:[2,47],106:40,107:[1,67],108:41,109:[2,47],110:69,118:[1,42],123:37,124:[1,64],125:[2,47],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,48],6:[2,48],25:[2,48],26:[2,48],54:[2,48],77:[2,48],101:[2,48],103:[2,48],105:[2,48],109:[2,48],125:[2,48]},{1:[2,73],6:[2,73],25:[2,73],26:[2,73],40:[2,73],49:[2,73],54:[2,73],57:[2,73],66:[2,73],67:[2,73],68:[2,73],70:[2,73],72:[2,73],73:[2,73],77:[2,73],83:[2,73],84:[2,73],85:[2,73],90:[2,73],92:[2,73],101:[2,73],103:[2,73],104:[2,73],105:[2,73],109:[2,73],117:[2,73],125:[2,73],127:[2,73],128:[2,73],131:[2,73],132:[2,73],133:[2,73],134:[2,73],135:[2,73],136:[2,73]},{1:[2,74],6:[2,74],25:[2,74],26:[2,74],40:[2,74],49:[2,74],54:[2,74],57:[2,74],66:[2,74],67:[2,74],68:[2,74],70:[2,74],72:[2,74],73:[2,74],77:[2,74],83:[2,74],84:[2,74],85:[2,74],90:[2,74],92:[2,74],101:[2,74],103:[2,74],104:[2,74],105:[2,74],109:[2,74],117:[2,74],125:[2,74],127:[2,74],128:[2,74],131:[2,74],132:[2,74],133:[2,74],134:[2,74],135:[2,74],136:[2,74]},{1:[2,29],6:[2,29],25:[2,29],26:[2,29],49:[2,29],54:[2,29],57:[2,29],66:[2,29],67:[2,29],68:[2,29],70:[2,29],72:[2,29],73:[2,29],77:[2,29],83:[2,29],84:[2,29],85:[2,29],90:[2,29],92:[2,29],101:[2,29],103:[2,29],104:[2,29],105:[2,29],109:[2,29],117:[2,29],125:[2,29],127:[2,29],128:[2,29],131:[2,29],132:[2,29],133:[2,29],134:[2,29],135:[2,29],136:[2,29]},{1:[2,30],6:[2,30],25:[2,30],26:[2,30],49:[2,30],54:[2,30],57:[2,30],66:[2,30],67:[2,30],68:[2,30],70:[2,30],72:[2,30],73:[2,30],77:[2,30],83:[2,30],84:[2,30],85:[2,30],90:[2,30],92:[2,30],101:[2,30],103:[2,30],104:[2,30],105:[2,30],109:[2,30],117:[2,30],125:[2,30],127:[2,30],128:[2,30],131:[2,30],132:[2,30],133:[2,30],134:[2,30],135:[2,30],136:[2,30]},{1:[2,31],6:[2,31],25:[2,31],26:[2,31],49:[2,31],54:[2,31],57:[2,31],66:[2,31],67:[2,31],68:[2,31],70:[2,31],72:[2,31],73:[2,31],77:[2,31],83:[2,31],84:[2,31],85:[2,31],90:[2,31],92:[2,31],101:[2,31],103:[2,31],104:[2,31],105:[2,31],109:[2,31],117:[2,31],125:[2,31],127:[2,31],128:[2,31],131:[2,31],132:[2,31],133:[2,31],134:[2,31],135:[2,31],136:[2,31]},{1:[2,32],6:[2,32],25:[2,32],26:[2,32],49:[2,32],54:[2,32],57:[2,32],66:[2,32],67:[2,32],68:[2,32],70:[2,32],72:[2,32],73:[2,32],77:[2,32],83:[2,32],84:[2,32],85:[2,32],90:[2,32],92:[2,32],101:[2,32],103:[2,32],104:[2,32],105:[2,32],109:[2,32],117:[2,32],125:[2,32],127:[2,32],128:[2,32],131:[2,32],132:[2,32],133:[2,32],134:[2,32],135:[2,32],136:[2,32]},{1:[2,33],6:[2,33],25:[2,33],26:[2,33],49:[2,33],54:[2,33],57:[2,33],66:[2,33],67:[2,33],68:[2,33],70:[2,33],72:[2,33],73:[2,33],77:[2,33],83:[2,33],84:[2,33],85:[2,33],90:[2,33],92:[2,33],101:[2,33],103:[2,33],104:[2,33],105:[2,33],109:[2,33],117:[2,33],125:[2,33],127:[2,33],128:[2,33],131:[2,33],132:[2,33],133:[2,33],134:[2,33],135:[2,33],136:[2,33]},{1:[2,34],6:[2,34],25:[2,34],26:[2,34],49:[2,34],54:[2,34],57:[2,34],66:[2,34],67:[2,34],68:[2,34],70:[2,34],72:[2,34],73:[2,34],77:[2,34],83:[2,34],84:[2,34],85:[2,34],90:[2,34],92:[2,34],101:[2,34],103:[2,34],104:[2,34],105:[2,34],109:[2,34],117:[2,34],125:[2,34],127:[2,34],128:[2,34],131:[2,34],132:[2,34],133:[2,34],134:[2,34],135:[2,34],136:[2,34]},{1:[2,35],6:[2,35],25:[2,35],26:[2,35],49:[2,35],54:[2,35],57:[2,35],66:[2,35],67:[2,35],68:[2,35],70:[2,35],72:[2,35],73:[2,35],77:[2,35],83:[2,35],84:[2,35],85:[2,35],90:[2,35],92:[2,35],101:[2,35],103:[2,35],104:[2,35],105:[2,35],109:[2,35],117:[2,35],125:[2,35],127:[2,35],128:[2,35],131:[2,35],132:[2,35],133:[2,35],134:[2,35],135:[2,35],136:[2,35]},{4:140,7:4,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,141],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:142,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,146],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],86:144,87:[1,58],88:[1,59],89:[1,57],90:[1,143],93:145,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,111],6:[2,111],25:[2,111],26:[2,111],49:[2,111],54:[2,111],57:[2,111],66:[2,111],67:[2,111],68:[2,111],70:[2,111],72:[2,111],73:[2,111],77:[2,111],83:[2,111],84:[2,111],85:[2,111],90:[2,111],92:[2,111],101:[2,111],103:[2,111],104:[2,111],105:[2,111],109:[2,111],117:[2,111],125:[2,111],127:[2,111],128:[2,111],131:[2,111],132:[2,111],133:[2,111],134:[2,111],135:[2,111],136:[2,111]},{1:[2,112],6:[2,112],25:[2,112],26:[2,112],27:148,28:[1,73],49:[2,112],54:[2,112],57:[2,112],66:[2,112],67:[2,112],68:[2,112],70:[2,112],72:[2,112],73:[2,112],77:[2,112],83:[2,112],84:[2,112],85:[2,112],90:[2,112],92:[2,112],101:[2,112],103:[2,112],104:[2,112],105:[2,112],109:[2,112],117:[2,112],125:[2,112],127:[2,112],128:[2,112],131:[2,112],132:[2,112],133:[2,112],134:[2,112],135:[2,112],136:[2,112]},{25:[2,51]},{25:[2,52]},{1:[2,68],6:[2,68],25:[2,68],26:[2,68],40:[2,68],49:[2,68],54:[2,68],57:[2,68],66:[2,68],67:[2,68],68:[2,68],70:[2,68],72:[2,68],73:[2,68],77:[2,68],79:[2,68],83:[2,68],84:[2,68],85:[2,68],90:[2,68],92:[2,68],101:[2,68],103:[2,68],104:[2,68],105:[2,68],109:[2,68],117:[2,68],125:[2,68],127:[2,68],128:[2,68],129:[2,68],130:[2,68],131:[2,68],132:[2,68],133:[2,68],134:[2,68],135:[2,68],136:[2,68],137:[2,68]},{1:[2,71],6:[2,71],25:[2,71],26:[2,71],40:[2,71],49:[2,71],54:[2,71],57:[2,71],66:[2,71],67:[2,71],68:[2,71],70:[2,71],72:[2,71],73:[2,71],77:[2,71],79:[2,71],83:[2,71],84:[2,71],85:[2,71],90:[2,71],92:[2,71],101:[2,71],103:[2,71],104:[2,71],105:[2,71],109:[2,71],117:[2,71],125:[2,71],127:[2,71],128:[2,71],129:[2,71],130:[2,71],131:[2,71],132:[2,71],133:[2,71],134:[2,71],135:[2,71],136:[2,71],137:[2,71]},{8:149,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:150,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:151,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{5:152,8:153,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,5],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{27:158,28:[1,73],44:159,58:160,59:161,64:154,75:[1,70],88:[1,113],89:[1,57],112:155,113:[1,156],114:157},{111:162,115:[1,163],116:[1,164]},{6:[2,90],11:168,25:[2,90],27:169,28:[1,73],29:170,30:[1,71],31:[1,72],41:166,42:167,44:171,46:[1,46],54:[2,90],76:165,77:[2,90],88:[1,113]},{1:[2,27],6:[2,27],25:[2,27],26:[2,27],43:[2,27],49:[2,27],54:[2,27],57:[2,27],66:[2,27],67:[2,27],68:[2,27],70:[2,27],72:[2,27],73:[2,27],77:[2,27],83:[2,27],84:[2,27],85:[2,27],90:[2,27],92:[2,27],101:[2,27],103:[2,27],104:[2,27],105:[2,27],109:[2,27],117:[2,27],125:[2,27],127:[2,27],128:[2,27],131:[2,27],132:[2,27],133:[2,27],134:[2,27],135:[2,27],136:[2,27]},{1:[2,28],6:[2,28],25:[2,28],26:[2,28],43:[2,28],49:[2,28],54:[2,28],57:[2,28],66:[2,28],67:[2,28],68:[2,28],70:[2,28],72:[2,28],73:[2,28],77:[2,28],83:[2,28],84:[2,28],85:[2,28],90:[2,28],92:[2,28],101:[2,28],103:[2,28],104:[2,28],105:[2,28],109:[2,28],117:[2,28],125:[2,28],127:[2,28],128:[2,28],131:[2,28],132:[2,28],133:[2,28],134:[2,28],135:[2,28],136:[2,28]},{1:[2,26],6:[2,26],25:[2,26],26:[2,26],40:[2,26],43:[2,26],49:[2,26],54:[2,26],57:[2,26],66:[2,26],67:[2,26],68:[2,26],70:[2,26],72:[2,26],73:[2,26],77:[2,26],79:[2,26],83:[2,26],84:[2,26],85:[2,26],90:[2,26],92:[2,26],101:[2,26],103:[2,26],104:[2,26],105:[2,26],109:[2,26],115:[2,26],116:[2,26],117:[2,26],125:[2,26],127:[2,26],128:[2,26],129:[2,26],130:[2,26],131:[2,26],132:[2,26],133:[2,26],134:[2,26],135:[2,26],136:[2,26],137:[2,26]},{1:[2,6],6:[2,6],7:172,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,26:[2,6],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],101:[2,6],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,3]},{1:[2,24],6:[2,24],25:[2,24],26:[2,24],49:[2,24],54:[2,24],57:[2,24],72:[2,24],77:[2,24],85:[2,24],90:[2,24],92:[2,24],97:[2,24],98:[2,24],101:[2,24],103:[2,24],104:[2,24],105:[2,24],109:[2,24],117:[2,24],120:[2,24],122:[2,24],125:[2,24],127:[2,24],128:[2,24],131:[2,24],132:[2,24],133:[2,24],134:[2,24],135:[2,24],136:[2,24]},{6:[1,74],26:[1,173]},{1:[2,191],6:[2,191],25:[2,191],26:[2,191],49:[2,191],54:[2,191],57:[2,191],72:[2,191],77:[2,191],85:[2,191],90:[2,191],92:[2,191],101:[2,191],103:[2,191],104:[2,191],105:[2,191],109:[2,191],117:[2,191],125:[2,191],127:[2,191],128:[2,191],131:[2,191],132:[2,191],133:[2,191],134:[2,191],135:[2,191],136:[2,191]},{8:174,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:175,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:176,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:177,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:178,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:179,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:180,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:181,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,146],6:[2,146],25:[2,146],26:[2,146],49:[2,146],54:[2,146],57:[2,146],72:[2,146],77:[2,146],85:[2,146],90:[2,146],92:[2,146],101:[2,146],103:[2,146],104:[2,146],105:[2,146],109:[2,146],117:[2,146],125:[2,146],127:[2,146],128:[2,146],131:[2,146],132:[2,146],133:[2,146],134:[2,146],135:[2,146],136:[2,146]},{1:[2,151],6:[2,151],25:[2,151],26:[2,151],49:[2,151],54:[2,151],57:[2,151],72:[2,151],77:[2,151],85:[2,151],90:[2,151],92:[2,151],101:[2,151],103:[2,151],104:[2,151],105:[2,151],109:[2,151],117:[2,151],125:[2,151],127:[2,151],128:[2,151],131:[2,151],132:[2,151],133:[2,151],134:[2,151],135:[2,151],136:[2,151]},{8:182,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,145],6:[2,145],25:[2,145],26:[2,145],49:[2,145],54:[2,145],57:[2,145],72:[2,145],77:[2,145],85:[2,145],90:[2,145],92:[2,145],101:[2,145],103:[2,145],104:[2,145],105:[2,145],109:[2,145],117:[2,145],125:[2,145],127:[2,145],128:[2,145],131:[2,145],132:[2,145],133:[2,145],134:[2,145],135:[2,145],136:[2,145]},{1:[2,150],6:[2,150],25:[2,150],26:[2,150],49:[2,150],54:[2,150],57:[2,150],72:[2,150],77:[2,150],85:[2,150],90:[2,150],92:[2,150],101:[2,150],103:[2,150],104:[2,150],105:[2,150],109:[2,150],117:[2,150],125:[2,150],127:[2,150],128:[2,150],131:[2,150],132:[2,150],133:[2,150],134:[2,150],135:[2,150],136:[2,150]},{81:183,84:[1,105]},{1:[2,69],6:[2,69],25:[2,69],26:[2,69],40:[2,69],49:[2,69],54:[2,69],57:[2,69],66:[2,69],67:[2,69],68:[2,69],70:[2,69],72:[2,69],73:[2,69],77:[2,69],79:[2,69],83:[2,69],84:[2,69],85:[2,69],90:[2,69],92:[2,69],101:[2,69],103:[2,69],104:[2,69],105:[2,69],109:[2,69],117:[2,69],125:[2,69],127:[2,69],128:[2,69],129:[2,69],130:[2,69],131:[2,69],132:[2,69],133:[2,69],134:[2,69],135:[2,69],136:[2,69],137:[2,69]},{84:[2,108]},{27:184,28:[1,73]},{27:185,28:[1,73]},{1:[2,83],6:[2,83],25:[2,83],26:[2,83],27:186,28:[1,73],40:[2,83],49:[2,83],54:[2,83],57:[2,83],66:[2,83],67:[2,83],68:[2,83],70:[2,83],72:[2,83],73:[2,83],77:[2,83],79:[2,83],83:[2,83],84:[2,83],85:[2,83],90:[2,83],92:[2,83],101:[2,83],103:[2,83],104:[2,83],105:[2,83],109:[2,83],117:[2,83],125:[2,83],127:[2,83],128:[2,83],129:[2,83],130:[2,83],131:[2,83],132:[2,83],133:[2,83],134:[2,83],135:[2,83],136:[2,83],137:[2,83]},{1:[2,84],6:[2,84],25:[2,84],26:[2,84],40:[2,84],49:[2,84],54:[2,84],57:[2,84],66:[2,84],67:[2,84],68:[2,84],70:[2,84],72:[2,84],73:[2,84],77:[2,84],79:[2,84],83:[2,84],84:[2,84],85:[2,84],90:[2,84],92:[2,84],101:[2,84],103:[2,84],104:[2,84],105:[2,84],109:[2,84],117:[2,84],125:[2,84],127:[2,84],128:[2,84],129:[2,84],130:[2,84],131:[2,84],132:[2,84],133:[2,84],134:[2,84],135:[2,84],136:[2,84],137:[2,84]},{8:188,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],57:[1,192],58:47,59:48,61:36,63:25,64:26,65:27,71:187,74:189,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],91:190,92:[1,191],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{69:193,70:[1,99],73:[1,100]},{81:194,84:[1,105]},{1:[2,70],6:[2,70],25:[2,70],26:[2,70],40:[2,70],49:[2,70],54:[2,70],57:[2,70],66:[2,70],67:[2,70],68:[2,70],70:[2,70],72:[2,70],73:[2,70],77:[2,70],79:[2,70],83:[2,70],84:[2,70],85:[2,70],90:[2,70],92:[2,70],101:[2,70],103:[2,70],104:[2,70],105:[2,70],109:[2,70],117:[2,70],125:[2,70],127:[2,70],128:[2,70],129:[2,70],130:[2,70],131:[2,70],132:[2,70],133:[2,70],134:[2,70],135:[2,70],136:[2,70],137:[2,70]},{6:[1,196],8:195,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,197],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,106],6:[2,106],25:[2,106],26:[2,106],49:[2,106],54:[2,106],57:[2,106],66:[2,106],67:[2,106],68:[2,106],70:[2,106],72:[2,106],73:[2,106],77:[2,106],83:[2,106],84:[2,106],85:[2,106],90:[2,106],92:[2,106],101:[2,106],103:[2,106],104:[2,106],105:[2,106],109:[2,106],117:[2,106],125:[2,106],127:[2,106],128:[2,106],131:[2,106],132:[2,106],133:[2,106],134:[2,106],135:[2,106],136:[2,106]},{8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,146],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],85:[1,198],86:199,87:[1,58],88:[1,59],89:[1,57],93:145,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,53],25:[2,53],49:[1,201],53:203,54:[1,202]},{6:[2,56],25:[2,56],26:[2,56],49:[2,56],54:[2,56]},{6:[2,60],25:[2,60],26:[2,60],40:[1,205],49:[2,60],54:[2,60],57:[1,204]},{6:[2,63],25:[2,63],26:[2,63],40:[2,63],49:[2,63],54:[2,63],57:[2,63]},{6:[2,64],25:[2,64],26:[2,64],40:[2,64],49:[2,64],54:[2,64],57:[2,64]},{6:[2,65],25:[2,65],26:[2,65],40:[2,65],49:[2,65],54:[2,65],57:[2,65]},{6:[2,66],25:[2,66],26:[2,66],40:[2,66],49:[2,66],54:[2,66],57:[2,66]},{27:148,28:[1,73]},{8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,146],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],86:144,87:[1,58],88:[1,59],89:[1,57],90:[1,143],93:145,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,50],6:[2,50],25:[2,50],26:[2,50],49:[2,50],54:[2,50],57:[2,50],72:[2,50],77:[2,50],85:[2,50],90:[2,50],92:[2,50],101:[2,50],103:[2,50],104:[2,50],105:[2,50],109:[2,50],117:[2,50],125:[2,50],127:[2,50],128:[2,50],131:[2,50],132:[2,50],133:[2,50],134:[2,50],135:[2,50],136:[2,50]},{1:[2,184],6:[2,184],25:[2,184],26:[2,184],49:[2,184],54:[2,184],57:[2,184],72:[2,184],77:[2,184],85:[2,184],90:[2,184],92:[2,184],101:[2,184],102:87,103:[2,184],104:[2,184],105:[2,184],108:88,109:[2,184],110:69,117:[2,184],125:[2,184],127:[2,184],128:[2,184],131:[1,78],132:[2,184],133:[2,184],134:[2,184],135:[2,184],136:[2,184]},{102:90,103:[1,65],105:[1,66],108:91,109:[1,68],110:69,125:[1,89]},{1:[2,185],6:[2,185],25:[2,185],26:[2,185],49:[2,185],54:[2,185],57:[2,185],72:[2,185],77:[2,185],85:[2,185],90:[2,185],92:[2,185],101:[2,185],102:87,103:[2,185],104:[2,185],105:[2,185],108:88,109:[2,185],110:69,117:[2,185],125:[2,185],127:[2,185],128:[2,185],131:[1,78],132:[2,185],133:[2,185],134:[2,185],135:[2,185],136:[2,185]},{1:[2,186],6:[2,186],25:[2,186],26:[2,186],49:[2,186],54:[2,186],57:[2,186],72:[2,186],77:[2,186],85:[2,186],90:[2,186],92:[2,186],101:[2,186],102:87,103:[2,186],104:[2,186],105:[2,186],108:88,109:[2,186],110:69,117:[2,186],125:[2,186],127:[2,186],128:[2,186],131:[1,78],132:[2,186],133:[2,186],134:[2,186],135:[2,186],136:[2,186]},{1:[2,187],6:[2,187],25:[2,187],26:[2,187],49:[2,187],54:[2,187],57:[2,187],66:[2,72],67:[2,72],68:[2,72],70:[2,72],72:[2,187],73:[2,72],77:[2,187],83:[2,72],84:[2,72],85:[2,187],90:[2,187],92:[2,187],101:[2,187],103:[2,187],104:[2,187],105:[2,187],109:[2,187],117:[2,187],125:[2,187],127:[2,187],128:[2,187],131:[2,187],132:[2,187],133:[2,187],134:[2,187],135:[2,187],136:[2,187]},{62:93,66:[1,95],67:[1,96],68:[1,97],69:98,70:[1,99],73:[1,100],80:92,83:[1,94],84:[2,107]},{62:102,66:[1,95],67:[1,96],68:[1,97],69:98,70:[1,99],73:[1,100],80:101,83:[1,94],84:[2,107]},{66:[2,75],67:[2,75],68:[2,75],70:[2,75],73:[2,75],83:[2,75],84:[2,75]},{1:[2,188],6:[2,188],25:[2,188],26:[2,188],49:[2,188],54:[2,188],57:[2,188],66:[2,72],67:[2,72],68:[2,72],70:[2,72],72:[2,188],73:[2,72],77:[2,188],83:[2,72],84:[2,72],85:[2,188],90:[2,188],92:[2,188],101:[2,188],103:[2,188],104:[2,188],105:[2,188],109:[2,188],117:[2,188],125:[2,188],127:[2,188],128:[2,188],131:[2,188],132:[2,188],133:[2,188],134:[2,188],135:[2,188],136:[2,188]},{1:[2,189],6:[2,189],25:[2,189],26:[2,189],49:[2,189],54:[2,189],57:[2,189],72:[2,189],77:[2,189],85:[2,189],90:[2,189],92:[2,189],101:[2,189],103:[2,189],104:[2,189],105:[2,189],109:[2,189],117:[2,189],125:[2,189],127:[2,189],128:[2,189],131:[2,189],132:[2,189],133:[2,189],134:[2,189],135:[2,189],136:[2,189]},{1:[2,190],6:[2,190],25:[2,190],26:[2,190],49:[2,190],54:[2,190],57:[2,190],72:[2,190],77:[2,190],85:[2,190],90:[2,190],92:[2,190],101:[2,190],103:[2,190],104:[2,190],105:[2,190],109:[2,190],117:[2,190],125:[2,190],127:[2,190],128:[2,190],131:[2,190],132:[2,190],133:[2,190],134:[2,190],135:[2,190],136:[2,190]},{8:206,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,207],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:208,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{5:209,25:[1,5],124:[1,210]},{1:[2,132],6:[2,132],25:[2,132],26:[2,132],49:[2,132],54:[2,132],57:[2,132],72:[2,132],77:[2,132],85:[2,132],90:[2,132],92:[2,132],96:211,97:[1,212],98:[1,213],101:[2,132],103:[2,132],104:[2,132],105:[2,132],109:[2,132],117:[2,132],125:[2,132],127:[2,132],128:[2,132],131:[2,132],132:[2,132],133:[2,132],134:[2,132],135:[2,132],136:[2,132]},{1:[2,144],6:[2,144],25:[2,144],26:[2,144],49:[2,144],54:[2,144],57:[2,144],72:[2,144],77:[2,144],85:[2,144],90:[2,144],92:[2,144],101:[2,144],103:[2,144],104:[2,144],105:[2,144],109:[2,144],117:[2,144],125:[2,144],127:[2,144],128:[2,144],131:[2,144],132:[2,144],133:[2,144],134:[2,144],135:[2,144],136:[2,144]},{1:[2,152],6:[2,152],25:[2,152],26:[2,152],49:[2,152],54:[2,152],57:[2,152],72:[2,152],77:[2,152],85:[2,152],90:[2,152],92:[2,152],101:[2,152],103:[2,152],104:[2,152],105:[2,152],109:[2,152],117:[2,152],125:[2,152],127:[2,152],128:[2,152],131:[2,152],132:[2,152],133:[2,152],134:[2,152],135:[2,152],136:[2,152]},{25:[1,214],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{119:215,121:216,122:[1,217]},{1:[2,96],6:[2,96],25:[2,96],26:[2,96],49:[2,96],54:[2,96],57:[2,96],72:[2,96],77:[2,96],85:[2,96],90:[2,96],92:[2,96],101:[2,96],103:[2,96],104:[2,96],105:[2,96],109:[2,96],117:[2,96],125:[2,96],127:[2,96],128:[2,96],131:[2,96],132:[2,96],133:[2,96],134:[2,96],135:[2,96],136:[2,96]},{8:218,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,99],5:219,6:[2,99],25:[1,5],26:[2,99],49:[2,99],54:[2,99],57:[2,99],66:[2,72],67:[2,72],68:[2,72],70:[2,72],72:[2,99],73:[2,72],77:[2,99],79:[1,220],83:[2,72],84:[2,72],85:[2,99],90:[2,99],92:[2,99],101:[2,99],103:[2,99],104:[2,99],105:[2,99],109:[2,99],117:[2,99],125:[2,99],127:[2,99],128:[2,99],131:[2,99],132:[2,99],133:[2,99],134:[2,99],135:[2,99],136:[2,99]},{1:[2,137],6:[2,137],25:[2,137],26:[2,137],49:[2,137],54:[2,137],57:[2,137],72:[2,137],77:[2,137],85:[2,137],90:[2,137],92:[2,137],101:[2,137],102:87,103:[2,137],104:[2,137],105:[2,137],108:88,109:[2,137],110:69,117:[2,137],125:[2,137],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,46],6:[2,46],26:[2,46],101:[2,46],102:87,103:[2,46],105:[2,46],108:88,109:[2,46],110:69,125:[2,46],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[1,74],101:[1,221]},{4:222,7:4,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,128],25:[2,128],54:[2,128],57:[1,224],90:[2,128],91:223,92:[1,191],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,114],6:[2,114],25:[2,114],26:[2,114],40:[2,114],49:[2,114],54:[2,114],57:[2,114],66:[2,114],67:[2,114],68:[2,114],70:[2,114],72:[2,114],73:[2,114],77:[2,114],83:[2,114],84:[2,114],85:[2,114],90:[2,114],92:[2,114],101:[2,114],103:[2,114],104:[2,114],105:[2,114],109:[2,114],115:[2,114],116:[2,114],117:[2,114],125:[2,114],127:[2,114],128:[2,114],131:[2,114],132:[2,114],133:[2,114],134:[2,114],135:[2,114],136:[2,114]},{6:[2,53],25:[2,53],53:225,54:[1,226],90:[2,53]},{6:[2,123],25:[2,123],26:[2,123],54:[2,123],85:[2,123],90:[2,123]},{8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,146],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],86:227,87:[1,58],88:[1,59],89:[1,57],93:145,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,129],25:[2,129],26:[2,129],54:[2,129],85:[2,129],90:[2,129]},{1:[2,113],6:[2,113],25:[2,113],26:[2,113],40:[2,113],43:[2,113],49:[2,113],54:[2,113],57:[2,113],66:[2,113],67:[2,113],68:[2,113],70:[2,113],72:[2,113],73:[2,113],77:[2,113],79:[2,113],83:[2,113],84:[2,113],85:[2,113],90:[2,113],92:[2,113],101:[2,113],103:[2,113],104:[2,113],105:[2,113],109:[2,113],115:[2,113],116:[2,113],117:[2,113],125:[2,113],127:[2,113],128:[2,113],129:[2,113],130:[2,113],131:[2,113],132:[2,113],133:[2,113],134:[2,113],135:[2,113],136:[2,113],137:[2,113]},{5:228,25:[1,5],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,140],6:[2,140],25:[2,140],26:[2,140],49:[2,140],54:[2,140],57:[2,140],72:[2,140],77:[2,140],85:[2,140],90:[2,140],92:[2,140],101:[2,140],102:87,103:[1,65],104:[1,229],105:[1,66],108:88,109:[1,68],110:69,117:[2,140],125:[2,140],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,142],6:[2,142],25:[2,142],26:[2,142],49:[2,142],54:[2,142],57:[2,142],72:[2,142],77:[2,142],85:[2,142],90:[2,142],92:[2,142],101:[2,142],102:87,103:[1,65],104:[1,230],105:[1,66],108:88,109:[1,68],110:69,117:[2,142],125:[2,142],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,148],6:[2,148],25:[2,148],26:[2,148],49:[2,148],54:[2,148],57:[2,148],72:[2,148],77:[2,148],85:[2,148],90:[2,148],92:[2,148],101:[2,148],103:[2,148],104:[2,148],105:[2,148],109:[2,148],117:[2,148],125:[2,148],127:[2,148],128:[2,148],131:[2,148],132:[2,148],133:[2,148],134:[2,148],135:[2,148],136:[2,148]},{1:[2,149],6:[2,149],25:[2,149],26:[2,149],49:[2,149],54:[2,149],57:[2,149],72:[2,149],77:[2,149],85:[2,149],90:[2,149],92:[2,149],101:[2,149],102:87,103:[1,65],104:[2,149],105:[1,66],108:88,109:[1,68],110:69,117:[2,149],125:[2,149],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,153],6:[2,153],25:[2,153],26:[2,153],49:[2,153],54:[2,153],57:[2,153],72:[2,153],77:[2,153],85:[2,153],90:[2,153],92:[2,153],101:[2,153],103:[2,153],104:[2,153],105:[2,153],109:[2,153],117:[2,153],125:[2,153],127:[2,153],128:[2,153],131:[2,153],132:[2,153],133:[2,153],134:[2,153],135:[2,153],136:[2,153]},{115:[2,155],116:[2,155]},{27:158,28:[1,73],44:159,58:160,59:161,75:[1,70],88:[1,113],89:[1,114],112:231,114:157},{54:[1,232],115:[2,161],116:[2,161]},{54:[2,157],115:[2,157],116:[2,157]},{54:[2,158],115:[2,158],116:[2,158]},{54:[2,159],115:[2,159],116:[2,159]},{54:[2,160],115:[2,160],116:[2,160]},{1:[2,154],6:[2,154],25:[2,154],26:[2,154],49:[2,154],54:[2,154],57:[2,154],72:[2,154],77:[2,154],85:[2,154],90:[2,154],92:[2,154],101:[2,154],103:[2,154],104:[2,154],105:[2,154],109:[2,154],117:[2,154],125:[2,154],127:[2,154],128:[2,154],131:[2,154],132:[2,154],133:[2,154],134:[2,154],135:[2,154],136:[2,154]},{8:233,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:234,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,53],25:[2,53],53:235,54:[1,236],77:[2,53]},{6:[2,91],25:[2,91],26:[2,91],54:[2,91],77:[2,91]},{6:[2,39],25:[2,39],26:[2,39],43:[1,237],54:[2,39],77:[2,39]},{6:[2,42],25:[2,42],26:[2,42],54:[2,42],77:[2,42]},{6:[2,43],25:[2,43],26:[2,43],43:[2,43],54:[2,43],77:[2,43]},{6:[2,44],25:[2,44],26:[2,44],43:[2,44],54:[2,44],77:[2,44]},{6:[2,45],25:[2,45],26:[2,45],43:[2,45],54:[2,45],77:[2,45]},{1:[2,5],6:[2,5],26:[2,5],101:[2,5]},{1:[2,25],6:[2,25],25:[2,25],26:[2,25],49:[2,25],54:[2,25],57:[2,25],72:[2,25],77:[2,25],85:[2,25],90:[2,25],92:[2,25],97:[2,25],98:[2,25],101:[2,25],103:[2,25],104:[2,25],105:[2,25],109:[2,25],117:[2,25],120:[2,25],122:[2,25],125:[2,25],127:[2,25],128:[2,25],131:[2,25],132:[2,25],133:[2,25],134:[2,25],135:[2,25],136:[2,25]},{1:[2,192],6:[2,192],25:[2,192],26:[2,192],49:[2,192],54:[2,192],57:[2,192],72:[2,192],77:[2,192],85:[2,192],90:[2,192],92:[2,192],101:[2,192],102:87,103:[2,192],104:[2,192],105:[2,192],108:88,109:[2,192],110:69,117:[2,192],125:[2,192],127:[2,192],128:[2,192],131:[1,78],132:[1,81],133:[2,192],134:[2,192],135:[2,192],136:[2,192]},{1:[2,193],6:[2,193],25:[2,193],26:[2,193],49:[2,193],54:[2,193],57:[2,193],72:[2,193],77:[2,193],85:[2,193],90:[2,193],92:[2,193],101:[2,193],102:87,103:[2,193],104:[2,193],105:[2,193],108:88,109:[2,193],110:69,117:[2,193],125:[2,193],127:[2,193],128:[2,193],131:[1,78],132:[1,81],133:[2,193],134:[2,193],135:[2,193],136:[2,193]},{1:[2,194],6:[2,194],25:[2,194],26:[2,194],49:[2,194],54:[2,194],57:[2,194],72:[2,194],77:[2,194],85:[2,194],90:[2,194],92:[2,194],101:[2,194],102:87,103:[2,194],104:[2,194],105:[2,194],108:88,109:[2,194],110:69,117:[2,194],125:[2,194],127:[2,194],128:[2,194],131:[1,78],132:[2,194],133:[2,194],134:[2,194],135:[2,194],136:[2,194]},{1:[2,195],6:[2,195],25:[2,195],26:[2,195],49:[2,195],54:[2,195],57:[2,195],72:[2,195],77:[2,195],85:[2,195],90:[2,195],92:[2,195],101:[2,195],102:87,103:[2,195],104:[2,195],105:[2,195],108:88,109:[2,195],110:69,117:[2,195],125:[2,195],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[2,195],134:[2,195],135:[2,195],136:[2,195]},{1:[2,196],6:[2,196],25:[2,196],26:[2,196],49:[2,196],54:[2,196],57:[2,196],72:[2,196],77:[2,196],85:[2,196],90:[2,196],92:[2,196],101:[2,196],102:87,103:[2,196],104:[2,196],105:[2,196],108:88,109:[2,196],110:69,117:[2,196],125:[2,196],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[2,196],135:[2,196],136:[1,85]},{1:[2,197],6:[2,197],25:[2,197],26:[2,197],49:[2,197],54:[2,197],57:[2,197],72:[2,197],77:[2,197],85:[2,197],90:[2,197],92:[2,197],101:[2,197],102:87,103:[2,197],104:[2,197],105:[2,197],108:88,109:[2,197],110:69,117:[2,197],125:[2,197],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[2,197],136:[1,85]},{1:[2,198],6:[2,198],25:[2,198],26:[2,198],49:[2,198],54:[2,198],57:[2,198],72:[2,198],77:[2,198],85:[2,198],90:[2,198],92:[2,198],101:[2,198],102:87,103:[2,198],104:[2,198],105:[2,198],108:88,109:[2,198],110:69,117:[2,198],125:[2,198],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[2,198],135:[2,198],136:[2,198]},{1:[2,183],6:[2,183],25:[2,183],26:[2,183],49:[2,183],54:[2,183],57:[2,183],72:[2,183],77:[2,183],85:[2,183],90:[2,183],92:[2,183],101:[2,183],102:87,103:[1,65],104:[2,183],105:[1,66],108:88,109:[1,68],110:69,117:[2,183],125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,182],6:[2,182],25:[2,182],26:[2,182],49:[2,182],54:[2,182],57:[2,182],72:[2,182],77:[2,182],85:[2,182],90:[2,182],92:[2,182],101:[2,182],102:87,103:[1,65],104:[2,182],105:[1,66],108:88,109:[1,68],110:69,117:[2,182],125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,103],6:[2,103],25:[2,103],26:[2,103],49:[2,103],54:[2,103],57:[2,103],66:[2,103],67:[2,103],68:[2,103],70:[2,103],72:[2,103],73:[2,103],77:[2,103],83:[2,103],84:[2,103],85:[2,103],90:[2,103],92:[2,103],101:[2,103],103:[2,103],104:[2,103],105:[2,103],109:[2,103],117:[2,103],125:[2,103],127:[2,103],128:[2,103],131:[2,103],132:[2,103],133:[2,103],134:[2,103],135:[2,103],136:[2,103]},{1:[2,80],6:[2,80],25:[2,80],26:[2,80],40:[2,80],49:[2,80],54:[2,80],57:[2,80],66:[2,80],67:[2,80],68:[2,80],70:[2,80],72:[2,80],73:[2,80],77:[2,80],79:[2,80],83:[2,80],84:[2,80],85:[2,80],90:[2,80],92:[2,80],101:[2,80],103:[2,80],104:[2,80],105:[2,80],109:[2,80],117:[2,80],125:[2,80],127:[2,80],128:[2,80],129:[2,80],130:[2,80],131:[2,80],132:[2,80],133:[2,80],134:[2,80],135:[2,80],136:[2,80],137:[2,80]},{1:[2,81],6:[2,81],25:[2,81],26:[2,81],40:[2,81],49:[2,81],54:[2,81],57:[2,81],66:[2,81],67:[2,81],68:[2,81],70:[2,81],72:[2,81],73:[2,81],77:[2,81],79:[2,81],83:[2,81],84:[2,81],85:[2,81],90:[2,81],92:[2,81],101:[2,81],103:[2,81],104:[2,81],105:[2,81],109:[2,81],117:[2,81],125:[2,81],127:[2,81],128:[2,81],129:[2,81],130:[2,81],131:[2,81],132:[2,81],133:[2,81],134:[2,81],135:[2,81],136:[2,81],137:[2,81]},{1:[2,82],6:[2,82],25:[2,82],26:[2,82],40:[2,82],49:[2,82],54:[2,82],57:[2,82],66:[2,82],67:[2,82],68:[2,82],70:[2,82],72:[2,82],73:[2,82],77:[2,82],79:[2,82],83:[2,82],84:[2,82],85:[2,82],90:[2,82],92:[2,82],101:[2,82],103:[2,82],104:[2,82],105:[2,82],109:[2,82],117:[2,82],125:[2,82],127:[2,82],128:[2,82],129:[2,82],130:[2,82],131:[2,82],132:[2,82],133:[2,82],134:[2,82],135:[2,82],136:[2,82],137:[2,82]},{72:[1,238]},{57:[1,192],72:[2,87],91:239,92:[1,191],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{72:[2,88]},{8:240,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,72:[2,122],75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{12:[2,116],28:[2,116],30:[2,116],31:[2,116],33:[2,116],34:[2,116],35:[2,116],36:[2,116],37:[2,116],38:[2,116],45:[2,116],46:[2,116],47:[2,116],51:[2,116],52:[2,116],72:[2,116],75:[2,116],78:[2,116],82:[2,116],87:[2,116],88:[2,116],89:[2,116],95:[2,116],99:[2,116],100:[2,116],103:[2,116],105:[2,116],107:[2,116],109:[2,116],118:[2,116],124:[2,116],126:[2,116],127:[2,116],128:[2,116],129:[2,116],130:[2,116]},{12:[2,117],28:[2,117],30:[2,117],31:[2,117],33:[2,117],34:[2,117],35:[2,117],36:[2,117],37:[2,117],38:[2,117],45:[2,117],46:[2,117],47:[2,117],51:[2,117],52:[2,117],72:[2,117],75:[2,117],78:[2,117],82:[2,117],87:[2,117],88:[2,117],89:[2,117],95:[2,117],99:[2,117],100:[2,117],103:[2,117],105:[2,117],107:[2,117],109:[2,117],118:[2,117],124:[2,117],126:[2,117],127:[2,117],128:[2,117],129:[2,117],130:[2,117]},{1:[2,86],6:[2,86],25:[2,86],26:[2,86],40:[2,86],49:[2,86],54:[2,86],57:[2,86],66:[2,86],67:[2,86],68:[2,86],70:[2,86],72:[2,86],73:[2,86],77:[2,86],79:[2,86],83:[2,86],84:[2,86],85:[2,86],90:[2,86],92:[2,86],101:[2,86],103:[2,86],104:[2,86],105:[2,86],109:[2,86],117:[2,86],125:[2,86],127:[2,86],128:[2,86],129:[2,86],130:[2,86],131:[2,86],132:[2,86],133:[2,86],134:[2,86],135:[2,86],136:[2,86],137:[2,86]},{1:[2,104],6:[2,104],25:[2,104],26:[2,104],49:[2,104],54:[2,104],57:[2,104],66:[2,104],67:[2,104],68:[2,104],70:[2,104],72:[2,104],73:[2,104],77:[2,104],83:[2,104],84:[2,104],85:[2,104],90:[2,104],92:[2,104],101:[2,104],103:[2,104],104:[2,104],105:[2,104],109:[2,104],117:[2,104],125:[2,104],127:[2,104],128:[2,104],131:[2,104],132:[2,104],133:[2,104],134:[2,104],135:[2,104],136:[2,104]},{1:[2,36],6:[2,36],25:[2,36],26:[2,36],49:[2,36],54:[2,36],57:[2,36],72:[2,36],77:[2,36],85:[2,36],90:[2,36],92:[2,36],101:[2,36],102:87,103:[2,36],104:[2,36],105:[2,36],108:88,109:[2,36],110:69,117:[2,36],125:[2,36],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{8:241,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:242,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,109],6:[2,109],25:[2,109],26:[2,109],49:[2,109],54:[2,109],57:[2,109],66:[2,109],67:[2,109],68:[2,109],70:[2,109],72:[2,109],73:[2,109],77:[2,109],83:[2,109],84:[2,109],85:[2,109],90:[2,109],92:[2,109],101:[2,109],103:[2,109],104:[2,109],105:[2,109],109:[2,109],117:[2,109],125:[2,109],127:[2,109],128:[2,109],131:[2,109],132:[2,109],133:[2,109],134:[2,109],135:[2,109],136:[2,109]},{6:[2,53],25:[2,53],53:243,54:[1,226],85:[2,53]},{6:[2,128],25:[2,128],26:[2,128],54:[2,128],57:[1,244],85:[2,128],90:[2,128],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{50:245,51:[1,60],52:[1,61]},{6:[2,54],25:[2,54],26:[2,54],27:109,28:[1,73],44:110,55:246,56:108,58:111,59:112,75:[1,70],88:[1,113],89:[1,114]},{6:[1,247],25:[1,248]},{6:[2,61],25:[2,61],26:[2,61],49:[2,61],54:[2,61]},{8:249,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,199],6:[2,199],25:[2,199],26:[2,199],49:[2,199],54:[2,199],57:[2,199],72:[2,199],77:[2,199],85:[2,199],90:[2,199],92:[2,199],101:[2,199],102:87,103:[2,199],104:[2,199],105:[2,199],108:88,109:[2,199],110:69,117:[2,199],125:[2,199],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{8:250,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,201],6:[2,201],25:[2,201],26:[2,201],49:[2,201],54:[2,201],57:[2,201],72:[2,201],77:[2,201],85:[2,201],90:[2,201],92:[2,201],101:[2,201],102:87,103:[2,201],104:[2,201],105:[2,201],108:88,109:[2,201],110:69,117:[2,201],125:[2,201],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,181],6:[2,181],25:[2,181],26:[2,181],49:[2,181],54:[2,181],57:[2,181],72:[2,181],77:[2,181],85:[2,181],90:[2,181],92:[2,181],101:[2,181],103:[2,181],104:[2,181],105:[2,181],109:[2,181],117:[2,181],125:[2,181],127:[2,181],128:[2,181],131:[2,181],132:[2,181],133:[2,181],134:[2,181],135:[2,181],136:[2,181]},{8:251,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,133],6:[2,133],25:[2,133],26:[2,133],49:[2,133],54:[2,133],57:[2,133],72:[2,133],77:[2,133],85:[2,133],90:[2,133],92:[2,133],97:[1,252],101:[2,133],103:[2,133],104:[2,133],105:[2,133],109:[2,133],117:[2,133],125:[2,133],127:[2,133],128:[2,133],131:[2,133],132:[2,133],133:[2,133],134:[2,133],135:[2,133],136:[2,133]},{5:253,25:[1,5]},{27:254,28:[1,73]},{119:255,121:216,122:[1,217]},{26:[1,256],120:[1,257],121:258,122:[1,217]},{26:[2,174],120:[2,174],122:[2,174]},{8:260,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],94:259,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,97],5:261,6:[2,97],25:[1,5],26:[2,97],49:[2,97],54:[2,97],57:[2,97],72:[2,97],77:[2,97],85:[2,97],90:[2,97],92:[2,97],101:[2,97],102:87,103:[1,65],104:[2,97],105:[1,66],108:88,109:[1,68],110:69,117:[2,97],125:[2,97],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,100],6:[2,100],25:[2,100],26:[2,100],49:[2,100],54:[2,100],57:[2,100],72:[2,100],77:[2,100],85:[2,100],90:[2,100],92:[2,100],101:[2,100],103:[2,100],104:[2,100],105:[2,100],109:[2,100],117:[2,100],125:[2,100],127:[2,100],128:[2,100],131:[2,100],132:[2,100],133:[2,100],134:[2,100],135:[2,100],136:[2,100]},{8:262,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,138],6:[2,138],25:[2,138],26:[2,138],49:[2,138],54:[2,138],57:[2,138],66:[2,138],67:[2,138],68:[2,138],70:[2,138],72:[2,138],73:[2,138],77:[2,138],83:[2,138],84:[2,138],85:[2,138],90:[2,138],92:[2,138],101:[2,138],103:[2,138],104:[2,138],105:[2,138],109:[2,138],117:[2,138],125:[2,138],127:[2,138],128:[2,138],131:[2,138],132:[2,138],133:[2,138],134:[2,138],135:[2,138],136:[2,138]},{6:[1,74],26:[1,263]},{8:264,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,67],12:[2,117],25:[2,67],28:[2,117],30:[2,117],31:[2,117],33:[2,117],34:[2,117],35:[2,117],36:[2,117],37:[2,117],38:[2,117],45:[2,117],46:[2,117],47:[2,117],51:[2,117],52:[2,117],54:[2,67],75:[2,117],78:[2,117],82:[2,117],87:[2,117],88:[2,117],89:[2,117],90:[2,67],95:[2,117],99:[2,117],100:[2,117],103:[2,117],105:[2,117],107:[2,117],109:[2,117],118:[2,117],124:[2,117],126:[2,117],127:[2,117],128:[2,117],129:[2,117],130:[2,117]},{6:[1,266],25:[1,267],90:[1,265]},{6:[2,54],8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[2,54],26:[2,54],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],85:[2,54],87:[1,58],88:[1,59],89:[1,57],90:[2,54],93:268,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,53],25:[2,53],26:[2,53],53:269,54:[1,226]},{1:[2,178],6:[2,178],25:[2,178],26:[2,178],49:[2,178],54:[2,178],57:[2,178],72:[2,178],77:[2,178],85:[2,178],90:[2,178],92:[2,178],101:[2,178],103:[2,178],104:[2,178],105:[2,178],109:[2,178],117:[2,178],120:[2,178],125:[2,178],127:[2,178],128:[2,178],131:[2,178],132:[2,178],133:[2,178],134:[2,178],135:[2,178],136:[2,178]},{8:270,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:271,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{115:[2,156],116:[2,156]},{27:158,28:[1,73],44:159,58:160,59:161,75:[1,70],88:[1,113],89:[1,114],114:272},{1:[2,163],6:[2,163],25:[2,163],26:[2,163],49:[2,163],54:[2,163],57:[2,163],72:[2,163],77:[2,163],85:[2,163],90:[2,163],92:[2,163],101:[2,163],102:87,103:[2,163],104:[1,273],105:[2,163],108:88,109:[2,163],110:69,117:[1,274],125:[2,163],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,164],6:[2,164],25:[2,164],26:[2,164],49:[2,164],54:[2,164],57:[2,164],72:[2,164],77:[2,164],85:[2,164],90:[2,164],92:[2,164],101:[2,164],102:87,103:[2,164],104:[1,275],105:[2,164],108:88,109:[2,164],110:69,117:[2,164],125:[2,164],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[1,277],25:[1,278],77:[1,276]},{6:[2,54],11:168,25:[2,54],26:[2,54],27:169,28:[1,73],29:170,30:[1,71],31:[1,72],41:279,42:167,44:171,46:[1,46],77:[2,54],88:[1,113]},{8:280,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,281],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,85],6:[2,85],25:[2,85],26:[2,85],40:[2,85],49:[2,85],54:[2,85],57:[2,85],66:[2,85],67:[2,85],68:[2,85],70:[2,85],72:[2,85],73:[2,85],77:[2,85],79:[2,85],83:[2,85],84:[2,85],85:[2,85],90:[2,85],92:[2,85],101:[2,85],103:[2,85],104:[2,85],105:[2,85],109:[2,85],117:[2,85],125:[2,85],127:[2,85],128:[2,85],129:[2,85],130:[2,85],131:[2,85],132:[2,85],133:[2,85],134:[2,85],135:[2,85],136:[2,85],137:[2,85]},{8:282,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,72:[2,120],75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{72:[2,121],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,37],6:[2,37],25:[2,37],26:[2,37],49:[2,37],54:[2,37],57:[2,37],72:[2,37],77:[2,37],85:[2,37],90:[2,37],92:[2,37],101:[2,37],102:87,103:[2,37],104:[2,37],105:[2,37],108:88,109:[2,37],110:69,117:[2,37],125:[2,37],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{26:[1,283],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[1,266],25:[1,267],85:[1,284]},{6:[2,67],25:[2,67],26:[2,67],54:[2,67],85:[2,67],90:[2,67]},{5:285,25:[1,5]},{6:[2,57],25:[2,57],26:[2,57],49:[2,57],54:[2,57]},{27:109,28:[1,73],44:110,55:286,56:108,58:111,59:112,75:[1,70],88:[1,113],89:[1,114]},{6:[2,55],25:[2,55],26:[2,55],27:109,28:[1,73],44:110,48:287,54:[2,55],55:107,56:108,58:111,59:112,75:[1,70],88:[1,113],89:[1,114]},{6:[2,62],25:[2,62],26:[2,62],49:[2,62],54:[2,62],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{26:[1,288],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{5:289,25:[1,5],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{5:290,25:[1,5]},{1:[2,134],6:[2,134],25:[2,134],26:[2,134],49:[2,134],54:[2,134],57:[2,134],72:[2,134],77:[2,134],85:[2,134],90:[2,134],92:[2,134],101:[2,134],103:[2,134],104:[2,134],105:[2,134],109:[2,134],117:[2,134],125:[2,134],127:[2,134],128:[2,134],131:[2,134],132:[2,134],133:[2,134],134:[2,134],135:[2,134],136:[2,134]},{5:291,25:[1,5]},{26:[1,292],120:[1,293],121:258,122:[1,217]},{1:[2,172],6:[2,172],25:[2,172],26:[2,172],49:[2,172],54:[2,172],57:[2,172],72:[2,172],77:[2,172],85:[2,172],90:[2,172],92:[2,172],101:[2,172],103:[2,172],104:[2,172],105:[2,172],109:[2,172],117:[2,172],125:[2,172],127:[2,172],128:[2,172],131:[2,172],132:[2,172],133:[2,172],134:[2,172],135:[2,172],136:[2,172]},{5:294,25:[1,5]},{26:[2,175],120:[2,175],122:[2,175]},{5:295,25:[1,5],54:[1,296]},{25:[2,130],54:[2,130],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,98],6:[2,98],25:[2,98],26:[2,98],49:[2,98],54:[2,98],57:[2,98],72:[2,98],77:[2,98],85:[2,98],90:[2,98],92:[2,98],101:[2,98],103:[2,98],104:[2,98],105:[2,98],109:[2,98],117:[2,98],125:[2,98],127:[2,98],128:[2,98],131:[2,98],132:[2,98],133:[2,98],134:[2,98],135:[2,98],136:[2,98]},{1:[2,101],5:297,6:[2,101],25:[1,5],26:[2,101],49:[2,101],54:[2,101],57:[2,101],72:[2,101],77:[2,101],85:[2,101],90:[2,101],92:[2,101],101:[2,101],102:87,103:[1,65],104:[2,101],105:[1,66],108:88,109:[1,68],110:69,117:[2,101],125:[2,101],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{101:[1,298]},{90:[1,299],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,115],6:[2,115],25:[2,115],26:[2,115],40:[2,115],49:[2,115],54:[2,115],57:[2,115],66:[2,115],67:[2,115],68:[2,115],70:[2,115],72:[2,115],73:[2,115],77:[2,115],83:[2,115],84:[2,115],85:[2,115],90:[2,115],92:[2,115],101:[2,115],103:[2,115],104:[2,115],105:[2,115],109:[2,115],115:[2,115],116:[2,115],117:[2,115],125:[2,115],127:[2,115],128:[2,115],131:[2,115],132:[2,115],133:[2,115],134:[2,115],135:[2,115],136:[2,115]},{8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],93:300,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,146],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],86:301,87:[1,58],88:[1,59],89:[1,57],93:145,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,124],25:[2,124],26:[2,124],54:[2,124],85:[2,124],90:[2,124]},{6:[1,266],25:[1,267],26:[1,302]},{1:[2,141],6:[2,141],25:[2,141],26:[2,141],49:[2,141],54:[2,141],57:[2,141],72:[2,141],77:[2,141],85:[2,141],90:[2,141],92:[2,141],101:[2,141],102:87,103:[1,65],104:[2,141],105:[1,66],108:88,109:[1,68],110:69,117:[2,141],125:[2,141],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,143],6:[2,143],25:[2,143],26:[2,143],49:[2,143],54:[2,143],57:[2,143],72:[2,143],77:[2,143],85:[2,143],90:[2,143],92:[2,143],101:[2,143],102:87,103:[1,65],104:[2,143],105:[1,66],108:88,109:[1,68],110:69,117:[2,143],125:[2,143],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{115:[2,162],116:[2,162]},{8:303,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:304,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:305,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,89],6:[2,89],25:[2,89],26:[2,89],40:[2,89],49:[2,89],54:[2,89],57:[2,89],66:[2,89],67:[2,89],68:[2,89],70:[2,89],72:[2,89],73:[2,89],77:[2,89],83:[2,89],84:[2,89],85:[2,89],90:[2,89],92:[2,89],101:[2,89],103:[2,89],104:[2,89],105:[2,89],109:[2,89],115:[2,89],116:[2,89],117:[2,89],125:[2,89],127:[2,89],128:[2,89],131:[2,89],132:[2,89],133:[2,89],134:[2,89],135:[2,89],136:[2,89]},{11:168,27:169,28:[1,73],29:170,30:[1,71],31:[1,72],41:306,42:167,44:171,46:[1,46],88:[1,113]},{6:[2,90],11:168,25:[2,90],26:[2,90],27:169,28:[1,73],29:170,30:[1,71],31:[1,72],41:166,42:167,44:171,46:[1,46],54:[2,90],76:307,88:[1,113]},{6:[2,92],25:[2,92],26:[2,92],54:[2,92],77:[2,92]},{6:[2,40],25:[2,40],26:[2,40],54:[2,40],77:[2,40],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{8:308,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{72:[2,119],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,38],6:[2,38],25:[2,38],26:[2,38],49:[2,38],54:[2,38],57:[2,38],72:[2,38],77:[2,38],85:[2,38],90:[2,38],92:[2,38],101:[2,38],103:[2,38],104:[2,38],105:[2,38],109:[2,38],117:[2,38],125:[2,38],127:[2,38],128:[2,38],131:[2,38],132:[2,38],133:[2,38],134:[2,38],135:[2,38],136:[2,38]},{1:[2,110],6:[2,110],25:[2,110],26:[2,110],49:[2,110],54:[2,110],57:[2,110],66:[2,110],67:[2,110],68:[2,110],70:[2,110],72:[2,110],73:[2,110],77:[2,110],83:[2,110],84:[2,110],85:[2,110],90:[2,110],92:[2,110],101:[2,110],103:[2,110],104:[2,110],105:[2,110],109:[2,110],117:[2,110],125:[2,110],127:[2,110],128:[2,110],131:[2,110],132:[2,110],133:[2,110],134:[2,110],135:[2,110],136:[2,110]},{1:[2,49],6:[2,49],25:[2,49],26:[2,49],49:[2,49],54:[2,49],57:[2,49],72:[2,49],77:[2,49],85:[2,49],90:[2,49],92:[2,49],101:[2,49],103:[2,49],104:[2,49],105:[2,49],109:[2,49],117:[2,49],125:[2,49],127:[2,49],128:[2,49],131:[2,49],132:[2,49],133:[2,49],134:[2,49],135:[2,49],136:[2,49]},{6:[2,58],25:[2,58],26:[2,58],49:[2,58],54:[2,58]},{6:[2,53],25:[2,53],26:[2,53],53:309,54:[1,202]},{1:[2,200],6:[2,200],25:[2,200],26:[2,200],49:[2,200],54:[2,200],57:[2,200],72:[2,200],77:[2,200],85:[2,200],90:[2,200],92:[2,200],101:[2,200],103:[2,200],104:[2,200],105:[2,200],109:[2,200],117:[2,200],125:[2,200],127:[2,200],128:[2,200],131:[2,200],132:[2,200],133:[2,200],134:[2,200],135:[2,200],136:[2,200]},{1:[2,179],6:[2,179],25:[2,179],26:[2,179],49:[2,179],54:[2,179],57:[2,179],72:[2,179],77:[2,179],85:[2,179],90:[2,179],92:[2,179],101:[2,179],103:[2,179],104:[2,179],105:[2,179],109:[2,179],117:[2,179],120:[2,179],125:[2,179],127:[2,179],128:[2,179],131:[2,179],132:[2,179],133:[2,179],134:[2,179],135:[2,179],136:[2,179]},{1:[2,135],6:[2,135],25:[2,135],26:[2,135],49:[2,135],54:[2,135],57:[2,135],72:[2,135],77:[2,135],85:[2,135],90:[2,135],92:[2,135],101:[2,135],103:[2,135],104:[2,135],105:[2,135],109:[2,135],117:[2,135],125:[2,135],127:[2,135],128:[2,135],131:[2,135],132:[2,135],133:[2,135],134:[2,135],135:[2,135],136:[2,135]},{1:[2,136],6:[2,136],25:[2,136],26:[2,136],49:[2,136],54:[2,136],57:[2,136],72:[2,136],77:[2,136],85:[2,136],90:[2,136],92:[2,136],97:[2,136],101:[2,136],103:[2,136],104:[2,136],105:[2,136],109:[2,136],117:[2,136],125:[2,136],127:[2,136],128:[2,136],131:[2,136],132:[2,136],133:[2,136],134:[2,136],135:[2,136],136:[2,136]},{1:[2,170],6:[2,170],25:[2,170],26:[2,170],49:[2,170],54:[2,170],57:[2,170],72:[2,170],77:[2,170],85:[2,170],90:[2,170],92:[2,170],101:[2,170],103:[2,170],104:[2,170],105:[2,170],109:[2,170],117:[2,170],125:[2,170],127:[2,170],128:[2,170],131:[2,170],132:[2,170],133:[2,170],134:[2,170],135:[2,170],136:[2,170]},{5:310,25:[1,5]},{26:[1,311]},{6:[1,312],26:[2,176],120:[2,176],122:[2,176]},{8:313,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,102],6:[2,102],25:[2,102],26:[2,102],49:[2,102],54:[2,102],57:[2,102],72:[2,102],77:[2,102],85:[2,102],90:[2,102],92:[2,102],101:[2,102],103:[2,102],104:[2,102],105:[2,102],109:[2,102],117:[2,102],125:[2,102],127:[2,102],128:[2,102],131:[2,102],132:[2,102],133:[2,102],134:[2,102],135:[2,102],136:[2,102]},{1:[2,139],6:[2,139],25:[2,139],26:[2,139],49:[2,139],54:[2,139],57:[2,139],66:[2,139],67:[2,139],68:[2,139],70:[2,139],72:[2,139],73:[2,139],77:[2,139],83:[2,139],84:[2,139],85:[2,139],90:[2,139],92:[2,139],101:[2,139],103:[2,139],104:[2,139],105:[2,139],109:[2,139],117:[2,139],125:[2,139],127:[2,139],128:[2,139],131:[2,139],132:[2,139],133:[2,139],134:[2,139],135:[2,139],136:[2,139]},{1:[2,118],6:[2,118],25:[2,118],26:[2,118],49:[2,118],54:[2,118],57:[2,118],66:[2,118],67:[2,118],68:[2,118],70:[2,118],72:[2,118],73:[2,118],77:[2,118],83:[2,118],84:[2,118],85:[2,118],90:[2,118],92:[2,118],101:[2,118],103:[2,118],104:[2,118],105:[2,118],109:[2,118],117:[2,118],125:[2,118],127:[2,118],128:[2,118],131:[2,118],132:[2,118],133:[2,118],134:[2,118],135:[2,118],136:[2,118]},{6:[2,125],25:[2,125],26:[2,125],54:[2,125],85:[2,125],90:[2,125]},{6:[2,53],25:[2,53],26:[2,53],53:314,54:[1,226]},{6:[2,126],25:[2,126],26:[2,126],54:[2,126],85:[2,126],90:[2,126]},{1:[2,165],6:[2,165],25:[2,165],26:[2,165],49:[2,165],54:[2,165],57:[2,165],72:[2,165],77:[2,165],85:[2,165],90:[2,165],92:[2,165],101:[2,165],102:87,103:[2,165],104:[2,165],105:[2,165],108:88,109:[2,165],110:69,117:[1,315],125:[2,165],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,167],6:[2,167],25:[2,167],26:[2,167],49:[2,167],54:[2,167],57:[2,167],72:[2,167],77:[2,167],85:[2,167],90:[2,167],92:[2,167],101:[2,167],102:87,103:[2,167],104:[1,316],105:[2,167],108:88,109:[2,167],110:69,117:[2,167],125:[2,167],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,166],6:[2,166],25:[2,166],26:[2,166],49:[2,166],54:[2,166],57:[2,166],72:[2,166],77:[2,166],85:[2,166],90:[2,166],92:[2,166],101:[2,166],102:87,103:[2,166],104:[2,166],105:[2,166],108:88,109:[2,166],110:69,117:[2,166],125:[2,166],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[2,93],25:[2,93],26:[2,93],54:[2,93],77:[2,93]},{6:[2,53],25:[2,53],26:[2,53],53:317,54:[1,236]},{26:[1,318],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[1,247],25:[1,248],26:[1,319]},{26:[1,320]},{1:[2,173],6:[2,173],25:[2,173],26:[2,173],49:[2,173],54:[2,173],57:[2,173],72:[2,173],77:[2,173],85:[2,173],90:[2,173],92:[2,173],101:[2,173],103:[2,173],104:[2,173],105:[2,173],109:[2,173],117:[2,173],125:[2,173],127:[2,173],128:[2,173],131:[2,173],132:[2,173],133:[2,173],134:[2,173],135:[2,173],136:[2,173]},{26:[2,177],120:[2,177],122:[2,177]},{25:[2,131],54:[2,131],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[1,266],25:[1,267],26:[1,321]},{8:322,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:323,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[1,277],25:[1,278],26:[1,324]},{6:[2,41],25:[2,41],26:[2,41],54:[2,41],77:[2,41]},{6:[2,59],25:[2,59],26:[2,59],49:[2,59],54:[2,59]},{1:[2,171],6:[2,171],25:[2,171],26:[2,171],49:[2,171],54:[2,171],57:[2,171],72:[2,171],77:[2,171],85:[2,171],90:[2,171],92:[2,171],101:[2,171],103:[2,171],104:[2,171],105:[2,171],109:[2,171],117:[2,171],125:[2,171],127:[2,171],128:[2,171],131:[2,171],132:[2,171],133:[2,171],134:[2,171],135:[2,171],136:[2,171]},{6:[2,127],25:[2,127],26:[2,127],54:[2,127],85:[2,127],90:[2,127]},{1:[2,168],6:[2,168],25:[2,168],26:[2,168],49:[2,168],54:[2,168],57:[2,168],72:[2,168],77:[2,168],85:[2,168],90:[2,168],92:[2,168],101:[2,168],102:87,103:[2,168],104:[2,168],105:[2,168],108:88,109:[2,168],110:69,117:[2,168],125:[2,168],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,169],6:[2,169],25:[2,169],26:[2,169],49:[2,169],54:[2,169],57:[2,169],72:[2,169],77:[2,169],85:[2,169],90:[2,169],92:[2,169],101:[2,169],102:87,103:[2,169],104:[2,169],105:[2,169],108:88,109:[2,169],110:69,117:[2,169],125:[2,169],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[2,94],25:[2,94],26:[2,94],54:[2,94],77:[2,94]}], +defaultActions: {60:[2,51],61:[2,52],75:[2,3],94:[2,108],189:[2,88]}, +parseError: function parseError(str, hash) { + throw new Error(str); +}, +parse: function parse(input) { + var self = this, + stack = [0], + vstack = [null], // semantic value stack + lstack = [], // location stack + table = this.table, + yytext = '', + yylineno = 0, + yyleng = 0, + recovering = 0, + TERROR = 2, + EOF = 1; + + //this.reductionCount = this.shiftCount = 0; + + this.lexer.setInput(input); + this.lexer.yy = this.yy; + this.yy.lexer = this.lexer; + if (typeof this.lexer.yylloc == 'undefined') + this.lexer.yylloc = {}; + var yyloc = this.lexer.yylloc; + lstack.push(yyloc); + + if (typeof this.yy.parseError === 'function') + this.parseError = this.yy.parseError; + + function popStack (n) { + stack.length = stack.length - 2*n; + vstack.length = vstack.length - n; + lstack.length = lstack.length - n; + } + + function lex() { + var token; + token = self.lexer.lex() || 1; // $end = 1 + // if token isn't its numeric value, convert + if (typeof token !== 'number') { + token = self.symbols_[token] || token; + } + return token; + } + + var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected; + while (true) { + // retreive state number from top of stack + state = stack[stack.length-1]; + + // use default actions if available + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol == null) + symbol = lex(); + // read action for current state and first input + action = table[state] && table[state][symbol]; + } + + // handle parse error + _handle_error: + if (typeof action === 'undefined' || !action.length || !action[0]) { + + if (!recovering) { + // Report error + expected = []; + for (p in table[state]) if (this.terminals_[p] && p > 2) { + expected.push("'"+this.terminals_[p]+"'"); + } + var errStr = ''; + if (this.lexer.showPosition) { + errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+expected.join(', ') + ", got '" + this.terminals_[symbol]+ "'"; + } else { + errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " + + (symbol == 1 /*EOF*/ ? "end of input" : + ("'"+(this.terminals_[symbol] || symbol)+"'")); + } + this.parseError(errStr, + {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected}); + } + + // just recovered from another error + if (recovering == 3) { + if (symbol == EOF) { + throw new Error(errStr || 'Parsing halted.'); + } + + // discard current lookahead and grab another + yyleng = this.lexer.yyleng; + yytext = this.lexer.yytext; + yylineno = this.lexer.yylineno; + yyloc = this.lexer.yylloc; + symbol = lex(); + } + + // try to recover from error + while (1) { + // check for error recovery rule in this state + if ((TERROR.toString()) in table[state]) { + break; + } + if (state == 0) { + throw new Error(errStr || 'Parsing halted.'); + } + popStack(1); + state = stack[stack.length-1]; + } + + preErrorSymbol = symbol; // save the lookahead token + symbol = TERROR; // insert generic error symbol as new lookahead + state = stack[stack.length-1]; + action = table[state] && table[state][TERROR]; + recovering = 3; // allow 3 real symbols to be shifted before reporting a new error + } + + // this shouldn't happen, unless resolve defaults are off + if (action[0] instanceof Array && action.length > 1) { + throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol); + } + + switch (action[0]) { + + case 1: // shift + //this.shiftCount++; + + stack.push(symbol); + vstack.push(this.lexer.yytext); + lstack.push(this.lexer.yylloc); + stack.push(action[1]); // push state + symbol = null; + if (!preErrorSymbol) { // normal execution/no error + yyleng = this.lexer.yyleng; + yytext = this.lexer.yytext; + yylineno = this.lexer.yylineno; + yyloc = this.lexer.yylloc; + if (recovering > 0) + recovering--; + } else { // error just occurred, resume old lookahead f/ before error + symbol = preErrorSymbol; + preErrorSymbol = null; + } + break; + + case 2: // reduce + //this.reductionCount++; + + len = this.productions_[action[1]][1]; + + // perform semantic action + yyval.$ = vstack[vstack.length-len]; // default to $$ = $1 + // default location, uses first token for firsts, last for lasts + yyval._$ = { + first_line: lstack[lstack.length-(len||1)].first_line, + last_line: lstack[lstack.length-1].last_line, + first_column: lstack[lstack.length-(len||1)].first_column, + last_column: lstack[lstack.length-1].last_column + }; + r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack); + + if (typeof r !== 'undefined') { + return r; + } + + // pop off stack + if (len) { + stack = stack.slice(0,-1*len*2); + vstack = vstack.slice(0, -1*len); + lstack = lstack.slice(0, -1*len); + } + + stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce) + vstack.push(yyval.$); + lstack.push(yyval._$); + // goto new state = table[STATE][NONTERMINAL] + newState = table[stack[stack.length-2]][stack[stack.length-1]]; + stack.push(newState); + break; + + case 3: // accept + return true; + } + + } + + return true; +}}; +undefined +return parser; +})(); +if (typeof require !== 'undefined' && typeof exports !== 'undefined') { +exports.parser = parser; +exports.parse = function () { return parser.parse.apply(parser, arguments); } +exports.main = function commonjsMain(args) { + if (!args[1]) + throw new Error('Usage: '+args[0]+' FILE'); + if (typeof process !== 'undefined') { + var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8"); + } else { + var cwd = require("file").path(require("file").cwd()); + var source = cwd.join(args[1]).read({charset: "utf-8"}); + } + return exports.parser.parse(source); +} +if (typeof module !== 'undefined' && require.main === module) { + exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args); +} +} \ No newline at end of file diff --git a/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/repl.js b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/repl.js new file mode 100644 index 0000000..b4a4765 --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/repl.js @@ -0,0 +1,261 @@ +// Generated by CoffeeScript 1.3.3 +(function() { + var ACCESSOR, CoffeeScript, Module, REPL_PROMPT, REPL_PROMPT_CONTINUATION, REPL_PROMPT_MULTILINE, SIMPLEVAR, Script, autocomplete, backlog, completeAttribute, completeVariable, enableColours, error, getCompletions, inspect, multilineMode, pipedInput, readline, repl, run, stdin, stdout; + + stdin = process.openStdin(); + + stdout = process.stdout; + + CoffeeScript = require('./coffee-script'); + + readline = require('readline'); + + inspect = require('util').inspect; + + Script = require('vm').Script; + + Module = require('module'); + + REPL_PROMPT = 'coffee> '; + + REPL_PROMPT_MULTILINE = '------> '; + + REPL_PROMPT_CONTINUATION = '......> '; + + enableColours = false; + + if (process.platform !== 'win32') { + enableColours = !process.env.NODE_DISABLE_COLORS; + } + + error = function(err) { + return stdout.write((err.stack || err.toString()) + '\n'); + }; + + ACCESSOR = /\s*([\w\.]+)(?:\.(\w*))$/; + + SIMPLEVAR = /(\w+)$/i; + + autocomplete = function(text) { + return completeAttribute(text) || completeVariable(text) || [[], text]; + }; + + completeAttribute = function(text) { + var all, completions, key, match, obj, possibilities, prefix, val; + if (match = text.match(ACCESSOR)) { + all = match[0], obj = match[1], prefix = match[2]; + try { + val = Script.runInThisContext(obj); + } catch (error) { + return; + } + val = Object(val); + possibilities = Object.getOwnPropertyNames(val); + for (key in val) { + if (~possibilities.indexOf(val)) { + possibilities.push(key); + } + } + completions = getCompletions(prefix, possibilities); + return [completions, prefix]; + } + }; + + completeVariable = function(text) { + var completions, free, keywords, possibilities, r, vars, _ref; + free = (_ref = text.match(SIMPLEVAR)) != null ? _ref[1] : void 0; + if (text === "") { + free = ""; + } + if (free != null) { + vars = Script.runInThisContext('Object.getOwnPropertyNames(Object(this))'); + keywords = (function() { + var _i, _len, _ref1, _results; + _ref1 = CoffeeScript.RESERVED; + _results = []; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + r = _ref1[_i]; + if (r.slice(0, 2) !== '__') { + _results.push(r); + } + } + return _results; + })(); + possibilities = vars.concat(keywords); + completions = getCompletions(free, possibilities); + return [completions, free]; + } + }; + + getCompletions = function(prefix, candidates) { + var el, _i, _len, _results; + _results = []; + for (_i = 0, _len = candidates.length; _i < _len; _i++) { + el = candidates[_i]; + if (el.indexOf(prefix) === 0) { + _results.push(el); + } + } + return _results; + }; + + process.on('uncaughtException', error); + + backlog = ''; + + run = function(buffer) { + var code, returnValue, _; + buffer = buffer.replace(/(^|[\r\n]+)(\s*)##?(?:[^#\r\n][^\r\n]*|)($|[\r\n])/, "$1$2$3"); + buffer = buffer.replace(/[\r\n]+$/, ""); + if (multilineMode) { + backlog += "" + buffer + "\n"; + repl.setPrompt(REPL_PROMPT_CONTINUATION); + repl.prompt(); + return; + } + if (!buffer.toString().trim() && !backlog) { + repl.prompt(); + return; + } + code = backlog += buffer; + if (code[code.length - 1] === '\\') { + backlog = "" + backlog.slice(0, -1) + "\n"; + repl.setPrompt(REPL_PROMPT_CONTINUATION); + repl.prompt(); + return; + } + repl.setPrompt(REPL_PROMPT); + backlog = ''; + try { + _ = global._; + returnValue = CoffeeScript["eval"]("_=(" + code + "\n)", { + filename: 'repl', + modulename: 'repl' + }); + if (returnValue === void 0) { + global._ = _; + } + repl.output.write("" + (inspect(returnValue, false, 2, enableColours)) + "\n"); + } catch (err) { + error(err); + } + return repl.prompt(); + }; + + if (stdin.readable) { + pipedInput = ''; + repl = { + prompt: function() { + return stdout.write(this._prompt); + }, + setPrompt: function(p) { + return this._prompt = p; + }, + input: stdin, + output: stdout, + on: function() {} + }; + stdin.on('data', function(chunk) { + var line, lines, _i, _len, _ref; + pipedInput += chunk; + if (!/\n/.test(pipedInput)) { + return; + } + lines = pipedInput.split("\n"); + pipedInput = lines[lines.length - 1]; + _ref = lines.slice(0, -1); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + line = _ref[_i]; + if (!(line)) { + continue; + } + stdout.write("" + line + "\n"); + run(line); + } + }); + stdin.on('end', function() { + var line, _i, _len, _ref; + _ref = pipedInput.trim().split("\n"); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + line = _ref[_i]; + if (!(line)) { + continue; + } + stdout.write("" + line + "\n"); + run(line); + } + stdout.write('\n'); + return process.exit(0); + }); + } else { + if (readline.createInterface.length < 3) { + repl = readline.createInterface(stdin, autocomplete); + stdin.on('data', function(buffer) { + return repl.write(buffer); + }); + } else { + repl = readline.createInterface(stdin, stdout, autocomplete); + } + } + + multilineMode = false; + + repl.input.on('keypress', function(char, key) { + var cursorPos, newPrompt; + if (!(key && key.ctrl && !key.meta && !key.shift && key.name === 'v')) { + return; + } + cursorPos = repl.cursor; + repl.output.cursorTo(0); + repl.output.clearLine(1); + multilineMode = !multilineMode; + if (!multilineMode && backlog) { + repl._line(); + } + backlog = ''; + repl.setPrompt((newPrompt = multilineMode ? REPL_PROMPT_MULTILINE : REPL_PROMPT)); + repl.prompt(); + return repl.output.cursorTo(newPrompt.length + (repl.cursor = cursorPos)); + }); + + repl.input.on('keypress', function(char, key) { + if (!(multilineMode && repl.line)) { + return; + } + if (!(key && key.ctrl && !key.meta && !key.shift && key.name === 'd')) { + return; + } + multilineMode = false; + return repl._line(); + }); + + repl.on('attemptClose', function() { + if (multilineMode) { + multilineMode = false; + repl.output.cursorTo(0); + repl.output.clearLine(1); + repl._onLine(repl.line); + return; + } + if (backlog) { + backlog = ''; + repl.output.write('\n'); + repl.setPrompt(REPL_PROMPT); + return repl.prompt(); + } else { + return repl.close(); + } + }); + + repl.on('close', function() { + repl.output.write('\n'); + return repl.input.destroy(); + }); + + repl.on('line', run); + + repl.setPrompt(REPL_PROMPT); + + repl.prompt(); + +}).call(this); diff --git a/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/rewriter.js b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/rewriter.js new file mode 100644 index 0000000..d26133c --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/rewriter.js @@ -0,0 +1,349 @@ +// Generated by CoffeeScript 1.3.3 +(function() { + var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, left, rite, _i, _len, _ref, + __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, + __slice = [].slice; + + exports.Rewriter = (function() { + + function Rewriter() {} + + Rewriter.prototype.rewrite = function(tokens) { + this.tokens = tokens; + this.removeLeadingNewlines(); + this.removeMidExpressionNewlines(); + this.closeOpenCalls(); + this.closeOpenIndexes(); + this.addImplicitIndentation(); + this.tagPostfixConditionals(); + this.addImplicitBraces(); + this.addImplicitParentheses(); + return this.tokens; + }; + + Rewriter.prototype.scanTokens = function(block) { + var i, token, tokens; + tokens = this.tokens; + i = 0; + while (token = tokens[i]) { + i += block.call(this, token, i, tokens); + } + return true; + }; + + Rewriter.prototype.detectEnd = function(i, condition, action) { + var levels, token, tokens, _ref, _ref1; + tokens = this.tokens; + levels = 0; + while (token = tokens[i]) { + if (levels === 0 && condition.call(this, token, i)) { + return action.call(this, token, i); + } + if (!token || levels < 0) { + return action.call(this, token, i - 1); + } + if (_ref = token[0], __indexOf.call(EXPRESSION_START, _ref) >= 0) { + levels += 1; + } else if (_ref1 = token[0], __indexOf.call(EXPRESSION_END, _ref1) >= 0) { + levels -= 1; + } + i += 1; + } + return i - 1; + }; + + Rewriter.prototype.removeLeadingNewlines = function() { + var i, tag, _i, _len, _ref; + _ref = this.tokens; + for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { + tag = _ref[i][0]; + if (tag !== 'TERMINATOR') { + break; + } + } + if (i) { + return this.tokens.splice(0, i); + } + }; + + Rewriter.prototype.removeMidExpressionNewlines = function() { + return this.scanTokens(function(token, i, tokens) { + var _ref; + if (!(token[0] === 'TERMINATOR' && (_ref = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref) >= 0))) { + return 1; + } + tokens.splice(i, 1); + return 0; + }); + }; + + Rewriter.prototype.closeOpenCalls = function() { + var action, condition; + condition = function(token, i) { + var _ref; + return ((_ref = token[0]) === ')' || _ref === 'CALL_END') || token[0] === 'OUTDENT' && this.tag(i - 1) === ')'; + }; + action = function(token, i) { + return this.tokens[token[0] === 'OUTDENT' ? i - 1 : i][0] = 'CALL_END'; + }; + return this.scanTokens(function(token, i) { + if (token[0] === 'CALL_START') { + this.detectEnd(i + 1, condition, action); + } + return 1; + }); + }; + + Rewriter.prototype.closeOpenIndexes = function() { + var action, condition; + condition = function(token, i) { + var _ref; + return (_ref = token[0]) === ']' || _ref === 'INDEX_END'; + }; + action = function(token, i) { + return token[0] = 'INDEX_END'; + }; + return this.scanTokens(function(token, i) { + if (token[0] === 'INDEX_START') { + this.detectEnd(i + 1, condition, action); + } + return 1; + }); + }; + + Rewriter.prototype.addImplicitBraces = function() { + var action, condition, sameLine, stack, start, startIndent, startIndex, startsLine; + stack = []; + start = null; + startsLine = null; + sameLine = true; + startIndent = 0; + startIndex = 0; + condition = function(token, i) { + var one, tag, three, two, _ref, _ref1; + _ref = this.tokens.slice(i + 1, (i + 3) + 1 || 9e9), one = _ref[0], two = _ref[1], three = _ref[2]; + if ('HERECOMMENT' === (one != null ? one[0] : void 0)) { + return false; + } + tag = token[0]; + if (__indexOf.call(LINEBREAKS, tag) >= 0) { + sameLine = false; + } + return (((tag === 'TERMINATOR' || tag === 'OUTDENT') || (__indexOf.call(IMPLICIT_END, tag) >= 0 && sameLine && !(i - startIndex === 1))) && ((!startsLine && this.tag(i - 1) !== ',') || !((two != null ? two[0] : void 0) === ':' || (one != null ? one[0] : void 0) === '@' && (three != null ? three[0] : void 0) === ':'))) || (tag === ',' && one && ((_ref1 = one[0]) !== 'IDENTIFIER' && _ref1 !== 'NUMBER' && _ref1 !== 'STRING' && _ref1 !== '@' && _ref1 !== 'TERMINATOR' && _ref1 !== 'OUTDENT')); + }; + action = function(token, i) { + var tok; + tok = this.generate('}', '}', token[2]); + return this.tokens.splice(i, 0, tok); + }; + return this.scanTokens(function(token, i, tokens) { + var ago, idx, prevTag, tag, tok, value, _ref, _ref1; + if (_ref = (tag = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0) { + stack.push([(tag === 'INDENT' && this.tag(i - 1) === '{' ? '{' : tag), i]); + return 1; + } + if (__indexOf.call(EXPRESSION_END, tag) >= 0) { + start = stack.pop(); + return 1; + } + if (!(tag === ':' && ((ago = this.tag(i - 2)) === ':' || ((_ref1 = stack[stack.length - 1]) != null ? _ref1[0] : void 0) !== '{'))) { + return 1; + } + sameLine = true; + startIndex = i + 1; + stack.push(['{']); + idx = ago === '@' ? i - 2 : i - 1; + while (this.tag(idx - 2) === 'HERECOMMENT') { + idx -= 2; + } + prevTag = this.tag(idx - 1); + startsLine = !prevTag || (__indexOf.call(LINEBREAKS, prevTag) >= 0); + value = new String('{'); + value.generated = true; + tok = this.generate('{', value, token[2]); + tokens.splice(idx, 0, tok); + this.detectEnd(i + 2, condition, action); + return 2; + }); + }; + + Rewriter.prototype.addImplicitParentheses = function() { + var action, condition, noCall, seenControl, seenSingle; + noCall = seenSingle = seenControl = false; + condition = function(token, i) { + var post, tag, _ref, _ref1; + tag = token[0]; + if (!seenSingle && token.fromThen) { + return true; + } + if (tag === 'IF' || tag === 'ELSE' || tag === 'CATCH' || tag === '->' || tag === '=>' || tag === 'CLASS') { + seenSingle = true; + } + if (tag === 'IF' || tag === 'ELSE' || tag === 'SWITCH' || tag === 'TRY' || tag === '=') { + seenControl = true; + } + if ((tag === '.' || tag === '?.' || tag === '::') && this.tag(i - 1) === 'OUTDENT') { + return true; + } + return !token.generated && this.tag(i - 1) !== ',' && (__indexOf.call(IMPLICIT_END, tag) >= 0 || (tag === 'INDENT' && !seenControl)) && (tag !== 'INDENT' || (((_ref = this.tag(i - 2)) !== 'CLASS' && _ref !== 'EXTENDS') && (_ref1 = this.tag(i - 1), __indexOf.call(IMPLICIT_BLOCK, _ref1) < 0) && !((post = this.tokens[i + 1]) && post.generated && post[0] === '{'))); + }; + action = function(token, i) { + return this.tokens.splice(i, 0, this.generate('CALL_END', ')', token[2])); + }; + return this.scanTokens(function(token, i, tokens) { + var callObject, current, next, prev, tag, _ref, _ref1, _ref2; + tag = token[0]; + if (tag === 'CLASS' || tag === 'IF' || tag === 'FOR' || tag === 'WHILE') { + noCall = true; + } + _ref = tokens.slice(i - 1, (i + 1) + 1 || 9e9), prev = _ref[0], current = _ref[1], next = _ref[2]; + callObject = !noCall && tag === 'INDENT' && next && next.generated && next[0] === '{' && prev && (_ref1 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref1) >= 0); + seenSingle = false; + seenControl = false; + if (__indexOf.call(LINEBREAKS, tag) >= 0) { + noCall = false; + } + if (prev && !prev.spaced && tag === '?') { + token.call = true; + } + if (token.fromThen) { + return 1; + } + if (!(callObject || (prev != null ? prev.spaced : void 0) && (prev.call || (_ref2 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref2) >= 0)) && (__indexOf.call(IMPLICIT_CALL, tag) >= 0 || !(token.spaced || token.newLine) && __indexOf.call(IMPLICIT_UNSPACED_CALL, tag) >= 0))) { + return 1; + } + tokens.splice(i, 0, this.generate('CALL_START', '(', token[2])); + this.detectEnd(i + 1, condition, action); + if (prev[0] === '?') { + prev[0] = 'FUNC_EXIST'; + } + return 2; + }); + }; + + Rewriter.prototype.addImplicitIndentation = function() { + var action, condition, indent, outdent, starter; + starter = indent = outdent = null; + condition = function(token, i) { + var _ref; + return token[1] !== ';' && (_ref = token[0], __indexOf.call(SINGLE_CLOSERS, _ref) >= 0) && !(token[0] === 'ELSE' && (starter !== 'IF' && starter !== 'THEN')); + }; + action = function(token, i) { + return this.tokens.splice((this.tag(i - 1) === ',' ? i - 1 : i), 0, outdent); + }; + return this.scanTokens(function(token, i, tokens) { + var tag, _ref, _ref1; + tag = token[0]; + if (tag === 'TERMINATOR' && this.tag(i + 1) === 'THEN') { + tokens.splice(i, 1); + return 0; + } + if (tag === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') { + tokens.splice.apply(tokens, [i, 0].concat(__slice.call(this.indentation(token)))); + return 2; + } + if (tag === 'CATCH' && ((_ref = this.tag(i + 2)) === 'OUTDENT' || _ref === 'TERMINATOR' || _ref === 'FINALLY')) { + tokens.splice.apply(tokens, [i + 2, 0].concat(__slice.call(this.indentation(token)))); + return 4; + } + if (__indexOf.call(SINGLE_LINERS, tag) >= 0 && this.tag(i + 1) !== 'INDENT' && !(tag === 'ELSE' && this.tag(i + 1) === 'IF')) { + starter = tag; + _ref1 = this.indentation(token, true), indent = _ref1[0], outdent = _ref1[1]; + if (starter === 'THEN') { + indent.fromThen = true; + } + tokens.splice(i + 1, 0, indent); + this.detectEnd(i + 2, condition, action); + if (tag === 'THEN') { + tokens.splice(i, 1); + } + return 1; + } + return 1; + }); + }; + + Rewriter.prototype.tagPostfixConditionals = function() { + var action, condition, original; + original = null; + condition = function(token, i) { + var _ref; + return (_ref = token[0]) === 'TERMINATOR' || _ref === 'INDENT'; + }; + action = function(token, i) { + if (token[0] !== 'INDENT' || (token.generated && !token.fromThen)) { + return original[0] = 'POST_' + original[0]; + } + }; + return this.scanTokens(function(token, i) { + if (token[0] !== 'IF') { + return 1; + } + original = token; + this.detectEnd(i + 1, condition, action); + return 1; + }); + }; + + Rewriter.prototype.indentation = function(token, implicit) { + var indent, outdent; + if (implicit == null) { + implicit = false; + } + indent = ['INDENT', 2, token[2]]; + outdent = ['OUTDENT', 2, token[2]]; + if (implicit) { + indent.generated = outdent.generated = true; + } + return [indent, outdent]; + }; + + Rewriter.prototype.generate = function(tag, value, line) { + var tok; + tok = [tag, value, line]; + tok.generated = true; + return tok; + }; + + Rewriter.prototype.tag = function(i) { + var _ref; + return (_ref = this.tokens[i]) != null ? _ref[0] : void 0; + }; + + return Rewriter; + + })(); + + BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'], ['CALL_START', 'CALL_END'], ['PARAM_START', 'PARAM_END'], ['INDEX_START', 'INDEX_END']]; + + exports.INVERSES = INVERSES = {}; + + EXPRESSION_START = []; + + EXPRESSION_END = []; + + for (_i = 0, _len = BALANCED_PAIRS.length; _i < _len; _i++) { + _ref = BALANCED_PAIRS[_i], left = _ref[0], rite = _ref[1]; + EXPRESSION_START.push(INVERSES[rite] = left); + EXPRESSION_END.push(INVERSES[left] = rite); + } + + EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END); + + IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS']; + + IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY', 'SUPER', '@', '->', '=>', '[', '(', '{', '--', '++']; + + IMPLICIT_UNSPACED_CALL = ['+', '-']; + + IMPLICIT_BLOCK = ['->', '=>', '{', '[', ',']; + + IMPLICIT_END = ['POST_IF', 'FOR', 'WHILE', 'UNTIL', 'WHEN', 'BY', 'LOOP', 'TERMINATOR']; + + SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN']; + + SINGLE_CLOSERS = ['TERMINATOR', 'CATCH', 'FINALLY', 'ELSE', 'OUTDENT', 'LEADING_WHEN']; + + LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT']; + +}).call(this); diff --git a/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/scope.js b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/scope.js new file mode 100644 index 0000000..3efc4ed --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/scope.js @@ -0,0 +1,146 @@ +// Generated by CoffeeScript 1.3.3 +(function() { + var Scope, extend, last, _ref; + + _ref = require('./helpers'), extend = _ref.extend, last = _ref.last; + + exports.Scope = Scope = (function() { + + Scope.root = null; + + function Scope(parent, expressions, method) { + this.parent = parent; + this.expressions = expressions; + this.method = method; + this.variables = [ + { + name: 'arguments', + type: 'arguments' + } + ]; + this.positions = {}; + if (!this.parent) { + Scope.root = this; + } + } + + Scope.prototype.add = function(name, type, immediate) { + if (this.shared && !immediate) { + return this.parent.add(name, type, immediate); + } + if (Object.prototype.hasOwnProperty.call(this.positions, name)) { + return this.variables[this.positions[name]].type = type; + } else { + return this.positions[name] = this.variables.push({ + name: name, + type: type + }) - 1; + } + }; + + Scope.prototype.namedMethod = function() { + if (this.method.name || !this.parent) { + return this.method; + } + return this.parent.namedMethod(); + }; + + Scope.prototype.find = function(name) { + if (this.check(name)) { + return true; + } + this.add(name, 'var'); + return false; + }; + + Scope.prototype.parameter = function(name) { + if (this.shared && this.parent.check(name, true)) { + return; + } + return this.add(name, 'param'); + }; + + Scope.prototype.check = function(name) { + var _ref1; + return !!(this.type(name) || ((_ref1 = this.parent) != null ? _ref1.check(name) : void 0)); + }; + + Scope.prototype.temporary = function(name, index) { + if (name.length > 1) { + return '_' + name + (index > 1 ? index - 1 : ''); + } else { + return '_' + (index + parseInt(name, 36)).toString(36).replace(/\d/g, 'a'); + } + }; + + Scope.prototype.type = function(name) { + var v, _i, _len, _ref1; + _ref1 = this.variables; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + v = _ref1[_i]; + if (v.name === name) { + return v.type; + } + } + return null; + }; + + Scope.prototype.freeVariable = function(name, reserve) { + var index, temp; + if (reserve == null) { + reserve = true; + } + index = 0; + while (this.check((temp = this.temporary(name, index)))) { + index++; + } + if (reserve) { + this.add(temp, 'var', true); + } + return temp; + }; + + Scope.prototype.assign = function(name, value) { + this.add(name, { + value: value, + assigned: true + }, true); + return this.hasAssignments = true; + }; + + Scope.prototype.hasDeclarations = function() { + return !!this.declaredVariables().length; + }; + + Scope.prototype.declaredVariables = function() { + var realVars, tempVars, v, _i, _len, _ref1; + realVars = []; + tempVars = []; + _ref1 = this.variables; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + v = _ref1[_i]; + if (v.type === 'var') { + (v.name.charAt(0) === '_' ? tempVars : realVars).push(v.name); + } + } + return realVars.sort().concat(tempVars.sort()); + }; + + Scope.prototype.assignedVariables = function() { + var v, _i, _len, _ref1, _results; + _ref1 = this.variables; + _results = []; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + v = _ref1[_i]; + if (v.type.assigned) { + _results.push("" + v.name + " = " + v.type.value); + } + } + return _results; + }; + + return Scope; + + })(); + +}).call(this); diff --git a/node_modules/grunt/node_modules/coffee-script/package.json b/node_modules/grunt/node_modules/coffee-script/package.json new file mode 100644 index 0000000..5c09780 --- /dev/null +++ b/node_modules/grunt/node_modules/coffee-script/package.json @@ -0,0 +1,68 @@ +{ + "name": "coffee-script", + "description": "Unfancy JavaScript", + "keywords": [ + "javascript", + "language", + "coffeescript", + "compiler" + ], + "author": { + "name": "Jeremy Ashkenas" + }, + "version": "1.3.3", + "licenses": [ + { + "type": "MIT", + "url": "https://raw.github.com/jashkenas/coffee-script/master/LICENSE" + } + ], + "engines": { + "node": ">=0.4.0" + }, + "directories": { + "lib": "./lib/coffee-script" + }, + "main": "./lib/coffee-script/coffee-script", + "bin": { + "coffee": "./bin/coffee", + "cake": "./bin/cake" + }, + "homepage": "http://coffeescript.org", + "bugs": { + "url": "https://github.com/jashkenas/coffee-script/issues" + }, + "repository": { + "type": "git", + "url": "git://github.com/jashkenas/coffee-script.git" + }, + "devDependencies": { + "uglify-js": ">=1.0.0", + "jison": ">=0.2.0" + }, + "_npmUser": { + "name": "jashkenas", + "email": "jashkenas@gmail.com" + }, + "_id": "coffee-script@1.3.3", + "dependencies": {}, + "optionalDependencies": {}, + "_engineSupported": true, + "_npmVersion": "1.1.18", + "_nodeVersion": "v0.6.16", + "_defaultsLoaded": true, + "dist": { + "shasum": "150d6b4cb522894369efed6a2101c20bc7f4a4f4", + "tarball": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz" + }, + "maintainers": [ + { + "name": "jashkenas", + "email": "jashkenas@gmail.com" + } + ], + "_shasum": "150d6b4cb522894369efed6a2101c20bc7f4a4f4", + "_resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz", + "_from": "coffee-script@>=1.3.3 <1.4.0", + "readme": "ERROR: No README data found!" +} diff --git a/node_modules/grunt/package.json b/node_modules/grunt/package.json new file mode 100644 index 0000000..07e5fea --- /dev/null +++ b/node_modules/grunt/package.json @@ -0,0 +1,105 @@ +{ + "name": "grunt", + "description": "The JavaScript Task Runner", + "version": "0.4.5", + "author": { + "name": "\"Cowboy\" Ben Alman", + "url": "http://benalman.com/" + }, + "homepage": "http://gruntjs.com/", + "repository": { + "type": "git", + "url": "git://github.com/gruntjs/grunt.git" + }, + "bugs": { + "url": "http://github.com/gruntjs/grunt/issues" + }, + "licenses": [ + { + "type": "MIT", + "url": "http://github.com/gruntjs/grunt/blob/master/LICENSE-MIT" + } + ], + "main": "lib/grunt", + "scripts": { + "test": "grunt test" + }, + "engines": { + "node": ">= 0.8.0" + }, + "keywords": [ + "task", + "async", + "cli", + "minify", + "uglify", + "build", + "lodash", + "unit", + "test", + "qunit", + "nodeunit", + "server", + "init", + "scaffold", + "make", + "jake", + "tool" + ], + "dependencies": { + "async": "~0.1.22", + "coffee-script": "~1.3.3", + "colors": "~0.6.2", + "dateformat": "1.0.2-1.2.3", + "eventemitter2": "~0.4.13", + "findup-sync": "~0.1.2", + "glob": "~3.1.21", + "hooker": "~0.2.3", + "iconv-lite": "~0.2.11", + "minimatch": "~0.2.12", + "nopt": "~1.0.10", + "rimraf": "~2.2.8", + "lodash": "~0.9.2", + "underscore.string": "~2.2.1", + "which": "~1.0.5", + "js-yaml": "~2.0.5", + "exit": "~0.1.1", + "getobject": "~0.1.0", + "grunt-legacy-util": "~0.2.0", + "grunt-legacy-log": "~0.1.0" + }, + "devDependencies": { + "temporary": "~0.0.4", + "grunt-contrib-jshint": "~0.6.4", + "grunt-contrib-nodeunit": "~0.2.0", + "grunt-contrib-watch": "~0.5.3", + "difflet": "~0.2.3", + "semver": "2.1.0", + "shelljs": "~0.2.5" + }, + "_id": "grunt@0.4.5", + "dist": { + "shasum": "56937cd5194324adff6d207631832a9d6ba4e7f0", + "tarball": "https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz" + }, + "_from": "grunt@>=0.4.0 <0.5.0", + "_npmVersion": "1.4.4", + "_npmUser": { + "name": "cowboy", + "email": "cowboy@rj3.net" + }, + "maintainers": [ + { + "name": "cowboy", + "email": "cowboy@rj3.net" + }, + { + "name": "tkellen", + "email": "tyler@sleekcode.net" + } + ], + "directories": {}, + "_shasum": "56937cd5194324adff6d207631832a9d6ba4e7f0", + "_resolved": "https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz", + "readme": "ERROR: No README data found!" +} diff --git a/node_modules/gzip-size/cli.js b/node_modules/gzip-size/cli.js new file mode 100644 index 0000000..d8a1356 --- /dev/null +++ b/node_modules/gzip-size/cli.js @@ -0,0 +1,48 @@ +#!/usr/bin/env node +'use strict'; +var fs = require('fs'); +var zlib = require('zlib'); +var concat = require('concat-stream'); +var pkg = require('./package.json'); +var argv = process.argv.slice(2); +var input = argv[0]; + +function help() { + console.log([ + '', + ' ' + pkg.description, + '', + ' Usage', + ' gzip-size ', + ' cat | gzip-size', + '', + ' Example', + ' gzip-size index.js', + ' 211' + ].join('\n')); +} + +function report(data) { + console.log(data.length); +} + +if (argv.indexOf('--help') !== -1) { + help(); + return; +} + +if (argv.indexOf('--version') !== -1) { + console.log(pkg.version); + return; +} + +if (process.stdin.isTTY) { + if (!input) { + help(); + return; + } + + fs.createReadStream(input).pipe(zlib.createGzip()).pipe(concat(report)); +} else { + process.stdin.pipe(zlib.createGzip()).pipe(concat(report)); +} diff --git a/node_modules/gzip-size/index.js b/node_modules/gzip-size/index.js new file mode 100644 index 0000000..4c7db1f --- /dev/null +++ b/node_modules/gzip-size/index.js @@ -0,0 +1,23 @@ +'use strict'; +var gzip = require('zlib').gzip; +var gzipSync = require('browserify-zlib').gzipSync; + +module.exports = function (str, cb) { + if (!str) { + cb(null, 0); + return; + } + + gzip(str, function (err, data) { + if (err) { + cb(err, 0); + return; + } + + cb(err, data.length); + }); +}; + +module.exports.sync = function (str) { + return gzipSync(str).length; +}; diff --git a/node_modules/gzip-size/package.json b/node_modules/gzip-size/package.json new file mode 100644 index 0000000..9eaaabe --- /dev/null +++ b/node_modules/gzip-size/package.json @@ -0,0 +1,106 @@ +{ + "_args": [ + [ + { + "raw": "gzip-size@^1.0.0", + "scope": null, + "escapedName": "gzip-size", + "name": "gzip-size", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/maxmin" + ] + ], + "_from": "gzip-size@>=1.0.0 <2.0.0", + "_id": "gzip-size@1.0.0", + "_inCache": true, + "_location": "/gzip-size", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "1.4.14", + "_phantomChildren": {}, + "_requested": { + "raw": "gzip-size@^1.0.0", + "scope": null, + "escapedName": "gzip-size", + "name": "gzip-size", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/maxmin" + ], + "_resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-1.0.0.tgz", + "_shasum": "66cf8b101047227b95bace6ea1da0c177ed5c22f", + "_shrinkwrap": null, + "_spec": "gzip-size@^1.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/maxmin", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bin": { + "gzip-size": "cli.js" + }, + "bugs": { + "url": "https://github.com/sindresorhus/gzip-size/issues" + }, + "dependencies": { + "browserify-zlib": "^0.1.4", + "concat-stream": "^1.4.1" + }, + "description": "Get the gzipped size of a string or buffer", + "devDependencies": { + "ava": "0.0.3" + }, + "directories": {}, + "dist": { + "shasum": "66cf8b101047227b95bace6ea1da0c177ed5c22f", + "tarball": "https://registry.npmjs.org/gzip-size/-/gzip-size-1.0.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js", + "cli.js" + ], + "gitHead": "709ef7e7670931e33975837c32b6f786d562342d", + "homepage": "https://github.com/sindresorhus/gzip-size", + "keywords": [ + "cli", + "bin", + "app", + "tool", + "zlib", + "gzip", + "compressed", + "size", + "string", + "buffer" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "gzip-size", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/sindresorhus/gzip-size.git" + }, + "scripts": { + "test": "node test.js" + }, + "version": "1.0.0" +} diff --git a/node_modules/gzip-size/readme.md b/node_modules/gzip-size/readme.md new file mode 100644 index 0000000..e06358b --- /dev/null +++ b/node_modules/gzip-size/readme.md @@ -0,0 +1,81 @@ +# gzip-size [![Build Status](https://travis-ci.org/sindresorhus/gzip-size.svg?branch=master)](https://travis-ci.org/sindresorhus/gzip-size) + +> Get the gzipped size of a string or buffer + + +## Install + +```sh +$ npm install --save gzip-size +``` + + +## Usage + +```js +var gzipSize = require('gzip-size'); +var string = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.'; + +console.log(string.length); +//=> 191 + +console.log(gzipSize.sync(string)); +//=> 78 +``` + + +## API + +### gzipSize(input, callback) + +#### input + +*Required* +Type: `string`, `buffer` + +#### callback(err, size) + +*Required* +Type: `function` + +### gzipSize.sync(input) + +Returns the size. + +#### input + +*Required* +Type: `string`, `buffer` + + +## CLI + +```sh +$ npm install --global gzip-size +``` + +```sh +$ gzip-size --help + + Usage + gzip-size + cat | gzip-size + + Example + gzip-size index.js + 211 +``` + +### Tip + +Combine it with [pretty-bytes](https://github.com/sindresorhus/pretty-bytes) to get a human readable output: + +```sh +$ pretty-bytes $(gzip-size jquery.min.js) +29.34 kB +``` + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/has-ansi/index.js b/node_modules/has-ansi/index.js new file mode 100644 index 0000000..98fae06 --- /dev/null +++ b/node_modules/has-ansi/index.js @@ -0,0 +1,4 @@ +'use strict'; +var ansiRegex = require('ansi-regex'); +var re = new RegExp(ansiRegex().source); // remove the `g` flag +module.exports = re.test.bind(re); diff --git a/node_modules/has-ansi/license b/node_modules/has-ansi/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/has-ansi/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/has-ansi/package.json b/node_modules/has-ansi/package.json new file mode 100644 index 0000000..4d472ff --- /dev/null +++ b/node_modules/has-ansi/package.json @@ -0,0 +1,118 @@ +{ + "_args": [ + [ + { + "raw": "has-ansi@^2.0.0", + "scope": null, + "escapedName": "has-ansi", + "name": "has-ansi", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/chalk" + ] + ], + "_from": "has-ansi@>=2.0.0 <3.0.0", + "_id": "has-ansi@2.0.0", + "_inCache": true, + "_location": "/has-ansi", + "_nodeVersion": "0.12.5", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.11.2", + "_phantomChildren": {}, + "_requested": { + "raw": "has-ansi@^2.0.0", + "scope": null, + "escapedName": "has-ansi", + "name": "has-ansi", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/chalk" + ], + "_resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "_shasum": "34f5049ce1ecdf2b0649af3ef24e45ed35416d91", + "_shrinkwrap": null, + "_spec": "has-ansi@^2.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/chalk", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/has-ansi/issues" + }, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "description": "Check if a string has ANSI escape codes", + "devDependencies": { + "ava": "0.0.4" + }, + "directories": {}, + "dist": { + "shasum": "34f5049ce1ecdf2b0649af3ef24e45ed35416d91", + "tarball": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "0722275e1bef139fcd09137da6e5550c3cd368b9", + "homepage": "https://github.com/sindresorhus/has-ansi", + "keywords": [ + "ansi", + "styles", + "color", + "colour", + "colors", + "terminal", + "console", + "string", + "tty", + "escape", + "shell", + "xterm", + "command-line", + "text", + "regex", + "regexp", + "re", + "match", + "test", + "find", + "pattern", + "has" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + { + "name": "jbnicolai", + "email": "jappelman@xebia.com" + } + ], + "name": "has-ansi", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/has-ansi.git" + }, + "scripts": { + "test": "node test.js" + }, + "version": "2.0.0" +} diff --git a/node_modules/has-ansi/readme.md b/node_modules/has-ansi/readme.md new file mode 100644 index 0000000..02bc7c2 --- /dev/null +++ b/node_modules/has-ansi/readme.md @@ -0,0 +1,36 @@ +# has-ansi [![Build Status](https://travis-ci.org/sindresorhus/has-ansi.svg?branch=master)](https://travis-ci.org/sindresorhus/has-ansi) + +> Check if a string has [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code) + + +## Install + +``` +$ npm install --save has-ansi +``` + + +## Usage + +```js +var hasAnsi = require('has-ansi'); + +hasAnsi('\u001b[4mcake\u001b[0m'); +//=> true + +hasAnsi('cake'); +//=> false +``` + + +## Related + +- [has-ansi-cli](https://github.com/sindresorhus/has-ansi-cli) - CLI for this module +- [strip-ansi](https://github.com/sindresorhus/strip-ansi) - Strip ANSI escape codes +- [ansi-regex](https://github.com/sindresorhus/ansi-regex) - Regular expression for matching ANSI escape codes +- [chalk](https://github.com/sindresorhus/chalk) - Terminal string styling done right + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/hooker/LICENSE-MIT b/node_modules/hooker/LICENSE-MIT new file mode 100644 index 0000000..90c336c --- /dev/null +++ b/node_modules/hooker/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) 2012 "Cowboy" Ben Alman + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/hooker/README.md b/node_modules/hooker/README.md new file mode 100644 index 0000000..138943a --- /dev/null +++ b/node_modules/hooker/README.md @@ -0,0 +1,186 @@ +# JavaScript Hooker + +Monkey-patch (hook) functions for debugging and stuff. + +## Getting Started + +This code should work just fine in Node.js: + +First, install the module with: `npm install hooker` + +```javascript +var hooker = require('hooker'); +hooker.hook(Math, "max", function() { + console.log(arguments.length + " arguments passed"); +}); +Math.max(5, 6, 7) // logs: "3 arguments passed", returns 7 +``` + +Or in the browser: + +```html + + +``` + +In the browser, you can attach Hooker's methods to any object. + +```html + + + +``` + +## Documentation + +### hooker.hook +Monkey-patch (hook) one or more methods of an object. +#### Signature: +`hooker.hook(object, [ props, ] [options | prehookFunction])` +#### `props` +The optional `props` argument can be a method name, array of method names or null. If null (or omitted), all enumerable methods of `object` will be hooked. +#### `options` +* `pre` - (Function) a pre-hook function to be executed before the original function. Arguments passed into the method will be passed into the pre-hook function as well. +* `post` - (Function) a post-hook function to be executed after the original function. The original function's result is passed into the post-hook function as its first argument, followed by the method arguments. +* `once` - (Boolean) if true, auto-unhook the function after the first execution. +* `passName` - (Boolean) if true, pass the name of the method into the pre-hook function as its first arg (preceding all other arguments), and into the post-hook function as the second arg (after result but preceding all other arguments). + +#### Returns: +An array of hooked method names. + +### hooker.unhook +Un-monkey-patch (unhook) one or more methods of an object. +#### Signature: +`hooker.unhook(object [, props ])` +#### `props` +The optional `props` argument can be a method name, array of method names or null. If null (or omitted), all methods of `object` will be unhooked. +#### Returns: +An array of unhooked method names. + +### hooker.orig +Get a reference to the original method from a hooked function. +#### Signature: +`hooker.orig(object, props)` + +### hooker.override +When a pre- or post-hook returns the result of this function, the value +passed will be used in place of the original function's return value. Any +post-hook override value will take precedence over a pre-hook override value. +#### Signature: +`hooker.override(value)` + +### hooker.preempt +When a pre-hook returns the result of this function, the value passed will +be used in place of the original function's return value, and the original +function will NOT be executed. +#### Signature: +`hooker.preempt(value)` + +### hooker.filter +When a pre-hook returns the result of this function, the context and +arguments passed will be applied into the original function. +#### Signature: +`hooker.filter(context, arguments)` + + +## Examples +See the unit tests for more examples. + +```javascript +var hooker = require('hooker'); +// Simple logging. +hooker.hook(Math, "max", function() { + console.log(arguments.length + " arguments passed"); +}); +Math.max(5, 6, 7) // logs: "3 arguments passed", returns 7 + +hooker.unhook(Math, "max"); // (This is assumed between all further examples) +Math.max(5, 6, 7) // 7 + +// Returning hooker.override(value) overrides the original value. +hooker.hook(Math, "max", function() { + if (arguments.length === 0) { + return hooker.override(9000); + } +}); +Math.max(5, 6, 7) // 7 +Math.max() // 9000 + +// Auto-unhook after one execution. +hooker.hook(Math, "max", { + once: true, + pre: function() { + console.log("Init something here"); + } +}); +Math.max(5, 6, 7) // logs: "Init something here", returns 7 +Math.max(5, 6, 7) // 7 + +// Filter `this` and arguments through a pre-hook function. +hooker.hook(Math, "max", { + pre: function() { + var args = [].map.call(arguments, function(num) { + return num * 2; + }); + return hooker.filter(this, args); // thisValue, arguments + } +}); +Math.max(5, 6, 7) // 14 + +// Modify the original function's result with a post-hook function. +hooker.hook(Math, "max", { + post: function(result) { + return hooker.override(result * 100); + } +}); +Math.max(5, 6, 7) // 700 + +// Hook every Math method. Note: if Math's methods were enumerable, the second +// argument could be omitted. Since they aren't, an array of properties to hook +// must be explicitly passed. Non-method properties will be skipped. +// See a more generic example here: http://bit.ly/vvJlrS +hooker.hook(Math, Object.getOwnPropertyNames(Math), { + passName: true, + pre: function(name) { + console.log("=> Math." + name, [].slice.call(arguments, 1)); + }, + post: function(result, name) { + console.log("<= Math." + name, result); + } +}); + +var result = Math.max(5, 6, 7); +// => Math.max [ 5, 6, 7 ] +// <= Math.max 7 +result // 7 + +result = Math.ceil(3.456); +// => Math.ceil [ 3.456 ] +// <= Math.ceil 4 +result // 4 +``` + +## Contributing +In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [grunt](https://github.com/cowboy/grunt). + +_Also, please don't edit files in the "dist" subdirectory as they are generated via grunt. You'll find source code in the "lib" subdirectory!_ + +## Release History +2012/01/09 - v0.2.3 - First official release. + +## License +Copyright (c) 2012 "Cowboy" Ben Alman +Licensed under the MIT license. + diff --git a/node_modules/hooker/child.js b/node_modules/hooker/child.js new file mode 100644 index 0000000..ae7dcf2 --- /dev/null +++ b/node_modules/hooker/child.js @@ -0,0 +1,101 @@ +var path = require('path'); +var fs = require('fs'); +var nodeunit = require('nodeunit'); + +var filepaths = fs.readdirSync('test').map(function(filename) { + return path.join('test', filename); +}); + +var unfinished = {}; +var currentModule; +function sendMessage(message) { + process.stdout.write(JSON.stringify(message) + '\n'); +} + +// If an exception is thrown, let the parent process know and exit. +process.on('uncaughtException', function (e) { + sendMessage({error: [e.name, e.message, e.stack]}); + process.exit(); +}); + +// If Nodeunit explodes because a test was missing test.done(), handle it. +var unfinished = {}; +process.on('exit', function (e) { + var len = Object.keys(unfinished).length + if (len > 0) { + sendMessage({exit: ['UNFINISHED']}); + // process.reallyExit(len); + } else { + sendMessage({exit: ['finished']}); + } + // process.exit(); +}); + +nodeunit.reporters.test = { + run: function(files, options, callback) { + // Nodeunit needs absolute paths. + var paths = files.map(function (filepath) { + return path.resolve(filepath); + }); + nodeunit.runFiles(paths, { + // No idea. + testspec: undefined, + // Executed when the first test in a file is run. If no tests exist in + // the file, this doesn't execute. + moduleStart: function(name) { + // Keep track of this so that moduleDone output can be suppressed in + // cases where a test file contains no tests. + currentModule = name; + // Send back to the parent process. + sendMessage({moduleStart: [name.toString()]}); + }, + // Executed after a file is done being processed. This executes whether + // tests exist in the file or not. + moduleDone: function(name) { + // Abort if no tests actually ran. + if (name !== currentModule) { return; } + // Send back to the parent process. + sendMessage({moduleDone: [name.toString()]}); + }, + // Executed before each test is run. + testStart: function(name) { + // Keep track of the current test, in case test.done() was omitted + // and Nodeunit explodes. + unfinished[name] = name; + // Send back to the parent process. + sendMessage({testStart: [name.toString()]}); + }, + // Executed after each test and all its assertions are run. + testDone: function(name, assertions) { + delete unfinished[name]; + // Send back to the parent process. + sendMessage({testDone: [ + name.toString(), + assertions.failures(), + assertions.map(function(assertion) { + var e = assertion.error; + if (e) { + assertion.error = { + name: e.name, + message: e.message, + stack: e.stack + }; + } + return assertion; + }) + ]}); + }, + // Executed when everything is all done. + done: function (assertions) { + // Send back to the parent process. + sendMessage({done: [ + assertions.failures(), + assertions.duration, + assertions + ]}); + } + }); + } +} + +nodeunit.reporters.test.run(filepaths, {}); diff --git a/node_modules/hooker/dist/ba-hooker.js b/node_modules/hooker/dist/ba-hooker.js new file mode 100644 index 0000000..d10a321 --- /dev/null +++ b/node_modules/hooker/dist/ba-hooker.js @@ -0,0 +1,169 @@ +/*! JavaScript Hooker - v0.2.3 - 1/29/2012 +* http://github.com/cowboy/javascript-hooker +* Copyright (c) 2012 "Cowboy" Ben Alman; Licensed MIT */ + +(function(exports) { + // Get an array from an array-like object with slice.call(arrayLikeObject). + var slice = [].slice; + // Get an "[object [[Class]]]" string with toString.call(value). + var toString = {}.toString; + + // I can't think of a better way to ensure a value is a specific type other + // than to create instances and use the `instanceof` operator. + function HookerOverride(v) { this.value = v; } + function HookerPreempt(v) { this.value = v; } + function HookerFilter(c, a) { this.context = c; this.args = a; } + + // When a pre- or post-hook returns the result of this function, the value + // passed will be used in place of the original function's return value. Any + // post-hook override value will take precedence over a pre-hook override + // value. + exports.override = function(value) { + return new HookerOverride(value); + }; + + // When a pre-hook returns the result of this function, the value passed will + // be used in place of the original function's return value, and the original + // function will NOT be executed. + exports.preempt = function(value) { + return new HookerPreempt(value); + }; + + // When a pre-hook returns the result of this function, the context and + // arguments passed will be applied into the original function. + exports.filter = function(context, args) { + return new HookerFilter(context, args); + }; + + // Execute callback(s) for properties of the specified object. + function forMethods(obj, props, callback) { + var prop; + if (typeof props === "string") { + // A single prop string was passed. Create an array. + props = [props]; + } else if (props == null) { + // No props were passed, so iterate over all properties, building an + // array. Unfortunately, Object.keys(obj) doesn't work everywhere yet, so + // this has to be done manually. + props = []; + for (prop in obj) { + if (obj.hasOwnProperty(prop)) { + props.push(prop); + } + } + } + // Execute callback for every method in the props array. + var i = props.length; + while (i--) { + // If the property isn't a function... + if (toString.call(obj[props[i]]) !== "[object Function]" || + // ...or the callback returns false... + callback(obj, props[i]) === false) { + // ...remove it from the props array to be returned. + props.splice(i, 1); + } + } + // Return an array of method names for which the callback didn't fail. + return props; + } + + // Monkey-patch (hook) a method of an object. + exports.hook = function(obj, props, options) { + // If the props argument was omitted, shuffle the arguments. + if (options == null) { + options = props; + props = null; + } + // If just a function is passed instead of an options hash, use that as a + // pre-hook function. + if (typeof options === "function") { + options = {pre: options}; + } + + // Hook the specified method of the object. + return forMethods(obj, props, function(obj, prop) { + // The original (current) method. + var orig = obj[prop]; + // The new hooked function. + function hooked() { + var result, origResult, tmp; + + // Get an array of arguments. + var args = slice.call(arguments); + + // If passName option is specified, prepend prop to the args array, + // passing it as the first argument to any specified hook functions. + if (options.passName) { + args.unshift(prop); + } + + // If a pre-hook function was specified, invoke it in the current + // context with the passed-in arguments, and store its result. + if (options.pre) { + result = options.pre.apply(this, args); + } + + if (result instanceof HookerFilter) { + // If the pre-hook returned hooker.filter(context, args), invoke the + // original function with that context and arguments, and store its + // result. + origResult = result = orig.apply(result.context, result.args); + } else if (result instanceof HookerPreempt) { + // If the pre-hook returned hooker.preempt(value) just use the passed + // value and don't execute the original function. + origResult = result = result.value; + } else { + // Invoke the original function in the current context with the + // passed-in arguments, and store its result. + origResult = orig.apply(this, arguments); + // If the pre-hook returned hooker.override(value), use the passed + // value, otherwise use the original function's result. + result = result instanceof HookerOverride ? result.value : origResult; + } + + if (options.post) { + // If a post-hook function was specified, invoke it in the current + // context, passing in the result of the original function as the + // first argument, followed by any passed-in arguments. + tmp = options.post.apply(this, [origResult].concat(args)); + if (tmp instanceof HookerOverride) { + // If the post-hook returned hooker.override(value), use the passed + // value, otherwise use the previously computed result. + result = tmp.value; + } + } + + // Unhook if the "once" option was specified. + if (options.once) { + exports.unhook(obj, prop); + } + + // Return the result! + return result; + } + // Re-define the method. + obj[prop] = hooked; + // Fail if the function couldn't be hooked. + if (obj[prop] !== hooked) { return false; } + // Store a reference to the original method as a property on the new one. + obj[prop]._orig = orig; + }); + }; + + // Get a reference to the original method from a hooked function. + exports.orig = function(obj, prop) { + return obj[prop]._orig; + }; + + // Un-monkey-patch (unhook) a method of an object. + exports.unhook = function(obj, props) { + return forMethods(obj, props, function(obj, prop) { + // Get a reference to the original method, if it exists. + var orig = exports.orig(obj, prop); + // If there's no original method, it can't be unhooked, so fail. + if (!orig) { return false; } + // Unhook the method. + obj[prop] = orig; + }); + }; +}(typeof exports === "object" && exports || this)); diff --git a/node_modules/hooker/dist/ba-hooker.min.js b/node_modules/hooker/dist/ba-hooker.min.js new file mode 100644 index 0000000..2bcdb54 --- /dev/null +++ b/node_modules/hooker/dist/ba-hooker.min.js @@ -0,0 +1,4 @@ +/*! JavaScript Hooker - v0.2.3 - 1/29/2012 +* http://github.com/cowboy/javascript-hooker +* Copyright (c) 2012 "Cowboy" Ben Alman; Licensed MIT */ +(function(a){function d(a){this.value=a}function e(a){this.value=a}function f(a,b){this.context=a,this.args=b}function g(a,b,d){var e;if(typeof b=="string")b=[b];else if(b==null){b=[];for(e in a)a.hasOwnProperty(e)&&b.push(e)}var f=b.length;while(f--)(c.call(a[b[f]])!=="[object Function]"||d(a,b[f])===!1)&&b.splice(f,1);return b}var b=[].slice,c={}.toString;a.override=function(a){return new d(a)},a.preempt=function(a){return new e(a)},a.filter=function(a,b){return new f(a,b)},a.hook=function(c,h,i){return i==null&&(i=h,h=null),typeof i=="function"&&(i={pre:i}),g(c,h,function(c,g){function j(){var j,k,l,m=b.call(arguments);return i.passName&&m.unshift(g),i.pre&&(j=i.pre.apply(this,m)),j instanceof f?k=j=h.apply(j.context,j.args):j instanceof e?k=j=j.value:(k=h.apply(this,arguments),j=j instanceof d?j.value:k),i.post&&(l=i.post.apply(this,[k].concat(m)),l instanceof d&&(j=l.value)),i.once&&a.unhook(c,g),j}var h=c[g];c[g]=j;if(c[g]!==j)return!1;c[g]._orig=h})},a.orig=function(a,b){return a[b]._orig},a.unhook=function(b,c){return g(b,c,function(b,c){var d=a.orig(b,c);if(!d)return!1;b[c]=d})}})(typeof exports=="object"&&exports||this) \ No newline at end of file diff --git a/node_modules/hooker/grunt.js b/node_modules/hooker/grunt.js new file mode 100644 index 0000000..c695148 --- /dev/null +++ b/node_modules/hooker/grunt.js @@ -0,0 +1,47 @@ +/*global config:true, task:true*/ +config.init({ + pkg: '', + meta: { + name: 'JavaScript Hooker', + banner: '/*! <%= meta.name %> - v<%= pkg.version %> - <%= template.today("m/d/yyyy") %>\n' + + '* <%= pkg.homepage %>\n' + + '* Copyright (c) <%= template.today("yyyy") %> <%= pkg.author.name %>;' + + ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */' + }, + concat: { + 'dist/ba-hooker.js': ['', ''] + }, + min: { + 'dist/ba-hooker.min.js': ['', 'dist/ba-hooker.js'] + }, + test: { + files: ['test/**/*.js'] + }, + lint: { + files: ['grunt.js', 'lib/**/*.js', 'test/**/*.js'] + }, + watch: { + files: '', + tasks: 'lint:files test:files' + }, + jshint: { + options: { + curly: true, + eqeqeq: true, + immed: true, + latedef: true, + newcap: true, + noarg: true, + sub: true, + undef: true, + eqnull: true + }, + globals: { + exports: true + } + }, + uglify: {} +}); + +// Default task. +task.registerTask('default', 'lint:files test:files concat min'); diff --git a/node_modules/hooker/lib/hooker.js b/node_modules/hooker/lib/hooker.js new file mode 100644 index 0000000..1ff9764 --- /dev/null +++ b/node_modules/hooker/lib/hooker.js @@ -0,0 +1,174 @@ +/* + * JavaScript Hooker + * http://github.com/cowboy/javascript-hooker + * + * Copyright (c) 2012 "Cowboy" Ben Alman + * Licensed under the MIT license. + * http://benalman.com/about/license/ + */ + +(function(exports) { + // Get an array from an array-like object with slice.call(arrayLikeObject). + var slice = [].slice; + // Get an "[object [[Class]]]" string with toString.call(value). + var toString = {}.toString; + + // I can't think of a better way to ensure a value is a specific type other + // than to create instances and use the `instanceof` operator. + function HookerOverride(v) { this.value = v; } + function HookerPreempt(v) { this.value = v; } + function HookerFilter(c, a) { this.context = c; this.args = a; } + + // When a pre- or post-hook returns the result of this function, the value + // passed will be used in place of the original function's return value. Any + // post-hook override value will take precedence over a pre-hook override + // value. + exports.override = function(value) { + return new HookerOverride(value); + }; + + // When a pre-hook returns the result of this function, the value passed will + // be used in place of the original function's return value, and the original + // function will NOT be executed. + exports.preempt = function(value) { + return new HookerPreempt(value); + }; + + // When a pre-hook returns the result of this function, the context and + // arguments passed will be applied into the original function. + exports.filter = function(context, args) { + return new HookerFilter(context, args); + }; + + // Execute callback(s) for properties of the specified object. + function forMethods(obj, props, callback) { + var prop; + if (typeof props === "string") { + // A single prop string was passed. Create an array. + props = [props]; + } else if (props == null) { + // No props were passed, so iterate over all properties, building an + // array. Unfortunately, Object.keys(obj) doesn't work everywhere yet, so + // this has to be done manually. + props = []; + for (prop in obj) { + if (obj.hasOwnProperty(prop)) { + props.push(prop); + } + } + } + // Execute callback for every method in the props array. + var i = props.length; + while (i--) { + // If the property isn't a function... + if (toString.call(obj[props[i]]) !== "[object Function]" || + // ...or the callback returns false... + callback(obj, props[i]) === false) { + // ...remove it from the props array to be returned. + props.splice(i, 1); + } + } + // Return an array of method names for which the callback didn't fail. + return props; + } + + // Monkey-patch (hook) a method of an object. + exports.hook = function(obj, props, options) { + // If the props argument was omitted, shuffle the arguments. + if (options == null) { + options = props; + props = null; + } + // If just a function is passed instead of an options hash, use that as a + // pre-hook function. + if (typeof options === "function") { + options = {pre: options}; + } + + // Hook the specified method of the object. + return forMethods(obj, props, function(obj, prop) { + // The original (current) method. + var orig = obj[prop]; + // The new hooked function. + function hooked() { + var result, origResult, tmp; + + // Get an array of arguments. + var args = slice.call(arguments); + + // If passName option is specified, prepend prop to the args array, + // passing it as the first argument to any specified hook functions. + if (options.passName) { + args.unshift(prop); + } + + // If a pre-hook function was specified, invoke it in the current + // context with the passed-in arguments, and store its result. + if (options.pre) { + result = options.pre.apply(this, args); + } + + if (result instanceof HookerFilter) { + // If the pre-hook returned hooker.filter(context, args), invoke the + // original function with that context and arguments, and store its + // result. + origResult = result = orig.apply(result.context, result.args); + } else if (result instanceof HookerPreempt) { + // If the pre-hook returned hooker.preempt(value) just use the passed + // value and don't execute the original function. + origResult = result = result.value; + } else { + // Invoke the original function in the current context with the + // passed-in arguments, and store its result. + origResult = orig.apply(this, arguments); + // If the pre-hook returned hooker.override(value), use the passed + // value, otherwise use the original function's result. + result = result instanceof HookerOverride ? result.value : origResult; + } + + if (options.post) { + // If a post-hook function was specified, invoke it in the current + // context, passing in the result of the original function as the + // first argument, followed by any passed-in arguments. + tmp = options.post.apply(this, [origResult].concat(args)); + if (tmp instanceof HookerOverride) { + // If the post-hook returned hooker.override(value), use the passed + // value, otherwise use the previously computed result. + result = tmp.value; + } + } + + // Unhook if the "once" option was specified. + if (options.once) { + exports.unhook(obj, prop); + } + + // Return the result! + return result; + } + // Re-define the method. + obj[prop] = hooked; + // Fail if the function couldn't be hooked. + if (obj[prop] !== hooked) { return false; } + // Store a reference to the original method as a property on the new one. + obj[prop]._orig = orig; + }); + }; + + // Get a reference to the original method from a hooked function. + exports.orig = function(obj, prop) { + return obj[prop]._orig; + }; + + // Un-monkey-patch (unhook) a method of an object. + exports.unhook = function(obj, props) { + return forMethods(obj, props, function(obj, prop) { + // Get a reference to the original method, if it exists. + var orig = exports.orig(obj, prop); + // If there's no original method, it can't be unhooked, so fail. + if (!orig) { return false; } + // Unhook the method. + obj[prop] = orig; + }); + }; +}(typeof exports === "object" && exports || this)); diff --git a/node_modules/hooker/package.json b/node_modules/hooker/package.json new file mode 100644 index 0000000..e8519f7 --- /dev/null +++ b/node_modules/hooker/package.json @@ -0,0 +1,103 @@ +{ + "_args": [ + [ + { + "raw": "hooker@~0.2.3", + "scope": null, + "escapedName": "hooker", + "name": "hooker", + "rawSpec": "~0.2.3", + "spec": ">=0.2.3 <0.3.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt" + ] + ], + "_defaultsLoaded": true, + "_engineSupported": true, + "_from": "hooker@>=0.2.3 <0.3.0", + "_id": "hooker@0.2.3", + "_inCache": true, + "_location": "/hooker", + "_nodeVersion": "v0.6.8", + "_npmUser": { + "name": "cowboy", + "email": "cowboy@rj3.net" + }, + "_npmVersion": "1.1.0-2", + "_phantomChildren": {}, + "_requested": { + "raw": "hooker@~0.2.3", + "scope": null, + "escapedName": "hooker", + "name": "hooker", + "rawSpec": "~0.2.3", + "spec": ">=0.2.3 <0.3.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt", + "/grunt-contrib-jshint", + "/grunt-legacy-log", + "/grunt-legacy-util", + "/grunt-sftp-deploy/grunt-legacy-log", + "/grunt-sftp-deploy/grunt-legacy-util" + ], + "_resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", + "_shasum": "b834f723cc4a242aa65963459df6d984c5d3d959", + "_shrinkwrap": null, + "_spec": "hooker@~0.2.3", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt", + "author": { + "name": "\"Cowboy\" Ben Alman", + "url": "http://benalman.com/" + }, + "bugs": { + "url": "https://github.com/cowboy/javascript-hooker/issues" + }, + "dependencies": {}, + "description": "Monkey-patch (hook) functions for debugging and stuff.", + "devDependencies": { + "grunt": "~0.2.1" + }, + "directories": {}, + "dist": { + "shasum": "b834f723cc4a242aa65963459df6d984c5d3d959", + "tarball": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz" + }, + "engines": { + "node": "*" + }, + "homepage": "http://github.com/cowboy/javascript-hooker", + "keywords": [ + "patch", + "hook", + "function", + "debug", + "aop" + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/cowboy/javascript-hooker/blob/master/LICENSE-MIT" + } + ], + "main": "lib/hooker", + "maintainers": [ + { + "name": "cowboy", + "email": "cowboy@rj3.net" + } + ], + "name": "hooker", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/cowboy/javascript-hooker.git" + }, + "scripts": { + "test": "grunt test" + }, + "version": "0.2.3" +} diff --git a/node_modules/hooker/parent.js b/node_modules/hooker/parent.js new file mode 100644 index 0000000..c4a055e --- /dev/null +++ b/node_modules/hooker/parent.js @@ -0,0 +1,17 @@ +var spawn = require('child_process').spawn; + +function loop() { + console.log('starting'); + console.log(this); + //var child = spawn('./node_modules/nodeunit/bin/nodeunit', ['test']); + var child = spawn('node', ['child.js']); + child.stdout.on('data', function(buffer) { + process.stdout.write(buffer); + }); + child.on('exit', this.async()); +} + +var context = { + async: function() { return loop.bind(context); } +}; +loop.call(context); \ No newline at end of file diff --git a/node_modules/hooker/test/hooker_test.js b/node_modules/hooker/test/hooker_test.js new file mode 100644 index 0000000..dc5910a --- /dev/null +++ b/node_modules/hooker/test/hooker_test.js @@ -0,0 +1,435 @@ +/*global require:true */ +var hooker = require('../lib/hooker'); + +exports['hook'] = { + setUp: function(done) { + this.order = []; + this.track = function() { + [].push.apply(this.order, arguments); + }; + + this.prop = 1; + this.add = function(a, b) { + this.track("add", this.prop, a, b); + return this.prop + a + b; + }; + + this.obj = { + that: this, + prop: 1, + add1: function(a, b) { + this.that.track("add1", this.prop, a, b); + return this.prop + a + b; + }, + add2: function(a, b) { + this.that.track("add2", this.prop, a, b); + return this.prop + a + b; + }, + add3: function(a, b) { + this.that.track("add3", this.prop, a, b); + return this.prop + a + b; + } + }; + + done(); + }, + 'orig': function(test) { + test.expect(1); + var orig = this.add; + hooker.hook(this, "add", function() {}); + test.strictEqual(hooker.orig(this, "add"), orig, "should return a refernce to the original function."); + test.done(); + }, + 'once': function(test) { + test.expect(5); + var orig = this.add; + hooker.hook(this, "add", { + once: true, + pre: function(a, b) { + // Arguments are passed into pre-hook as specified. + this.track("before", this.prop, a, b); + } + }); + test.strictEqual(this.add(2, 3), 6, "should return the original function's result."); + test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3], "functions should execute in-order."); + test.strictEqual(this.add, orig, "should automatically unhook when once is specified."); + this.order = []; + test.strictEqual(this.add(2, 3), 6, "should return the original function's result."); + test.deepEqual(this.order, ["add", 1, 2, 3], "only the original function should execute."); + test.done(); + }, + 'pre-hook (simple syntax)': function(test) { + test.expect(3); + // Pre-hook. + var result = hooker.hook(this, "add", function(a, b) { + // Arguments are passed into pre-hook as specified. + this.track("before", this.prop, a, b); + }); + test.deepEqual(result, ["add"], "add should have been hooked."); + test.strictEqual(this.add(2, 3), 6, "should return the original function's result."); + test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3], "functions should execute in-order."); + test.done(); + }, + 'pre-hook': function(test) { + test.expect(3); + // Pre-hook. + var result = hooker.hook(this, "add", { + pre: function(a, b) { + // Arguments are passed into pre-hook as specified. + this.track("before", this.prop, a, b); + } + }); + test.deepEqual(result, ["add"], "add should have been hooked."); + test.strictEqual(this.add(2, 3), 6, "should return the original function's result."); + test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3], "functions should execute in-order."); + test.done(); + }, + 'post-hook': function(test) { + test.expect(3); + // Post-hook. + var result = hooker.hook(this, "add", { + post: function(result, a, b) { + // Arguments to post-hook are the original function's return value, + // followed by the specified function arguments. + this.track("after", this.prop, a, b, result); + } + }); + test.deepEqual(result, ["add"], "add should have been hooked."); + test.strictEqual(this.add(2, 3), 6, "should return the original function's result."); + test.deepEqual(this.order, ["add", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); + test.done(); + }, + 'pre- & post-hook': function(test) { + test.expect(2); + // Pre- & post-hook. + hooker.hook(this, "add", { + pre: function(a, b) { + // Arguments are passed into pre-hook as specified. + this.track("before", this.prop, a, b); + }, + post: function(result, a, b) { + // Arguments to post-hook are the original function's return value, + // followed by the specified function arguments. + this.track("after", this.prop, a, b, result); + } + }); + test.strictEqual(this.add(2, 3), 6, "should return the original function's result."); + test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); + test.done(); + }, + + 'pre-hook, return value override': function(test) { + test.expect(2); + // Pre-hook. + hooker.hook(this, "add", { + pre: function(a, b) { + // Arguments are passed into pre-hook as specified. + this.track("before", this.prop, a, b); + // This return value will override the original function's return value. + return hooker.override("b" + this.prop + a + b); + } + }); + test.strictEqual(this.add(2, 3), "b123", "should return the overridden result."); + test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3], "functions should execute in-order."); + test.done(); + }, + 'post-hook, return value override': function(test) { + test.expect(2); + // Post-hook. + hooker.hook(this, "add", { + post: function(result, a, b) { + // Arguments to post-hook are the original function's return value, + // followed by the specified function arguments. + this.track("after", this.prop, a, b, result); + // This return value will override the original function's return value. + return hooker.override("a" + this.prop + a + b + result); + } + }); + test.strictEqual(this.add(2, 3), "a1236", "should return the post-hook overridden result."); + test.deepEqual(this.order, ["add", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); + test.done(); + }, + 'pre- & post-hook, return value override': function(test) { + test.expect(2); + // Pre- & post-hook. + hooker.hook(this, "add", { + pre: function(a, b) { + // Arguments are passed into pre-hook as specified. + this.track("before", this.prop, a, b); + // This return value will override the original function's return value. + return hooker.override("b" + this.prop + a + b); + }, + post: function(result, a, b) { + // Arguments to post-hook are the original function's return value, + // followed by the specified function arguments. + this.track("after", this.prop, a, b, result); + // This return value will override the original function's return value + // AND the pre-hook's return value. + return hooker.override("a" + this.prop + a + b + result); + } + }); + test.strictEqual(this.add(2, 3), "a1236", "should return the overridden result, and post-hook result should take precedence over pre-hook result."); + test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); + test.done(); + }, + + 'pre-hook, filtering arguments': function(test) { + test.expect(2); + // Pre-hook. + hooker.hook(this, "add", { + pre: function(a, b) { + // Arguments are passed into pre-hook as specified. + this.track("before", this.prop, a, b); + // Return hooker.filter(context, arguments) and they will be passed into + // the original function. The "track" and "order" propterites are just + // set here for the same of this unit test. + return hooker.filter({prop: "x", track: this.track, order: this.order}, ["y", "z"]); + } + }); + test.strictEqual(this.add(2, 3), "xyz", "should return the original function's result, given filtered context and arguments."); + test.deepEqual(this.order, ["before", 1, 2, 3, "add", "x", "y", "z"], "functions should execute in-order."); + test.done(); + }, + 'pre- & post-hook, filtering arguments': function(test) { + test.expect(2); + // Pre- & post-hook. + hooker.hook(this, "add", { + pre: function(a, b) { + // Arguments are passed into pre-hook as specified. + this.track("before", this.prop, a, b); + // Return hooker.filter(context, arguments) and they will be passed into + // the original function. The "track" and "order" propterites are just + // set here for the same of this unit test. + return hooker.filter({prop: "x", track: this.track, order: this.order}, ["y", "z"]); + }, + post: function(result, a, b) { + // Arguments to post-hook are the original function's return value, + // followed by the specified function arguments. + this.track("after", this.prop, a, b, result); + } + }); + test.strictEqual(this.add(2, 3), "xyz", "should return the original function's result, given filtered context and arguments."); + test.deepEqual(this.order, ["before", 1, 2, 3, "add", "x", "y", "z", "after", 1, 2, 3, "xyz"], "functions should execute in-order."); + test.done(); + }, + 'pre- & post-hook, filtering arguments, return value override': function(test) { + test.expect(2); + // Pre- & post-hook. + hooker.hook(this, "add", { + pre: function(a, b) { + // Arguments are passed into pre-hook as specified. + this.track("before", this.prop, a, b); + // Return hooker.filter(context, arguments) and they will be passed into + // the original function. The "track" and "order" propterites are just + // set here for the same of this unit test. + return hooker.filter({prop: "x", track: this.track, order: this.order}, ["y", "z"]); + }, + post: function(result, a, b) { + // Arguments to post-hook are the original function's return value, + // followed by the specified function arguments. + this.track("after", this.prop, a, b, result); + // This return value will override the original function's return value + // AND the pre-hook's return value. + return hooker.override("a" + this.prop + a + b + result); + } + }); + test.strictEqual(this.add(2, 3), "a123xyz", "should return the post-hook overridden result."); + test.deepEqual(this.order, ["before", 1, 2, 3, "add", "x", "y", "z", "after", 1, 2, 3, "xyz"], "functions should execute in-order."); + test.done(); + }, + + 'pre-hook, preempt original function': function(test) { + test.expect(2); + // Pre-hook. + hooker.hook(this, "add", { + pre: function(a, b) { + // Arguments are passed into pre-hook as specified. + this.track("before", this.prop, a, b); + // Returning hooker.preempt will prevent the original function from being + // invoked and optionally set a return value. + return hooker.preempt(); + } + }); + test.strictEqual(this.add(2, 3), undefined, "should return the value passed to preempt."); + test.deepEqual(this.order, ["before", 1, 2, 3], "functions should execute in-order."); + test.done(); + }, + 'pre-hook, preempt original function with value': function(test) { + test.expect(2); + // Pre-hook. + hooker.hook(this, "add", { + pre: function(a, b) { + // Arguments are passed into pre-hook as specified. + this.track("before", this.prop, a, b); + // Returning hooker.preempt will prevent the original function from being + // invoked and optionally set a return value. + return hooker.preempt(9000); + } + }); + test.strictEqual(this.add(2, 3), 9000, "should return the value passed to preempt."); + test.deepEqual(this.order, ["before", 1, 2, 3], "functions should execute in-order."); + test.done(); + }, + 'pre- & post-hook, preempt original function with value': function(test) { + test.expect(2); + // Pre- & post-hook. + hooker.hook(this, "add", { + pre: function(a, b) { + // Arguments are passed into pre-hook as specified. + this.track("before", this.prop, a, b); + // Returning hooker.preempt will prevent the original function from being + // invoked and optionally set a return value. + return hooker.preempt(9000); + }, + post: function(result, a, b) { + // Arguments to post-hook are the original function's return value, + // followed by the specified function arguments. + this.track("after", this.prop, a, b, result); + } + }); + test.strictEqual(this.add(2, 3), 9000, "should return the value passed to preempt."); + test.deepEqual(this.order, ["before", 1, 2, 3, "after", 1, 2, 3, 9000], "functions should execute in-order."); + test.done(); + }, + 'pre- & post-hook, preempt original function with value, return value override': function(test) { + test.expect(2); + // Pre- & post-hook. + hooker.hook(this, "add", { + pre: function(a, b) { + // Arguments are passed into pre-hook as specified. + this.track("before", this.prop, a, b); + // Returning hooker.preempt will prevent the original function from being + // invoked and optionally set a return value. + return hooker.preempt(9000); + }, + post: function(result, a, b) { + // Arguments to post-hook are the original function's return value, + // followed by the specified function arguments. + this.track("after", this.prop, a, b, result); + // This return value will override any preempt value set in pre-hook. + return hooker.override("a" + this.prop + a + b + result); + } + }); + test.strictEqual(this.add(2, 3), "a1239000", "should return the overridden result, and post-hook result should take precedence over preempt value."); + test.deepEqual(this.order, ["before", 1, 2, 3, "after", 1, 2, 3, 9000], "functions should execute in-order."); + test.done(); + }, + 'pre- & post-hook, some properties': function(test) { + test.expect(7); + // Pre- & post-hook. + var result = hooker.hook(this.obj, ["add1", "add2"], { + pre: function(a, b) { + // Arguments are passed into pre-hook as specified. + this.that.track("before", this.prop, a, b); + }, + post: function(result, a, b) { + // Arguments to post-hook are the original function's return value, + // followed by the specified function arguments. + this.that.track("after", this.prop, a, b, result); + } + }); + test.deepEqual(result.sort(), ["add1", "add2"], "both functions should have been hooked."); + test.strictEqual(this.obj.add1(2, 3), 6, "should return the original function's result."); + test.deepEqual(this.order, ["before", 1, 2, 3, "add1", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); + this.order = []; + test.strictEqual(this.obj.add2(2, 3), 6, "should return the original function's result."); + test.deepEqual(this.order, ["before", 1, 2, 3, "add2", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); + this.order = []; + test.strictEqual(this.obj.add3(2, 3), 6, "should return the original function's result."); + test.deepEqual(this.order, ["add3", 1, 2, 3], "functions should execute in-order."); + test.done(); + }, + 'pre- & post-hook, all properties': function(test) { + test.expect(7); + // Pre- & post-hook. + var result = hooker.hook(this.obj, { + pre: function(a, b) { + // Arguments are passed into pre-hook as specified. + this.that.track("before", this.prop, a, b); + }, + post: function(result, a, b) { + // Arguments to post-hook are the original function's return value, + // followed by the specified function arguments. + this.that.track("after", this.prop, a, b, result); + } + }); + test.deepEqual(result.sort(), ["add1", "add2", "add3"], "all functions should have been hooked."); + test.strictEqual(this.obj.add1(2, 3), 6, "should return the original function's result."); + test.deepEqual(this.order, ["before", 1, 2, 3, "add1", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); + this.order = []; + test.strictEqual(this.obj.add2(2, 3), 6, "should return the original function's result."); + test.deepEqual(this.order, ["before", 1, 2, 3, "add2", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); + this.order = []; + test.strictEqual(this.obj.add3(2, 3), 6, "should return the original function's result."); + test.deepEqual(this.order, ["before", 1, 2, 3, "add3", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); + test.done(); + }, + 'pre- & post-hook, all properties, passName': function(test) { + test.expect(6); + // Pre- & post-hook. + hooker.hook(this.obj, { + passName: true, + pre: function(name, a, b) { + // Arguments are passed into pre-hook as specified. + this.that.track("before", this.prop, name, a, b); + }, + post: function(result, name, a, b) { + // Arguments to post-hook are the original function's return value, + // followed by the specified function arguments. + this.that.track("after", this.prop, name, a, b, result); + } + }); + test.strictEqual(this.obj.add1(2, 3), 6, "should return the original function's result."); + test.deepEqual(this.order, ["before", 1, "add1", 2, 3, "add1", 1, 2, 3, "after", 1, "add1", 2, 3, 6], "functions should execute in-order."); + this.order = []; + test.strictEqual(this.obj.add2(2, 3), 6, "should return the original function's result."); + test.deepEqual(this.order, ["before", 1, "add2", 2, 3, "add2", 1, 2, 3, "after", 1, "add2", 2, 3, 6], "functions should execute in-order."); + this.order = []; + test.strictEqual(this.obj.add3(2, 3), 6, "should return the original function's result."); + test.deepEqual(this.order, ["before", 1, "add3", 2, 3, "add3", 1, 2, 3, "after", 1, "add3", 2, 3, 6], "functions should execute in-order."); + test.done(); + }, + 'unhook one property': function(test) { + test.expect(5); + var orig = this.add; + hooker.hook(this, "add", function() {}); + var result = hooker.unhook(this, "add"); + test.deepEqual(result, ["add"], "one function should have been unhooked."); + test.strictEqual(this.add, orig, "should have unhooked, restoring the original function"); + result = hooker.unhook(this, "add"); + test.deepEqual(result, [], "nothing should have been unhooked."); + test.strictEqual(this.add, orig, "shouldn't explode if already unhooked"); + test.strictEqual(this.add.orig, undefined, "original function shouldn't have an orig property"); + test.done(); + }, + 'unhook some properties': function(test) { + test.expect(6); + var add1 = this.obj.add1; + var add2 = this.obj.add2; + hooker.hook(this.obj, ["add1", "add2"], function() {}); + test.strictEqual(hooker.orig(this.obj, "add1"), add1, "should return a refernce to the original function"); + test.strictEqual(hooker.orig(this.obj, "add2"), add2, "should return a refernce to the original function"); + test.strictEqual(hooker.orig(this.obj, "add3"), undefined, "should not have been hooked, so should not have an original function"); + var result = hooker.unhook(this.obj, ["add1", "add2"]); + test.deepEqual(result.sort(), ["add1", "add2"], "both functions should have been unhooked."); + test.strictEqual(this.obj.add1, add1, "should have unhooked, restoring the original function"); + test.strictEqual(this.obj.add2, add2, "should have unhooked, restoring the original function"); + test.done(); + }, + 'unhook all properties': function(test) { + test.expect(7); + var add1 = this.obj.add1; + var add2 = this.obj.add2; + var add3 = this.obj.add3; + hooker.hook(this.obj, function() {}); + test.strictEqual(hooker.orig(this.obj, "add1"), add1, "should return a refernce to the original function"); + test.strictEqual(hooker.orig(this.obj, "add2"), add2, "should return a refernce to the original function"); + test.strictEqual(hooker.orig(this.obj, "add3"), add3, "should return a refernce to the original function"); + var result = hooker.unhook(this.obj); + test.deepEqual(result.sort(), ["add1", "add2", "add3"], "all functions should have been unhooked."); + test.strictEqual(this.obj.add1, add1, "should have unhooked, restoring the original function"); + test.strictEqual(this.obj.add2, add2, "should have unhooked, restoring the original function"); + test.strictEqual(this.obj.add3, add3, "should have unhooked, restoring the original function"); + test.done(); + } +}; diff --git a/node_modules/hosted-git-info/.npmignore b/node_modules/hosted-git-info/.npmignore new file mode 100644 index 0000000..efab07f --- /dev/null +++ b/node_modules/hosted-git-info/.npmignore @@ -0,0 +1,2 @@ +test +.travis.yml diff --git a/node_modules/hosted-git-info/LICENSE b/node_modules/hosted-git-info/LICENSE new file mode 100644 index 0000000..4505576 --- /dev/null +++ b/node_modules/hosted-git-info/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2015, Rebecca Turner + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/hosted-git-info/README.md b/node_modules/hosted-git-info/README.md new file mode 100644 index 0000000..1db47dd --- /dev/null +++ b/node_modules/hosted-git-info/README.md @@ -0,0 +1,99 @@ +# hosted-git-info + +This will let you identify and transform various git hosts URLs between +protocols. It also can tell you what the URL is for the raw path for +particular file for direct access without git. + +## Usage + +```javascript +var hostedGitInfo = require("hosted-git-info") +var info = hostedGitInfo.fromUrl("git@github.com:npm/hosted-git-info.git") +/* info looks like: +{ + type: "github", + domain: "github.com", + user: "npm", + project: "hosted-git-info" +} +*/ +``` + +If the URL can't be matched with a git host, `null` will be returned. We +can match git, ssh and https urls. Additionally, we can match ssh connect +strings (`git@github.com:npm/hosted-git-info`) and shortcuts (eg, +`github:npm/hosted-git-info`). Github specifically, is detected in the case +of a third, unprefixed, form: `npm/hosted-git-info`. + +If it does match, the returned object has properties of: + +* info.type -- The short name of the service +* info.domain -- The domain for git protocol use +* info.user -- The name of the user/org on the git host +* info.project -- The name of the project on the git host + +And methods of: + +* info.file(path) + +Given the path of a file relative to the repository, returns a URL for +directly fetching it from the githost. If no committish was set then +`master` will be used as the default. + +For example `hostedGitInfo.fromUrl("git@github.com:npm/hosted-git-info.git#v1.0.0").file("package.json")` +would return `https://raw.githubusercontent.com/npm/hosted-git-info/v1.0.0/package.json` + +* info.shortcut() + +eg, `github:npm/hosted-git-info` + +* info.browse() + +eg, `https://github.com/npm/hosted-git-info/tree/v1.2.0` + +* info.bugs() + +eg, `https://github.com/npm/hosted-git-info/issues` + +* info.docs() + +eg, `https://github.com/npm/hosted-git-info/tree/v1.2.0#readme` + +* info.https() + +eg, `git+https://github.com/npm/hosted-git-info.git` + +* info.sshurl() + +eg, `git+ssh://git@github.com/npm/hosted-git-info.git` + +* info.ssh() + +eg, `git@github.com:npm/hosted-git-info.git` + +* info.path() + +eg, `npm/hosted-git-info` + +* info.getDefaultRepresentation() + +Returns the default output type. The default output type is based on the +string you passed in to be parsed + +* info.toString() + +Uses the getDefaultRepresentation to call one of the other methods to get a URL for +this resource. As such `hostedGitInfo.fromUrl(url).toString()` will give +you a normalized version of the URL that still uses the same protocol. + +Shortcuts will still be returned as shortcuts, but the special case github +form of `org/project` will be normalized to `github:org/project`. + +SSH connect strings will be normalized into `git+ssh` URLs. + + +## Supported hosts + +Currently this supports Github, Bitbucket and Gitlab. Pull requests for +additional hosts welcome. + diff --git a/node_modules/hosted-git-info/git-host-info.js b/node_modules/hosted-git-info/git-host-info.js new file mode 100644 index 0000000..2234333 --- /dev/null +++ b/node_modules/hosted-git-info/git-host-info.js @@ -0,0 +1,64 @@ +'use strict' + +var gitHosts = module.exports = { + github: { + // First two are insecure and generally shouldn't be used any more, but + // they are still supported. + 'protocols': [ 'git', 'http', 'git+ssh', 'git+https', 'ssh', 'https' ], + 'domain': 'github.com', + 'treepath': 'tree', + 'filetemplate': 'https://{auth@}raw.githubusercontent.com/{user}/{project}/{committish}/{path}', + 'bugstemplate': 'https://{domain}/{user}/{project}/issues', + 'gittemplate': 'git://{auth@}{domain}/{user}/{project}.git{#committish}' + }, + bitbucket: { + 'protocols': [ 'git+ssh', 'git+https', 'ssh', 'https' ], + 'domain': 'bitbucket.org', + 'treepath': 'src' + }, + gitlab: { + 'protocols': [ 'git+ssh', 'git+https', 'ssh', 'https' ], + 'domain': 'gitlab.com', + 'treepath': 'tree', + 'docstemplate': 'https://{domain}/{user}/{project}{/tree/committish}#README', + 'bugstemplate': 'https://{domain}/{user}/{project}/issues' + }, + gist: { + 'protocols': [ 'git', 'git+ssh', 'git+https', 'ssh', 'https' ], + 'domain': 'gist.github.com', + 'pathmatch': /^[/](?:([^/]+)[/])?([a-z0-9]+)(?:[.]git)?$/, + 'filetemplate': 'https://gist.githubusercontent.com/{user}/{project}/raw{/committish}/{path}', + 'bugstemplate': 'https://{domain}/{project}', + 'gittemplate': 'git://{domain}/{project}.git{#committish}', + 'sshtemplate': 'git@{domain}:/{project}.git{#committish}', + 'sshurltemplate': 'git+ssh://git@{domain}/{project}.git{#committish}', + 'browsetemplate': 'https://{domain}/{project}{/committish}', + 'docstemplate': 'https://{domain}/{project}{/committish}', + 'httpstemplate': 'git+https://{domain}/{project}.git{#committish}', + 'shortcuttemplate': '{type}:{project}{#committish}', + 'pathtemplate': '{project}{#committish}' + } +} + +var gitHostDefaults = { + 'sshtemplate': 'git@{domain}:{user}/{project}.git{#committish}', + 'sshurltemplate': 'git+ssh://git@{domain}/{user}/{project}.git{#committish}', + 'browsetemplate': 'https://{domain}/{user}/{project}{/tree/committish}', + 'docstemplate': 'https://{domain}/{user}/{project}{/tree/committish}#readme', + 'httpstemplate': 'git+https://{auth@}{domain}/{user}/{project}.git{#committish}', + 'filetemplate': 'https://{domain}/{user}/{project}/raw/{committish}/{path}', + 'shortcuttemplate': '{type}:{user}/{project}{#committish}', + 'pathtemplate': '{user}/{project}{#committish}', + 'pathmatch': /^[/]([^/]+)[/]([^/]+?)(?:[.]git)?$/ +} + +Object.keys(gitHosts).forEach(function (name) { + Object.keys(gitHostDefaults).forEach(function (key) { + if (gitHosts[name][key]) return + gitHosts[name][key] = gitHostDefaults[key] + }) + gitHosts[name].protocols_re = RegExp('^(' + + gitHosts[name].protocols.map(function (protocol) { + return protocol.replace(/([\\+*{}()\[\]$^|])/g, '\\$1') + }).join('|') + '):$') +}) diff --git a/node_modules/hosted-git-info/git-host.js b/node_modules/hosted-git-info/git-host.js new file mode 100644 index 0000000..ea31380 --- /dev/null +++ b/node_modules/hosted-git-info/git-host.js @@ -0,0 +1,96 @@ +'use strict' +var gitHosts = require('./git-host-info.js') + +var GitHost = module.exports = function (type, user, auth, project, committish, defaultRepresentation) { + var gitHostInfo = this + gitHostInfo.type = type + Object.keys(gitHosts[type]).forEach(function (key) { + gitHostInfo[key] = gitHosts[type][key] + }) + gitHostInfo.user = user + gitHostInfo.auth = auth + gitHostInfo.project = project + gitHostInfo.committish = committish + gitHostInfo.default = defaultRepresentation +} +GitHost.prototype = {} + +GitHost.prototype.hash = function () { + return this.committish ? '#' + this.committish : '' +} + +GitHost.prototype._fill = function (template, vars) { + if (!template) return + if (!vars) vars = {} + var self = this + Object.keys(this).forEach(function (key) { + if (self[key] != null && vars[key] == null) vars[key] = self[key] + }) + var rawAuth = vars.auth + var rawComittish = vars.committish + Object.keys(vars).forEach(function (key) { + vars[key] = encodeURIComponent(vars[key]) + }) + vars['auth@'] = rawAuth ? rawAuth + '@' : '' + vars['#committish'] = rawComittish ? '#' + rawComittish : '' + vars['/tree/committish'] = vars.committish + ? '/' + vars.treepath + '/' + vars.committish + : '' + vars['/committish'] = vars.committish ? '/' + vars.committish : '' + vars.committish = vars.committish || 'master' + var res = template + Object.keys(vars).forEach(function (key) { + res = res.replace(new RegExp('[{]' + key + '[}]', 'g'), vars[key]) + }) + return res +} + +GitHost.prototype.ssh = function () { + return this._fill(this.sshtemplate) +} + +GitHost.prototype.sshurl = function () { + return this._fill(this.sshurltemplate) +} + +GitHost.prototype.browse = function () { + return this._fill(this.browsetemplate) +} + +GitHost.prototype.docs = function () { + return this._fill(this.docstemplate) +} + +GitHost.prototype.bugs = function () { + return this._fill(this.bugstemplate) +} + +GitHost.prototype.https = function () { + return this._fill(this.httpstemplate) +} + +GitHost.prototype.git = function () { + return this._fill(this.gittemplate) +} + +GitHost.prototype.shortcut = function () { + return this._fill(this.shortcuttemplate) +} + +GitHost.prototype.path = function () { + return this._fill(this.pathtemplate) +} + +GitHost.prototype.file = function (P) { + return this._fill(this.filetemplate, { + path: P.replace(/^[/]+/g, '') + }) +} + +GitHost.prototype.getDefaultRepresentation = function () { + return this.default +} + +GitHost.prototype.toString = function () { + return (this[this.default] || this.sshurl).call(this) +} diff --git a/node_modules/hosted-git-info/index.js b/node_modules/hosted-git-info/index.js new file mode 100644 index 0000000..453ce87 --- /dev/null +++ b/node_modules/hosted-git-info/index.js @@ -0,0 +1,103 @@ +'use strict' +var url = require('url') +var gitHosts = require('./git-host-info.js') +var GitHost = module.exports = require('./git-host.js') + +var protocolToRepresentationMap = { + 'git+ssh': 'sshurl', + 'git+https': 'https', + 'ssh': 'sshurl', + 'git': 'git' +} + +function protocolToRepresentation (protocol) { + if (protocol.substr(-1) === ':') protocol = protocol.slice(0, -1) + return protocolToRepresentationMap[protocol] || protocol +} + +var authProtocols = { + 'git:': true, + 'https:': true, + 'git+https:': true, + 'http:': true, + 'git+http:': true +} + +module.exports.fromUrl = function (giturl) { + if (giturl == null || giturl === '') return + var url = fixupUnqualifiedGist( + isGitHubShorthand(giturl) ? 'github:' + giturl : giturl + ) + var parsed = parseGitUrl(url) + var matches = Object.keys(gitHosts).map(function (gitHostName) { + var gitHostInfo = gitHosts[gitHostName] + var auth = null + if (parsed.auth && authProtocols[parsed.protocol]) { + auth = decodeURIComponent(parsed.auth) + } + var committish = parsed.hash ? decodeURIComponent(parsed.hash.substr(1)) : null + var user = null + var project = null + var defaultRepresentation = null + if (parsed.protocol === gitHostName + ':') { + user = decodeURIComponent(parsed.host) + project = parsed.path && decodeURIComponent(parsed.path.replace(/^[/](.*?)(?:[.]git)?$/, '$1')) + defaultRepresentation = 'shortcut' + } else { + if (parsed.host !== gitHostInfo.domain) return + if (!gitHostInfo.protocols_re.test(parsed.protocol)) return + var pathmatch = gitHostInfo.pathmatch + var matched = parsed.path.match(pathmatch) + if (!matched) return + if (matched[1] != null) user = decodeURIComponent(matched[1]) + if (matched[2] != null) project = decodeURIComponent(matched[2]) + defaultRepresentation = protocolToRepresentation(parsed.protocol) + } + return new GitHost(gitHostName, user, auth, project, committish, defaultRepresentation) + }).filter(function (gitHostInfo) { return gitHostInfo }) + if (matches.length !== 1) return + return matches[0] +} + +function isGitHubShorthand (arg) { + // Note: This does not fully test the git ref format. + // See https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html + // + // The only way to do this properly would be to shell out to + // git-check-ref-format, and as this is a fast sync function, + // we don't want to do that. Just let git fail if it turns + // out that the commit-ish is invalid. + // GH usernames cannot start with . or - + return /^[^:@%/\s.-][^:@%/\s]*[/][^:@\s/%]+(?:#.*)?$/.test(arg) +} + +function fixupUnqualifiedGist (giturl) { + // necessary for round-tripping gists + var parsed = url.parse(giturl) + if (parsed.protocol === 'gist:' && parsed.host && !parsed.path) { + return parsed.protocol + '/' + parsed.host + } else { + return giturl + } +} + +function parseGitUrl (giturl) { + if (typeof giturl !== 'string') giturl = '' + giturl + var matched = giturl.match(/^([^@]+)@([^:]+):[/]?((?:[^/]+[/])?[^/]+?)(?:[.]git)?(#.*)?$/) + if (!matched) return url.parse(giturl) + return { + protocol: 'git+ssh:', + slashes: true, + auth: matched[1], + host: matched[2], + port: null, + hostname: matched[2], + hash: matched[4], + search: null, + query: null, + pathname: '/' + matched[3], + path: '/' + matched[3], + href: 'git+ssh://' + matched[1] + '@' + matched[2] + + '/' + matched[3] + (matched[4] || '') + } +} diff --git a/node_modules/hosted-git-info/package.json b/node_modules/hosted-git-info/package.json new file mode 100644 index 0000000..95a049a --- /dev/null +++ b/node_modules/hosted-git-info/package.json @@ -0,0 +1,102 @@ +{ + "_args": [ + [ + { + "raw": "hosted-git-info@^2.1.4", + "scope": null, + "escapedName": "hosted-git-info", + "name": "hosted-git-info", + "rawSpec": "^2.1.4", + "spec": ">=2.1.4 <3.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/normalize-package-data" + ] + ], + "_from": "hosted-git-info@>=2.1.4 <3.0.0", + "_id": "hosted-git-info@2.1.5", + "_inCache": true, + "_location": "/hosted-git-info", + "_nodeVersion": "5.10.1", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/hosted-git-info-2.1.5.tgz_1463518889246_0.20443619322031736" + }, + "_npmUser": { + "name": "zkat", + "email": "kat@sykosomatic.org" + }, + "_npmVersion": "3.9.1", + "_phantomChildren": {}, + "_requested": { + "raw": "hosted-git-info@^2.1.4", + "scope": null, + "escapedName": "hosted-git-info", + "name": "hosted-git-info", + "rawSpec": "^2.1.4", + "spec": ">=2.1.4 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/normalize-package-data" + ], + "_resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.1.5.tgz", + "_shasum": "0ba81d90da2e25ab34a332e6ec77936e1598118b", + "_shrinkwrap": null, + "_spec": "hosted-git-info@^2.1.4", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/normalize-package-data", + "author": { + "name": "Rebecca Turner", + "email": "me@re-becca.org", + "url": "http://re-becca.org" + }, + "bugs": { + "url": "https://github.com/npm/hosted-git-info/issues" + }, + "dependencies": {}, + "description": "Provides metadata and conversions from repository urls for Github, Bitbucket and Gitlab", + "devDependencies": { + "standard": "^3.3.2", + "tap": "^0.4.13" + }, + "directories": {}, + "dist": { + "shasum": "0ba81d90da2e25ab34a332e6ec77936e1598118b", + "tarball": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.1.5.tgz" + }, + "gitHead": "4e6bb323a97a57c18e6b4b891527e26154d04fbe", + "homepage": "https://github.com/npm/hosted-git-info", + "keywords": [ + "git", + "github", + "bitbucket", + "gitlab" + ], + "license": "ISC", + "main": "index.js", + "maintainers": [ + { + "name": "iarna", + "email": "me@re-becca.org" + }, + { + "name": "othiym23", + "email": "ogd@aoaioxxysz.net" + }, + { + "name": "zkat", + "email": "kat@sykosomatic.org" + } + ], + "name": "hosted-git-info", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/hosted-git-info.git" + }, + "scripts": { + "test": "standard && tap test/*.js" + }, + "version": "2.1.5" +} diff --git a/node_modules/htmlparser2/.gitattributes b/node_modules/htmlparser2/.gitattributes new file mode 100644 index 0000000..4bb50dc --- /dev/null +++ b/node_modules/htmlparser2/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text eol=lf \ No newline at end of file diff --git a/node_modules/htmlparser2/.jscsrc b/node_modules/htmlparser2/.jscsrc new file mode 100644 index 0000000..bf1a6d3 --- /dev/null +++ b/node_modules/htmlparser2/.jscsrc @@ -0,0 +1,30 @@ +{ + "requireCurlyBraces": ["do", "switch", "return", "try", "catch"], + "requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", "<", ">=", "<="], + "requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", "<", ">=", "<="], + "requireSpaceAfterKeywords": ["else", "do", "switch", "return", "try"], + "disallowSpaceAfterKeywords": ["if", "catch", "for", "while"], + "disallowSpacesInFunctionExpression": { "beforeOpeningCurlyBrace": true }, + + "requireCapitalizedConstructors": true, + "requireCommaBeforeLineBreak": true, + "requireDotNotation": true, + "requireParenthesesAroundIIFE": true, + + "disallowEmptyBlocks": true, + + "disallowSpaceAfterPrefixUnaryOperators": ["!"], + "disallowSpaceBeforeBinaryOperators": [","], + "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], + "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], + + "disallowKeywords": ["with"], + "disallowMultipleLineStrings": true, + "disallowTrailingWhitespace": true, + + "validateIndentation": "\t", + "validateLineBreaks": "LF", + "validateQuoteMarks": "\"", + + "safeContextKeyword": "_this" +} diff --git a/node_modules/htmlparser2/.travis.yml b/node_modules/htmlparser2/.travis.yml new file mode 100644 index 0000000..5dfe363 --- /dev/null +++ b/node_modules/htmlparser2/.travis.yml @@ -0,0 +1,8 @@ +language: node_js +node_js: + - 0.10 + - 0.11 + +sudo: false + +script: npm run coveralls diff --git a/node_modules/htmlparser2/LICENSE b/node_modules/htmlparser2/LICENSE new file mode 100644 index 0000000..0a35e02 --- /dev/null +++ b/node_modules/htmlparser2/LICENSE @@ -0,0 +1,18 @@ +Copyright 2010, 2011, Chris Winberry . All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/htmlparser2/README.md b/node_modules/htmlparser2/README.md new file mode 100644 index 0000000..8d12a0b --- /dev/null +++ b/node_modules/htmlparser2/README.md @@ -0,0 +1,91 @@ +# htmlparser2 + +[![NPM version](http://img.shields.io/npm/v/htmlparser2.svg?style=flat)](https://npmjs.org/package/htmlparser2) +[![Downloads](https://img.shields.io/npm/dm/htmlparser2.svg?style=flat)](https://npmjs.org/package/htmlparser2) +[![Build Status](http://img.shields.io/travis/fb55/htmlparser2/master.svg?style=flat)](http://travis-ci.org/fb55/htmlparser2) +[![Coverage](http://img.shields.io/coveralls/fb55/htmlparser2.svg?style=flat)](https://coveralls.io/r/fb55/htmlparser2) + +A forgiving HTML/XML/RSS parser. The parser can handle streams and provides a callback interface. + +## Installation + npm install htmlparser2 + +A live demo of htmlparser2 is available [here](http://demos.forbeslindesay.co.uk/htmlparser2/). + +## Usage + +```javascript +var htmlparser = require("htmlparser2"); +var parser = new htmlparser.Parser({ + onopentag: function(name, attribs){ + if(name === "script" && attribs.type === "text/javascript"){ + console.log("JS! Hooray!"); + } + }, + ontext: function(text){ + console.log("-->", text); + }, + onclosetag: function(tagname){ + if(tagname === "script"){ + console.log("That's it?!"); + } + } +}, {decodeEntities: true}); +parser.write("Xyz

          ", + "expected": [ + { + "event": "opentagname", + "data": [ + "p" + ] + }, + { + "event": "opentag", + "data": [ + "p", + {} + ] + }, + { + "event": "opentagname", + "data": [ + "script" + ] + }, + { + "event": "attribute", + "data": [ + "type", + "text/template" + ] + }, + { + "event": "opentag", + "data": [ + "script", + { + "type": "text/template" + } + ] + }, + { + "event": "text", + "data": [ + "

          Heading1

          " + ] + }, + { + "event": "closetag", + "data": [ + "script" + ] + }, + { + "event": "closetag", + "data": [ + "p" + ] + } + ] +} \ No newline at end of file diff --git a/node_modules/htmlparser2/test/Events/03-lowercase_tags.json b/node_modules/htmlparser2/test/Events/03-lowercase_tags.json new file mode 100644 index 0000000..9b58c59 --- /dev/null +++ b/node_modules/htmlparser2/test/Events/03-lowercase_tags.json @@ -0,0 +1,46 @@ +{ + "name": "Lowercase tags", + "options": { + "handler": {}, + "parser": { + "lowerCaseTags": true + } + }, + "html": "

          adsf

          ", + "expected": [ + { + "event": "opentagname", + "data": [ + "h1" + ] + }, + { + "event": "attribute", + "data": [ + "class", + "test" + ] + }, + { + "event": "opentag", + "data": [ + "h1", + { + "class": "test" + } + ] + }, + { + "event": "text", + "data": [ + "adsf" + ] + }, + { + "event": "closetag", + "data": [ + "h1" + ] + } + ] +} \ No newline at end of file diff --git a/node_modules/htmlparser2/test/Events/04-cdata.json b/node_modules/htmlparser2/test/Events/04-cdata.json new file mode 100644 index 0000000..6032b68 --- /dev/null +++ b/node_modules/htmlparser2/test/Events/04-cdata.json @@ -0,0 +1,50 @@ +{ + "name": "CDATA", + "options": { + "handler": {}, + "parser": {"xmlMode": true} + }, + "html": "<> fo]]>", + "expected": [ + { + "event": "opentagname", + "data": [ + "tag" + ] + }, + { + "event": "opentag", + "data": [ + "tag", + {} + ] + }, + { + "event": "cdatastart", + "data": [] + }, + { + "event": "text", + "data": [ + " asdf ><> fo" + ] + }, + { + "event": "cdataend", + "data": [] + }, + { + "event": "closetag", + "data": [ + "tag" + ] + }, + { + "event": "processinginstruction", + "data": [ + "![CD", + "![CD" + ] + } + ] +} \ No newline at end of file diff --git a/node_modules/htmlparser2/test/Events/05-cdata-special.json b/node_modules/htmlparser2/test/Events/05-cdata-special.json new file mode 100644 index 0000000..686cb1a --- /dev/null +++ b/node_modules/htmlparser2/test/Events/05-cdata-special.json @@ -0,0 +1,35 @@ +{ + "name": "CDATA (inside special)", + "options": { + "handler": {}, + "parser": {} + }, + "html": "", + "expected": [ + { + "event": "opentagname", + "data": [ + "script" + ] + }, + { + "event": "opentag", + "data": [ + "script", + {} + ] + }, + { + "event": "text", + "data": [ + "/*<> fo/*]]>*/" + ] + }, + { + "event": "closetag", + "data": [ + "script" + ] + } + ] +} diff --git a/node_modules/htmlparser2/test/Events/06-leading-lt.json b/node_modules/htmlparser2/test/Events/06-leading-lt.json new file mode 100644 index 0000000..fcec852 --- /dev/null +++ b/node_modules/htmlparser2/test/Events/06-leading-lt.json @@ -0,0 +1,16 @@ +{ + "name": "leading lt", + "options": { + "handler": {}, + "parser": {} + }, + "html": ">a>", + "expected": [ + { + "event": "text", + "data": [ + ">a>" + ] + } + ] +} \ No newline at end of file diff --git a/node_modules/htmlparser2/test/Events/07-self-closing.json b/node_modules/htmlparser2/test/Events/07-self-closing.json new file mode 100644 index 0000000..49ed93b --- /dev/null +++ b/node_modules/htmlparser2/test/Events/07-self-closing.json @@ -0,0 +1,67 @@ +{ + "name": "Self-closing tags", + "options": { + "handler": { + + }, + "parser": { + + } + }, + "html": "Foo
          ", + "expected": [ + { + "event": "opentagname", + "data": [ + "a" + ] + }, + { + "event": "attribute", + "data": [ + "href", + "http://test.com/" + ] + }, + { + "event": "opentag", + "data": [ + "a", + { + "href": "http://test.com/" + } + ] + }, + { + "event": "text", + "data": [ + "Foo" + ] + }, + { + "event": "closetag", + "data": [ + "a" + ] + }, + { + "event": "opentagname", + "data": [ + "hr" + ] + }, + { + "event": "opentag", + "data": [ + "hr", + {} + ] + }, + { + "event": "closetag", + "data": [ + "hr" + ] + } + ] +} \ No newline at end of file diff --git a/node_modules/htmlparser2/test/Events/08-implicit-close-tags.json b/node_modules/htmlparser2/test/Events/08-implicit-close-tags.json new file mode 100644 index 0000000..331e785 --- /dev/null +++ b/node_modules/htmlparser2/test/Events/08-implicit-close-tags.json @@ -0,0 +1,71 @@ +{ + "name": "Implicit close tags", + "options": {}, + "html": "
          1. TH

            Heading

            Div
            Div2
          2. Heading 2

          Para

          Heading 4

          ", + "expected": [ + { "event": "opentagname", "data": [ "ol" ] }, + { "event": "opentag", "data": [ "ol", {} ] }, + { "event": "opentagname", "data": [ "li" ] }, + { "event": "attribute", "data": [ "class", "test" ] }, + { "event": "opentag", "data": [ "li", { "class": "test" } ] }, + { "event": "opentagname", "data": [ "div" ] }, + { "event": "opentag", "data": [ "div", {} ] }, + { "event": "opentagname", "data": [ "table" ] }, + { "event": "attribute", "data": [ "style", "width:100%" ] }, + { "event": "opentag", "data": [ "table", { "style": "width:100%" } ] }, + { "event": "opentagname", "data": [ "tr" ] }, + { "event": "opentag", "data": [ "tr", {} ] }, + { "event": "opentagname", "data": [ "th" ] }, + { "event": "opentag", "data": [ "th", {} ] }, + { "event": "text", "data": [ "TH" ] }, + { "event": "closetag", "data": [ "th" ] }, + { "event": "opentagname", "data": [ "td" ] }, + { "event": "attribute", "data": [ "colspan", "2" ] }, + { "event": "opentag", "data": [ "td", { "colspan": "2" } ] }, + { "event": "opentagname", "data": [ "h3" ] }, + { "event": "opentag", "data": [ "h3", {} ] }, + { "event": "text", "data": [ "Heading" ] }, + { "event": "closetag", "data": [ "h3" ] }, + { "event": "closetag", "data": [ "td" ] }, + { "event": "closetag", "data": [ "tr" ] }, + { "event": "opentagname", "data": [ "tr" ] }, + { "event": "opentag", "data": [ "tr", {} ] }, + { "event": "opentagname", "data": [ "td" ] }, + { "event": "opentag", "data": [ "td", {} ] }, + { "event": "opentagname", "data": [ "div" ] }, + { "event": "opentag", "data": [ "div", {} ] }, + { "event": "text", "data": [ "Div" ] }, + { "event": "closetag", "data": [ "div" ] }, + { "event": "closetag", "data": [ "td" ] }, + { "event": "opentagname", "data": [ "td" ] }, + { "event": "opentag", "data": [ "td", {} ] }, + { "event": "opentagname", "data": [ "div" ] }, + { "event": "opentag", "data": [ "div", {} ] }, + { "event": "text", "data": [ "Div2" ] }, + { "event": "closetag", "data": [ "div" ] }, + { "event": "closetag", "data": [ "td" ] }, + { "event": "closetag", "data": [ "tr" ] }, + { "event": "closetag", "data": [ "table" ] }, + { "event": "closetag", "data": [ "div" ] }, + { "event": "closetag", "data": [ "li" ] }, + { "event": "opentagname", "data": [ "li" ] }, + { "event": "opentag", "data": [ "li", {} ] }, + { "event": "opentagname", "data": [ "div" ] }, + { "event": "opentag", "data": [ "div", {} ] }, + { "event": "opentagname", "data": [ "h3" ] }, + { "event": "opentag", "data": [ "h3", {} ] }, + { "event": "text", "data": [ "Heading 2" ] }, + { "event": "closetag", "data": [ "h3" ] }, + { "event": "closetag", "data": [ "div" ] }, + { "event": "closetag", "data": [ "li" ] }, + { "event": "closetag", "data": [ "ol" ] }, + { "event": "opentagname", "data": [ "p" ] }, + { "event": "opentag", "data": [ "p", {} ] }, + { "event": "text", "data": [ "Para" ] }, + { "event": "closetag", "data": [ "p" ] }, + { "event": "opentagname", "data": [ "h4" ] }, + { "event": "opentag", "data": [ "h4", {} ] }, + { "event": "text", "data": [ "Heading 4" ] }, + { "event": "closetag", "data": [ "h4" ] } + ] +} \ No newline at end of file diff --git a/node_modules/htmlparser2/test/Events/09-attributes.json b/node_modules/htmlparser2/test/Events/09-attributes.json new file mode 100644 index 0000000..afa6e4a --- /dev/null +++ b/node_modules/htmlparser2/test/Events/09-attributes.json @@ -0,0 +1,68 @@ +{ + "name": "attributes (no white space, no value, no quotes)", + "options": { + "handler": {}, + "parser": {} + }, + "html": "", + "expected": [ + { + "event": "opentagname", + "data": [ + "button" + ] + }, + { + "event": "attribute", + "data": [ + "class", + "test0" + ] + }, + { + "event": "attribute", + "data": [ + "title", + "test1" + ] + }, + { + "event": "attribute", + "data": [ + "disabled", + "" + ] + }, + { + "event": "attribute", + "data": [ + "value", + "test2" + ] + }, + { + "event": "opentag", + "data": [ + "button", + { + "class": "test0", + "title": "test1", + "disabled": "", + "value": "test2" + } + ] + }, + { + "event": "text", + "data": [ + "adsf" + ] + }, + { + "event": "closetag", + "data": [ + "button" + ] + } + ] +} \ No newline at end of file diff --git a/node_modules/htmlparser2/test/Events/10-crazy-attrib.json b/node_modules/htmlparser2/test/Events/10-crazy-attrib.json new file mode 100644 index 0000000..00bad5f --- /dev/null +++ b/node_modules/htmlparser2/test/Events/10-crazy-attrib.json @@ -0,0 +1,52 @@ +{ + "name": "crazy attribute", + "options": { + "handler": {}, + "parser": {} + }, + "html": "

          stuff

          ", + "expected": [ + { + "event": "opentagname", + "data": [ + "p" + ] + }, + { + "event": "opentag", + "data": [ + "p", + {} + ] + }, + { + "event": "opentagname", + "data": [ + "script" + ] + }, + { + "event": "opentag", + "data": [ + "script", + {} + ] + }, + { + "event": "text", + "data": [ + "var str = '", + "expected": [ + { + "event": "opentagname", + "data": [ + "script" + ] + }, + { + "event": "opentag", + "data": [ + "script", + {} + ] + }, + { + "event": "text", + "data": [ + "", + "expected": [ + { + "event": "text", + "data": [ + "< >" + ] + } + ] +} diff --git a/node_modules/htmlparser2/test/Events/26-not-quite-closed.json b/node_modules/htmlparser2/test/Events/26-not-quite-closed.json new file mode 100644 index 0000000..8504440 --- /dev/null +++ b/node_modules/htmlparser2/test/Events/26-not-quite-closed.json @@ -0,0 +1,35 @@ +{ + "name": "Not quite closed", + "options": {}, + "html": "", + "expected": [ + { + "event": "opentagname", + "data": [ + "foo" + ] + }, + { + "event": "attribute", + "data": [ + "bar", + "" + ] + }, + { + "event": "opentag", + "data": [ + "foo", + { + "bar": "" + } + ] + }, + { + "event": "closetag", + "data": [ + "foo" + ] + } + ] +} diff --git a/node_modules/htmlparser2/test/Events/27-entities_in_attributes.json b/node_modules/htmlparser2/test/Events/27-entities_in_attributes.json new file mode 100644 index 0000000..b03cbdf --- /dev/null +++ b/node_modules/htmlparser2/test/Events/27-entities_in_attributes.json @@ -0,0 +1,62 @@ +{ + "name": "Entities in attributes", + "options": { + "handler": {}, + "parser": {"decodeEntities": true} + }, + "html": "", + "expected": [ + { + "event": "opentagname", + "data": [ + "foo" + ] + }, + { + "event": "attribute", + "data": [ + "bar", + "&" + ] + }, + { + "event": "attribute", + "data": [ + "baz", + "&" + ] + }, + { + "event": "attribute", + "data": [ + "boo", + "&" + ] + }, + { + "event": "attribute", + "data": [ + "noo", + "" + ] + }, + { + "event": "opentag", + "data": [ + "foo", + { + "bar": "&", + "baz": "&", + "boo": "&", + "noo": "" + } + ] + }, + { + "event": "closetag", + "data": [ + "foo" + ] + } + ] +} diff --git a/node_modules/htmlparser2/test/Events/28-cdata_in_html.json b/node_modules/htmlparser2/test/Events/28-cdata_in_html.json new file mode 100644 index 0000000..80c033b --- /dev/null +++ b/node_modules/htmlparser2/test/Events/28-cdata_in_html.json @@ -0,0 +1,9 @@ +{ + "name": "CDATA in HTML", + "options": {}, + "html": "", + "expected": [ + { "event": "comment", "data": [ "[CDATA[ foo ]]" ] }, + { "event": "commentend", "data": [] } + ] +} \ No newline at end of file diff --git a/node_modules/htmlparser2/test/Events/29-comment_edge-cases.json b/node_modules/htmlparser2/test/Events/29-comment_edge-cases.json new file mode 100644 index 0000000..9d9709a --- /dev/null +++ b/node_modules/htmlparser2/test/Events/29-comment_edge-cases.json @@ -0,0 +1,18 @@ +{ + "name": "Comment edge-cases", + "options": {}, + "html": "", + "expected": [ + { "event": "comment", "data": [ " a-b-> " ] }, + { "event": "commentend", "data": [] } + ] +} diff --git a/node_modules/htmlparser2/test/Feeds/01-rss.js b/node_modules/htmlparser2/test/Feeds/01-rss.js new file mode 100644 index 0000000..a3aae47 --- /dev/null +++ b/node_modules/htmlparser2/test/Feeds/01-rss.js @@ -0,0 +1,34 @@ +exports.name = "RSS (2.0)"; +exports.file = "/RSS_Example.xml"; +exports.expected = { + type: "rss", + id: "", + title: "Liftoff News", + link: "http://liftoff.msfc.nasa.gov/", + description: "Liftoff to Space Exploration.", + updated: new Date("Tue, 10 Jun 2003 09:41:01 GMT"), + author: "editor@example.com", + items: [{ + id: "http://liftoff.msfc.nasa.gov/2003/06/03.html#item573", + title: "Star City", + link: "http://liftoff.msfc.nasa.gov/news/2003/news-starcity.asp", + description: "How do Americans get ready to work with Russians aboard the International Space Station? They take a crash course in culture, language and protocol at Russia's <a href=\"http://howe.iki.rssi.ru/GCTC/gctc_e.htm\">Star City</a>.", + pubDate: new Date("Tue, 03 Jun 2003 09:39:21 GMT") + }, { + id: "http://liftoff.msfc.nasa.gov/2003/05/30.html#item572", + description: "Sky watchers in Europe, Asia, and parts of Alaska and Canada will experience a <a href=\"http://science.nasa.gov/headlines/y2003/30may_solareclipse.htm\">partial eclipse of the Sun</a> on Saturday, May 31st.", + pubDate: new Date("Fri, 30 May 2003 11:06:42 GMT") + }, { + id: "http://liftoff.msfc.nasa.gov/2003/05/27.html#item571", + title: "The Engine That Does More", + link: "http://liftoff.msfc.nasa.gov/news/2003/news-VASIMR.asp", + description: "Before man travels to Mars, NASA hopes to design new engines that will let us fly through the Solar System more quickly. The proposed VASIMR engine would do that.", + pubDate: new Date("Tue, 27 May 2003 08:37:32 GMT") + }, { + id: "http://liftoff.msfc.nasa.gov/2003/05/20.html#item570", + title: "Astronauts' Dirty Laundry", + link: "http://liftoff.msfc.nasa.gov/news/2003/news-laundry.asp", + description: "Compared to earlier spacecraft, the International Space Station has many luxuries, but laundry facilities are not one of them. Instead, astronauts have other options.", + pubDate: new Date("Tue, 20 May 2003 08:56:02 GMT") + }] +}; \ No newline at end of file diff --git a/node_modules/htmlparser2/test/Feeds/02-atom.js b/node_modules/htmlparser2/test/Feeds/02-atom.js new file mode 100644 index 0000000..5b5d88e --- /dev/null +++ b/node_modules/htmlparser2/test/Feeds/02-atom.js @@ -0,0 +1,18 @@ +exports.name = "Atom (1.0)"; +exports.file = "/Atom_Example.xml"; +exports.expected = { + type: "atom", + id: "urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af6", + title: "Example Feed", + link: "http://example.org/feed/", + description: "A subtitle.", + updated: new Date("2003-12-13T18:30:02Z"), + author: "johndoe@example.com", + items: [{ + id: "urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a", + title: "Atom-Powered Robots Run Amok", + link: "http://example.org/2003/12/13/atom03", + description: "Some content.", + pubDate: new Date("2003-12-13T18:30:02Z") + }] +}; diff --git a/node_modules/htmlparser2/test/Feeds/03-rdf.js b/node_modules/htmlparser2/test/Feeds/03-rdf.js new file mode 100644 index 0000000..b38ee13 --- /dev/null +++ b/node_modules/htmlparser2/test/Feeds/03-rdf.js @@ -0,0 +1,20 @@ +exports.name = "RDF test"; +exports.file = "/RDF_Example.xml"; +exports.expected = { + "type": "rdf", + "id": "", + "title": "craigslist | all community in SF bay area", + "link": "http://sfbay.craigslist.org/ccc/", + "items": [ + { + "title": "Music Equipment Repair and Consignment", + "link": "http://sfbay.craigslist.org/sby/muc/2681301534.html", + "description": "San Jose Rock Shop offers musical instrument repair and consignment! (408) 215-2065

          We are pleased to announce our NEW LOCATION: 1199 N 5th st. San Jose, ca 95112. Please call ahead, by appointment only.

          Recently featured by Metro Newspaper in their 2011 Best of the Silicon Valley edition see it online here:
          http://www.metroactive.com/best-of-silicon-valley/2011/music-nightlife/editor-picks.html

          Guitar Set up (acoustic and electronic) $40!" + }, + { + "title": "Ride Offered - Oakland/BART to LA/SFV - TODAY 3PM 11/04 (oakland north / temescal)", + "link": "http://sfbay.craigslist.org/eby/rid/2685010755.html", + "description": "Im offering a lift for up to two people from Oakland (or near any BART station in the East Bay/580/880 Corridor, or San Jose/Morgan Hill, Gilroy) to the San Fernando Valley / Los Angeles area. Specifically, Im leaving from Oakland between 2:30 and 3:00pm (this is flexible, but if I leave too late my girlfriend will kill me), and heading to Woodland Hills via the 580, I-5, 405, and 101." + } + ] +}; diff --git a/node_modules/htmlparser2/test/Stream/01-basic.json b/node_modules/htmlparser2/test/Stream/01-basic.json new file mode 100644 index 0000000..e0766e7 --- /dev/null +++ b/node_modules/htmlparser2/test/Stream/01-basic.json @@ -0,0 +1,83 @@ +{ + "name": "Basic html", + "options": {}, + "file": "Basic.html", + "expected": [ + { + "event": "processinginstruction", + "data": [ + "!doctype", + "!DOCTYPE html" + ] + }, + { + "event": "opentagname", + "data": [ + "html" + ] + }, + { + "event": "opentag", + "data": [ + "html", + {} + ] + }, + { + "event": "opentagname", + "data": [ + "title" + ] + }, + { + "event": "opentag", + "data": [ + "title", + {} + ] + }, + { + "event": "text", + "data": [ + "The Title" + ] + }, + { + "event": "closetag", + "data": [ + "title" + ] + }, + { + "event": "opentagname", + "data": [ + "body" + ] + }, + { + "event": "opentag", + "data": [ + "body", + {} + ] + }, + { + "event": "text", + "data": [ + "Hello world" + ] + }, + { + "event": "closetag", + "data": [ + "body" + ] + }, + { + "event": "closetag", + "data": [ + "html" + ] + } + ] +} \ No newline at end of file diff --git a/node_modules/htmlparser2/test/Stream/02-RSS.json b/node_modules/htmlparser2/test/Stream/02-RSS.json new file mode 100644 index 0000000..0d5921c --- /dev/null +++ b/node_modules/htmlparser2/test/Stream/02-RSS.json @@ -0,0 +1,1093 @@ +{ + "name": "RSS feed", + "options": {"xmlMode": true}, + "file": "RSS_Example.xml", + "expected": [ + { + "event": "processinginstruction", + "data": [ + "?xml", + "?xml version=\"1.0\"?" + ] + }, + { + "event": "text", + "data": [ + "\n" + ] + }, + { + "event": "comment", + "data": [ + " http://cyber.law.harvard.edu/rss/examples/rss2sample.xml " + ] + }, + { + "event": "commentend", + "data": [] + }, + { + "event": "text", + "data": [ + "\n" + ] + }, + { + "event": "opentagname", + "data": [ + "rss" + ] + }, + { + "event": "attribute", + "data": [ + "version", + "2.0" + ] + }, + { + "event": "opentag", + "data": [ + "rss", + { + "version": "2.0" + } + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "channel" + ] + }, + { + "event": "opentag", + "data": [ + "channel", + {} + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "title" + ] + }, + { + "event": "opentag", + "data": [ + "title", + {} + ] + }, + { + "event": "text", + "data": [ + "Liftoff News" + ] + }, + { + "event": "closetag", + "data": [ + "title" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "link" + ] + }, + { + "event": "opentag", + "data": [ + "link", + {} + ] + }, + { + "event": "text", + "data": [ + "http://liftoff.msfc.nasa.gov/" + ] + }, + { + "event": "closetag", + "data": [ + "link" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "description" + ] + }, + { + "event": "opentag", + "data": [ + "description", + {} + ] + }, + { + "event": "text", + "data": [ + "Liftoff to Space Exploration." + ] + }, + { + "event": "closetag", + "data": [ + "description" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "language" + ] + }, + { + "event": "opentag", + "data": [ + "language", + {} + ] + }, + { + "event": "text", + "data": [ + "en-us" + ] + }, + { + "event": "closetag", + "data": [ + "language" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "pubDate" + ] + }, + { + "event": "opentag", + "data": [ + "pubDate", + {} + ] + }, + { + "event": "text", + "data": [ + "Tue, 10 Jun 2003 04:00:00 GMT" + ] + }, + { + "event": "closetag", + "data": [ + "pubDate" + ] + }, + { + "event": "text", + "data": [ + "\n\n " + ] + }, + { + "event": "opentagname", + "data": [ + "lastBuildDate" + ] + }, + { + "event": "opentag", + "data": [ + "lastBuildDate", + {} + ] + }, + { + "event": "text", + "data": [ + "Tue, 10 Jun 2003 09:41:01 GMT" + ] + }, + { + "event": "closetag", + "data": [ + "lastBuildDate" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "docs" + ] + }, + { + "event": "opentag", + "data": [ + "docs", + {} + ] + }, + { + "event": "text", + "data": [ + "http://blogs.law.harvard.edu/tech/rss" + ] + }, + { + "event": "closetag", + "data": [ + "docs" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "generator" + ] + }, + { + "event": "opentag", + "data": [ + "generator", + {} + ] + }, + { + "event": "text", + "data": [ + "Weblog Editor 2.0" + ] + }, + { + "event": "closetag", + "data": [ + "generator" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "managingEditor" + ] + }, + { + "event": "opentag", + "data": [ + "managingEditor", + {} + ] + }, + { + "event": "text", + "data": [ + "editor@example.com" + ] + }, + { + "event": "closetag", + "data": [ + "managingEditor" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "webMaster" + ] + }, + { + "event": "opentag", + "data": [ + "webMaster", + {} + ] + }, + { + "event": "text", + "data": [ + "webmaster@example.com" + ] + }, + { + "event": "closetag", + "data": [ + "webMaster" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "item" + ] + }, + { + "event": "opentag", + "data": [ + "item", + {} + ] + }, + { + "event": "text", + "data": [ + "\n\n " + ] + }, + { + "event": "opentagname", + "data": [ + "title" + ] + }, + { + "event": "opentag", + "data": [ + "title", + {} + ] + }, + { + "event": "text", + "data": [ + "Star City" + ] + }, + { + "event": "closetag", + "data": [ + "title" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "link" + ] + }, + { + "event": "opentag", + "data": [ + "link", + {} + ] + }, + { + "event": "text", + "data": [ + "http://liftoff.msfc.nasa.gov/news/2003/news-starcity.asp" + ] + }, + { + "event": "closetag", + "data": [ + "link" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "description" + ] + }, + { + "event": "opentag", + "data": [ + "description", + {} + ] + }, + { + "event": "text", + "data": [ + "How do Americans get ready to work with Russians aboard the International Space Station? They take a crash course in culture, language and protocol at Russia's <a href=\"http://howe.iki.rssi.ru/GCTC/gctc_e.htm\">Star City</a>." + ] + }, + { + "event": "closetag", + "data": [ + "description" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "pubDate" + ] + }, + { + "event": "opentag", + "data": [ + "pubDate", + {} + ] + }, + { + "event": "text", + "data": [ + "Tue, 03 Jun 2003 09:39:21 GMT" + ] + }, + { + "event": "closetag", + "data": [ + "pubDate" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "guid" + ] + }, + { + "event": "opentag", + "data": [ + "guid", + {} + ] + }, + { + "event": "text", + "data": [ + "http://liftoff.msfc.nasa.gov/2003/06/03.html#item573" + ] + }, + { + "event": "closetag", + "data": [ + "guid" + ] + }, + { + "event": "text", + "data": [ + "\n\n " + ] + }, + { + "event": "closetag", + "data": [ + "item" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "item" + ] + }, + { + "event": "opentag", + "data": [ + "item", + {} + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "description" + ] + }, + { + "event": "opentag", + "data": [ + "description", + {} + ] + }, + { + "event": "text", + "data": [ + "Sky watchers in Europe, Asia, and parts of Alaska and Canada will experience a <a href=\"http://science.nasa.gov/headlines/y2003/30may_solareclipse.htm\">partial eclipse of the Sun</a> on Saturday, May 31st." + ] + }, + { + "event": "closetag", + "data": [ + "description" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "pubDate" + ] + }, + { + "event": "opentag", + "data": [ + "pubDate", + {} + ] + }, + { + "event": "text", + "data": [ + "Fri, 30 May 2003 11:06:42 GMT" + ] + }, + { + "event": "closetag", + "data": [ + "pubDate" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "guid" + ] + }, + { + "event": "opentag", + "data": [ + "guid", + {} + ] + }, + { + "event": "text", + "data": [ + "http://liftoff.msfc.nasa.gov/2003/05/30.html#item572" + ] + }, + { + "event": "closetag", + "data": [ + "guid" + ] + }, + { + "event": "text", + "data": [ + "\n\n " + ] + }, + { + "event": "closetag", + "data": [ + "item" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "item" + ] + }, + { + "event": "opentag", + "data": [ + "item", + {} + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "title" + ] + }, + { + "event": "opentag", + "data": [ + "title", + {} + ] + }, + { + "event": "text", + "data": [ + "The Engine That Does More" + ] + }, + { + "event": "closetag", + "data": [ + "title" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "link" + ] + }, + { + "event": "opentag", + "data": [ + "link", + {} + ] + }, + { + "event": "text", + "data": [ + "http://liftoff.msfc.nasa.gov/news/2003/news-VASIMR.asp" + ] + }, + { + "event": "closetag", + "data": [ + "link" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "description" + ] + }, + { + "event": "opentag", + "data": [ + "description", + {} + ] + }, + { + "event": "text", + "data": [ + "Before man travels to Mars, NASA hopes to design new engines that will let us fly through the Solar System more quickly. The proposed VASIMR engine would do that." + ] + }, + { + "event": "closetag", + "data": [ + "description" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "pubDate" + ] + }, + { + "event": "opentag", + "data": [ + "pubDate", + {} + ] + }, + { + "event": "text", + "data": [ + "Tue, 27 May 2003 08:37:32 GMT" + ] + }, + { + "event": "closetag", + "data": [ + "pubDate" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "guid" + ] + }, + { + "event": "opentag", + "data": [ + "guid", + {} + ] + }, + { + "event": "text", + "data": [ + "http://liftoff.msfc.nasa.gov/2003/05/27.html#item571" + ] + }, + { + "event": "closetag", + "data": [ + "guid" + ] + }, + { + "event": "text", + "data": [ + "\n\n " + ] + }, + { + "event": "closetag", + "data": [ + "item" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "item" + ] + }, + { + "event": "opentag", + "data": [ + "item", + {} + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "title" + ] + }, + { + "event": "opentag", + "data": [ + "title", + {} + ] + }, + { + "event": "text", + "data": [ + "Astronauts' Dirty Laundry" + ] + }, + { + "event": "closetag", + "data": [ + "title" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "link" + ] + }, + { + "event": "opentag", + "data": [ + "link", + {} + ] + }, + { + "event": "text", + "data": [ + "http://liftoff.msfc.nasa.gov/news/2003/news-laundry.asp" + ] + }, + { + "event": "closetag", + "data": [ + "link" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "description" + ] + }, + { + "event": "opentag", + "data": [ + "description", + {} + ] + }, + { + "event": "text", + "data": [ + "Compared to earlier spacecraft, the International Space Station has many luxuries, but laundry facilities are not one of them. Instead, astronauts have other options." + ] + }, + { + "event": "closetag", + "data": [ + "description" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "pubDate" + ] + }, + { + "event": "opentag", + "data": [ + "pubDate", + {} + ] + }, + { + "event": "text", + "data": [ + "Tue, 20 May 2003 08:56:02 GMT" + ] + }, + { + "event": "closetag", + "data": [ + "pubDate" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "opentagname", + "data": [ + "guid" + ] + }, + { + "event": "opentag", + "data": [ + "guid", + {} + ] + }, + { + "event": "text", + "data": [ + "http://liftoff.msfc.nasa.gov/2003/05/20.html#item570" + ] + }, + { + "event": "closetag", + "data": [ + "guid" + ] + }, + { + "event": "text", + "data": [ + "\n\n " + ] + }, + { + "event": "closetag", + "data": [ + "item" + ] + }, + { + "event": "text", + "data": [ + "\n " + ] + }, + { + "event": "closetag", + "data": [ + "channel" + ] + }, + { + "event": "text", + "data": [ + "\n" + ] + }, + { + "event": "closetag", + "data": [ + "rss" + ] + } + ] +} \ No newline at end of file diff --git a/node_modules/htmlparser2/test/Stream/03-Atom.json b/node_modules/htmlparser2/test/Stream/03-Atom.json new file mode 100644 index 0000000..0cbf24e --- /dev/null +++ b/node_modules/htmlparser2/test/Stream/03-Atom.json @@ -0,0 +1,678 @@ +{ + "name": "Atom feed", + "options": {"xmlMode": true}, + "file": "Atom_Example.xml", + "expected": [ + { + "event": "processinginstruction", + "data": [ + "?xml", + "?xml version=\"1.0\" encoding=\"utf-8\"?" + ] + }, + { + "event": "text", + "data": [ + "\n" + ] + }, + { + "event": "comment", + "data": [ + " http://en.wikipedia.org/wiki/Atom_%28standard%29 " + ] + }, + { + "event": "commentend", + "data": [] + }, + { + "event": "text", + "data": [ + "\n" + ] + }, + { + "event": "opentagname", + "data": [ + "feed" + ] + }, + { + "event": "attribute", + "data": [ + "xmlns", + "http://www.w3.org/2005/Atom" + ] + }, + { + "event": "opentag", + "data": [ + "feed", + { + "xmlns": "http://www.w3.org/2005/Atom" + } + ] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "opentagname", + "data": [ + "title" + ] + }, + { + "event": "opentag", + "data": [ + "title", + {} + ] + }, + { + "event": "text", + "data": [ + "Example Feed" + ] + }, + { + "event": "closetag", + "data": [ + "title" + ] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "opentagname", + "data": [ + "subtitle" + ] + }, + { + "event": "opentag", + "data": [ + "subtitle", + {} + ] + }, + { + "event": "text", + "data": [ + "A subtitle." + ] + }, + { + "event": "closetag", + "data": [ + "subtitle" + ] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "opentagname", + "data": [ + "link" + ] + }, + { + "event": "attribute", + "data": [ + "href", + "http://example.org/feed/" + ] + }, + { + "event": "attribute", + "data": [ + "rel", + "self" + ] + }, + { + "event": "opentag", + "data": [ + "link", + { + "href": "http://example.org/feed/", + "rel": "self" + } + ] + }, + { + "event": "closetag", + "data": [ + "link" + ] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "opentagname", + "data": [ + "link" + ] + }, + { + "event": "attribute", + "data": [ + "href", + "http://example.org/" + ] + }, + { + "event": "opentag", + "data": [ + "link", + { + "href": "http://example.org/" + } + ] + }, + { + "event": "closetag", + "data": [ + "link" + ] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "opentagname", + "data": [ + "id" + ] + }, + { + "event": "opentag", + "data": [ + "id", + {} + ] + }, + { + "event": "text", + "data": [ + "urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af6" + ] + }, + { + "event": "closetag", + "data": [ + "id" + ] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "opentagname", + "data": [ + "updated" + ] + }, + { + "event": "opentag", + "data": [ + "updated", + {} + ] + }, + { + "event": "text", + "data": [ + "2003-12-13T18:30:02Z" + ] + }, + { + "event": "closetag", + "data": [ + "updated" + ] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "opentagname", + "data": [ + "author" + ] + }, + { + "event": "opentag", + "data": [ + "author", + {} + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "name" + ] + }, + { + "event": "opentag", + "data": [ + "name", + {} + ] + }, + { + "event": "text", + "data": [ + "John Doe" + ] + }, + { + "event": "closetag", + "data": [ + "name" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "email" + ] + }, + { + "event": "opentag", + "data": [ + "email", + {} + ] + }, + { + "event": "text", + "data": [ + "johndoe@example.com" + ] + }, + { + "event": "closetag", + "data": [ + "email" + ] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "closetag", + "data": [ + "author" + ] + }, + { + "event": "text", + "data": [ + "\n\n\t" + ] + }, + { + "event": "opentagname", + "data": [ + "entry" + ] + }, + { + "event": "opentag", + "data": [ + "entry", + {} + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "title" + ] + }, + { + "event": "opentag", + "data": [ + "title", + {} + ] + }, + { + "event": "text", + "data": [ + "Atom-Powered Robots Run Amok" + ] + }, + { + "event": "closetag", + "data": [ + "title" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "link" + ] + }, + { + "event": "attribute", + "data": [ + "href", + "http://example.org/2003/12/13/atom03" + ] + }, + { + "event": "opentag", + "data": [ + "link", + { + "href": "http://example.org/2003/12/13/atom03" + } + ] + }, + { + "event": "closetag", + "data": [ + "link" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "link" + ] + }, + { + "event": "attribute", + "data": [ + "rel", + "alternate" + ] + }, + { + "event": "attribute", + "data": [ + "type", + "text/html" + ] + }, + { + "event": "attribute", + "data": [ + "href", + "http://example.org/2003/12/13/atom03.html" + ] + }, + { + "event": "opentag", + "data": [ + "link", + { + "rel": "alternate", + "type": "text/html", + "href": "http://example.org/2003/12/13/atom03.html" + } + ] + }, + { + "event": "closetag", + "data": [ + "link" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "link" + ] + }, + { + "event": "attribute", + "data": [ + "rel", + "edit" + ] + }, + { + "event": "attribute", + "data": [ + "href", + "http://example.org/2003/12/13/atom03/edit" + ] + }, + { + "event": "opentag", + "data": [ + "link", + { + "rel": "edit", + "href": "http://example.org/2003/12/13/atom03/edit" + } + ] + }, + { + "event": "closetag", + "data": [ + "link" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "id" + ] + }, + { + "event": "opentag", + "data": [ + "id", + {} + ] + }, + { + "event": "text", + "data": [ + "urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a" + ] + }, + { + "event": "closetag", + "data": [ + "id" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "updated" + ] + }, + { + "event": "opentag", + "data": [ + "updated", + {} + ] + }, + { + "event": "text", + "data": [ + "2003-12-13T18:30:02Z" + ] + }, + { + "event": "closetag", + "data": [ + "updated" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "content" + ] + }, + { + "event": "attribute", + "data": [ + "type", + "html" + ] + }, + { + "event": "opentag", + "data": [ + "content", + { + "type": "html" + } + ] + }, + { + "event": "opentagname", + "data": [ + "p" + ] + }, + { + "event": "opentag", + "data": [ + "p", + {} + ] + }, + { + "event": "text", + "data": [ + "Some content." + ] + }, + { + "event": "closetag", + "data": [ + "p" + ] + }, + { + "event": "closetag", + "data": [ + "content" + ] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "closetag", + "data": [ + "entry" + ] + }, + { + "event": "text", + "data": [ + "\n\n" + ] + }, + { + "event": "closetag", + "data": [ + "feed" + ] + }, + { + "event": "text", + "data": [ + "\n" + ] + } + ] +} diff --git a/node_modules/htmlparser2/test/Stream/04-RDF.json b/node_modules/htmlparser2/test/Stream/04-RDF.json new file mode 100644 index 0000000..7ebf516 --- /dev/null +++ b/node_modules/htmlparser2/test/Stream/04-RDF.json @@ -0,0 +1,1399 @@ +{ + "name": "RDF feed", + "options": {"xmlMode": true}, + "file": "RDF_Example.xml", + "expected": [ + { + "event": "processinginstruction", + "data": [ + "?xml", + "?xml version=\"1.0\" encoding=\"UTF-8\"?" + ] + }, + { + "event": "text", + "data": [ + "\n" + ] + }, + { + "event": "opentagname", + "data": [ + "rdf:RDF" + ] + }, + { + "event": "attribute", + "data": [ + "xmlns:rdf", + "http://www.w3.org/1999/02/22-rdf-syntax-ns#" + ] + }, + { + "event": "attribute", + "data": [ + "xmlns", + "http://purl.org/rss/1.0/" + ] + }, + { + "event": "attribute", + "data": [ + "xmlns:ev", + "http://purl.org/rss/1.0/modules/event/" + ] + }, + { + "event": "attribute", + "data": [ + "xmlns:content", + "http://purl.org/rss/1.0/modules/content/" + ] + }, + { + "event": "attribute", + "data": [ + "xmlns:taxo", + "http://purl.org/rss/1.0/modules/taxonomy/" + ] + }, + { + "event": "attribute", + "data": [ + "xmlns:dc", + "http://purl.org/dc/elements/1.1/" + ] + }, + { + "event": "attribute", + "data": [ + "xmlns:syn", + "http://purl.org/rss/1.0/modules/syndication/" + ] + }, + { + "event": "attribute", + "data": [ + "xmlns:dcterms", + "http://purl.org/dc/terms/" + ] + }, + { + "event": "attribute", + "data": [ + "xmlns:admin", + "http://webns.net/mvcb/" + ] + }, + { + "event": "opentag", + "data": [ + "rdf:RDF", + { + "xmlns:rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "xmlns": "http://purl.org/rss/1.0/", + "xmlns:ev": "http://purl.org/rss/1.0/modules/event/", + "xmlns:content": "http://purl.org/rss/1.0/modules/content/", + "xmlns:taxo": "http://purl.org/rss/1.0/modules/taxonomy/", + "xmlns:dc": "http://purl.org/dc/elements/1.1/", + "xmlns:syn": "http://purl.org/rss/1.0/modules/syndication/", + "xmlns:dcterms": "http://purl.org/dc/terms/", + "xmlns:admin": "http://webns.net/mvcb/" + } + ] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "opentagname", + "data": [ + "channel" + ] + }, + { + "event": "attribute", + "data": [ + "rdf:about", + "http://sfbay.craigslist.org/ccc/" + ] + }, + { + "event": "opentag", + "data": [ + "channel", + { + "rdf:about": "http://sfbay.craigslist.org/ccc/" + } + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "title" + ] + }, + { + "event": "opentag", + "data": [ + "title", + {} + ] + }, + { + "event": "text", + "data": [ + "craigslist | all community in SF bay area" + ] + }, + { + "event": "closetag", + "data": [ + "title" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "link" + ] + }, + { + "event": "opentag", + "data": [ + "link", + {} + ] + }, + { + "event": "text", + "data": [ + "http://sfbay.craigslist.org/ccc/" + ] + }, + { + "event": "closetag", + "data": [ + "link" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "description" + ] + }, + { + "event": "opentag", + "data": [ + "description", + {} + ] + }, + { + "event": "closetag", + "data": [ + "description" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:language" + ] + }, + { + "event": "opentag", + "data": [ + "dc:language", + {} + ] + }, + { + "event": "text", + "data": [ + "en-us" + ] + }, + { + "event": "closetag", + "data": [ + "dc:language" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:rights" + ] + }, + { + "event": "opentag", + "data": [ + "dc:rights", + {} + ] + }, + { + "event": "text", + "data": [ + "Copyright 2011 craigslist, inc." + ] + }, + { + "event": "closetag", + "data": [ + "dc:rights" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:publisher" + ] + }, + { + "event": "opentag", + "data": [ + "dc:publisher", + {} + ] + }, + { + "event": "text", + "data": [ + "webmaster@craigslist.org" + ] + }, + { + "event": "closetag", + "data": [ + "dc:publisher" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:creator" + ] + }, + { + "event": "opentag", + "data": [ + "dc:creator", + {} + ] + }, + { + "event": "text", + "data": [ + "webmaster@craigslist.org" + ] + }, + { + "event": "closetag", + "data": [ + "dc:creator" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:source" + ] + }, + { + "event": "opentag", + "data": [ + "dc:source", + {} + ] + }, + { + "event": "text", + "data": [ + "http://sfbay.craigslist.org/ccc//" + ] + }, + { + "event": "closetag", + "data": [ + "dc:source" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:title" + ] + }, + { + "event": "opentag", + "data": [ + "dc:title", + {} + ] + }, + { + "event": "text", + "data": [ + "craigslist | all community in SF bay area" + ] + }, + { + "event": "closetag", + "data": [ + "dc:title" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:type" + ] + }, + { + "event": "opentag", + "data": [ + "dc:type", + {} + ] + }, + { + "event": "text", + "data": [ + "Collection" + ] + }, + { + "event": "closetag", + "data": [ + "dc:type" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "syn:updateBase" + ] + }, + { + "event": "opentag", + "data": [ + "syn:updateBase", + {} + ] + }, + { + "event": "text", + "data": [ + "2011-11-04T09:39:10-07:00" + ] + }, + { + "event": "closetag", + "data": [ + "syn:updateBase" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "syn:updateFrequency" + ] + }, + { + "event": "opentag", + "data": [ + "syn:updateFrequency", + {} + ] + }, + { + "event": "text", + "data": [ + "4" + ] + }, + { + "event": "closetag", + "data": [ + "syn:updateFrequency" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "syn:updatePeriod" + ] + }, + { + "event": "opentag", + "data": [ + "syn:updatePeriod", + {} + ] + }, + { + "event": "text", + "data": [ + "hourly" + ] + }, + { + "event": "closetag", + "data": [ + "syn:updatePeriod" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "items" + ] + }, + { + "event": "opentag", + "data": [ + "items", + {} + ] + }, + { + "event": "text", + "data": [ + "\n\t\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "rdf:Seq" + ] + }, + { + "event": "opentag", + "data": [ + "rdf:Seq", + {} + ] + }, + { + "event": "text", + "data": [ + "\n\t\t\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "rdf:li" + ] + }, + { + "event": "attribute", + "data": [ + "rdf:resource", + "http://sfbay.craigslist.org/sby/muc/2681301534.html" + ] + }, + { + "event": "opentag", + "data": [ + "rdf:li", + { + "rdf:resource": "http://sfbay.craigslist.org/sby/muc/2681301534.html" + } + ] + }, + { + "event": "closetag", + "data": [ + "rdf:li" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t\t" + ] + }, + { + "event": "closetag", + "data": [ + "rdf:Seq" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "closetag", + "data": [ + "items" + ] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "closetag", + "data": [ + "channel" + ] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "opentagname", + "data": [ + "item" + ] + }, + { + "event": "attribute", + "data": [ + "rdf:about", + "http://sfbay.craigslist.org/sby/muc/2681301534.html" + ] + }, + { + "event": "opentag", + "data": [ + "item", + { + "rdf:about": "http://sfbay.craigslist.org/sby/muc/2681301534.html" + } + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "title" + ] + }, + { + "event": "opentag", + "data": [ + "title", + {} + ] + }, + { + "event": "cdatastart", + "data": [] + }, + { + "event": "text", + "data": [ + " Music Equipment Repair and Consignment " + ] + }, + { + "event": "cdataend", + "data": [] + }, + { + "event": "closetag", + "data": [ + "title" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "link" + ] + }, + { + "event": "opentag", + "data": [ + "link", + {} + ] + }, + { + "event": "text", + "data": [ + "\nhttp://sfbay.craigslist.org/sby/muc/2681301534.html\n" + ] + }, + { + "event": "closetag", + "data": [ + "link" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "description" + ] + }, + { + "event": "opentag", + "data": [ + "description", + {} + ] + }, + { + "event": "cdatastart", + "data": [] + }, + { + "event": "text", + "data": [ + "\nSan Jose Rock Shop offers musical instrument repair and consignment! (408) 215-2065

          We are pleased to announce our NEW LOCATION: 1199 N 5th st. San Jose, ca 95112. Please call ahead, by appointment only.

          Recently featured by Metro Newspaper in their 2011 Best of the Silicon Valley edition see it online here:
          http://www.metroactive.com/best-of-silicon-valley/2011/music-nightlife/editor-picks.html

          Guitar Set up (acoustic and electronic) $40!\n" + ] + }, + { + "event": "cdataend", + "data": [] + }, + { + "event": "closetag", + "data": [ + "description" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:date" + ] + }, + { + "event": "opentag", + "data": [ + "dc:date", + {} + ] + }, + { + "event": "text", + "data": [ + "2011-11-04T09:35:17-07:00" + ] + }, + { + "event": "closetag", + "data": [ + "dc:date" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:language" + ] + }, + { + "event": "opentag", + "data": [ + "dc:language", + {} + ] + }, + { + "event": "text", + "data": [ + "en-us" + ] + }, + { + "event": "closetag", + "data": [ + "dc:language" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:rights" + ] + }, + { + "event": "opentag", + "data": [ + "dc:rights", + {} + ] + }, + { + "event": "text", + "data": [ + "Copyright 2011 craigslist, inc." + ] + }, + { + "event": "closetag", + "data": [ + "dc:rights" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:source" + ] + }, + { + "event": "opentag", + "data": [ + "dc:source", + {} + ] + }, + { + "event": "text", + "data": [ + "\nhttp://sfbay.craigslist.org/sby/muc/2681301534.html\n" + ] + }, + { + "event": "closetag", + "data": [ + "dc:source" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:title" + ] + }, + { + "event": "opentag", + "data": [ + "dc:title", + {} + ] + }, + { + "event": "cdatastart", + "data": [] + }, + { + "event": "text", + "data": [ + " Music Equipment Repair and Consignment " + ] + }, + { + "event": "cdataend", + "data": [] + }, + { + "event": "closetag", + "data": [ + "dc:title" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:type" + ] + }, + { + "event": "opentag", + "data": [ + "dc:type", + {} + ] + }, + { + "event": "text", + "data": [ + "text" + ] + }, + { + "event": "closetag", + "data": [ + "dc:type" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dcterms:issued" + ] + }, + { + "event": "opentag", + "data": [ + "dcterms:issued", + {} + ] + }, + { + "event": "text", + "data": [ + "2011-11-04T09:35:17-07:00" + ] + }, + { + "event": "closetag", + "data": [ + "dcterms:issued" + ] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "closetag", + "data": [ + "item" + ] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "opentagname", + "data": [ + "item" + ] + }, + { + "event": "attribute", + "data": [ + "rdf:about", + "http://sfbay.craigslist.org/eby/rid/2685010755.html" + ] + }, + { + "event": "opentag", + "data": [ + "item", + { + "rdf:about": "http://sfbay.craigslist.org/eby/rid/2685010755.html" + } + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "title" + ] + }, + { + "event": "opentag", + "data": [ + "title", + {} + ] + }, + { + "event": "cdatastart", + "data": [] + }, + { + "event": "text", + "data": [ + "\nRide Offered - Oakland/BART to LA/SFV - TODAY 3PM 11/04 (oakland north / temescal)\n" + ] + }, + { + "event": "cdataend", + "data": [] + }, + { + "event": "closetag", + "data": [ + "title" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "link" + ] + }, + { + "event": "opentag", + "data": [ + "link", + {} + ] + }, + { + "event": "text", + "data": [ + "\nhttp://sfbay.craigslist.org/eby/rid/2685010755.html\n" + ] + }, + { + "event": "closetag", + "data": [ + "link" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "description" + ] + }, + { + "event": "opentag", + "data": [ + "description", + {} + ] + }, + { + "event": "cdatastart", + "data": [] + }, + { + "event": "text", + "data": [ + "\nIm offering a lift for up to two people from Oakland (or near any BART station in the East Bay/580/880 Corridor, or San Jose/Morgan Hill, Gilroy) to the San Fernando Valley / Los Angeles area. Specifically, Im leaving from Oakland between 2:30 and 3:00pm (this is flexible, but if I leave too late my girlfriend will kill me), and heading to Woodland Hills via the 580, I-5, 405, and 101.\n" + ] + }, + { + "event": "cdataend", + "data": [] + }, + { + "event": "closetag", + "data": [ + "description" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:date" + ] + }, + { + "event": "opentag", + "data": [ + "dc:date", + {} + ] + }, + { + "event": "text", + "data": [ + "2011-11-04T09:34:54-07:00" + ] + }, + { + "event": "closetag", + "data": [ + "dc:date" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:language" + ] + }, + { + "event": "opentag", + "data": [ + "dc:language", + {} + ] + }, + { + "event": "text", + "data": [ + "en-us" + ] + }, + { + "event": "closetag", + "data": [ + "dc:language" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:rights" + ] + }, + { + "event": "opentag", + "data": [ + "dc:rights", + {} + ] + }, + { + "event": "text", + "data": [ + "Copyright 2011 craigslist, inc." + ] + }, + { + "event": "closetag", + "data": [ + "dc:rights" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:source" + ] + }, + { + "event": "opentag", + "data": [ + "dc:source", + {} + ] + }, + { + "event": "text", + "data": [ + "\nhttp://sfbay.craigslist.org/eby/rid/2685010755.html\n" + ] + }, + { + "event": "closetag", + "data": [ + "dc:source" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:title" + ] + }, + { + "event": "opentag", + "data": [ + "dc:title", + {} + ] + }, + { + "event": "cdatastart", + "data": [] + }, + { + "event": "text", + "data": [ + "\nRide Offered - Oakland/BART to LA/SFV - TODAY 3PM 11/04 (oakland north / temescal)\n" + ] + }, + { + "event": "cdataend", + "data": [] + }, + { + "event": "closetag", + "data": [ + "dc:title" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dc:type" + ] + }, + { + "event": "opentag", + "data": [ + "dc:type", + {} + ] + }, + { + "event": "text", + "data": [ + "text" + ] + }, + { + "event": "closetag", + "data": [ + "dc:type" + ] + }, + { + "event": "text", + "data": [ + "\n\t\t" + ] + }, + { + "event": "opentagname", + "data": [ + "dcterms:issued" + ] + }, + { + "event": "opentag", + "data": [ + "dcterms:issued", + {} + ] + }, + { + "event": "text", + "data": [ + "2011-11-04T09:34:54-07:00" + ] + }, + { + "event": "closetag", + "data": [ + "dcterms:issued" + ] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "closetag", + "data": [ + "item" + ] + }, + { + "event": "text", + "data": [ + "\n" + ] + }, + { + "event": "closetag", + "data": [ + "rdf:RDF" + ] + } + ] +} \ No newline at end of file diff --git a/node_modules/htmlparser2/test/Stream/05-Attributes.json b/node_modules/htmlparser2/test/Stream/05-Attributes.json new file mode 100644 index 0000000..ad364c0 --- /dev/null +++ b/node_modules/htmlparser2/test/Stream/05-Attributes.json @@ -0,0 +1,354 @@ +{ + "name": "Attributes", + "options": {}, + "file": "Attributes.html", + "expected": [ + { + "event": "processinginstruction", + "data": [ + "!doctype", + "!doctype html" + ] + }, + { + "event": "text", + "data": [ + "\n" + ] + }, + { + "event": "opentagname", + "data": [ + "html" + ] + }, + { + "event": "opentag", + "data": [ + "html", + {} + ] + }, + { + "event": "text", + "data": [ + "\n" + ] + }, + { + "event": "opentagname", + "data": [ + "head" + ] + }, + { + "event": "opentag", + "data": [ + "head", + {} + ] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "opentagname", + "data": [ + "title" + ] + }, + { + "event": "opentag", + "data": [ + "title", + {} + ] + }, + { + "event": "text", + "data": [ + "Attributes test" + ] + }, + { + "event": "closetag", + "data": [ + "title" + ] + }, + { + "event": "text", + "data": [ + "\n" + ] + }, + { + "event": "closetag", + "data": [ + "head" + ] + }, + { + "event": "text", + "data": [ + "\n" + ] + }, + { + "event": "opentagname", + "data": [ + "body" + ] + }, + { + "event": "opentag", + "data": [ + "body", + {} + ] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "comment", + "data": [ + " Normal attributes " + ] + }, + { + "event": "commentend", + "data": [] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "opentagname", + "data": [ + "button" + ] + }, + { + "event": "attribute", + "data": [ + "id", + "test0" + ] + }, + { + "event": "attribute", + "data": [ + "class", + "value0" + ] + }, + { + "event": "attribute", + "data": [ + "title", + "value1" + ] + }, + { + "event": "opentag", + "data": [ + "button", + { + "id": "test0", + "class": "value0", + "title": "value1" + } + ] + }, + { + "event": "text", + "data": [ + "class=\"value0\" title=\"value1\"" + ] + }, + { + "event": "closetag", + "data": [ + "button" + ] + }, + { + "event": "text", + "data": [ + "\n\n\t" + ] + }, + { + "event": "comment", + "data": [ + " Attributes with no quotes or value " + ] + }, + { + "event": "commentend", + "data": [] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "opentagname", + "data": [ + "button" + ] + }, + { + "event": "attribute", + "data": [ + "id", + "test1" + ] + }, + { + "event": "attribute", + "data": [ + "class", + "value2" + ] + }, + { + "event": "attribute", + "data": [ + "disabled", + "" + ] + }, + { + "event": "opentag", + "data": [ + "button", + { + "id": "test1", + "class": "value2", + "disabled": "" + } + ] + }, + { + "event": "text", + "data": [ + "class=value2 disabled" + ] + }, + { + "event": "closetag", + "data": [ + "button" + ] + }, + { + "event": "text", + "data": [ + "\n\n\t" + ] + }, + { + "event": "comment", + "data": [ + " Attributes with no space between them. No valid, but accepted by the browser " + ] + }, + { + "event": "commentend", + "data": [] + }, + { + "event": "text", + "data": [ + "\n\t" + ] + }, + { + "event": "opentagname", + "data": [ + "button" + ] + }, + { + "event": "attribute", + "data": [ + "id", + "test2" + ] + }, + { + "event": "attribute", + "data": [ + "class", + "value4" + ] + }, + { + "event": "attribute", + "data": [ + "title", + "value5" + ] + }, + { + "event": "opentag", + "data": [ + "button", + { + "id": "test2", + "class": "value4", + "title": "value5" + } + ] + }, + { + "event": "text", + "data": [ + "class=\"value4\"title=\"value5\"" + ] + }, + { + "event": "closetag", + "data": [ + "button" + ] + }, + { + "event": "text", + "data": [ + "\n" + ] + }, + { + "event": "closetag", + "data": [ + "body" + ] + }, + { + "event": "text", + "data": [ + "\n" + ] + }, + { + "event": "closetag", + "data": [ + "html" + ] + } + ] +} \ No newline at end of file diff --git a/node_modules/htmlparser2/test/api.js b/node_modules/htmlparser2/test/api.js new file mode 100644 index 0000000..49b3196 --- /dev/null +++ b/node_modules/htmlparser2/test/api.js @@ -0,0 +1,75 @@ +var htmlparser2 = require(".."), + assert = require("assert"); + +describe("API", function(){ + + it("should load all modules", function(){ + var Stream = require("../lib/Stream.js"); + assert.strictEqual(htmlparser2.Stream, Stream, "should load module"); + assert.strictEqual(htmlparser2.Stream, Stream, "should load it again (cache)"); + + var ProxyHandler = require("../lib/ProxyHandler.js"); + assert.strictEqual(htmlparser2.ProxyHandler, ProxyHandler, "should load module"); + assert.strictEqual(htmlparser2.ProxyHandler, ProxyHandler, "should load it again (cache)"); + }); + + it("should work without callbacks", function(){ + var p = new htmlparser2.Parser(null, {xmlMode: true, lowerCaseAttributeNames: true}); + + p.end("boohay"); + p.write("foo"); + + //check for an error + p.end(); + var err = false; + p._cbs.onerror = function(){ err = true; }; + p.write("foo"); + assert(err); + err = false; + p.end(); + assert(err); + + p.reset(); + + //remove method + p._cbs.onopentag = function(){}; + p.write(""); + + //pause/resume + var processed = false; + p._cbs.ontext = function(t){ + assert.equal(t, "foo"); + processed = true; + }; + p.pause(); + p.write("foo"); + assert(!processed); + p.resume(); + assert(processed); + processed = false; + p.pause(); + assert(!processed); + p.resume(); + assert(!processed); + p.pause(); + p.end("foo"); + assert(!processed); + p.resume(); + assert(processed); + + }); + + it("should update the position", function(){ + var p = new htmlparser2.Parser(null); + + p.write("foo"); + + assert.equal(p.startIndex, 0); + + p.write(""); + + assert.equal(p.startIndex, 3); + }); +}); \ No newline at end of file diff --git a/node_modules/htmlparser2/test/test-helper.js b/node_modules/htmlparser2/test/test-helper.js new file mode 100644 index 0000000..90a9907 --- /dev/null +++ b/node_modules/htmlparser2/test/test-helper.js @@ -0,0 +1,83 @@ +var htmlparser2 = require(".."), + fs = require("fs"), + path = require("path"), + assert = require("assert"), + Parser = htmlparser2.Parser, + CollectingHandler = htmlparser2.CollectingHandler; + +exports.writeToParser = function(handler, options, data){ + var parser = new Parser(handler, options); + //first, try to run the test via chunks + for(var i = 0; i < data.length; i++){ + parser.write(data.charAt(i)); + } + parser.end(); + //then parse everything + parser.parseComplete(data); +}; + +//returns a tree structure +exports.getEventCollector = function(cb){ + var handler = new CollectingHandler({onerror: cb, onend: onend}); + + return handler; + + function onend(){ + cb(null, handler.events.reduce(eventReducer, [])); + } +}; + +function eventReducer(events, arr){ + if(arr[0] === "onerror" || arr[0] === "onend"); + else if(arr[0] === "ontext" && events.length && events[events.length - 1].event === "text"){ + events[events.length - 1].data[0] += arr[1]; + } else { + events.push({ + event: arr[0].substr(2), + data: arr.slice(1) + }); + } + + return events; +} + +function getCallback(expected, done){ + var repeated = false; + + return function(err, actual){ + assert.ifError(err); + try { + assert.deepEqual(expected, actual, "didn't get expected output"); + } catch(e){ + e.expected = JSON.stringify(expected, null, 2); + e.actual = JSON.stringify(actual, null, 2); + throw e; + } + + if(repeated) done(); + else repeated = true; + }; +} + +exports.mochaTest = function(name, root, test){ + describe(name, readDir); + + function readDir(){ + var dir = path.join(root, name); + + fs + .readdirSync(dir) + .filter(RegExp.prototype.test, /^[^\._]/) //ignore all files with a leading dot or underscore + .map(function(name){ + return path.join(dir, name); + }) + .map(require) + .forEach(runTest); + } + + function runTest(file){ + it(file.name, function(done){ + test(file, getCallback(file.expected, done)); + }); + } +}; diff --git a/node_modules/i/.npmignore b/node_modules/i/.npmignore new file mode 100644 index 0000000..435e4bb --- /dev/null +++ b/node_modules/i/.npmignore @@ -0,0 +1,3 @@ +node_modules +npm-debug.log +*.swp diff --git a/node_modules/i/.travis.yml b/node_modules/i/.travis.yml new file mode 100644 index 0000000..2f1969e --- /dev/null +++ b/node_modules/i/.travis.yml @@ -0,0 +1,14 @@ +sudo: false +language: node_js +node_js: + - '5' + - '4' + - '3' + - '2' + - '1' + - '0.12' + - '0.10' + - '0.8' +notifications: + email: + on_success: never diff --git a/node_modules/i/LICENSE b/node_modules/i/LICENSE new file mode 100644 index 0000000..c9b44cb --- /dev/null +++ b/node_modules/i/LICENSE @@ -0,0 +1,18 @@ +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/i/README.md b/node_modules/i/README.md new file mode 100644 index 0000000..37ca209 --- /dev/null +++ b/node_modules/i/README.md @@ -0,0 +1,176 @@ +# inflect + +customizable inflections for nodejs + +**NOTE: 0.3.2 was accidentally unpublished from the server and npm doesn't allow me to publish it back. Please upgrade to 0.3.3** + +## Installation + +```bash +npm install i +``` + +## Usage + +Require the module before using + +```js +var inflect = require('i')(); +``` + +All the below api functions can be called directly on a string + +```js +inflect.titleize('messages to store') // === 'Messages To Store' +'messages to store'.titleize // === 'Messages To Store' +``` + +only if `true` is passed while initiating + +```js +var inflect = require('i')(true); +``` + +### Pluralize + +```js +inflect.pluralize('person'); // === 'people' +inflect.pluralize('octopus'); // === 'octopi' +inflect.pluralize('Hat'); // === 'Hats' +``` + +### Singularize + +```js +inflect.singularize('people'); // === 'person' +inflect.singularize('octopi'); // === 'octopus' +inflect.singularize('Hats'); // === 'Hat' +``` + +### Camelize + +```js +inflect.camelize('message_properties'); // === 'MessageProperties' +inflect.camelize('message_properties', false); // === 'messageProperties' +``` + +### Underscore + +```js +inflect.underscore('MessageProperties'); // === 'message_properties' +inflect.underscore('messageProperties'); // === 'message_properties' +``` + +### Humanize + +```js +inflect.humanize('message_id'); // === 'Message' +``` + +### Dasherize + +```js +inflect.dasherize('message_properties'); // === 'message-properties' +inflect.dasherize('Message Properties'); // === 'Message Properties' +``` + +### Titleize + +```js +inflect.titleize('message_properties'); // === 'Message Properties' +inflect.titleize('message properties to keep'); // === 'Message Properties to Keep' +``` + +### Demodulize + +```js +inflect.demodulize('Message.Bus.Properties'); // === 'Properties' +``` + +### Tableize + +```js +inflect.tableize('MessageBusProperty'); // === 'message_bus_properties' +``` + +### Classify + +```js +inflect.classify('message_bus_properties'); // === 'MessageBusProperty' +``` + +### Foreign key + +```js +inflect.foreign_key('MessageBusProperty'); // === 'message_bus_property_id' +inflect.foreign_key('MessageBusProperty', false); // === 'message_bus_propertyid' +``` + +### Ordinalize + +```js +inflect.ordinalize( '1' ); // === '1st' +``` + +## Custom rules for inflection + +### Custom plural + +We can use regexp in any of these custom rules + +```js +inflect.inflections.plural('person', 'guys'); +inflect.pluralize('person'); // === 'guys' +inflect.singularize('guys'); // === 'guy' +``` + +### Custom singular + +```js +inflect.inflections.singular('guys', 'person') +inflect.singularize('guys'); // === 'person' +inflect.pluralize('person'); // === 'people' +``` + +### Custom irregular + +```js +inflect.inflections.irregular('person', 'guys') +inflect.pluralize('person'); // === 'guys' +inflect.singularize('guys'); // === 'person' +``` + +### Custom human + +```js +inflect.inflections.human(/^(.*)_cnt$/i, '$1_count'); +inflect.inflections.humanize('jargon_cnt'); // === 'Jargon count' +``` + +### Custom uncountable + +```js +inflect.inflections.uncountable('oil') +inflect.pluralize('oil'); // === 'oil' +inflect.singularize('oil'); // === 'oil' +``` + +## Contributors +Here is a list of [Contributors](http://github.com/pksunkara/inflect/contributors) + +### TODO + +- More obscure test cases + +__I accept pull requests and guarantee a reply back within a day__ + +## License +MIT/X11 + +## Bug Reports +Report [here](http://github.com/pksunkara/inflect/issues). __Guaranteed reply within a day__. + +## Contact +Pavan Kumar Sunkara (pavan.sss1991@gmail.com) + +Follow me on [github](https://github.com/users/follow?target=pksunkara), [twitter](http://twitter.com/pksunkara) diff --git a/node_modules/i/lib/defaults.js b/node_modules/i/lib/defaults.js new file mode 100644 index 0000000..05bdaf2 --- /dev/null +++ b/node_modules/i/lib/defaults.js @@ -0,0 +1,68 @@ +// Default inflections +module.exports = function (inflect) { + + inflect.plural(/$/, 's'); + inflect.plural(/s$/i, 's'); + inflect.plural(/(ax|test)is$/i, '$1es'); + inflect.plural(/(octop|vir)us$/i, '$1i'); + inflect.plural(/(octop|vir)i$/i, '$1i'); + inflect.plural(/(alias|status)$/i, '$1es'); + inflect.plural(/(bu)s$/i, '$1ses'); + inflect.plural(/(buffal|tomat)o$/i, '$1oes'); + inflect.plural(/([ti])um$/i, '$1a'); + inflect.plural(/([ti])a$/i, '$1a'); + inflect.plural(/sis$/i, 'ses'); + inflect.plural(/(?:([^fa])fe|(?:(oa)f)|([lr])f)$/i, '$1ves'); + inflect.plural(/(hive)$/i, '$1s'); + inflect.plural(/([^aeiouy]|qu)y$/i, '$1ies'); + inflect.plural(/(x|ch|ss|sh)$/i, '$1es'); + inflect.plural(/(matr|vert|ind)(?:ix|ex)$/i, '$1ices'); + inflect.plural(/([m|l])ouse$/i, '$1ice'); + inflect.plural(/([m|l])ice$/i, '$1ice'); + inflect.plural(/^(ox)$/i, '$1en'); + inflect.plural(/^(oxen)$/i, '$1'); + inflect.plural(/(quiz)$/i, '$1zes'); + + inflect.singular(/s$/i, ''); + inflect.singular(/(n)ews$/i, '$1ews'); + inflect.singular(/([ti])a$/i, '$1um'); + inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '$1sis'); + inflect.singular(/(^analy)ses$/i, '$1sis'); + inflect.singular(/([^f])ves$/i, '$1fe'); + inflect.singular(/(hive)s$/i, '$1'); + inflect.singular(/(tive)s$/i, '$1'); + inflect.singular(/(oave)s$/i, 'oaf'); + inflect.singular(/([lr])ves$/i, '$1f'); + inflect.singular(/([^aeiouy]|qu)ies$/i, '$1y'); + inflect.singular(/(s)eries$/i, '$1eries'); + inflect.singular(/(m)ovies$/i, '$1ovie'); + inflect.singular(/(x|ch|ss|sh)es$/i, '$1'); + inflect.singular(/([m|l])ice$/i, '$1ouse'); + inflect.singular(/(bus)es$/i, '$1'); + inflect.singular(/(o)es$/i, '$1'); + inflect.singular(/(shoe)s$/i, '$1'); + inflect.singular(/(cris|ax|test)es$/i, '$1is'); + inflect.singular(/(octop|vir)i$/i, '$1us'); + inflect.singular(/(alias|status)es$/i, '$1'); + inflect.singular(/^(ox)en/i, '$1'); + inflect.singular(/(vert|ind)ices$/i, '$1ex'); + inflect.singular(/(matr)ices$/i, '$1ix'); + inflect.singular(/(quiz)zes$/i, '$1'); + inflect.singular(/(database)s$/i, '$1'); + + inflect.irregular('child', 'children'); + inflect.irregular('person', 'people'); + inflect.irregular('man', 'men'); + inflect.irregular('child', 'children'); + inflect.irregular('sex', 'sexes'); + inflect.irregular('move', 'moves'); + inflect.irregular('cow', 'kine'); + inflect.irregular('zombie', 'zombies'); + inflect.irregular('oaf', 'oafs', true); + inflect.irregular('jefe', 'jefes'); + inflect.irregular('save', 'saves'); + inflect.irregular('safe', 'safes'); + inflect.irregular('fife', 'fifes'); + + inflect.uncountable(['equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep', 'jeans', 'sushi']); +} diff --git a/node_modules/i/lib/inflect.js b/node_modules/i/lib/inflect.js new file mode 100644 index 0000000..5e0cc70 --- /dev/null +++ b/node_modules/i/lib/inflect.js @@ -0,0 +1,11 @@ +// Requiring modules + +module.exports = function (attach) { + var methods = require('./methods'); + + if (attach) { + require('./native')(methods); + } + + return methods +}; diff --git a/node_modules/i/lib/inflections.js b/node_modules/i/lib/inflections.js new file mode 100644 index 0000000..1972551 --- /dev/null +++ b/node_modules/i/lib/inflections.js @@ -0,0 +1,120 @@ +// A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional +// inflection rules. Examples: +// +// BulletSupport.Inflector.inflect ($) -> +// $.plural /^(ox)$/i, '$1en' +// $.singular /^(ox)en/i, '$1' +// +// $.irregular 'octopus', 'octopi' +// +// $.uncountable "equipment" +// +// New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the +// pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may +// already have been loaded. + +var util = require('./util'); + +var Inflections = function () { + this.plurals = []; + this.singulars = []; + this.uncountables = []; + this.humans = []; + require('./defaults')(this); + return this; +}; + +// Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression. +// The replacement should always be a string that may include references to the matched data from the rule. +Inflections.prototype.plural = function (rule, replacement) { + if (typeof rule == 'string') { + this.uncountables = util.array.del(this.uncountables, rule); + } + this.uncountables = util.array.del(this.uncountables, replacement); + this.plurals.unshift([rule, replacement]); +}; + +// Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression. +// The replacement should always be a string that may include references to the matched data from the rule. +Inflections.prototype.singular = function (rule, replacement) { + if (typeof rule == 'string') { + this.uncountables = util.array.del(this.uncountables, rule); + } + this.uncountables = util.array.del(this.uncountables, replacement); + this.singulars.unshift([rule, replacement]); +}; + +// Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used +// for strings, not regular expressions. You simply pass the irregular in singular and plural form. +// +// irregular 'octopus', 'octopi' +// irregular 'person', 'people' +Inflections.prototype.irregular = function (singular, plural, fullMatchRequired) { + this.uncountables = util.array.del(this.uncountables, singular); + this.uncountables = util.array.del(this.uncountables, plural); + var prefix = ""; + if (fullMatchRequired) { + prefix = "^"; + } + if (singular[0].toUpperCase() == plural[0].toUpperCase()) { + this.plural(new RegExp("(" + prefix + singular[0] + ")" + singular.slice(1) + "$", "i"), '$1' + plural.slice(1)); + this.plural(new RegExp("(" + prefix + plural[0] + ")" + plural.slice(1) + "$", "i"), '$1' + plural.slice(1)); + this.singular(new RegExp("(" + prefix + plural[0] + ")" + plural.slice(1) + "$", "i"), '$1' + singular.slice(1)); + } else { + this.plural(new RegExp(prefix + (singular[0].toUpperCase()) + singular.slice(1) + "$"), plural[0].toUpperCase() + plural.slice(1)); + this.plural(new RegExp(prefix + (singular[0].toLowerCase()) + singular.slice(1) + "$"), plural[0].toLowerCase() + plural.slice(1)); + this.plural(new RegExp(prefix + (plural[0].toUpperCase()) + plural.slice(1) + "$"), plural[0].toUpperCase() + plural.slice(1)); + this.plural(new RegExp(prefix + (plural[0].toLowerCase()) + plural.slice(1) + "$"), plural[0].toLowerCase() + plural.slice(1)); + this.singular(new RegExp(prefix + (plural[0].toUpperCase()) + plural.slice(1) + "$"), singular[0].toUpperCase() + singular.slice(1)); + this.singular(new RegExp(prefix + (plural[0].toLowerCase()) + plural.slice(1) + "$"), singular[0].toLowerCase() + singular.slice(1)); + } +}; + +// Specifies a humanized form of a string by a regular expression rule or by a string mapping. +// When using a regular expression based replacement, the normal humanize formatting is called after the replacement. +// When a string is used, the human form should be specified as desired (example: 'The name', not 'the_name') +// +// human /(.*)_cnt$/i, '$1_count' +// human "legacy_col_person_name", "Name" +Inflections.prototype.human = function (rule, replacement) { + this.humans.unshift([rule, replacement]); +} + +// Add uncountable words that shouldn't be attempted inflected. +// +// uncountable "money" +// uncountable ["money", "information"] +Inflections.prototype.uncountable = function (words) { + this.uncountables = this.uncountables.concat(words); +} + +// Clears the loaded inflections within a given scope (default is _'all'_). +// Give the scope as a symbol of the inflection type, the options are: _'plurals'_, +// _'singulars'_, _'uncountables'_, _'humans'_. +// +// clear 'all' +// clear 'plurals' +Inflections.prototype.clear = function (scope) { + if (scope == null) scope = 'all'; + switch (scope) { + case 'all': + this.plurals = []; + this.singulars = []; + this.uncountables = []; + this.humans = []; + default: + this[scope] = []; + } +} + +// Clears the loaded inflections and initializes them to [default](../inflections.html) +Inflections.prototype.default = function () { + this.plurals = []; + this.singulars = []; + this.uncountables = []; + this.humans = []; + require('./defaults')(this); + return this; +}; + +module.exports = new Inflections(); diff --git a/node_modules/i/lib/methods.js b/node_modules/i/lib/methods.js new file mode 100644 index 0000000..6f6beeb --- /dev/null +++ b/node_modules/i/lib/methods.js @@ -0,0 +1,232 @@ +// The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without, +// and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept +// in inflections.coffee +// +// If you discover an incorrect inflection and require it for your application, you'll need +// to correct it yourself (explained below). + +var util = require('./util'); + +var inflect = module.exports; + +// Import [inflections](inflections.html) instance +inflect.inflections = require('./inflections') + +// Gives easy access to add inflections to this class +inflect.inflect = function (inflections_function) { + inflections_function(inflect.inflections); +}; + +// By default, _camelize_ converts strings to UpperCamelCase. If the argument to _camelize_ +// is set to _false_ then _camelize_ produces lowerCamelCase. +// +// _camelize_ will also convert '/' to '.' which is useful for converting paths to namespaces. +// +// "bullet_record".camelize() // => "BulletRecord" +// "bullet_record".camelize(false) // => "bulletRecord" +// "bullet_record/errors".camelize() // => "BulletRecord.Errors" +// "bullet_record/errors".camelize(false) // => "bulletRecord.Errors" +// +// As a rule of thumb you can think of _camelize_ as the inverse of _underscore_, +// though there are cases where that does not hold: +// +// "SSLError".underscore.camelize // => "SslError" +inflect.camelize = function(lower_case_and_underscored_word, first_letter_in_uppercase) { + var result; + if (first_letter_in_uppercase == null) first_letter_in_uppercase = true; + result = util.string.gsub(lower_case_and_underscored_word, /\/(.?)/, function($) { + return "." + (util.string.upcase($[1])); + }); + result = util.string.gsub(result, /(?:_)(.)/, function($) { + return util.string.upcase($[1]); + }); + if (first_letter_in_uppercase) { + return util.string.upcase(result); + } else { + return util.string.downcase(result); + } +}; + +// Makes an underscored, lowercase form from the expression in the string. +// +// Changes '.' to '/' to convert namespaces to paths. +// +// "BulletRecord".underscore() // => "bullet_record" +// "BulletRecord.Errors".underscore() // => "bullet_record/errors" +// +// As a rule of thumb you can think of +underscore+ as the inverse of +camelize+, +// though there are cases where that does not hold: +// +// "SSLError".underscore().camelize() // => "SslError" +inflect.underscore = function (camel_cased_word) { + var self; + self = util.string.gsub(camel_cased_word, /\./, '/'); + self = util.string.gsub(self, /([A-Z]+)([A-Z][a-z])/, "$1_$2"); + self = util.string.gsub(self, /([a-z\d])([A-Z])/, "$1_$2"); + self = util.string.gsub(self, /-/, '_'); + return self.toLowerCase(); +}; + +// Replaces underscores with dashes in the string. +// +// "puni_puni".dasherize() // => "puni-puni" +inflect.dasherize = function (underscored_word) { + return util.string.gsub(underscored_word, /_/, '-'); +}; + +// Removes the module part from the expression in the string. +// +// "BulletRecord.String.Inflections".demodulize() // => "Inflections" +// "Inflections".demodulize() // => "Inflections" +inflect.demodulize = function (class_name_in_module) { + return util.string.gsub(class_name_in_module, /^.*\./, ''); +}; + +// Creates a foreign key name from a class name. +// _separate_class_name_and_id_with_underscore_ sets whether +// the method should put '_' between the name and 'id'. +// +// "Message".foreign_key() // => "message_id" +// "Message".foreign_key(false) // => "messageid" +// "Admin::Post".foreign_key() // => "post_id" +inflect.foreign_key = function (class_name, separate_class_name_and_id_with_underscore) { + if (separate_class_name_and_id_with_underscore == null) { + separate_class_name_and_id_with_underscore = true; + } + return inflect.underscore(inflect.demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id"); +}; + +// Turns a number into an ordinal string used to denote the position in an +// ordered sequence such as 1st, 2nd, 3rd, 4th. +// +// ordinalize(1) // => "1st" +// ordinalize(2) // => "2nd" +// ordinalize(1002) // => "1002nd" +// ordinalize(1003) // => "1003rd" +// ordinalize(-11) // => "-11th" +// ordinalize(-1021) // => "-1021st" +inflect.ordinalize = function (number) { + var _ref; + number = parseInt(number); + if ((_ref = Math.abs(number) % 100) === 11 || _ref === 12 || _ref === 13) { + return "" + number + "th"; + } else { + switch (Math.abs(number) % 10) { + case 1: + return "" + number + "st"; + case 2: + return "" + number + "nd"; + case 3: + return "" + number + "rd"; + default: + return "" + number + "th"; + } + } +}; + +// Checks a given word for uncountability +// +// "money".uncountability() // => true +// "my money".uncountability() // => true +inflect.uncountability = function (word) { + return inflect.inflections.uncountables.some(function(ele, ind, arr) { + return word.match(new RegExp("(\\b|_)" + ele + "$", 'i')) != null; + }); +}; + +// Returns the plural form of the word in the string. +// +// "post".pluralize() // => "posts" +// "octopus".pluralize() // => "octopi" +// "sheep".pluralize() // => "sheep" +// "words".pluralize() // => "words" +// "CamelOctopus".pluralize() // => "CamelOctopi" +inflect.pluralize = function (word) { + var plural, result; + result = word; + if (word === '' || inflect.uncountability(word)) { + return result; + } else { + for (var i = 0; i < inflect.inflections.plurals.length; i++) { + plural = inflect.inflections.plurals[i]; + result = util.string.gsub(result, plural[0], plural[1]); + if (word.match(plural[0]) != null) break; + } + return result; + } +}; + +// The reverse of _pluralize_, returns the singular form of a word in a string. +// +// "posts".singularize() // => "post" +// "octopi".singularize() // => "octopus" +// "sheep".singularize() // => "sheep" +// "word".singularize() // => "word" +// "CamelOctopi".singularize() // => "CamelOctopus" +inflect.singularize = function (word) { + var result, singular; + result = word; + if (word === '' || inflect.uncountability(word)) { + return result; + } else { + for (var i = 0; i < inflect.inflections.singulars.length; i++) { + singular = inflect.inflections.singulars[i]; + result = util.string.gsub(result, singular[0], singular[1]); + if (word.match(singular[0])) break; + } + return result; + } +}; + +// Capitalizes the first word and turns underscores into spaces and strips a +// trailing "_id", if any. Like _titleize_, this is meant for creating pretty output. +// +// "employee_salary".humanize() // => "Employee salary" +// "author_id".humanize() // => "Author" +inflect.humanize = function (lower_case_and_underscored_word) { + var human, result; + result = lower_case_and_underscored_word; + for (var i = 0; i < inflect.inflections.humans.length; i++) { + human = inflect.inflections.humans[i]; + result = util.string.gsub(result, human[0], human[1]); + } + result = util.string.gsub(result, /_id$/, ""); + result = util.string.gsub(result, /_/, " "); + return util.string.capitalize(result, true); +}; + +// Capitalizes all the words and replaces some characters in the string to create +// a nicer looking title. _titleize_ is meant for creating pretty output. It is not +// used in the Bullet internals. +// +// +// "man from the boondocks".titleize() // => "Man From The Boondocks" +// "x-men: the last stand".titleize() // => "X Men: The Last Stand" +inflect.titleize = function (word) { + var self; + self = inflect.humanize(inflect.underscore(word)); + return util.string.capitalize(self); +}; + +// Create the name of a table like Bullet does for models to table names. This method +// uses the _pluralize_ method on the last word in the string. +// +// "RawScaledScorer".tableize() // => "raw_scaled_scorers" +// "egg_and_ham".tableize() // => "egg_and_hams" +// "fancyCategory".tableize() // => "fancy_categories" +inflect.tableize = function (class_name) { + return inflect.pluralize(inflect.underscore(class_name)); +}; + +// Create a class name from a plural table name like Bullet does for table names to models. +// Note that this returns a string and not a Class. +// +// "egg_and_hams".classify() // => "EggAndHam" +// "posts".classify() // => "Post" +// +// Singular names are not handled correctly: +// +// "business".classify() // => "Busines" +inflect.classify = function (table_name) { + return inflect.camelize(inflect.singularize(util.string.gsub(table_name, /.*\./, ''))); +} diff --git a/node_modules/i/lib/native.js b/node_modules/i/lib/native.js new file mode 100644 index 0000000..d2c8de1 --- /dev/null +++ b/node_modules/i/lib/native.js @@ -0,0 +1,26 @@ +module.exports = function (obj) { + + var addProperty = function (method, func) { + String.prototype.__defineGetter__(method, func); + } + + var stringPrototypeBlacklist = [ + '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', 'charAt', 'constructor', + 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf', 'charCodeAt', + 'indexOf', 'lastIndexof', 'length', 'localeCompare', 'match', 'replace', 'search', 'slice', 'split', 'substring', + 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'gsub' + ]; + + Object.keys(obj).forEach(function (key) { + if (key != 'inflect' && key != 'inflections') { + if (stringPrototypeBlacklist.indexOf(key) !== -1) { + console.log('warn: You should not override String.prototype.' + key); + } else { + addProperty(key, function () { + return obj[key](this); + }); + } + } + }); + +} diff --git a/node_modules/i/lib/util.js b/node_modules/i/lib/util.js new file mode 100644 index 0000000..87ebd3e --- /dev/null +++ b/node_modules/i/lib/util.js @@ -0,0 +1,136 @@ +// Some utility functions in js + +var u = module.exports = { + array: { + // Returns a copy of the array with the value removed once + // + // [1, 2, 3, 1].del 1 #=> [2, 3, 1] + // [1, 2, 3].del 4 #=> [1, 2, 3] + del: function (arr, val) { + var index = arr.indexOf(val); + if (index != -1) { + if (index == 0) { + return arr.slice(1) + } else { + return arr.slice(0, index).concat(arr.slice(index+1)); + } + } else { + return arr; + } + }, + + // Returns the first element of the array + // + // [1, 2, 3].first() #=> 1 + first: function(arr) { + return arr[0]; + }, + + // Returns the last element of the array + // + // [1, 2, 3].last() #=> 3 + last: function(arr) { + return arr[arr.length-1]; + } + }, + string: { + // Returns a copy of str with all occurrences of pattern replaced with either replacement or the return value of a function. + // The pattern will typically be a Regexp; if it is a String then no regular expression metacharacters will be interpreted + // (that is /\d/ will match a digit, but ‘\d’ will match a backslash followed by a ‘d’). + // + // In the function form, the current match object is passed in as a parameter to the function, and variables such as + // $[1], $[2], $[3] (where $ is the match object) will be set appropriately. The value returned by the function will be + // substituted for the match on each call. + // + // The result inherits any tainting in the original string or any supplied replacement string. + // + // "hello".gsub /[aeiou]/, '*' #=> "h*ll*" + // "hello".gsub /[aeiou]/, '<$1>' #=> "hll" + // "hello".gsub /[aeiou]/, ($) { + // "<#{$[1]}>" #=> "hll" + // + gsub: function (str, pattern, replacement) { + var i, match, matchCmpr, matchCmprPrev, replacementStr, result, self; + if (!((pattern != null) && (replacement != null))) return u.string.value(str); + result = ''; + self = str; + while (self.length > 0) { + if ((match = self.match(pattern))) { + result += self.slice(0, match.index); + if (typeof replacement === 'function') { + match[1] = match[1] || match[0]; + result += replacement(match); + } else if (replacement.match(/\$[1-9]/)) { + matchCmprPrev = match; + matchCmpr = u.array.del(match, void 0); + while (matchCmpr !== matchCmprPrev) { + matchCmprPrev = matchCmpr; + matchCmpr = u.array.del(matchCmpr, void 0); + } + match[1] = match[1] || match[0]; + replacementStr = replacement; + for (i = 1; i <= 9; i++) { + if (matchCmpr[i]) { + replacementStr = u.string.gsub(replacementStr, new RegExp("\\\$" + i), matchCmpr[i]); + } + } + result += replacementStr; + } else { + result += replacement; + } + self = self.slice(match.index + match[0].length); + } else { + result += self; + self = ''; + } + } + return result; + }, + + // Returns a copy of the String with the first letter being upper case + // + // "hello".upcase #=> "Hello" + upcase: function(str) { + var self = u.string.gsub(str, /_([a-z])/, function ($) { + return "_" + $[1].toUpperCase(); + }); + self = u.string.gsub(self, /\/([a-z])/, function ($) { + return "/" + $[1].toUpperCase(); + }); + return self[0].toUpperCase() + self.substr(1); + }, + + // Returns a copy of capitalized string + // + // "employee salary" #=> "Employee Salary" + capitalize: function (str, spaces) { + var self = str.toLowerCase(); + if(!spaces) { + self = u.string.gsub(self, /\s([a-z])/, function ($) { + return " " + $[1].toUpperCase(); + }); + } + return self[0].toUpperCase() + self.substr(1); + }, + + // Returns a copy of the String with the first letter being lower case + // + // "HELLO".downcase #=> "hELLO" + downcase: function(str) { + var self = u.string.gsub(str, /_([A-Z])/, function ($) { + return "_" + $[1].toLowerCase(); + }); + self = u.string.gsub(self, /\/([A-Z])/, function ($) { + return "/" + $[1].toLowerCase(); + }); + return self[0].toLowerCase() + self.substr(1); + }, + + // Returns a string value for the String object + // + // "hello".value() #=> "hello" + value: function (str) { + return str.substr(0); + } + } +} diff --git a/node_modules/i/package.json b/node_modules/i/package.json new file mode 100644 index 0000000..0d481cd --- /dev/null +++ b/node_modules/i/package.json @@ -0,0 +1,117 @@ +{ + "_args": [ + [ + { + "raw": "i@0.3.x", + "scope": null, + "escapedName": "i", + "name": "i", + "rawSpec": "0.3.x", + "spec": ">=0.3.0 <0.4.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/utile" + ] + ], + "_from": "i@>=0.3.0 <0.4.0", + "_id": "i@0.3.5", + "_inCache": true, + "_location": "/i", + "_nodeVersion": "0.12.9", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/i-0.3.5.tgz_1462355680372_0.1744775390252471" + }, + "_npmUser": { + "name": "pksunkara", + "email": "pavan.sss1991@gmail.com" + }, + "_npmVersion": "2.14.9", + "_phantomChildren": {}, + "_requested": { + "raw": "i@0.3.x", + "scope": null, + "escapedName": "i", + "name": "i", + "rawSpec": "0.3.x", + "spec": ">=0.3.0 <0.4.0", + "type": "range" + }, + "_requiredBy": [ + "/utile" + ], + "_resolved": "https://registry.npmjs.org/i/-/i-0.3.5.tgz", + "_shasum": "1d2b854158ec8169113c6cb7f6b6801e99e211d5", + "_shrinkwrap": null, + "_spec": "i@0.3.x", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/utile", + "author": { + "name": "Pavan Kumar Sunkara", + "email": "pavan.sss1991@gmail.com", + "url": "pksunkara.github.com" + }, + "bugs": { + "url": "https://github.com/pksunkara/inflect/issues" + }, + "contributors": [ + { + "name": "Pavan Kumar Sunkara", + "email": "pavan.sss1991@gmail.com" + } + ], + "dependencies": {}, + "description": "custom inflections for nodejs", + "devDependencies": { + "vows": "0.7.0" + }, + "directories": {}, + "dist": { + "shasum": "1d2b854158ec8169113c6cb7f6b6801e99e211d5", + "tarball": "https://registry.npmjs.org/i/-/i-0.3.5.tgz" + }, + "engines": { + "node": ">=0.4" + }, + "gitHead": "bbcadd57a182007ab158acea511515b815385d4d", + "homepage": "http://pksunkara.github.com/inflect", + "keywords": [ + "singular", + "plural", + "camelize", + "underscore", + "dasherize", + "demodulize", + "ordinalize", + "uncountable", + "pluralize", + "singularize", + "titleize", + "tableize", + "classify", + "foreign_key" + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/pksunkara/inflect/raw/master/LICENSE" + } + ], + "main": "./lib/inflect", + "maintainers": [ + { + "name": "pksunkara", + "email": "pavan.sss1991@gmail.com" + } + ], + "name": "i", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/pksunkara/inflect.git" + }, + "scripts": { + "test": "vows --spec $(find test -name '*-test.js')" + }, + "version": "0.3.5" +} diff --git a/node_modules/i/test/inflector/cases.js b/node_modules/i/test/inflector/cases.js new file mode 100644 index 0000000..a818f9a --- /dev/null +++ b/node_modules/i/test/inflector/cases.js @@ -0,0 +1,230 @@ +(function() { + + module.exports = { + SingularToPlural: { + "search": "searches", + "switch": "switches", + "fix": "fixes", + "box": "boxes", + "process": "processes", + "address": "addresses", + "case": "cases", + "stack": "stacks", + "wish": "wishes", + "fish": "fish", + "jeans": "jeans", + "funky jeans": "funky jeans", + "my money": "my money", + "category": "categories", + "query": "queries", + "ability": "abilities", + "agency": "agencies", + "movie": "movies", + "archive": "archives", + "index": "indices", + "wife": "wives", + "safe": "saves", + "half": "halves", + "move": "moves", + "salesperson": "salespeople", + "person": "people", + "spokesman": "spokesmen", + "man": "men", + "woman": "women", + "basis": "bases", + "diagnosis": "diagnoses", + "diagnosis_a": "diagnosis_as", + "datum": "data", + "medium": "media", + "stadium": "stadia", + "analysis": "analyses", + "node_child": "node_children", + "child": "children", + "experience": "experiences", + "day": "days", + "comment": "comments", + "foobar": "foobars", + "newsletter": "newsletters", + "old_news": "old_news", + "news": "news", + "series": "series", + "species": "species", + "quiz": "quizzes", + "perspective": "perspectives", + "ox": "oxen", + "photo": "photos", + "buffalo": "buffaloes", + "tomato": "tomatoes", + "dwarf": "dwarves", + "elf": "elves", + "information": "information", + "equipment": "equipment", + "bus": "buses", + "status": "statuses", + "status_code": "status_codes", + "mouse": "mice", + "louse": "lice", + "house": "houses", + "octopus": "octopi", + "virus": "viri", + "alias": "aliases", + "portfolio": "portfolios", + "vertex": "vertices", + "matrix": "matrices", + "matrix_fu": "matrix_fus", + "axis": "axes", + "testis": "testes", + "crisis": "crises", + "rice": "rice", + "shoe": "shoes", + "horse": "horses", + "prize": "prizes", + "edge": "edges", + "cow": "kine", + "database": "databases", + "safe": "safes", + "belief": "beliefs", + "gaffe": "gaffes", + "cafe": "cafes", + "caffe": "caffes", + "life": "lives", + "wife": "wives", + "save": "saves", + "fife": "fifes", + "carafe": "carafes", + "giraffe": "giraffes", + "elf": "elves", + "calf": "calves", + "bookshelf": "bookshelves", + "wolf": "wolves", + "half": "halves", + "meatloaf": "meatloaves", + "loaf": "loaves", + "oaf": "oafs", + "jefe": "jefes", + "afterlife": "afterlives", + }, + CamelToUnderscore: { + "Product": "product", + "SpecialGuest": "special_guest", + "ApplicationController": "application_controller", + "Area51Controller": "area51_controller" + }, + UnderscoreToLowerCamel: { + "product": "product", + "Widget": "widget", + "special_guest": "specialGuest", + "application_controller": "applicationController", + "area51_controller": "area51Controller" + }, + CamelToUnderscoreWithoutReverse: { + "HTMLTidy": "html_tidy", + "HTMLTidyGenerator": "html_tidy_generator", + "FreeBSD": "free_bsd", + "HTML": "html" + }, + CamelWithModuleToUnderscoreWithSlash: { + "Admin.Product": "admin/product", + "Users.Commission.Department": "users/commission/department", + "UsersSection.CommissionDepartment": "users_section/commission_department" + }, + ClassNameToForeignKeyWithUnderscore: { + "Person": "person_id", + "MyApplication.Billing.Account": "account_id" + }, + ClassNameToForeignKeyWithoutUnderscore: { + "Person": "personid", + "MyApplication.Billing.Account": "accountid" + }, + ClassNameToTableName: { + "PrimarySpokesman": "primary_spokesmen", + "NodeChild": "node_children" + }, + UnderscoreToHuman: { + "employee_salary": "Employee salary", + "employee_id": "Employee", + "underground": "Underground" + }, + MixtureToTitleCase: { + 'bullet_record': 'Bullet Record', + 'BulletRecord': 'Bullet Record', + 'bullet web service': 'Bullet Web Service', + 'Bullet Web Service': 'Bullet Web Service', + 'Bullet web service': 'Bullet Web Service', + 'bulletwebservice': 'Bulletwebservice', + 'Bulletwebservice': 'Bulletwebservice', + "pavan's code": "Pavan's Code", + "Pavan's code": "Pavan's Code", + "pavan's Code": "Pavan's Code" + }, + OrdinalNumbers: { + "-1": "-1st", + "-2": "-2nd", + "-3": "-3rd", + "-4": "-4th", + "-5": "-5th", + "-6": "-6th", + "-7": "-7th", + "-8": "-8th", + "-9": "-9th", + "-10": "-10th", + "-11": "-11th", + "-12": "-12th", + "-13": "-13th", + "-14": "-14th", + "-20": "-20th", + "-21": "-21st", + "-22": "-22nd", + "-23": "-23rd", + "-24": "-24th", + "-100": "-100th", + "-101": "-101st", + "-102": "-102nd", + "-103": "-103rd", + "-104": "-104th", + "-110": "-110th", + "-111": "-111th", + "-112": "-112th", + "-113": "-113th", + "-1000": "-1000th", + "-1001": "-1001st", + "0": "0th", + "1": "1st", + "2": "2nd", + "3": "3rd", + "4": "4th", + "5": "5th", + "6": "6th", + "7": "7th", + "8": "8th", + "9": "9th", + "10": "10th", + "11": "11th", + "12": "12th", + "13": "13th", + "14": "14th", + "20": "20th", + "21": "21st", + "22": "22nd", + "23": "23rd", + "24": "24th", + "100": "100th", + "101": "101st", + "102": "102nd", + "103": "103rd", + "104": "104th", + "110": "110th", + "111": "111th", + "112": "112th", + "113": "113th", + "1000": "1000th", + "1001": "1001st" + }, + UnderscoresToDashes: { + "street": "street", + "street_address": "street-address", + "person_street_address": "person-street-address" + } + }; + +}).call(this); diff --git a/node_modules/i/test/inflector/inflections-test.js b/node_modules/i/test/inflector/inflections-test.js new file mode 100644 index 0000000..be8d960 --- /dev/null +++ b/node_modules/i/test/inflector/inflections-test.js @@ -0,0 +1,87 @@ +(function() { + var assert, vows; + + vows = require('vows'); + + assert = require('assert'); + + vows.describe('Module Inflector inflections').addBatch({ + 'Test inflector inflections': { + topic: require('../../lib/inflections'), + 'clear': { + 'single': function(topic) { + topic.uncountables = [1, 2, 3]; + topic.humans = [1, 2, 3]; + topic.clear('uncountables'); + assert.isEmpty(topic.uncountables); + return assert.deepEqual(topic.humans, [1, 2, 3]); + }, + 'all': function(topic) { + assert.deepEqual(topic.humans, [1, 2, 3]); + topic.uncountables = [1, 2, 3]; + topic.clear(); + assert.isEmpty(topic.uncountables); + return assert.isEmpty(topic.humans); + } + }, + 'uncountable': { + 'one item': function(topic) { + topic.clear(); + assert.isEmpty(topic.uncountables); + topic.uncountable('money'); + return assert.deepEqual(topic.uncountables, ['money']); + }, + 'many items': function(topic) { + topic.clear(); + assert.isEmpty(topic.uncountables); + topic.uncountable(['money', 'rice']); + return assert.deepEqual(topic.uncountables, ['money', 'rice']); + } + }, + 'human': function(topic) { + topic.clear(); + assert.isEmpty(topic.humans); + topic.human("legacy_col_person_name", "Name"); + return assert.deepEqual(topic.humans, [["legacy_col_person_name", "Name"]]); + }, + 'plural': function(topic) { + topic.clear(); + assert.isEmpty(topic.plurals); + topic.plural('ox', 'oxen'); + assert.deepEqual(topic.plurals, [['ox', 'oxen']]); + topic.uncountable('money'); + assert.deepEqual(topic.uncountables, ['money']); + topic.uncountable('monies'); + topic.plural('money', 'monies'); + assert.deepEqual(topic.plurals, [['money', 'monies'], ['ox', 'oxen']]); + return assert.isEmpty(topic.uncountables); + }, + 'singular': function(topic) { + topic.clear(); + assert.isEmpty(topic.singulars); + topic.singular('ox', 'oxen'); + assert.deepEqual(topic.singulars, [['ox', 'oxen']]); + topic.uncountable('money'); + assert.deepEqual(topic.uncountables, ['money']); + topic.uncountable('monies'); + topic.singular('money', 'monies'); + assert.deepEqual(topic.singulars, [['money', 'monies'], ['ox', 'oxen']]); + return assert.isEmpty(topic.uncountables); + }, + 'irregular': function(topic) { + topic.clear(); + topic.uncountable(['octopi', 'octopus']); + assert.deepEqual(topic.uncountables, ['octopi', 'octopus']); + topic.irregular('octopus', 'octopi'); + assert.isEmpty(topic.uncountables); + assert.equal(topic.singulars[0][0].toString(), /(o)ctopi$/i.toString()); + assert.equal(topic.singulars[0][1], '$1ctopus'); + assert.equal(topic.plurals[0][0].toString(), /(o)ctopi$/i.toString()); + assert.equal(topic.plurals[0][1], '$1ctopi'); + assert.equal(topic.plurals[1][0].toString(), /(o)ctopus$/i.toString()); + return assert.equal(topic.plurals[1][1].toString(), '$1ctopi'); + } + } + })["export"](module); + +}).call(this); diff --git a/node_modules/i/test/inflector/methods-test.js b/node_modules/i/test/inflector/methods-test.js new file mode 100644 index 0000000..d49d414 --- /dev/null +++ b/node_modules/i/test/inflector/methods-test.js @@ -0,0 +1,345 @@ +(function() { + var assert, cases, vows, util; + + vows = require('vows'); + + assert = require('assert'); + + util = require('../../lib/util'); + + cases = require('./cases'); + + vows.describe('Module Inflector methods').addBatch({ + 'Test inflector method': { + topic: require('../../lib/methods'), + 'camelize': { + 'word': function(topic) { + var i, words, _i, _len, _ref, _results; + words = cases.CamelToUnderscore; + _ref = Object.keys(words); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + _results.push(assert.equal(topic.camelize(words[i]), i)); + } + return _results; + }, + 'word with first letter lower': function(topic) { + var i, words, _i, _len, _ref, _results; + words = cases.UnderscoreToLowerCamel; + _ref = Object.keys(words); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + _results.push(assert.equal(topic.camelize(i, false), words[i])); + } + return _results; + }, + 'path': function(topic) { + var i, words, _i, _len, _ref, _results; + words = cases.CamelWithModuleToUnderscoreWithSlash; + _ref = Object.keys(words); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + _results.push(assert.equal(topic.camelize(words[i]), i)); + } + return _results; + }, + 'path with first letter lower': function(topic) { + return assert.equal(topic.camelize('bullet_record/errors', false), 'bulletRecord.Errors'); + } + }, + 'underscore': { + 'word': function(topic) { + var i, words, _i, _j, _len, _len2, _ref, _ref2, _results; + words = cases.CamelToUnderscore; + _ref = Object.keys(words); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + assert.equal(topic.underscore(i), words[i]); + } + words = cases.CamelToUnderscoreWithoutReverse; + _ref2 = Object.keys(words); + _results = []; + for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { + i = _ref2[_j]; + _results.push(assert.equal(topic.underscore(i), words[i])); + } + return _results; + }, + 'path': function(topic) { + var i, words, _i, _len, _ref, _results; + words = cases.CamelWithModuleToUnderscoreWithSlash; + _ref = Object.keys(words); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + _results.push(assert.equal(topic.underscore(i), words[i])); + } + return _results; + }, + 'from dasherize': function(topic) { + var i, words, _i, _len, _ref, _results; + words = cases.UnderscoresToDashes; + _ref = Object.keys(words); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + _results.push(assert.equal(topic.underscore(topic.dasherize(i)), i)); + } + return _results; + } + }, + 'dasherize': { + 'underscored_word': function(topic) { + var i, words, _i, _len, _ref, _results; + words = cases.UnderscoresToDashes; + _ref = Object.keys(words); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + _results.push(assert.equal(topic.dasherize(i), words[i])); + } + return _results; + } + }, + 'demodulize': { + 'module name': function(topic) { + return assert.equal(topic.demodulize('BulletRecord.CoreExtensions.Inflections'), 'Inflections'); + }, + 'isolated module name': function(topic) { + return assert.equal(topic.demodulize('Inflections'), 'Inflections'); + } + }, + 'foreign_key': { + 'normal': function(topic) { + var i, words, _i, _len, _ref, _results; + words = cases.ClassNameToForeignKeyWithoutUnderscore; + _ref = Object.keys(words); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + _results.push(assert.equal(topic.foreign_key(i, false), words[i])); + } + return _results; + }, + 'with_underscore': function(topic) { + var i, words, _i, _len, _ref, _results; + words = cases.ClassNameToForeignKeyWithUnderscore; + _ref = Object.keys(words); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + _results.push(assert.equal(topic.foreign_key(i), words[i])); + } + return _results; + } + }, + 'ordinalize': function(topic) { + var i, words, _i, _len, _ref, _results; + words = cases.OrdinalNumbers; + _ref = Object.keys(words); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + _results.push(assert.equal(topic.ordinalize(i), words[i])); + } + return _results; + } + } + }).addBatch({ + 'Test inflector inflection methods': { + topic: function() { + var Inflector; + Inflector = require('../../lib/methods'); + Inflector.inflections["default"](); + return Inflector; + }, + 'pluralize': { + 'empty': function(topic) { + return assert.equal(topic.pluralize(''), ''); + }, + 'uncountable': function(topic) { + return assert.equal(topic.pluralize('money'), 'money'); + }, + 'normal': function(topic) { + topic.inflections.irregular('octopus', 'octopi'); + return assert.equal(topic.pluralize('octopus'), 'octopi'); + }, + 'cases': function(topic) { + var i, words, _i, _j, _len, _len2, _ref, _ref2, _results; + words = cases.SingularToPlural; + _ref = Object.keys(words); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + assert.equal(topic.pluralize(i), words[i]); + } + _ref2 = Object.keys(words); + _results = []; + for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { + i = _ref2[_j]; + _results.push(assert.equal(topic.pluralize(util.string.capitalize(i)), util.string.capitalize(words[i]))); + } + return _results; + }, + 'cases plural': function(topic) { + var i, words, _i, _j, _len, _len2, _ref, _ref2, _results; + words = cases.SingularToPlural; + _ref = Object.keys(words); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + assert.equal(topic.pluralize(words[i]), words[i]); + } + _ref2 = Object.keys(words); + _results = []; + for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { + i = _ref2[_j]; + _results.push(assert.equal(topic.pluralize(util.string.capitalize(words[i])), util.string.capitalize(words[i]))); + } + return _results; + } + }, + 'singuralize': { + 'empty': function(topic) { + return assert.equal(topic.singularize(''), ''); + }, + 'uncountable': function(topic) { + return assert.equal(topic.singularize('money'), 'money'); + }, + 'normal': function(topic) { + topic.inflections.irregular('octopus', 'octopi'); + return assert.equal(topic.singularize('octopi'), 'octopus'); + }, + 'cases': function(topic) { + var i, words, _i, _j, _len, _len2, _ref, _ref2, _results; + words = cases.SingularToPlural; + _ref = Object.keys(words); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + assert.equal(topic.singularize(words[i]), i); + } + _ref2 = Object.keys(words); + _results = []; + for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { + i = _ref2[_j]; + _results.push(assert.equal(topic.singularize(util.string.capitalize(words[i])), util.string.capitalize(i))); + } + return _results; + } + }, + 'uncountablility': { + 'normal': function(topic) { + var i, words, _i, _j, _k, _len, _len2, _len3, _results; + words = topic.inflections.uncountables; + for (_i = 0, _len = words.length; _i < _len; _i++) { + i = words[_i]; + assert.equal(topic.singularize(i), i); + } + for (_j = 0, _len2 = words.length; _j < _len2; _j++) { + i = words[_j]; + assert.equal(topic.pluralize(i), i); + } + _results = []; + for (_k = 0, _len3 = words.length; _k < _len3; _k++) { + i = words[_k]; + _results.push(assert.equal(topic.singularize(i), topic.pluralize(i))); + } + return _results; + }, + 'greedy': function(topic) { + var countable_word, uncountable_word; + uncountable_word = "ors"; + countable_word = "sponsor"; + topic.inflections.uncountable(uncountable_word); + assert.equal(topic.singularize(uncountable_word), uncountable_word); + assert.equal(topic.pluralize(uncountable_word), uncountable_word); + assert.equal(topic.pluralize(uncountable_word), topic.singularize(uncountable_word)); + assert.equal(topic.singularize(countable_word), 'sponsor'); + assert.equal(topic.pluralize(countable_word), 'sponsors'); + return assert.equal(topic.singularize(topic.pluralize(countable_word)), 'sponsor'); + } + }, + 'humanize': { + 'normal': function(topic) { + var i, words, _i, _len, _ref, _results; + words = cases.UnderscoreToHuman; + _ref = Object.keys(words); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + _results.push(assert.equal(topic.humanize(i), words[i])); + } + return _results; + }, + 'with rule': function(topic) { + topic.inflections.human(/^(.*)_cnt$/i, '$1_count'); + topic.inflections.human(/^prefix_(.*)$/i, '$1'); + assert.equal(topic.humanize('jargon_cnt'), 'Jargon count'); + return assert.equal(topic.humanize('prefix_request'), 'Request'); + }, + 'with string': function(topic) { + topic.inflections.human('col_rpted_bugs', 'Reported bugs'); + assert.equal(topic.humanize('col_rpted_bugs'), 'Reported bugs'); + return assert.equal(topic.humanize('COL_rpted_bugs'), 'Col rpted bugs'); + }, + 'with _id': function(topic) { + return assert.equal(topic.humanize('author_id'), 'Author'); + } + }, + 'titleize': { + 'normal': function(topic) { + var i, words, _i, _len, _ref, _results; + words = cases.MixtureToTitleCase; + _ref = Object.keys(words); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + _results.push(assert.equal(topic.titleize(i), words[i])); + } + return _results; + }, + 'with hyphens': function(topic) { + return assert.equal(topic.titleize('x-men: the last stand'), 'X Men: The Last Stand'); + }, + 'with ampersands': function(topic) { + return assert.equal(topic.titleize('garfunkel & oates'), 'Garfunkel & Oates'); + } + }, + 'tableize': function(topic) { + var i, words, _i, _len, _ref, _results; + words = cases.ClassNameToTableName; + _ref = Object.keys(words); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + _results.push(assert.equal(topic.tableize(i), words[i])); + } + return _results; + }, + 'classify': { + 'underscore': function(topic) { + var i, words, _i, _j, _len, _len2, _ref, _ref2, _results; + words = cases.ClassNameToTableName; + _ref = Object.keys(words); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + assert.equal(topic.classify(words[i]), i); + } + _ref2 = Object.keys(words); + _results = []; + for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { + i = _ref2[_j]; + _results.push(assert.equal(topic.classify('table_prefix.' + words[i]), i)); + } + return _results; + }, + 'normal': function(topic) { + topic.inflections.irregular('octopus', 'octopi'); + return assert.equal(topic.classify('octopi'), 'Octopus'); + } + } + } + })["export"](module); + +}).call(this); diff --git a/node_modules/i/test/utils/array-test.js b/node_modules/i/test/utils/array-test.js new file mode 100644 index 0000000..95ba2bc --- /dev/null +++ b/node_modules/i/test/utils/array-test.js @@ -0,0 +1,39 @@ +(function() { + var assert, vows, util; + + vows = require('vows'); + + assert = require('assert'); + + util = require('../../lib/util'); + + vows.describe('Module core extension Array').addBatch({ + 'Testing del': { + topic: ['a', 'b', 'c'], + 'element exists': { + 'first element': function(topic) { + return assert.deepEqual(util.array.del(topic, 'a'), ['b', 'c']); + }, + 'middle element': function(topic) { + return assert.deepEqual(util.array.del(topic, 'b'), ['a', 'c']); + }, + 'last element': function(topic) { + return assert.deepEqual(util.array.del(topic, 'c'), ['a', 'b']); + } + }, + 'element does not exist': function(topic) { + return assert.deepEqual(util.array.del(topic, 'd'), ['a', 'b', 'c']); + } + }, + 'Testing utils': { + topic: ['a', 'b', 'c'], + 'first': function(topic) { + return assert.equal(util.array.first(topic), 'a'); + }, + 'last': function(topic) { + return assert.equal(util.array.last(topic), 'c'); + } + } + })["export"](module); + +}).call(this); diff --git a/node_modules/i/test/utils/string-test.js b/node_modules/i/test/utils/string-test.js new file mode 100644 index 0000000..e932233 --- /dev/null +++ b/node_modules/i/test/utils/string-test.js @@ -0,0 +1,88 @@ +(function() { + var assert, vows, util; + + vows = require('vows'); + + assert = require('assert'); + + util = require('../../lib/util'); + + vows.describe('Module core extension String').addBatch({ + 'Testing value': { + topic: 'bullet', + 'join the keys': function(topic) { + return assert.equal(util.string.value(topic), 'bullet'); + } + }, + 'Testing gsub': { + topic: 'bullet', + 'when no args': function(topic) { + return assert.equal(util.string.gsub(topic), 'bullet'); + }, + 'when only 1 arg': function(topic) { + return assert.equal(util.string.gsub(topic, /./), 'bullet'); + }, + 'when given proper args': function(topic) { + return assert.equal(util.string.gsub(topic, /[aeiou]/, '*'), 'b*ll*t'); + }, + 'when replacement is a function': { + 'with many groups': function(topic) { + var str; + str = util.string.gsub(topic, /([aeiou])(.)/, function($) { + return "<" + $[1] + ">" + $[2]; + }); + return assert.equal(str, 'bllt'); + }, + 'with no groups': function(topic) { + var str; + str = util.string.gsub(topic, /[aeiou]/, function($) { + return "<" + $[1] + ">"; + }); + return assert.equal(str, 'bllt'); + } + }, + 'when replacement is special': { + 'with many groups': function(topic) { + return assert.equal(util.string.gsub(topic, /([aeiou])(.)/, '<$1>$2'), 'bllt'); + }, + 'with no groups': function(topic) { + return assert.equal(util.string.gsub(topic, /[aeiou]/, '<$1>'), 'bllt'); + } + } + }, + 'Testing capitalize': { + topic: 'employee salary', + 'normal': function(topic) { + return assert.equal(util.string.capitalize(topic), 'Employee Salary'); + } + }, + 'Testing upcase': { + topic: 'bullet', + 'only first letter should be upcase': function(topic) { + return assert.equal(util.string.upcase(topic), 'Bullet'); + }, + 'letter after underscore': function(topic) { + return assert.equal(util.string.upcase('bullet_record'), 'Bullet_Record'); + }, + 'letter after slash': function(topic) { + return assert.equal(util.string.upcase('bullet_record/errors'), 'Bullet_Record/Errors'); + }, + 'no letter after space': function(topic) { + return assert.equal(util.string.upcase('employee salary'), 'Employee salary'); + } + }, + 'Testing downcase': { + topic: 'BULLET', + 'only first letter should be downcase': function(topic) { + return assert.equal(util.string.downcase(topic), 'bULLET'); + }, + 'letter after underscore': function(topic) { + return assert.equal(util.string.downcase('BULLET_RECORD'), 'bULLET_rECORD'); + }, + 'letter after slash': function(topic) { + return assert.equal(util.string.downcase('BULLET_RECORD/ERRORS'), 'bULLET_rECORD/eRRORS'); + } + } + })["export"](module); + +}).call(this); diff --git a/node_modules/iconv-lite/.npmignore b/node_modules/iconv-lite/.npmignore new file mode 100644 index 0000000..fe46877 --- /dev/null +++ b/node_modules/iconv-lite/.npmignore @@ -0,0 +1,3 @@ +node_modules +*~ +*sublime-* diff --git a/node_modules/iconv-lite/.travis.yml b/node_modules/iconv-lite/.travis.yml new file mode 100644 index 0000000..0bab9cd --- /dev/null +++ b/node_modules/iconv-lite/.travis.yml @@ -0,0 +1,5 @@ + language: node_js + node_js: + - 0.4 + - 0.6 + - 0.8 diff --git a/node_modules/iconv-lite/LICENSE b/node_modules/iconv-lite/LICENSE new file mode 100644 index 0000000..d518d83 --- /dev/null +++ b/node_modules/iconv-lite/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2011 Alexander Shtuchkin + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/node_modules/iconv-lite/README.md b/node_modules/iconv-lite/README.md new file mode 100644 index 0000000..ba30a32 --- /dev/null +++ b/node_modules/iconv-lite/README.md @@ -0,0 +1,72 @@ +iconv-lite - pure javascript character encoding conversion +====================================================================== + +[![Build Status](https://secure.travis-ci.org/ashtuchkin/iconv-lite.png?branch=master)](http://travis-ci.org/ashtuchkin/iconv-lite) + +## Features + +* Pure javascript. Doesn't need native code compilation. +* Easy API. +* Works on Windows and in sandboxed environments like [Cloud9](http://c9.io). +* Encoding is much faster than node-iconv (see below for performance comparison). + +## Usage + + var iconv = require('iconv-lite'); + + // Convert from an encoded buffer to string. + str = iconv.decode(buf, 'win1251'); + + // Convert from string to an encoded buffer. + buf = iconv.encode("Sample input string", 'win1251'); + + // Check if encoding is supported + iconv.encodingExists("us-ascii") + + +## Supported encodings + +* All node.js native encodings: 'utf8', 'ucs2', 'ascii', 'binary', 'base64' +* All widespread single byte encodings: Windows 125x family, ISO-8859 family, + IBM/DOS codepages, Macintosh family, KOI8 family. + Aliases like 'latin1', 'us-ascii' also supported. +* Multibyte encodings: 'gbk', 'gb2313', 'Big5', 'cp950'. + +Others are easy to add, see the source. Please, participate. +Most encodings are generated from node-iconv. Thank you Ben Noordhuis and iconv authors! + +Not supported yet: EUC family, Shift_JIS. + + +## Encoding/decoding speed + +Comparison with node-iconv module (1000x256kb, on Ubuntu 12.04, Core i5/2.5 GHz, Node v0.8.7). +Note: your results may vary, so please always check on your hardware. + + operation iconv@1.2.4 iconv-lite@0.2.4 + ---------------------------------------------------------- + encode('win1251') ~115 Mb/s ~230 Mb/s + decode('win1251') ~95 Mb/s ~130 Mb/s + + +## Notes + +When decoding, a 'binary'-encoded string can be used as a source buffer. +Untranslatable characters are set to � or ?. No transliteration is currently supported, pull requests are welcome. + +## Testing + + git clone git@github.com:ashtuchkin/iconv-lite.git + cd iconv-lite + npm install + npm test + + # To view performance: + node test/performance.js + +## TODO + +* Support streaming character conversion, something like util.pipe(req, iconv.fromEncodingStream('latin1')). +* Add more encodings. +* Add transliteration (best fit char). +* Add tests and correct support of variable-byte encodings (currently work is delegated to node). diff --git a/node_modules/iconv-lite/README.md~ b/node_modules/iconv-lite/README.md~ new file mode 100644 index 0000000..5f57561 --- /dev/null +++ b/node_modules/iconv-lite/README.md~ @@ -0,0 +1,54 @@ +iconv-lite - native javascript conversion between character encodings. +====================================================================== + +## Usage + + var iconv = require('iconv-lite'); + + // Convert from an encoded buffer to string. + str = iconv.fromEncoding(buf, 'win-1251'); + // Or + str = iconv.decode(buf, 'win-1251'); + + // Convert from string to an encoded buffer. + buf = iconv.toEncoding("Sample input string", 'win-1251'); + // Or + buf = iconv.encode("Sample input string", 'win-1251'); + +## Supported encodings + +Currently only a small part of encodings supported: + +* All node.js native encodings: 'utf8', 'ucs2', 'ascii', 'binary', 'base64'. +* 'latin1' +* Cyrillic encodings: 'windows-1251', 'koi8-r', 'iso 8859-5'. + +Other encodings are easy to add, see the source. Please, participate. + + +## Encoding/decoding speed + +Comparison with iconv module (1000 times 256kb, on Core i5/2.5 GHz). + + Operation\module iconv iconv-lite (this) + toEncoding('win1251') 19.57 mb/s 49.04 mb/s + fromEncoding('win1251') 16.39 mb/s 24.11 mb/s + + +## Notes + +This module is JavaScript-only, thus can be used in a sandboxed environment like [Cloud9](http://c9.io). + +Untranslatable characters are set to '?'. No transliteration is currently supported, pull requests are welcome. + +## Testing + + npm install --dev iconv-lite + vows + +## TODO + +* Support streaming character conversion, something like util.pipe(req, iconv.fromEncodingStream('latin1')). +* Add more encodings. +* Add transliteration (best fit char). +* Add tests and correct support of variable-byte encodings (currently work is delegated to node). diff --git a/node_modules/iconv-lite/encodings/big5.js b/node_modules/iconv-lite/encodings/big5.js new file mode 100644 index 0000000..0423d63 --- /dev/null +++ b/node_modules/iconv-lite/encodings/big5.js @@ -0,0 +1,9 @@ +var big5Table = require('./table/big5.js'); +module.exports = { + 'windows950': 'big5', + 'cp950': 'big5', + 'big5': { + type: 'table', + table: big5Table + } +} diff --git a/node_modules/iconv-lite/encodings/gbk.js b/node_modules/iconv-lite/encodings/gbk.js new file mode 100644 index 0000000..78a63ec --- /dev/null +++ b/node_modules/iconv-lite/encodings/gbk.js @@ -0,0 +1,9 @@ +var gbkTable = require('./table/gbk.js'); +module.exports = { + 'windows936': 'gbk', + 'gb2312': 'gbk', + 'gbk': { + type: 'table', + table: gbkTable + } +} diff --git a/node_modules/iconv-lite/encodings/singlebyte.js b/node_modules/iconv-lite/encodings/singlebyte.js new file mode 100644 index 0000000..f41a7ea --- /dev/null +++ b/node_modules/iconv-lite/encodings/singlebyte.js @@ -0,0 +1,340 @@ +module.exports = { + "437": "cp437", + "737": "cp737", + "775": "cp775", + "850": "cp850", + "852": "cp852", + "855": "cp855", + "857": "cp857", + "858": "cp858", + "860": "cp860", + "861": "cp861", + "862": "cp862", + "863": "cp863", + "864": "cp864", + "865": "cp865", + "866": "cp866", + "869": "cp869", + "874": "iso885911", + "1250": "windows1250", + "1251": "windows1251", + "1252": "windows1252", + "1253": "windows1253", + "1254": "windows1254", + "1255": "windows1255", + "1256": "windows1256", + "1257": "windows1257", + "1258": "windows1258", + "10000": "macroman", + "10006": "macgreek", + "10007": "maccyrillic", + "10029": "maccenteuro", + "10079": "maciceland", + "10081": "macturkish", + "20866": "koi8r", + "21866": "koi8u", + "28591": "iso88591", + "28592": "iso88592", + "28593": "iso88593", + "28594": "iso88594", + "28595": "iso88595", + "28596": "iso88596", + "28597": "iso88597", + "28598": "iso88598", + "28599": "iso88599", + "28600": "iso885910", + "28601": "iso885911", + "28603": "iso885913", + "28604": "iso885914", + "28605": "iso885915", + "28606": "iso885916", + "ascii8bit": "ascii", + "usascii": "ascii", + "latin1": "iso88591", + "latin2": "iso88592", + "latin3": "iso88593", + "latin4": "iso88594", + "latin6": "iso885910", + "latin7": "iso885913", + "latin8": "iso885914", + "latin9": "iso885915", + "latin10": "iso885916", + "cp819": "iso88951", + "arabic": "iso88596", + "arabic8": "iso88596", + "greek": "iso88597", + "greek8": "iso88597", + "hebrew": "iso88598", + "hebrew8": "iso88598", + "turkish": "iso88599", + "turkish8": "iso88599", + "thai": "iso885911", + "thai8": "iso885911", + "tis620": "iso885911", + "windows874": "iso885911", + "win874": "iso885911", + "cp874": "iso885911", + "celtic": "iso885914", + "celtic8": "iso885914", + "cp20866": "koi8r", + "ibm878": "koi8r", + "cp21866": "koi8u", + "ibm1168": "koi8u", + "windows1250": { + "type": "singlebyte", + "chars": "€�‚�„…†‡�‰Š‹ŚŤŽŹ�‘’“”•–—�™š›śťžź ˇ˘Ł¤Ą¦§¨©Ş«¬­®Ż°±˛ł´µ¶·¸ąş»Ľ˝ľżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙" + }, + "win1250": "windows1250", + "cp1250": "windows1250", + "windows1251": { + "type": "singlebyte", + "chars": "ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋЏђ‘’“”•–—�™љ›њќћџ ЎўЈ¤Ґ¦§Ё©Є«¬­®Ї°±Ііґµ¶·ё№є»јЅѕїАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" + }, + "win1251": "windows1251", + "cp1251": "windows1251", + "windows1252": { + "type": "singlebyte", + "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "win1252": "windows1252", + "cp1252": "windows1252", + "windows1253": { + "type": "singlebyte", + "chars": "€�‚ƒ„…†‡�‰�‹�����‘’“”•–—�™�›���� ΅Ά£¤¥¦§¨©�«¬­®―°±²³΄µ¶·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�" + }, + "win1253": "windows1253", + "cp1253": "windows1253", + "windows1254": { + "type": "singlebyte", + "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ����‘’“”•–—˜™š›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ" + }, + "win1254": "windows1254", + "cp1254": "windows1254", + "windows1255": { + "type": "singlebyte", + "chars": "€�‚ƒ„…†‡ˆ‰�‹�����‘’“”•–—˜™�›���� ¡¢£₪¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾¿ְֱֲֳִֵֶַָֹ�ֻּֽ־ֿ׀ׁׂ׃װױײ׳״�������אבגדהוזחטיךכלםמןנסעףפץצקרשת��‎‏�" + }, + "win1255": "windows1255", + "cp1255": "windows1255", + "windows1256": { + "type": "singlebyte", + "chars": "€پ‚ƒ„…†‡ˆ‰ٹ‹Œچژڈگ‘’“”•–—ک™ڑ›œ‌‍ں ،¢£¤¥¦§¨©ھ«¬­®¯°±²³´µ¶·¸¹؛»¼½¾؟ہءآأؤإئابةتثجحخدذرزسشصض×طظعغـفقكàلâمنهوçèéêëىيîïًٌٍَôُِ÷ّùْûü‎‏ے" + }, + "win1256": "windows1256", + "cp1256": "windows1256", + "windows1257": { + "type": "singlebyte", + "chars": "€�‚�„…†‡�‰�‹�¨ˇ¸�‘’“”•–—�™�›�¯˛� �¢£¤�¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙" + }, + "win1257": "windows1257", + "cp1257": "windows1257", + "windows1258": { + "type": "singlebyte", + "chars": "€�‚ƒ„…†‡ˆ‰�‹Œ����‘’“”•–—˜™�›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖ×ØÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ" + }, + "win1258": "windows1258", + "cp1258": "windows1258", + "iso88591": { + "type": "singlebyte", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "cp28591": "iso88591", + "iso88592": { + "type": "singlebyte", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ą˘Ł¤ĽŚ§¨ŠŞŤŹ­ŽŻ°ą˛ł´ľśˇ¸šşťź˝žżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙" + }, + "cp28592": "iso88592", + "iso88593": { + "type": "singlebyte", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ħ˘£¤�Ĥ§¨İŞĞĴ­�Ż°ħ²³´µĥ·¸ışğĵ½�żÀÁÂ�ÄĊĈÇÈÉÊËÌÍÎÏ�ÑÒÓÔĠÖ×ĜÙÚÛÜŬŜßàáâ�äċĉçèéêëìíîï�ñòóôġö÷ĝùúûüŭŝ˙" + }, + "cp28593": "iso88593", + "iso88594": { + "type": "singlebyte", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄĸŖ¤ĨĻ§¨ŠĒĢŦ­Ž¯°ą˛ŗ´ĩļˇ¸šēģŧŊžŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎĪĐŅŌĶÔÕÖ×ØŲÚÛÜŨŪßāáâãäåæįčéęëėíîīđņōķôõö÷øųúûüũū˙" + }, + "cp28594": "iso88594", + "iso88595": { + "type": "singlebyte", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂЃЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђѓєѕіїјљњћќ§ўџ" + }, + "cp28595": "iso88595", + "iso88596": { + "type": "singlebyte", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ���¤�������،­�������������؛���؟�ءآأؤإئابةتثجحخدذرزسشصضطظعغ�����ـفقكلمنهوىيًٌٍَُِّْ�������������" + }, + "cp28596": "iso88596", + "iso88597": { + "type": "singlebyte", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ‘’£€₯¦§¨©ͺ«¬­�―°±²³΄΅Ά·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�" + }, + "cp28597": "iso88597", + "iso88598": { + "type": "singlebyte", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ �¢£¤¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾��������������������������������‗אבגדהוזחטיךכלםמןנסעףפץצקרשת��‎‏�" + }, + "cp28598": "iso88598", + "iso88599": { + "type": "singlebyte", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ" + }, + "cp28599": "iso88599", + "iso885910": { + "type": "singlebyte", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄĒĢĪĨĶ§ĻĐŠŦŽ­ŪŊ°ąēģīĩķ·ļđšŧž―ūŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎÏÐŅŌÓÔÕÖŨØŲÚÛÜÝÞßāáâãäåæįčéęëėíîïðņōóôõöũøųúûüýþĸ" + }, + "cp28600": "iso885910", + "iso885911": { + "type": "singlebyte", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" + }, + "cp28601": "iso885911", + "iso885913": { + "type": "singlebyte", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ”¢£¤„¦§Ø©Ŗ«¬­®Æ°±²³“µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž’" + }, + "cp28603": "iso885913", + "iso885914": { + "type": "singlebyte", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ḃḃ£ĊċḊ§Ẁ©ẂḋỲ­®ŸḞḟĠġṀṁ¶ṖẁṗẃṠỳẄẅṡÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŴÑÒÓÔÕÖṪØÙÚÛÜÝŶßàáâãäåæçèéêëìíîïŵñòóôõöṫøùúûüýŷÿ" + }, + "cp28604": "iso885914", + "iso885915": { + "type": "singlebyte", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "cp28605": "iso885915", + "iso885916": { + "type": "singlebyte", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄąŁ€„Š§š©Ș«Ź­źŻ°±ČłŽ”¶·žčș»ŒœŸżÀÁÂĂÄĆÆÇÈÉÊËÌÍÎÏĐŃÒÓÔŐÖŚŰÙÚÛÜĘȚßàáâăäćæçèéêëìíîïđńòóôőöśűùúûüęțÿ" + }, + "cp28606": "iso885916", + "cp437": { + "type": "singlebyte", + "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm437": "cp437", + "cp737": { + "type": "singlebyte", + "chars": "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ " + }, + "ibm737": "cp737", + "cp775": { + "type": "singlebyte", + "chars": "ĆüéāäģåćłēŖŗīŹÄÅÉæÆōöĢ¢ŚśÖÜø£ØפĀĪóŻżź”¦©®¬½¼Ł«»░▒▓│┤ĄČĘĖ╣║╗╝ĮŠ┐└┴┬├─┼ŲŪ╚╔╩╦╠═╬Žąčęėįšųūž┘┌█▄▌▐▀ÓßŌŃõÕµńĶķĻļņĒŅ’­±“¾¶§÷„°∙·¹³²■ " + }, + "ibm775": "cp775", + "cp850": { + "type": "singlebyte", + "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈıÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²■ " + }, + "ibm850": "cp850", + "cp852": { + "type": "singlebyte", + "chars": "ÇüéâäůćçłëŐőîŹÄĆÉĹĺôöĽľŚśÖÜŤťŁ×čáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÁÂĚŞ╣║╗╝Żż┐└┴┬├─┼Ăă╚╔╩╦╠═╬¤đĐĎËďŇÍÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÝţ´­˝˛ˇ˘§÷¸°¨˙űŘř■ " + }, + "ibm852": "cp852", + "cp855": { + "type": "singlebyte", + "chars": "ђЂѓЃёЁєЄѕЅіІїЇјЈљЉњЊћЋќЌўЎџЏюЮъЪаАбБцЦдДеЕфФгГ«»░▒▓│┤хХиИ╣║╗╝йЙ┐└┴┬├─┼кК╚╔╩╦╠═╬¤лЛмМнНоОп┘┌█▄Пя▀ЯрРсСтТуУжЖвВьЬ№­ыЫзЗшШэЭщЩчЧ§■ " + }, + "ibm855": "cp855", + "cp857": { + "type": "singlebyte", + "chars": "ÇüéâäàåçêëèïîıÄÅÉæÆôöòûùİÖÜø£ØŞşáíóúñÑĞ𿮬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ºªÊËÈ�ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµ�×ÚÛÙìÿ¯´­±�¾¶§÷¸°¨·¹³²■ " + }, + "ibm857": "cp857", + "cp858": { + "type": "singlebyte", + "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈ€ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²■ " + }, + "ibm858": "cp858", + "cp860": { + "type": "singlebyte", + "chars": "ÇüéâãàÁçêÊèÍÔìÃÂÉÀÈôõòÚùÌÕÜ¢£Ù₧ÓáíóúñѪº¿Ò¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm860": "cp860", + "cp861": { + "type": "singlebyte", + "chars": "ÇüéâäàåçêëèÐðÞÄÅÉæÆôöþûÝýÖÜø£Ø₧ƒáíóúÁÍÓÚ¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm861": "cp861", + "cp862": { + "type": "singlebyte", + "chars": "אבגדהוזחטיךכלםמןנסעףפץצקרשת¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm862": "cp862", + "cp863": { + "type": "singlebyte", + "chars": "ÇüéâÂà¶çêëèïî‗À§ÉÈÊôËÏûù¤ÔÜ¢£ÙÛƒ¦´óú¨¸³¯Î⌐¬½¼¾«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm863": "cp863", + "cp864": { + "type": "singlebyte", + "chars": "°·∙√▒─│┼┤┬├┴┐┌└┘β∞φ±½¼≈«»ﻷﻸ��ﻻﻼ� ­ﺂ£¤ﺄ��ﺎﺏﺕﺙ،ﺝﺡﺥ٠١٢٣٤٥٦٧٨٩ﻑ؛ﺱﺵﺹ؟¢ﺀﺁﺃﺅﻊﺋﺍﺑﺓﺗﺛﺟﺣﺧﺩﺫﺭﺯﺳﺷﺻﺿﻁﻅﻋﻏ¦¬÷×ﻉـﻓﻗﻛﻟﻣﻧﻫﻭﻯﻳﺽﻌﻎﻍﻡﹽّﻥﻩﻬﻰﻲﻐﻕﻵﻶﻝﻙﻱ■�" + }, + "ibm864": "cp864", + "cp865": { + "type": "singlebyte", + "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø₧ƒáíóúñѪº¿⌐¬½¼¡«¤░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm865": "cp865", + "cp866": { + "type": "singlebyte", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№¤■ " + }, + "ibm866": "cp866", + "cp869": { + "type": "singlebyte", + "chars": "������Ά�·¬¦‘’Έ―ΉΊΪΌ��ΎΫ©Ώ²³ά£έήίϊΐόύΑΒΓΔΕΖΗ½ΘΙ«»░▒▓│┤ΚΛΜΝ╣║╗╝ΞΟ┐└┴┬├─┼ΠΡ╚╔╩╦╠═╬ΣΤΥΦΧΨΩαβγ┘┌█▄δε▀ζηθικλμνξοπρσςτ΄­±υφχ§ψ΅°¨ωϋΰώ■ " + }, + "ibm869": "cp869", + "maccenteuro": { + "type": "singlebyte", + "chars": "ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ" + }, + "maccroatian": { + "type": "singlebyte", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø¿¡¬√ƒ≈Ć«Č… ÀÃÕŒœĐ—“”‘’÷◊�©⁄¤‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ" + }, + "maccyrillic": { + "type": "singlebyte", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°¢£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµ∂ЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю¤" + }, + "macgreek": { + "type": "singlebyte", + "chars": "Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦­ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάΝ¬ΟΡ≈Τ«»… ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ�" + }, + "maciceland": { + "type": "singlebyte", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüÝ°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" + }, + "macroman": { + "type": "singlebyte", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" + }, + "macromania": { + "type": "singlebyte", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂŞ∞±≤≥¥µ∂∑∏π∫ªºΩăş¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›Ţţ‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" + }, + "macthai": { + "type": "singlebyte", + "chars": "«»…“”�•‘’� กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู​–—฿เแโใไๅๆ็่้๊๋์ํ™๏๐๑๒๓๔๕๖๗๘๙®©����" + }, + "macturkish": { + "type": "singlebyte", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙ�ˆ˜¯˘˙˚¸˝˛ˇ" + }, + "macukraine": { + "type": "singlebyte", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю¤" + }, + "koi8r": { + "type": "singlebyte", + "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ё╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡Ё╢╣╤╥╦╧╨╩╪╫╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" + }, + "koi8u": { + "type": "singlebyte", + "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ёє╔ії╗╘╙╚╛ґ╝╞╟╠╡ЁЄ╣ІЇ╦╧╨╩╪Ґ╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" + } +}; diff --git a/node_modules/iconv-lite/encodings/table/big5.js b/node_modules/iconv-lite/encodings/table/big5.js new file mode 100644 index 0000000..605c72d --- /dev/null +++ b/node_modules/iconv-lite/encodings/table/big5.js @@ -0,0 +1 @@ +module.exports={"33088":19991,"33089":20002,"33090":20012,"33091":20053,"33092":20066,"33093":20106,"33094":20144,"33095":20203,"33096":20205,"33097":20220,"33098":20252,"33099":20362,"33100":20479,"33101":20546,"33102":20560,"33103":20600,"33104":20696,"33105":20702,"33106":20724,"33107":20758,"33108":20810,"33109":20817,"33110":20836,"33111":20842,"33112":20869,"33113":20880,"33114":20893,"33115":20902,"33116":20904,"33117":20905,"33118":20935,"33119":20950,"33120":20955,"33121":20972,"33122":20988,"33123":21003,"33124":21012,"33125":21013,"33126":21024,"33127":21035,"33128":21049,"33129":21071,"33130":21105,"33131":21136,"33132":21138,"33133":21140,"33134":21148,"33135":21167,"33136":21173,"33137":21200,"33138":21248,"33139":21255,"33140":21284,"33141":21318,"33142":21343,"33143":21395,"33144":21424,"33145":21469,"33146":21539,"33147":21584,"33148":21585,"33149":21642,"33150":21661,"33185":21667,"33186":21684,"33187":21712,"33188":21795,"33189":21823,"33190":21836,"33191":21843,"33192":21853,"33193":21868,"33194":21918,"33195":21929,"33196":21996,"33197":22005,"33198":22051,"33199":22096,"33200":22140,"33201":22154,"33202":22164,"33203":22176,"33204":22191,"33205":22232,"33206":22272,"33207":22361,"33208":22373,"33209":22399,"33210":22405,"33211":22409,"33212":22433,"33213":22444,"33214":22452,"33215":22464,"33216":22472,"33217":22483,"33218":22511,"33219":22596,"33220":22636,"33221":22674,"33222":22682,"33223":22706,"33224":22712,"33225":22757,"33226":22779,"33227":22786,"33228":22795,"33229":22800,"33230":22808,"33231":22811,"33232":29836,"33233":29837,"33234":29849,"33235":29851,"33236":29860,"33237":29876,"33238":29881,"33239":29896,"33240":29900,"33241":29904,"33242":29907,"33243":30018,"33244":30037,"33245":30062,"33246":30093,"33247":30110,"33248":30172,"33249":30252,"33250":30287,"33251":30289,"33252":30323,"33253":30324,"33254":30373,"33255":30425,"33256":30478,"33257":30479,"33258":30552,"33259":30578,"33260":30583,"33261":30584,"33262":30586,"33263":30587,"33264":30616,"33265":30639,"33266":30654,"33267":30659,"33268":30661,"33269":30667,"33270":30685,"33271":30694,"33272":30708,"33273":30750,"33274":30781,"33275":30786,"33276":30788,"33277":30795,"33278":30801,"33344":21782,"33345":22775,"33346":38964,"33347":33883,"33348":28948,"33349":33398,"33350":35158,"33351":40236,"33352":40206,"33353":36527,"33354":24674,"33355":26214,"33356":34510,"33357":25785,"33358":37772,"33359":22107,"33360":28485,"33361":35532,"33362":29001,"33363":24012,"33364":34633,"33365":39464,"33366":31658,"33367":36107,"33368":39255,"33369":23597,"33370":32331,"33371":38938,"33372":20518,"33373":25458,"33374":40568,"33375":30783,"33376":40633,"33377":40634,"33378":36046,"33379":35715,"33380":61305,"33381":33931,"33382":37284,"33383":31331,"33384":25776,"33385":24061,"33386":24214,"33387":32865,"33388":26965,"33389":31466,"33390":28710,"33391":26812,"33392":31095,"33393":28060,"33394":36841,"33395":31074,"33396":22178,"33397":34687,"33398":21093,"33399":31108,"33400":28300,"33401":37271,"33402":31622,"33403":38956,"33404":26717,"33405":20397,"33406":34222,"33441":31725,"33442":34635,"33443":20534,"33444":26893,"33445":27542,"33446":24910,"33447":20855,"33448":30495,"33449":20516,"33450":32622,"33451":30452,"33452":27097,"33453":24803,"33454":25334,"33455":21599,"33456":38788,"33457":22092,"33458":20677,"33459":22040,"33460":34398,"33461":22834,"33462":22875,"33463":22877,"33464":22883,"33465":22892,"33466":22939,"33467":22999,"33468":23019,"33469":23066,"33470":23210,"33471":23248,"33472":23281,"33473":23350,"33474":23497,"33475":23539,"33476":23571,"33477":23580,"33478":23582,"33479":23635,"33480":23705,"33481":23708,"33482":23738,"33483":23739,"33484":23745,"33485":23797,"33486":23802,"33487":23829,"33488":23832,"33489":23870,"33490":23891,"33491":23900,"33492":23917,"33493":23923,"33494":23924,"33495":23948,"33496":23952,"33497":23993,"33498":24016,"33499":24019,"33500":24135,"33501":24164,"33502":24271,"33503":24272,"33504":24298,"33505":24304,"33506":24329,"33507":24332,"33508":24337,"33509":24353,"33510":24372,"33511":24385,"33512":24389,"33513":24401,"33514":24412,"33515":24422,"33516":24451,"33517":24560,"33518":24650,"33519":24672,"33520":24715,"33521":24742,"33522":24798,"33523":24849,"33524":24864,"33525":24865,"33526":24892,"33527":24893,"33528":24984,"33529":25015,"33530":25076,"33531":25107,"33532":25117,"33533":25118,"33534":25143,"33600":24186,"33601":27664,"33602":21454,"33603":20267,"33604":20302,"33605":21556,"33606":22257,"33607":22766,"33608":22841,"33609":22918,"33610":23596,"33611":20915,"33612":20914,"33613":28798,"33614":35265,"33615":35282,"33616":36125,"33617":36710,"33618":20122,"33619":26469,"33620":20177,"33621":20004,"33622":21327,"33623":23626,"33624":20872,"33625":24213,"33626":25269,"33627":19996,"33628":20105,"33629":29366,"33630":31868,"33631":32416,"33632":21351,"33633":36711,"33634":37048,"33635":38271,"33636":38376,"33637":20384,"33638":20387,"33639":20822,"33640":21017,"33641":21170,"33642":21364,"33643":22850,"33644":24069,"33645":26594,"33646":27769,"33647":20026,"33648":32419,"33649":32418,"33650":32426,"33651":32427,"33652":32421,"33653":32422,"33654":32417,"33655":32989,"33656":33486,"33657":35745,"33658":35746,"33659":35747,"33660":36126,"33661":36127,"33662":20891,"33697":36712,"33698":38377,"33699":38886,"33700":39029,"33701":39118,"33702":39134,"33703":20457,"33704":20204,"33705":20261,"33706":20010,"33707":20262,"33708":20179,"33709":20923,"33710":21018,"33711":21093,"33712":21592,"33713":23089,"33714":23385,"33715":23777,"33716":23707,"33717":23704,"33718":24072,"33719":24211,"33720":24452,"33721":25375,"33722":26102,"33723":26187,"33724":20070,"33725":27902,"33726":27971,"33727":20044,"33728":29421,"33729":29384,"33730":20137,"33731":30757,"33732":31210,"33733":32442,"33734":32433,"33735":32441,"33736":32431,"33737":32445,"33738":32432,"33739":32423,"33740":32429,"33741":32435,"33742":32440,"33743":32439,"33744":32961,"33745":33033,"33746":21005,"33747":35760,"33748":35750,"33749":35752,"33750":35751,"33751":35754,"33752":35759,"33753":35757,"33754":35755,"33755":23682,"33756":36130,"33757":36129,"33758":36713,"33759":36715,"33760":38025,"33761":38024,"33762":38026,"33763":38027,"33764":38378,"33765":38453,"33766":38485,"33767":38473,"33768":39269,"33769":39532,"33770":39592,"33771":20266,"33772":20255,"33773":20390,"33774":20391,"33775":21153,"33776":21160,"33777":21306,"33778":21442,"33779":21713,"33780":38382,"33781":34900,"33782":22269,"33783":22362,"33784":22441,"33785":25191,"33786":22815,"33787":23044,"33788":22919,"33789":19987,"33790":23558,"33856":23625,"33857":23781,"33858":23703,"33859":24102,"33860":24080,"33861":24352,"33862":24378,"33863":20174,"33864":24469,"33865":20932,"33866":24581,"33867":25195,"33868":25346,"33869":25194,"33870":25249,"33871":25379,"33872":36133,"33873":21551,"33874":26011,"33875":26025,"33876":26172,"33877":21206,"33878":24323,"33879":26465,"33880":26541,"33881":26432,"33882":27682,"33883":20937,"33884":27973,"33885":28170,"33886":27882,"33887":27814,"33888":20928,"33889":29301,"33890":29424,"33891":29616,"33892":20135,"33893":27605,"33894":24322,"33895":20247,"33896":32458,"33897":32479,"33898":32461,"33899":32459,"33900":32460,"33901":32454,"33902":32453,"33903":32452,"33904":32456,"33905":32449,"33906":32450,"33907":38069,"33908":20064,"33909":33626,"33910":33550,"33911":33682,"33912":24196,"33913":33483,"33914":22788,"33915":26415,"33916":34926,"33917":35269,"33918":35268,"33953":35775,"33954":35766,"33955":35776,"33956":35767,"33957":35768,"33958":35774,"33959":35772,"33960":35769,"33961":36137,"33962":36131,"33963":36143,"33964":36135,"33965":36138,"33966":36139,"33967":36717,"33968":36719,"33969":36825,"33970":36830,"33971":36851,"33972":38039,"33973":38035,"33974":38031,"33975":38034,"33976":38381,"33977":38472,"33978":38470,"33979":38452,"33980":39030,"33981":39031,"33982":40060,"33983":40479,"33984":21348,"33985":40614,"33986":22791,"33987":20263,"33988":20254,"33989":20975,"33990":21056,"33991":21019,"33992":21171,"33993":21195,"33994":20007,"33995":21333,"33996":21727,"33997":21796,"33998":20052,"33999":22260,"34000":23591,"34001":22330,"34002":25253,"34003":22490,"34004":22774,"34005":23090,"34006":23547,"34007":23706,"34008":24103,"34009":24079,"34010":21397,"34011":21417,"34012":24694,"34013":38391,"34014":24812,"34015":24699,"34016":24700,"34017":25315,"34018":25381,"34019":25442,"34020":25196,"34021":26531,"34022":26635,"34023":26632,"34024":38054,"34025":27531,"34026":22771,"34027":27695,"34028":27689,"34029":28044,"34030":20945,"34031":28270,"34032":28065,"34033":27748,"34034":27979,"34035":27985,"34036":28067,"34037":26080,"34038":29369,"34039":33487,"34040":30011,"34041":30153,"34042":21457,"34043":30423,"34044":30746,"34045":31174,"34046":31383,"34112":31508,"34113":31499,"34114":32478,"34115":32467,"34116":32466,"34117":32477,"34118":19997,"34119":32476,"34120":32473,"34121":32474,"34122":32470,"34123":32475,"34124":32899,"34125":32958,"34126":32960,"34127":21326,"34128":33713,"34129":33484,"34130":34394,"34131":35270,"34132":35780,"34133":35789,"34134":35777,"34135":35778,"34136":35791,"34137":35781,"34138":35784,"34139":35787,"34140":35785,"34141":35786,"34142":35779,"34143":36142,"34144":36148,"34145":36144,"34146":36155,"34147":36146,"34148":36153,"34149":36154,"34150":36149,"34151":20080,"34152":36140,"34153":36152,"34154":36151,"34155":36722,"34156":36724,"34157":36726,"34158":36827,"34159":37038,"34160":20065,"34161":38046,"34162":38062,"34163":38041,"34164":38048,"34165":38055,"34166":38045,"34167":38052,"34168":38051,"34169":38389,"34170":38384,"34171":24320,"34172":38386,"34173":38388,"34174":38387,"34209":38431,"34210":38454,"34211":38451,"34212":38887,"34213":39033,"34214":39034,"34215":39035,"34216":39274,"34217":39277,"34218":39272,"34219":39278,"34220":39276,"34221":20911,"34222":39533,"34223":20081,"34224":20538,"34225":20256,"34226":20165,"34227":20542,"34228":20260,"34229":20588,"34230":38130,"34231":21183,"34232":31215,"34233":27719,"34234":21527,"34235":21596,"34236":21595,"34237":22253,"34238":22278,"34239":28034,"34240":22359,"34241":22366,"34242":22488,"34243":33556,"34244":22885,"34245":22920,"34246":29233,"34247":24574,"34248":24582,"34249":24698,"34250":25439,"34251":25250,"34252":25443,"34253":26500,"34254":26198,"34255":26197,"34256":26104,"34257":20250,"34258":19994,"34259":26497,"34260":26472,"34261":26722,"34262":26539,"34263":23681,"34264":27807,"34265":28781,"34266":28287,"34267":28369,"34268":27815,"34269":28902,"34270":28860,"34271":28800,"34272":28949,"34273":29239,"34274":29422,"34275":29502,"34276":29682,"34277":24403,"34278":30415,"34279":30544,"34280":30529,"34281":38606,"34282":30860,"34283":33410,"34284":31509,"34285":31908,"34286":32463,"34287":32482,"34288":32465,"34289":32485,"34290":32486,"34291":20041,"34292":32673,"34293":22307,"34294":32928,"34295":33050,"34296":32959,"34297":33041,"34298":33636,"34299":33479,"34300":21494,"34301":33716,"34302":34398,"34368":34383,"34369":21495,"34370":34568,"34371":34476,"34372":34917,"34373":35013,"34374":35815,"34375":35813,"34376":35814,"34377":35797,"34378":35799,"34379":35800,"34380":35801,"34381":35811,"34382":35802,"34383":35805,"34384":35803,"34385":35809,"34386":35810,"34387":35808,"34388":35807,"34389":36156,"34390":36164,"34391":36158,"34392":36159,"34393":36160,"34394":36161,"34395":36162,"34396":36165,"34397":36739,"34398":36733,"34399":36732,"34400":36734,"34401":20892,"34402":36816,"34403":36798,"34404":36829,"34405":36807,"34406":37049,"34407":38068,"34408":38067,"34409":38073,"34410":38072,"34411":38078,"34412":38080,"34413":38085,"34414":38057,"34415":38082,"34416":38083,"34417":38089,"34418":38091,"34419":38044,"34420":38093,"34421":38079,"34422":38086,"34423":38392,"34424":38504,"34425":38589,"34426":30005,"34427":39044,"34428":39037,"34429":39039,"34430":39036,"34465":39041,"34466":39042,"34467":39282,"34468":39284,"34469":39281,"34470":39280,"34471":39536,"34472":39534,"34473":39535,"34474":40480,"34475":20389,"34476":20392,"34477":21294,"34478":21388,"34479":23581,"34480":21589,"34481":21497,"34482":21949,"34483":21863,"34484":21716,"34485":22242,"34486":22270,"34487":23576,"34488":22443,"34489":22545,"34490":23551,"34491":26790,"34492":22842,"34493":22849,"34494":22954,"34495":23454,"34496":23517,"34497":23545,"34498":23649,"34499":23853,"34500":23702,"34501":24065,"34502":24124,"34503":24443,"34504":24577,"34505":24815,"34506":24696,"34507":24813,"34508":24808,"34509":25602,"34510":25524,"34511":25530,"34512":30021,"34513":33635,"34514":26538,"34515":28378,"34516":28173,"34517":27721,"34518":28385,"34519":28382,"34520":28176,"34521":28072,"34522":28063,"34523":27818,"34524":28180,"34525":28183,"34526":28068,"34527":33639,"34528":23572,"34529":33638,"34530":29425,"34531":29712,"34532":29595,"34533":30111,"34534":30113,"34535":30127,"34536":30186,"34537":23613,"34538":30417,"34539":30805,"34540":31087,"34541":31096,"34542":31181,"34543":31216,"34544":27964,"34545":31389,"34546":31546,"34547":31581,"34548":32509,"34549":32510,"34550":32508,"34551":32496,"34552":32491,"34553":32511,"34554":32039,"34555":32512,"34556":32434,"34557":32494,"34558":32504,"34624":32501,"34625":32438,"34626":32500,"34627":32490,"34628":32513,"34629":32502,"34630":32602,"34631":38395,"34632":33669,"34633":30422,"34634":33642,"34635":33485,"34636":34432,"34637":35829,"34638":35821,"34639":35820,"34640":35748,"34641":35819,"34642":35823,"34643":35828,"34644":35824,"34645":35826,"34646":35825,"34647":35827,"34648":35822,"34649":23486,"34650":36168,"34651":36170,"34652":36213,"34653":36214,"34654":36741,"34655":36740,"34656":36731,"34657":36828,"34658":36874,"34659":36882,"34660":38128,"34661":38134,"34662":38108,"34663":38125,"34664":38114,"34665":38124,"34666":38120,"34667":38133,"34668":38115,"34669":38402,"34670":38394,"34671":38397,"34672":38401,"34673":38400,"34674":38469,"34675":39047,"34676":39046,"34677":39122,"34678":39290,"34679":39292,"34680":39285,"34681":39287,"34682":39539,"34683":32942,"34684":39600,"34685":40483,"34686":40482,"34721":20964,"34722":40784,"34723":20159,"34724":20202,"34725":20215,"34726":20396,"34727":20393,"34728":20461,"34729":21095,"34730":21016,"34731":21073,"34732":21053,"34733":21385,"34734":21792,"34735":22068,"34736":21719,"34737":22040,"34738":21943,"34739":21880,"34740":21501,"34741":22687,"34742":22367,"34743":22368,"34744":22549,"34745":23092,"34746":23157,"34747":22953,"34748":23047,"34749":23046,"34750":23485,"34751":23457,"34752":20889,"34753":23618,"34754":23956,"34755":24092,"34756":24223,"34757":21416,"34758":24217,"34759":21422,"34760":24191,"34761":24377,"34762":24198,"34763":34385,"34764":24551,"34765":24578,"34766":24751,"34767":24814,"34768":24868,"34769":24579,"34770":25370,"34771":25169,"34772":25438,"34773":25320,"34774":25376,"34775":25242,"34776":25528,"34777":25599,"34778":25932,"34779":25968,"34780":26242,"34781":26165,"34782":26679,"34783":26729,"34784":26530,"34785":26631,"34786":27004,"34787":26728,"34788":20048,"34789":26526,"34790":27431,"34791":27527,"34792":27572,"34793":27974,"34794":27900,"34795":27905,"34796":27975,"34797":28291,"34798":28070,"34799":28071,"34800":27988,"34801":28909,"34802":22870,"34803":33721,"34804":30126,"34805":30353,"34806":30385,"34807":30424,"34808":30830,"34809":30721,"34810":31377,"34811":31351,"34812":32532,"34813":32451,"34814":32428,"34880":32516,"34881":32517,"34882":32521,"34883":32534,"34884":32536,"34885":32447,"34886":32526,"34887":32531,"34888":32525,"34889":32514,"34890":32520,"34891":32519,"34892":39554,"34893":32610,"34894":33014,"34895":32932,"34896":33714,"34897":33643,"34898":33931,"34899":34430,"34900":34583,"34901":21355,"34902":35850,"34903":35845,"34904":35848,"34905":35846,"34906":35806,"34907":35831,"34908":35832,"34909":35838,"34910":35839,"34911":35844,"34912":35843,"34913":35841,"34914":35770,"34915":35812,"34916":35847,"34917":35837,"34918":35840,"34919":31446,"34920":36180,"34921":36175,"34922":36171,"34923":36145,"34924":36134,"34925":36172,"34926":36132,"34927":21334,"34928":36176,"34929":36136,"34930":36179,"34931":36341,"34932":36745,"34933":36742,"34934":36749,"34935":36744,"34936":36743,"34937":36718,"34938":36750,"34939":36747,"34940":36746,"34941":36866,"34942":36801,"34977":37051,"34978":37073,"34979":37011,"34980":38156,"34981":38161,"34982":38144,"34983":38138,"34984":38096,"34985":38148,"34986":38109,"34987":38160,"34988":38153,"34989":38155,"34990":38049,"34991":38146,"34992":38398,"34993":38405,"34994":24041,"34995":39049,"34996":39052,"34997":20859,"34998":39295,"34999":39297,"35000":39548,"35001":39547,"35002":39543,"35003":39542,"35004":39549,"35005":39550,"35006":39545,"35007":39544,"35008":39607,"35009":38393,"35010":40063,"35011":40065,"35012":40489,"35013":40486,"35014":40632,"35015":40831,"35016":20454,"35017":20647,"35018":20394,"35019":24130,"35020":21058,"35021":21544,"35022":21725,"35023":22003,"35024":22438,"35025":22363,"35026":22859,"35027":34949,"35028":23398,"35029":23548,"35030":23466,"35031":20973,"35032":24811,"35033":25044,"35034":24518,"35035":25112,"35036":25317,"35037":25377,"35038":25374,"35039":25454,"35040":25523,"35041":25321,"35042":25441,"35043":25285,"35044":25373,"35045":21382,"35046":26195,"35047":26196,"35048":26137,"35049":26726,"35050":27178,"35051":26641,"35052":26925,"35053":26725,"35054":26426,"35055":26721,"35056":28096,"35057":27987,"35058":27901,"35059":27978,"35060":27811,"35061":28582,"35062":28177,"35063":28861,"35064":28903,"35065":28783,"35066":28907,"35067":28950,"35068":29420,"35069":29585,"35070":29935,"35136":30232,"35137":21346,"35138":30610,"35139":30742,"35140":30875,"35141":31215,"35142":39062,"35143":31267,"35144":31397,"35145":31491,"35146":31579,"35147":32546,"35148":32547,"35149":33830,"35150":32538,"35151":21439,"35152":32543,"35153":32540,"35154":32537,"35155":32457,"35156":33147,"35157":20852,"35158":33329,"35159":33633,"35160":33831,"35161":33436,"35162":34434,"35163":33828,"35164":35044,"35165":20146,"35166":35278,"35167":35867,"35168":35866,"35169":35855,"35170":35763,"35171":35851,"35172":35853,"35173":35856,"35174":35864,"35175":35834,"35176":35858,"35177":35859,"35178":35773,"35179":35861,"35180":35865,"35181":35852,"35182":35862,"35183":36182,"35184":36752,"35185":36753,"35186":36755,"35187":36751,"35188":21150,"35189":36873,"35190":36831,"35191":36797,"35192":36951,"35193":37050,"35194":38189,"35195":38191,"35196":38192,"35197":38169,"35198":38065,"35233":38050,"35234":38177,"35235":24405,"35236":38126,"35237":38181,"35238":38182,"35239":38175,"35240":38178,"35241":38193,"35242":38414,"35243":38543,"35244":38505,"35245":38745,"35246":33148,"35247":39050,"35248":39048,"35249":39057,"35250":39060,"35251":22836,"35252":39059,"35253":39056,"35254":39302,"35255":39279,"35256":39300,"35257":39301,"35258":39559,"35259":39560,"35260":39558,"35261":39608,"35262":39612,"35263":40077,"35264":40501,"35265":40490,"35266":40495,"35267":40493,"35268":40499,"35269":40857,"35270":40863,"35271":20248,"35272":20607,"35273":20648,"35274":21169,"35275":21659,"35276":21523,"35277":21387,"35278":22489,"35279":23156,"35280":23252,"35281":23351,"35282":23604,"35283":23654,"35284":23679,"35285":23896,"35286":24110,"35287":24357,"35288":24212,"35289":24691,"35290":25103,"35291":20987,"35292":25380,"35293":25319,"35294":25311,"35295":25601,"35296":25947,"35297":27609,"35298":26279,"35299":26723,"35300":26816,"35301":26727,"35302":26633,"35303":27183,"35304":27539,"35305":27617,"35306":27870,"35307":28392,"35308":27982,"35309":28059,"35310":28389,"35311":28073,"35312":28493,"35313":33829,"35314":28799,"35315":28891,"35316":28905,"35317":22681,"35318":29406,"35319":33719,"35320":29615,"35321":29815,"35322":30184,"35323":30103,"35324":30699,"35325":30970,"35326":30710,"35392":31699,"35393":31914,"35394":38214,"35395":31937,"35396":32553,"35397":32489,"35398":32554,"35399":32533,"35400":32551,"35401":32503,"35402":32541,"35403":24635,"35404":32437,"35405":32555,"35406":32420,"35407":32549,"35408":32358,"35409":32550,"35410":22768,"35411":32874,"35412":32852,"35413":32824,"35414":33043,"35415":32966,"35416":33080,"35417":33037,"35418":20020,"35419":20030,"35420":33392,"35421":34103,"35422":34015,"35423":20111,"35424":34684,"35425":34632,"35426":20149,"35427":35099,"35428":35274,"35429":35868,"35430":35876,"35431":35878,"35432":35762,"35433":35854,"35434":35875,"35435":35874,"35436":35466,"35437":35879,"35438":36186,"35439":36187,"35440":36141,"35441":36185,"35442":36235,"35443":36758,"35444":36759,"35445":27586,"35446":36757,"35447":33286,"35448":36824,"35449":36808,"35450":37213,"35451":38208,"35452":38209,"35453":38170,"35454":38190,"35489":38194,"35490":38149,"35491":38180,"35492":38202,"35493":38201,"35494":38203,"35495":38206,"35496":38199,"35497":38420,"35498":38421,"35499":38417,"35500":38385,"35501":38544,"35502":38582,"35503":34429,"35504":38889,"35505":39063,"35506":39123,"35507":39563,"35508":39567,"35509":40092,"35510":40091,"35511":40084,"35512":40081,"35513":40511,"35514":40509,"35515":28857,"35516":25995,"35517":19995,"35518":22108,"35519":22329,"35520":22418,"35521":23158,"35522":25041,"35523":25193,"35524":25527,"35525":25200,"35526":25781,"35527":25670,"35528":25822,"35529":25783,"35530":26029,"35531":27103,"35532":26588,"35533":27099,"35534":26592,"35535":27428,"35536":24402,"35537":27553,"35538":27899,"35539":28182,"35540":28388,"35541":28174,"35542":28293,"35543":27983,"35544":28908,"35545":28952,"35546":29367,"35547":29454,"35548":29934,"35549":30112,"35550":30545,"35551":30784,"35552":31036,"35553":31313,"35554":31229,"35555":31388,"35556":31373,"35557":31659,"35558":31783,"35559":31658,"35560":31697,"35561":31616,"35562":31918,"35563":32455,"35564":32558,"35565":32469,"35566":32557,"35567":32483,"35568":32559,"35569":32728,"35570":32844,"35571":32834,"35572":33040,"35573":33169,"35574":26087,"35575":33832,"35576":34013,"35577":33632,"35578":34546,"35579":34633,"35580":35280,"35581":35294,"35582":35871,"35648":35880,"35649":35884,"35650":35882,"35651":36184,"35652":36434,"35653":36857,"35654":36344,"35655":36527,"35656":36716,"35657":36761,"35658":36841,"35659":21307,"35660":37233,"35661":38225,"35662":38145,"35663":38056,"35664":38221,"35665":38215,"35666":38224,"35667":38226,"35668":38217,"35669":38422,"35670":38383,"35671":38423,"35672":38425,"35673":26434,"35674":21452,"35675":38607,"35676":40481,"35677":39069,"35678":39068,"35679":39064,"35680":39066,"35681":39067,"35682":39311,"35683":39306,"35684":39304,"35685":39569,"35686":39617,"35687":40104,"35688":40100,"35689":40107,"35690":40103,"35691":40515,"35692":40517,"35693":40516,"35694":22404,"35695":22364,"35696":23456,"35697":24222,"35698":24208,"35699":24809,"35700":24576,"35701":25042,"35702":25314,"35703":26103,"35704":27249,"35705":26911,"35706":27016,"35707":27257,"35708":28487,"35709":28625,"35710":27813,"35745":28626,"35746":27896,"35747":28865,"35748":29261,"35749":29322,"35750":20861,"35751":29549,"35752":29626,"35753":29756,"35754":30068,"35755":30250,"35756":30861,"35757":31095,"35758":31283,"35759":31614,"35760":33575,"35761":32462,"35762":32499,"35763":32472,"35764":32599,"35765":32564,"35766":33211,"35767":33402,"35768":34222,"35769":33647,"35770":34433,"35771":34631,"35772":35014,"35773":34948,"35774":35889,"35775":35782,"35776":35885,"35777":35890,"35778":35749,"35779":35887,"35780":36192,"35781":36190,"35782":36343,"35783":36762,"35784":36735,"35785":36766,"35786":36793,"35787":38236,"35788":38237,"35789":38238,"35790":38142,"35791":38231,"35792":38232,"35793":38230,"35794":38233,"35795":38197,"35796":38210,"35797":38143,"35798":37694,"35799":20851,"35800":38471,"35801":38590,"35802":38654,"35803":38892,"35804":38901,"35805":31867,"35806":39072,"35807":39125,"35808":39314,"35809":39313,"35810":39579,"35811":39575,"35812":40120,"35813":40115,"35814":40109,"35815":40119,"35816":40529,"35817":40521,"35818":40522,"35819":40524,"35820":40527,"35821":20029,"35822":40628,"35823":21149,"35824":21657,"35825":22052,"35826":20005,"35827":23453,"35828":24748,"35829":24527,"35830":25318,"35831":25600,"35832":32999,"35833":27015,"35834":28572,"35835":28491,"35836":28809,"35837":29649,"35838":30719,"35904":30778,"35905":30718,"35906":30782,"35907":31398,"35908":31454,"35909":31609,"35910":31726,"35911":36779,"35912":32548,"35913":32487,"35914":32578,"35915":33002,"35916":33328,"35917":34108,"35918":34106,"35919":33446,"35920":33529,"35921":34164,"35922":34461,"35923":35124,"35924":35273,"35925":35302,"35926":35758,"35927":35793,"35928":35893,"35929":36194,"35930":36193,"35931":36280,"35932":37322,"35933":38047,"35934":38105,"35935":38152,"35936":38416,"35937":39128,"35938":39286,"35939":39269,"35940":39582,"35941":33150,"35942":39578,"35943":40131,"35944":40133,"35945":20826,"35946":40835,"35947":40836,"35948":20458,"35949":21995,"35950":21869,"35951":22179,"35952":23646,"35953":24807,"35954":24913,"35955":25668,"35956":25658,"35957":26003,"35958":27185,"35959":26639,"35960":26818,"35961":27516,"35962":28866,"35963":29306,"35964":38262,"35965":29838,"35966":30302,"36001":32544,"36002":32493,"36003":20848,"36004":34259,"36005":34510,"36006":35272,"36007":35892,"36008":25252,"36009":35465,"36010":36163,"36011":36364,"36012":36291,"36013":36347,"36014":36720,"36015":36777,"36016":38256,"36017":38253,"36018":38081,"36019":38107,"36020":38094,"36021":38255,"36022":38220,"36023":21709,"36024":39038,"36025":39074,"36026":39144,"36027":39537,"36028":39584,"36029":34022,"36030":39585,"36031":39621,"36032":40141,"36033":40143,"36034":33722,"36035":40548,"36036":40542,"36037":40839,"36038":40840,"36039":21870,"36040":20456,"36041":20645,"36042":21587,"36043":23402,"36044":24005,"36045":23782,"36046":24367,"36047":25674,"36048":26435,"36049":27426,"36050":28393,"36051":29473,"36052":21472,"36053":30270,"36054":30307,"36055":31548,"36056":31809,"36057":32843,"36058":33039,"36059":34989,"36060":34924,"36061":35835,"36062":36174,"36063":36189,"36064":36399,"36065":36396,"36066":36756,"36067":37094,"36068":38136,"36069":37492,"36070":38657,"36071":38801,"36072":32366,"36073":39076,"36074":39556,"36075":39553,"36076":40150,"36077":40098,"36078":40148,"36079":40151,"36080":40551,"36081":40485,"36082":40761,"36083":40841,"36084":40842,"36085":40858,"36086":24651,"36087":25371,"36088":25605,"36089":29906,"36090":31363,"36091":32552,"36092":33250,"36093":33821,"36094":34506,"36160":21464,"36161":36902,"36162":36923,"36163":38259,"36164":38084,"36165":38757,"36166":26174,"36167":39181,"36168":24778,"36169":39551,"36170":39564,"36171":39635,"36172":39633,"36173":40157,"36174":40158,"36175":40156,"36176":40502,"36177":22065,"36178":22365,"36179":25597,"36180":30251,"36181":30315,"36182":32641,"36183":34453,"36184":35753,"36185":35863,"36186":35894,"36187":33395,"36188":36195,"36189":37247,"36190":38643,"36191":28789,"36192":38701,"36193":39078,"36194":39588,"36195":39699,"36196":39751,"36197":40078,"36198":40560,"36199":40557,"36200":30839,"36201":30416,"36202":40140,"36203":40844,"36204":40843,"36205":21381,"36206":27012,"36207":28286,"36208":31729,"36209":31657,"36210":34542,"36211":35266,"36212":36433,"36213":34885,"36214":38053,"36215":39045,"36216":39307,"36217":39627,"36218":40649,"36219":28390,"36220":30633,"36221":38218,"36222":38831,"36257":39540,"36258":39589,"36259":32518,"36260":35872,"36261":36495,"36262":37245,"36263":38075,"36264":37550,"36265":38179,"36266":40132,"36267":40072,"36268":40681,"36269":20991,"36270":40550,"36271":39562,"36272":40563,"36273":40510,"36274":38074,"36275":20162,"36276":34381,"36277":27538,"36278":22439,"36279":22395,"36280":25099,"36281":20451,"36282":21037,"36283":21389,"36284":21593,"36285":21370,"36286":32424,"36287":33543,"36288":38023,"36289":38022,"36290":21591,"36291":24362,"36292":31059,"36293":32446,"36294":37071,"36295":38028,"36296":21072,"36297":21286,"36298":22261,"36299":22445,"36300":23045,"36301":23741,"36302":23811,"36303":28062,"36304":28172,"36305":28867,"36306":30502,"36307":32448,"36308":32464,"36309":33003,"36310":38030,"36311":38032,"36312":38037,"36313":38029,"36314":38379,"36315":22955,"36316":23899,"36317":24701,"36318":26720,"36319":26536,"36320":27817,"36321":27976,"36322":30066,"36323":30743,"36324":32471,"36325":33757,"36326":35271,"36327":35765,"36328":35790,"36329":35794,"36330":36150,"36331":36147,"36332":36730,"36333":36725,"36334":36728,"36335":36911,"36336":37075,"36337":37124,"36338":38059,"36339":38060,"36340":38043,"36341":38063,"36342":38061,"36343":38058,"36344":38390,"36345":38503,"36346":39032,"36347":39275,"36348":40697,"36349":20251,"36350":20603,"36416":20325,"36417":21794,"36418":22450,"36419":24047,"36420":24493,"36421":28828,"36422":33557,"36423":29426,"36424":29614,"36425":32488,"36426":32480,"36427":32481,"36428":32671,"36429":33645,"36430":34545,"36431":35795,"36432":35798,"36433":35817,"36434":35796,"36435":35804,"36436":36241,"36437":36738,"36438":36737,"36439":37036,"36440":38090,"36441":38088,"36442":38064,"36443":38066,"36444":38070,"36445":38157,"36446":38092,"36447":38077,"36448":38076,"36449":39043,"36450":39040,"36451":20971,"36452":40702,"36453":20606,"36454":21787,"36455":23901,"36456":24123,"36457":24747,"36458":24749,"36459":24580,"36460":25132,"36461":25111,"36462":25247,"36463":25248,"36464":25532,"36465":26724,"36466":26473,"36467":33637,"36468":27986,"36469":27812,"36470":28829,"36471":30386,"36472":30720,"36473":32507,"36474":32498,"36475":32495,"36476":32506,"36477":33715,"36478":35275,"36513":35830,"36514":36167,"36515":38129,"36516":38098,"36517":38097,"36518":38101,"36519":38111,"36520":38123,"36521":38127,"36522":38122,"36523":38135,"36524":38102,"36525":38117,"36526":39121,"36527":21055,"36528":21154,"36529":21715,"36530":21586,"36531":23810,"36532":23780,"36533":24209,"36534":24870,"36535":25378,"36536":26912,"36537":27637,"36538":39053,"36539":28061,"36540":28514,"36541":28064,"36542":28375,"36543":29711,"36544":29825,"36545":30231,"36546":32515,"36547":32535,"36548":32524,"36549":32527,"36550":32529,"36551":33628,"36552":33932,"36553":33553,"36554":33473,"36555":35833,"36556":35836,"36557":35842,"36558":36181,"36559":37112,"36560":38162,"36561":38103,"36562":38141,"36563":38163,"36564":38154,"36565":38116,"36566":38150,"36567":38151,"36568":38164,"36569":38406,"36570":38403,"36571":38739,"36572":39055,"36573":39293,"36574":39541,"36575":39552,"36576":40066,"36577":40488,"36578":21714,"36579":21717,"36580":21721,"36581":23250,"36582":23748,"36583":24639,"36584":27546,"36585":27981,"36586":28904,"36587":29443,"36588":29423,"36589":30876,"36590":31405,"36591":32279,"36592":32539,"36593":33927,"36594":33640,"36595":33929,"36596":33630,"36597":33720,"36598":33431,"36599":34547,"36600":35816,"36601":35857,"36602":35860,"36603":35869,"36604":37072,"36605":38185,"36606":38188,"36672":38166,"36673":38167,"36674":38140,"36675":38171,"36676":38165,"36677":38174,"36678":38036,"36679":38415,"36680":38408,"36681":38409,"36682":38410,"36683":38412,"36684":38413,"36685":40498,"36686":40497,"36687":21724,"36688":24113,"36689":24697,"36690":25672,"36691":58305,"36692":27894,"36693":29461,"36694":29971,"36695":30213,"36696":30187,"36697":30807,"36698":31654,"36699":31578,"36700":31976,"36701":32545,"36702":32807,"36703":33631,"36704":33718,"36705":34544,"36706":35042,"36707":35279,"36708":35873,"36709":35788,"36710":35877,"36711":36292,"36712":38200,"36713":38196,"36714":38113,"36715":38198,"36716":38418,"36717":39271,"36718":40082,"36719":40085,"36720":40504,"36721":40505,"36722":40506,"36723":40832,"36724":24636,"36725":25669,"36726":25784,"36727":27898,"36728":30102,"36729":32523,"36730":32873,"36731":33641,"36732":34789,"36733":34414,"36734":35764,"36769":35881,"36770":36188,"36771":36157,"36772":36760,"36773":37021,"36774":38227,"36775":38112,"36776":38204,"36777":38223,"36778":34021,"36779":38890,"36780":39273,"36781":39568,"36782":39570,"36783":39571,"36784":38411,"36785":40105,"36786":40096,"36787":40520,"36788":40513,"36789":40518,"36790":21411,"36791":21590,"36792":22406,"36793":27104,"36794":26638,"36795":27655,"36796":27895,"36797":28486,"36798":31074,"36799":32562,"36800":32563,"36801":32628,"36802":33315,"36803":34511,"36804":34431,"36805":35043,"36806":35281,"36807":35311,"36808":35886,"36809":38235,"36810":38239,"36811":38250,"36812":38214,"36813":38121,"36814":38891,"36815":39073,"36816":39312,"36817":39618,"36818":40117,"36819":40118,"36820":40123,"36821":40113,"36822":40526,"36823":40491,"36824":40700,"36825":21950,"36826":25732,"36827":26634,"36828":26533,"36829":26636,"36830":32561,"36831":32845,"36832":33551,"36833":33480,"36834":34162,"36835":34548,"36836":34686,"36837":38132,"36838":38246,"36839":38248,"36840":38241,"36841":38243,"36842":38212,"36843":38251,"36844":38119,"36845":38244,"36846":38137,"36847":38426,"36848":39071,"36849":39316,"36850":39546,"36851":39581,"36852":39583,"36853":39576,"36854":40535,"36855":40538,"36856":40540,"36857":40838,"36858":40837,"36859":20649,"36860":23743,"36861":30152,"36862":25786,"36928":27017,"36929":28384,"36930":30779,"36931":31901,"36932":32425,"36933":32556,"36934":34105,"36935":36166,"36936":38257,"36937":38396,"36938":39129,"36939":39586,"36940":39574,"36941":39580,"36942":40101,"36943":40142,"36944":40144,"36945":40547,"36946":40536,"36947":40574,"36948":20865,"36949":23048,"36950":28757,"36951":25874,"36952":30271,"36953":31656,"36954":31860,"36955":33339,"36956":35276,"36957":36345,"36958":36318,"36959":36729,"36960":38228,"36961":38252,"36962":39587,"36963":39557,"36964":40149,"36965":40099,"36966":40102,"36967":40552,"36968":40503,"36969":40859,"36970":26686,"36971":26916,"36972":34016,"36973":38624,"36974":36723,"36975":40159,"36976":40095,"36977":40553,"36978":40556,"36979":40554,"36980":40555,"36981":40519,"36982":28751,"36983":31766,"36984":35888,"36985":39628,"36986":31550,"36987":31900,"36988":32565,"36989":33044,"36990":36479,"37025":38247,"37026":40090,"37027":36273,"37028":36508,"37029":37246,"37030":35891,"37031":39070,"37032":39079,"37033":39591,"37034":40492,"37035":25094,"37036":38404,"37037":40097,"37038":40514,"37039":31160,"37040":25300,"37041":36299,"37042":29648,"37043":23467,"37044":25296,"37045":27585,"37046":20943,"37047":31108,"37048":21525,"37049":28508,"37050":34972,"37051":37095,"37052":20857,"37053":25144,"37054":25243,"37055":25383,"37056":25531,"37057":25566,"37058":25594,"37059":25745,"37060":25792,"37061":25825,"37062":25846,"37063":25861,"37064":25909,"37065":25934,"37066":25963,"37067":25992,"37068":26073,"37069":26142,"37070":26171,"37071":26175,"37072":26180,"37073":26199,"37074":26217,"37075":26227,"37076":26243,"37077":26300,"37078":26303,"37079":26305,"37080":26357,"37081":26362,"37082":26363,"37083":26382,"37084":26390,"37085":26423,"37086":26468,"37087":26470,"37088":26534,"37089":26535,"37090":26537,"37091":26619,"37092":26621,"37093":26624,"37094":26625,"37095":26629,"37096":26654,"37097":26698,"37098":26706,"37099":26709,"37100":26713,"37101":26765,"37102":26809,"37103":26831,"37104":20616,"37105":38184,"37106":40087,"37107":26914,"37108":26918,"37109":220,"37110":58591,"37111":58592,"37112":252,"37113":58594,"37114":58595,"37115":220,"37116":252,"37117":26934,"37118":26977,"37184":33477,"37185":33482,"37186":33496,"37187":33560,"37188":33562,"37189":33571,"37190":33606,"37191":33627,"37192":33634,"37193":33644,"37194":33646,"37195":33692,"37196":33695,"37197":33717,"37198":33724,"37199":33783,"37200":33834,"37201":33864,"37202":33884,"37203":33890,"37204":33924,"37205":33928,"37206":34012,"37207":34019,"37208":34104,"37209":34138,"37210":34199,"37211":34219,"37212":34241,"37213":34323,"37214":34326,"37215":8715,"37216":34581,"37217":34672,"37218":34685,"37219":34699,"37220":34728,"37221":34759,"37222":34768,"37223":34823,"37224":34830,"37225":34855,"37226":34990,"37227":8712,"37228":34997,"37229":35007,"37230":35045,"37231":35061,"37232":35100,"37233":35101,"37234":35191,"37235":35303,"37236":35383,"37237":35500,"37238":35546,"37239":35675,"37240":35697,"37241":35883,"37242":35898,"37243":35964,"37244":35982,"37245":36014,"37246":36114,"37281":36169,"37282":36173,"37283":36209,"37284":36360,"37285":36410,"37286":36464,"37287":36505,"37288":36528,"37289":36529,"37290":36549,"37291":36550,"37292":36558,"37293":36579,"37294":36620,"37295":36721,"37296":36727,"37297":36775,"37298":36847,"37299":36878,"37300":36921,"37301":36965,"37302":37001,"37303":37086,"37304":37141,"37305":37334,"37306":37339,"37307":37342,"37308":37345,"37309":37349,"37310":37366,"37311":37372,"37312":37417,"37313":37420,"37314":65287,"37315":37465,"37316":37495,"37317":37613,"37318":37690,"37319":58701,"37320":58702,"37321":29227,"37322":20866,"37323":20886,"37324":20023,"37325":20843,"37326":20799,"37327":58709,"37328":58710,"37329":26409,"37330":27706,"37331":21378,"37332":30098,"37333":32896,"37334":34916,"37335":19974,"37336":58718,"37337":58719,"37338":58720,"37339":11927,"37340":21241,"37341":21269,"37342":8225,"37343":58725,"37344":13316,"37345":58727,"37346":58728,"37347":58729,"37348":58730,"37349":58731,"37350":20981,"37351":58733,"37352":23662,"37353":58735,"37354":22231,"37355":20128,"37356":20907,"37357":11904,"37358":27079,"37359":58741,"37360":9550,"37361":9688,"37362":9689,"37363":9794,"37364":9654,"37365":9668,"37366":8597,"37367":8252,"37368":182,"37369":8704,"37370":8616,"37371":8596,"37372":8962,"37373":58755,"37374":58756,"37440":20124,"37441":24746,"37442":22311,"37443":22258,"37444":21307,"37445":22769,"37446":36920,"37447":38560,"37448":26628,"37449":21942,"37450":39365,"37451":35585,"37452":20870,"37453":32257,"37454":24540,"37455":27431,"37456":27572,"37457":26716,"37458":22885,"37459":31311,"37460":20206,"37461":20385,"37462":30011,"37463":28784,"37464":20250,"37465":24724,"37466":28023,"37467":32117,"37468":22730,"37469":25040,"37470":25313,"37471":27579,"37472":35226,"37473":23398,"37474":27005,"37475":21917,"37476":28167,"37477":58794,"37478":24059,"37479":38501,"37480":21223,"37481":23515,"37482":28450,"37483":38306,"37484":27475,"37485":35251,"37486":27671,"37487":24112,"37488":25135,"37489":29344,"37490":34384,"37491":26087,"37492":24613,"37493":25312,"37494":25369,"37495":34394,"37496":23777,"37497":25375,"37498":29421,"37499":37111,"37500":38911,"37501":26241,"37502":21220,"37537":35641,"37538":21306,"37539":39366,"37540":21234,"37541":58824,"37542":24452,"37543":33550,"37544":24693,"37545":25522,"37546":28179,"37547":32076,"37548":34509,"37549":36605,"37550":32153,"37551":40335,"37552":25731,"37553":30476,"37554":20537,"37555":21091,"37556":38522,"37557":22287,"37558":26908,"37559":27177,"37560":38997,"37561":39443,"37562":21427,"37563":21577,"37564":23087,"37565":35492,"37566":24195,"37567":28207,"37568":37489,"37569":21495,"37570":22269,"37571":40658,"37572":31296,"37573":30741,"37574":28168,"37575":25998,"37576":27507,"37577":21092,"37578":38609,"37579":21442,"37580":26719,"37581":24808,"37582":36059,"37583":27531,"37584":27503,"37585":20816,"37586":36766,"37587":28287,"37588":23455,"37589":20889,"37590":33294,"37591":25448,"37592":37320,"37593":23551,"37594":21454,"37595":34886,"37596":24467,"37597":28171,"37598":29539,"37599":32294,"37600":31899,"37601":20966,"37602":23558,"37603":31216,"37604":28169,"37605":28988,"37606":22888,"37607":26465,"37608":29366,"37609":20055,"37610":27972,"37611":21104,"37612":30067,"37613":32260,"37614":22732,"37615":23330,"37616":35698,"37617":37304,"37618":35302,"37619":22065,"37620":23517,"37621":23613,"37622":22259,"37623":31883,"37624":37204,"37625":31298,"37626":38543,"37627":39620,"37628":26530,"37629":25968,"37630":25454,"37696":28716,"37697":22768,"37698":25993,"37699":38745,"37700":31363,"37701":25666,"37702":32118,"37703":23554,"37704":27973,"37705":25126,"37706":36341,"37707":37549,"37708":28508,"37709":36983,"37710":36984,"37711":32330,"37712":31109,"37713":30094,"37714":22766,"37715":20105,"37716":33624,"37717":25436,"37718":25407,"37719":24035,"37720":31379,"37721":35013,"37722":20711,"37723":23652,"37724":32207,"37725":39442,"37726":22679,"37727":24974,"37728":34101,"37729":36104,"37730":33235,"37731":23646,"37732":32154,"37733":22549,"37734":23550,"37735":24111,"37736":28382,"37737":28381,"37738":25246,"37739":27810,"37740":28655,"37741":21336,"37742":22022,"37743":22243,"37744":26029,"37745":24382,"37746":36933,"37747":26172,"37748":37619,"37749":24193,"37750":24500,"37751":32884,"37752":25074,"37753":22618,"37754":36883,"37755":37444,"37756":28857,"37757":36578,"37758":20253,"37793":38651,"37794":28783,"37795":24403,"37796":20826,"37797":30423,"37798":31282,"37799":38360,"37800":24499,"37801":27602,"37802":29420,"37803":35501,"37804":23626,"37805":38627,"37806":24336,"37807":24745,"37808":33075,"37809":25309,"37810":24259,"37811":22770,"37812":26757,"37813":21338,"37814":34180,"37815":40614,"37816":32283,"37817":30330,"37818":39658,"37819":25244,"37820":27996,"37821":27996,"37822":25935,"37823":25975,"37824":20398,"37825":25173,"37826":20175,"37827":36794,"37828":22793,"37829":27497,"37830":33303,"37831":31807,"37832":21253,"37833":23453,"37834":25265,"37835":27873,"37836":32990,"37837":30770,"37838":35914,"37839":39165,"37840":22696,"37841":27598,"37842":28288,"37843":33032,"37844":40665,"37845":35379,"37846":34220,"37847":36493,"37848":19982,"37849":35465,"37850":25671,"37851":27096,"37852":35617,"37853":26332,"37854":26469,"37855":38972,"37856":20081,"37857":35239,"37858":31452,"37859":38534,"37860":26053,"37861":20001,"37862":29471,"37863":32209,"37864":28057,"37865":22593,"37866":31036,"37867":21169,"37868":25147,"37869":38666,"37870":40802,"37871":26278,"37872":27508,"37873":24651,"37874":32244,"37875":37676,"37876":28809,"37877":21172,"37878":27004,"37879":37682,"37880":28286,"37881":24357,"37882":20096,"37883":26365,"37884":22985,"37885":23437,"37886":23947,"37952":27179,"37953":26907,"37954":21936,"37955":31874,"37956":36796,"37957":27018,"37958":21682,"37959":40235,"37960":38635,"37961":26905,"37962":25539,"37963":39364,"37964":20967,"37965":26626,"37966":36795,"37967":20685,"37968":23776,"37969":26627,"37970":20970,"37971":21250,"37972":30834,"37973":30033,"37974":30048,"37975":22138,"37976":37618,"37977":22592,"37978":26622,"37979":20451,"37980":26466,"37981":31870,"37982":21249,"37983":20452,"37984":20453,"37985":20969,"37986":21498,"37987":21720,"37988":22222,"37989":22310,"37990":22327,"37991":22328,"37992":22408,"37993":22451,"37994":22442,"37995":22448,"37996":22486,"37997":22640,"37998":22713,"37999":22743,"38000":23670,"38001":23740,"38002":23749,"38003":23742,"38004":23926,"38005":24342,"38006":24634,"38007":25525,"38008":26433,"38009":26467,"38010":26529,"38011":26810,"38012":26917,"38013":26920,"38014":27258,"38049":26915,"38050":26913,"38051":27006,"38052":27009,"38053":27101,"38054":27182,"38055":27250,"38056":27423,"38057":27615,"38058":28181,"38059":29077,"38060":29927,"38061":29938,"38062":29936,"38063":29937,"38064":29944,"38065":29957,"38066":30057,"38067":30314,"38068":30836,"38069":31437,"38070":31439,"38071":31445,"38072":31443,"38073":31457,"38074":31472,"38075":31490,"38076":31763,"38077":31767,"38078":31888,"38079":31917,"38080":31936,"38081":31960,"38082":32155,"38083":32261,"38084":32359,"38085":32387,"38086":32400,"38087":33188,"38088":33373,"38089":33826,"38090":34009,"38091":34352,"38092":34475,"38093":34543,"38094":34992,"38095":35011,"38096":35012,"38097":35076,"38098":59183,"38099":36542,"38100":36552,"38101":36684,"38102":36791,"38103":36826,"38104":36903,"38105":36950,"38106":37685,"38107":37691,"38108":37817,"38109":38282,"38110":38294,"38111":38777,"38112":38790,"38113":38800,"38114":39082,"38115":39830,"38116":39831,"38117":39860,"38118":39887,"38119":39889,"38120":39890,"38121":39922,"38122":39921,"38123":39984,"38124":40007,"38125":40026,"38126":40176,"38127":40262,"38128":40292,"38129":40363,"38130":20036,"38131":21583,"38132":25368,"38133":39857,"38134":40041,"38135":40263,"38136":40293,"38137":39983,"38138":40639,"38139":20916,"38140":21610,"38141":26528,"38142":39822,"38208":37032,"38209":20914,"38210":13869,"38211":25285,"38212":21189,"38213":26545,"38214":21709,"38215":24658,"38216":21441,"38217":28913,"38218":22531,"38219":21855,"38220":37390,"38221":30528,"38222":29756,"38223":29002,"38224":28377,"38225":21472,"38226":29486,"38227":35023,"38228":30861,"38229":32675,"38230":32171,"38231":36394,"38232":37979,"38233":25452,"38234":24487,"38235":23557,"38236":32827,"38237":23791,"38238":14776,"38239":29009,"38240":36045,"38241":38894,"38242":22642,"38243":23139,"38244":32632,"38245":23895,"38246":24943,"38247":27032,"38248":32137,"38249":31918,"38250":32179,"38251":28545,"38252":23290,"38253":22715,"38254":29269,"38255":30286,"38256":36653,"38257":37561,"38258":40286,"38259":40623,"38260":32583,"38261":40388,"38262":36120,"38263":20915,"38264":34412,"38265":21668,"38266":21414,"38267":21030,"38268":26422,"38269":20001,"38270":21364,"38305":24313,"38306":21177,"38307":21647,"38308":24312,"38309":22956,"38310":24625,"38311":29248,"38312":33047,"38313":30267,"38314":24333,"38315":26187,"38316":26280,"38317":24932,"38318":25423,"38319":28895,"38320":27940,"38321":31911,"38322":31945,"38323":21465,"38324":25933,"38325":22338,"38326":29647,"38327":32966,"38328":13649,"38329":27445,"38330":30849,"38331":21452,"38332":29483,"38333":29482,"38334":29641,"38335":30026,"38336":23033,"38337":29124,"38338":29966,"38339":32220,"38340":39393,"38341":35241,"38342":28662,"38343":14935,"38344":25834,"38345":15341,"38346":27809,"38347":28284,"38348":30055,"38349":22633,"38350":22633,"38351":20996,"38352":59338,"38353":24967,"38354":25658,"38355":33263,"38356":59342,"38357":20917,"38358":20945,"38359":27769,"38360":22815,"38361":36857,"38362":39153,"38363":25911,"38364":33033,"38365":34996,"38366":14890,"38367":36525,"38368":32663,"38369":39440,"38370":32037,"38371":27336,"38372":20876,"38373":21031,"38374":59360,"38375":33050,"38376":21408,"38377":21410,"38378":27738,"38379":27703,"38380":33304,"38381":21894,"38382":24315,"38383":20937,"38384":30897,"38385":37474,"38386":21357,"38387":20931,"38388":59374,"38389":33905,"38390":35207,"38391":38765,"38392":35728,"38393":38563,"38394":24316,"38395":38583,"38396":20814,"38397":39952,"38398":26160,"38464":37461,"38465":30728,"38466":37701,"38467":37491,"38468":37737,"38469":59390,"38470":59391,"38471":59392,"38472":59393,"38473":37343,"38474":37338,"38475":30804,"38476":30822,"38477":30856,"38478":30902,"38479":30919,"38480":30930,"38481":30935,"38482":8491,"38483":8651,"38484":30948,"38485":30958,"38486":30960,"38487":30961,"38488":30965,"38489":31026,"38490":31027,"38491":31030,"38492":31064,"38493":12307,"38494":31065,"38495":31089,"38496":31102,"38497":31107,"38498":31110,"38499":31111,"38500":31121,"38501":31129,"38502":31135,"38503":31141,"38504":31202,"38505":31217,"38506":31220,"38507":31274,"38508":31290,"38509":31301,"38510":31333,"38511":31420,"38512":31426,"38513":31433,"38514":31451,"38515":31465,"38516":31486,"38517":31500,"38518":31527,"38519":31529,"38520":31554,"38521":31555,"38522":31573,"38523":31599,"38524":31666,"38525":27102,"38526":27129,"38561":37238,"38562":33114,"38563":33527,"38564":21579,"38565":33074,"38566":32957,"38567":33816,"38568":37214,"38569":37232,"38570":37260,"38571":33096,"38572":59459,"38573":17462,"38574":33113,"38575":32927,"38576":59463,"38577":21833,"38578":21537,"38579":21722,"38580":21554,"38581":21945,"38582":21652,"38583":59470,"38584":30802,"38585":30789,"38586":30796,"38587":59474,"38588":33981,"38589":33820,"38590":33476,"38591":59478,"38592":33915,"38593":35629,"38594":59481,"38595":22347,"38596":59483,"38597":59484,"38598":22341,"38599":34766,"38600":22112,"38601":21994,"38602":22139,"38603":32956,"38604":59491,"38605":30904,"38606":27148,"38607":21708,"38608":31696,"38609":31724,"38610":31738,"38611":31765,"38612":31771,"38613":31797,"38614":31812,"38615":31853,"38616":31886,"38617":31928,"38618":31939,"38619":31974,"38620":31981,"38621":31987,"38622":31989,"38623":31993,"38624":59511,"38625":31996,"38626":32139,"38627":32151,"38628":32164,"38629":32168,"38630":32205,"38631":32208,"38632":32211,"38633":32229,"38634":32253,"38635":27154,"38636":27170,"38637":27184,"38638":27190,"38639":27237,"38640":59527,"38641":59528,"38642":59529,"38643":59530,"38644":59531,"38645":59532,"38646":59533,"38647":59534,"38648":27251,"38649":27256,"38650":59537,"38651":59538,"38652":27260,"38653":27305,"38654":27306,"38720":9450,"38721":9312,"38722":9313,"38723":9314,"38724":9315,"38725":9316,"38726":9317,"38727":9318,"38728":9319,"38729":9320,"38730":9321,"38731":9322,"38732":9323,"38733":9324,"38734":9325,"38735":9326,"38736":9327,"38737":9328,"38738":9329,"38739":9330,"38740":9331,"38741":37700,"38742":37805,"38743":37830,"38744":37861,"38745":37914,"38746":37921,"38747":37950,"38748":37953,"38749":37971,"38750":37978,"38751":38042,"38752":38071,"38753":38104,"38754":38110,"38755":38131,"38756":38147,"38757":38158,"38758":38159,"38759":38168,"38760":38173,"38761":38186,"38762":38187,"38763":38207,"38764":38213,"38765":38222,"38766":38242,"38767":38245,"38768":38249,"38769":38258,"38770":38279,"38771":38297,"38772":38304,"38773":38322,"38774":38502,"38775":38557,"38776":38575,"38777":38578,"38778":38707,"38779":38715,"38780":38733,"38781":38735,"38782":38737,"38817":38741,"38818":38756,"38819":38763,"38820":38769,"38821":38802,"38822":38834,"38823":38898,"38824":38973,"38825":38996,"38826":39077,"38827":39107,"38828":39130,"38829":39150,"38830":39197,"38831":39200,"38832":39267,"38833":39296,"38834":39303,"38835":39309,"38836":39315,"38837":39317,"38838":39356,"38839":39368,"38840":39410,"38841":39606,"38842":39641,"38843":39646,"38844":39695,"38845":39753,"38846":39794,"38847":39811,"38848":39839,"38849":39867,"38850":39907,"38851":39925,"38852":39936,"38853":39940,"38854":39963,"38855":9398,"38856":9399,"38857":9400,"38858":9401,"38859":9402,"38860":9403,"38861":9404,"38862":9405,"38863":9406,"38864":9407,"38865":9408,"38866":9409,"38867":9410,"38868":9411,"38869":9412,"38870":9413,"38871":9414,"38872":9415,"38873":9416,"38874":9417,"38875":9418,"38876":9419,"38877":9420,"38878":9421,"38879":9422,"38880":9423,"38881":9424,"38882":9425,"38883":9426,"38884":9427,"38885":9428,"38886":9429,"38887":9430,"38888":9431,"38889":9432,"38890":9433,"38891":9434,"38892":9435,"38893":9436,"38894":9437,"38895":9438,"38896":9439,"38897":9440,"38898":9441,"38899":9442,"38900":9443,"38901":9444,"38902":9445,"38903":9446,"38904":9447,"38905":9448,"38906":9449,"38907":174,"38908":8482,"38909":59697,"38910":59698,"38976":40054,"38977":10122,"38978":10123,"38979":10124,"38980":10125,"38981":10126,"38982":10127,"38983":10128,"38984":10129,"38985":10130,"38986":10131,"38987":40069,"38988":40070,"38989":40071,"38990":40075,"38991":40080,"38992":40094,"38993":40110,"38994":40112,"38995":40114,"38996":40116,"38997":40122,"38998":40124,"38999":40125,"39000":40134,"39001":40135,"39002":40138,"39003":40139,"39004":40147,"39005":40152,"39006":40153,"39007":40162,"39008":40171,"39009":40172,"39010":40234,"39011":40264,"39012":40272,"39013":40314,"39014":40390,"39015":40523,"39016":40533,"39017":40539,"39018":40561,"39019":40618,"39020":40637,"39021":40644,"39022":40674,"39023":40682,"39024":40712,"39025":40715,"39026":40717,"39027":40737,"39028":40772,"39029":40785,"39030":40861,"39031":64014,"39032":64015,"39033":64017,"39034":64019,"39035":64020,"39036":64024,"39037":64031,"39038":64032,"39073":64033,"39074":64035,"39075":64036,"39076":64039,"39077":64040,"39078":64041,"39079":19972,"39080":20015,"39081":20097,"39082":20103,"39083":20131,"39084":20151,"39085":20156,"39086":20216,"39087":20264,"39088":20265,"39089":20279,"39090":20290,"39091":20293,"39092":20299,"39093":20338,"39094":20386,"39095":20400,"39096":20413,"39097":20424,"39098":20428,"39099":20464,"39100":20466,"39101":20473,"39102":20483,"39103":20488,"39104":20532,"39105":20539,"39106":20568,"39107":20582,"39108":20609,"39109":20624,"39110":20668,"39111":20688,"39112":20703,"39113":20705,"39114":20732,"39115":20749,"39116":20779,"39117":20832,"39118":20910,"39119":20920,"39120":20946,"39121":20962,"39122":20997,"39123":21044,"39124":21052,"39125":21081,"39126":21096,"39127":21113,"39128":21156,"39129":21196,"39130":21287,"39131":21314,"39132":21341,"39133":21373,"39134":21374,"39135":21445,"39136":21456,"39137":21458,"39138":21502,"39139":21613,"39140":21637,"39141":21651,"39142":21662,"39143":21689,"39144":21731,"39145":21743,"39146":21773,"39147":21784,"39148":21797,"39149":21800,"39150":21803,"39151":21831,"39152":21881,"39153":21904,"39154":21940,"39155":21953,"39156":21975,"39157":21976,"39158":22011,"39159":20404,"39160":22049,"39161":8707,"39162":22098,"39163":59852,"39164":9787,"39165":59854,"39166":59855,"39232":22109,"39233":9332,"39234":9333,"39235":9334,"39236":9335,"39237":9336,"39238":9337,"39239":9338,"39240":9339,"39241":9340,"39242":9341,"39243":9342,"39244":9343,"39245":9344,"39246":9345,"39247":9346,"39248":9347,"39249":9348,"39250":9349,"39251":9350,"39252":9351,"39253":22113,"39254":22153,"39255":22155,"39256":22174,"39257":22177,"39258":22193,"39259":22201,"39260":22207,"39261":22230,"39262":22255,"39263":22293,"39264":22301,"39265":22322,"39266":22333,"39267":22335,"39268":22339,"39269":8660,"39270":22398,"39271":22410,"39272":22413,"39273":22416,"39274":22428,"39275":22459,"39276":22462,"39277":22468,"39278":22494,"39279":22526,"39280":22546,"39281":22562,"39282":22599,"39283":22620,"39284":22623,"39285":22643,"39286":22695,"39287":22698,"39288":22704,"39289":22709,"39290":22710,"39291":22731,"39292":22736,"39293":22752,"39294":22789,"39329":22801,"39330":22921,"39331":22932,"39332":22938,"39333":22943,"39334":22960,"39335":22968,"39336":22980,"39337":23023,"39338":23024,"39339":23032,"39340":23042,"39341":23051,"39342":23053,"39343":23058,"39344":23073,"39345":23076,"39346":23079,"39347":23082,"39348":23083,"39349":23084,"39350":23101,"39351":23109,"39352":23124,"39353":23129,"39354":23137,"39355":23144,"39356":23147,"39357":23150,"39358":23153,"39359":23161,"39360":23166,"39361":23169,"39362":23170,"39363":23174,"39364":23176,"39365":23185,"39366":23193,"39367":23200,"39368":23201,"39369":23211,"39370":23235,"39371":23246,"39372":23247,"39373":23251,"39374":23268,"39375":23280,"39376":23294,"39377":23309,"39378":23313,"39379":23317,"39380":23327,"39381":23339,"39382":23361,"39383":23364,"39384":23366,"39385":23370,"39386":23375,"39387":23400,"39388":23412,"39389":23414,"39390":23420,"39391":23426,"39392":23440,"39393":9372,"39394":9373,"39395":9374,"39396":9375,"39397":9376,"39398":9377,"39399":9378,"39400":9379,"39401":9380,"39402":9381,"39403":9382,"39404":9383,"39405":9384,"39406":9385,"39407":9386,"39408":9387,"39409":9388,"39410":9389,"39411":9390,"39412":9391,"39413":9392,"39414":9393,"39415":9394,"39416":9395,"39417":9396,"39418":9397,"39419":60009,"39420":12850,"39421":12849,"39422":27307,"39488":23446,"39489":9352,"39490":9353,"39491":9354,"39492":9355,"39493":9356,"39494":9357,"39495":9358,"39496":9359,"39497":9360,"39498":9361,"39499":9362,"39500":9363,"39501":9364,"39502":9365,"39503":9366,"39504":9367,"39505":9368,"39506":9369,"39507":9370,"39508":9371,"39509":23509,"39510":23511,"39511":23587,"39512":23685,"39513":23710,"39514":23746,"39515":23824,"39516":23852,"39517":23855,"39518":23880,"39519":23894,"39520":23920,"39521":23931,"39522":23941,"39523":23972,"39524":23979,"39525":23990,"39526":24001,"39527":24023,"39528":24073,"39529":24136,"39530":24210,"39531":24253,"39532":24334,"39533":24434,"39534":24497,"39535":24514,"39536":24539,"39537":24543,"39538":24611,"39539":24702,"39540":24791,"39541":24839,"39542":24844,"39543":24857,"39544":24866,"39545":24912,"39546":24928,"39547":24961,"39548":24981,"39549":25017,"39550":25024,"39585":25039,"39586":25043,"39587":25050,"39588":25232,"39589":25393,"39590":8835,"39591":25399,"39592":25465,"39593":25483,"39594":25537,"39595":25570,"39596":25574,"39597":25595,"39598":25598,"39599":25607,"39600":25650,"39601":25656,"39602":25659,"39603":25690,"39604":25713,"39605":25724,"39606":25741,"39607":25775,"39608":25780,"39609":25782,"39610":25821,"39611":25829,"39612":25866,"39613":25873,"39614":25887,"39615":25951,"39616":25965,"39617":25990,"39618":26037,"39619":26046,"39620":26065,"39621":26068,"39622":26083,"39623":26111,"39624":26136,"39625":26147,"39626":26211,"39627":26219,"39628":26237,"39629":26245,"39630":26258,"39631":26266,"39632":26276,"39633":26285,"39634":26291,"39635":26294,"39636":26317,"39637":26318,"39638":26370,"39639":26380,"39640":26393,"39641":26436,"39642":26475,"39643":26511,"39644":26532,"39645":26559,"39646":26582,"39647":26583,"39648":8834,"39649":26637,"39650":26640,"39651":26651,"39652":26678,"39653":26695,"39654":26710,"39655":26756,"39656":26760,"39657":26813,"39658":26819,"39659":26821,"39660":26882,"39661":26883,"39662":26889,"39663":26904,"39664":26947,"39665":26950,"39666":26980,"39667":26983,"39668":26994,"39669":27013,"39670":27039,"39671":27042,"39672":27089,"39673":27093,"39674":27094,"39675":39457,"39676":39462,"39677":39471,"39678":27329,"39744":22975,"39745":27105,"39746":27139,"39747":27162,"39748":27164,"39749":27180,"39750":27181,"39751":27187,"39752":27203,"39753":27205,"39754":27212,"39755":27219,"39756":27223,"39757":27235,"39758":27252,"39759":27266,"39760":27274,"39761":27279,"39762":27289,"39763":27303,"39764":27313,"39765":27317,"39766":27326,"39767":27337,"39768":27348,"39769":27352,"39770":27382,"39771":27479,"39772":27514,"39773":27612,"39774":27676,"39775":27697,"39776":27736,"39777":27758,"39778":27765,"39779":27775,"39780":27823,"39781":27851,"39782":27871,"39783":27903,"39784":27906,"39785":27909,"39786":27910,"39787":27942,"39788":27991,"39789":27995,"39790":28017,"39791":28033,"39792":28047,"39793":28069,"39794":28081,"39795":28158,"39796":28162,"39797":28164,"39798":28175,"39799":28184,"39800":28202,"39801":28240,"39802":28249,"39803":28314,"39804":28341,"39805":28344,"39806":28379,"39841":28410,"39842":28420,"39843":28427,"39844":28428,"39845":28438,"39846":28439,"39847":28468,"39848":28477,"39849":28502,"39850":28537,"39851":28554,"39852":28573,"39853":28575,"39854":28603,"39855":28606,"39856":28627,"39857":28633,"39858":28664,"39859":28675,"39860":28747,"39861":28749,"39862":28752,"39863":28756,"39864":28764,"39865":28775,"39866":28791,"39867":28793,"39868":28811,"39869":28815,"39870":28832,"39871":28835,"39872":28837,"39873":28838,"39874":28839,"39875":28868,"39876":28876,"39877":28880,"39878":28886,"39879":618,"39880":603,"39881":230,"39882":652,"39883":593,"39884":596,"39885":650,"39886":605,"39887":601,"39888":602,"39889":604,"39890":609,"39891":7747,"39892":7753,"39893":330,"39894":7739,"39895":629,"39896":240,"39897":643,"39898":658,"39899":679,"39900":676,"39901":227,"39902":60294,"39903":60295,"39904":623,"39905":632,"39906":647,"39907":60299,"39908":199,"39909":339,"39910":594,"39911":65351,"39912":715,"39913":719,"39914":65345,"39915":65346,"39916":65348,"39917":65349,"39918":65350,"39919":65352,"39920":65353,"39921":65354,"39922":65355,"39923":65356,"39924":65357,"39925":65358,"39926":65359,"39927":65360,"39928":65362,"39929":65363,"39930":65364,"39931":65365,"39932":65366,"39933":65367,"39934":65370,"40000":28917,"40001":12832,"40002":12833,"40003":12834,"40004":12835,"40005":12836,"40006":12837,"40007":12838,"40008":12839,"40009":12840,"40010":12841,"40011":28926,"40012":28933,"40013":28957,"40014":28969,"40015":28971,"40016":28972,"40017":28979,"40018":28981,"40019":28987,"40020":28990,"40021":28992,"40022":29007,"40023":29035,"40024":29045,"40025":29047,"40026":29052,"40027":29054,"40028":29068,"40029":29070,"40030":29073,"40031":29078,"40032":29090,"40033":29091,"40034":29101,"40035":29108,"40036":29111,"40037":29114,"40038":29137,"40039":29149,"40040":29163,"40041":29184,"40042":29193,"40043":29198,"40044":29199,"40045":29206,"40046":29207,"40047":29220,"40048":23204,"40049":29230,"40050":8838,"40051":29271,"40052":29276,"40053":29332,"40054":29444,"40055":29456,"40056":29505,"40057":29556,"40058":29580,"40059":29583,"40060":29592,"40061":29596,"40062":29598,"40097":29607,"40098":29610,"40099":29653,"40100":29665,"40101":29666,"40102":29668,"40103":29670,"40104":29679,"40105":29683,"40106":8839,"40107":29689,"40108":29691,"40109":29698,"40110":29713,"40111":29714,"40112":29716,"40113":29717,"40114":29719,"40115":29721,"40116":29724,"40117":29726,"40118":29727,"40119":29751,"40120":29752,"40121":29753,"40122":29763,"40123":29765,"40124":29767,"40125":29768,"40126":29769,"40127":29779,"40128":29782,"40129":29797,"40130":29803,"40131":29804,"40132":29812,"40133":29818,"40134":29826,"40135":21378,"40136":24191,"40137":20008,"40138":24186,"40139":20886,"40140":23424,"40141":21353,"40142":11911,"40143":60436,"40144":21251,"40145":9746,"40146":33401,"40147":17553,"40148":11916,"40149":11914,"40150":20022,"40151":60444,"40152":21274,"40153":60446,"40154":60447,"40155":11925,"40156":60449,"40157":60450,"40158":9492,"40159":20058,"40160":36790,"40161":24308,"40162":20872,"40163":20101,"40164":60457,"40165":20031,"40166":60459,"40167":60460,"40168":20059,"40169":21430,"40170":36710,"40171":32415,"40172":35744,"40173":36125,"40174":40479,"40175":38376,"40176":38021,"40177":38429,"40178":25164,"40179":27701,"40180":20155,"40181":24516,"40182":28780,"40183":11950,"40184":21475,"40185":27362,"40186":39483,"40187":39484,"40188":39512,"40189":39516,"40190":39523,"40256":9742,"40257":8594,"40258":8592,"40259":8593,"40260":8595,"40261":8680,"40262":8678,"40263":8679,"40264":8681,"40265":8680,"40266":8678,"40267":8679,"40268":8681,"40269":9758,"40270":9756,"40271":9755,"40272":9759,"40273":12310,"40274":12311,"40275":9675,"40276":10005,"40277":10003,"40278":22267,"40279":9789,"40280":22813,"40281":26189,"40282":29221,"40283":10025,"40284":10017,"40285":9786,"40286":9785,"40287":60515,"40288":60516,"40289":60517,"40290":60518,"40291":60519,"40292":23672,"40293":9836,"40294":9834,"40295":23249,"40296":23479,"40297":23804,"40298":60526,"40299":9993,"40300":9986,"40301":60529,"40302":60530,"40303":60531,"40304":60532,"40305":23765,"40306":26478,"40307":29793,"40308":29853,"40309":32595,"40310":34195,"40311":10063,"40312":60540,"40313":60541,"40314":23928,"40315":24379,"40316":60544,"40317":9473,"40318":9475,"40353":60547,"40354":60548,"40355":60549,"40356":60550,"40357":60551,"40358":60552,"40359":60553,"40360":60554,"40361":60555,"40362":60556,"40363":60557,"40364":60558,"40365":60559,"40366":60560,"40367":60561,"40368":39602,"40369":39648,"40370":39700,"40371":39732,"40372":39737,"40373":39744,"40374":39760,"40375":39807,"40376":9788,"40377":32149,"40378":9729,"40379":38708,"40380":9730,"40381":60575,"40382":60576,"40383":60577,"40384":9992,"40385":60579,"40386":60580,"40387":60581,"40388":60582,"40389":60583,"40390":60584,"40391":60585,"40392":8507,"40393":8481,"40394":26343,"40395":28247,"40396":60590,"40397":29015,"40398":31178,"40399":8470,"40400":33132,"40401":35577,"40402":38998,"40403":60597,"40404":60598,"40405":9760,"40406":60600,"40407":9828,"40408":9824,"40409":9831,"40410":9827,"40411":9826,"40412":9830,"40413":9825,"40414":9829,"40415":60609,"40416":60610,"40417":27364,"40418":8478,"40419":13250,"40420":13272,"40421":13217,"40422":60616,"40423":13221,"40424":60618,"40425":60619,"40426":60620,"40427":60621,"40428":60622,"40429":9745,"40430":39809,"40431":39819,"40432":39821,"40433":39901,"40434":39913,"40435":39917,"40436":39924,"40437":39967,"40438":39968,"40439":39974,"40440":40019,"40441":40029,"40442":40059,"40443":40204,"40444":40214,"40445":8626,"40446":27397,"40512":36073,"40513":36082,"40514":36099,"40515":36113,"40516":36124,"40517":36218,"40518":36265,"40519":36288,"40520":36353,"40521":36366,"40522":36422,"40523":36456,"40524":36465,"40525":36478,"40526":36480,"40527":36534,"40528":36537,"40529":36540,"40530":36547,"40531":36580,"40532":36589,"40533":36594,"40534":36656,"40535":36673,"40536":36682,"40537":36773,"40538":36787,"40539":36792,"40540":36810,"40541":36815,"40542":36872,"40543":36915,"40544":36919,"40545":36964,"40546":36972,"40547":37289,"40548":37302,"40549":37316,"40550":37370,"40551":37384,"40552":37395,"40553":37409,"40554":37416,"40555":37419,"40556":37429,"40557":37436,"40558":37441,"40559":37464,"40560":37469,"40561":37471,"40562":37483,"40563":37486,"40564":37505,"40565":37508,"40566":37513,"40567":37519,"40568":37553,"40569":37562,"40570":37567,"40571":37588,"40572":37595,"40573":37603,"40574":37605,"40609":37611,"40610":37612,"40611":37620,"40612":37622,"40613":37629,"40614":37635,"40615":37639,"40616":37680,"40617":37681,"40618":37696,"40619":37698,"40620":37699,"40621":37727,"40622":37730,"40623":37734,"40624":37736,"40625":37747,"40626":37748,"40627":37752,"40628":37757,"40629":37761,"40630":37764,"40631":37766,"40632":37767,"40633":37776,"40634":37788,"40635":37792,"40636":37816,"40637":37819,"40638":37821,"40639":37823,"40640":37835,"40641":37843,"40642":37851,"40643":37856,"40644":37872,"40645":37873,"40646":37875,"40647":37876,"40648":37889,"40649":37892,"40650":37896,"40651":37911,"40652":37915,"40653":37917,"40654":37924,"40655":37925,"40656":37926,"40657":37933,"40658":37954,"40659":37955,"40660":37965,"40661":37972,"40662":37976,"40663":37989,"40664":37991,"40665":37996,"40666":38009,"40667":38011,"40668":38264,"40669":38277,"40670":38310,"40671":38314,"40672":38486,"40673":38523,"40674":38565,"40675":38644,"40676":38683,"40677":38710,"40678":38720,"40679":38721,"40680":38743,"40681":38791,"40682":38793,"40683":38811,"40684":38833,"40685":38845,"40686":38848,"40687":38850,"40688":38866,"40689":38880,"40690":38932,"40691":38933,"40692":38947,"40693":38963,"40694":39016,"40695":39095,"40696":39097,"40697":39111,"40698":39114,"40699":39136,"40700":39137,"40701":39148,"40702":39157,"40768":40225,"40769":40244,"40770":40249,"40771":40265,"40772":40270,"40773":40301,"40774":8759,"40775":40302,"40776":40316,"40777":40323,"40778":40339,"40779":40357,"40780":8748,"40781":40381,"40782":27521,"40783":27569,"40784":40015,"40785":40592,"40786":40384,"40787":60817,"40788":60818,"40789":9775,"40790":9776,"40791":9783,"40792":9779,"40793":9780,"40794":9781,"40795":9778,"40796":9782,"40797":9777,"40798":40393,"40799":40404,"40800":40444,"40801":40458,"40802":40460,"40803":40462,"40804":40472,"40805":40571,"40806":40581,"40807":40610,"40808":40620,"40809":40625,"40810":40641,"40811":40646,"40812":40647,"40813":40689,"40814":40696,"40815":40743,"40816":39182,"40817":39193,"40818":39196,"40819":39223,"40820":39261,"40821":39266,"40822":39323,"40823":39332,"40824":39338,"40825":39352,"40826":39392,"40827":39398,"40828":39413,"40829":39455,"40830":32254,"40865":32263,"40866":32347,"40867":32357,"40868":32364,"40869":32567,"40870":32576,"40871":32577,"40872":32585,"40873":32594,"40874":32655,"40875":32659,"40876":32692,"40877":32733,"40878":32743,"40879":32762,"40880":32770,"40881":32776,"40882":32814,"40883":32815,"40884":32828,"40885":32935,"40886":33036,"40887":33066,"40888":33076,"40889":33090,"40890":33110,"40891":33156,"40892":33189,"40893":33252,"40894":33364,"40895":33381,"40896":33403,"40897":33415,"40898":33471,"40899":33506,"40900":33518,"40901":33528,"40902":33532,"40903":33535,"40904":33547,"40905":33565,"40906":33597,"40907":33623,"40908":33681,"40909":33708,"40910":33741,"40911":33773,"40912":33797,"40913":33812,"40914":33814,"40915":33825,"40916":33838,"40917":33854,"40918":33866,"40919":33875,"40920":33877,"40921":33880,"40922":33892,"40923":33906,"40924":33919,"40925":33920,"40926":33938,"40927":33939,"40928":33942,"40929":33955,"40930":33982,"40931":34014,"40932":34017,"40933":34018,"40934":34020,"40935":34040,"40936":34051,"40937":34053,"40938":34064,"40939":34099,"40940":8208,"40941":34114,"40942":34124,"40943":34130,"40944":34143,"40945":34159,"40946":34160,"40947":34163,"40948":34262,"40949":34272,"40950":34286,"40951":34300,"40952":34317,"40953":34319,"40954":34324,"40955":34344,"40956":34370,"40957":34373,"40958":34418,"41024":34972,"41025":23405,"41026":33079,"41027":60958,"41028":39224,"41029":21874,"41030":21867,"41031":60962,"41032":13774,"41033":21873,"41034":21946,"41035":22001,"41036":13778,"41037":22000,"41038":22021,"41039":22050,"41040":22061,"41041":22083,"41042":22046,"41043":22162,"41044":31949,"41045":21530,"41046":21523,"41047":21655,"41048":26353,"41049":30004,"41050":21581,"41051":22180,"41052":22175,"41053":25811,"41054":25390,"41055":25592,"41056":25886,"41057":20088,"41058":27626,"41059":27698,"41060":27709,"41061":27746,"41062":27826,"41063":28152,"41064":28201,"41065":28278,"41066":28290,"41067":28294,"41068":28347,"41069":28383,"41070":28386,"41071":28433,"41072":28452,"41073":28532,"41074":28561,"41075":28597,"41076":28659,"41077":28661,"41078":28859,"41079":28864,"41080":28943,"41081":8706,"41082":29013,"41083":29043,"41084":29050,"41085":61016,"41086":21027,"41121":61018,"41122":13393,"41123":61020,"41124":36812,"41125":61022,"41126":61023,"41127":192,"41128":200,"41129":204,"41130":210,"41131":217,"41132":193,"41133":205,"41134":211,"41135":218,"41136":257,"41137":275,"41138":299,"41139":333,"41140":363,"41141":470,"41142":196,"41143":203,"41144":207,"41145":214,"41146":220,"41147":198,"41148":199,"41149":209,"41150":195,"41151":213,"41152":225,"41153":233,"41154":237,"41155":243,"41156":250,"41157":472,"41158":228,"41159":235,"41160":239,"41161":246,"41162":252,"41163":230,"41164":231,"41165":241,"41166":227,"41167":245,"41168":462,"41169":283,"41170":464,"41171":466,"41172":468,"41173":474,"41174":197,"41175":201,"41176":29064,"41177":216,"41178":208,"41179":7922,"41180":222,"41181":223,"41182":170,"41183":161,"41184":224,"41185":232,"41186":236,"41187":242,"41188":249,"41189":476,"41190":229,"41191":29080,"41192":29143,"41193":248,"41194":240,"41195":7923,"41196":254,"41197":255,"41198":186,"41199":191,"41200":226,"41201":234,"41202":238,"41203":244,"41204":251,"41205":29173,"41206":194,"41207":202,"41208":206,"41209":212,"41210":219,"41211":184,"41212":164,"41213":61110,"41214":402,"41280":12288,"41281":65292,"41282":12289,"41283":12290,"41284":65294,"41285":8231,"41286":65307,"41287":65306,"41288":65311,"41289":65281,"41290":65072,"41291":8230,"41292":8229,"41293":65104,"41294":65105,"41295":65106,"41296":183,"41297":65108,"41298":65109,"41299":65110,"41300":65111,"41301":65372,"41302":8211,"41303":65073,"41304":8212,"41305":65075,"41306":9588,"41307":65076,"41308":65103,"41309":65288,"41310":65289,"41311":65077,"41312":65078,"41313":65371,"41314":65373,"41315":65079,"41316":65080,"41317":12308,"41318":12309,"41319":65081,"41320":65082,"41321":12304,"41322":12305,"41323":65083,"41324":65084,"41325":12298,"41326":12299,"41327":65085,"41328":65086,"41329":12296,"41330":12297,"41331":65087,"41332":65088,"41333":12300,"41334":12301,"41335":65089,"41336":65090,"41337":12302,"41338":12303,"41339":65091,"41340":65092,"41341":65113,"41342":65114,"41377":65115,"41378":65116,"41379":65117,"41380":65118,"41381":8216,"41382":8217,"41383":8220,"41384":8221,"41385":12317,"41386":12318,"41387":8245,"41388":8242,"41389":65283,"41390":65286,"41391":65290,"41392":8251,"41393":167,"41394":12291,"41395":9675,"41396":9679,"41397":9651,"41398":9650,"41399":9678,"41400":9734,"41401":9733,"41402":9671,"41403":9670,"41404":9633,"41405":9632,"41406":9661,"41407":9660,"41408":12963,"41409":8453,"41410":175,"41411":65507,"41412":65343,"41413":717,"41414":65097,"41415":65098,"41416":65101,"41417":65102,"41418":65099,"41419":65100,"41420":65119,"41421":65120,"41422":65121,"41423":65291,"41424":65293,"41425":215,"41426":247,"41427":177,"41428":8730,"41429":65308,"41430":65310,"41431":65309,"41432":8806,"41433":8807,"41434":8800,"41435":8734,"41436":8786,"41437":8801,"41438":65122,"41439":65123,"41440":65124,"41441":65125,"41442":65126,"41443":65374,"41444":8745,"41445":8746,"41446":8869,"41447":8736,"41448":8735,"41449":8895,"41450":13266,"41451":13265,"41452":8747,"41453":8750,"41454":8757,"41455":8756,"41456":9792,"41457":9794,"41458":8853,"41459":8857,"41460":8593,"41461":8595,"41462":8592,"41463":8594,"41464":8598,"41465":8599,"41466":8601,"41467":8600,"41468":8741,"41469":8739,"41470":65295,"41536":65340,"41537":8725,"41538":65128,"41539":65284,"41540":65509,"41541":12306,"41542":65504,"41543":65505,"41544":65285,"41545":65312,"41546":8451,"41547":8457,"41548":65129,"41549":65130,"41550":65131,"41551":13269,"41552":13212,"41553":13213,"41554":13214,"41555":13262,"41556":13217,"41557":13198,"41558":13199,"41559":13252,"41560":176,"41561":20825,"41562":20827,"41563":20830,"41564":20829,"41565":20833,"41566":20835,"41567":21991,"41568":29929,"41569":31950,"41570":9601,"41571":9602,"41572":9603,"41573":9604,"41574":9605,"41575":9606,"41576":9607,"41577":9608,"41578":9615,"41579":9614,"41580":9613,"41581":9612,"41582":9611,"41583":9610,"41584":9609,"41585":9532,"41586":9524,"41587":9516,"41588":9508,"41589":9500,"41590":9620,"41591":9472,"41592":9474,"41593":9621,"41594":9484,"41595":9488,"41596":9492,"41597":9496,"41598":9581,"41633":9582,"41634":9584,"41635":9583,"41636":9552,"41637":9566,"41638":9578,"41639":9569,"41640":9698,"41641":9699,"41642":9701,"41643":9700,"41644":9585,"41645":9586,"41646":9587,"41647":65296,"41648":65297,"41649":65298,"41650":65299,"41651":65300,"41652":65301,"41653":65302,"41654":65303,"41655":65304,"41656":65305,"41657":8544,"41658":8545,"41659":8546,"41660":8547,"41661":8548,"41662":8549,"41663":8550,"41664":8551,"41665":8552,"41666":8553,"41667":12321,"41668":12322,"41669":12323,"41670":12324,"41671":12325,"41672":12326,"41673":12327,"41674":12328,"41675":12329,"41676":21313,"41677":21316,"41678":21317,"41679":65313,"41680":65314,"41681":65315,"41682":65316,"41683":65317,"41684":65318,"41685":65319,"41686":65320,"41687":65321,"41688":65322,"41689":65323,"41690":65324,"41691":65325,"41692":65326,"41693":65327,"41694":65328,"41695":65329,"41696":65330,"41697":65331,"41698":65332,"41699":65333,"41700":65334,"41701":65335,"41702":65336,"41703":65337,"41704":65338,"41705":65345,"41706":65346,"41707":65347,"41708":65348,"41709":65349,"41710":65350,"41711":65351,"41712":65352,"41713":65353,"41714":65354,"41715":65355,"41716":65356,"41717":65357,"41718":65358,"41719":65359,"41720":65360,"41721":65361,"41722":65362,"41723":65363,"41724":65364,"41725":65365,"41726":65366,"41792":65367,"41793":65368,"41794":65369,"41795":65370,"41796":913,"41797":914,"41798":915,"41799":916,"41800":917,"41801":918,"41802":919,"41803":920,"41804":921,"41805":922,"41806":923,"41807":924,"41808":925,"41809":926,"41810":927,"41811":928,"41812":929,"41813":931,"41814":932,"41815":933,"41816":934,"41817":935,"41818":936,"41819":937,"41820":945,"41821":946,"41822":947,"41823":948,"41824":949,"41825":950,"41826":951,"41827":952,"41828":953,"41829":954,"41830":955,"41831":956,"41832":957,"41833":958,"41834":959,"41835":960,"41836":961,"41837":963,"41838":964,"41839":965,"41840":966,"41841":967,"41842":968,"41843":969,"41844":12549,"41845":12550,"41846":12551,"41847":12552,"41848":12553,"41849":12554,"41850":12555,"41851":12556,"41852":12557,"41853":12558,"41854":12559,"41889":12560,"41890":12561,"41891":12562,"41892":12563,"41893":12564,"41894":12565,"41895":12566,"41896":12567,"41897":12568,"41898":12569,"41899":12570,"41900":12571,"41901":12572,"41902":12573,"41903":12574,"41904":12575,"41905":12576,"41906":12577,"41907":12578,"41908":12579,"41909":12580,"41910":12581,"41911":12582,"41912":12583,"41913":12584,"41914":12585,"41915":729,"41916":713,"41917":714,"41918":711,"41919":715,"41920":9216,"41921":9217,"41922":9218,"41923":9219,"41924":9220,"41925":9221,"41926":9222,"41927":9223,"41928":9224,"41929":9225,"41930":9226,"41931":9227,"41932":9228,"41933":9229,"41934":9230,"41935":9231,"41936":9232,"41937":9233,"41938":9234,"41939":9235,"41940":9236,"41941":9237,"41942":9238,"41943":9239,"41944":9240,"41945":9241,"41946":9242,"41947":9243,"41948":9244,"41949":9245,"41950":9246,"41951":9247,"41952":9249,"41953":8364,"41954":63561,"41955":63562,"41956":63563,"41957":63564,"41958":63565,"41959":63566,"41960":63567,"41961":63568,"41962":63569,"41963":63570,"41964":63571,"41965":63572,"41966":63573,"41967":63574,"41968":63575,"41969":63576,"41970":63577,"41971":63578,"41972":63579,"41973":63580,"41974":63581,"41975":63582,"41976":63583,"41977":63584,"41978":63585,"41979":63586,"41980":63587,"41981":63588,"41982":63589,"42048":19968,"42049":20057,"42050":19969,"42051":19971,"42052":20035,"42053":20061,"42054":20102,"42055":20108,"42056":20154,"42057":20799,"42058":20837,"42059":20843,"42060":20960,"42061":20992,"42062":20993,"42063":21147,"42064":21269,"42065":21313,"42066":21340,"42067":21448,"42068":19977,"42069":19979,"42070":19976,"42071":19978,"42072":20011,"42073":20024,"42074":20961,"42075":20037,"42076":20040,"42077":20063,"42078":20062,"42079":20110,"42080":20129,"42081":20800,"42082":20995,"42083":21242,"42084":21315,"42085":21449,"42086":21475,"42087":22303,"42088":22763,"42089":22805,"42090":22823,"42091":22899,"42092":23376,"42093":23377,"42094":23379,"42095":23544,"42096":23567,"42097":23586,"42098":23608,"42099":23665,"42100":24029,"42101":24037,"42102":24049,"42103":24050,"42104":24051,"42105":24062,"42106":24178,"42107":24318,"42108":24331,"42109":24339,"42110":25165,"42145":19985,"42146":19984,"42147":19981,"42148":20013,"42149":20016,"42150":20025,"42151":20043,"42152":23609,"42153":20104,"42154":20113,"42155":20117,"42156":20114,"42157":20116,"42158":20130,"42159":20161,"42160":20160,"42161":20163,"42162":20166,"42163":20167,"42164":20173,"42165":20170,"42166":20171,"42167":20164,"42168":20803,"42169":20801,"42170":20839,"42171":20845,"42172":20846,"42173":20844,"42174":20887,"42175":20982,"42176":20998,"42177":20999,"42178":21000,"42179":21243,"42180":21246,"42181":21247,"42182":21270,"42183":21305,"42184":21320,"42185":21319,"42186":21317,"42187":21342,"42188":21380,"42189":21451,"42190":21450,"42191":21453,"42192":22764,"42193":22825,"42194":22827,"42195":22826,"42196":22829,"42197":23380,"42198":23569,"42199":23588,"42200":23610,"42201":23663,"42202":24052,"42203":24187,"42204":24319,"42205":24340,"42206":24341,"42207":24515,"42208":25096,"42209":25142,"42210":25163,"42211":25166,"42212":25903,"42213":25991,"42214":26007,"42215":26020,"42216":26041,"42217":26085,"42218":26352,"42219":26376,"42220":26408,"42221":27424,"42222":27490,"42223":27513,"42224":27595,"42225":27604,"42226":27611,"42227":27663,"42228":27700,"42229":28779,"42230":29226,"42231":29238,"42232":29243,"42233":29255,"42234":29273,"42235":29275,"42236":29356,"42237":29579,"42238":19993,"42304":19990,"42305":19989,"42306":19988,"42307":19992,"42308":20027,"42309":20045,"42310":20047,"42311":20046,"42312":20197,"42313":20184,"42314":20180,"42315":20181,"42316":20182,"42317":20183,"42318":20195,"42319":20196,"42320":20185,"42321":20190,"42322":20805,"42323":20804,"42324":20873,"42325":20874,"42326":20908,"42327":20985,"42328":20986,"42329":20984,"42330":21002,"42331":21152,"42332":21151,"42333":21253,"42334":21254,"42335":21271,"42336":21277,"42337":20191,"42338":21322,"42339":21321,"42340":21345,"42341":21344,"42342":21359,"42343":21358,"42344":21435,"42345":21487,"42346":21476,"42347":21491,"42348":21484,"42349":21486,"42350":21481,"42351":21480,"42352":21500,"42353":21496,"42354":21493,"42355":21483,"42356":21478,"42357":21482,"42358":21490,"42359":21489,"42360":21488,"42361":21477,"42362":21485,"42363":21499,"42364":22235,"42365":22234,"42366":22806,"42401":22830,"42402":22833,"42403":22900,"42404":22902,"42405":23381,"42406":23427,"42407":23612,"42408":24040,"42409":24039,"42410":24038,"42411":24066,"42412":24067,"42413":24179,"42414":24188,"42415":24321,"42416":24344,"42417":24343,"42418":24517,"42419":25098,"42420":25171,"42421":25172,"42422":25170,"42423":25169,"42424":26021,"42425":26086,"42426":26414,"42427":26412,"42428":26410,"42429":26411,"42430":26413,"42431":27491,"42432":27597,"42433":27665,"42434":27664,"42435":27704,"42436":27713,"42437":27712,"42438":27710,"42439":29359,"42440":29572,"42441":29577,"42442":29916,"42443":29926,"42444":29976,"42445":29983,"42446":29992,"42447":29993,"42448":30000,"42449":30001,"42450":30002,"42451":30003,"42452":30091,"42453":30333,"42454":30382,"42455":30399,"42456":30446,"42457":30683,"42458":30690,"42459":30707,"42460":31034,"42461":31166,"42462":31348,"42463":31435,"42464":19998,"42465":19999,"42466":20050,"42467":20051,"42468":20073,"42469":20121,"42470":20132,"42471":20134,"42472":20133,"42473":20223,"42474":20233,"42475":20249,"42476":20234,"42477":20245,"42478":20237,"42479":20240,"42480":20241,"42481":20239,"42482":20210,"42483":20214,"42484":20219,"42485":20208,"42486":20211,"42487":20221,"42488":20225,"42489":20235,"42490":20809,"42491":20807,"42492":20806,"42493":20808,"42494":20840,"42560":20849,"42561":20877,"42562":20912,"42563":21015,"42564":21009,"42565":21010,"42566":21006,"42567":21014,"42568":21155,"42569":21256,"42570":21281,"42571":21280,"42572":21360,"42573":21361,"42574":21513,"42575":21519,"42576":21516,"42577":21514,"42578":21520,"42579":21505,"42580":21515,"42581":21508,"42582":21521,"42583":21517,"42584":21512,"42585":21507,"42586":21518,"42587":21510,"42588":21522,"42589":22240,"42590":22238,"42591":22237,"42592":22323,"42593":22320,"42594":22312,"42595":22317,"42596":22316,"42597":22319,"42598":22313,"42599":22809,"42600":22810,"42601":22839,"42602":22840,"42603":22916,"42604":22904,"42605":22915,"42606":22909,"42607":22905,"42608":22914,"42609":22913,"42610":23383,"42611":23384,"42612":23431,"42613":23432,"42614":23429,"42615":23433,"42616":23546,"42617":23574,"42618":23673,"42619":24030,"42620":24070,"42621":24182,"42622":24180,"42657":24335,"42658":24347,"42659":24537,"42660":24534,"42661":25102,"42662":25100,"42663":25101,"42664":25104,"42665":25187,"42666":25179,"42667":25176,"42668":25910,"42669":26089,"42670":26088,"42671":26092,"42672":26093,"42673":26354,"42674":26355,"42675":26377,"42676":26429,"42677":26420,"42678":26417,"42679":26421,"42680":27425,"42681":27492,"42682":27515,"42683":27670,"42684":27741,"42685":27735,"42686":27737,"42687":27743,"42688":27744,"42689":27728,"42690":27733,"42691":27745,"42692":27739,"42693":27725,"42694":27726,"42695":28784,"42696":29279,"42697":29277,"42698":30334,"42699":31481,"42700":31859,"42701":31992,"42702":32566,"42703":32650,"42704":32701,"42705":32769,"42706":32771,"42707":32780,"42708":32786,"42709":32819,"42710":32895,"42711":32905,"42712":32907,"42713":32908,"42714":33251,"42715":33258,"42716":33267,"42717":33276,"42718":33292,"42719":33307,"42720":33311,"42721":33390,"42722":33394,"42723":33406,"42724":34411,"42725":34880,"42726":34892,"42727":34915,"42728":35199,"42729":38433,"42730":20018,"42731":20136,"42732":20301,"42733":20303,"42734":20295,"42735":20311,"42736":20318,"42737":20276,"42738":20315,"42739":20309,"42740":20272,"42741":20304,"42742":20305,"42743":20285,"42744":20282,"42745":20280,"42746":20291,"42747":20308,"42748":20284,"42749":20294,"42750":20323,"42816":20316,"42817":20320,"42818":20271,"42819":20302,"42820":20278,"42821":20313,"42822":20317,"42823":20296,"42824":20314,"42825":20812,"42826":20811,"42827":20813,"42828":20853,"42829":20918,"42830":20919,"42831":21029,"42832":21028,"42833":21033,"42834":21034,"42835":21032,"42836":21163,"42837":21161,"42838":21162,"42839":21164,"42840":21283,"42841":21363,"42842":21365,"42843":21533,"42844":21549,"42845":21534,"42846":21566,"42847":21542,"42848":21582,"42849":21543,"42850":21574,"42851":21571,"42852":21555,"42853":21576,"42854":21570,"42855":21531,"42856":21545,"42857":21578,"42858":21561,"42859":21563,"42860":21560,"42861":21550,"42862":21557,"42863":21558,"42864":21536,"42865":21564,"42866":21568,"42867":21553,"42868":21547,"42869":21535,"42870":21548,"42871":22250,"42872":22256,"42873":22244,"42874":22251,"42875":22346,"42876":22353,"42877":22336,"42878":22349,"42913":22343,"42914":22350,"42915":22334,"42916":22352,"42917":22351,"42918":22331,"42919":22767,"42920":22846,"42921":22941,"42922":22930,"42923":22952,"42924":22942,"42925":22947,"42926":22937,"42927":22934,"42928":22925,"42929":22948,"42930":22931,"42931":22922,"42932":22949,"42933":23389,"42934":23388,"42935":23386,"42936":23387,"42937":23436,"42938":23435,"42939":23439,"42940":23596,"42941":23616,"42942":23617,"42943":23615,"42944":23614,"42945":23696,"42946":23697,"42947":23700,"42948":23692,"42949":24043,"42950":24076,"42951":24207,"42952":24199,"42953":24202,"42954":24311,"42955":24324,"42956":24351,"42957":24420,"42958":24418,"42959":24439,"42960":24441,"42961":24536,"42962":24524,"42963":24535,"42964":24525,"42965":24561,"42966":24555,"42967":24568,"42968":24554,"42969":25106,"42970":25105,"42971":25220,"42972":25239,"42973":25238,"42974":25216,"42975":25206,"42976":25225,"42977":25197,"42978":25226,"42979":25212,"42980":25214,"42981":25209,"42982":25203,"42983":25234,"42984":25199,"42985":25240,"42986":25198,"42987":25237,"42988":25235,"42989":25233,"42990":25222,"42991":25913,"42992":25915,"42993":25912,"42994":26097,"42995":26356,"42996":26463,"42997":26446,"42998":26447,"42999":26448,"43000":26449,"43001":26460,"43002":26454,"43003":26462,"43004":26441,"43005":26438,"43006":26464,"43072":26451,"43073":26455,"43074":27493,"43075":27599,"43076":27714,"43077":27742,"43078":27801,"43079":27777,"43080":27784,"43081":27785,"43082":27781,"43083":27803,"43084":27754,"43085":27770,"43086":27792,"43087":27760,"43088":27788,"43089":27752,"43090":27798,"43091":27794,"43092":27773,"43093":27779,"43094":27762,"43095":27774,"43096":27764,"43097":27782,"43098":27766,"43099":27789,"43100":27796,"43101":27800,"43102":27778,"43103":28790,"43104":28796,"43105":28797,"43106":28792,"43107":29282,"43108":29281,"43109":29280,"43110":29380,"43111":29378,"43112":29590,"43113":29996,"43114":29995,"43115":30007,"43116":30008,"43117":30338,"43118":30447,"43119":30691,"43120":31169,"43121":31168,"43122":31167,"43123":31350,"43124":31995,"43125":32597,"43126":32918,"43127":32915,"43128":32925,"43129":32920,"43130":32923,"43131":32922,"43132":32946,"43133":33391,"43134":33426,"43169":33419,"43170":33421,"43171":35211,"43172":35282,"43173":35328,"43174":35895,"43175":35910,"43176":35925,"43177":35997,"43178":36196,"43179":36208,"43180":36275,"43181":36523,"43182":36554,"43183":36763,"43184":36784,"43185":36802,"43186":36806,"43187":36805,"43188":36804,"43189":24033,"43190":37009,"43191":37026,"43192":37034,"43193":37030,"43194":37027,"43195":37193,"43196":37318,"43197":37324,"43198":38450,"43199":38446,"43200":38449,"43201":38442,"43202":38444,"43203":20006,"43204":20054,"43205":20083,"43206":20107,"43207":20123,"43208":20126,"43209":20139,"43210":20140,"43211":20335,"43212":20381,"43213":20365,"43214":20339,"43215":20351,"43216":20332,"43217":20379,"43218":20363,"43219":20358,"43220":20355,"43221":20336,"43222":20341,"43223":20360,"43224":20329,"43225":20347,"43226":20374,"43227":20350,"43228":20367,"43229":20369,"43230":20346,"43231":20820,"43232":20818,"43233":20821,"43234":20841,"43235":20855,"43236":20854,"43237":20856,"43238":20925,"43239":20989,"43240":21051,"43241":21048,"43242":21047,"43243":21050,"43244":21040,"43245":21038,"43246":21046,"43247":21057,"43248":21182,"43249":21179,"43250":21330,"43251":21332,"43252":21331,"43253":21329,"43254":21350,"43255":21367,"43256":21368,"43257":21369,"43258":21462,"43259":21460,"43260":21463,"43261":21619,"43262":21621,"43328":21654,"43329":21624,"43330":21653,"43331":21632,"43332":21627,"43333":21623,"43334":21636,"43335":21650,"43336":21638,"43337":21628,"43338":21648,"43339":21617,"43340":21622,"43341":21644,"43342":21658,"43343":21602,"43344":21608,"43345":21643,"43346":21629,"43347":21646,"43348":22266,"43349":22403,"43350":22391,"43351":22378,"43352":22377,"43353":22369,"43354":22374,"43355":22372,"43356":22396,"43357":22812,"43358":22857,"43359":22855,"43360":22856,"43361":22852,"43362":22868,"43363":22974,"43364":22971,"43365":22996,"43366":22969,"43367":22958,"43368":22993,"43369":22982,"43370":22992,"43371":22989,"43372":22987,"43373":22995,"43374":22986,"43375":22959,"43376":22963,"43377":22994,"43378":22981,"43379":23391,"43380":23396,"43381":23395,"43382":23447,"43383":23450,"43384":23448,"43385":23452,"43386":23449,"43387":23451,"43388":23578,"43389":23624,"43390":23621,"43425":23622,"43426":23735,"43427":23713,"43428":23736,"43429":23721,"43430":23723,"43431":23729,"43432":23731,"43433":24088,"43434":24090,"43435":24086,"43436":24085,"43437":24091,"43438":24081,"43439":24184,"43440":24218,"43441":24215,"43442":24220,"43443":24213,"43444":24214,"43445":24310,"43446":24358,"43447":24359,"43448":24361,"43449":24448,"43450":24449,"43451":24447,"43452":24444,"43453":24541,"43454":24544,"43455":24573,"43456":24565,"43457":24575,"43458":24591,"43459":24596,"43460":24623,"43461":24629,"43462":24598,"43463":24618,"43464":24597,"43465":24609,"43466":24615,"43467":24617,"43468":24619,"43469":24603,"43470":25110,"43471":25109,"43472":25151,"43473":25150,"43474":25152,"43475":25215,"43476":25289,"43477":25292,"43478":25284,"43479":25279,"43480":25282,"43481":25273,"43482":25298,"43483":25307,"43484":25259,"43485":25299,"43486":25300,"43487":25291,"43488":25288,"43489":25256,"43490":25277,"43491":25276,"43492":25296,"43493":25305,"43494":25287,"43495":25293,"43496":25269,"43497":25306,"43498":25265,"43499":25304,"43500":25302,"43501":25303,"43502":25286,"43503":25260,"43504":25294,"43505":25918,"43506":26023,"43507":26044,"43508":26106,"43509":26132,"43510":26131,"43511":26124,"43512":26118,"43513":26114,"43514":26126,"43515":26112,"43516":26127,"43517":26133,"43518":26122,"43584":26119,"43585":26381,"43586":26379,"43587":26477,"43588":26507,"43589":26517,"43590":26481,"43591":26524,"43592":26483,"43593":26487,"43594":26503,"43595":26525,"43596":26519,"43597":26479,"43598":26480,"43599":26495,"43600":26505,"43601":26494,"43602":26512,"43603":26485,"43604":26522,"43605":26515,"43606":26492,"43607":26474,"43608":26482,"43609":27427,"43610":27494,"43611":27495,"43612":27519,"43613":27667,"43614":27675,"43615":27875,"43616":27880,"43617":27891,"43618":27825,"43619":27852,"43620":27877,"43621":27827,"43622":27837,"43623":27838,"43624":27836,"43625":27874,"43626":27819,"43627":27861,"43628":27859,"43629":27832,"43630":27844,"43631":27833,"43632":27841,"43633":27822,"43634":27863,"43635":27845,"43636":27889,"43637":27839,"43638":27835,"43639":27873,"43640":27867,"43641":27850,"43642":27820,"43643":27887,"43644":27868,"43645":27862,"43646":27872,"43681":28821,"43682":28814,"43683":28818,"43684":28810,"43685":28825,"43686":29228,"43687":29229,"43688":29240,"43689":29256,"43690":29287,"43691":29289,"43692":29376,"43693":29390,"43694":29401,"43695":29399,"43696":29392,"43697":29609,"43698":29608,"43699":29599,"43700":29611,"43701":29605,"43702":30013,"43703":30109,"43704":30105,"43705":30106,"43706":30340,"43707":30402,"43708":30450,"43709":30452,"43710":30693,"43711":30717,"43712":31038,"43713":31040,"43714":31041,"43715":31177,"43716":31176,"43717":31354,"43718":31353,"43719":31482,"43720":31998,"43721":32596,"43722":32652,"43723":32651,"43724":32773,"43725":32954,"43726":32933,"43727":32930,"43728":32945,"43729":32929,"43730":32939,"43731":32937,"43732":32948,"43733":32938,"43734":32943,"43735":33253,"43736":33278,"43737":33293,"43738":33459,"43739":33437,"43740":33433,"43741":33453,"43742":33469,"43743":33439,"43744":33465,"43745":33457,"43746":33452,"43747":33445,"43748":33455,"43749":33464,"43750":33443,"43751":33456,"43752":33470,"43753":33463,"43754":34382,"43755":34417,"43756":21021,"43757":34920,"43758":36555,"43759":36814,"43760":36820,"43761":36817,"43762":37045,"43763":37048,"43764":37041,"43765":37046,"43766":37319,"43767":37329,"43768":38263,"43769":38272,"43770":38428,"43771":38464,"43772":38463,"43773":38459,"43774":38468,"43840":38466,"43841":38585,"43842":38632,"43843":38738,"43844":38750,"43845":20127,"43846":20141,"43847":20142,"43848":20449,"43849":20405,"43850":20399,"43851":20415,"43852":20448,"43853":20433,"43854":20431,"43855":20445,"43856":20419,"43857":20406,"43858":20440,"43859":20447,"43860":20426,"43861":20439,"43862":20398,"43863":20432,"43864":20420,"43865":20418,"43866":20442,"43867":20430,"43868":20446,"43869":20407,"43870":20823,"43871":20882,"43872":20881,"43873":20896,"43874":21070,"43875":21059,"43876":21066,"43877":21069,"43878":21068,"43879":21067,"43880":21063,"43881":21191,"43882":21193,"43883":21187,"43884":21185,"43885":21261,"43886":21335,"43887":21371,"43888":21402,"43889":21467,"43890":21676,"43891":21696,"43892":21672,"43893":21710,"43894":21705,"43895":21688,"43896":21670,"43897":21683,"43898":21703,"43899":21698,"43900":21693,"43901":21674,"43902":21697,"43937":21700,"43938":21704,"43939":21679,"43940":21675,"43941":21681,"43942":21691,"43943":21673,"43944":21671,"43945":21695,"43946":22271,"43947":22402,"43948":22411,"43949":22432,"43950":22435,"43951":22434,"43952":22478,"43953":22446,"43954":22419,"43955":22869,"43956":22865,"43957":22863,"43958":22862,"43959":22864,"43960":23004,"43961":23000,"43962":23039,"43963":23011,"43964":23016,"43965":23043,"43966":23013,"43967":23018,"43968":23002,"43969":23014,"43970":23041,"43971":23035,"43972":23401,"43973":23459,"43974":23462,"43975":23460,"43976":23458,"43977":23461,"43978":23553,"43979":23630,"43980":23631,"43981":23629,"43982":23627,"43983":23769,"43984":23762,"43985":24055,"43986":24093,"43987":24101,"43988":24095,"43989":24189,"43990":24224,"43991":24230,"43992":24314,"43993":24328,"43994":24365,"43995":24421,"43996":24456,"43997":24453,"43998":24458,"43999":24459,"44000":24455,"44001":24460,"44002":24457,"44003":24594,"44004":24605,"44005":24608,"44006":24613,"44007":24590,"44008":24616,"44009":24653,"44010":24688,"44011":24680,"44012":24674,"44013":24646,"44014":24643,"44015":24684,"44016":24683,"44017":24682,"44018":24676,"44019":25153,"44020":25308,"44021":25366,"44022":25353,"44023":25340,"44024":25325,"44025":25345,"44026":25326,"44027":25341,"44028":25351,"44029":25329,"44030":25335,"44096":25327,"44097":25324,"44098":25342,"44099":25332,"44100":25361,"44101":25346,"44102":25919,"44103":25925,"44104":26027,"44105":26045,"44106":26082,"44107":26149,"44108":26157,"44109":26144,"44110":26151,"44111":26159,"44112":26143,"44113":26152,"44114":26161,"44115":26148,"44116":26359,"44117":26623,"44118":26579,"44119":26609,"44120":26580,"44121":26576,"44122":26604,"44123":26550,"44124":26543,"44125":26613,"44126":26601,"44127":26607,"44128":26564,"44129":26577,"44130":26548,"44131":26586,"44132":26597,"44133":26552,"44134":26575,"44135":26590,"44136":26611,"44137":26544,"44138":26585,"44139":26594,"44140":26589,"44141":26578,"44142":27498,"44143":27523,"44144":27526,"44145":27573,"44146":27602,"44147":27607,"44148":27679,"44149":27849,"44150":27915,"44151":27954,"44152":27946,"44153":27969,"44154":27941,"44155":27916,"44156":27953,"44157":27934,"44158":27927,"44193":27963,"44194":27965,"44195":27966,"44196":27958,"44197":27931,"44198":27893,"44199":27961,"44200":27943,"44201":27960,"44202":27945,"44203":27950,"44204":27957,"44205":27918,"44206":27947,"44207":28843,"44208":28858,"44209":28851,"44210":28844,"44211":28847,"44212":28845,"44213":28856,"44214":28846,"44215":28836,"44216":29232,"44217":29298,"44218":29295,"44219":29300,"44220":29417,"44221":29408,"44222":29409,"44223":29623,"44224":29642,"44225":29627,"44226":29618,"44227":29645,"44228":29632,"44229":29619,"44230":29978,"44231":29997,"44232":30031,"44233":30028,"44234":30030,"44235":30027,"44236":30123,"44237":30116,"44238":30117,"44239":30114,"44240":30115,"44241":30328,"44242":30342,"44243":30343,"44244":30344,"44245":30408,"44246":30406,"44247":30403,"44248":30405,"44249":30465,"44250":30457,"44251":30456,"44252":30473,"44253":30475,"44254":30462,"44255":30460,"44256":30471,"44257":30684,"44258":30722,"44259":30740,"44260":30732,"44261":30733,"44262":31046,"44263":31049,"44264":31048,"44265":31047,"44266":31161,"44267":31162,"44268":31185,"44269":31186,"44270":31179,"44271":31359,"44272":31361,"44273":31487,"44274":31485,"44275":31869,"44276":32002,"44277":32005,"44278":32000,"44279":32009,"44280":32007,"44281":32004,"44282":32006,"44283":32568,"44284":32654,"44285":32703,"44286":32772,"44352":32784,"44353":32781,"44354":32785,"44355":32822,"44356":32982,"44357":32997,"44358":32986,"44359":32963,"44360":32964,"44361":32972,"44362":32993,"44363":32987,"44364":32974,"44365":32990,"44366":32996,"44367":32989,"44368":33268,"44369":33314,"44370":33511,"44371":33539,"44372":33541,"44373":33507,"44374":33499,"44375":33510,"44376":33540,"44377":33509,"44378":33538,"44379":33545,"44380":33490,"44381":33495,"44382":33521,"44383":33537,"44384":33500,"44385":33492,"44386":33489,"44387":33502,"44388":33491,"44389":33503,"44390":33519,"44391":33542,"44392":34384,"44393":34425,"44394":34427,"44395":34426,"44396":34893,"44397":34923,"44398":35201,"44399":35284,"44400":35336,"44401":35330,"44402":35331,"44403":35998,"44404":36000,"44405":36212,"44406":36211,"44407":36276,"44408":36557,"44409":36556,"44410":36848,"44411":36838,"44412":36834,"44413":36842,"44414":36837,"44449":36845,"44450":36843,"44451":36836,"44452":36840,"44453":37066,"44454":37070,"44455":37057,"44456":37059,"44457":37195,"44458":37194,"44459":37325,"44460":38274,"44461":38480,"44462":38475,"44463":38476,"44464":38477,"44465":38754,"44466":38761,"44467":38859,"44468":38893,"44469":38899,"44470":38913,"44471":39080,"44472":39131,"44473":39135,"44474":39318,"44475":39321,"44476":20056,"44477":20147,"44478":20492,"44479":20493,"44480":20515,"44481":20463,"44482":20518,"44483":20517,"44484":20472,"44485":20521,"44486":20502,"44487":20486,"44488":20540,"44489":20511,"44490":20506,"44491":20498,"44492":20497,"44493":20474,"44494":20480,"44495":20500,"44496":20520,"44497":20465,"44498":20513,"44499":20491,"44500":20505,"44501":20504,"44502":20467,"44503":20462,"44504":20525,"44505":20522,"44506":20478,"44507":20523,"44508":20489,"44509":20860,"44510":20900,"44511":20901,"44512":20898,"44513":20941,"44514":20940,"44515":20934,"44516":20939,"44517":21078,"44518":21084,"44519":21076,"44520":21083,"44521":21085,"44522":21290,"44523":21375,"44524":21407,"44525":21405,"44526":21471,"44527":21736,"44528":21776,"44529":21761,"44530":21815,"44531":21756,"44532":21733,"44533":21746,"44534":21766,"44535":21754,"44536":21780,"44537":21737,"44538":21741,"44539":21729,"44540":21769,"44541":21742,"44542":21738,"44608":21734,"44609":21799,"44610":21767,"44611":21757,"44612":21775,"44613":22275,"44614":22276,"44615":22466,"44616":22484,"44617":22475,"44618":22467,"44619":22537,"44620":22799,"44621":22871,"44622":22872,"44623":22874,"44624":23057,"44625":23064,"44626":23068,"44627":23071,"44628":23067,"44629":23059,"44630":23020,"44631":23072,"44632":23075,"44633":23081,"44634":23077,"44635":23052,"44636":23049,"44637":23403,"44638":23640,"44639":23472,"44640":23475,"44641":23478,"44642":23476,"44643":23470,"44644":23477,"44645":23481,"44646":23480,"44647":23556,"44648":23633,"44649":23637,"44650":23632,"44651":23789,"44652":23805,"44653":23803,"44654":23786,"44655":23784,"44656":23792,"44657":23798,"44658":23809,"44659":23796,"44660":24046,"44661":24109,"44662":24107,"44663":24235,"44664":24237,"44665":24231,"44666":24369,"44667":24466,"44668":24465,"44669":24464,"44670":24665,"44705":24675,"44706":24677,"44707":24656,"44708":24661,"44709":24685,"44710":24681,"44711":24687,"44712":24708,"44713":24735,"44714":24730,"44715":24717,"44716":24724,"44717":24716,"44718":24709,"44719":24726,"44720":25159,"44721":25331,"44722":25352,"44723":25343,"44724":25422,"44725":25406,"44726":25391,"44727":25429,"44728":25410,"44729":25414,"44730":25423,"44731":25417,"44732":25402,"44733":25424,"44734":25405,"44735":25386,"44736":25387,"44737":25384,"44738":25421,"44739":25420,"44740":25928,"44741":25929,"44742":26009,"44743":26049,"44744":26053,"44745":26178,"44746":26185,"44747":26191,"44748":26179,"44749":26194,"44750":26188,"44751":26181,"44752":26177,"44753":26360,"44754":26388,"44755":26389,"44756":26391,"44757":26657,"44758":26680,"44759":26696,"44760":26694,"44761":26707,"44762":26681,"44763":26690,"44764":26708,"44765":26665,"44766":26803,"44767":26647,"44768":26700,"44769":26705,"44770":26685,"44771":26612,"44772":26704,"44773":26688,"44774":26684,"44775":26691,"44776":26666,"44777":26693,"44778":26643,"44779":26648,"44780":26689,"44781":27530,"44782":27529,"44783":27575,"44784":27683,"44785":27687,"44786":27688,"44787":27686,"44788":27684,"44789":27888,"44790":28010,"44791":28053,"44792":28040,"44793":28039,"44794":28006,"44795":28024,"44796":28023,"44797":27993,"44798":28051,"44864":28012,"44865":28041,"44866":28014,"44867":27994,"44868":28020,"44869":28009,"44870":28044,"44871":28042,"44872":28025,"44873":28037,"44874":28005,"44875":28052,"44876":28874,"44877":28888,"44878":28900,"44879":28889,"44880":28872,"44881":28879,"44882":29241,"44883":29305,"44884":29436,"44885":29433,"44886":29437,"44887":29432,"44888":29431,"44889":29574,"44890":29677,"44891":29705,"44892":29678,"44893":29664,"44894":29674,"44895":29662,"44896":30036,"44897":30045,"44898":30044,"44899":30042,"44900":30041,"44901":30142,"44902":30149,"44903":30151,"44904":30130,"44905":30131,"44906":30141,"44907":30140,"44908":30137,"44909":30146,"44910":30136,"44911":30347,"44912":30384,"44913":30410,"44914":30413,"44915":30414,"44916":30505,"44917":30495,"44918":30496,"44919":30504,"44920":30697,"44921":30768,"44922":30759,"44923":30776,"44924":30749,"44925":30772,"44926":30775,"44961":30757,"44962":30765,"44963":30752,"44964":30751,"44965":30770,"44966":31061,"44967":31056,"44968":31072,"44969":31071,"44970":31062,"44971":31070,"44972":31069,"44973":31063,"44974":31066,"44975":31204,"44976":31203,"44977":31207,"44978":31199,"44979":31206,"44980":31209,"44981":31192,"44982":31364,"44983":31368,"44984":31449,"44985":31494,"44986":31505,"44987":31881,"44988":32033,"44989":32023,"44990":32011,"44991":32010,"44992":32032,"44993":32034,"44994":32020,"44995":32016,"44996":32021,"44997":32026,"44998":32028,"44999":32013,"45000":32025,"45001":32027,"45002":32570,"45003":32607,"45004":32660,"45005":32709,"45006":32705,"45007":32774,"45008":32792,"45009":32789,"45010":32793,"45011":32791,"45012":32829,"45013":32831,"45014":33009,"45015":33026,"45016":33008,"45017":33029,"45018":33005,"45019":33012,"45020":33030,"45021":33016,"45022":33011,"45023":33032,"45024":33021,"45025":33034,"45026":33020,"45027":33007,"45028":33261,"45029":33260,"45030":33280,"45031":33296,"45032":33322,"45033":33323,"45034":33320,"45035":33324,"45036":33467,"45037":33579,"45038":33618,"45039":33620,"45040":33610,"45041":33592,"45042":33616,"45043":33609,"45044":33589,"45045":33588,"45046":33615,"45047":33586,"45048":33593,"45049":33590,"45050":33559,"45051":33600,"45052":33585,"45053":33576,"45054":33603,"45120":34388,"45121":34442,"45122":34474,"45123":34451,"45124":34468,"45125":34473,"45126":34444,"45127":34467,"45128":34460,"45129":34928,"45130":34935,"45131":34945,"45132":34946,"45133":34941,"45134":34937,"45135":35352,"45136":35344,"45137":35342,"45138":35340,"45139":35349,"45140":35338,"45141":35351,"45142":35347,"45143":35350,"45144":35343,"45145":35345,"45146":35912,"45147":35962,"45148":35961,"45149":36001,"45150":36002,"45151":36215,"45152":36524,"45153":36562,"45154":36564,"45155":36559,"45156":36785,"45157":36865,"45158":36870,"45159":36855,"45160":36864,"45161":36858,"45162":36852,"45163":36867,"45164":36861,"45165":36869,"45166":36856,"45167":37013,"45168":37089,"45169":37085,"45170":37090,"45171":37202,"45172":37197,"45173":37196,"45174":37336,"45175":37341,"45176":37335,"45177":37340,"45178":37337,"45179":38275,"45180":38498,"45181":38499,"45182":38497,"45217":38491,"45218":38493,"45219":38500,"45220":38488,"45221":38494,"45222":38587,"45223":39138,"45224":39340,"45225":39592,"45226":39640,"45227":39717,"45228":39730,"45229":39740,"45230":20094,"45231":20602,"45232":20605,"45233":20572,"45234":20551,"45235":20547,"45236":20556,"45237":20570,"45238":20553,"45239":20581,"45240":20598,"45241":20558,"45242":20565,"45243":20597,"45244":20596,"45245":20599,"45246":20559,"45247":20495,"45248":20591,"45249":20589,"45250":20828,"45251":20885,"45252":20976,"45253":21098,"45254":21103,"45255":21202,"45256":21209,"45257":21208,"45258":21205,"45259":21264,"45260":21263,"45261":21273,"45262":21311,"45263":21312,"45264":21310,"45265":21443,"45266":26364,"45267":21830,"45268":21866,"45269":21862,"45270":21828,"45271":21854,"45272":21857,"45273":21827,"45274":21834,"45275":21809,"45276":21846,"45277":21839,"45278":21845,"45279":21807,"45280":21860,"45281":21816,"45282":21806,"45283":21852,"45284":21804,"45285":21859,"45286":21811,"45287":21825,"45288":21847,"45289":22280,"45290":22283,"45291":22281,"45292":22495,"45293":22533,"45294":22538,"45295":22534,"45296":22496,"45297":22500,"45298":22522,"45299":22530,"45300":22581,"45301":22519,"45302":22521,"45303":22816,"45304":22882,"45305":23094,"45306":23105,"45307":23113,"45308":23142,"45309":23146,"45310":23104,"45376":23100,"45377":23138,"45378":23130,"45379":23110,"45380":23114,"45381":23408,"45382":23495,"45383":23493,"45384":23492,"45385":23490,"45386":23487,"45387":23494,"45388":23561,"45389":23560,"45390":23559,"45391":23648,"45392":23644,"45393":23645,"45394":23815,"45395":23814,"45396":23822,"45397":23835,"45398":23830,"45399":23842,"45400":23825,"45401":23849,"45402":23828,"45403":23833,"45404":23844,"45405":23847,"45406":23831,"45407":24034,"45408":24120,"45409":24118,"45410":24115,"45411":24119,"45412":24247,"45413":24248,"45414":24246,"45415":24245,"45416":24254,"45417":24373,"45418":24375,"45419":24407,"45420":24428,"45421":24425,"45422":24427,"45423":24471,"45424":24473,"45425":24478,"45426":24472,"45427":24481,"45428":24480,"45429":24476,"45430":24703,"45431":24739,"45432":24713,"45433":24736,"45434":24744,"45435":24779,"45436":24756,"45437":24806,"45438":24765,"45473":24773,"45474":24763,"45475":24757,"45476":24796,"45477":24764,"45478":24792,"45479":24789,"45480":24774,"45481":24799,"45482":24760,"45483":24794,"45484":24775,"45485":25114,"45486":25115,"45487":25160,"45488":25504,"45489":25511,"45490":25458,"45491":25494,"45492":25506,"45493":25509,"45494":25463,"45495":25447,"45496":25496,"45497":25514,"45498":25457,"45499":25513,"45500":25481,"45501":25475,"45502":25499,"45503":25451,"45504":25512,"45505":25476,"45506":25480,"45507":25497,"45508":25505,"45509":25516,"45510":25490,"45511":25487,"45512":25472,"45513":25467,"45514":25449,"45515":25448,"45516":25466,"45517":25949,"45518":25942,"45519":25937,"45520":25945,"45521":25943,"45522":21855,"45523":25935,"45524":25944,"45525":25941,"45526":25940,"45527":26012,"45528":26011,"45529":26028,"45530":26063,"45531":26059,"45532":26060,"45533":26062,"45534":26205,"45535":26202,"45536":26212,"45537":26216,"45538":26214,"45539":26206,"45540":26361,"45541":21207,"45542":26395,"45543":26753,"45544":26799,"45545":26786,"45546":26771,"45547":26805,"45548":26751,"45549":26742,"45550":26801,"45551":26791,"45552":26775,"45553":26800,"45554":26755,"45555":26820,"45556":26797,"45557":26758,"45558":26757,"45559":26772,"45560":26781,"45561":26792,"45562":26783,"45563":26785,"45564":26754,"45565":27442,"45566":27578,"45632":27627,"45633":27628,"45634":27691,"45635":28046,"45636":28092,"45637":28147,"45638":28121,"45639":28082,"45640":28129,"45641":28108,"45642":28132,"45643":28155,"45644":28154,"45645":28165,"45646":28103,"45647":28107,"45648":28079,"45649":28113,"45650":28078,"45651":28126,"45652":28153,"45653":28088,"45654":28151,"45655":28149,"45656":28101,"45657":28114,"45658":28186,"45659":28085,"45660":28122,"45661":28139,"45662":28120,"45663":28138,"45664":28145,"45665":28142,"45666":28136,"45667":28102,"45668":28100,"45669":28074,"45670":28140,"45671":28095,"45672":28134,"45673":28921,"45674":28937,"45675":28938,"45676":28925,"45677":28911,"45678":29245,"45679":29309,"45680":29313,"45681":29468,"45682":29467,"45683":29462,"45684":29459,"45685":29465,"45686":29575,"45687":29701,"45688":29706,"45689":29699,"45690":29702,"45691":29694,"45692":29709,"45693":29920,"45694":29942,"45729":29943,"45730":29980,"45731":29986,"45732":30053,"45733":30054,"45734":30050,"45735":30064,"45736":30095,"45737":30164,"45738":30165,"45739":30133,"45740":30154,"45741":30157,"45742":30350,"45743":30420,"45744":30418,"45745":30427,"45746":30519,"45747":30526,"45748":30524,"45749":30518,"45750":30520,"45751":30522,"45752":30827,"45753":30787,"45754":30798,"45755":31077,"45756":31080,"45757":31085,"45758":31227,"45759":31378,"45760":31381,"45761":31520,"45762":31528,"45763":31515,"45764":31532,"45765":31526,"45766":31513,"45767":31518,"45768":31534,"45769":31890,"45770":31895,"45771":31893,"45772":32070,"45773":32067,"45774":32113,"45775":32046,"45776":32057,"45777":32060,"45778":32064,"45779":32048,"45780":32051,"45781":32068,"45782":32047,"45783":32066,"45784":32050,"45785":32049,"45786":32573,"45787":32670,"45788":32666,"45789":32716,"45790":32718,"45791":32722,"45792":32796,"45793":32842,"45794":32838,"45795":33071,"45796":33046,"45797":33059,"45798":33067,"45799":33065,"45800":33072,"45801":33060,"45802":33282,"45803":33333,"45804":33335,"45805":33334,"45806":33337,"45807":33678,"45808":33694,"45809":33688,"45810":33656,"45811":33698,"45812":33686,"45813":33725,"45814":33707,"45815":33682,"45816":33674,"45817":33683,"45818":33673,"45819":33696,"45820":33655,"45821":33659,"45822":33660,"45888":33670,"45889":33703,"45890":34389,"45891":24426,"45892":34503,"45893":34496,"45894":34486,"45895":34500,"45896":34485,"45897":34502,"45898":34507,"45899":34481,"45900":34479,"45901":34505,"45902":34899,"45903":34974,"45904":34952,"45905":34987,"45906":34962,"45907":34966,"45908":34957,"45909":34955,"45910":35219,"45911":35215,"45912":35370,"45913":35357,"45914":35363,"45915":35365,"45916":35377,"45917":35373,"45918":35359,"45919":35355,"45920":35362,"45921":35913,"45922":35930,"45923":36009,"45924":36012,"45925":36011,"45926":36008,"45927":36010,"45928":36007,"45929":36199,"45930":36198,"45931":36286,"45932":36282,"45933":36571,"45934":36575,"45935":36889,"45936":36877,"45937":36890,"45938":36887,"45939":36899,"45940":36895,"45941":36893,"45942":36880,"45943":36885,"45944":36894,"45945":36896,"45946":36879,"45947":36898,"45948":36886,"45949":36891,"45950":36884,"45985":37096,"45986":37101,"45987":37117,"45988":37207,"45989":37326,"45990":37365,"45991":37350,"45992":37347,"45993":37351,"45994":37357,"45995":37353,"45996":38281,"45997":38506,"45998":38517,"45999":38515,"46000":38520,"46001":38512,"46002":38516,"46003":38518,"46004":38519,"46005":38508,"46006":38592,"46007":38634,"46008":38633,"46009":31456,"46010":31455,"46011":38914,"46012":38915,"46013":39770,"46014":40165,"46015":40565,"46016":40575,"46017":40613,"46018":40635,"46019":20642,"46020":20621,"46021":20613,"46022":20633,"46023":20625,"46024":20608,"46025":20630,"46026":20632,"46027":20634,"46028":26368,"46029":20977,"46030":21106,"46031":21108,"46032":21109,"46033":21097,"46034":21214,"46035":21213,"46036":21211,"46037":21338,"46038":21413,"46039":21883,"46040":21888,"46041":21927,"46042":21884,"46043":21898,"46044":21917,"46045":21912,"46046":21890,"46047":21916,"46048":21930,"46049":21908,"46050":21895,"46051":21899,"46052":21891,"46053":21939,"46054":21934,"46055":21919,"46056":21822,"46057":21938,"46058":21914,"46059":21947,"46060":21932,"46061":21937,"46062":21886,"46063":21897,"46064":21931,"46065":21913,"46066":22285,"46067":22575,"46068":22570,"46069":22580,"46070":22564,"46071":22576,"46072":22577,"46073":22561,"46074":22557,"46075":22560,"46076":22777,"46077":22778,"46078":22880,"46144":23159,"46145":23194,"46146":23167,"46147":23186,"46148":23195,"46149":23207,"46150":23411,"46151":23409,"46152":23506,"46153":23500,"46154":23507,"46155":23504,"46156":23562,"46157":23563,"46158":23601,"46159":23884,"46160":23888,"46161":23860,"46162":23879,"46163":24061,"46164":24133,"46165":24125,"46166":24128,"46167":24131,"46168":24190,"46169":24266,"46170":24257,"46171":24258,"46172":24260,"46173":24380,"46174":24429,"46175":24489,"46176":24490,"46177":24488,"46178":24785,"46179":24801,"46180":24754,"46181":24758,"46182":24800,"46183":24860,"46184":24867,"46185":24826,"46186":24853,"46187":24816,"46188":24827,"46189":24820,"46190":24936,"46191":24817,"46192":24846,"46193":24822,"46194":24841,"46195":24832,"46196":24850,"46197":25119,"46198":25161,"46199":25507,"46200":25484,"46201":25551,"46202":25536,"46203":25577,"46204":25545,"46205":25542,"46206":25549,"46241":25554,"46242":25571,"46243":25552,"46244":25569,"46245":25558,"46246":25581,"46247":25582,"46248":25462,"46249":25588,"46250":25578,"46251":25563,"46252":25682,"46253":25562,"46254":25593,"46255":25950,"46256":25958,"46257":25954,"46258":25955,"46259":26001,"46260":26000,"46261":26031,"46262":26222,"46263":26224,"46264":26228,"46265":26230,"46266":26223,"46267":26257,"46268":26234,"46269":26238,"46270":26231,"46271":26366,"46272":26367,"46273":26399,"46274":26397,"46275":26874,"46276":26837,"46277":26848,"46278":26840,"46279":26839,"46280":26885,"46281":26847,"46282":26869,"46283":26862,"46284":26855,"46285":26873,"46286":26834,"46287":26866,"46288":26851,"46289":26827,"46290":26829,"46291":26893,"46292":26898,"46293":26894,"46294":26825,"46295":26842,"46296":26990,"46297":26875,"46298":27454,"46299":27450,"46300":27453,"46301":27544,"46302":27542,"46303":27580,"46304":27631,"46305":27694,"46306":27695,"46307":27692,"46308":28207,"46309":28216,"46310":28244,"46311":28193,"46312":28210,"46313":28263,"46314":28234,"46315":28192,"46316":28197,"46317":28195,"46318":28187,"46319":28251,"46320":28248,"46321":28196,"46322":28246,"46323":28270,"46324":28205,"46325":28198,"46326":28271,"46327":28212,"46328":28237,"46329":28218,"46330":28204,"46331":28227,"46332":28189,"46333":28222,"46334":28363,"46400":28297,"46401":28185,"46402":28238,"46403":28259,"46404":28228,"46405":28274,"46406":28265,"46407":28255,"46408":28953,"46409":28954,"46410":28966,"46411":28976,"46412":28961,"46413":28982,"46414":29038,"46415":28956,"46416":29260,"46417":29316,"46418":29312,"46419":29494,"46420":29477,"46421":29492,"46422":29481,"46423":29754,"46424":29738,"46425":29747,"46426":29730,"46427":29733,"46428":29749,"46429":29750,"46430":29748,"46431":29743,"46432":29723,"46433":29734,"46434":29736,"46435":29989,"46436":29990,"46437":30059,"46438":30058,"46439":30178,"46440":30171,"46441":30179,"46442":30169,"46443":30168,"46444":30174,"46445":30176,"46446":30331,"46447":30332,"46448":30358,"46449":30355,"46450":30388,"46451":30428,"46452":30543,"46453":30701,"46454":30813,"46455":30828,"46456":30831,"46457":31245,"46458":31240,"46459":31243,"46460":31237,"46461":31232,"46462":31384,"46497":31383,"46498":31382,"46499":31461,"46500":31459,"46501":31561,"46502":31574,"46503":31558,"46504":31568,"46505":31570,"46506":31572,"46507":31565,"46508":31563,"46509":31567,"46510":31569,"46511":31903,"46512":31909,"46513":32094,"46514":32080,"46515":32104,"46516":32085,"46517":32043,"46518":32110,"46519":32114,"46520":32097,"46521":32102,"46522":32098,"46523":32112,"46524":32115,"46525":21892,"46526":32724,"46527":32725,"46528":32779,"46529":32850,"46530":32901,"46531":33109,"46532":33108,"46533":33099,"46534":33105,"46535":33102,"46536":33081,"46537":33094,"46538":33086,"46539":33100,"46540":33107,"46541":33140,"46542":33298,"46543":33308,"46544":33769,"46545":33795,"46546":33784,"46547":33805,"46548":33760,"46549":33733,"46550":33803,"46551":33729,"46552":33775,"46553":33777,"46554":33780,"46555":33879,"46556":33802,"46557":33776,"46558":33804,"46559":33740,"46560":33789,"46561":33778,"46562":33738,"46563":33848,"46564":33806,"46565":33796,"46566":33756,"46567":33799,"46568":33748,"46569":33759,"46570":34395,"46571":34527,"46572":34521,"46573":34541,"46574":34516,"46575":34523,"46576":34532,"46577":34512,"46578":34526,"46579":34903,"46580":35009,"46581":35010,"46582":34993,"46583":35203,"46584":35222,"46585":35387,"46586":35424,"46587":35413,"46588":35422,"46589":35388,"46590":35393,"46656":35412,"46657":35419,"46658":35408,"46659":35398,"46660":35380,"46661":35386,"46662":35382,"46663":35414,"46664":35937,"46665":35970,"46666":36015,"46667":36028,"46668":36019,"46669":36029,"46670":36033,"46671":36027,"46672":36032,"46673":36020,"46674":36023,"46675":36022,"46676":36031,"46677":36024,"46678":36234,"46679":36229,"46680":36225,"46681":36302,"46682":36317,"46683":36299,"46684":36314,"46685":36305,"46686":36300,"46687":36315,"46688":36294,"46689":36603,"46690":36600,"46691":36604,"46692":36764,"46693":36910,"46694":36917,"46695":36913,"46696":36920,"46697":36914,"46698":36918,"46699":37122,"46700":37109,"46701":37129,"46702":37118,"46703":37219,"46704":37221,"46705":37327,"46706":37396,"46707":37397,"46708":37411,"46709":37385,"46710":37406,"46711":37389,"46712":37392,"46713":37383,"46714":37393,"46715":38292,"46716":38287,"46717":38283,"46718":38289,"46753":38291,"46754":38290,"46755":38286,"46756":38538,"46757":38542,"46758":38539,"46759":38525,"46760":38533,"46761":38534,"46762":38541,"46763":38514,"46764":38532,"46765":38593,"46766":38597,"46767":38596,"46768":38598,"46769":38599,"46770":38639,"46771":38642,"46772":38860,"46773":38917,"46774":38918,"46775":38920,"46776":39143,"46777":39146,"46778":39151,"46779":39145,"46780":39154,"46781":39149,"46782":39342,"46783":39341,"46784":40643,"46785":40653,"46786":40657,"46787":20098,"46788":20653,"46789":20661,"46790":20658,"46791":20659,"46792":20677,"46793":20670,"46794":20652,"46795":20663,"46796":20667,"46797":20655,"46798":20679,"46799":21119,"46800":21111,"46801":21117,"46802":21215,"46803":21222,"46804":21220,"46805":21218,"46806":21219,"46807":21295,"46808":21983,"46809":21992,"46810":21971,"46811":21990,"46812":21966,"46813":21980,"46814":21959,"46815":21969,"46816":21987,"46817":21988,"46818":21999,"46819":21978,"46820":21985,"46821":21957,"46822":21958,"46823":21989,"46824":21961,"46825":22290,"46826":22291,"46827":22622,"46828":22609,"46829":22616,"46830":22615,"46831":22618,"46832":22612,"46833":22635,"46834":22604,"46835":22637,"46836":22602,"46837":22626,"46838":22610,"46839":22603,"46840":22887,"46841":23233,"46842":23241,"46843":23244,"46844":23230,"46845":23229,"46846":23228,"46912":23219,"46913":23234,"46914":23218,"46915":23913,"46916":23919,"46917":24140,"46918":24185,"46919":24265,"46920":24264,"46921":24338,"46922":24409,"46923":24492,"46924":24494,"46925":24858,"46926":24847,"46927":24904,"46928":24863,"46929":24819,"46930":24859,"46931":24825,"46932":24833,"46933":24840,"46934":24910,"46935":24908,"46936":24900,"46937":24909,"46938":24894,"46939":24884,"46940":24871,"46941":24845,"46942":24838,"46943":24887,"46944":25121,"46945":25122,"46946":25619,"46947":25662,"46948":25630,"46949":25642,"46950":25645,"46951":25661,"46952":25644,"46953":25615,"46954":25628,"46955":25620,"46956":25613,"46957":25654,"46958":25622,"46959":25623,"46960":25606,"46961":25964,"46962":26015,"46963":26032,"46964":26263,"46965":26249,"46966":26247,"46967":26248,"46968":26262,"46969":26244,"46970":26264,"46971":26253,"46972":26371,"46973":27028,"46974":26989,"47009":26970,"47010":26999,"47011":26976,"47012":26964,"47013":26997,"47014":26928,"47015":27010,"47016":26954,"47017":26984,"47018":26987,"47019":26974,"47020":26963,"47021":27001,"47022":27014,"47023":26973,"47024":26979,"47025":26971,"47026":27463,"47027":27506,"47028":27584,"47029":27583,"47030":27603,"47031":27645,"47032":28322,"47033":28335,"47034":28371,"47035":28342,"47036":28354,"47037":28304,"47038":28317,"47039":28359,"47040":28357,"47041":28325,"47042":28312,"47043":28348,"47044":28346,"47045":28331,"47046":28369,"47047":28310,"47048":28316,"47049":28356,"47050":28372,"47051":28330,"47052":28327,"47053":28340,"47054":29006,"47055":29017,"47056":29033,"47057":29028,"47058":29001,"47059":29031,"47060":29020,"47061":29036,"47062":29030,"47063":29004,"47064":29029,"47065":29022,"47066":28998,"47067":29032,"47068":29014,"47069":29242,"47070":29266,"47071":29495,"47072":29509,"47073":29503,"47074":29502,"47075":29807,"47076":29786,"47077":29781,"47078":29791,"47079":29790,"47080":29761,"47081":29759,"47082":29785,"47083":29787,"47084":29788,"47085":30070,"47086":30072,"47087":30208,"47088":30192,"47089":30209,"47090":30194,"47091":30193,"47092":30202,"47093":30207,"47094":30196,"47095":30195,"47096":30430,"47097":30431,"47098":30555,"47099":30571,"47100":30566,"47101":30558,"47102":30563,"47168":30585,"47169":30570,"47170":30572,"47171":30556,"47172":30565,"47173":30568,"47174":30562,"47175":30702,"47176":30862,"47177":30896,"47178":30871,"47179":30872,"47180":30860,"47181":30857,"47182":30844,"47183":30865,"47184":30867,"47185":30847,"47186":31098,"47187":31103,"47188":31105,"47189":33836,"47190":31165,"47191":31260,"47192":31258,"47193":31264,"47194":31252,"47195":31263,"47196":31262,"47197":31391,"47198":31392,"47199":31607,"47200":31680,"47201":31584,"47202":31598,"47203":31591,"47204":31921,"47205":31923,"47206":31925,"47207":32147,"47208":32121,"47209":32145,"47210":32129,"47211":32143,"47212":32091,"47213":32622,"47214":32617,"47215":32618,"47216":32626,"47217":32681,"47218":32680,"47219":32676,"47220":32854,"47221":32856,"47222":32902,"47223":32900,"47224":33137,"47225":33136,"47226":33144,"47227":33125,"47228":33134,"47229":33139,"47230":33131,"47265":33145,"47266":33146,"47267":33126,"47268":33285,"47269":33351,"47270":33922,"47271":33911,"47272":33853,"47273":33841,"47274":33909,"47275":33894,"47276":33899,"47277":33865,"47278":33900,"47279":33883,"47280":33852,"47281":33845,"47282":33889,"47283":33891,"47284":33897,"47285":33901,"47286":33862,"47287":34398,"47288":34396,"47289":34399,"47290":34553,"47291":34579,"47292":34568,"47293":34567,"47294":34560,"47295":34558,"47296":34555,"47297":34562,"47298":34563,"47299":34566,"47300":34570,"47301":34905,"47302":35039,"47303":35028,"47304":35033,"47305":35036,"47306":35032,"47307":35037,"47308":35041,"47309":35018,"47310":35029,"47311":35026,"47312":35228,"47313":35299,"47314":35435,"47315":35442,"47316":35443,"47317":35430,"47318":35433,"47319":35440,"47320":35463,"47321":35452,"47322":35427,"47323":35488,"47324":35441,"47325":35461,"47326":35437,"47327":35426,"47328":35438,"47329":35436,"47330":35449,"47331":35451,"47332":35390,"47333":35432,"47334":35938,"47335":35978,"47336":35977,"47337":36042,"47338":36039,"47339":36040,"47340":36036,"47341":36018,"47342":36035,"47343":36034,"47344":36037,"47345":36321,"47346":36319,"47347":36328,"47348":36335,"47349":36339,"47350":36346,"47351":36330,"47352":36324,"47353":36326,"47354":36530,"47355":36611,"47356":36617,"47357":36606,"47358":36618,"47424":36767,"47425":36786,"47426":36939,"47427":36938,"47428":36947,"47429":36930,"47430":36948,"47431":36924,"47432":36949,"47433":36944,"47434":36935,"47435":36943,"47436":36942,"47437":36941,"47438":36945,"47439":36926,"47440":36929,"47441":37138,"47442":37143,"47443":37228,"47444":37226,"47445":37225,"47446":37321,"47447":37431,"47448":37463,"47449":37432,"47450":37437,"47451":37440,"47452":37438,"47453":37467,"47454":37451,"47455":37476,"47456":37457,"47457":37428,"47458":37449,"47459":37453,"47460":37445,"47461":37433,"47462":37439,"47463":37466,"47464":38296,"47465":38552,"47466":38548,"47467":38549,"47468":38605,"47469":38603,"47470":38601,"47471":38602,"47472":38647,"47473":38651,"47474":38649,"47475":38646,"47476":38742,"47477":38772,"47478":38774,"47479":38928,"47480":38929,"47481":38931,"47482":38922,"47483":38930,"47484":38924,"47485":39164,"47486":39156,"47521":39165,"47522":39166,"47523":39347,"47524":39345,"47525":39348,"47526":39649,"47527":40169,"47528":40578,"47529":40718,"47530":40723,"47531":40736,"47532":20711,"47533":20718,"47534":20709,"47535":20694,"47536":20717,"47537":20698,"47538":20693,"47539":20687,"47540":20689,"47541":20721,"47542":20686,"47543":20713,"47544":20834,"47545":20979,"47546":21123,"47547":21122,"47548":21297,"47549":21421,"47550":22014,"47551":22016,"47552":22043,"47553":22039,"47554":22013,"47555":22036,"47556":22022,"47557":22025,"47558":22029,"47559":22030,"47560":22007,"47561":22038,"47562":22047,"47563":22024,"47564":22032,"47565":22006,"47566":22296,"47567":22294,"47568":22645,"47569":22654,"47570":22659,"47571":22675,"47572":22666,"47573":22649,"47574":22661,"47575":22653,"47576":22781,"47577":22821,"47578":22818,"47579":22820,"47580":22890,"47581":22889,"47582":23265,"47583":23270,"47584":23273,"47585":23255,"47586":23254,"47587":23256,"47588":23267,"47589":23413,"47590":23518,"47591":23527,"47592":23521,"47593":23525,"47594":23526,"47595":23528,"47596":23522,"47597":23524,"47598":23519,"47599":23565,"47600":23650,"47601":23940,"47602":23943,"47603":24155,"47604":24163,"47605":24149,"47606":24151,"47607":24148,"47608":24275,"47609":24278,"47610":24330,"47611":24390,"47612":24432,"47613":24505,"47614":24903,"47680":24895,"47681":24907,"47682":24951,"47683":24930,"47684":24931,"47685":24927,"47686":24922,"47687":24920,"47688":24949,"47689":25130,"47690":25735,"47691":25688,"47692":25684,"47693":25764,"47694":25720,"47695":25695,"47696":25722,"47697":25681,"47698":25703,"47699":25652,"47700":25709,"47701":25723,"47702":25970,"47703":26017,"47704":26071,"47705":26070,"47706":26274,"47707":26280,"47708":26269,"47709":27036,"47710":27048,"47711":27029,"47712":27073,"47713":27054,"47714":27091,"47715":27083,"47716":27035,"47717":27063,"47718":27067,"47719":27051,"47720":27060,"47721":27088,"47722":27085,"47723":27053,"47724":27084,"47725":27046,"47726":27075,"47727":27043,"47728":27465,"47729":27468,"47730":27699,"47731":28467,"47732":28436,"47733":28414,"47734":28435,"47735":28404,"47736":28457,"47737":28478,"47738":28448,"47739":28460,"47740":28431,"47741":28418,"47742":28450,"47777":28415,"47778":28399,"47779":28422,"47780":28465,"47781":28472,"47782":28466,"47783":28451,"47784":28437,"47785":28459,"47786":28463,"47787":28552,"47788":28458,"47789":28396,"47790":28417,"47791":28402,"47792":28364,"47793":28407,"47794":29076,"47795":29081,"47796":29053,"47797":29066,"47798":29060,"47799":29074,"47800":29246,"47801":29330,"47802":29334,"47803":29508,"47804":29520,"47805":29796,"47806":29795,"47807":29802,"47808":29808,"47809":29805,"47810":29956,"47811":30097,"47812":30247,"47813":30221,"47814":30219,"47815":30217,"47816":30227,"47817":30433,"47818":30435,"47819":30596,"47820":30589,"47821":30591,"47822":30561,"47823":30913,"47824":30879,"47825":30887,"47826":30899,"47827":30889,"47828":30883,"47829":31118,"47830":31119,"47831":31117,"47832":31278,"47833":31281,"47834":31402,"47835":31401,"47836":31469,"47837":31471,"47838":31649,"47839":31637,"47840":31627,"47841":31605,"47842":31639,"47843":31645,"47844":31636,"47845":31631,"47846":31672,"47847":31623,"47848":31620,"47849":31929,"47850":31933,"47851":31934,"47852":32187,"47853":32176,"47854":32156,"47855":32189,"47856":32190,"47857":32160,"47858":32202,"47859":32180,"47860":32178,"47861":32177,"47862":32186,"47863":32162,"47864":32191,"47865":32181,"47866":32184,"47867":32173,"47868":32210,"47869":32199,"47870":32172,"47936":32624,"47937":32736,"47938":32737,"47939":32735,"47940":32862,"47941":32858,"47942":32903,"47943":33104,"47944":33152,"47945":33167,"47946":33160,"47947":33162,"47948":33151,"47949":33154,"47950":33255,"47951":33274,"47952":33287,"47953":33300,"47954":33310,"47955":33355,"47956":33993,"47957":33983,"47958":33990,"47959":33988,"47960":33945,"47961":33950,"47962":33970,"47963":33948,"47964":33995,"47965":33976,"47966":33984,"47967":34003,"47968":33936,"47969":33980,"47970":34001,"47971":33994,"47972":34623,"47973":34588,"47974":34619,"47975":34594,"47976":34597,"47977":34612,"47978":34584,"47979":34645,"47980":34615,"47981":34601,"47982":35059,"47983":35074,"47984":35060,"47985":35065,"47986":35064,"47987":35069,"47988":35048,"47989":35098,"47990":35055,"47991":35494,"47992":35468,"47993":35486,"47994":35491,"47995":35469,"47996":35489,"47997":35475,"47998":35492,"48033":35498,"48034":35493,"48035":35496,"48036":35480,"48037":35473,"48038":35482,"48039":35495,"48040":35946,"48041":35981,"48042":35980,"48043":36051,"48044":36049,"48045":36050,"48046":36203,"48047":36249,"48048":36245,"48049":36348,"48050":36628,"48051":36626,"48052":36629,"48053":36627,"48054":36771,"48055":36960,"48056":36952,"48057":36956,"48058":36963,"48059":36953,"48060":36958,"48061":36962,"48062":36957,"48063":36955,"48064":37145,"48065":37144,"48066":37150,"48067":37237,"48068":37240,"48069":37239,"48070":37236,"48071":37496,"48072":37504,"48073":37509,"48074":37528,"48075":37526,"48076":37499,"48077":37523,"48078":37532,"48079":37544,"48080":37500,"48081":37521,"48082":38305,"48083":38312,"48084":38313,"48085":38307,"48086":38309,"48087":38308,"48088":38553,"48089":38556,"48090":38555,"48091":38604,"48092":38610,"48093":38656,"48094":38780,"48095":38789,"48096":38902,"48097":38935,"48098":38936,"48099":39087,"48100":39089,"48101":39171,"48102":39173,"48103":39180,"48104":39177,"48105":39361,"48106":39599,"48107":39600,"48108":39654,"48109":39745,"48110":39746,"48111":40180,"48112":40182,"48113":40179,"48114":40636,"48115":40763,"48116":40778,"48117":20740,"48118":20736,"48119":20731,"48120":20725,"48121":20729,"48122":20738,"48123":20744,"48124":20745,"48125":20741,"48126":20956,"48192":21127,"48193":21128,"48194":21129,"48195":21133,"48196":21130,"48197":21232,"48198":21426,"48199":22062,"48200":22075,"48201":22073,"48202":22066,"48203":22079,"48204":22068,"48205":22057,"48206":22099,"48207":22094,"48208":22103,"48209":22132,"48210":22070,"48211":22063,"48212":22064,"48213":22656,"48214":22687,"48215":22686,"48216":22707,"48217":22684,"48218":22702,"48219":22697,"48220":22694,"48221":22893,"48222":23305,"48223":23291,"48224":23307,"48225":23285,"48226":23308,"48227":23304,"48228":23534,"48229":23532,"48230":23529,"48231":23531,"48232":23652,"48233":23653,"48234":23965,"48235":23956,"48236":24162,"48237":24159,"48238":24161,"48239":24290,"48240":24282,"48241":24287,"48242":24285,"48243":24291,"48244":24288,"48245":24392,"48246":24433,"48247":24503,"48248":24501,"48249":24950,"48250":24935,"48251":24942,"48252":24925,"48253":24917,"48254":24962,"48289":24956,"48290":24944,"48291":24939,"48292":24958,"48293":24999,"48294":24976,"48295":25003,"48296":24974,"48297":25004,"48298":24986,"48299":24996,"48300":24980,"48301":25006,"48302":25134,"48303":25705,"48304":25711,"48305":25721,"48306":25758,"48307":25778,"48308":25736,"48309":25744,"48310":25776,"48311":25765,"48312":25747,"48313":25749,"48314":25769,"48315":25746,"48316":25774,"48317":25773,"48318":25771,"48319":25754,"48320":25772,"48321":25753,"48322":25762,"48323":25779,"48324":25973,"48325":25975,"48326":25976,"48327":26286,"48328":26283,"48329":26292,"48330":26289,"48331":27171,"48332":27167,"48333":27112,"48334":27137,"48335":27166,"48336":27161,"48337":27133,"48338":27169,"48339":27155,"48340":27146,"48341":27123,"48342":27138,"48343":27141,"48344":27117,"48345":27153,"48346":27472,"48347":27470,"48348":27556,"48349":27589,"48350":27590,"48351":28479,"48352":28540,"48353":28548,"48354":28497,"48355":28518,"48356":28500,"48357":28550,"48358":28525,"48359":28507,"48360":28536,"48361":28526,"48362":28558,"48363":28538,"48364":28528,"48365":28516,"48366":28567,"48367":28504,"48368":28373,"48369":28527,"48370":28512,"48371":28511,"48372":29087,"48373":29100,"48374":29105,"48375":29096,"48376":29270,"48377":29339,"48378":29518,"48379":29527,"48380":29801,"48381":29835,"48382":29827,"48448":29822,"48449":29824,"48450":30079,"48451":30240,"48452":30249,"48453":30239,"48454":30244,"48455":30246,"48456":30241,"48457":30242,"48458":30362,"48459":30394,"48460":30436,"48461":30606,"48462":30599,"48463":30604,"48464":30609,"48465":30603,"48466":30923,"48467":30917,"48468":30906,"48469":30922,"48470":30910,"48471":30933,"48472":30908,"48473":30928,"48474":31295,"48475":31292,"48476":31296,"48477":31293,"48478":31287,"48479":31291,"48480":31407,"48481":31406,"48482":31661,"48483":31665,"48484":31684,"48485":31668,"48486":31686,"48487":31687,"48488":31681,"48489":31648,"48490":31692,"48491":31946,"48492":32224,"48493":32244,"48494":32239,"48495":32251,"48496":32216,"48497":32236,"48498":32221,"48499":32232,"48500":32227,"48501":32218,"48502":32222,"48503":32233,"48504":32158,"48505":32217,"48506":32242,"48507":32249,"48508":32629,"48509":32631,"48510":32687,"48545":32745,"48546":32806,"48547":33179,"48548":33180,"48549":33181,"48550":33184,"48551":33178,"48552":33176,"48553":34071,"48554":34109,"48555":34074,"48556":34030,"48557":34092,"48558":34093,"48559":34067,"48560":34065,"48561":34083,"48562":34081,"48563":34068,"48564":34028,"48565":34085,"48566":34047,"48567":34054,"48568":34690,"48569":34676,"48570":34678,"48571":34656,"48572":34662,"48573":34680,"48574":34664,"48575":34649,"48576":34647,"48577":34636,"48578":34643,"48579":34907,"48580":34909,"48581":35088,"48582":35079,"48583":35090,"48584":35091,"48585":35093,"48586":35082,"48587":35516,"48588":35538,"48589":35527,"48590":35524,"48591":35477,"48592":35531,"48593":35576,"48594":35506,"48595":35529,"48596":35522,"48597":35519,"48598":35504,"48599":35542,"48600":35533,"48601":35510,"48602":35513,"48603":35547,"48604":35916,"48605":35918,"48606":35948,"48607":36064,"48608":36062,"48609":36070,"48610":36068,"48611":36076,"48612":36077,"48613":36066,"48614":36067,"48615":36060,"48616":36074,"48617":36065,"48618":36205,"48619":36255,"48620":36259,"48621":36395,"48622":36368,"48623":36381,"48624":36386,"48625":36367,"48626":36393,"48627":36383,"48628":36385,"48629":36382,"48630":36538,"48631":36637,"48632":36635,"48633":36639,"48634":36649,"48635":36646,"48636":36650,"48637":36636,"48638":36638,"48704":36645,"48705":36969,"48706":36974,"48707":36968,"48708":36973,"48709":36983,"48710":37168,"48711":37165,"48712":37159,"48713":37169,"48714":37255,"48715":37257,"48716":37259,"48717":37251,"48718":37573,"48719":37563,"48720":37559,"48721":37610,"48722":37548,"48723":37604,"48724":37569,"48725":37555,"48726":37564,"48727":37586,"48728":37575,"48729":37616,"48730":37554,"48731":38317,"48732":38321,"48733":38660,"48734":38662,"48735":38663,"48736":38665,"48737":38752,"48738":38797,"48739":38795,"48740":38799,"48741":38945,"48742":38955,"48743":38940,"48744":39091,"48745":39178,"48746":39187,"48747":39186,"48748":39192,"48749":39389,"48750":39376,"48751":39391,"48752":39387,"48753":39377,"48754":39381,"48755":39378,"48756":39385,"48757":39607,"48758":39662,"48759":39663,"48760":39719,"48761":39749,"48762":39748,"48763":39799,"48764":39791,"48765":40198,"48766":40201,"48801":40195,"48802":40617,"48803":40638,"48804":40654,"48805":22696,"48806":40786,"48807":20754,"48808":20760,"48809":20756,"48810":20752,"48811":20757,"48812":20864,"48813":20906,"48814":20957,"48815":21137,"48816":21139,"48817":21235,"48818":22105,"48819":22123,"48820":22137,"48821":22121,"48822":22116,"48823":22136,"48824":22122,"48825":22120,"48826":22117,"48827":22129,"48828":22127,"48829":22124,"48830":22114,"48831":22134,"48832":22721,"48833":22718,"48834":22727,"48835":22725,"48836":22894,"48837":23325,"48838":23348,"48839":23416,"48840":23536,"48841":23566,"48842":24394,"48843":25010,"48844":24977,"48845":25001,"48846":24970,"48847":25037,"48848":25014,"48849":25022,"48850":25034,"48851":25032,"48852":25136,"48853":25797,"48854":25793,"48855":25803,"48856":25787,"48857":25788,"48858":25818,"48859":25796,"48860":25799,"48861":25794,"48862":25805,"48863":25791,"48864":25810,"48865":25812,"48866":25790,"48867":25972,"48868":26310,"48869":26313,"48870":26297,"48871":26308,"48872":26311,"48873":26296,"48874":27197,"48875":27192,"48876":27194,"48877":27225,"48878":27243,"48879":27224,"48880":27193,"48881":27204,"48882":27234,"48883":27233,"48884":27211,"48885":27207,"48886":27189,"48887":27231,"48888":27208,"48889":27481,"48890":27511,"48891":27653,"48892":28610,"48893":28593,"48894":28577,"48960":28611,"48961":28580,"48962":28609,"48963":28583,"48964":28595,"48965":28608,"48966":28601,"48967":28598,"48968":28582,"48969":28576,"48970":28596,"48971":29118,"48972":29129,"48973":29136,"48974":29138,"48975":29128,"48976":29141,"48977":29113,"48978":29134,"48979":29145,"48980":29148,"48981":29123,"48982":29124,"48983":29544,"48984":29852,"48985":29859,"48986":29848,"48987":29855,"48988":29854,"48989":29922,"48990":29964,"48991":29965,"48992":30260,"48993":30264,"48994":30266,"48995":30439,"48996":30437,"48997":30624,"48998":30622,"48999":30623,"49000":30629,"49001":30952,"49002":30938,"49003":30956,"49004":30951,"49005":31142,"49006":31309,"49007":31310,"49008":31302,"49009":31308,"49010":31307,"49011":31418,"49012":31705,"49013":31761,"49014":31689,"49015":31716,"49016":31707,"49017":31713,"49018":31721,"49019":31718,"49020":31957,"49021":31958,"49022":32266,"49057":32273,"49058":32264,"49059":32283,"49060":32291,"49061":32286,"49062":32285,"49063":32265,"49064":32272,"49065":32633,"49066":32690,"49067":32752,"49068":32753,"49069":32750,"49070":32808,"49071":33203,"49072":33193,"49073":33192,"49074":33275,"49075":33288,"49076":33368,"49077":33369,"49078":34122,"49079":34137,"49080":34120,"49081":34152,"49082":34153,"49083":34115,"49084":34121,"49085":34157,"49086":34154,"49087":34142,"49088":34691,"49089":34719,"49090":34718,"49091":34722,"49092":34701,"49093":34913,"49094":35114,"49095":35122,"49096":35109,"49097":35115,"49098":35105,"49099":35242,"49100":35238,"49101":35558,"49102":35578,"49103":35563,"49104":35569,"49105":35584,"49106":35548,"49107":35559,"49108":35566,"49109":35582,"49110":35585,"49111":35586,"49112":35575,"49113":35565,"49114":35571,"49115":35574,"49116":35580,"49117":35947,"49118":35949,"49119":35987,"49120":36084,"49121":36420,"49122":36401,"49123":36404,"49124":36418,"49125":36409,"49126":36405,"49127":36667,"49128":36655,"49129":36664,"49130":36659,"49131":36776,"49132":36774,"49133":36981,"49134":36980,"49135":36984,"49136":36978,"49137":36988,"49138":36986,"49139":37172,"49140":37266,"49141":37664,"49142":37686,"49143":37624,"49144":37683,"49145":37679,"49146":37666,"49147":37628,"49148":37675,"49149":37636,"49150":37658,"49216":37648,"49217":37670,"49218":37665,"49219":37653,"49220":37678,"49221":37657,"49222":38331,"49223":38567,"49224":38568,"49225":38570,"49226":38613,"49227":38670,"49228":38673,"49229":38678,"49230":38669,"49231":38675,"49232":38671,"49233":38747,"49234":38748,"49235":38758,"49236":38808,"49237":38960,"49238":38968,"49239":38971,"49240":38967,"49241":38957,"49242":38969,"49243":38948,"49244":39184,"49245":39208,"49246":39198,"49247":39195,"49248":39201,"49249":39194,"49250":39405,"49251":39394,"49252":39409,"49253":39608,"49254":39612,"49255":39675,"49256":39661,"49257":39720,"49258":39825,"49259":40213,"49260":40227,"49261":40230,"49262":40232,"49263":40210,"49264":40219,"49265":40664,"49266":40660,"49267":40845,"49268":40860,"49269":20778,"49270":20767,"49271":20769,"49272":20786,"49273":21237,"49274":22158,"49275":22144,"49276":22160,"49277":22149,"49278":22151,"49313":22159,"49314":22741,"49315":22739,"49316":22737,"49317":22734,"49318":23344,"49319":23338,"49320":23332,"49321":23418,"49322":23607,"49323":23656,"49324":23996,"49325":23994,"49326":23997,"49327":23992,"49328":24171,"49329":24396,"49330":24509,"49331":25033,"49332":25026,"49333":25031,"49334":25062,"49335":25035,"49336":25138,"49337":25140,"49338":25806,"49339":25802,"49340":25816,"49341":25824,"49342":25840,"49343":25830,"49344":25836,"49345":25841,"49346":25826,"49347":25837,"49348":25986,"49349":25987,"49350":26329,"49351":26326,"49352":27264,"49353":27284,"49354":27268,"49355":27298,"49356":27292,"49357":27355,"49358":27299,"49359":27262,"49360":27287,"49361":27280,"49362":27296,"49363":27484,"49364":27566,"49365":27610,"49366":27656,"49367":28632,"49368":28657,"49369":28639,"49370":28640,"49371":28635,"49372":28644,"49373":28651,"49374":28655,"49375":28544,"49376":28652,"49377":28641,"49378":28649,"49379":28629,"49380":28654,"49381":28656,"49382":29159,"49383":29151,"49384":29166,"49385":29158,"49386":29157,"49387":29165,"49388":29164,"49389":29172,"49390":29152,"49391":29237,"49392":29254,"49393":29552,"49394":29554,"49395":29865,"49396":29872,"49397":29862,"49398":29864,"49399":30278,"49400":30274,"49401":30284,"49402":30442,"49403":30643,"49404":30634,"49405":30640,"49406":30636,"49472":30631,"49473":30637,"49474":30703,"49475":30967,"49476":30970,"49477":30964,"49478":30959,"49479":30977,"49480":31143,"49481":31146,"49482":31319,"49483":31423,"49484":31751,"49485":31757,"49486":31742,"49487":31735,"49488":31756,"49489":31712,"49490":31968,"49491":31964,"49492":31966,"49493":31970,"49494":31967,"49495":31961,"49496":31965,"49497":32302,"49498":32318,"49499":32326,"49500":32311,"49501":32306,"49502":32323,"49503":32299,"49504":32317,"49505":32305,"49506":32325,"49507":32321,"49508":32308,"49509":32313,"49510":32328,"49511":32309,"49512":32319,"49513":32303,"49514":32580,"49515":32755,"49516":32764,"49517":32881,"49518":32882,"49519":32880,"49520":32879,"49521":32883,"49522":33222,"49523":33219,"49524":33210,"49525":33218,"49526":33216,"49527":33215,"49528":33213,"49529":33225,"49530":33214,"49531":33256,"49532":33289,"49533":33393,"49534":34218,"49569":34180,"49570":34174,"49571":34204,"49572":34193,"49573":34196,"49574":34223,"49575":34203,"49576":34183,"49577":34216,"49578":34186,"49579":34407,"49580":34752,"49581":34769,"49582":34739,"49583":34770,"49584":34758,"49585":34731,"49586":34747,"49587":34746,"49588":34760,"49589":34763,"49590":35131,"49591":35126,"49592":35140,"49593":35128,"49594":35133,"49595":35244,"49596":35598,"49597":35607,"49598":35609,"49599":35611,"49600":35594,"49601":35616,"49602":35613,"49603":35588,"49604":35600,"49605":35905,"49606":35903,"49607":35955,"49608":36090,"49609":36093,"49610":36092,"49611":36088,"49612":36091,"49613":36264,"49614":36425,"49615":36427,"49616":36424,"49617":36426,"49618":36676,"49619":36670,"49620":36674,"49621":36677,"49622":36671,"49623":36991,"49624":36989,"49625":36996,"49626":36993,"49627":36994,"49628":36992,"49629":37177,"49630":37283,"49631":37278,"49632":37276,"49633":37709,"49634":37762,"49635":37672,"49636":37749,"49637":37706,"49638":37733,"49639":37707,"49640":37656,"49641":37758,"49642":37740,"49643":37723,"49644":37744,"49645":37722,"49646":37716,"49647":38346,"49648":38347,"49649":38348,"49650":38344,"49651":38342,"49652":38577,"49653":38584,"49654":38614,"49655":38684,"49656":38686,"49657":38816,"49658":38867,"49659":38982,"49660":39094,"49661":39221,"49662":39425,"49728":39423,"49729":39854,"49730":39851,"49731":39850,"49732":39853,"49733":40251,"49734":40255,"49735":40587,"49736":40655,"49737":40670,"49738":40668,"49739":40669,"49740":40667,"49741":40766,"49742":40779,"49743":21474,"49744":22165,"49745":22190,"49746":22745,"49747":22744,"49748":23352,"49749":24413,"49750":25059,"49751":25139,"49752":25844,"49753":25842,"49754":25854,"49755":25862,"49756":25850,"49757":25851,"49758":25847,"49759":26039,"49760":26332,"49761":26406,"49762":27315,"49763":27308,"49764":27331,"49765":27323,"49766":27320,"49767":27330,"49768":27310,"49769":27311,"49770":27487,"49771":27512,"49772":27567,"49773":28681,"49774":28683,"49775":28670,"49776":28678,"49777":28666,"49778":28689,"49779":28687,"49780":29179,"49781":29180,"49782":29182,"49783":29176,"49784":29559,"49785":29557,"49786":29863,"49787":29887,"49788":29973,"49789":30294,"49790":30296,"49825":30290,"49826":30653,"49827":30655,"49828":30651,"49829":30652,"49830":30990,"49831":31150,"49832":31329,"49833":31330,"49834":31328,"49835":31428,"49836":31429,"49837":31787,"49838":31783,"49839":31786,"49840":31774,"49841":31779,"49842":31777,"49843":31975,"49844":32340,"49845":32341,"49846":32350,"49847":32346,"49848":32353,"49849":32338,"49850":32345,"49851":32584,"49852":32761,"49853":32763,"49854":32887,"49855":32886,"49856":33229,"49857":33231,"49858":33290,"49859":34255,"49860":34217,"49861":34253,"49862":34256,"49863":34249,"49864":34224,"49865":34234,"49866":34233,"49867":34214,"49868":34799,"49869":34796,"49870":34802,"49871":34784,"49872":35206,"49873":35250,"49874":35316,"49875":35624,"49876":35641,"49877":35628,"49878":35627,"49879":35920,"49880":36101,"49881":36441,"49882":36451,"49883":36454,"49884":36452,"49885":36447,"49886":36437,"49887":36544,"49888":36681,"49889":36685,"49890":36999,"49891":36995,"49892":37000,"49893":37291,"49894":37292,"49895":37328,"49896":37780,"49897":37770,"49898":37782,"49899":37794,"49900":37811,"49901":37806,"49902":37804,"49903":37808,"49904":37784,"49905":37786,"49906":37783,"49907":38356,"49908":38358,"49909":38352,"49910":38357,"49911":38626,"49912":38620,"49913":38617,"49914":38619,"49915":38622,"49916":38692,"49917":38819,"49918":38822,"49984":38829,"49985":38905,"49986":38989,"49987":38991,"49988":38988,"49989":38990,"49990":38995,"49991":39098,"49992":39230,"49993":39231,"49994":39229,"49995":39214,"49996":39333,"49997":39438,"49998":39617,"49999":39683,"50000":39686,"50001":39759,"50002":39758,"50003":39757,"50004":39882,"50005":39881,"50006":39933,"50007":39880,"50008":39872,"50009":40273,"50010":40285,"50011":40288,"50012":40672,"50013":40725,"50014":40748,"50015":20787,"50016":22181,"50017":22750,"50018":22751,"50019":22754,"50020":23541,"50021":40848,"50022":24300,"50023":25074,"50024":25079,"50025":25078,"50026":25077,"50027":25856,"50028":25871,"50029":26336,"50030":26333,"50031":27365,"50032":27357,"50033":27354,"50034":27347,"50035":28699,"50036":28703,"50037":28712,"50038":28698,"50039":28701,"50040":28693,"50041":28696,"50042":29190,"50043":29197,"50044":29272,"50045":29346,"50046":29560,"50081":29562,"50082":29885,"50083":29898,"50084":29923,"50085":30087,"50086":30086,"50087":30303,"50088":30305,"50089":30663,"50090":31001,"50091":31153,"50092":31339,"50093":31337,"50094":31806,"50095":31807,"50096":31800,"50097":31805,"50098":31799,"50099":31808,"50100":32363,"50101":32365,"50102":32377,"50103":32361,"50104":32362,"50105":32645,"50106":32371,"50107":32694,"50108":32697,"50109":32696,"50110":33240,"50111":34281,"50112":34269,"50113":34282,"50114":34261,"50115":34276,"50116":34277,"50117":34295,"50118":34811,"50119":34821,"50120":34829,"50121":34809,"50122":34814,"50123":35168,"50124":35167,"50125":35158,"50126":35166,"50127":35649,"50128":35676,"50129":35672,"50130":35657,"50131":35674,"50132":35662,"50133":35663,"50134":35654,"50135":35673,"50136":36104,"50137":36106,"50138":36476,"50139":36466,"50140":36487,"50141":36470,"50142":36460,"50143":36474,"50144":36468,"50145":36692,"50146":36686,"50147":36781,"50148":37002,"50149":37003,"50150":37297,"50151":37294,"50152":37857,"50153":37841,"50154":37855,"50155":37827,"50156":37832,"50157":37852,"50158":37853,"50159":37846,"50160":37858,"50161":37837,"50162":37848,"50163":37860,"50164":37847,"50165":37864,"50166":38364,"50167":38580,"50168":38627,"50169":38698,"50170":38695,"50171":38753,"50172":38876,"50173":38907,"50174":39006,"50240":39000,"50241":39003,"50242":39100,"50243":39237,"50244":39241,"50245":39446,"50246":39449,"50247":39693,"50248":39912,"50249":39911,"50250":39894,"50251":39899,"50252":40329,"50253":40289,"50254":40306,"50255":40298,"50256":40300,"50257":40594,"50258":40599,"50259":40595,"50260":40628,"50261":21240,"50262":22184,"50263":22199,"50264":22198,"50265":22196,"50266":22204,"50267":22756,"50268":23360,"50269":23363,"50270":23421,"50271":23542,"50272":24009,"50273":25080,"50274":25082,"50275":25880,"50276":25876,"50277":25881,"50278":26342,"50279":26407,"50280":27372,"50281":28734,"50282":28720,"50283":28722,"50284":29200,"50285":29563,"50286":29903,"50287":30306,"50288":30309,"50289":31014,"50290":31018,"50291":31020,"50292":31019,"50293":31431,"50294":31478,"50295":31820,"50296":31811,"50297":31821,"50298":31983,"50299":31984,"50300":36782,"50301":32381,"50302":32380,"50337":32386,"50338":32588,"50339":32768,"50340":33242,"50341":33382,"50342":34299,"50343":34297,"50344":34321,"50345":34298,"50346":34310,"50347":34315,"50348":34311,"50349":34314,"50350":34836,"50351":34837,"50352":35172,"50353":35258,"50354":35320,"50355":35696,"50356":35692,"50357":35686,"50358":35695,"50359":35679,"50360":35691,"50361":36111,"50362":36109,"50363":36489,"50364":36481,"50365":36485,"50366":36482,"50367":37300,"50368":37323,"50369":37912,"50370":37891,"50371":37885,"50372":38369,"50373":38704,"50374":39108,"50375":39250,"50376":39249,"50377":39336,"50378":39467,"50379":39472,"50380":39479,"50381":39477,"50382":39955,"50383":39949,"50384":40569,"50385":40629,"50386":40680,"50387":40751,"50388":40799,"50389":40803,"50390":40801,"50391":20791,"50392":20792,"50393":22209,"50394":22208,"50395":22210,"50396":22804,"50397":23660,"50398":24013,"50399":25084,"50400":25086,"50401":25885,"50402":25884,"50403":26005,"50404":26345,"50405":27387,"50406":27396,"50407":27386,"50408":27570,"50409":28748,"50410":29211,"50411":29351,"50412":29910,"50413":29908,"50414":30313,"50415":30675,"50416":31824,"50417":32399,"50418":32396,"50419":32700,"50420":34327,"50421":34349,"50422":34330,"50423":34851,"50424":34850,"50425":34849,"50426":34847,"50427":35178,"50428":35180,"50429":35261,"50430":35700,"50496":35703,"50497":35709,"50498":36115,"50499":36490,"50500":36493,"50501":36491,"50502":36703,"50503":36783,"50504":37306,"50505":37934,"50506":37939,"50507":37941,"50508":37946,"50509":37944,"50510":37938,"50511":37931,"50512":38370,"50513":38712,"50514":38713,"50515":38706,"50516":38911,"50517":39015,"50518":39013,"50519":39255,"50520":39493,"50521":39491,"50522":39488,"50523":39486,"50524":39631,"50525":39764,"50526":39761,"50527":39981,"50528":39973,"50529":40367,"50530":40372,"50531":40386,"50532":40376,"50533":40605,"50534":40687,"50535":40729,"50536":40796,"50537":40806,"50538":40807,"50539":20796,"50540":20795,"50541":22216,"50542":22218,"50543":22217,"50544":23423,"50545":24020,"50546":24018,"50547":24398,"50548":25087,"50549":25892,"50550":27402,"50551":27489,"50552":28753,"50553":28760,"50554":29568,"50555":29924,"50556":30090,"50557":30318,"50558":30316,"50593":31155,"50594":31840,"50595":31839,"50596":32894,"50597":32893,"50598":33247,"50599":35186,"50600":35183,"50601":35324,"50602":35712,"50603":36118,"50604":36119,"50605":36497,"50606":36499,"50607":36705,"50608":37192,"50609":37956,"50610":37969,"50611":37970,"50612":38717,"50613":38718,"50614":38851,"50615":38849,"50616":39019,"50617":39253,"50618":39509,"50619":39501,"50620":39634,"50621":39706,"50622":40009,"50623":39985,"50624":39998,"50625":39995,"50626":40403,"50627":40407,"50628":40756,"50629":40812,"50630":40810,"50631":40852,"50632":22220,"50633":24022,"50634":25088,"50635":25891,"50636":25899,"50637":25898,"50638":26348,"50639":27408,"50640":29914,"50641":31434,"50642":31844,"50643":31843,"50644":31845,"50645":32403,"50646":32406,"50647":32404,"50648":33250,"50649":34360,"50650":34367,"50651":34865,"50652":35722,"50653":37008,"50654":37007,"50655":37987,"50656":37984,"50657":37988,"50658":38760,"50659":39023,"50660":39260,"50661":39514,"50662":39515,"50663":39511,"50664":39635,"50665":39636,"50666":39633,"50667":40020,"50668":40023,"50669":40022,"50670":40421,"50671":40607,"50672":40692,"50673":22225,"50674":22761,"50675":25900,"50676":28766,"50677":30321,"50678":30322,"50679":30679,"50680":32592,"50681":32648,"50682":34870,"50683":34873,"50684":34914,"50685":35731,"50686":35730,"50752":35734,"50753":33399,"50754":36123,"50755":37312,"50756":37994,"50757":38722,"50758":38728,"50759":38724,"50760":38854,"50761":39024,"50762":39519,"50763":39714,"50764":39768,"50765":40031,"50766":40441,"50767":40442,"50768":40572,"50769":40573,"50770":40711,"50771":40823,"50772":40818,"50773":24307,"50774":27414,"50775":28771,"50776":31852,"50777":31854,"50778":34875,"50779":35264,"50780":36513,"50781":37313,"50782":38002,"50783":38000,"50784":39025,"50785":39262,"50786":39638,"50787":39715,"50788":40652,"50789":28772,"50790":30682,"50791":35738,"50792":38007,"50793":38857,"50794":39522,"50795":39525,"50796":32412,"50797":35740,"50798":36522,"50799":37317,"50800":38013,"50801":38014,"50802":38012,"50803":40055,"50804":40056,"50805":40695,"50806":35924,"50807":38015,"50808":40474,"50809":29224,"50810":39530,"50811":39729,"50812":40475,"50813":40478,"50814":31858,"50849":9312,"50850":9313,"50851":9314,"50852":9315,"50853":9316,"50854":9317,"50855":9318,"50856":9319,"50857":9320,"50858":9321,"50859":9332,"50860":9333,"50861":9334,"50862":9335,"50863":9336,"50864":9337,"50865":9338,"50866":9339,"50867":9340,"50868":9341,"50869":8560,"50870":8561,"50871":8562,"50872":8563,"50873":8564,"50874":8565,"50875":8566,"50876":8567,"50877":8568,"50878":8569,"50879":20022,"50880":20031,"50881":20101,"50882":20128,"50883":20866,"50884":20886,"50885":20907,"50886":21241,"50887":21304,"50888":21353,"50889":21430,"50890":22794,"50891":23424,"50892":24027,"50893":24186,"50894":24191,"50895":24308,"50896":24400,"50897":24417,"50898":25908,"50899":26080,"50900":30098,"50901":30326,"50902":36789,"50903":38582,"50904":168,"50905":710,"50906":12541,"50907":12542,"50908":12445,"50909":12446,"50910":12291,"50911":20189,"50912":12293,"50913":12294,"50914":12295,"50915":12540,"50916":65339,"50917":65341,"50918":10045,"50919":12353,"50920":12354,"50921":12355,"50922":12356,"50923":12357,"50924":12358,"50925":12359,"50926":12360,"50927":12361,"50928":12362,"50929":12363,"50930":12364,"50931":12365,"50932":12366,"50933":12367,"50934":12368,"50935":12369,"50936":12370,"50937":12371,"50938":12372,"50939":12373,"50940":12374,"50941":12375,"50942":12376,"51008":12377,"51009":12378,"51010":12379,"51011":12380,"51012":12381,"51013":12382,"51014":12383,"51015":12384,"51016":12385,"51017":12386,"51018":12387,"51019":12388,"51020":12389,"51021":12390,"51022":12391,"51023":12392,"51024":12393,"51025":12394,"51026":12395,"51027":12396,"51028":12397,"51029":12398,"51030":12399,"51031":12400,"51032":12401,"51033":12402,"51034":12403,"51035":12404,"51036":12405,"51037":12406,"51038":12407,"51039":12408,"51040":12409,"51041":12410,"51042":12411,"51043":12412,"51044":12413,"51045":12414,"51046":12415,"51047":12416,"51048":12417,"51049":12418,"51050":12419,"51051":12420,"51052":12421,"51053":12422,"51054":12423,"51055":12424,"51056":12425,"51057":12426,"51058":12427,"51059":12428,"51060":12429,"51061":12430,"51062":12431,"51063":12432,"51064":12433,"51065":12434,"51066":12435,"51067":12449,"51068":12450,"51069":12451,"51070":12452,"51105":12453,"51106":12454,"51107":12455,"51108":12456,"51109":12457,"51110":12458,"51111":12459,"51112":12460,"51113":12461,"51114":12462,"51115":12463,"51116":12464,"51117":12465,"51118":12466,"51119":12467,"51120":12468,"51121":12469,"51122":12470,"51123":12471,"51124":12472,"51125":12473,"51126":12474,"51127":12475,"51128":12476,"51129":12477,"51130":12478,"51131":12479,"51132":12480,"51133":12481,"51134":12482,"51135":12483,"51136":12484,"51137":12485,"51138":12486,"51139":12487,"51140":12488,"51141":12489,"51142":12490,"51143":12491,"51144":12492,"51145":12493,"51146":12494,"51147":12495,"51148":12496,"51149":12497,"51150":12498,"51151":12499,"51152":12500,"51153":12501,"51154":12502,"51155":12503,"51156":12504,"51157":12505,"51158":12506,"51159":12507,"51160":12508,"51161":12509,"51162":12510,"51163":12511,"51164":12512,"51165":12513,"51166":12514,"51167":12515,"51168":12516,"51169":12517,"51170":12518,"51171":12519,"51172":12520,"51173":12521,"51174":12522,"51175":12523,"51176":12524,"51177":12525,"51178":12526,"51179":12527,"51180":12528,"51181":12529,"51182":12530,"51183":12531,"51184":12532,"51185":12533,"51186":12534,"51187":1040,"51188":1041,"51189":1042,"51190":1043,"51191":1044,"51192":1045,"51193":1025,"51194":1046,"51195":1047,"51196":1048,"51197":1049,"51198":1050,"51264":1051,"51265":1052,"51266":1053,"51267":1054,"51268":1055,"51269":1056,"51270":1057,"51271":1058,"51272":1059,"51273":1060,"51274":1061,"51275":1062,"51276":1063,"51277":1064,"51278":1065,"51279":1066,"51280":1067,"51281":1068,"51282":1069,"51283":1070,"51284":1071,"51285":1072,"51286":1073,"51287":1074,"51288":1075,"51289":1076,"51290":1077,"51291":1105,"51292":1078,"51293":1079,"51294":1080,"51295":1081,"51296":1082,"51297":1083,"51298":1084,"51299":1085,"51300":1086,"51301":1087,"51302":1088,"51303":1089,"51304":1090,"51305":1091,"51306":1092,"51307":1093,"51308":1094,"51309":1095,"51310":1096,"51311":1097,"51312":1098,"51313":1099,"51314":1100,"51315":1101,"51316":1102,"51317":1103,"51318":8679,"51319":8632,"51320":8633,"51321":12751,"51322":63462,"51323":20058,"51324":63464,"51325":20994,"51326":17553,"51361":40880,"51362":20872,"51363":40881,"51364":63470,"51365":63471,"51366":63472,"51367":63473,"51368":63474,"51369":63475,"51370":63476,"51371":63477,"51372":63478,"51373":63479,"51374":63480,"51375":63481,"51376":63482,"51377":12443,"51378":12444,"51379":12436,"51380":12535,"51381":12536,"51382":12537,"51383":12538,"51384":12539,"51385":65377,"51386":65378,"51387":65379,"51388":65380,"51389":65381,"51390":65382,"51391":65383,"51392":65384,"51393":65385,"51394":65386,"51395":65387,"51396":65388,"51397":65389,"51398":65390,"51399":65391,"51400":65392,"51401":65393,"51402":65394,"51403":65395,"51404":65396,"51405":65506,"51406":65508,"51407":65287,"51408":65282,"51409":12849,"51410":8470,"51411":8481,"51412":65397,"51413":65398,"51414":65399,"51415":65400,"51416":65401,"51417":65402,"51418":65403,"51419":65404,"51420":65405,"51421":65406,"51422":65407,"51423":65408,"51424":65409,"51425":65410,"51426":65411,"51427":65412,"51428":65413,"51429":65414,"51430":65415,"51431":65416,"51432":65417,"51433":65418,"51434":65419,"51435":65420,"51436":65421,"51437":65422,"51438":65423,"51439":65424,"51440":65425,"51441":65426,"51442":65427,"51443":65428,"51444":65429,"51445":65430,"51446":65431,"51447":65432,"51448":65433,"51449":65434,"51450":65435,"51451":65436,"51452":65437,"51453":65438,"51454":65439,"51520":20034,"51521":20060,"51522":20981,"51523":21274,"51524":21378,"51525":19975,"51526":19980,"51527":20039,"51528":20109,"51529":22231,"51530":64012,"51531":23662,"51532":24435,"51533":19983,"51534":20871,"51535":19982,"51536":20014,"51537":20115,"51538":20162,"51539":20169,"51540":20168,"51541":20888,"51542":21244,"51543":21356,"51544":21433,"51545":22304,"51546":22787,"51547":22828,"51548":23568,"51549":24063,"51550":26081,"51551":27571,"51552":27596,"51553":27668,"51554":29247,"51555":20017,"51556":20028,"51557":20200,"51558":20188,"51559":20201,"51560":20193,"51561":20189,"51562":20186,"51563":21004,"51564":21276,"51565":21324,"51566":22306,"51567":22307,"51568":22807,"51569":22831,"51570":23425,"51571":23428,"51572":23570,"51573":23611,"51574":23668,"51575":23667,"51576":24068,"51577":24192,"51578":24194,"51579":24521,"51580":25097,"51581":25168,"51582":27669,"51617":27702,"51618":27715,"51619":27711,"51620":27707,"51621":29358,"51622":29360,"51623":29578,"51624":31160,"51625":32906,"51626":38430,"51627":20238,"51628":20248,"51629":20268,"51630":20213,"51631":20244,"51632":20209,"51633":20224,"51634":20215,"51635":20232,"51636":20253,"51637":20226,"51638":20229,"51639":20258,"51640":20243,"51641":20228,"51642":20212,"51643":20242,"51644":20913,"51645":21011,"51646":21001,"51647":21008,"51648":21158,"51649":21282,"51650":21279,"51651":21325,"51652":21386,"51653":21511,"51654":22241,"51655":22239,"51656":22318,"51657":22314,"51658":22324,"51659":22844,"51660":22912,"51661":22908,"51662":22917,"51663":22907,"51664":22910,"51665":22903,"51666":22911,"51667":23382,"51668":23573,"51669":23589,"51670":23676,"51671":23674,"51672":23675,"51673":23678,"51674":24031,"51675":24181,"51676":24196,"51677":24322,"51678":24346,"51679":24436,"51680":24533,"51681":24532,"51682":24527,"51683":25180,"51684":25182,"51685":25188,"51686":25185,"51687":25190,"51688":25186,"51689":25177,"51690":25184,"51691":25178,"51692":25189,"51693":26095,"51694":26094,"51695":26430,"51696":26425,"51697":26424,"51698":26427,"51699":26426,"51700":26431,"51701":26428,"51702":26419,"51703":27672,"51704":27718,"51705":27730,"51706":27740,"51707":27727,"51708":27722,"51709":27732,"51710":27723,"51776":27724,"51777":28785,"51778":29278,"51779":29364,"51780":29365,"51781":29582,"51782":29994,"51783":30335,"51784":31349,"51785":32593,"51786":33400,"51787":33404,"51788":33408,"51789":33405,"51790":33407,"51791":34381,"51792":35198,"51793":37017,"51794":37015,"51795":37016,"51796":37019,"51797":37012,"51798":38434,"51799":38436,"51800":38432,"51801":38435,"51802":20310,"51803":20283,"51804":20322,"51805":20297,"51806":20307,"51807":20324,"51808":20286,"51809":20327,"51810":20306,"51811":20319,"51812":20289,"51813":20312,"51814":20269,"51815":20275,"51816":20287,"51817":20321,"51818":20879,"51819":20921,"51820":21020,"51821":21022,"51822":21025,"51823":21165,"51824":21166,"51825":21257,"51826":21347,"51827":21362,"51828":21390,"51829":21391,"51830":21552,"51831":21559,"51832":21546,"51833":21588,"51834":21573,"51835":21529,"51836":21532,"51837":21541,"51838":21528,"51873":21565,"51874":21583,"51875":21569,"51876":21544,"51877":21540,"51878":21575,"51879":22254,"51880":22247,"51881":22245,"51882":22337,"51883":22341,"51884":22348,"51885":22345,"51886":22347,"51887":22354,"51888":22790,"51889":22848,"51890":22950,"51891":22936,"51892":22944,"51893":22935,"51894":22926,"51895":22946,"51896":22928,"51897":22927,"51898":22951,"51899":22945,"51900":23438,"51901":23442,"51902":23592,"51903":23594,"51904":23693,"51905":23695,"51906":23688,"51907":23691,"51908":23689,"51909":23698,"51910":23690,"51911":23686,"51912":23699,"51913":23701,"51914":24032,"51915":24074,"51916":24078,"51917":24203,"51918":24201,"51919":24204,"51920":24200,"51921":24205,"51922":24325,"51923":24349,"51924":24440,"51925":24438,"51926":24530,"51927":24529,"51928":24528,"51929":24557,"51930":24552,"51931":24558,"51932":24563,"51933":24545,"51934":24548,"51935":24547,"51936":24570,"51937":24559,"51938":24567,"51939":24571,"51940":24576,"51941":24564,"51942":25146,"51943":25219,"51944":25228,"51945":25230,"51946":25231,"51947":25236,"51948":25223,"51949":25201,"51950":25211,"51951":25210,"51952":25200,"51953":25217,"51954":25224,"51955":25207,"51956":25213,"51957":25202,"51958":25204,"51959":25911,"51960":26096,"51961":26100,"51962":26099,"51963":26098,"51964":26101,"51965":26437,"51966":26439,"52032":26457,"52033":26453,"52034":26444,"52035":26440,"52036":26461,"52037":26445,"52038":26458,"52039":26443,"52040":27600,"52041":27673,"52042":27674,"52043":27768,"52044":27751,"52045":27755,"52046":27780,"52047":27787,"52048":27791,"52049":27761,"52050":27759,"52051":27753,"52052":27802,"52053":27757,"52054":27783,"52055":27797,"52056":27804,"52057":27750,"52058":27763,"52059":27749,"52060":27771,"52061":27790,"52062":28788,"52063":28794,"52064":29283,"52065":29375,"52066":29373,"52067":29379,"52068":29382,"52069":29377,"52070":29370,"52071":29381,"52072":29589,"52073":29591,"52074":29587,"52075":29588,"52076":29586,"52077":30010,"52078":30009,"52079":30100,"52080":30101,"52081":30337,"52082":31037,"52083":32820,"52084":32917,"52085":32921,"52086":32912,"52087":32914,"52088":32924,"52089":33424,"52090":33423,"52091":33413,"52092":33422,"52093":33425,"52094":33427,"52129":33418,"52130":33411,"52131":33412,"52132":35960,"52133":36809,"52134":36799,"52135":37023,"52136":37025,"52137":37029,"52138":37022,"52139":37031,"52140":37024,"52141":38448,"52142":38440,"52143":38447,"52144":38445,"52145":20019,"52146":20376,"52147":20348,"52148":20357,"52149":20349,"52150":20352,"52151":20359,"52152":20342,"52153":20340,"52154":20361,"52155":20356,"52156":20343,"52157":20300,"52158":20375,"52159":20330,"52160":20378,"52161":20345,"52162":20353,"52163":20344,"52164":20368,"52165":20380,"52166":20372,"52167":20382,"52168":20370,"52169":20354,"52170":20373,"52171":20331,"52172":20334,"52173":20894,"52174":20924,"52175":20926,"52176":21045,"52177":21042,"52178":21043,"52179":21062,"52180":21041,"52181":21180,"52182":21258,"52183":21259,"52184":21308,"52185":21394,"52186":21396,"52187":21639,"52188":21631,"52189":21633,"52190":21649,"52191":21634,"52192":21640,"52193":21611,"52194":21626,"52195":21630,"52196":21605,"52197":21612,"52198":21620,"52199":21606,"52200":21645,"52201":21615,"52202":21601,"52203":21600,"52204":21656,"52205":21603,"52206":21607,"52207":21604,"52208":22263,"52209":22265,"52210":22383,"52211":22386,"52212":22381,"52213":22379,"52214":22385,"52215":22384,"52216":22390,"52217":22400,"52218":22389,"52219":22395,"52220":22387,"52221":22388,"52222":22370,"52288":22376,"52289":22397,"52290":22796,"52291":22853,"52292":22965,"52293":22970,"52294":22991,"52295":22990,"52296":22962,"52297":22988,"52298":22977,"52299":22966,"52300":22972,"52301":22979,"52302":22998,"52303":22961,"52304":22973,"52305":22976,"52306":22984,"52307":22964,"52308":22983,"52309":23394,"52310":23397,"52311":23443,"52312":23445,"52313":23620,"52314":23623,"52315":23726,"52316":23716,"52317":23712,"52318":23733,"52319":23727,"52320":23720,"52321":23724,"52322":23711,"52323":23715,"52324":23725,"52325":23714,"52326":23722,"52327":23719,"52328":23709,"52329":23717,"52330":23734,"52331":23728,"52332":23718,"52333":24087,"52334":24084,"52335":24089,"52336":24360,"52337":24354,"52338":24355,"52339":24356,"52340":24404,"52341":24450,"52342":24446,"52343":24445,"52344":24542,"52345":24549,"52346":24621,"52347":24614,"52348":24601,"52349":24626,"52350":24587,"52385":24628,"52386":24586,"52387":24599,"52388":24627,"52389":24602,"52390":24606,"52391":24620,"52392":24610,"52393":24589,"52394":24592,"52395":24622,"52396":24595,"52397":24593,"52398":24588,"52399":24585,"52400":24604,"52401":25108,"52402":25149,"52403":25261,"52404":25268,"52405":25297,"52406":25278,"52407":25258,"52408":25270,"52409":25290,"52410":25262,"52411":25267,"52412":25263,"52413":25275,"52414":25257,"52415":25264,"52416":25272,"52417":25917,"52418":26024,"52419":26043,"52420":26121,"52421":26108,"52422":26116,"52423":26130,"52424":26120,"52425":26107,"52426":26115,"52427":26123,"52428":26125,"52429":26117,"52430":26109,"52431":26129,"52432":26128,"52433":26358,"52434":26378,"52435":26501,"52436":26476,"52437":26510,"52438":26514,"52439":26486,"52440":26491,"52441":26520,"52442":26502,"52443":26500,"52444":26484,"52445":26509,"52446":26508,"52447":26490,"52448":26527,"52449":26513,"52450":26521,"52451":26499,"52452":26493,"52453":26497,"52454":26488,"52455":26489,"52456":26516,"52457":27429,"52458":27520,"52459":27518,"52460":27614,"52461":27677,"52462":27795,"52463":27884,"52464":27883,"52465":27886,"52466":27865,"52467":27830,"52468":27860,"52469":27821,"52470":27879,"52471":27831,"52472":27856,"52473":27842,"52474":27834,"52475":27843,"52476":27846,"52477":27885,"52478":27890,"52544":27858,"52545":27869,"52546":27828,"52547":27786,"52548":27805,"52549":27776,"52550":27870,"52551":27840,"52552":27952,"52553":27853,"52554":27847,"52555":27824,"52556":27897,"52557":27855,"52558":27881,"52559":27857,"52560":28820,"52561":28824,"52562":28805,"52563":28819,"52564":28806,"52565":28804,"52566":28817,"52567":28822,"52568":28802,"52569":28826,"52570":28803,"52571":29290,"52572":29398,"52573":29387,"52574":29400,"52575":29385,"52576":29404,"52577":29394,"52578":29396,"52579":29402,"52580":29388,"52581":29393,"52582":29604,"52583":29601,"52584":29613,"52585":29606,"52586":29602,"52587":29600,"52588":29612,"52589":29597,"52590":29917,"52591":29928,"52592":30015,"52593":30016,"52594":30014,"52595":30092,"52596":30104,"52597":30383,"52598":30451,"52599":30449,"52600":30448,"52601":30453,"52602":30712,"52603":30716,"52604":30713,"52605":30715,"52606":30714,"52641":30711,"52642":31042,"52643":31039,"52644":31173,"52645":31352,"52646":31355,"52647":31483,"52648":31861,"52649":31997,"52650":32821,"52651":32911,"52652":32942,"52653":32931,"52654":32952,"52655":32949,"52656":32941,"52657":33312,"52658":33440,"52659":33472,"52660":33451,"52661":33434,"52662":33432,"52663":33435,"52664":33461,"52665":33447,"52666":33454,"52667":33468,"52668":33438,"52669":33466,"52670":33460,"52671":33448,"52672":33441,"52673":33449,"52674":33474,"52675":33444,"52676":33475,"52677":33462,"52678":33442,"52679":34416,"52680":34415,"52681":34413,"52682":34414,"52683":35926,"52684":36818,"52685":36811,"52686":36819,"52687":36813,"52688":36822,"52689":36821,"52690":36823,"52691":37042,"52692":37044,"52693":37039,"52694":37043,"52695":37040,"52696":38457,"52697":38461,"52698":38460,"52699":38458,"52700":38467,"52701":20429,"52702":20421,"52703":20435,"52704":20402,"52705":20425,"52706":20427,"52707":20417,"52708":20436,"52709":20444,"52710":20441,"52711":20411,"52712":20403,"52713":20443,"52714":20423,"52715":20438,"52716":20410,"52717":20416,"52718":20409,"52719":20460,"52720":21060,"52721":21065,"52722":21184,"52723":21186,"52724":21309,"52725":21372,"52726":21399,"52727":21398,"52728":21401,"52729":21400,"52730":21690,"52731":21665,"52732":21677,"52733":21669,"52734":21711,"52800":21699,"52801":33549,"52802":21687,"52803":21678,"52804":21718,"52805":21686,"52806":21701,"52807":21702,"52808":21664,"52809":21616,"52810":21692,"52811":21666,"52812":21694,"52813":21618,"52814":21726,"52815":21680,"52816":22453,"52817":22430,"52818":22431,"52819":22436,"52820":22412,"52821":22423,"52822":22429,"52823":22427,"52824":22420,"52825":22424,"52826":22415,"52827":22425,"52828":22437,"52829":22426,"52830":22421,"52831":22772,"52832":22797,"52833":22867,"52834":23009,"52835":23006,"52836":23022,"52837":23040,"52838":23025,"52839":23005,"52840":23034,"52841":23037,"52842":23036,"52843":23030,"52844":23012,"52845":23026,"52846":23031,"52847":23003,"52848":23017,"52849":23027,"52850":23029,"52851":23008,"52852":23038,"52853":23028,"52854":23021,"52855":23464,"52856":23628,"52857":23760,"52858":23768,"52859":23756,"52860":23767,"52861":23755,"52862":23771,"52897":23774,"52898":23770,"52899":23753,"52900":23751,"52901":23754,"52902":23766,"52903":23763,"52904":23764,"52905":23759,"52906":23752,"52907":23750,"52908":23758,"52909":23775,"52910":23800,"52911":24057,"52912":24097,"52913":24098,"52914":24099,"52915":24096,"52916":24100,"52917":24240,"52918":24228,"52919":24226,"52920":24219,"52921":24227,"52922":24229,"52923":24327,"52924":24366,"52925":24406,"52926":24454,"52927":24631,"52928":24633,"52929":24660,"52930":24690,"52931":24670,"52932":24645,"52933":24659,"52934":24647,"52935":24649,"52936":24667,"52937":24652,"52938":24640,"52939":24642,"52940":24671,"52941":24612,"52942":24644,"52943":24664,"52944":24678,"52945":24686,"52946":25154,"52947":25155,"52948":25295,"52949":25357,"52950":25355,"52951":25333,"52952":25358,"52953":25347,"52954":25323,"52955":25337,"52956":25359,"52957":25356,"52958":25336,"52959":25334,"52960":25344,"52961":25363,"52962":25364,"52963":25338,"52964":25365,"52965":25339,"52966":25328,"52967":25921,"52968":25923,"52969":26026,"52970":26047,"52971":26166,"52972":26145,"52973":26162,"52974":26165,"52975":26140,"52976":26150,"52977":26146,"52978":26163,"52979":26155,"52980":26170,"52981":26141,"52982":26164,"52983":26169,"52984":26158,"52985":26383,"52986":26384,"52987":26561,"52988":26610,"52989":26568,"52990":26554,"53056":26588,"53057":26555,"53058":26616,"53059":26584,"53060":26560,"53061":26551,"53062":26565,"53063":26603,"53064":26596,"53065":26591,"53066":26549,"53067":26573,"53068":26547,"53069":26615,"53070":26614,"53071":26606,"53072":26595,"53073":26562,"53074":26553,"53075":26574,"53076":26599,"53077":26608,"53078":26546,"53079":26620,"53080":26566,"53081":26605,"53082":26572,"53083":26542,"53084":26598,"53085":26587,"53086":26618,"53087":26569,"53088":26570,"53089":26563,"53090":26602,"53091":26571,"53092":27432,"53093":27522,"53094":27524,"53095":27574,"53096":27606,"53097":27608,"53098":27616,"53099":27680,"53100":27681,"53101":27944,"53102":27956,"53103":27949,"53104":27935,"53105":27964,"53106":27967,"53107":27922,"53108":27914,"53109":27866,"53110":27955,"53111":27908,"53112":27929,"53113":27962,"53114":27930,"53115":27921,"53116":27904,"53117":27933,"53118":27970,"53153":27905,"53154":27928,"53155":27959,"53156":27907,"53157":27919,"53158":27968,"53159":27911,"53160":27936,"53161":27948,"53162":27912,"53163":27938,"53164":27913,"53165":27920,"53166":28855,"53167":28831,"53168":28862,"53169":28849,"53170":28848,"53171":28833,"53172":28852,"53173":28853,"53174":28841,"53175":29249,"53176":29257,"53177":29258,"53178":29292,"53179":29296,"53180":29299,"53181":29294,"53182":29386,"53183":29412,"53184":29416,"53185":29419,"53186":29407,"53187":29418,"53188":29414,"53189":29411,"53190":29573,"53191":29644,"53192":29634,"53193":29640,"53194":29637,"53195":29625,"53196":29622,"53197":29621,"53198":29620,"53199":29675,"53200":29631,"53201":29639,"53202":29630,"53203":29635,"53204":29638,"53205":29624,"53206":29643,"53207":29932,"53208":29934,"53209":29998,"53210":30023,"53211":30024,"53212":30119,"53213":30122,"53214":30329,"53215":30404,"53216":30472,"53217":30467,"53218":30468,"53219":30469,"53220":30474,"53221":30455,"53222":30459,"53223":30458,"53224":30695,"53225":30696,"53226":30726,"53227":30737,"53228":30738,"53229":30725,"53230":30736,"53231":30735,"53232":30734,"53233":30729,"53234":30723,"53235":30739,"53236":31050,"53237":31052,"53238":31051,"53239":31045,"53240":31044,"53241":31189,"53242":31181,"53243":31183,"53244":31190,"53245":31182,"53246":31360,"53312":31358,"53313":31441,"53314":31488,"53315":31489,"53316":31866,"53317":31864,"53318":31865,"53319":31871,"53320":31872,"53321":31873,"53322":32003,"53323":32008,"53324":32001,"53325":32600,"53326":32657,"53327":32653,"53328":32702,"53329":32775,"53330":32782,"53331":32783,"53332":32788,"53333":32823,"53334":32984,"53335":32967,"53336":32992,"53337":32977,"53338":32968,"53339":32962,"53340":32976,"53341":32965,"53342":32995,"53343":32985,"53344":32988,"53345":32970,"53346":32981,"53347":32969,"53348":32975,"53349":32983,"53350":32998,"53351":32973,"53352":33279,"53353":33313,"53354":33428,"53355":33497,"53356":33534,"53357":33529,"53358":33543,"53359":33512,"53360":33536,"53361":33493,"53362":33594,"53363":33515,"53364":33494,"53365":33524,"53366":33516,"53367":33505,"53368":33522,"53369":33525,"53370":33548,"53371":33531,"53372":33526,"53373":33520,"53374":33514,"53409":33508,"53410":33504,"53411":33530,"53412":33523,"53413":33517,"53414":34423,"53415":34420,"53416":34428,"53417":34419,"53418":34881,"53419":34894,"53420":34919,"53421":34922,"53422":34921,"53423":35283,"53424":35332,"53425":35335,"53426":36210,"53427":36835,"53428":36833,"53429":36846,"53430":36832,"53431":37105,"53432":37053,"53433":37055,"53434":37077,"53435":37061,"53436":37054,"53437":37063,"53438":37067,"53439":37064,"53440":37332,"53441":37331,"53442":38484,"53443":38479,"53444":38481,"53445":38483,"53446":38474,"53447":38478,"53448":20510,"53449":20485,"53450":20487,"53451":20499,"53452":20514,"53453":20528,"53454":20507,"53455":20469,"53456":20468,"53457":20531,"53458":20535,"53459":20524,"53460":20470,"53461":20471,"53462":20503,"53463":20508,"53464":20512,"53465":20519,"53466":20533,"53467":20527,"53468":20529,"53469":20494,"53470":20826,"53471":20884,"53472":20883,"53473":20938,"53474":20932,"53475":20933,"53476":20936,"53477":20942,"53478":21089,"53479":21082,"53480":21074,"53481":21086,"53482":21087,"53483":21077,"53484":21090,"53485":21197,"53486":21262,"53487":21406,"53488":21798,"53489":21730,"53490":21783,"53491":21778,"53492":21735,"53493":21747,"53494":21732,"53495":21786,"53496":21759,"53497":21764,"53498":21768,"53499":21739,"53500":21777,"53501":21765,"53502":21745,"53568":21770,"53569":21755,"53570":21751,"53571":21752,"53572":21728,"53573":21774,"53574":21763,"53575":21771,"53576":22273,"53577":22274,"53578":22476,"53579":22578,"53580":22485,"53581":22482,"53582":22458,"53583":22470,"53584":22461,"53585":22460,"53586":22456,"53587":22454,"53588":22463,"53589":22471,"53590":22480,"53591":22457,"53592":22465,"53593":22798,"53594":22858,"53595":23065,"53596":23062,"53597":23085,"53598":23086,"53599":23061,"53600":23055,"53601":23063,"53602":23050,"53603":23070,"53604":23091,"53605":23404,"53606":23463,"53607":23469,"53608":23468,"53609":23555,"53610":23638,"53611":23636,"53612":23788,"53613":23807,"53614":23790,"53615":23793,"53616":23799,"53617":23808,"53618":23801,"53619":24105,"53620":24104,"53621":24232,"53622":24238,"53623":24234,"53624":24236,"53625":24371,"53626":24368,"53627":24423,"53628":24669,"53629":24666,"53630":24679,"53665":24641,"53666":24738,"53667":24712,"53668":24704,"53669":24722,"53670":24705,"53671":24733,"53672":24707,"53673":24725,"53674":24731,"53675":24727,"53676":24711,"53677":24732,"53678":24718,"53679":25113,"53680":25158,"53681":25330,"53682":25360,"53683":25430,"53684":25388,"53685":25412,"53686":25413,"53687":25398,"53688":25411,"53689":25572,"53690":25401,"53691":25419,"53692":25418,"53693":25404,"53694":25385,"53695":25409,"53696":25396,"53697":25432,"53698":25428,"53699":25433,"53700":25389,"53701":25415,"53702":25395,"53703":25434,"53704":25425,"53705":25400,"53706":25431,"53707":25408,"53708":25416,"53709":25930,"53710":25926,"53711":26054,"53712":26051,"53713":26052,"53714":26050,"53715":26186,"53716":26207,"53717":26183,"53718":26193,"53719":26386,"53720":26387,"53721":26655,"53722":26650,"53723":26697,"53724":26674,"53725":26675,"53726":26683,"53727":26699,"53728":26703,"53729":26646,"53730":26673,"53731":26652,"53732":26677,"53733":26667,"53734":26669,"53735":26671,"53736":26702,"53737":26692,"53738":26676,"53739":26653,"53740":26642,"53741":26644,"53742":26662,"53743":26664,"53744":26670,"53745":26701,"53746":26682,"53747":26661,"53748":26656,"53749":27436,"53750":27439,"53751":27437,"53752":27441,"53753":27444,"53754":27501,"53755":32898,"53756":27528,"53757":27622,"53758":27620,"53824":27624,"53825":27619,"53826":27618,"53827":27623,"53828":27685,"53829":28026,"53830":28003,"53831":28004,"53832":28022,"53833":27917,"53834":28001,"53835":28050,"53836":27992,"53837":28002,"53838":28013,"53839":28015,"53840":28049,"53841":28045,"53842":28143,"53843":28031,"53844":28038,"53845":27998,"53846":28007,"53847":28000,"53848":28055,"53849":28016,"53850":28028,"53851":27999,"53852":28034,"53853":28056,"53854":27951,"53855":28008,"53856":28043,"53857":28030,"53858":28032,"53859":28036,"53860":27926,"53861":28035,"53862":28027,"53863":28029,"53864":28021,"53865":28048,"53866":28892,"53867":28883,"53868":28881,"53869":28893,"53870":28875,"53871":32569,"53872":28898,"53873":28887,"53874":28882,"53875":28894,"53876":28896,"53877":28884,"53878":28877,"53879":28869,"53880":28870,"53881":28871,"53882":28890,"53883":28878,"53884":28897,"53885":29250,"53886":29304,"53921":29303,"53922":29302,"53923":29440,"53924":29434,"53925":29428,"53926":29438,"53927":29430,"53928":29427,"53929":29435,"53930":29441,"53931":29651,"53932":29657,"53933":29669,"53934":29654,"53935":29628,"53936":29671,"53937":29667,"53938":29673,"53939":29660,"53940":29650,"53941":29659,"53942":29652,"53943":29661,"53944":29658,"53945":29655,"53946":29656,"53947":29672,"53948":29918,"53949":29919,"53950":29940,"53951":29941,"53952":29985,"53953":30043,"53954":30047,"53955":30128,"53956":30145,"53957":30139,"53958":30148,"53959":30144,"53960":30143,"53961":30134,"53962":30138,"53963":30346,"53964":30409,"53965":30493,"53966":30491,"53967":30480,"53968":30483,"53969":30482,"53970":30499,"53971":30481,"53972":30485,"53973":30489,"53974":30490,"53975":30498,"53976":30503,"53977":30755,"53978":30764,"53979":30754,"53980":30773,"53981":30767,"53982":30760,"53983":30766,"53984":30763,"53985":30753,"53986":30761,"53987":30771,"53988":30762,"53989":30769,"53990":31060,"53991":31067,"53992":31055,"53993":31068,"53994":31059,"53995":31058,"53996":31057,"53997":31211,"53998":31212,"53999":31200,"54000":31214,"54001":31213,"54002":31210,"54003":31196,"54004":31198,"54005":31197,"54006":31366,"54007":31369,"54008":31365,"54009":31371,"54010":31372,"54011":31370,"54012":31367,"54013":31448,"54014":31504,"54080":31492,"54081":31507,"54082":31493,"54083":31503,"54084":31496,"54085":31498,"54086":31502,"54087":31497,"54088":31506,"54089":31876,"54090":31889,"54091":31882,"54092":31884,"54093":31880,"54094":31885,"54095":31877,"54096":32030,"54097":32029,"54098":32017,"54099":32014,"54100":32024,"54101":32022,"54102":32019,"54103":32031,"54104":32018,"54105":32015,"54106":32012,"54107":32604,"54108":32609,"54109":32606,"54110":32608,"54111":32605,"54112":32603,"54113":32662,"54114":32658,"54115":32707,"54116":32706,"54117":32704,"54118":32790,"54119":32830,"54120":32825,"54121":33018,"54122":33010,"54123":33017,"54124":33013,"54125":33025,"54126":33019,"54127":33024,"54128":33281,"54129":33327,"54130":33317,"54131":33587,"54132":33581,"54133":33604,"54134":33561,"54135":33617,"54136":33573,"54137":33622,"54138":33599,"54139":33601,"54140":33574,"54141":33564,"54142":33570,"54177":33602,"54178":33614,"54179":33563,"54180":33578,"54181":33544,"54182":33596,"54183":33613,"54184":33558,"54185":33572,"54186":33568,"54187":33591,"54188":33583,"54189":33577,"54190":33607,"54191":33605,"54192":33612,"54193":33619,"54194":33566,"54195":33580,"54196":33611,"54197":33575,"54198":33608,"54199":34387,"54200":34386,"54201":34466,"54202":34472,"54203":34454,"54204":34445,"54205":34449,"54206":34462,"54207":34439,"54208":34455,"54209":34438,"54210":34443,"54211":34458,"54212":34437,"54213":34469,"54214":34457,"54215":34465,"54216":34471,"54217":34453,"54218":34456,"54219":34446,"54220":34461,"54221":34448,"54222":34452,"54223":34883,"54224":34884,"54225":34925,"54226":34933,"54227":34934,"54228":34930,"54229":34944,"54230":34929,"54231":34943,"54232":34927,"54233":34947,"54234":34942,"54235":34932,"54236":34940,"54237":35346,"54238":35911,"54239":35927,"54240":35963,"54241":36004,"54242":36003,"54243":36214,"54244":36216,"54245":36277,"54246":36279,"54247":36278,"54248":36561,"54249":36563,"54250":36862,"54251":36853,"54252":36866,"54253":36863,"54254":36859,"54255":36868,"54256":36860,"54257":36854,"54258":37078,"54259":37088,"54260":37081,"54261":37082,"54262":37091,"54263":37087,"54264":37093,"54265":37080,"54266":37083,"54267":37079,"54268":37084,"54269":37092,"54270":37200,"54336":37198,"54337":37199,"54338":37333,"54339":37346,"54340":37338,"54341":38492,"54342":38495,"54343":38588,"54344":39139,"54345":39647,"54346":39727,"54347":20095,"54348":20592,"54349":20586,"54350":20577,"54351":20574,"54352":20576,"54353":20563,"54354":20555,"54355":20573,"54356":20594,"54357":20552,"54358":20557,"54359":20545,"54360":20571,"54361":20554,"54362":20578,"54363":20501,"54364":20549,"54365":20575,"54366":20585,"54367":20587,"54368":20579,"54369":20580,"54370":20550,"54371":20544,"54372":20590,"54373":20595,"54374":20567,"54375":20561,"54376":20944,"54377":21099,"54378":21101,"54379":21100,"54380":21102,"54381":21206,"54382":21203,"54383":21293,"54384":21404,"54385":21877,"54386":21878,"54387":21820,"54388":21837,"54389":21840,"54390":21812,"54391":21802,"54392":21841,"54393":21858,"54394":21814,"54395":21813,"54396":21808,"54397":21842,"54398":21829,"54433":21772,"54434":21810,"54435":21861,"54436":21838,"54437":21817,"54438":21832,"54439":21805,"54440":21819,"54441":21824,"54442":21835,"54443":22282,"54444":22279,"54445":22523,"54446":22548,"54447":22498,"54448":22518,"54449":22492,"54450":22516,"54451":22528,"54452":22509,"54453":22525,"54454":22536,"54455":22520,"54456":22539,"54457":22515,"54458":22479,"54459":22535,"54460":22510,"54461":22499,"54462":22514,"54463":22501,"54464":22508,"54465":22497,"54466":22542,"54467":22524,"54468":22544,"54469":22503,"54470":22529,"54471":22540,"54472":22513,"54473":22505,"54474":22512,"54475":22541,"54476":22532,"54477":22876,"54478":23136,"54479":23128,"54480":23125,"54481":23143,"54482":23134,"54483":23096,"54484":23093,"54485":23149,"54486":23120,"54487":23135,"54488":23141,"54489":23148,"54490":23123,"54491":23140,"54492":23127,"54493":23107,"54494":23133,"54495":23122,"54496":23108,"54497":23131,"54498":23112,"54499":23182,"54500":23102,"54501":23117,"54502":23097,"54503":23116,"54504":23152,"54505":23145,"54506":23111,"54507":23121,"54508":23126,"54509":23106,"54510":23132,"54511":23410,"54512":23406,"54513":23489,"54514":23488,"54515":23641,"54516":23838,"54517":23819,"54518":23837,"54519":23834,"54520":23840,"54521":23820,"54522":23848,"54523":23821,"54524":23846,"54525":23845,"54526":23823,"54592":23856,"54593":23826,"54594":23843,"54595":23839,"54596":23854,"54597":24126,"54598":24116,"54599":24241,"54600":24244,"54601":24249,"54602":24242,"54603":24243,"54604":24374,"54605":24376,"54606":24475,"54607":24470,"54608":24479,"54609":24714,"54610":24720,"54611":24710,"54612":24766,"54613":24752,"54614":24762,"54615":24787,"54616":24788,"54617":24783,"54618":24804,"54619":24793,"54620":24797,"54621":24776,"54622":24753,"54623":24795,"54624":24759,"54625":24778,"54626":24767,"54627":24771,"54628":24781,"54629":24768,"54630":25394,"54631":25445,"54632":25482,"54633":25474,"54634":25469,"54635":25533,"54636":25502,"54637":25517,"54638":25501,"54639":25495,"54640":25515,"54641":25486,"54642":25455,"54643":25479,"54644":25488,"54645":25454,"54646":25519,"54647":25461,"54648":25500,"54649":25453,"54650":25518,"54651":25468,"54652":25508,"54653":25403,"54654":25503,"54689":25464,"54690":25477,"54691":25473,"54692":25489,"54693":25485,"54694":25456,"54695":25939,"54696":26061,"54697":26213,"54698":26209,"54699":26203,"54700":26201,"54701":26204,"54702":26210,"54703":26392,"54704":26745,"54705":26759,"54706":26768,"54707":26780,"54708":26733,"54709":26734,"54710":26798,"54711":26795,"54712":26966,"54713":26735,"54714":26787,"54715":26796,"54716":26793,"54717":26741,"54718":26740,"54719":26802,"54720":26767,"54721":26743,"54722":26770,"54723":26748,"54724":26731,"54725":26738,"54726":26794,"54727":26752,"54728":26737,"54729":26750,"54730":26779,"54731":26774,"54732":26763,"54733":26784,"54734":26761,"54735":26788,"54736":26744,"54737":26747,"54738":26769,"54739":26764,"54740":26762,"54741":26749,"54742":27446,"54743":27443,"54744":27447,"54745":27448,"54746":27537,"54747":27535,"54748":27533,"54749":27534,"54750":27532,"54751":27690,"54752":28096,"54753":28075,"54754":28084,"54755":28083,"54756":28276,"54757":28076,"54758":28137,"54759":28130,"54760":28087,"54761":28150,"54762":28116,"54763":28160,"54764":28104,"54765":28128,"54766":28127,"54767":28118,"54768":28094,"54769":28133,"54770":28124,"54771":28125,"54772":28123,"54773":28148,"54774":28106,"54775":28093,"54776":28141,"54777":28144,"54778":28090,"54779":28117,"54780":28098,"54781":28111,"54782":28105,"54848":28112,"54849":28146,"54850":28115,"54851":28157,"54852":28119,"54853":28109,"54854":28131,"54855":28091,"54856":28922,"54857":28941,"54858":28919,"54859":28951,"54860":28916,"54861":28940,"54862":28912,"54863":28932,"54864":28915,"54865":28944,"54866":28924,"54867":28927,"54868":28934,"54869":28947,"54870":28928,"54871":28920,"54872":28918,"54873":28939,"54874":28930,"54875":28942,"54876":29310,"54877":29307,"54878":29308,"54879":29311,"54880":29469,"54881":29463,"54882":29447,"54883":29457,"54884":29464,"54885":29450,"54886":29448,"54887":29439,"54888":29455,"54889":29470,"54890":29576,"54891":29686,"54892":29688,"54893":29685,"54894":29700,"54895":29697,"54896":29693,"54897":29703,"54898":29696,"54899":29690,"54900":29692,"54901":29695,"54902":29708,"54903":29707,"54904":29684,"54905":29704,"54906":30052,"54907":30051,"54908":30158,"54909":30162,"54910":30159,"54945":30155,"54946":30156,"54947":30161,"54948":30160,"54949":30351,"54950":30345,"54951":30419,"54952":30521,"54953":30511,"54954":30509,"54955":30513,"54956":30514,"54957":30516,"54958":30515,"54959":30525,"54960":30501,"54961":30523,"54962":30517,"54963":30792,"54964":30802,"54965":30793,"54966":30797,"54967":30794,"54968":30796,"54969":30758,"54970":30789,"54971":30800,"54972":31076,"54973":31079,"54974":31081,"54975":31082,"54976":31075,"54977":31083,"54978":31073,"54979":31163,"54980":31226,"54981":31224,"54982":31222,"54983":31223,"54984":31375,"54985":31380,"54986":31376,"54987":31541,"54988":31559,"54989":31540,"54990":31525,"54991":31536,"54992":31522,"54993":31524,"54994":31539,"54995":31512,"54996":31530,"54997":31517,"54998":31537,"54999":31531,"55000":31533,"55001":31535,"55002":31538,"55003":31544,"55004":31514,"55005":31523,"55006":31892,"55007":31896,"55008":31894,"55009":31907,"55010":32053,"55011":32061,"55012":32056,"55013":32054,"55014":32058,"55015":32069,"55016":32044,"55017":32041,"55018":32065,"55019":32071,"55020":32062,"55021":32063,"55022":32074,"55023":32059,"55024":32040,"55025":32611,"55026":32661,"55027":32668,"55028":32669,"55029":32667,"55030":32714,"55031":32715,"55032":32717,"55033":32720,"55034":32721,"55035":32711,"55036":32719,"55037":32713,"55038":32799,"55104":32798,"55105":32795,"55106":32839,"55107":32835,"55108":32840,"55109":33048,"55110":33061,"55111":33049,"55112":33051,"55113":33069,"55114":33055,"55115":33068,"55116":33054,"55117":33057,"55118":33045,"55119":33063,"55120":33053,"55121":33058,"55122":33297,"55123":33336,"55124":33331,"55125":33338,"55126":33332,"55127":33330,"55128":33396,"55129":33680,"55130":33699,"55131":33704,"55132":33677,"55133":33658,"55134":33651,"55135":33700,"55136":33652,"55137":33679,"55138":33665,"55139":33685,"55140":33689,"55141":33653,"55142":33684,"55143":33705,"55144":33661,"55145":33667,"55146":33676,"55147":33693,"55148":33691,"55149":33706,"55150":33675,"55151":33662,"55152":33701,"55153":33711,"55154":33672,"55155":33687,"55156":33712,"55157":33663,"55158":33702,"55159":33671,"55160":33710,"55161":33654,"55162":33690,"55163":34393,"55164":34390,"55165":34495,"55166":34487,"55201":34498,"55202":34497,"55203":34501,"55204":34490,"55205":34480,"55206":34504,"55207":34489,"55208":34483,"55209":34488,"55210":34508,"55211":34484,"55212":34491,"55213":34492,"55214":34499,"55215":34493,"55216":34494,"55217":34898,"55218":34953,"55219":34965,"55220":34984,"55221":34978,"55222":34986,"55223":34970,"55224":34961,"55225":34977,"55226":34975,"55227":34968,"55228":34983,"55229":34969,"55230":34971,"55231":34967,"55232":34980,"55233":34988,"55234":34956,"55235":34963,"55236":34958,"55237":35202,"55238":35286,"55239":35289,"55240":35285,"55241":35376,"55242":35367,"55243":35372,"55244":35358,"55245":35897,"55246":35899,"55247":35932,"55248":35933,"55249":35965,"55250":36005,"55251":36221,"55252":36219,"55253":36217,"55254":36284,"55255":36290,"55256":36281,"55257":36287,"55258":36289,"55259":36568,"55260":36574,"55261":36573,"55262":36572,"55263":36567,"55264":36576,"55265":36577,"55266":36900,"55267":36875,"55268":36881,"55269":36892,"55270":36876,"55271":36897,"55272":37103,"55273":37098,"55274":37104,"55275":37108,"55276":37106,"55277":37107,"55278":37076,"55279":37099,"55280":37100,"55281":37097,"55282":37206,"55283":37208,"55284":37210,"55285":37203,"55286":37205,"55287":37356,"55288":37364,"55289":37361,"55290":37363,"55291":37368,"55292":37348,"55293":37369,"55294":37354,"55360":37355,"55361":37367,"55362":37352,"55363":37358,"55364":38266,"55365":38278,"55366":38280,"55367":38524,"55368":38509,"55369":38507,"55370":38513,"55371":38511,"55372":38591,"55373":38762,"55374":38916,"55375":39141,"55376":39319,"55377":20635,"55378":20629,"55379":20628,"55380":20638,"55381":20619,"55382":20643,"55383":20611,"55384":20620,"55385":20622,"55386":20637,"55387":20584,"55388":20636,"55389":20626,"55390":20610,"55391":20615,"55392":20831,"55393":20948,"55394":21266,"55395":21265,"55396":21412,"55397":21415,"55398":21905,"55399":21928,"55400":21925,"55401":21933,"55402":21879,"55403":22085,"55404":21922,"55405":21907,"55406":21896,"55407":21903,"55408":21941,"55409":21889,"55410":21923,"55411":21906,"55412":21924,"55413":21885,"55414":21900,"55415":21926,"55416":21887,"55417":21909,"55418":21921,"55419":21902,"55420":22284,"55421":22569,"55422":22583,"55457":22553,"55458":22558,"55459":22567,"55460":22563,"55461":22568,"55462":22517,"55463":22600,"55464":22565,"55465":22556,"55466":22555,"55467":22579,"55468":22591,"55469":22582,"55470":22574,"55471":22585,"55472":22584,"55473":22573,"55474":22572,"55475":22587,"55476":22881,"55477":23215,"55478":23188,"55479":23199,"55480":23162,"55481":23202,"55482":23198,"55483":23160,"55484":23206,"55485":23164,"55486":23205,"55487":23212,"55488":23189,"55489":23214,"55490":23095,"55491":23172,"55492":23178,"55493":23191,"55494":23171,"55495":23179,"55496":23209,"55497":23163,"55498":23165,"55499":23180,"55500":23196,"55501":23183,"55502":23187,"55503":23197,"55504":23530,"55505":23501,"55506":23499,"55507":23508,"55508":23505,"55509":23498,"55510":23502,"55511":23564,"55512":23600,"55513":23863,"55514":23875,"55515":23915,"55516":23873,"55517":23883,"55518":23871,"55519":23861,"55520":23889,"55521":23886,"55522":23893,"55523":23859,"55524":23866,"55525":23890,"55526":23869,"55527":23857,"55528":23897,"55529":23874,"55530":23865,"55531":23881,"55532":23864,"55533":23868,"55534":23858,"55535":23862,"55536":23872,"55537":23877,"55538":24132,"55539":24129,"55540":24408,"55541":24486,"55542":24485,"55543":24491,"55544":24777,"55545":24761,"55546":24780,"55547":24802,"55548":24782,"55549":24772,"55550":24852,"55616":24818,"55617":24842,"55618":24854,"55619":24837,"55620":24821,"55621":24851,"55622":24824,"55623":24828,"55624":24830,"55625":24769,"55626":24835,"55627":24856,"55628":24861,"55629":24848,"55630":24831,"55631":24836,"55632":24843,"55633":25162,"55634":25492,"55635":25521,"55636":25520,"55637":25550,"55638":25573,"55639":25576,"55640":25583,"55641":25539,"55642":25757,"55643":25587,"55644":25546,"55645":25568,"55646":25590,"55647":25557,"55648":25586,"55649":25589,"55650":25697,"55651":25567,"55652":25534,"55653":25565,"55654":25564,"55655":25540,"55656":25560,"55657":25555,"55658":25538,"55659":25543,"55660":25548,"55661":25547,"55662":25544,"55663":25584,"55664":25559,"55665":25561,"55666":25906,"55667":25959,"55668":25962,"55669":25956,"55670":25948,"55671":25960,"55672":25957,"55673":25996,"55674":26013,"55675":26014,"55676":26030,"55677":26064,"55678":26066,"55713":26236,"55714":26220,"55715":26235,"55716":26240,"55717":26225,"55718":26233,"55719":26218,"55720":26226,"55721":26369,"55722":26892,"55723":26835,"55724":26884,"55725":26844,"55726":26922,"55727":26860,"55728":26858,"55729":26865,"55730":26895,"55731":26838,"55732":26871,"55733":26859,"55734":26852,"55735":26870,"55736":26899,"55737":26896,"55738":26867,"55739":26849,"55740":26887,"55741":26828,"55742":26888,"55743":26992,"55744":26804,"55745":26897,"55746":26863,"55747":26822,"55748":26900,"55749":26872,"55750":26832,"55751":26877,"55752":26876,"55753":26856,"55754":26891,"55755":26890,"55756":26903,"55757":26830,"55758":26824,"55759":26845,"55760":26846,"55761":26854,"55762":26868,"55763":26833,"55764":26886,"55765":26836,"55766":26857,"55767":26901,"55768":26917,"55769":26823,"55770":27449,"55771":27451,"55772":27455,"55773":27452,"55774":27540,"55775":27543,"55776":27545,"55777":27541,"55778":27581,"55779":27632,"55780":27634,"55781":27635,"55782":27696,"55783":28156,"55784":28230,"55785":28231,"55786":28191,"55787":28233,"55788":28296,"55789":28220,"55790":28221,"55791":28229,"55792":28258,"55793":28203,"55794":28223,"55795":28225,"55796":28253,"55797":28275,"55798":28188,"55799":28211,"55800":28235,"55801":28224,"55802":28241,"55803":28219,"55804":28163,"55805":28206,"55806":28254,"55872":28264,"55873":28252,"55874":28257,"55875":28209,"55876":28200,"55877":28256,"55878":28273,"55879":28267,"55880":28217,"55881":28194,"55882":28208,"55883":28243,"55884":28261,"55885":28199,"55886":28280,"55887":28260,"55888":28279,"55889":28245,"55890":28281,"55891":28242,"55892":28262,"55893":28213,"55894":28214,"55895":28250,"55896":28960,"55897":28958,"55898":28975,"55899":28923,"55900":28974,"55901":28977,"55902":28963,"55903":28965,"55904":28962,"55905":28978,"55906":28959,"55907":28968,"55908":28986,"55909":28955,"55910":29259,"55911":29274,"55912":29320,"55913":29321,"55914":29318,"55915":29317,"55916":29323,"55917":29458,"55918":29451,"55919":29488,"55920":29474,"55921":29489,"55922":29491,"55923":29479,"55924":29490,"55925":29485,"55926":29478,"55927":29475,"55928":29493,"55929":29452,"55930":29742,"55931":29740,"55932":29744,"55933":29739,"55934":29718,"55969":29722,"55970":29729,"55971":29741,"55972":29745,"55973":29732,"55974":29731,"55975":29725,"55976":29737,"55977":29728,"55978":29746,"55979":29947,"55980":29999,"55981":30063,"55982":30060,"55983":30183,"55984":30170,"55985":30177,"55986":30182,"55987":30173,"55988":30175,"55989":30180,"55990":30167,"55991":30357,"55992":30354,"55993":30426,"55994":30534,"55995":30535,"55996":30532,"55997":30541,"55998":30533,"55999":30538,"56000":30542,"56001":30539,"56002":30540,"56003":30686,"56004":30700,"56005":30816,"56006":30820,"56007":30821,"56008":30812,"56009":30829,"56010":30833,"56011":30826,"56012":30830,"56013":30832,"56014":30825,"56015":30824,"56016":30814,"56017":30818,"56018":31092,"56019":31091,"56020":31090,"56021":31088,"56022":31234,"56023":31242,"56024":31235,"56025":31244,"56026":31236,"56027":31385,"56028":31462,"56029":31460,"56030":31562,"56031":31547,"56032":31556,"56033":31560,"56034":31564,"56035":31566,"56036":31552,"56037":31576,"56038":31557,"56039":31906,"56040":31902,"56041":31912,"56042":31905,"56043":32088,"56044":32111,"56045":32099,"56046":32083,"56047":32086,"56048":32103,"56049":32106,"56050":32079,"56051":32109,"56052":32092,"56053":32107,"56054":32082,"56055":32084,"56056":32105,"56057":32081,"56058":32095,"56059":32078,"56060":32574,"56061":32575,"56062":32613,"56128":32614,"56129":32674,"56130":32672,"56131":32673,"56132":32727,"56133":32849,"56134":32847,"56135":32848,"56136":33022,"56137":32980,"56138":33091,"56139":33098,"56140":33106,"56141":33103,"56142":33095,"56143":33085,"56144":33101,"56145":33082,"56146":33254,"56147":33262,"56148":33271,"56149":33272,"56150":33273,"56151":33284,"56152":33340,"56153":33341,"56154":33343,"56155":33397,"56156":33595,"56157":33743,"56158":33785,"56159":33827,"56160":33728,"56161":33768,"56162":33810,"56163":33767,"56164":33764,"56165":33788,"56166":33782,"56167":33808,"56168":33734,"56169":33736,"56170":33771,"56171":33763,"56172":33727,"56173":33793,"56174":33757,"56175":33765,"56176":33752,"56177":33791,"56178":33761,"56179":33739,"56180":33742,"56181":33750,"56182":33781,"56183":33737,"56184":33801,"56185":33807,"56186":33758,"56187":33809,"56188":33798,"56189":33730,"56190":33779,"56225":33749,"56226":33786,"56227":33735,"56228":33745,"56229":33770,"56230":33811,"56231":33731,"56232":33772,"56233":33774,"56234":33732,"56235":33787,"56236":33751,"56237":33762,"56238":33819,"56239":33755,"56240":33790,"56241":34520,"56242":34530,"56243":34534,"56244":34515,"56245":34531,"56246":34522,"56247":34538,"56248":34525,"56249":34539,"56250":34524,"56251":34540,"56252":34537,"56253":34519,"56254":34536,"56255":34513,"56256":34888,"56257":34902,"56258":34901,"56259":35002,"56260":35031,"56261":35001,"56262":35000,"56263":35008,"56264":35006,"56265":34998,"56266":35004,"56267":34999,"56268":35005,"56269":34994,"56270":35073,"56271":35017,"56272":35221,"56273":35224,"56274":35223,"56275":35293,"56276":35290,"56277":35291,"56278":35406,"56279":35405,"56280":35385,"56281":35417,"56282":35392,"56283":35415,"56284":35416,"56285":35396,"56286":35397,"56287":35410,"56288":35400,"56289":35409,"56290":35402,"56291":35404,"56292":35407,"56293":35935,"56294":35969,"56295":35968,"56296":36026,"56297":36030,"56298":36016,"56299":36025,"56300":36021,"56301":36228,"56302":36224,"56303":36233,"56304":36312,"56305":36307,"56306":36301,"56307":36295,"56308":36310,"56309":36316,"56310":36303,"56311":36309,"56312":36313,"56313":36296,"56314":36311,"56315":36293,"56316":36591,"56317":36599,"56318":36602,"56384":36601,"56385":36582,"56386":36590,"56387":36581,"56388":36597,"56389":36583,"56390":36584,"56391":36598,"56392":36587,"56393":36593,"56394":36588,"56395":36596,"56396":36585,"56397":36909,"56398":36916,"56399":36911,"56400":37126,"56401":37164,"56402":37124,"56403":37119,"56404":37116,"56405":37128,"56406":37113,"56407":37115,"56408":37121,"56409":37120,"56410":37127,"56411":37125,"56412":37123,"56413":37217,"56414":37220,"56415":37215,"56416":37218,"56417":37216,"56418":37377,"56419":37386,"56420":37413,"56421":37379,"56422":37402,"56423":37414,"56424":37391,"56425":37388,"56426":37376,"56427":37394,"56428":37375,"56429":37373,"56430":37382,"56431":37380,"56432":37415,"56433":37378,"56434":37404,"56435":37412,"56436":37401,"56437":37399,"56438":37381,"56439":37398,"56440":38267,"56441":38285,"56442":38284,"56443":38288,"56444":38535,"56445":38526,"56446":38536,"56481":38537,"56482":38531,"56483":38528,"56484":38594,"56485":38600,"56486":38595,"56487":38641,"56488":38640,"56489":38764,"56490":38768,"56491":38766,"56492":38919,"56493":39081,"56494":39147,"56495":40166,"56496":40697,"56497":20099,"56498":20100,"56499":20150,"56500":20669,"56501":20671,"56502":20678,"56503":20654,"56504":20676,"56505":20682,"56506":20660,"56507":20680,"56508":20674,"56509":20656,"56510":20673,"56511":20666,"56512":20657,"56513":20683,"56514":20681,"56515":20662,"56516":20664,"56517":20951,"56518":21114,"56519":21112,"56520":21115,"56521":21116,"56522":21955,"56523":21979,"56524":21964,"56525":21968,"56526":21963,"56527":21962,"56528":21981,"56529":21952,"56530":21972,"56531":21956,"56532":21993,"56533":21951,"56534":21970,"56535":21901,"56536":21967,"56537":21973,"56538":21986,"56539":21974,"56540":21960,"56541":22002,"56542":21965,"56543":21977,"56544":21954,"56545":22292,"56546":22611,"56547":22632,"56548":22628,"56549":22607,"56550":22605,"56551":22601,"56552":22639,"56553":22613,"56554":22606,"56555":22621,"56556":22617,"56557":22629,"56558":22619,"56559":22589,"56560":22627,"56561":22641,"56562":22780,"56563":23239,"56564":23236,"56565":23243,"56566":23226,"56567":23224,"56568":23217,"56569":23221,"56570":23216,"56571":23231,"56572":23240,"56573":23227,"56574":23238,"56640":23223,"56641":23232,"56642":23242,"56643":23220,"56644":23222,"56645":23245,"56646":23225,"56647":23184,"56648":23510,"56649":23512,"56650":23513,"56651":23583,"56652":23603,"56653":23921,"56654":23907,"56655":23882,"56656":23909,"56657":23922,"56658":23916,"56659":23902,"56660":23912,"56661":23911,"56662":23906,"56663":24048,"56664":24143,"56665":24142,"56666":24138,"56667":24141,"56668":24139,"56669":24261,"56670":24268,"56671":24262,"56672":24267,"56673":24263,"56674":24384,"56675":24495,"56676":24493,"56677":24823,"56678":24905,"56679":24906,"56680":24875,"56681":24901,"56682":24886,"56683":24882,"56684":24878,"56685":24902,"56686":24879,"56687":24911,"56688":24873,"56689":24896,"56690":25120,"56691":37224,"56692":25123,"56693":25125,"56694":25124,"56695":25541,"56696":25585,"56697":25579,"56698":25616,"56699":25618,"56700":25609,"56701":25632,"56702":25636,"56737":25651,"56738":25667,"56739":25631,"56740":25621,"56741":25624,"56742":25657,"56743":25655,"56744":25634,"56745":25635,"56746":25612,"56747":25638,"56748":25648,"56749":25640,"56750":25665,"56751":25653,"56752":25647,"56753":25610,"56754":25626,"56755":25664,"56756":25637,"56757":25639,"56758":25611,"56759":25575,"56760":25627,"56761":25646,"56762":25633,"56763":25614,"56764":25967,"56765":26002,"56766":26067,"56767":26246,"56768":26252,"56769":26261,"56770":26256,"56771":26251,"56772":26250,"56773":26265,"56774":26260,"56775":26232,"56776":26400,"56777":26982,"56778":26975,"56779":26936,"56780":26958,"56781":26978,"56782":26993,"56783":26943,"56784":26949,"56785":26986,"56786":26937,"56787":26946,"56788":26967,"56789":26969,"56790":27002,"56791":26952,"56792":26953,"56793":26933,"56794":26988,"56795":26931,"56796":26941,"56797":26981,"56798":26864,"56799":27000,"56800":26932,"56801":26985,"56802":26944,"56803":26991,"56804":26948,"56805":26998,"56806":26968,"56807":26945,"56808":26996,"56809":26956,"56810":26939,"56811":26955,"56812":26935,"56813":26972,"56814":26959,"56815":26961,"56816":26930,"56817":26962,"56818":26927,"56819":27003,"56820":26940,"56821":27462,"56822":27461,"56823":27459,"56824":27458,"56825":27464,"56826":27457,"56827":27547,"56828":64013,"56829":27643,"56830":27644,"56896":27641,"56897":27639,"56898":27640,"56899":28315,"56900":28374,"56901":28360,"56902":28303,"56903":28352,"56904":28319,"56905":28307,"56906":28308,"56907":28320,"56908":28337,"56909":28345,"56910":28358,"56911":28370,"56912":28349,"56913":28353,"56914":28318,"56915":28361,"56916":28343,"56917":28336,"56918":28365,"56919":28326,"56920":28367,"56921":28338,"56922":28350,"56923":28355,"56924":28380,"56925":28376,"56926":28313,"56927":28306,"56928":28302,"56929":28301,"56930":28324,"56931":28321,"56932":28351,"56933":28339,"56934":28368,"56935":28362,"56936":28311,"56937":28334,"56938":28323,"56939":28999,"56940":29012,"56941":29010,"56942":29027,"56943":29024,"56944":28993,"56945":29021,"56946":29026,"56947":29042,"56948":29048,"56949":29034,"56950":29025,"56951":28994,"56952":29016,"56953":28995,"56954":29003,"56955":29040,"56956":29023,"56957":29008,"56958":29011,"56993":28996,"56994":29005,"56995":29018,"56996":29263,"56997":29325,"56998":29324,"56999":29329,"57000":29328,"57001":29326,"57002":29500,"57003":29506,"57004":29499,"57005":29498,"57006":29504,"57007":29514,"57008":29513,"57009":29764,"57010":29770,"57011":29771,"57012":29778,"57013":29777,"57014":29783,"57015":29760,"57016":29775,"57017":29776,"57018":29774,"57019":29762,"57020":29766,"57021":29773,"57022":29780,"57023":29921,"57024":29951,"57025":29950,"57026":29949,"57027":29981,"57028":30073,"57029":30071,"57030":27011,"57031":30191,"57032":30223,"57033":30211,"57034":30199,"57035":30206,"57036":30204,"57037":30201,"57038":30200,"57039":30224,"57040":30203,"57041":30198,"57042":30189,"57043":30197,"57044":30205,"57045":30361,"57046":30389,"57047":30429,"57048":30549,"57049":30559,"57050":30560,"57051":30546,"57052":30550,"57053":30554,"57054":30569,"57055":30567,"57056":30548,"57057":30553,"57058":30573,"57059":30688,"57060":30855,"57061":30874,"57062":30868,"57063":30863,"57064":30852,"57065":30869,"57066":30853,"57067":30854,"57068":30881,"57069":30851,"57070":30841,"57071":30873,"57072":30848,"57073":30870,"57074":30843,"57075":31100,"57076":31106,"57077":31101,"57078":31097,"57079":31249,"57080":31256,"57081":31257,"57082":31250,"57083":31255,"57084":31253,"57085":31266,"57086":31251,"57152":31259,"57153":31248,"57154":31395,"57155":31394,"57156":31390,"57157":31467,"57158":31590,"57159":31588,"57160":31597,"57161":31604,"57162":31593,"57163":31602,"57164":31589,"57165":31603,"57166":31601,"57167":31600,"57168":31585,"57169":31608,"57170":31606,"57171":31587,"57172":31922,"57173":31924,"57174":31919,"57175":32136,"57176":32134,"57177":32128,"57178":32141,"57179":32127,"57180":32133,"57181":32122,"57182":32142,"57183":32123,"57184":32131,"57185":32124,"57186":32140,"57187":32148,"57188":32132,"57189":32125,"57190":32146,"57191":32621,"57192":32619,"57193":32615,"57194":32616,"57195":32620,"57196":32678,"57197":32677,"57198":32679,"57199":32731,"57200":32732,"57201":32801,"57202":33124,"57203":33120,"57204":33143,"57205":33116,"57206":33129,"57207":33115,"57208":33122,"57209":33138,"57210":26401,"57211":33118,"57212":33142,"57213":33127,"57214":33135,"57249":33092,"57250":33121,"57251":33309,"57252":33353,"57253":33348,"57254":33344,"57255":33346,"57256":33349,"57257":34033,"57258":33855,"57259":33878,"57260":33910,"57261":33913,"57262":33935,"57263":33933,"57264":33893,"57265":33873,"57266":33856,"57267":33926,"57268":33895,"57269":33840,"57270":33869,"57271":33917,"57272":33882,"57273":33881,"57274":33908,"57275":33907,"57276":33885,"57277":34055,"57278":33886,"57279":33847,"57280":33850,"57281":33844,"57282":33914,"57283":33859,"57284":33912,"57285":33842,"57286":33861,"57287":33833,"57288":33753,"57289":33867,"57290":33839,"57291":33858,"57292":33837,"57293":33887,"57294":33904,"57295":33849,"57296":33870,"57297":33868,"57298":33874,"57299":33903,"57300":33989,"57301":33934,"57302":33851,"57303":33863,"57304":33846,"57305":33843,"57306":33896,"57307":33918,"57308":33860,"57309":33835,"57310":33888,"57311":33876,"57312":33902,"57313":33872,"57314":34571,"57315":34564,"57316":34551,"57317":34572,"57318":34554,"57319":34518,"57320":34549,"57321":34637,"57322":34552,"57323":34574,"57324":34569,"57325":34561,"57326":34550,"57327":34573,"57328":34565,"57329":35030,"57330":35019,"57331":35021,"57332":35022,"57333":35038,"57334":35035,"57335":35034,"57336":35020,"57337":35024,"57338":35205,"57339":35227,"57340":35295,"57341":35301,"57342":35300,"57408":35297,"57409":35296,"57410":35298,"57411":35292,"57412":35302,"57413":35446,"57414":35462,"57415":35455,"57416":35425,"57417":35391,"57418":35447,"57419":35458,"57420":35460,"57421":35445,"57422":35459,"57423":35457,"57424":35444,"57425":35450,"57426":35900,"57427":35915,"57428":35914,"57429":35941,"57430":35940,"57431":35942,"57432":35974,"57433":35972,"57434":35973,"57435":36044,"57436":36200,"57437":36201,"57438":36241,"57439":36236,"57440":36238,"57441":36239,"57442":36237,"57443":36243,"57444":36244,"57445":36240,"57446":36242,"57447":36336,"57448":36320,"57449":36332,"57450":36337,"57451":36334,"57452":36304,"57453":36329,"57454":36323,"57455":36322,"57456":36327,"57457":36338,"57458":36331,"57459":36340,"57460":36614,"57461":36607,"57462":36609,"57463":36608,"57464":36613,"57465":36615,"57466":36616,"57467":36610,"57468":36619,"57469":36946,"57470":36927,"57505":36932,"57506":36937,"57507":36925,"57508":37136,"57509":37133,"57510":37135,"57511":37137,"57512":37142,"57513":37140,"57514":37131,"57515":37134,"57516":37230,"57517":37231,"57518":37448,"57519":37458,"57520":37424,"57521":37434,"57522":37478,"57523":37427,"57524":37477,"57525":37470,"57526":37507,"57527":37422,"57528":37450,"57529":37446,"57530":37485,"57531":37484,"57532":37455,"57533":37472,"57534":37479,"57535":37487,"57536":37430,"57537":37473,"57538":37488,"57539":37425,"57540":37460,"57541":37475,"57542":37456,"57543":37490,"57544":37454,"57545":37459,"57546":37452,"57547":37462,"57548":37426,"57549":38303,"57550":38300,"57551":38302,"57552":38299,"57553":38546,"57554":38547,"57555":38545,"57556":38551,"57557":38606,"57558":38650,"57559":38653,"57560":38648,"57561":38645,"57562":38771,"57563":38775,"57564":38776,"57565":38770,"57566":38927,"57567":38925,"57568":38926,"57569":39084,"57570":39158,"57571":39161,"57572":39343,"57573":39346,"57574":39344,"57575":39349,"57576":39597,"57577":39595,"57578":39771,"57579":40170,"57580":40173,"57581":40167,"57582":40576,"57583":40701,"57584":20710,"57585":20692,"57586":20695,"57587":20712,"57588":20723,"57589":20699,"57590":20714,"57591":20701,"57592":20708,"57593":20691,"57594":20716,"57595":20720,"57596":20719,"57597":20707,"57598":20704,"57664":20952,"57665":21120,"57666":21121,"57667":21225,"57668":21227,"57669":21296,"57670":21420,"57671":22055,"57672":22037,"57673":22028,"57674":22034,"57675":22012,"57676":22031,"57677":22044,"57678":22017,"57679":22035,"57680":22018,"57681":22010,"57682":22045,"57683":22020,"57684":22015,"57685":22009,"57686":22665,"57687":22652,"57688":22672,"57689":22680,"57690":22662,"57691":22657,"57692":22655,"57693":22644,"57694":22667,"57695":22650,"57696":22663,"57697":22673,"57698":22670,"57699":22646,"57700":22658,"57701":22664,"57702":22651,"57703":22676,"57704":22671,"57705":22782,"57706":22891,"57707":23260,"57708":23278,"57709":23269,"57710":23253,"57711":23274,"57712":23258,"57713":23277,"57714":23275,"57715":23283,"57716":23266,"57717":23264,"57718":23259,"57719":23276,"57720":23262,"57721":23261,"57722":23257,"57723":23272,"57724":23263,"57725":23415,"57726":23520,"57761":23523,"57762":23651,"57763":23938,"57764":23936,"57765":23933,"57766":23942,"57767":23930,"57768":23937,"57769":23927,"57770":23946,"57771":23945,"57772":23944,"57773":23934,"57774":23932,"57775":23949,"57776":23929,"57777":23935,"57778":24152,"57779":24153,"57780":24147,"57781":24280,"57782":24273,"57783":24279,"57784":24270,"57785":24284,"57786":24277,"57787":24281,"57788":24274,"57789":24276,"57790":24388,"57791":24387,"57792":24431,"57793":24502,"57794":24876,"57795":24872,"57796":24897,"57797":24926,"57798":24945,"57799":24947,"57800":24914,"57801":24915,"57802":24946,"57803":24940,"57804":24960,"57805":24948,"57806":24916,"57807":24954,"57808":24923,"57809":24933,"57810":24891,"57811":24938,"57812":24929,"57813":24918,"57814":25129,"57815":25127,"57816":25131,"57817":25643,"57818":25677,"57819":25691,"57820":25693,"57821":25716,"57822":25718,"57823":25714,"57824":25715,"57825":25725,"57826":25717,"57827":25702,"57828":25766,"57829":25678,"57830":25730,"57831":25694,"57832":25692,"57833":25675,"57834":25683,"57835":25696,"57836":25680,"57837":25727,"57838":25663,"57839":25708,"57840":25707,"57841":25689,"57842":25701,"57843":25719,"57844":25971,"57845":26016,"57846":26273,"57847":26272,"57848":26271,"57849":26373,"57850":26372,"57851":26402,"57852":27057,"57853":27062,"57854":27081,"57920":27040,"57921":27086,"57922":27030,"57923":27056,"57924":27052,"57925":27068,"57926":27025,"57927":27033,"57928":27022,"57929":27047,"57930":27021,"57931":27049,"57932":27070,"57933":27055,"57934":27071,"57935":27076,"57936":27069,"57937":27044,"57938":27092,"57939":27065,"57940":27082,"57941":27034,"57942":27087,"57943":27059,"57944":27027,"57945":27050,"57946":27041,"57947":27038,"57948":27097,"57949":27031,"57950":27024,"57951":27074,"57952":27061,"57953":27045,"57954":27078,"57955":27466,"57956":27469,"57957":27467,"57958":27550,"57959":27551,"57960":27552,"57961":27587,"57962":27588,"57963":27646,"57964":28366,"57965":28405,"57966":28401,"57967":28419,"57968":28453,"57969":28408,"57970":28471,"57971":28411,"57972":28462,"57973":28425,"57974":28494,"57975":28441,"57976":28442,"57977":28455,"57978":28440,"57979":28475,"57980":28434,"57981":28397,"57982":28426,"58017":28470,"58018":28531,"58019":28409,"58020":28398,"58021":28461,"58022":28480,"58023":28464,"58024":28476,"58025":28469,"58026":28395,"58027":28423,"58028":28430,"58029":28483,"58030":28421,"58031":28413,"58032":28406,"58033":28473,"58034":28444,"58035":28412,"58036":28474,"58037":28447,"58038":28429,"58039":28446,"58040":28424,"58041":28449,"58042":29063,"58043":29072,"58044":29065,"58045":29056,"58046":29061,"58047":29058,"58048":29071,"58049":29051,"58050":29062,"58051":29057,"58052":29079,"58053":29252,"58054":29267,"58055":29335,"58056":29333,"58057":29331,"58058":29507,"58059":29517,"58060":29521,"58061":29516,"58062":29794,"58063":29811,"58064":29809,"58065":29813,"58066":29810,"58067":29799,"58068":29806,"58069":29952,"58070":29954,"58071":29955,"58072":30077,"58073":30096,"58074":30230,"58075":30216,"58076":30220,"58077":30229,"58078":30225,"58079":30218,"58080":30228,"58081":30392,"58082":30593,"58083":30588,"58084":30597,"58085":30594,"58086":30574,"58087":30592,"58088":30575,"58089":30590,"58090":30595,"58091":30898,"58092":30890,"58093":30900,"58094":30893,"58095":30888,"58096":30846,"58097":30891,"58098":30878,"58099":30885,"58100":30880,"58101":30892,"58102":30882,"58103":30884,"58104":31128,"58105":31114,"58106":31115,"58107":31126,"58108":31125,"58109":31124,"58110":31123,"58176":31127,"58177":31112,"58178":31122,"58179":31120,"58180":31275,"58181":31306,"58182":31280,"58183":31279,"58184":31272,"58185":31270,"58186":31400,"58187":31403,"58188":31404,"58189":31470,"58190":31624,"58191":31644,"58192":31626,"58193":31633,"58194":31632,"58195":31638,"58196":31629,"58197":31628,"58198":31643,"58199":31630,"58200":31621,"58201":31640,"58202":21124,"58203":31641,"58204":31652,"58205":31618,"58206":31931,"58207":31935,"58208":31932,"58209":31930,"58210":32167,"58211":32183,"58212":32194,"58213":32163,"58214":32170,"58215":32193,"58216":32192,"58217":32197,"58218":32157,"58219":32206,"58220":32196,"58221":32198,"58222":32203,"58223":32204,"58224":32175,"58225":32185,"58226":32150,"58227":32188,"58228":32159,"58229":32166,"58230":32174,"58231":32169,"58232":32161,"58233":32201,"58234":32627,"58235":32738,"58236":32739,"58237":32741,"58238":32734,"58273":32804,"58274":32861,"58275":32860,"58276":33161,"58277":33158,"58278":33155,"58279":33159,"58280":33165,"58281":33164,"58282":33163,"58283":33301,"58284":33943,"58285":33956,"58286":33953,"58287":33951,"58288":33978,"58289":33998,"58290":33986,"58291":33964,"58292":33966,"58293":33963,"58294":33977,"58295":33972,"58296":33985,"58297":33997,"58298":33962,"58299":33946,"58300":33969,"58301":34000,"58302":33949,"58303":33959,"58304":33979,"58305":33954,"58306":33940,"58307":33991,"58308":33996,"58309":33947,"58310":33961,"58311":33967,"58312":33960,"58313":34006,"58314":33944,"58315":33974,"58316":33999,"58317":33952,"58318":34007,"58319":34004,"58320":34002,"58321":34011,"58322":33968,"58323":33937,"58324":34401,"58325":34611,"58326":34595,"58327":34600,"58328":34667,"58329":34624,"58330":34606,"58331":34590,"58332":34593,"58333":34585,"58334":34587,"58335":34627,"58336":34604,"58337":34625,"58338":34622,"58339":34630,"58340":34592,"58341":34610,"58342":34602,"58343":34605,"58344":34620,"58345":34578,"58346":34618,"58347":34609,"58348":34613,"58349":34626,"58350":34598,"58351":34599,"58352":34616,"58353":34596,"58354":34586,"58355":34608,"58356":34577,"58357":35063,"58358":35047,"58359":35057,"58360":35058,"58361":35066,"58362":35070,"58363":35054,"58364":35068,"58365":35062,"58366":35067,"58432":35056,"58433":35052,"58434":35051,"58435":35229,"58436":35233,"58437":35231,"58438":35230,"58439":35305,"58440":35307,"58441":35304,"58442":35499,"58443":35481,"58444":35467,"58445":35474,"58446":35471,"58447":35478,"58448":35901,"58449":35944,"58450":35945,"58451":36053,"58452":36047,"58453":36055,"58454":36246,"58455":36361,"58456":36354,"58457":36351,"58458":36365,"58459":36349,"58460":36362,"58461":36355,"58462":36359,"58463":36358,"58464":36357,"58465":36350,"58466":36352,"58467":36356,"58468":36624,"58469":36625,"58470":36622,"58471":36621,"58472":37155,"58473":37148,"58474":37152,"58475":37154,"58476":37151,"58477":37149,"58478":37146,"58479":37156,"58480":37153,"58481":37147,"58482":37242,"58483":37234,"58484":37241,"58485":37235,"58486":37541,"58487":37540,"58488":37494,"58489":37531,"58490":37498,"58491":37536,"58492":37524,"58493":37546,"58494":37517,"58529":37542,"58530":37530,"58531":37547,"58532":37497,"58533":37527,"58534":37503,"58535":37539,"58536":37614,"58537":37518,"58538":37506,"58539":37525,"58540":37538,"58541":37501,"58542":37512,"58543":37537,"58544":37514,"58545":37510,"58546":37516,"58547":37529,"58548":37543,"58549":37502,"58550":37511,"58551":37545,"58552":37533,"58553":37515,"58554":37421,"58555":38558,"58556":38561,"58557":38655,"58558":38744,"58559":38781,"58560":38778,"58561":38782,"58562":38787,"58563":38784,"58564":38786,"58565":38779,"58566":38788,"58567":38785,"58568":38783,"58569":38862,"58570":38861,"58571":38934,"58572":39085,"58573":39086,"58574":39170,"58575":39168,"58576":39175,"58577":39325,"58578":39324,"58579":39363,"58580":39353,"58581":39355,"58582":39354,"58583":39362,"58584":39357,"58585":39367,"58586":39601,"58587":39651,"58588":39655,"58589":39742,"58590":39743,"58591":39776,"58592":39777,"58593":39775,"58594":40177,"58595":40178,"58596":40181,"58597":40615,"58598":20735,"58599":20739,"58600":20784,"58601":20728,"58602":20742,"58603":20743,"58604":20726,"58605":20734,"58606":20747,"58607":20748,"58608":20733,"58609":20746,"58610":21131,"58611":21132,"58612":21233,"58613":21231,"58614":22088,"58615":22082,"58616":22092,"58617":22069,"58618":22081,"58619":22090,"58620":22089,"58621":22086,"58622":22104,"58688":22106,"58689":22080,"58690":22067,"58691":22077,"58692":22060,"58693":22078,"58694":22072,"58695":22058,"58696":22074,"58697":22298,"58698":22699,"58699":22685,"58700":22705,"58701":22688,"58702":22691,"58703":22703,"58704":22700,"58705":22693,"58706":22689,"58707":22783,"58708":23295,"58709":23284,"58710":23293,"58711":23287,"58712":23286,"58713":23299,"58714":23288,"58715":23298,"58716":23289,"58717":23297,"58718":23303,"58719":23301,"58720":23311,"58721":23655,"58722":23961,"58723":23959,"58724":23967,"58725":23954,"58726":23970,"58727":23955,"58728":23957,"58729":23968,"58730":23964,"58731":23969,"58732":23962,"58733":23966,"58734":24169,"58735":24157,"58736":24160,"58737":24156,"58738":32243,"58739":24283,"58740":24286,"58741":24289,"58742":24393,"58743":24498,"58744":24971,"58745":24963,"58746":24953,"58747":25009,"58748":25008,"58749":24994,"58750":24969,"58785":24987,"58786":24979,"58787":25007,"58788":25005,"58789":24991,"58790":24978,"58791":25002,"58792":24993,"58793":24973,"58794":24934,"58795":25011,"58796":25133,"58797":25710,"58798":25712,"58799":25750,"58800":25760,"58801":25733,"58802":25751,"58803":25756,"58804":25743,"58805":25739,"58806":25738,"58807":25740,"58808":25763,"58809":25759,"58810":25704,"58811":25777,"58812":25752,"58813":25974,"58814":25978,"58815":25977,"58816":25979,"58817":26034,"58818":26035,"58819":26293,"58820":26288,"58821":26281,"58822":26290,"58823":26295,"58824":26282,"58825":26287,"58826":27136,"58827":27142,"58828":27159,"58829":27109,"58830":27128,"58831":27157,"58832":27121,"58833":27108,"58834":27168,"58835":27135,"58836":27116,"58837":27106,"58838":27163,"58839":27165,"58840":27134,"58841":27175,"58842":27122,"58843":27118,"58844":27156,"58845":27127,"58846":27111,"58847":27200,"58848":27144,"58849":27110,"58850":27131,"58851":27149,"58852":27132,"58853":27115,"58854":27145,"58855":27140,"58856":27160,"58857":27173,"58858":27151,"58859":27126,"58860":27174,"58861":27143,"58862":27124,"58863":27158,"58864":27473,"58865":27557,"58866":27555,"58867":27554,"58868":27558,"58869":27649,"58870":27648,"58871":27647,"58872":27650,"58873":28481,"58874":28454,"58875":28542,"58876":28551,"58877":28614,"58878":28562,"58944":28557,"58945":28553,"58946":28556,"58947":28514,"58948":28495,"58949":28549,"58950":28506,"58951":28566,"58952":28534,"58953":28524,"58954":28546,"58955":28501,"58956":28530,"58957":28498,"58958":28496,"58959":28503,"58960":28564,"58961":28563,"58962":28509,"58963":28416,"58964":28513,"58965":28523,"58966":28541,"58967":28519,"58968":28560,"58969":28499,"58970":28555,"58971":28521,"58972":28543,"58973":28565,"58974":28515,"58975":28535,"58976":28522,"58977":28539,"58978":29106,"58979":29103,"58980":29083,"58981":29104,"58982":29088,"58983":29082,"58984":29097,"58985":29109,"58986":29085,"58987":29093,"58988":29086,"58989":29092,"58990":29089,"58991":29098,"58992":29084,"58993":29095,"58994":29107,"58995":29336,"58996":29338,"58997":29528,"58998":29522,"58999":29534,"59000":29535,"59001":29536,"59002":29533,"59003":29531,"59004":29537,"59005":29530,"59006":29529,"59041":29538,"59042":29831,"59043":29833,"59044":29834,"59045":29830,"59046":29825,"59047":29821,"59048":29829,"59049":29832,"59050":29820,"59051":29817,"59052":29960,"59053":29959,"59054":30078,"59055":30245,"59056":30238,"59057":30233,"59058":30237,"59059":30236,"59060":30243,"59061":30234,"59062":30248,"59063":30235,"59064":30364,"59065":30365,"59066":30366,"59067":30363,"59068":30605,"59069":30607,"59070":30601,"59071":30600,"59072":30925,"59073":30907,"59074":30927,"59075":30924,"59076":30929,"59077":30926,"59078":30932,"59079":30920,"59080":30915,"59081":30916,"59082":30921,"59083":31130,"59084":31137,"59085":31136,"59086":31132,"59087":31138,"59088":31131,"59089":27510,"59090":31289,"59091":31410,"59092":31412,"59093":31411,"59094":31671,"59095":31691,"59096":31678,"59097":31660,"59098":31694,"59099":31663,"59100":31673,"59101":31690,"59102":31669,"59103":31941,"59104":31944,"59105":31948,"59106":31947,"59107":32247,"59108":32219,"59109":32234,"59110":32231,"59111":32215,"59112":32225,"59113":32259,"59114":32250,"59115":32230,"59116":32246,"59117":32241,"59118":32240,"59119":32238,"59120":32223,"59121":32630,"59122":32684,"59123":32688,"59124":32685,"59125":32749,"59126":32747,"59127":32746,"59128":32748,"59129":32742,"59130":32744,"59131":32868,"59132":32871,"59133":33187,"59134":33183,"59200":33182,"59201":33173,"59202":33186,"59203":33177,"59204":33175,"59205":33302,"59206":33359,"59207":33363,"59208":33362,"59209":33360,"59210":33358,"59211":33361,"59212":34084,"59213":34107,"59214":34063,"59215":34048,"59216":34089,"59217":34062,"59218":34057,"59219":34061,"59220":34079,"59221":34058,"59222":34087,"59223":34076,"59224":34043,"59225":34091,"59226":34042,"59227":34056,"59228":34060,"59229":34036,"59230":34090,"59231":34034,"59232":34069,"59233":34039,"59234":34027,"59235":34035,"59236":34044,"59237":34066,"59238":34026,"59239":34025,"59240":34070,"59241":34046,"59242":34088,"59243":34077,"59244":34094,"59245":34050,"59246":34045,"59247":34078,"59248":34038,"59249":34097,"59250":34086,"59251":34023,"59252":34024,"59253":34032,"59254":34031,"59255":34041,"59256":34072,"59257":34080,"59258":34096,"59259":34059,"59260":34073,"59261":34095,"59262":34402,"59297":34646,"59298":34659,"59299":34660,"59300":34679,"59301":34785,"59302":34675,"59303":34648,"59304":34644,"59305":34651,"59306":34642,"59307":34657,"59308":34650,"59309":34641,"59310":34654,"59311":34669,"59312":34666,"59313":34640,"59314":34638,"59315":34655,"59316":34653,"59317":34671,"59318":34668,"59319":34682,"59320":34670,"59321":34652,"59322":34661,"59323":34639,"59324":34683,"59325":34677,"59326":34658,"59327":34663,"59328":34665,"59329":34906,"59330":35077,"59331":35084,"59332":35092,"59333":35083,"59334":35095,"59335":35096,"59336":35097,"59337":35078,"59338":35094,"59339":35089,"59340":35086,"59341":35081,"59342":35234,"59343":35236,"59344":35235,"59345":35309,"59346":35312,"59347":35308,"59348":35535,"59349":35526,"59350":35512,"59351":35539,"59352":35537,"59353":35540,"59354":35541,"59355":35515,"59356":35543,"59357":35518,"59358":35520,"59359":35525,"59360":35544,"59361":35523,"59362":35514,"59363":35517,"59364":35545,"59365":35902,"59366":35917,"59367":35983,"59368":36069,"59369":36063,"59370":36057,"59371":36072,"59372":36058,"59373":36061,"59374":36071,"59375":36256,"59376":36252,"59377":36257,"59378":36251,"59379":36384,"59380":36387,"59381":36389,"59382":36388,"59383":36398,"59384":36373,"59385":36379,"59386":36374,"59387":36369,"59388":36377,"59389":36390,"59390":36391,"59456":36372,"59457":36370,"59458":36376,"59459":36371,"59460":36380,"59461":36375,"59462":36378,"59463":36652,"59464":36644,"59465":36632,"59466":36634,"59467":36640,"59468":36643,"59469":36630,"59470":36631,"59471":36979,"59472":36976,"59473":36975,"59474":36967,"59475":36971,"59476":37167,"59477":37163,"59478":37161,"59479":37162,"59480":37170,"59481":37158,"59482":37166,"59483":37253,"59484":37254,"59485":37258,"59486":37249,"59487":37250,"59488":37252,"59489":37248,"59490":37584,"59491":37571,"59492":37572,"59493":37568,"59494":37593,"59495":37558,"59496":37583,"59497":37617,"59498":37599,"59499":37592,"59500":37609,"59501":37591,"59502":37597,"59503":37580,"59504":37615,"59505":37570,"59506":37608,"59507":37578,"59508":37576,"59509":37582,"59510":37606,"59511":37581,"59512":37589,"59513":37577,"59514":37600,"59515":37598,"59516":37607,"59517":37585,"59518":37587,"59553":37557,"59554":37601,"59555":37574,"59556":37556,"59557":38268,"59558":38316,"59559":38315,"59560":38318,"59561":38320,"59562":38564,"59563":38562,"59564":38611,"59565":38661,"59566":38664,"59567":38658,"59568":38746,"59569":38794,"59570":38798,"59571":38792,"59572":38864,"59573":38863,"59574":38942,"59575":38941,"59576":38950,"59577":38953,"59578":38952,"59579":38944,"59580":38939,"59581":38951,"59582":39090,"59583":39176,"59584":39162,"59585":39185,"59586":39188,"59587":39190,"59588":39191,"59589":39189,"59590":39388,"59591":39373,"59592":39375,"59593":39379,"59594":39380,"59595":39374,"59596":39369,"59597":39382,"59598":39384,"59599":39371,"59600":39383,"59601":39372,"59602":39603,"59603":39660,"59604":39659,"59605":39667,"59606":39666,"59607":39665,"59608":39750,"59609":39747,"59610":39783,"59611":39796,"59612":39793,"59613":39782,"59614":39798,"59615":39797,"59616":39792,"59617":39784,"59618":39780,"59619":39788,"59620":40188,"59621":40186,"59622":40189,"59623":40191,"59624":40183,"59625":40199,"59626":40192,"59627":40185,"59628":40187,"59629":40200,"59630":40197,"59631":40196,"59632":40579,"59633":40659,"59634":40719,"59635":40720,"59636":20764,"59637":20755,"59638":20759,"59639":20762,"59640":20753,"59641":20958,"59642":21300,"59643":21473,"59644":22128,"59645":22112,"59646":22126,"59712":22131,"59713":22118,"59714":22115,"59715":22125,"59716":22130,"59717":22110,"59718":22135,"59719":22300,"59720":22299,"59721":22728,"59722":22717,"59723":22729,"59724":22719,"59725":22714,"59726":22722,"59727":22716,"59728":22726,"59729":23319,"59730":23321,"59731":23323,"59732":23329,"59733":23316,"59734":23315,"59735":23312,"59736":23318,"59737":23336,"59738":23322,"59739":23328,"59740":23326,"59741":23535,"59742":23980,"59743":23985,"59744":23977,"59745":23975,"59746":23989,"59747":23984,"59748":23982,"59749":23978,"59750":23976,"59751":23986,"59752":23981,"59753":23983,"59754":23988,"59755":24167,"59756":24168,"59757":24166,"59758":24175,"59759":24297,"59760":24295,"59761":24294,"59762":24296,"59763":24293,"59764":24395,"59765":24508,"59766":24989,"59767":25000,"59768":24982,"59769":25029,"59770":25012,"59771":25030,"59772":25025,"59773":25036,"59774":25018,"59809":25023,"59810":25016,"59811":24972,"59812":25815,"59813":25814,"59814":25808,"59815":25807,"59816":25801,"59817":25789,"59818":25737,"59819":25795,"59820":25819,"59821":25843,"59822":25817,"59823":25907,"59824":25983,"59825":25980,"59826":26018,"59827":26312,"59828":26302,"59829":26304,"59830":26314,"59831":26315,"59832":26319,"59833":26301,"59834":26299,"59835":26298,"59836":26316,"59837":26403,"59838":27188,"59839":27238,"59840":27209,"59841":27239,"59842":27186,"59843":27240,"59844":27198,"59845":27229,"59846":27245,"59847":27254,"59848":27227,"59849":27217,"59850":27176,"59851":27226,"59852":27195,"59853":27199,"59854":27201,"59855":27242,"59856":27236,"59857":27216,"59858":27215,"59859":27220,"59860":27247,"59861":27241,"59862":27232,"59863":27196,"59864":27230,"59865":27222,"59866":27221,"59867":27213,"59868":27214,"59869":27206,"59870":27477,"59871":27476,"59872":27478,"59873":27559,"59874":27562,"59875":27563,"59876":27592,"59877":27591,"59878":27652,"59879":27651,"59880":27654,"59881":28589,"59882":28619,"59883":28579,"59884":28615,"59885":28604,"59886":28622,"59887":28616,"59888":28510,"59889":28612,"59890":28605,"59891":28574,"59892":28618,"59893":28584,"59894":28676,"59895":28581,"59896":28590,"59897":28602,"59898":28588,"59899":28586,"59900":28623,"59901":28607,"59902":28600,"59968":28578,"59969":28617,"59970":28587,"59971":28621,"59972":28591,"59973":28594,"59974":28592,"59975":29125,"59976":29122,"59977":29119,"59978":29112,"59979":29142,"59980":29120,"59981":29121,"59982":29131,"59983":29140,"59984":29130,"59985":29127,"59986":29135,"59987":29117,"59988":29144,"59989":29116,"59990":29126,"59991":29146,"59992":29147,"59993":29341,"59994":29342,"59995":29545,"59996":29542,"59997":29543,"59998":29548,"59999":29541,"60000":29547,"60001":29546,"60002":29823,"60003":29850,"60004":29856,"60005":29844,"60006":29842,"60007":29845,"60008":29857,"60009":29963,"60010":30080,"60011":30255,"60012":30253,"60013":30257,"60014":30269,"60015":30259,"60016":30268,"60017":30261,"60018":30258,"60019":30256,"60020":30395,"60021":30438,"60022":30618,"60023":30621,"60024":30625,"60025":30620,"60026":30619,"60027":30626,"60028":30627,"60029":30613,"60030":30617,"60065":30615,"60066":30941,"60067":30953,"60068":30949,"60069":30954,"60070":30942,"60071":30947,"60072":30939,"60073":30945,"60074":30946,"60075":30957,"60076":30943,"60077":30944,"60078":31140,"60079":31300,"60080":31304,"60081":31303,"60082":31414,"60083":31416,"60084":31413,"60085":31409,"60086":31415,"60087":31710,"60088":31715,"60089":31719,"60090":31709,"60091":31701,"60092":31717,"60093":31706,"60094":31720,"60095":31737,"60096":31700,"60097":31722,"60098":31714,"60099":31708,"60100":31723,"60101":31704,"60102":31711,"60103":31954,"60104":31956,"60105":31959,"60106":31952,"60107":31953,"60108":32274,"60109":32289,"60110":32279,"60111":32268,"60112":32287,"60113":32288,"60114":32275,"60115":32270,"60116":32284,"60117":32277,"60118":32282,"60119":32290,"60120":32267,"60121":32271,"60122":32278,"60123":32269,"60124":32276,"60125":32293,"60126":32292,"60127":32579,"60128":32635,"60129":32636,"60130":32634,"60131":32689,"60132":32751,"60133":32810,"60134":32809,"60135":32876,"60136":33201,"60137":33190,"60138":33198,"60139":33209,"60140":33205,"60141":33195,"60142":33200,"60143":33196,"60144":33204,"60145":33202,"60146":33207,"60147":33191,"60148":33266,"60149":33365,"60150":33366,"60151":33367,"60152":34134,"60153":34117,"60154":34155,"60155":34125,"60156":34131,"60157":34145,"60158":34136,"60224":34112,"60225":34118,"60226":34148,"60227":34113,"60228":34146,"60229":34116,"60230":34129,"60231":34119,"60232":34147,"60233":34110,"60234":34139,"60235":34161,"60236":34126,"60237":34158,"60238":34165,"60239":34133,"60240":34151,"60241":34144,"60242":34188,"60243":34150,"60244":34141,"60245":34132,"60246":34149,"60247":34156,"60248":34403,"60249":34405,"60250":34404,"60251":34715,"60252":34703,"60253":34711,"60254":34707,"60255":34706,"60256":34696,"60257":34689,"60258":34710,"60259":34712,"60260":34681,"60261":34695,"60262":34723,"60263":34693,"60264":34704,"60265":34705,"60266":34717,"60267":34692,"60268":34708,"60269":34716,"60270":34714,"60271":34697,"60272":35102,"60273":35110,"60274":35120,"60275":35117,"60276":35118,"60277":35111,"60278":35121,"60279":35106,"60280":35113,"60281":35107,"60282":35119,"60283":35116,"60284":35103,"60285":35313,"60286":35552,"60321":35554,"60322":35570,"60323":35572,"60324":35573,"60325":35549,"60326":35604,"60327":35556,"60328":35551,"60329":35568,"60330":35528,"60331":35550,"60332":35553,"60333":35560,"60334":35583,"60335":35567,"60336":35579,"60337":35985,"60338":35986,"60339":35984,"60340":36085,"60341":36078,"60342":36081,"60343":36080,"60344":36083,"60345":36204,"60346":36206,"60347":36261,"60348":36263,"60349":36403,"60350":36414,"60351":36408,"60352":36416,"60353":36421,"60354":36406,"60355":36412,"60356":36413,"60357":36417,"60358":36400,"60359":36415,"60360":36541,"60361":36662,"60362":36654,"60363":36661,"60364":36658,"60365":36665,"60366":36663,"60367":36660,"60368":36982,"60369":36985,"60370":36987,"60371":36998,"60372":37114,"60373":37171,"60374":37173,"60375":37174,"60376":37267,"60377":37264,"60378":37265,"60379":37261,"60380":37263,"60381":37671,"60382":37662,"60383":37640,"60384":37663,"60385":37638,"60386":37647,"60387":37754,"60388":37688,"60389":37692,"60390":37659,"60391":37667,"60392":37650,"60393":37633,"60394":37702,"60395":37677,"60396":37646,"60397":37645,"60398":37579,"60399":37661,"60400":37626,"60401":37669,"60402":37651,"60403":37625,"60404":37623,"60405":37684,"60406":37634,"60407":37668,"60408":37631,"60409":37673,"60410":37689,"60411":37685,"60412":37674,"60413":37652,"60414":37644,"60480":37643,"60481":37630,"60482":37641,"60483":37632,"60484":37627,"60485":37654,"60486":38332,"60487":38349,"60488":38334,"60489":38329,"60490":38330,"60491":38326,"60492":38335,"60493":38325,"60494":38333,"60495":38569,"60496":38612,"60497":38667,"60498":38674,"60499":38672,"60500":38809,"60501":38807,"60502":38804,"60503":38896,"60504":38904,"60505":38965,"60506":38959,"60507":38962,"60508":39204,"60509":39199,"60510":39207,"60511":39209,"60512":39326,"60513":39406,"60514":39404,"60515":39397,"60516":39396,"60517":39408,"60518":39395,"60519":39402,"60520":39401,"60521":39399,"60522":39609,"60523":39615,"60524":39604,"60525":39611,"60526":39670,"60527":39674,"60528":39673,"60529":39671,"60530":39731,"60531":39808,"60532":39813,"60533":39815,"60534":39804,"60535":39806,"60536":39803,"60537":39810,"60538":39827,"60539":39826,"60540":39824,"60541":39802,"60542":39829,"60577":39805,"60578":39816,"60579":40229,"60580":40215,"60581":40224,"60582":40222,"60583":40212,"60584":40233,"60585":40221,"60586":40216,"60587":40226,"60588":40208,"60589":40217,"60590":40223,"60591":40584,"60592":40582,"60593":40583,"60594":40622,"60595":40621,"60596":40661,"60597":40662,"60598":40698,"60599":40722,"60600":40765,"60601":20774,"60602":20773,"60603":20770,"60604":20772,"60605":20768,"60606":20777,"60607":21236,"60608":22163,"60609":22156,"60610":22157,"60611":22150,"60612":22148,"60613":22147,"60614":22142,"60615":22146,"60616":22143,"60617":22145,"60618":22742,"60619":22740,"60620":22735,"60621":22738,"60622":23341,"60623":23333,"60624":23346,"60625":23331,"60626":23340,"60627":23335,"60628":23334,"60629":23343,"60630":23342,"60631":23419,"60632":23537,"60633":23538,"60634":23991,"60635":24172,"60636":24170,"60637":24510,"60638":24507,"60639":25027,"60640":25013,"60641":25020,"60642":25063,"60643":25056,"60644":25061,"60645":25060,"60646":25064,"60647":25054,"60648":25839,"60649":25833,"60650":25827,"60651":25835,"60652":25828,"60653":25832,"60654":25985,"60655":25984,"60656":26038,"60657":26074,"60658":26322,"60659":27277,"60660":27286,"60661":27265,"60662":27301,"60663":27273,"60664":27295,"60665":27291,"60666":27297,"60667":27294,"60668":27271,"60669":27283,"60670":27278,"60736":27285,"60737":27267,"60738":27304,"60739":27300,"60740":27281,"60741":27263,"60742":27302,"60743":27290,"60744":27269,"60745":27276,"60746":27282,"60747":27483,"60748":27565,"60749":27657,"60750":28620,"60751":28585,"60752":28660,"60753":28628,"60754":28643,"60755":28636,"60756":28653,"60757":28647,"60758":28646,"60759":28638,"60760":28658,"60761":28637,"60762":28642,"60763":28648,"60764":29153,"60765":29169,"60766":29160,"60767":29170,"60768":29156,"60769":29168,"60770":29154,"60771":29555,"60772":29550,"60773":29551,"60774":29847,"60775":29874,"60776":29867,"60777":29840,"60778":29866,"60779":29869,"60780":29873,"60781":29861,"60782":29871,"60783":29968,"60784":29969,"60785":29970,"60786":29967,"60787":30084,"60788":30275,"60789":30280,"60790":30281,"60791":30279,"60792":30372,"60793":30441,"60794":30645,"60795":30635,"60796":30642,"60797":30647,"60798":30646,"60833":30644,"60834":30641,"60835":30632,"60836":30704,"60837":30963,"60838":30973,"60839":30978,"60840":30971,"60841":30972,"60842":30962,"60843":30981,"60844":30969,"60845":30974,"60846":30980,"60847":31147,"60848":31144,"60849":31324,"60850":31323,"60851":31318,"60852":31320,"60853":31316,"60854":31322,"60855":31422,"60856":31424,"60857":31425,"60858":31749,"60859":31759,"60860":31730,"60861":31744,"60862":31743,"60863":31739,"60864":31758,"60865":31732,"60866":31755,"60867":31731,"60868":31746,"60869":31753,"60870":31747,"60871":31745,"60872":31736,"60873":31741,"60874":31750,"60875":31728,"60876":31729,"60877":31760,"60878":31754,"60879":31976,"60880":32301,"60881":32316,"60882":32322,"60883":32307,"60884":38984,"60885":32312,"60886":32298,"60887":32329,"60888":32320,"60889":32327,"60890":32297,"60891":32332,"60892":32304,"60893":32315,"60894":32310,"60895":32324,"60896":32314,"60897":32581,"60898":32639,"60899":32638,"60900":32637,"60901":32756,"60902":32754,"60903":32812,"60904":33211,"60905":33220,"60906":33228,"60907":33226,"60908":33221,"60909":33223,"60910":33212,"60911":33257,"60912":33371,"60913":33370,"60914":33372,"60915":34179,"60916":34176,"60917":34191,"60918":34215,"60919":34197,"60920":34208,"60921":34187,"60922":34211,"60923":34171,"60924":34212,"60925":34202,"60926":34206,"60992":34167,"60993":34172,"60994":34185,"60995":34209,"60996":34170,"60997":34168,"60998":34135,"60999":34190,"61000":34198,"61001":34182,"61002":34189,"61003":34201,"61004":34205,"61005":34177,"61006":34210,"61007":34178,"61008":34184,"61009":34181,"61010":34169,"61011":34166,"61012":34200,"61013":34192,"61014":34207,"61015":34408,"61016":34750,"61017":34730,"61018":34733,"61019":34757,"61020":34736,"61021":34732,"61022":34745,"61023":34741,"61024":34748,"61025":34734,"61026":34761,"61027":34755,"61028":34754,"61029":34764,"61030":34743,"61031":34735,"61032":34756,"61033":34762,"61034":34740,"61035":34742,"61036":34751,"61037":34744,"61038":34749,"61039":34782,"61040":34738,"61041":35125,"61042":35123,"61043":35132,"61044":35134,"61045":35137,"61046":35154,"61047":35127,"61048":35138,"61049":35245,"61050":35247,"61051":35246,"61052":35314,"61053":35315,"61054":35614,"61089":35608,"61090":35606,"61091":35601,"61092":35589,"61093":35595,"61094":35618,"61095":35599,"61096":35602,"61097":35605,"61098":35591,"61099":35597,"61100":35592,"61101":35590,"61102":35612,"61103":35603,"61104":35610,"61105":35919,"61106":35952,"61107":35954,"61108":35953,"61109":35951,"61110":35989,"61111":35988,"61112":36089,"61113":36207,"61114":36430,"61115":36429,"61116":36435,"61117":36432,"61118":36428,"61119":36423,"61120":36675,"61121":36672,"61122":36997,"61123":36990,"61124":37176,"61125":37274,"61126":37282,"61127":37275,"61128":37273,"61129":37279,"61130":37281,"61131":37277,"61132":37280,"61133":37793,"61134":37763,"61135":37807,"61136":37732,"61137":37718,"61138":37703,"61139":37756,"61140":37720,"61141":37724,"61142":37750,"61143":37705,"61144":37712,"61145":37713,"61146":37728,"61147":37741,"61148":37775,"61149":37708,"61150":37738,"61151":37753,"61152":37719,"61153":37717,"61154":37714,"61155":37711,"61156":37745,"61157":37751,"61158":37755,"61159":37729,"61160":37726,"61161":37731,"61162":37735,"61163":37760,"61164":37710,"61165":37721,"61166":38343,"61167":38336,"61168":38345,"61169":38339,"61170":38341,"61171":38327,"61172":38574,"61173":38576,"61174":38572,"61175":38688,"61176":38687,"61177":38680,"61178":38685,"61179":38681,"61180":38810,"61181":38817,"61182":38812,"61248":38814,"61249":38813,"61250":38869,"61251":38868,"61252":38897,"61253":38977,"61254":38980,"61255":38986,"61256":38985,"61257":38981,"61258":38979,"61259":39205,"61260":39211,"61261":39212,"61262":39210,"61263":39219,"61264":39218,"61265":39215,"61266":39213,"61267":39217,"61268":39216,"61269":39320,"61270":39331,"61271":39329,"61272":39426,"61273":39418,"61274":39412,"61275":39415,"61276":39417,"61277":39416,"61278":39414,"61279":39419,"61280":39421,"61281":39422,"61282":39420,"61283":39427,"61284":39614,"61285":39678,"61286":39677,"61287":39681,"61288":39676,"61289":39752,"61290":39834,"61291":39848,"61292":39838,"61293":39835,"61294":39846,"61295":39841,"61296":39845,"61297":39844,"61298":39814,"61299":39842,"61300":39840,"61301":39855,"61302":40243,"61303":40257,"61304":40295,"61305":40246,"61306":40238,"61307":40239,"61308":40241,"61309":40248,"61310":40240,"61345":40261,"61346":40258,"61347":40259,"61348":40254,"61349":40247,"61350":40256,"61351":40253,"61352":32757,"61353":40237,"61354":40586,"61355":40585,"61356":40589,"61357":40624,"61358":40648,"61359":40666,"61360":40699,"61361":40703,"61362":40740,"61363":40739,"61364":40738,"61365":40788,"61366":40864,"61367":20785,"61368":20781,"61369":20782,"61370":22168,"61371":22172,"61372":22167,"61373":22170,"61374":22173,"61375":22169,"61376":22896,"61377":23356,"61378":23657,"61379":23658,"61380":24000,"61381":24173,"61382":24174,"61383":25048,"61384":25055,"61385":25069,"61386":25070,"61387":25073,"61388":25066,"61389":25072,"61390":25067,"61391":25046,"61392":25065,"61393":25855,"61394":25860,"61395":25853,"61396":25848,"61397":25857,"61398":25859,"61399":25852,"61400":26004,"61401":26075,"61402":26330,"61403":26331,"61404":26328,"61405":27333,"61406":27321,"61407":27325,"61408":27361,"61409":27334,"61410":27322,"61411":27318,"61412":27319,"61413":27335,"61414":27316,"61415":27309,"61416":27486,"61417":27593,"61418":27659,"61419":28679,"61420":28684,"61421":28685,"61422":28673,"61423":28677,"61424":28692,"61425":28686,"61426":28671,"61427":28672,"61428":28667,"61429":28710,"61430":28668,"61431":28663,"61432":28682,"61433":29185,"61434":29183,"61435":29177,"61436":29187,"61437":29181,"61438":29558,"61504":29880,"61505":29888,"61506":29877,"61507":29889,"61508":29886,"61509":29878,"61510":29883,"61511":29890,"61512":29972,"61513":29971,"61514":30300,"61515":30308,"61516":30297,"61517":30288,"61518":30291,"61519":30295,"61520":30298,"61521":30374,"61522":30397,"61523":30444,"61524":30658,"61525":30650,"61526":30975,"61527":30988,"61528":30995,"61529":30996,"61530":30985,"61531":30992,"61532":30994,"61533":30993,"61534":31149,"61535":31148,"61536":31327,"61537":31772,"61538":31785,"61539":31769,"61540":31776,"61541":31775,"61542":31789,"61543":31773,"61544":31782,"61545":31784,"61546":31778,"61547":31781,"61548":31792,"61549":32348,"61550":32336,"61551":32342,"61552":32355,"61553":32344,"61554":32354,"61555":32351,"61556":32337,"61557":32352,"61558":32343,"61559":32339,"61560":32693,"61561":32691,"61562":32759,"61563":32760,"61564":32885,"61565":33233,"61566":33234,"61601":33232,"61602":33375,"61603":33374,"61604":34228,"61605":34246,"61606":34240,"61607":34243,"61608":34242,"61609":34227,"61610":34229,"61611":34237,"61612":34247,"61613":34244,"61614":34239,"61615":34251,"61616":34254,"61617":34248,"61618":34245,"61619":34225,"61620":34230,"61621":34258,"61622":34340,"61623":34232,"61624":34231,"61625":34238,"61626":34409,"61627":34791,"61628":34790,"61629":34786,"61630":34779,"61631":34795,"61632":34794,"61633":34789,"61634":34783,"61635":34803,"61636":34788,"61637":34772,"61638":34780,"61639":34771,"61640":34797,"61641":34776,"61642":34787,"61643":34724,"61644":34775,"61645":34777,"61646":34817,"61647":34804,"61648":34792,"61649":34781,"61650":35155,"61651":35147,"61652":35151,"61653":35148,"61654":35142,"61655":35152,"61656":35153,"61657":35145,"61658":35626,"61659":35623,"61660":35619,"61661":35635,"61662":35632,"61663":35637,"61664":35655,"61665":35631,"61666":35644,"61667":35646,"61668":35633,"61669":35621,"61670":35639,"61671":35622,"61672":35638,"61673":35630,"61674":35620,"61675":35643,"61676":35645,"61677":35642,"61678":35906,"61679":35957,"61680":35993,"61681":35992,"61682":35991,"61683":36094,"61684":36100,"61685":36098,"61686":36096,"61687":36444,"61688":36450,"61689":36448,"61690":36439,"61691":36438,"61692":36446,"61693":36453,"61694":36455,"61760":36443,"61761":36442,"61762":36449,"61763":36445,"61764":36457,"61765":36436,"61766":36678,"61767":36679,"61768":36680,"61769":36683,"61770":37160,"61771":37178,"61772":37179,"61773":37182,"61774":37288,"61775":37285,"61776":37287,"61777":37295,"61778":37290,"61779":37813,"61780":37772,"61781":37778,"61782":37815,"61783":37787,"61784":37789,"61785":37769,"61786":37799,"61787":37774,"61788":37802,"61789":37790,"61790":37798,"61791":37781,"61792":37768,"61793":37785,"61794":37791,"61795":37773,"61796":37809,"61797":37777,"61798":37810,"61799":37796,"61800":37800,"61801":37812,"61802":37795,"61803":37797,"61804":38354,"61805":38355,"61806":38353,"61807":38579,"61808":38615,"61809":38618,"61810":24002,"61811":38623,"61812":38616,"61813":38621,"61814":38691,"61815":38690,"61816":38693,"61817":38828,"61818":38830,"61819":38824,"61820":38827,"61821":38820,"61822":38826,"61857":38818,"61858":38821,"61859":38871,"61860":38873,"61861":38870,"61862":38872,"61863":38906,"61864":38992,"61865":38993,"61866":38994,"61867":39096,"61868":39233,"61869":39228,"61870":39226,"61871":39439,"61872":39435,"61873":39433,"61874":39437,"61875":39428,"61876":39441,"61877":39434,"61878":39429,"61879":39431,"61880":39430,"61881":39616,"61882":39644,"61883":39688,"61884":39684,"61885":39685,"61886":39721,"61887":39733,"61888":39754,"61889":39756,"61890":39755,"61891":39879,"61892":39878,"61893":39875,"61894":39871,"61895":39873,"61896":39861,"61897":39864,"61898":39891,"61899":39862,"61900":39876,"61901":39865,"61902":39869,"61903":40284,"61904":40275,"61905":40271,"61906":40266,"61907":40283,"61908":40267,"61909":40281,"61910":40278,"61911":40268,"61912":40279,"61913":40274,"61914":40276,"61915":40287,"61916":40280,"61917":40282,"61918":40590,"61919":40588,"61920":40671,"61921":40705,"61922":40704,"61923":40726,"61924":40741,"61925":40747,"61926":40746,"61927":40745,"61928":40744,"61929":40780,"61930":40789,"61931":20788,"61932":20789,"61933":21142,"61934":21239,"61935":21428,"61936":22187,"61937":22189,"61938":22182,"61939":22183,"61940":22186,"61941":22188,"61942":22746,"61943":22749,"61944":22747,"61945":22802,"61946":23357,"61947":23358,"61948":23359,"61949":24003,"61950":24176,"62016":24511,"62017":25083,"62018":25863,"62019":25872,"62020":25869,"62021":25865,"62022":25868,"62023":25870,"62024":25988,"62025":26078,"62026":26077,"62027":26334,"62028":27367,"62029":27360,"62030":27340,"62031":27345,"62032":27353,"62033":27339,"62034":27359,"62035":27356,"62036":27344,"62037":27371,"62038":27343,"62039":27341,"62040":27358,"62041":27488,"62042":27568,"62043":27660,"62044":28697,"62045":28711,"62046":28704,"62047":28694,"62048":28715,"62049":28705,"62050":28706,"62051":28707,"62052":28713,"62053":28695,"62054":28708,"62055":28700,"62056":28714,"62057":29196,"62058":29194,"62059":29191,"62060":29186,"62061":29189,"62062":29349,"62063":29350,"62064":29348,"62065":29347,"62066":29345,"62067":29899,"62068":29893,"62069":29879,"62070":29891,"62071":29974,"62072":30304,"62073":30665,"62074":30666,"62075":30660,"62076":30705,"62077":31005,"62078":31003,"62113":31009,"62114":31004,"62115":30999,"62116":31006,"62117":31152,"62118":31335,"62119":31336,"62120":31795,"62121":31804,"62122":31801,"62123":31788,"62124":31803,"62125":31980,"62126":31978,"62127":32374,"62128":32373,"62129":32376,"62130":32368,"62131":32375,"62132":32367,"62133":32378,"62134":32370,"62135":32372,"62136":32360,"62137":32587,"62138":32586,"62139":32643,"62140":32646,"62141":32695,"62142":32765,"62143":32766,"62144":32888,"62145":33239,"62146":33237,"62147":33380,"62148":33377,"62149":33379,"62150":34283,"62151":34289,"62152":34285,"62153":34265,"62154":34273,"62155":34280,"62156":34266,"62157":34263,"62158":34284,"62159":34290,"62160":34296,"62161":34264,"62162":34271,"62163":34275,"62164":34268,"62165":34257,"62166":34288,"62167":34278,"62168":34287,"62169":34270,"62170":34274,"62171":34816,"62172":34810,"62173":34819,"62174":34806,"62175":34807,"62176":34825,"62177":34828,"62178":34827,"62179":34822,"62180":34812,"62181":34824,"62182":34815,"62183":34826,"62184":34818,"62185":35170,"62186":35162,"62187":35163,"62188":35159,"62189":35169,"62190":35164,"62191":35160,"62192":35165,"62193":35161,"62194":35208,"62195":35255,"62196":35254,"62197":35318,"62198":35664,"62199":35656,"62200":35658,"62201":35648,"62202":35667,"62203":35670,"62204":35668,"62205":35659,"62206":35669,"62272":35665,"62273":35650,"62274":35666,"62275":35671,"62276":35907,"62277":35959,"62278":35958,"62279":35994,"62280":36102,"62281":36103,"62282":36105,"62283":36268,"62284":36266,"62285":36269,"62286":36267,"62287":36461,"62288":36472,"62289":36467,"62290":36458,"62291":36463,"62292":36475,"62293":36546,"62294":36690,"62295":36689,"62296":36687,"62297":36688,"62298":36691,"62299":36788,"62300":37184,"62301":37183,"62302":37296,"62303":37293,"62304":37854,"62305":37831,"62306":37839,"62307":37826,"62308":37850,"62309":37840,"62310":37881,"62311":37868,"62312":37836,"62313":37849,"62314":37801,"62315":37862,"62316":37834,"62317":37844,"62318":37870,"62319":37859,"62320":37845,"62321":37828,"62322":37838,"62323":37824,"62324":37842,"62325":37863,"62326":38269,"62327":38362,"62328":38363,"62329":38625,"62330":38697,"62331":38699,"62332":38700,"62333":38696,"62334":38694,"62369":38835,"62370":38839,"62371":38838,"62372":38877,"62373":38878,"62374":38879,"62375":39004,"62376":39001,"62377":39005,"62378":38999,"62379":39103,"62380":39101,"62381":39099,"62382":39102,"62383":39240,"62384":39239,"62385":39235,"62386":39334,"62387":39335,"62388":39450,"62389":39445,"62390":39461,"62391":39453,"62392":39460,"62393":39451,"62394":39458,"62395":39456,"62396":39463,"62397":39459,"62398":39454,"62399":39452,"62400":39444,"62401":39618,"62402":39691,"62403":39690,"62404":39694,"62405":39692,"62406":39735,"62407":39914,"62408":39915,"62409":39904,"62410":39902,"62411":39908,"62412":39910,"62413":39906,"62414":39920,"62415":39892,"62416":39895,"62417":39916,"62418":39900,"62419":39897,"62420":39909,"62421":39893,"62422":39905,"62423":39898,"62424":40311,"62425":40321,"62426":40330,"62427":40324,"62428":40328,"62429":40305,"62430":40320,"62431":40312,"62432":40326,"62433":40331,"62434":40332,"62435":40317,"62436":40299,"62437":40308,"62438":40309,"62439":40304,"62440":40297,"62441":40325,"62442":40307,"62443":40315,"62444":40322,"62445":40303,"62446":40313,"62447":40319,"62448":40327,"62449":40296,"62450":40596,"62451":40593,"62452":40640,"62453":40700,"62454":40749,"62455":40768,"62456":40769,"62457":40781,"62458":40790,"62459":40791,"62460":40792,"62461":21303,"62462":22194,"62528":22197,"62529":22195,"62530":22755,"62531":23365,"62532":24006,"62533":24007,"62534":24302,"62535":24303,"62536":24512,"62537":24513,"62538":25081,"62539":25879,"62540":25878,"62541":25877,"62542":25875,"62543":26079,"62544":26344,"62545":26339,"62546":26340,"62547":27379,"62548":27376,"62549":27370,"62550":27368,"62551":27385,"62552":27377,"62553":27374,"62554":27375,"62555":28732,"62556":28725,"62557":28719,"62558":28727,"62559":28724,"62560":28721,"62561":28738,"62562":28728,"62563":28735,"62564":28730,"62565":28729,"62566":28736,"62567":28731,"62568":28723,"62569":28737,"62570":29203,"62571":29204,"62572":29352,"62573":29565,"62574":29564,"62575":29882,"62576":30379,"62577":30378,"62578":30398,"62579":30445,"62580":30668,"62581":30670,"62582":30671,"62583":30669,"62584":30706,"62585":31013,"62586":31011,"62587":31015,"62588":31016,"62589":31012,"62590":31017,"62625":31154,"62626":31342,"62627":31340,"62628":31341,"62629":31479,"62630":31817,"62631":31816,"62632":31818,"62633":31815,"62634":31813,"62635":31982,"62636":32379,"62637":32382,"62638":32385,"62639":32384,"62640":32698,"62641":32767,"62642":32889,"62643":33243,"62644":33241,"62645":33291,"62646":33384,"62647":33385,"62648":34338,"62649":34303,"62650":34305,"62651":34302,"62652":34331,"62653":34304,"62654":34294,"62655":34308,"62656":34313,"62657":34309,"62658":34316,"62659":34301,"62660":34841,"62661":34832,"62662":34833,"62663":34839,"62664":34835,"62665":34838,"62666":35171,"62667":35174,"62668":35257,"62669":35319,"62670":35680,"62671":35690,"62672":35677,"62673":35688,"62674":35683,"62675":35685,"62676":35687,"62677":35693,"62678":36270,"62679":36486,"62680":36488,"62681":36484,"62682":36697,"62683":36694,"62684":36695,"62685":36693,"62686":36696,"62687":36698,"62688":37005,"62689":37187,"62690":37185,"62691":37303,"62692":37301,"62693":37298,"62694":37299,"62695":37899,"62696":37907,"62697":37883,"62698":37920,"62699":37903,"62700":37908,"62701":37886,"62702":37909,"62703":37904,"62704":37928,"62705":37913,"62706":37901,"62707":37877,"62708":37888,"62709":37879,"62710":37895,"62711":37902,"62712":37910,"62713":37906,"62714":37882,"62715":37897,"62716":37880,"62717":37898,"62718":37887,"62784":37884,"62785":37900,"62786":37878,"62787":37905,"62788":37894,"62789":38366,"62790":38368,"62791":38367,"62792":38702,"62793":38703,"62794":38841,"62795":38843,"62796":38909,"62797":38910,"62798":39008,"62799":39010,"62800":39011,"62801":39007,"62802":39105,"62803":39106,"62804":39248,"62805":39246,"62806":39257,"62807":39244,"62808":39243,"62809":39251,"62810":39474,"62811":39476,"62812":39473,"62813":39468,"62814":39466,"62815":39478,"62816":39465,"62817":39470,"62818":39480,"62819":39469,"62820":39623,"62821":39626,"62822":39622,"62823":39696,"62824":39698,"62825":39697,"62826":39947,"62827":39944,"62828":39927,"62829":39941,"62830":39954,"62831":39928,"62832":40000,"62833":39943,"62834":39950,"62835":39942,"62836":39959,"62837":39956,"62838":39945,"62839":40351,"62840":40345,"62841":40356,"62842":40349,"62843":40338,"62844":40344,"62845":40336,"62846":40347,"62881":40352,"62882":40340,"62883":40348,"62884":40362,"62885":40343,"62886":40353,"62887":40346,"62888":40354,"62889":40360,"62890":40350,"62891":40355,"62892":40383,"62893":40361,"62894":40342,"62895":40358,"62896":40359,"62897":40601,"62898":40603,"62899":40602,"62900":40677,"62901":40676,"62902":40679,"62903":40678,"62904":40752,"62905":40750,"62906":40795,"62907":40800,"62908":40798,"62909":40797,"62910":40793,"62911":40849,"62912":20794,"62913":20793,"62914":21144,"62915":21143,"62916":22211,"62917":22205,"62918":22206,"62919":23368,"62920":23367,"62921":24011,"62922":24015,"62923":24305,"62924":25085,"62925":25883,"62926":27394,"62927":27388,"62928":27395,"62929":27384,"62930":27392,"62931":28739,"62932":28740,"62933":28746,"62934":28744,"62935":28745,"62936":28741,"62937":28742,"62938":29213,"62939":29210,"62940":29209,"62941":29566,"62942":29975,"62943":30314,"62944":30672,"62945":31021,"62946":31025,"62947":31023,"62948":31828,"62949":31827,"62950":31986,"62951":32394,"62952":32391,"62953":32392,"62954":32395,"62955":32390,"62956":32397,"62957":32589,"62958":32699,"62959":32816,"62960":33245,"62961":34328,"62962":34346,"62963":34342,"62964":34335,"62965":34339,"62966":34332,"62967":34329,"62968":34343,"62969":34350,"62970":34337,"62971":34336,"62972":34345,"62973":34334,"62974":34341,"63040":34857,"63041":34845,"63042":34843,"63043":34848,"63044":34852,"63045":34844,"63046":34859,"63047":34890,"63048":35181,"63049":35177,"63050":35182,"63051":35179,"63052":35322,"63053":35705,"63054":35704,"63055":35653,"63056":35706,"63057":35707,"63058":36112,"63059":36116,"63060":36271,"63061":36494,"63062":36492,"63063":36702,"63064":36699,"63065":36701,"63066":37190,"63067":37188,"63068":37189,"63069":37305,"63070":37951,"63071":37947,"63072":37942,"63073":37929,"63074":37949,"63075":37948,"63076":37936,"63077":37945,"63078":37930,"63079":37943,"63080":37932,"63081":37952,"63082":37937,"63083":38373,"63084":38372,"63085":38371,"63086":38709,"63087":38714,"63088":38847,"63089":38881,"63090":39012,"63091":39113,"63092":39110,"63093":39104,"63094":39256,"63095":39254,"63096":39481,"63097":39485,"63098":39494,"63099":39492,"63100":39490,"63101":39489,"63102":39482,"63137":39487,"63138":39629,"63139":39701,"63140":39703,"63141":39704,"63142":39702,"63143":39738,"63144":39762,"63145":39979,"63146":39965,"63147":39964,"63148":39980,"63149":39971,"63150":39976,"63151":39977,"63152":39972,"63153":39969,"63154":40375,"63155":40374,"63156":40380,"63157":40385,"63158":40391,"63159":40394,"63160":40399,"63161":40382,"63162":40389,"63163":40387,"63164":40379,"63165":40373,"63166":40398,"63167":40377,"63168":40378,"63169":40364,"63170":40392,"63171":40369,"63172":40365,"63173":40396,"63174":40371,"63175":40397,"63176":40370,"63177":40570,"63178":40604,"63179":40683,"63180":40686,"63181":40685,"63182":40731,"63183":40728,"63184":40730,"63185":40753,"63186":40782,"63187":40805,"63188":40804,"63189":40850,"63190":20153,"63191":22214,"63192":22213,"63193":22219,"63194":22897,"63195":23371,"63196":23372,"63197":24021,"63198":24017,"63199":24306,"63200":25889,"63201":25888,"63202":25894,"63203":25890,"63204":27403,"63205":27400,"63206":27401,"63207":27661,"63208":28757,"63209":28758,"63210":28759,"63211":28754,"63212":29214,"63213":29215,"63214":29353,"63215":29567,"63216":29912,"63217":29909,"63218":29913,"63219":29911,"63220":30317,"63221":30381,"63222":31029,"63223":31156,"63224":31344,"63225":31345,"63226":31831,"63227":31836,"63228":31833,"63229":31835,"63230":31834,"63296":31988,"63297":31985,"63298":32401,"63299":32591,"63300":32647,"63301":33246,"63302":33387,"63303":34356,"63304":34357,"63305":34355,"63306":34348,"63307":34354,"63308":34358,"63309":34860,"63310":34856,"63311":34854,"63312":34858,"63313":34853,"63314":35185,"63315":35263,"63316":35262,"63317":35323,"63318":35710,"63319":35716,"63320":35714,"63321":35718,"63322":35717,"63323":35711,"63324":36117,"63325":36501,"63326":36500,"63327":36506,"63328":36498,"63329":36496,"63330":36502,"63331":36503,"63332":36704,"63333":36706,"63334":37191,"63335":37964,"63336":37968,"63337":37962,"63338":37963,"63339":37967,"63340":37959,"63341":37957,"63342":37960,"63343":37961,"63344":37958,"63345":38719,"63346":38883,"63347":39018,"63348":39017,"63349":39115,"63350":39252,"63351":39259,"63352":39502,"63353":39507,"63354":39508,"63355":39500,"63356":39503,"63357":39496,"63358":39498,"63393":39497,"63394":39506,"63395":39504,"63396":39632,"63397":39705,"63398":39723,"63399":39739,"63400":39766,"63401":39765,"63402":40006,"63403":40008,"63404":39999,"63405":40004,"63406":39993,"63407":39987,"63408":40001,"63409":39996,"63410":39991,"63411":39988,"63412":39986,"63413":39997,"63414":39990,"63415":40411,"63416":40402,"63417":40414,"63418":40410,"63419":40395,"63420":40400,"63421":40412,"63422":40401,"63423":40415,"63424":40425,"63425":40409,"63426":40408,"63427":40406,"63428":40437,"63429":40405,"63430":40413,"63431":40630,"63432":40688,"63433":40757,"63434":40755,"63435":40754,"63436":40770,"63437":40811,"63438":40853,"63439":40866,"63440":20797,"63441":21145,"63442":22760,"63443":22759,"63444":22898,"63445":23373,"63446":24024,"63447":34863,"63448":24399,"63449":25089,"63450":25091,"63451":25092,"63452":25897,"63453":25893,"63454":26006,"63455":26347,"63456":27409,"63457":27410,"63458":27407,"63459":27594,"63460":28763,"63461":28762,"63462":29218,"63463":29570,"63464":29569,"63465":29571,"63466":30320,"63467":30676,"63468":31847,"63469":31846,"63470":32405,"63471":33388,"63472":34362,"63473":34368,"63474":34361,"63475":34364,"63476":34353,"63477":34363,"63478":34366,"63479":34864,"63480":34866,"63481":34862,"63482":34867,"63483":35190,"63484":35188,"63485":35187,"63486":35326,"63552":35724,"63553":35726,"63554":35723,"63555":35720,"63556":35909,"63557":36121,"63558":36504,"63559":36708,"63560":36707,"63561":37308,"63562":37986,"63563":37973,"63564":37981,"63565":37975,"63566":37982,"63567":38852,"63568":38853,"63569":38912,"63570":39510,"63571":39513,"63572":39710,"63573":39711,"63574":39712,"63575":40018,"63576":40024,"63577":40016,"63578":40010,"63579":40013,"63580":40011,"63581":40021,"63582":40025,"63583":40012,"63584":40014,"63585":40443,"63586":40439,"63587":40431,"63588":40419,"63589":40427,"63590":40440,"63591":40420,"63592":40438,"63593":40417,"63594":40430,"63595":40422,"63596":40434,"63597":40432,"63598":40418,"63599":40428,"63600":40436,"63601":40435,"63602":40424,"63603":40429,"63604":40642,"63605":40656,"63606":40690,"63607":40691,"63608":40710,"63609":40732,"63610":40760,"63611":40759,"63612":40758,"63613":40771,"63614":40783,"63649":40817,"63650":40816,"63651":40814,"63652":40815,"63653":22227,"63654":22221,"63655":23374,"63656":23661,"63657":25901,"63658":26349,"63659":26350,"63660":27411,"63661":28767,"63662":28769,"63663":28765,"63664":28768,"63665":29219,"63666":29915,"63667":29925,"63668":30677,"63669":31032,"63670":31159,"63671":31158,"63672":31850,"63673":32407,"63674":32649,"63675":33389,"63676":34371,"63677":34872,"63678":34871,"63679":34869,"63680":34891,"63681":35732,"63682":35733,"63683":36510,"63684":36511,"63685":36512,"63686":36509,"63687":37310,"63688":37309,"63689":37314,"63690":37995,"63691":37992,"63692":37993,"63693":38629,"63694":38726,"63695":38723,"63696":38727,"63697":38855,"63698":38885,"63699":39518,"63700":39637,"63701":39769,"63702":40035,"63703":40039,"63704":40038,"63705":40034,"63706":40030,"63707":40032,"63708":40450,"63709":40446,"63710":40455,"63711":40451,"63712":40454,"63713":40453,"63714":40448,"63715":40449,"63716":40457,"63717":40447,"63718":40445,"63719":40452,"63720":40608,"63721":40734,"63722":40774,"63723":40820,"63724":40821,"63725":40822,"63726":22228,"63727":25902,"63728":26040,"63729":27416,"63730":27417,"63731":27415,"63732":27418,"63733":28770,"63734":29222,"63735":29354,"63736":30680,"63737":30681,"63738":31033,"63739":31849,"63740":31851,"63741":31990,"63742":32410,"63808":32408,"63809":32411,"63810":32409,"63811":33248,"63812":33249,"63813":34374,"63814":34375,"63815":34376,"63816":35193,"63817":35194,"63818":35196,"63819":35195,"63820":35327,"63821":35736,"63822":35737,"63823":36517,"63824":36516,"63825":36515,"63826":37998,"63827":37997,"63828":37999,"63829":38001,"63830":38003,"63831":38729,"63832":39026,"63833":39263,"63834":40040,"63835":40046,"63836":40045,"63837":40459,"63838":40461,"63839":40464,"63840":40463,"63841":40466,"63842":40465,"63843":40609,"63844":40693,"63845":40713,"63846":40775,"63847":40824,"63848":40827,"63849":40826,"63850":40825,"63851":22302,"63852":28774,"63853":31855,"63854":34876,"63855":36274,"63856":36518,"63857":37315,"63858":38004,"63859":38008,"63860":38006,"63861":38005,"63862":39520,"63863":40052,"63864":40051,"63865":40049,"63866":40053,"63867":40468,"63868":40467,"63869":40694,"63870":40714,"63905":40868,"63906":28776,"63907":28773,"63908":31991,"63909":34410,"63910":34878,"63911":34877,"63912":34879,"63913":35742,"63914":35996,"63915":36521,"63916":36553,"63917":38731,"63918":39027,"63919":39028,"63920":39116,"63921":39265,"63922":39339,"63923":39524,"63924":39526,"63925":39527,"63926":39716,"63927":40469,"63928":40471,"63929":40776,"63930":25095,"63931":27422,"63932":29223,"63933":34380,"63934":36520,"63935":38018,"63936":38016,"63937":38017,"63938":39529,"63939":39528,"63940":39726,"63941":40473,"63942":29225,"63943":34379,"63944":35743,"63945":38019,"63946":40057,"63947":40631,"63948":30325,"63949":39531,"63950":40058,"63951":40477,"63952":28777,"63953":28778,"63954":40612,"63955":40830,"63956":40777,"63957":40856,"63958":30849,"63959":37561,"63960":35023,"63961":22715,"63962":24658,"63963":31911,"63964":23290,"63965":9556,"63966":9574,"63967":9559,"63968":9568,"63969":9580,"63970":9571,"63971":9562,"63972":9577,"63973":9565,"63974":9554,"63975":9572,"63976":9557,"63977":9566,"63978":9578,"63979":9569,"63980":9560,"63981":9575,"63982":9563,"63983":9555,"63984":9573,"63985":9558,"63986":9567,"63987":9579,"63988":9570,"63989":9561,"63990":9576,"63991":9564,"63992":9553,"63993":9552,"63994":9581,"63995":9582,"63996":9584,"63997":9583,"63998":9619,"64064":57344,"64065":57345,"64066":57346,"64067":57347,"64068":57348,"64069":57349,"64070":57350,"64071":57351,"64072":57352,"64073":57353,"64074":57354,"64075":57355,"64076":57356,"64077":57357,"64078":57358,"64079":57359,"64080":57360,"64081":57361,"64082":57362,"64083":57363,"64084":57364,"64085":57365,"64086":57366,"64087":57367,"64088":57368,"64089":57369,"64090":57370,"64091":57371,"64092":57372,"64093":57373,"64094":57374,"64095":57375,"64096":57376,"64097":57377,"64098":57378,"64099":57379,"64100":29234,"64101":29244,"64102":29286,"64103":29314,"64104":29327,"64105":29343,"64106":29357,"64107":29361,"64108":29368,"64109":29374,"64110":29389,"64111":29403,"64112":29476,"64113":29487,"64114":29496,"64115":29497,"64116":29629,"64117":29646,"64118":29681,"64119":29814,"64120":29858,"64121":29953,"64122":29977,"64123":29987,"64124":30012,"64125":30020,"64126":30025,"64161":30029,"64162":30061,"64163":30082,"64164":30083,"64165":30089,"64166":30124,"64167":30166,"64168":30185,"64169":30272,"64170":30285,"64171":30292,"64172":30312,"64173":30336,"64174":30339,"64175":30352,"64176":30391,"64177":30393,"64178":30477,"64179":30494,"64180":30531,"64181":30744,"64182":30748,"64183":30777,"64184":30780,"64185":30791,"64186":30806,"64187":30842,"64188":30901,"64189":30905,"64190":30918,"64191":30937,"64192":30983,"64193":31024,"64194":31028,"64195":31035,"64196":31104,"64197":31133,"64198":31171,"64199":31201,"64200":31238,"64201":31246,"64202":31299,"64203":31312,"64204":31427,"64205":31442,"64206":31458,"64207":31463,"64208":31480,"64209":31542,"64210":31586,"64211":31596,"64212":31610,"64213":31611,"64214":31642,"64215":31646,"64216":31647,"64217":31650,"64218":31655,"64219":31734,"64220":31762,"64221":31764,"64222":31823,"64223":31830,"64224":31832,"64225":31915,"64226":31994,"64227":32072,"64228":32075,"64229":32119,"64230":32212,"64231":32213,"64232":32214,"64233":32228,"64234":32333,"64235":32349,"64236":32383,"64237":32393,"64238":32398,"64239":32402,"64240":32468,"64241":32497,"64242":32530,"64243":32560,"64244":32625,"64245":32642,"64246":32686,"64247":32710,"64248":32800,"64249":32802,"64250":32805,"64251":32817,"64252":32863,"64253":32872,"64254":32940,"64320":32951,"64321":20890,"64322":21526,"64323":21524,"64324":13535,"64325":19581,"64326":25283,"64327":57508,"64328":57509,"64329":57510,"64330":21707,"64331":57512,"64332":21948,"64333":32950,"64334":20903,"64335":57516,"64336":57517,"64337":57518,"64338":21779,"64339":33318,"64340":57521,"64341":21790,"64342":21982,"64343":25529,"64344":26776,"64345":57526,"64346":21762,"64347":21865,"64348":30132,"64349":25596,"64350":40580,"64351":37418,"64352":57533,"64353":57534,"64354":57535,"64355":35015,"64356":24734,"64357":22053,"64358":28997,"64359":23282,"64360":57541,"64361":21135,"64362":22095,"64363":30611,"64364":34694,"64365":36397,"64366":33206,"64367":13822,"64368":29174,"64369":57550,"64370":34820,"64371":37765,"64372":57553,"64373":57554,"64374":30310,"64375":57556,"64376":40050,"64377":57558,"64378":25294,"64379":57560,"64380":40598,"64381":18825,"64382":31955,"64417":36570,"64418":40619,"64419":25831,"64420":57567,"64421":33450,"64422":26471,"64423":28018,"64424":30982,"64425":31172,"64426":32590,"64427":34798,"64428":57575,"64429":33726,"64430":34351,"64431":35237,"64432":17935,"64433":57580,"64434":39112,"64435":39232,"64436":39245,"64437":39436,"64438":39639,"64439":40600,"64440":40742,"64441":57588,"64442":20227,"64443":57590,"64444":20281,"64445":20274,"64446":20395,"64447":20566,"64448":57595,"64449":20526,"64450":20646,"64451":20697,"64452":20750,"64453":20717,"64454":20737,"64455":20980,"64456":21023,"64457":21088,"64458":21079,"64459":21146,"64460":21201,"64461":21216,"64462":21217,"64463":20947,"64464":20959,"64465":30022,"64466":20990,"64467":21298,"64468":21292,"64469":21299,"64470":21419,"64471":21418,"64472":40846,"64473":21609,"64474":21660,"64475":21466,"64476":27338,"64477":21875,"64478":57625,"64479":13782,"64480":57627,"64481":22033,"64482":22093,"64483":57630,"64484":22100,"64485":13811,"64486":57633,"64487":22342,"64488":22394,"64489":22375,"64490":22586,"64491":22502,"64492":22493,"64493":22592,"64494":57641,"64495":22566,"64496":22748,"64497":22967,"64498":23001,"64499":23584,"64500":57647,"64501":23761,"64502":23785,"64503":23878,"64504":23950,"64505":57652,"64506":24053,"64507":24075,"64508":24082,"64509":24110,"64510":24158,"64576":57658,"64577":24397,"64578":31357,"64579":23491,"64580":31419,"64581":57663,"64582":57664,"64583":24484,"64584":24506,"64585":24508,"64586":57668,"64587":24695,"64588":24740,"64589":24755,"64590":24829,"64591":24880,"64592":57674,"64593":24988,"64594":24921,"64595":24957,"64596":24924,"64597":25471,"64598":25058,"64599":28885,"64600":25145,"64601":25192,"64602":25221,"64603":25218,"64604":25254,"64605":25301,"64606":25444,"64607":25397,"64608":25744,"64609":14940,"64610":26184,"64611":26215,"64612":26398,"64613":26627,"64614":26540,"64615":26617,"64616":26806,"64617":26924,"64618":26881,"64619":26880,"64620":26826,"64621":26995,"64622":27008,"64623":26942,"64624":57706,"64625":27058,"64626":27072,"64627":27018,"64628":27130,"64629":27113,"64630":27314,"64631":27218,"64632":27293,"64633":27421,"64634":27474,"64635":27642,"64636":15569,"64637":27854,"64638":28239,"64673":28089,"64674":28484,"64675":57723,"64676":28634,"64677":28801,"64678":31180,"64679":28980,"64680":15820,"64681":29046,"64682":57730,"64683":57731,"64684":29205,"64685":29264,"64686":29319,"64687":29484,"64688":29362,"64689":29410,"64690":29442,"64691":29512,"64692":29480,"64693":29519,"64694":29553,"64695":25989,"64696":57744,"64697":29789,"64698":29800,"64699":29982,"64700":30035,"64701":30074,"64702":30369,"64703":30412,"64704":30500,"64705":30507,"64706":16485,"64707":30803,"64708":30931,"64709":30936,"64710":40318,"64711":30895,"64712":57760,"64713":24898,"64714":31145,"64715":39994,"64716":31188,"64717":57765,"64718":31277,"64719":31294,"64720":31305,"64721":31453,"64722":31450,"64723":30147,"64724":30215,"64725":30210,"64726":57774,"64727":30311,"64728":30319,"64729":22048,"64730":35431,"64731":40727,"64732":31519,"64733":31634,"64734":31651,"64735":31695,"64736":57784,"64737":31740,"64738":31810,"64739":31825,"64740":31837,"64741":31856,"64742":31870,"64743":31878,"64744":31875,"64745":31916,"64746":31943,"64747":31938,"64748":57796,"64749":31962,"64750":57798,"64751":32077,"64752":32090,"64753":32245,"64754":32295,"64755":32366,"64756":40597,"64757":21107,"64758":32797,"64759":32866,"64760":32867,"64761":32870,"64762":32859,"64763":32934,"64764":33027,"64765":40577,"64766":33224,"64832":57815,"64833":36768,"64834":33270,"64835":33306,"64836":57819,"64837":34673,"64838":34729,"64839":34700,"64840":40606,"64841":34753,"64842":40476,"64843":57826,"64844":34774,"64845":34805,"64846":34831,"64847":34840,"64848":34861,"64849":34882,"64850":34885,"64851":39989,"64852":34926,"64853":34986,"64854":34976,"64855":25245,"64856":35139,"64857":35149,"64858":29042,"64859":34910,"64860":57843,"64861":33533,"64862":17591,"64863":33488,"64864":33669,"64865":40194,"64866":40809,"64867":33824,"64868":57851,"64869":34010,"64870":33965,"64871":17659,"64872":34123,"64873":57856,"64874":34306,"64875":34320,"64876":25553,"64877":35209,"64878":35210,"64879":35220,"64880":40005,"64881":35260,"64882":35454,"64883":35401,"64884":35596,"64885":35651,"64886":35713,"64887":35660,"64888":57871,"64889":36013,"64890":36075,"64891":36087,"64892":36108,"64893":36226,"64894":36262,"64929":36308,"64930":36392,"64931":36431,"64932":36471,"64933":36469,"64934":36519,"64935":36633,"64936":57885,"64937":36700,"64938":40260,"64939":37060,"64940":37201,"64941":57890,"64942":37212,"64943":37209,"64944":37223,"64945":37244,"64946":37262,"64947":37307,"64948":40616,"64949":36950,"64950":36940,"64951":37374,"64952":37474,"64953":37566,"64954":37739,"64955":37742,"64956":37818,"64957":37927,"64958":38295,"64959":38311,"64960":57909,"64961":38456,"64962":57911,"64963":38531,"64964":38550,"64965":38529,"64966":38589,"64967":38659,"64968":38689,"64969":38705,"64970":38751,"64971":38815,"64972":38836,"64973":38840,"64974":38842,"64975":38846,"64976":38856,"64977":40639,"64978":38943,"64979":38958,"64980":40869,"64981":38983,"64982":38987,"64983":39014,"64984":39020,"64985":39092,"64986":40794,"64987":39132,"64988":39142,"64989":39234,"64990":39225,"64991":39227,"64992":40787,"64993":39242,"64994":40773,"64995":19326,"64996":39386,"64997":31432,"64998":39610,"64999":39613,"65000":40706,"65001":39722,"65002":57951,"65003":39725,"65004":39650,"65005":39682,"65006":39679,"65007":19463,"65008":39689,"65009":19460,"65010":19515,"65011":39823,"65012":39837,"65013":39856,"65014":39948,"65015":39957,"65016":39946,"65017":39935,"65018":39982,"65019":33000,"65020":33001,"65021":33004,"65022":33038,"65088":27705,"65089":20074,"65090":38465,"65091":22770,"65092":31074,"65093":26658,"65094":57978,"65095":57979,"65096":33031,"65097":22487,"65098":17642,"65099":25653,"65100":34100,"65101":16607,"65102":57986,"65103":26906,"65104":39938,"65105":30129,"65106":33747,"65107":29041,"65108":27147,"65109":57993,"65110":27258,"65111":39668,"65112":57996,"65113":57997,"65114":30649,"65115":25904,"65116":28054,"65117":22071,"65118":26405,"65119":27179,"65120":32093,"65121":36961,"65122":20120,"65123":31910,"65124":31545,"65125":58009,"65126":22901,"65127":14023,"65128":28799,"65129":58013,"65130":28299,"65131":58015,"65132":58016,"65133":38749,"65134":37584,"65135":22356,"65136":58020,"65137":16089,"65138":58022,"65139":58023,"65140":24985,"65141":29792,"65142":28991,"65143":31022,"65144":23190,"65145":37704,"65146":26254,"65147":20477,"65148":37697,"65149":13908,"65150":23925,"65185":28702,"65186":25979,"65187":28813,"65188":24269,"65189":58039,"65190":24743,"65191":31408,"65192":24419,"65193":58043,"65194":29687,"65195":58045,"65196":29800,"65197":30132,"65198":58048,"65199":39785,"65200":189,"65201":8531,"65202":8532,"65203":188,"65204":190,"65205":8533,"65206":8534,"65207":8535,"65208":8536,"65209":8537,"65210":8538,"65211":34450,"65212":34464,"65213":34477,"65214":34482,"65215":34725,"65216":34737,"65217":8539,"65218":8540,"65219":8541,"65220":8542,"65221":34778,"65222":34895,"65223":34912,"65224":34951,"65225":34959,"65226":34960,"65227":35046,"65228":35071,"65229":35072,"65230":35108,"65231":35143,"65232":35156,"65233":35173,"65234":35200,"65235":35217,"65236":35356,"65237":35369,"65238":35371,"65239":35384,"65240":35389,"65241":8978,"65242":35472,"65243":35476,"65244":35484,"65245":35497,"65246":35503,"65247":35508,"65248":35562,"65249":35615,"65250":8240,"65251":35647,"65252":35661,"65253":35678,"65254":35682,"65255":35689,"65256":35739,"65257":35921,"65258":35995,"65259":35999,"65260":36052,"65261":36054,"65262":33042,"65263":33073,"65264":33078,"65265":33119,"65266":33133,"65267":33149,"65268":33171,"65269":33194,"65270":33208,"65271":33217,"65272":33321,"65273":33325,"65274":33326,"65275":33342,"65276":33378,"65277":33386,"65278":33416,"NaN":null} \ No newline at end of file diff --git a/node_modules/iconv-lite/encodings/table/gbk.js b/node_modules/iconv-lite/encodings/table/gbk.js new file mode 100644 index 0000000..c464623 --- /dev/null +++ b/node_modules/iconv-lite/encodings/table/gbk.js @@ -0,0 +1 @@ +module.exports={33088:19970,33089:19972,33090:19973,33091:19974,33092:19983,33093:19986,33094:19991,33095:19999,33096:20000,33097:20001,33098:20003,33099:20006,33100:20009,33101:20014,33102:20015,33103:20017,33104:20019,33105:20021,33106:20023,33107:20028,33108:20032,33109:20033,33110:20034,33111:20036,33112:20038,33113:20042,33114:20049,33115:20053,33116:20055,33117:20058,33118:20059,33119:20066,33120:20067,33121:20068,33122:20069,33123:20071,33124:20072,33125:20074,33126:20075,33127:20076,33128:20077,33129:20078,33130:20079,33131:20082,33132:20084,33133:20085,33134:20086,33135:20087,33136:20088,33137:20089,33138:20090,33139:20091,33140:20092,33141:20093,33142:20095,33143:20096,33144:20097,33145:20098,33146:20099,33147:20100,33148:20101,33149:20103,33150:20106,33152:20112,33153:20118,33154:20119,33155:20121,33156:20124,33157:20125,33158:20126,33159:20131,33160:20138,33161:20143,33162:20144,33163:20145,33164:20148,33165:20150,33166:20151,33167:20152,33168:20153,33169:20156,33170:20157,33171:20158,33172:20168,33173:20172,33174:20175,33175:20176,33176:20178,33177:20186,33178:20187,33179:20188,33180:20192,33181:20194,33182:20198,33183:20199,33184:20201,33185:20205,33186:20206,33187:20207,33188:20209,33189:20212,33190:20216,33191:20217,33192:20218,33193:20220,33194:20222,33195:20224,33196:20226,33197:20227,33198:20228,33199:20229,33200:20230,33201:20231,33202:20232,33203:20235,33204:20236,33205:20242,33206:20243,33207:20244,33208:20245,33209:20246,33210:20252,33211:20253,33212:20257,33213:20259,33214:20264,33215:20265,33216:20268,33217:20269,33218:20270,33219:20273,33220:20275,33221:20277,33222:20279,33223:20281,33224:20283,33225:20286,33226:20287,33227:20288,33228:20289,33229:20290,33230:20292,33231:20293,33232:20295,33233:20296,33234:20297,33235:20298,33236:20299,33237:20300,33238:20306,33239:20308,33240:20310,33241:20321,33242:20322,33243:20326,33244:20328,33245:20330,33246:20331,33247:20333,33248:20334,33249:20337,33250:20338,33251:20341,33252:20343,33253:20344,33254:20345,33255:20346,33256:20349,33257:20352,33258:20353,33259:20354,33260:20357,33261:20358,33262:20359,33263:20362,33264:20364,33265:20366,33266:20368,33267:20370,33268:20371,33269:20373,33270:20374,33271:20376,33272:20377,33273:20378,33274:20380,33275:20382,33276:20383,33277:20385,33278:20386,33344:20388,33345:20395,33346:20397,33347:20400,33348:20401,33349:20402,33350:20403,33351:20404,33352:20406,33353:20407,33354:20408,33355:20409,33356:20410,33357:20411,33358:20412,33359:20413,33360:20414,33361:20416,33362:20417,33363:20418,33364:20422,33365:20423,33366:20424,33367:20425,33368:20427,33369:20428,33370:20429,33371:20434,33372:20435,33373:20436,33374:20437,33375:20438,33376:20441,33377:20443,33378:20448,33379:20450,33380:20452,33381:20453,33382:20455,33383:20459,33384:20460,33385:20464,33386:20466,33387:20468,33388:20469,33389:20470,33390:20471,33391:20473,33392:20475,33393:20476,33394:20477,33395:20479,33396:20480,33397:20481,33398:20482,33399:20483,33400:20484,33401:20485,33402:20486,33403:20487,33404:20488,33405:20489,33406:20490,33408:20491,33409:20494,33410:20496,33411:20497,33412:20499,33413:20501,33414:20502,33415:20503,33416:20507,33417:20509,33418:20510,33419:20512,33420:20514,33421:20515,33422:20516,33423:20519,33424:20523,33425:20527,33426:20528,33427:20529,33428:20530,33429:20531,33430:20532,33431:20533,33432:20534,33433:20535,33434:20536,33435:20537,33436:20539,33437:20541,33438:20543,33439:20544,33440:20545,33441:20546,33442:20548,33443:20549,33444:20550,33445:20553,33446:20554,33447:20555,33448:20557,33449:20560,33450:20561,33451:20562,33452:20563,33453:20564,33454:20566,33455:20567,33456:20568,33457:20569,33458:20571,33459:20573,33460:20574,33461:20575,33462:20576,33463:20577,33464:20578,33465:20579,33466:20580,33467:20582,33468:20583,33469:20584,33470:20585,33471:20586,33472:20587,33473:20589,33474:20590,33475:20591,33476:20592,33477:20593,33478:20594,33479:20595,33480:20596,33481:20597,33482:20600,33483:20601,33484:20602,33485:20604,33486:20605,33487:20609,33488:20610,33489:20611,33490:20612,33491:20614,33492:20615,33493:20617,33494:20618,33495:20619,33496:20620,33497:20622,33498:20623,33499:20624,33500:20625,33501:20626,33502:20627,33503:20628,33504:20629,33505:20630,33506:20631,33507:20632,33508:20633,33509:20634,33510:20635,33511:20636,33512:20637,33513:20638,33514:20639,33515:20640,33516:20641,33517:20642,33518:20644,33519:20646,33520:20650,33521:20651,33522:20653,33523:20654,33524:20655,33525:20656,33526:20657,33527:20659,33528:20660,33529:20661,33530:20662,33531:20663,33532:20664,33533:20665,33534:20668,33600:20669,33601:20670,33602:20671,33603:20672,33604:20673,33605:20674,33606:20675,33607:20676,33608:20677,33609:20678,33610:20679,33611:20680,33612:20681,33613:20682,33614:20683,33615:20684,33616:20685,33617:20686,33618:20688,33619:20689,33620:20690,33621:20691,33622:20692,33623:20693,33624:20695,33625:20696,33626:20697,33627:20699,33628:20700,33629:20701,33630:20702,33631:20703,33632:20704,33633:20705,33634:20706,33635:20707,33636:20708,33637:20709,33638:20712,33639:20713,33640:20714,33641:20715,33642:20719,33643:20720,33644:20721,33645:20722,33646:20724,33647:20726,33648:20727,33649:20728,33650:20729,33651:20730,33652:20732,33653:20733,33654:20734,33655:20735,33656:20736,33657:20737,33658:20738,33659:20739,33660:20740,33661:20741,33662:20744,33664:20745,33665:20746,33666:20748,33667:20749,33668:20750,33669:20751,33670:20752,33671:20753,33672:20755,33673:20756,33674:20757,33675:20758,33676:20759,33677:20760,33678:20761,33679:20762,33680:20763,33681:20764,33682:20765,33683:20766,33684:20767,33685:20768,33686:20770,33687:20771,33688:20772,33689:20773,33690:20774,33691:20775,33692:20776,33693:20777,33694:20778,33695:20779,33696:20780,33697:20781,33698:20782,33699:20783,33700:20784,33701:20785,33702:20786,33703:20787,33704:20788,33705:20789,33706:20790,33707:20791,33708:20792,33709:20793,33710:20794,33711:20795,33712:20796,33713:20797,33714:20798,33715:20802,33716:20807,33717:20810,33718:20812,33719:20814,33720:20815,33721:20816,33722:20818,33723:20819,33724:20823,33725:20824,33726:20825,33727:20827,33728:20829,33729:20830,33730:20831,33731:20832,33732:20833,33733:20835,33734:20836,33735:20838,33736:20839,33737:20841,33738:20842,33739:20847,33740:20850,33741:20858,33742:20862,33743:20863,33744:20867,33745:20868,33746:20870,33747:20871,33748:20874,33749:20875,33750:20878,33751:20879,33752:20880,33753:20881,33754:20883,33755:20884,33756:20888,33757:20890,33758:20893,33759:20894,33760:20895,33761:20897,33762:20899,33763:20902,33764:20903,33765:20904,33766:20905,33767:20906,33768:20909,33769:20910,33770:20916,33771:20920,33772:20921,33773:20922,33774:20926,33775:20927,33776:20929,33777:20930,33778:20931,33779:20933,33780:20936,33781:20938,33782:20941,33783:20942,33784:20944,33785:20946,33786:20947,33787:20948,33788:20949,33789:20950,33790:20951,33856:20952,33857:20953,33858:20954,33859:20956,33860:20958,33861:20959,33862:20962,33863:20963,33864:20965,33865:20966,33866:20967,33867:20968,33868:20969,33869:20970,33870:20972,33871:20974,33872:20977,33873:20978,33874:20980,33875:20983,33876:20990,33877:20996,33878:20997,33879:21001,33880:21003,33881:21004,33882:21007,33883:21008,33884:21011,33885:21012,33886:21013,33887:21020,33888:21022,33889:21023,33890:21025,33891:21026,33892:21027,33893:21029,33894:21030,33895:21031,33896:21034,33897:21036,33898:21039,33899:21041,33900:21042,33901:21044,33902:21045,33903:21052,33904:21054,33905:21060,33906:21061,33907:21062,33908:21063,33909:21064,33910:21065,33911:21067,33912:21070,33913:21071,33914:21074,33915:21075,33916:21077,33917:21079,33918:21080,33920:21081,33921:21082,33922:21083,33923:21085,33924:21087,33925:21088,33926:21090,33927:21091,33928:21092,33929:21094,33930:21096,33931:21099,33932:21100,33933:21101,33934:21102,33935:21104,33936:21105,33937:21107,33938:21108,33939:21109,33940:21110,33941:21111,33942:21112,33943:21113,33944:21114,33945:21115,33946:21116,33947:21118,33948:21120,33949:21123,33950:21124,33951:21125,33952:21126,33953:21127,33954:21129,33955:21130,33956:21131,33957:21132,33958:21133,33959:21134,33960:21135,33961:21137,33962:21138,33963:21140,33964:21141,33965:21142,33966:21143,33967:21144,33968:21145,33969:21146,33970:21148,33971:21156,33972:21157,33973:21158,33974:21159,33975:21166,33976:21167,33977:21168,33978:21172,33979:21173,33980:21174,33981:21175,33982:21176,33983:21177,33984:21178,33985:21179,33986:21180,33987:21181,33988:21184,33989:21185,33990:21186,33991:21188,33992:21189,33993:21190,33994:21192,33995:21194,33996:21196,33997:21197,33998:21198,33999:21199,34000:21201,34001:21203,34002:21204,34003:21205,34004:21207,34005:21209,34006:21210,34007:21211,34008:21212,34009:21213,34010:21214,34011:21216,34012:21217,34013:21218,34014:21219,34015:21221,34016:21222,34017:21223,34018:21224,34019:21225,34020:21226,34021:21227,34022:21228,34023:21229,34024:21230,34025:21231,34026:21233,34027:21234,34028:21235,34029:21236,34030:21237,34031:21238,34032:21239,34033:21240,34034:21243,34035:21244,34036:21245,34037:21249,34038:21250,34039:21251,34040:21252,34041:21255,34042:21257,34043:21258,34044:21259,34045:21260,34046:21262,34112:21265,34113:21266,34114:21267,34115:21268,34116:21272,34117:21275,34118:21276,34119:21278,34120:21279,34121:21282,34122:21284,34123:21285,34124:21287,34125:21288,34126:21289,34127:21291,34128:21292,34129:21293,34130:21295,34131:21296,34132:21297,34133:21298,34134:21299,34135:21300,34136:21301,34137:21302,34138:21303,34139:21304,34140:21308,34141:21309,34142:21312,34143:21314,34144:21316,34145:21318,34146:21323,34147:21324,34148:21325,34149:21328,34150:21332,34151:21336,34152:21337,34153:21339,34154:21341,34155:21349,34156:21352,34157:21354,34158:21356,34159:21357,34160:21362,34161:21366,34162:21369,34163:21371,34164:21372,34165:21373,34166:21374,34167:21376,34168:21377,34169:21379,34170:21383,34171:21384,34172:21386,34173:21390,34174:21391,34176:21392,34177:21393,34178:21394,34179:21395,34180:21396,34181:21398,34182:21399,34183:21401,34184:21403,34185:21404,34186:21406,34187:21408,34188:21409,34189:21412,34190:21415,34191:21418,34192:21419,34193:21420,34194:21421,34195:21423,34196:21424,34197:21425,34198:21426,34199:21427,34200:21428,34201:21429,34202:21431,34203:21432,34204:21433,34205:21434,34206:21436,34207:21437,34208:21438,34209:21440,34210:21443,34211:21444,34212:21445,34213:21446,34214:21447,34215:21454,34216:21455,34217:21456,34218:21458,34219:21459,34220:21461,34221:21466,34222:21468,34223:21469,34224:21470,34225:21473,34226:21474,34227:21479,34228:21492,34229:21498,34230:21502,34231:21503,34232:21504,34233:21506,34234:21509,34235:21511,34236:21515,34237:21524,34238:21528,34239:21529,34240:21530,34241:21532,34242:21538,34243:21540,34244:21541,34245:21546,34246:21552,34247:21555,34248:21558,34249:21559,34250:21562,34251:21565,34252:21567,34253:21569,34254:21570,34255:21572,34256:21573,34257:21575,34258:21577,34259:21580,34260:21581,34261:21582,34262:21583,34263:21585,34264:21594,34265:21597,34266:21598,34267:21599,34268:21600,34269:21601,34270:21603,34271:21605,34272:21607,34273:21609,34274:21610,34275:21611,34276:21612,34277:21613,34278:21614,34279:21615,34280:21616,34281:21620,34282:21625,34283:21626,34284:21630,34285:21631,34286:21633,34287:21635,34288:21637,34289:21639,34290:21640,34291:21641,34292:21642,34293:21645,34294:21649,34295:21651,34296:21655,34297:21656,34298:21660,34299:21662,34300:21663,34301:21664,34302:21665,34368:21666,34369:21669,34370:21678,34371:21680,34372:21682,34373:21685,34374:21686,34375:21687,34376:21689,34377:21690,34378:21692,34379:21694,34380:21699,34381:21701,34382:21706,34383:21707,34384:21718,34385:21720,34386:21723,34387:21728,34388:21729,34389:21730,34390:21731,34391:21732,34392:21739,34393:21740,34394:21743,34395:21744,34396:21745,34397:21748,34398:21749,34399:21750,34400:21751,34401:21752,34402:21753,34403:21755,34404:21758,34405:21760,34406:21762,34407:21763,34408:21764,34409:21765,34410:21768,34411:21770,34412:21771,34413:21772,34414:21773,34415:21774,34416:21778,34417:21779,34418:21781,34419:21782,34420:21783,34421:21784,34422:21785,34423:21786,34424:21788,34425:21789,34426:21790,34427:21791,34428:21793,34429:21797,34430:21798,34432:21800,34433:21801,34434:21803,34435:21805,34436:21810,34437:21812,34438:21813,34439:21814,34440:21816,34441:21817,34442:21818,34443:21819,34444:21821,34445:21824,34446:21826,34447:21829,34448:21831,34449:21832,34450:21835,34451:21836,34452:21837,34453:21838,34454:21839,34455:21841,34456:21842,34457:21843,34458:21844,34459:21847,34460:21848,34461:21849,34462:21850,34463:21851,34464:21853,34465:21854,34466:21855,34467:21856,34468:21858,34469:21859,34470:21864,34471:21865,34472:21867,34473:21871,34474:21872,34475:21873,34476:21874,34477:21875,34478:21876,34479:21881,34480:21882,34481:21885,34482:21887,34483:21893,34484:21894,34485:21900,34486:21901,34487:21902,34488:21904,34489:21906,34490:21907,34491:21909,34492:21910,34493:21911,34494:21914,34495:21915,34496:21918,34497:21920,34498:21921,34499:21922,34500:21923,34501:21924,34502:21925,34503:21926,34504:21928,34505:21929,34506:21930,34507:21931,34508:21932,34509:21933,34510:21934,34511:21935,34512:21936,34513:21938,34514:21940,34515:21942,34516:21944,34517:21946,34518:21948,34519:21951,34520:21952,34521:21953,34522:21954,34523:21955,34524:21958,34525:21959,34526:21960,34527:21962,34528:21963,34529:21966,34530:21967,34531:21968,34532:21973,34533:21975,34534:21976,34535:21977,34536:21978,34537:21979,34538:21982,34539:21984,34540:21986,34541:21991,34542:21993,34543:21997,34544:21998,34545:22000,34546:22001,34547:22004,34548:22006,34549:22008,34550:22009,34551:22010,34552:22011,34553:22012,34554:22015,34555:22018,34556:22019,34557:22020,34558:22021,34624:22022,34625:22023,34626:22026,34627:22027,34628:22029,34629:22032,34630:22033,34631:22034,34632:22035,34633:22036,34634:22037,34635:22038,34636:22039,34637:22041,34638:22042,34639:22044,34640:22045,34641:22048,34642:22049,34643:22050,34644:22053,34645:22054,34646:22056,34647:22057,34648:22058,34649:22059,34650:22062,34651:22063,34652:22064,34653:22067,34654:22069,34655:22071,34656:22072,34657:22074,34658:22076,34659:22077,34660:22078,34661:22080,34662:22081,34663:22082,34664:22083,34665:22084,34666:22085,34667:22086,34668:22087,34669:22088,34670:22089,34671:22090,34672:22091,34673:22095,34674:22096,34675:22097,34676:22098,34677:22099,34678:22101,34679:22102,34680:22106,34681:22107,34682:22109,34683:22110,34684:22111,34685:22112,34686:22113,34688:22115,34689:22117,34690:22118,34691:22119,34692:22125,34693:22126,34694:22127,34695:22128,34696:22130,34697:22131,34698:22132,34699:22133,34700:22135,34701:22136,34702:22137,34703:22138,34704:22141,34705:22142,34706:22143,34707:22144,34708:22145,34709:22146,34710:22147,34711:22148,34712:22151,34713:22152,34714:22153,34715:22154,34716:22155,34717:22156,34718:22157,34719:22160,34720:22161,34721:22162,34722:22164,34723:22165,34724:22166,34725:22167,34726:22168,34727:22169,34728:22170,34729:22171,34730:22172,34731:22173,34732:22174,34733:22175,34734:22176,34735:22177,34736:22178,34737:22180,34738:22181,34739:22182,34740:22183,34741:22184,34742:22185,34743:22186,34744:22187,34745:22188,34746:22189,34747:22190,34748:22192,34749:22193,34750:22194,34751:22195,34752:22196,34753:22197,34754:22198,34755:22200,34756:22201,34757:22202,34758:22203,34759:22205,34760:22206,34761:22207,34762:22208,34763:22209,34764:22210,34765:22211,34766:22212,34767:22213,34768:22214,34769:22215,34770:22216,34771:22217,34772:22219,34773:22220,34774:22221,34775:22222,34776:22223,34777:22224,34778:22225,34779:22226,34780:22227,34781:22229,34782:22230,34783:22232,34784:22233,34785:22236,34786:22243,34787:22245,34788:22246,34789:22247,34790:22248,34791:22249,34792:22250,34793:22252,34794:22254,34795:22255,34796:22258,34797:22259,34798:22262,34799:22263,34800:22264,34801:22267,34802:22268,34803:22272,34804:22273,34805:22274,34806:22277,34807:22279,34808:22283,34809:22284,34810:22285,34811:22286,34812:22287,34813:22288,34814:22289,34880:22290,34881:22291,34882:22292,34883:22293,34884:22294,34885:22295,34886:22296,34887:22297,34888:22298,34889:22299,34890:22301,34891:22302,34892:22304,34893:22305,34894:22306,34895:22308,34896:22309,34897:22310,34898:22311,34899:22315,34900:22321,34901:22322,34902:22324,34903:22325,34904:22326,34905:22327,34906:22328,34907:22332,34908:22333,34909:22335,34910:22337,34911:22339,34912:22340,34913:22341,34914:22342,34915:22344,34916:22345,34917:22347,34918:22354,34919:22355,34920:22356,34921:22357,34922:22358,34923:22360,34924:22361,34925:22370,34926:22371,34927:22373,34928:22375,34929:22380,34930:22382,34931:22384,34932:22385,34933:22386,34934:22388,34935:22389,34936:22392,34937:22393,34938:22394,34939:22397,34940:22398,34941:22399,34942:22400,34944:22401,34945:22407,34946:22408,34947:22409,34948:22410,34949:22413,34950:22414,34951:22415,34952:22416,34953:22417,34954:22420,34955:22421,34956:22422,34957:22423,34958:22424,34959:22425,34960:22426,34961:22428,34962:22429,34963:22430,34964:22431,34965:22437,34966:22440,34967:22442,34968:22444,34969:22447,34970:22448,34971:22449,34972:22451,34973:22453,34974:22454,34975:22455,34976:22457,34977:22458,34978:22459,34979:22460,34980:22461,34981:22462,34982:22463,34983:22464,34984:22465,34985:22468,34986:22469,34987:22470,34988:22471,34989:22472,34990:22473,34991:22474,34992:22476,34993:22477,34994:22480,34995:22481,34996:22483,34997:22486,34998:22487,34999:22491,35000:22492,35001:22494,35002:22497,35003:22498,35004:22499,35005:22501,35006:22502,35007:22503,35008:22504,35009:22505,35010:22506,35011:22507,35012:22508,35013:22510,35014:22512,35015:22513,35016:22514,35017:22515,35018:22517,35019:22518,35020:22519,35021:22523,35022:22524,35023:22526,35024:22527,35025:22529,35026:22531,35027:22532,35028:22533,35029:22536,35030:22537,35031:22538,35032:22540,35033:22542,35034:22543,35035:22544,35036:22546,35037:22547,35038:22548,35039:22550,35040:22551,35041:22552,35042:22554,35043:22555,35044:22556,35045:22557,35046:22559,35047:22562,35048:22563,35049:22565,35050:22566,35051:22567,35052:22568,35053:22569,35054:22571,35055:22572,35056:22573,35057:22574,35058:22575,35059:22577,35060:22578,35061:22579,35062:22580,35063:22582,35064:22583,35065:22584,35066:22585,35067:22586,35068:22587,35069:22588,35070:22589,35136:22590,35137:22591,35138:22592,35139:22593,35140:22594,35141:22595,35142:22597,35143:22598,35144:22599,35145:22600,35146:22601,35147:22602,35148:22603,35149:22606,35150:22607,35151:22608,35152:22610,35153:22611,35154:22613,35155:22614,35156:22615,35157:22617,35158:22618,35159:22619,35160:22620,35161:22621,35162:22623,35163:22624,35164:22625,35165:22626,35166:22627,35167:22628,35168:22630,35169:22631,35170:22632,35171:22633,35172:22634,35173:22637,35174:22638,35175:22639,35176:22640,35177:22641,35178:22642,35179:22643,35180:22644,35181:22645,35182:22646,35183:22647,35184:22648,35185:22649,35186:22650,35187:22651,35188:22652,35189:22653,35190:22655,35191:22658,35192:22660,35193:22662,35194:22663,35195:22664,35196:22666,35197:22667,35198:22668,35200:22669,35201:22670,35202:22671,35203:22672,35204:22673,35205:22676,35206:22677,35207:22678,35208:22679,35209:22680,35210:22683,35211:22684,35212:22685,35213:22688,35214:22689,35215:22690,35216:22691,35217:22692,35218:22693,35219:22694,35220:22695,35221:22698,35222:22699,35223:22700,35224:22701,35225:22702,35226:22703,35227:22704,35228:22705,35229:22706,35230:22707,35231:22708,35232:22709,35233:22710,35234:22711,35235:22712,35236:22713,35237:22714,35238:22715,35239:22717,35240:22718,35241:22719,35242:22720,35243:22722,35244:22723,35245:22724,35246:22726,35247:22727,35248:22728,35249:22729,35250:22730,35251:22731,35252:22732,35253:22733,35254:22734,35255:22735,35256:22736,35257:22738,35258:22739,35259:22740,35260:22742,35261:22743,35262:22744,35263:22745,35264:22746,35265:22747,35266:22748,35267:22749,35268:22750,35269:22751,35270:22752,35271:22753,35272:22754,35273:22755,35274:22757,35275:22758,35276:22759,35277:22760,35278:22761,35279:22762,35280:22765,35281:22767,35282:22769,35283:22770,35284:22772,35285:22773,35286:22775,35287:22776,35288:22778,35289:22779,35290:22780,35291:22781,35292:22782,35293:22783,35294:22784,35295:22785,35296:22787,35297:22789,35298:22790,35299:22792,35300:22793,35301:22794,35302:22795,35303:22796,35304:22798,35305:22800,35306:22801,35307:22802,35308:22803,35309:22807,35310:22808,35311:22811,35312:22813,35313:22814,35314:22816,35315:22817,35316:22818,35317:22819,35318:22822,35319:22824,35320:22828,35321:22832,35322:22834,35323:22835,35324:22837,35325:22838,35326:22843,35392:22845,35393:22846,35394:22847,35395:22848,35396:22851,35397:22853,35398:22854,35399:22858,35400:22860,35401:22861,35402:22864,35403:22866,35404:22867,35405:22873,35406:22875,35407:22876,35408:22877,35409:22878,35410:22879,35411:22881,35412:22883,35413:22884,35414:22886,35415:22887,35416:22888,35417:22889,35418:22890,35419:22891,35420:22892,35421:22893,35422:22894,35423:22895,35424:22896,35425:22897,35426:22898,35427:22901,35428:22903,35429:22906,35430:22907,35431:22908,35432:22910,35433:22911,35434:22912,35435:22917,35436:22921,35437:22923,35438:22924,35439:22926,35440:22927,35441:22928,35442:22929,35443:22932,35444:22933,35445:22936,35446:22938,35447:22939,35448:22940,35449:22941,35450:22943,35451:22944,35452:22945,35453:22946,35454:22950,35456:22951,35457:22956,35458:22957,35459:22960,35460:22961,35461:22963,35462:22964,35463:22965,35464:22966,35465:22967,35466:22968,35467:22970,35468:22972,35469:22973,35470:22975,35471:22976,35472:22977,35473:22978,35474:22979,35475:22980,35476:22981,35477:22983,35478:22984,35479:22985,35480:22988,35481:22989,35482:22990,35483:22991,35484:22997,35485:22998,35486:23001,35487:23003,35488:23006,35489:23007,35490:23008,35491:23009,35492:23010,35493:23012,35494:23014,35495:23015,35496:23017,35497:23018,35498:23019,35499:23021,35500:23022,35501:23023,35502:23024,35503:23025,35504:23026,35505:23027,35506:23028,35507:23029,35508:23030,35509:23031,35510:23032,35511:23034,35512:23036,35513:23037,35514:23038,35515:23040,35516:23042,35517:23050,35518:23051,35519:23053,35520:23054,35521:23055,35522:23056,35523:23058,35524:23060,35525:23061,35526:23062,35527:23063,35528:23065,35529:23066,35530:23067,35531:23069,35532:23070,35533:23073,35534:23074,35535:23076,35536:23078,35537:23079,35538:23080,35539:23082,35540:23083,35541:23084,35542:23085,35543:23086,35544:23087,35545:23088,35546:23091,35547:23093,35548:23095,35549:23096,35550:23097,35551:23098,35552:23099,35553:23101,35554:23102,35555:23103,35556:23105,35557:23106,35558:23107,35559:23108,35560:23109,35561:23111,35562:23112,35563:23115,35564:23116,35565:23117,35566:23118,35567:23119,35568:23120,35569:23121,35570:23122,35571:23123,35572:23124,35573:23126,35574:23127,35575:23128,35576:23129,35577:23131,35578:23132,35579:23133,35580:23134,35581:23135,35582:23136,35648:23137,35649:23139,35650:23140,35651:23141,35652:23142,35653:23144,35654:23145,35655:23147,35656:23148,35657:23149,35658:23150,35659:23151,35660:23152,35661:23153,35662:23154,35663:23155,35664:23160,35665:23161,35666:23163,35667:23164,35668:23165,35669:23166,35670:23168,35671:23169,35672:23170,35673:23171,35674:23172,35675:23173,35676:23174,35677:23175,35678:23176,35679:23177,35680:23178,35681:23179,35682:23180,35683:23181,35684:23182,35685:23183,35686:23184,35687:23185,35688:23187,35689:23188,35690:23189,35691:23190,35692:23191,35693:23192,35694:23193,35695:23196,35696:23197,35697:23198,35698:23199,35699:23200,35700:23201,35701:23202,35702:23203,35703:23204,35704:23205,35705:23206,35706:23207,35707:23208,35708:23209,35709:23211,35710:23212,35712:23213,35713:23214,35714:23215,35715:23216,35716:23217,35717:23220,35718:23222,35719:23223,35720:23225,35721:23226,35722:23227,35723:23228,35724:23229,35725:23231,35726:23232,35727:23235,35728:23236,35729:23237,35730:23238,35731:23239,35732:23240,35733:23242,35734:23243,35735:23245,35736:23246,35737:23247,35738:23248,35739:23249,35740:23251,35741:23253,35742:23255,35743:23257,35744:23258,35745:23259,35746:23261,35747:23262,35748:23263,35749:23266,35750:23268,35751:23269,35752:23271,35753:23272,35754:23274,35755:23276,35756:23277,35757:23278,35758:23279,35759:23280,35760:23282,35761:23283,35762:23284,35763:23285,35764:23286,35765:23287,35766:23288,35767:23289,35768:23290,35769:23291,35770:23292,35771:23293,35772:23294,35773:23295,35774:23296,35775:23297,35776:23298,35777:23299,35778:23300,35779:23301,35780:23302,35781:23303,35782:23304,35783:23306,35784:23307,35785:23308,35786:23309,35787:23310,35788:23311,35789:23312,35790:23313,35791:23314,35792:23315,35793:23316,35794:23317,35795:23320,35796:23321,35797:23322,35798:23323,35799:23324,35800:23325,35801:23326,35802:23327,35803:23328,35804:23329,35805:23330,35806:23331,35807:23332,35808:23333,35809:23334,35810:23335,35811:23336,35812:23337,35813:23338,35814:23339,35815:23340,35816:23341,35817:23342,35818:23343,35819:23344,35820:23345,35821:23347,35822:23349,35823:23350,35824:23352,35825:23353,35826:23354,35827:23355,35828:23356,35829:23357,35830:23358,35831:23359,35832:23361,35833:23362,35834:23363,35835:23364,35836:23365,35837:23366,35838:23367,35904:23368,35905:23369,35906:23370,35907:23371,35908:23372,35909:23373,35910:23374,35911:23375,35912:23378,35913:23382,35914:23390,35915:23392,35916:23393,35917:23399,35918:23400,35919:23403,35920:23405,35921:23406,35922:23407,35923:23410,35924:23412,35925:23414,35926:23415,35927:23416,35928:23417,35929:23419,35930:23420,35931:23422,35932:23423,35933:23426,35934:23430,35935:23434,35936:23437,35937:23438,35938:23440,35939:23441,35940:23442,35941:23444,35942:23446,35943:23455,35944:23463,35945:23464,35946:23465,35947:23468,35948:23469,35949:23470,35950:23471,35951:23473,35952:23474,35953:23479,35954:23482,35955:23483,35956:23484,35957:23488,35958:23489,35959:23491,35960:23496,35961:23497,35962:23498,35963:23499,35964:23501,35965:23502,35966:23503,35968:23505,35969:23508,35970:23509,35971:23510,35972:23511,35973:23512,35974:23513,35975:23514,35976:23515,35977:23516,35978:23520,35979:23522,35980:23523,35981:23526,35982:23527,35983:23529,35984:23530,35985:23531,35986:23532,35987:23533,35988:23535,35989:23537,35990:23538,35991:23539,35992:23540,35993:23541,35994:23542,35995:23543,35996:23549,35997:23550,35998:23552,35999:23554,36000:23555,36001:23557,36002:23559,36003:23560,36004:23563,36005:23564,36006:23565,36007:23566,36008:23568,36009:23570,36010:23571,36011:23575,36012:23577,36013:23579,36014:23582,36015:23583,36016:23584,36017:23585,36018:23587,36019:23590,36020:23592,36021:23593,36022:23594,36023:23595,36024:23597,36025:23598,36026:23599,36027:23600,36028:23602,36029:23603,36030:23605,36031:23606,36032:23607,36033:23619,36034:23620,36035:23622,36036:23623,36037:23628,36038:23629,36039:23634,36040:23635,36041:23636,36042:23638,36043:23639,36044:23640,36045:23642,36046:23643,36047:23644,36048:23645,36049:23647,36050:23650,36051:23652,36052:23655,36053:23656,36054:23657,36055:23658,36056:23659,36057:23660,36058:23661,36059:23664,36060:23666,36061:23667,36062:23668,36063:23669,36064:23670,36065:23671,36066:23672,36067:23675,36068:23676,36069:23677,36070:23678,36071:23680,36072:23683,36073:23684,36074:23685,36075:23686,36076:23687,36077:23689,36078:23690,36079:23691,36080:23694,36081:23695,36082:23698,36083:23699,36084:23701,36085:23709,36086:23710,36087:23711,36088:23712,36089:23713,36090:23716,36091:23717,36092:23718,36093:23719,36094:23720,36160:23722,36161:23726,36162:23727,36163:23728,36164:23730,36165:23732,36166:23734,36167:23737,36168:23738,36169:23739,36170:23740,36171:23742,36172:23744,36173:23746,36174:23747,36175:23749,36176:23750,36177:23751,36178:23752,36179:23753,36180:23754,36181:23756,36182:23757,36183:23758,36184:23759,36185:23760,36186:23761,36187:23763,36188:23764,36189:23765,36190:23766,36191:23767,36192:23768,36193:23770,36194:23771,36195:23772,36196:23773,36197:23774,36198:23775,36199:23776,36200:23778,36201:23779,36202:23783,36203:23785,36204:23787,36205:23788,36206:23790,36207:23791,36208:23793,36209:23794,36210:23795,36211:23796,36212:23797,36213:23798,36214:23799,36215:23800,36216:23801,36217:23802,36218:23804,36219:23805,36220:23806,36221:23807,36222:23808,36224:23809,36225:23812,36226:23813,36227:23816,36228:23817,36229:23818,36230:23819,36231:23820,36232:23821,36233:23823,36234:23824,36235:23825,36236:23826,36237:23827,36238:23829,36239:23831,36240:23832,36241:23833,36242:23834,36243:23836,36244:23837,36245:23839,36246:23840,36247:23841,36248:23842,36249:23843,36250:23845,36251:23848,36252:23850,36253:23851,36254:23852,36255:23855,36256:23856,36257:23857,36258:23858,36259:23859,36260:23861,36261:23862,36262:23863,36263:23864,36264:23865,36265:23866,36266:23867,36267:23868,36268:23871,36269:23872,36270:23873,36271:23874,36272:23875,36273:23876,36274:23877,36275:23878,36276:23880,36277:23881,36278:23885,36279:23886,36280:23887,36281:23888,36282:23889,36283:23890,36284:23891,36285:23892,36286:23893,36287:23894,36288:23895,36289:23897,36290:23898,36291:23900,36292:23902,36293:23903,36294:23904,36295:23905,36296:23906,36297:23907,36298:23908,36299:23909,36300:23910,36301:23911,36302:23912,36303:23914,36304:23917,36305:23918,36306:23920,36307:23921,36308:23922,36309:23923,36310:23925,36311:23926,36312:23927,36313:23928,36314:23929,36315:23930,36316:23931,36317:23932,36318:23933,36319:23934,36320:23935,36321:23936,36322:23937,36323:23939,36324:23940,36325:23941,36326:23942,36327:23943,36328:23944,36329:23945,36330:23946,36331:23947,36332:23948,36333:23949,36334:23950,36335:23951,36336:23952,36337:23953,36338:23954,36339:23955,36340:23956,36341:23957,36342:23958,36343:23959,36344:23960,36345:23962,36346:23963,36347:23964,36348:23966,36349:23967,36350:23968,36416:23969,36417:23970,36418:23971,36419:23972,36420:23973,36421:23974,36422:23975,36423:23976,36424:23977,36425:23978,36426:23979,36427:23980,36428:23981,36429:23982,36430:23983,36431:23984,36432:23985,36433:23986,36434:23987,36435:23988,36436:23989,36437:23990,36438:23992,36439:23993,36440:23994,36441:23995,36442:23996,36443:23997,36444:23998,36445:23999,36446:24000,36447:24001,36448:24002,36449:24003,36450:24004,36451:24006,36452:24007,36453:24008,36454:24009,36455:24010,36456:24011,36457:24012,36458:24014,36459:24015,36460:24016,36461:24017,36462:24018,36463:24019,36464:24020,36465:24021,36466:24022,36467:24023,36468:24024,36469:24025,36470:24026,36471:24028,36472:24031,36473:24032,36474:24035,36475:24036,36476:24042,36477:24044,36478:24045,36480:24048,36481:24053,36482:24054,36483:24056,36484:24057,36485:24058,36486:24059,36487:24060,36488:24063,36489:24064,36490:24068,36491:24071,36492:24073,36493:24074,36494:24075,36495:24077,36496:24078,36497:24082,36498:24083,36499:24087,36500:24094,36501:24095,36502:24096,36503:24097,36504:24098,36505:24099,36506:24100,36507:24101,36508:24104,36509:24105,36510:24106,36511:24107,36512:24108,36513:24111,36514:24112,36515:24114,36516:24115,36517:24116,36518:24117,36519:24118,36520:24121,36521:24122,36522:24126,36523:24127,36524:24128,36525:24129,36526:24131,36527:24134,36528:24135,36529:24136,36530:24137,36531:24138,36532:24139,36533:24141,36534:24142,36535:24143,36536:24144,36537:24145,36538:24146,36539:24147,36540:24150,36541:24151,36542:24152,36543:24153,36544:24154,36545:24156,36546:24157,36547:24159,36548:24160,36549:24163,36550:24164,36551:24165,36552:24166,36553:24167,36554:24168,36555:24169,36556:24170,36557:24171,36558:24172,36559:24173,36560:24174,36561:24175,36562:24176,36563:24177,36564:24181,36565:24183,36566:24185,36567:24190,36568:24193,36569:24194,36570:24195,36571:24197,36572:24200,36573:24201,36574:24204,36575:24205,36576:24206,36577:24210,36578:24216,36579:24219,36580:24221,36581:24225,36582:24226,36583:24227,36584:24228,36585:24232,36586:24233,36587:24234,36588:24235,36589:24236,36590:24238,36591:24239,36592:24240,36593:24241,36594:24242,36595:24244,36596:24250,36597:24251,36598:24252,36599:24253,36600:24255,36601:24256,36602:24257,36603:24258,36604:24259,36605:24260,36606:24261,36672:24262,36673:24263,36674:24264,36675:24267,36676:24268,36677:24269,36678:24270,36679:24271,36680:24272,36681:24276,36682:24277,36683:24279,36684:24280,36685:24281,36686:24282,36687:24284,36688:24285,36689:24286,36690:24287,36691:24288,36692:24289,36693:24290,36694:24291,36695:24292,36696:24293,36697:24294,36698:24295,36699:24297,36700:24299,36701:24300,36702:24301,36703:24302,36704:24303,36705:24304,36706:24305,36707:24306,36708:24307,36709:24309,36710:24312,36711:24313,36712:24315,36713:24316,36714:24317,36715:24325,36716:24326,36717:24327,36718:24329,36719:24332,36720:24333,36721:24334,36722:24336,36723:24338,36724:24340,36725:24342,36726:24345,36727:24346,36728:24348,36729:24349,36730:24350,36731:24353,36732:24354,36733:24355,36734:24356,36736:24360,36737:24363,36738:24364,36739:24366,36740:24368,36741:24370,36742:24371,36743:24372,36744:24373,36745:24374,36746:24375,36747:24376,36748:24379,36749:24381,36750:24382,36751:24383,36752:24385,36753:24386,36754:24387,36755:24388,36756:24389,36757:24390,36758:24391,36759:24392,36760:24393,36761:24394,36762:24395,36763:24396,36764:24397,36765:24398,36766:24399,36767:24401,36768:24404,36769:24409,36770:24410,36771:24411,36772:24412,36773:24414,36774:24415,36775:24416,36776:24419,36777:24421,36778:24423,36779:24424,36780:24427,36781:24430,36782:24431,36783:24434,36784:24436,36785:24437,36786:24438,36787:24440,36788:24442,36789:24445,36790:24446,36791:24447,36792:24451,36793:24454,36794:24461,36795:24462,36796:24463,36797:24465,36798:24467,36799:24468,36800:24470,36801:24474,36802:24475,36803:24477,36804:24478,36805:24479,36806:24480,36807:24482,36808:24483,36809:24484,36810:24485,36811:24486,36812:24487,36813:24489,36814:24491,36815:24492,36816:24495,36817:24496,36818:24497,36819:24498,36820:24499,36821:24500,36822:24502,36823:24504,36824:24505,36825:24506,36826:24507,36827:24510,36828:24511,36829:24512,36830:24513,36831:24514,36832:24519,36833:24520,36834:24522,36835:24523,36836:24526,36837:24531,36838:24532,36839:24533,36840:24538,36841:24539,36842:24540,36843:24542,36844:24543,36845:24546,36846:24547,36847:24549,36848:24550,36849:24552,36850:24553,36851:24556,36852:24559,36853:24560,36854:24562,36855:24563,36856:24564,36857:24566,36858:24567,36859:24569,36860:24570,36861:24572,36862:24583,36928:24584,36929:24585,36930:24587,36931:24588,36932:24592,36933:24593,36934:24595,36935:24599,36936:24600,36937:24602,36938:24606,36939:24607,36940:24610,36941:24611,36942:24612,36943:24620,36944:24621,36945:24622,36946:24624,36947:24625,36948:24626,36949:24627,36950:24628,36951:24630,36952:24631,36953:24632,36954:24633,36955:24634,36956:24637,36957:24638,36958:24640,36959:24644,36960:24645,36961:24646,36962:24647,36963:24648,36964:24649,36965:24650,36966:24652,36967:24654,36968:24655,36969:24657,36970:24659,36971:24660,36972:24662,36973:24663,36974:24664,36975:24667,36976:24668,36977:24670,36978:24671,36979:24672,36980:24673,36981:24677,36982:24678,36983:24686,36984:24689,36985:24690,36986:24692,36987:24693,36988:24695,36989:24702,36990:24704,36992:24705,36993:24706,36994:24709,36995:24710,36996:24711,36997:24712,36998:24714,36999:24715,37000:24718,37001:24719,37002:24720,37003:24721,37004:24723,37005:24725,37006:24727,37007:24728,37008:24729,37009:24732,37010:24734,37011:24737,37012:24738,37013:24740,37014:24741,37015:24743,37016:24745,37017:24746,37018:24750,37019:24752,37020:24755,37021:24757,37022:24758,37023:24759,37024:24761,37025:24762,37026:24765,37027:24766,37028:24767,37029:24768,37030:24769,37031:24770,37032:24771,37033:24772,37034:24775,37035:24776,37036:24777,37037:24780,37038:24781,37039:24782,37040:24783,37041:24784,37042:24786,37043:24787,37044:24788,37045:24790,37046:24791,37047:24793,37048:24795,37049:24798,37050:24801,37051:24802,37052:24803,37053:24804,37054:24805,37055:24810,37056:24817,37057:24818,37058:24821,37059:24823,37060:24824,37061:24827,37062:24828,37063:24829,37064:24830,37065:24831,37066:24834,37067:24835,37068:24836,37069:24837,37070:24839,37071:24842,37072:24843,37073:24844,37074:24848,37075:24849,37076:24850,37077:24851,37078:24852,37079:24854,37080:24855,37081:24856,37082:24857,37083:24859,37084:24860,37085:24861,37086:24862,37087:24865,37088:24866,37089:24869,37090:24872,37091:24873,37092:24874,37093:24876,37094:24877,37095:24878,37096:24879,37097:24880,37098:24881,37099:24882,37100:24883,37101:24884,37102:24885,37103:24886,37104:24887,37105:24888,37106:24889,37107:24890,37108:24891,37109:24892,37110:24893,37111:24894,37112:24896,37113:24897,37114:24898,37115:24899,37116:24900,37117:24901,37118:24902,37184:24903,37185:24905,37186:24907,37187:24909,37188:24911,37189:24912,37190:24914,37191:24915,37192:24916,37193:24918,37194:24919,37195:24920,37196:24921,37197:24922,37198:24923,37199:24924,37200:24926,37201:24927,37202:24928,37203:24929,37204:24931,37205:24932,37206:24933,37207:24934,37208:24937,37209:24938,37210:24939,37211:24940,37212:24941,37213:24942,37214:24943,37215:24945,37216:24946,37217:24947,37218:24948,37219:24950,37220:24952,37221:24953,37222:24954,37223:24955,37224:24956,37225:24957,37226:24958,37227:24959,37228:24960,37229:24961,37230:24962,37231:24963,37232:24964,37233:24965,37234:24966,37235:24967,37236:24968,37237:24969,37238:24970,37239:24972,37240:24973,37241:24975,37242:24976,37243:24977,37244:24978,37245:24979,37246:24981,37248:24982,37249:24983,37250:24984,37251:24985,37252:24986,37253:24987,37254:24988,37255:24990,37256:24991,37257:24992,37258:24993,37259:24994,37260:24995,37261:24996,37262:24997,37263:24998,37264:25002,37265:25003,37266:25005,37267:25006,37268:25007,37269:25008,37270:25009,37271:25010,37272:25011,37273:25012,37274:25013,37275:25014,37276:25016,37277:25017,37278:25018,37279:25019,37280:25020,37281:25021,37282:25023,37283:25024,37284:25025,37285:25027,37286:25028,37287:25029,37288:25030,37289:25031,37290:25033,37291:25036,37292:25037,37293:25038,37294:25039,37295:25040,37296:25043,37297:25045,37298:25046,37299:25047,37300:25048,37301:25049,37302:25050,37303:25051,37304:25052,37305:25053,37306:25054,37307:25055,37308:25056,37309:25057,37310:25058,37311:25059,37312:25060,37313:25061,37314:25063,37315:25064,37316:25065,37317:25066,37318:25067,37319:25068,37320:25069,37321:25070,37322:25071,37323:25072,37324:25073,37325:25074,37326:25075,37327:25076,37328:25078,37329:25079,37330:25080,37331:25081,37332:25082,37333:25083,37334:25084,37335:25085,37336:25086,37337:25088,37338:25089,37339:25090,37340:25091,37341:25092,37342:25093,37343:25095,37344:25097,37345:25107,37346:25108,37347:25113,37348:25116,37349:25117,37350:25118,37351:25120,37352:25123,37353:25126,37354:25127,37355:25128,37356:25129,37357:25131,37358:25133,37359:25135,37360:25136,37361:25137,37362:25138,37363:25141,37364:25142,37365:25144,37366:25145,37367:25146,37368:25147,37369:25148,37370:25154,37371:25156,37372:25157,37373:25158,37374:25162,37440:25167,37441:25168,37442:25173,37443:25174,37444:25175,37445:25177,37446:25178,37447:25180,37448:25181,37449:25182,37450:25183,37451:25184,37452:25185,37453:25186,37454:25188,37455:25189,37456:25192,37457:25201,37458:25202,37459:25204,37460:25205,37461:25207,37462:25208,37463:25210,37464:25211,37465:25213,37466:25217,37467:25218,37468:25219,37469:25221,37470:25222,37471:25223,37472:25224,37473:25227,37474:25228,37475:25229,37476:25230,37477:25231,37478:25232,37479:25236,37480:25241,37481:25244,37482:25245,37483:25246,37484:25251,37485:25254,37486:25255,37487:25257,37488:25258,37489:25261,37490:25262,37491:25263,37492:25264,37493:25266,37494:25267,37495:25268,37496:25270,37497:25271,37498:25272,37499:25274,37500:25278,37501:25280,37502:25281,37504:25283,37505:25291,37506:25295,37507:25297,37508:25301,37509:25309,37510:25310,37511:25312,37512:25313,37513:25316,37514:25322,37515:25323,37516:25328,37517:25330,37518:25333,37519:25336,37520:25337,37521:25338,37522:25339,37523:25344,37524:25347,37525:25348,37526:25349,37527:25350,37528:25354,37529:25355,37530:25356,37531:25357,37532:25359,37533:25360,37534:25362,37535:25363,37536:25364,37537:25365,37538:25367,37539:25368,37540:25369,37541:25372,37542:25382,37543:25383,37544:25385,37545:25388,37546:25389,37547:25390,37548:25392,37549:25393,37550:25395,37551:25396,37552:25397,37553:25398,37554:25399,37555:25400,37556:25403,37557:25404,37558:25406,37559:25407,37560:25408,37561:25409,37562:25412,37563:25415,37564:25416,37565:25418,37566:25425,37567:25426,37568:25427,37569:25428,37570:25430,37571:25431,37572:25432,37573:25433,37574:25434,37575:25435,37576:25436,37577:25437,37578:25440,37579:25444,37580:25445,37581:25446,37582:25448,37583:25450,37584:25451,37585:25452,37586:25455,37587:25456,37588:25458,37589:25459,37590:25460,37591:25461,37592:25464,37593:25465,37594:25468,37595:25469,37596:25470,37597:25471,37598:25473,37599:25475,37600:25476,37601:25477,37602:25478,37603:25483,37604:25485,37605:25489,37606:25491,37607:25492,37608:25493,37609:25495,37610:25497,37611:25498,37612:25499,37613:25500,37614:25501,37615:25502,37616:25503,37617:25505,37618:25508,37619:25510,37620:25515,37621:25519,37622:25521,37623:25522,37624:25525,37625:25526,37626:25529,37627:25531,37628:25533,37629:25535,37630:25536,37696:25537,37697:25538,37698:25539,37699:25541,37700:25543,37701:25544,37702:25546,37703:25547,37704:25548,37705:25553,37706:25555,37707:25556,37708:25557,37709:25559,37710:25560,37711:25561,37712:25562,37713:25563,37714:25564,37715:25565,37716:25567,37717:25570,37718:25572,37719:25573,37720:25574,37721:25575,37722:25576,37723:25579,37724:25580,37725:25582,37726:25583,37727:25584,37728:25585,37729:25587,37730:25589,37731:25591,37732:25593,37733:25594,37734:25595,37735:25596,37736:25598,37737:25603,37738:25604,37739:25606,37740:25607,37741:25608,37742:25609,37743:25610,37744:25613,37745:25614,37746:25617,37747:25618,37748:25621,37749:25622,37750:25623,37751:25624,37752:25625,37753:25626,37754:25629,37755:25631,37756:25634,37757:25635,37758:25636,37760:25637,37761:25639,37762:25640,37763:25641,37764:25643,37765:25646,37766:25647,37767:25648,37768:25649,37769:25650,37770:25651,37771:25653,37772:25654,37773:25655,37774:25656,37775:25657,37776:25659,37777:25660,37778:25662,37779:25664,37780:25666,37781:25667,37782:25673,37783:25675,37784:25676,37785:25677,37786:25678,37787:25679,37788:25680,37789:25681,37790:25683,37791:25685,37792:25686,37793:25687,37794:25689,37795:25690,37796:25691,37797:25692,37798:25693,37799:25695,37800:25696,37801:25697,37802:25698,37803:25699,37804:25700,37805:25701,37806:25702,37807:25704,37808:25706,37809:25707,37810:25708,37811:25710,37812:25711,37813:25712,37814:25713,37815:25714,37816:25715,37817:25716,37818:25717,37819:25718,37820:25719,37821:25723,37822:25724,37823:25725,37824:25726,37825:25727,37826:25728,37827:25729,37828:25731,37829:25734,37830:25736,37831:25737,37832:25738,37833:25739,37834:25740,37835:25741,37836:25742,37837:25743,37838:25744,37839:25747,37840:25748,37841:25751,37842:25752,37843:25754,37844:25755,37845:25756,37846:25757,37847:25759,37848:25760,37849:25761,37850:25762,37851:25763,37852:25765,37853:25766,37854:25767,37855:25768,37856:25770,37857:25771,37858:25775,37859:25777,37860:25778,37861:25779,37862:25780,37863:25782,37864:25785,37865:25787,37866:25789,37867:25790,37868:25791,37869:25793,37870:25795,37871:25796,37872:25798,37873:25799,37874:25800,37875:25801,37876:25802,37877:25803,37878:25804,37879:25807,37880:25809,37881:25811,37882:25812,37883:25813,37884:25814,37885:25817,37886:25818,37952:25819,37953:25820,37954:25821,37955:25823,37956:25824,37957:25825,37958:25827,37959:25829,37960:25831,37961:25832,37962:25833,37963:25834,37964:25835,37965:25836,37966:25837,37967:25838,37968:25839,37969:25840,37970:25841,37971:25842,37972:25843,37973:25844,37974:25845,37975:25846,37976:25847,37977:25848,37978:25849,37979:25850,37980:25851,37981:25852,37982:25853,37983:25854,37984:25855,37985:25857,37986:25858,37987:25859,37988:25860,37989:25861,37990:25862,37991:25863,37992:25864,37993:25866,37994:25867,37995:25868,37996:25869,37997:25870,37998:25871,37999:25872,38000:25873,38001:25875,38002:25876,38003:25877,38004:25878,38005:25879,38006:25881,38007:25882,38008:25883,38009:25884,38010:25885,38011:25886,38012:25887,38013:25888,38014:25889,38016:25890,38017:25891,38018:25892,38019:25894,38020:25895,38021:25896,38022:25897,38023:25898,38024:25900,38025:25901,38026:25904,38027:25905,38028:25906,38029:25907,38030:25911,38031:25914,38032:25916,38033:25917,38034:25920,38035:25921,38036:25922,38037:25923,38038:25924,38039:25926,38040:25927,38041:25930,38042:25931,38043:25933,38044:25934,38045:25936,38046:25938,38047:25939,38048:25940,38049:25943,38050:25944,38051:25946,38052:25948,38053:25951,38054:25952,38055:25953,38056:25956,38057:25957,38058:25959,38059:25960,38060:25961,38061:25962,38062:25965,38063:25966,38064:25967,38065:25969,38066:25971,38067:25973,38068:25974,38069:25976,38070:25977,38071:25978,38072:25979,38073:25980,38074:25981,38075:25982,38076:25983,38077:25984,38078:25985,38079:25986,38080:25987,38081:25988,38082:25989,38083:25990,38084:25992,38085:25993,38086:25994,38087:25997,38088:25998,38089:25999,38090:26002,38091:26004,38092:26005,38093:26006,38094:26008,38095:26010,38096:26013,38097:26014,38098:26016,38099:26018,38100:26019,38101:26022,38102:26024,38103:26026,38104:26028,38105:26030,38106:26033,38107:26034,38108:26035,38109:26036,38110:26037,38111:26038,38112:26039,38113:26040,38114:26042,38115:26043,38116:26046,38117:26047,38118:26048,38119:26050,38120:26055,38121:26056,38122:26057,38123:26058,38124:26061,38125:26064,38126:26065,38127:26067,38128:26068,38129:26069,38130:26072,38131:26073,38132:26074,38133:26075,38134:26076,38135:26077,38136:26078,38137:26079,38138:26081,38139:26083,38140:26084,38141:26090,38142:26091,38208:26098,38209:26099,38210:26100,38211:26101,38212:26104,38213:26105,38214:26107,38215:26108,38216:26109,38217:26110,38218:26111,38219:26113,38220:26116,38221:26117,38222:26119,38223:26120,38224:26121,38225:26123,38226:26125,38227:26128,38228:26129,38229:26130,38230:26134,38231:26135,38232:26136,38233:26138,38234:26139,38235:26140,38236:26142,38237:26145,38238:26146,38239:26147,38240:26148,38241:26150,38242:26153,38243:26154,38244:26155,38245:26156,38246:26158,38247:26160,38248:26162,38249:26163,38250:26167,38251:26168,38252:26169,38253:26170,38254:26171,38255:26173,38256:26175,38257:26176,38258:26178,38259:26180,38260:26181,38261:26182,38262:26183,38263:26184,38264:26185,38265:26186,38266:26189,38267:26190,38268:26192,38269:26193,38270:26200,38272:26201,38273:26203,38274:26204,38275:26205,38276:26206,38277:26208,38278:26210,38279:26211,38280:26213,38281:26215,38282:26217,38283:26218,38284:26219,38285:26220,38286:26221,38287:26225,38288:26226,38289:26227,38290:26229,38291:26232,38292:26233,38293:26235,38294:26236,38295:26237,38296:26239,38297:26240,38298:26241,38299:26243,38300:26245,38301:26246,38302:26248,38303:26249,38304:26250,38305:26251,38306:26253,38307:26254,38308:26255,38309:26256,38310:26258,38311:26259,38312:26260,38313:26261,38314:26264,38315:26265,38316:26266,38317:26267,38318:26268,38319:26270,38320:26271,38321:26272,38322:26273,38323:26274,38324:26275,38325:26276,38326:26277,38327:26278,38328:26281,38329:26282,38330:26283,38331:26284,38332:26285,38333:26287,38334:26288,38335:26289,38336:26290,38337:26291,38338:26293,38339:26294,38340:26295,38341:26296,38342:26298,38343:26299,38344:26300,38345:26301,38346:26303,38347:26304,38348:26305,38349:26306,38350:26307,38351:26308,38352:26309,38353:26310,38354:26311,38355:26312,38356:26313,38357:26314,38358:26315,38359:26316,38360:26317,38361:26318,38362:26319,38363:26320,38364:26321,38365:26322,38366:26323,38367:26324,38368:26325,38369:26326,38370:26327,38371:26328,38372:26330,38373:26334,38374:26335,38375:26336,38376:26337,38377:26338,38378:26339,38379:26340,38380:26341,38381:26343,38382:26344,38383:26346,38384:26347,38385:26348,38386:26349,38387:26350,38388:26351,38389:26353,38390:26357,38391:26358,38392:26360,38393:26362,38394:26363,38395:26365,38396:26369,38397:26370,38398:26371,38464:26372,38465:26373,38466:26374,38467:26375,38468:26380,38469:26382,38470:26383,38471:26385,38472:26386,38473:26387,38474:26390,38475:26392,38476:26393,38477:26394,38478:26396,38479:26398,38480:26400,38481:26401,38482:26402,38483:26403,38484:26404,38485:26405,38486:26407,38487:26409,38488:26414,38489:26416,38490:26418,38491:26419,38492:26422,38493:26423,38494:26424,38495:26425,38496:26427,38497:26428,38498:26430,38499:26431,38500:26433,38501:26436,38502:26437,38503:26439,38504:26442,38505:26443,38506:26445,38507:26450,38508:26452,38509:26453,38510:26455,38511:26456,38512:26457,38513:26458,38514:26459,38515:26461,38516:26466,38517:26467,38518:26468,38519:26470,38520:26471,38521:26475,38522:26476,38523:26478,38524:26481,38525:26484,38526:26486,38528:26488,38529:26489,38530:26490,38531:26491,38532:26493,38533:26496,38534:26498,38535:26499,38536:26501,38537:26502,38538:26504,38539:26506,38540:26508,38541:26509,38542:26510,38543:26511,38544:26513,38545:26514,38546:26515,38547:26516,38548:26518,38549:26521,38550:26523,38551:26527,38552:26528,38553:26529,38554:26532,38555:26534,38556:26537,38557:26540,38558:26542,38559:26545,38560:26546,38561:26548,38562:26553,38563:26554,38564:26555,38565:26556,38566:26557,38567:26558,38568:26559,38569:26560,38570:26562,38571:26565,38572:26566,38573:26567,38574:26568,38575:26569,38576:26570,38577:26571,38578:26572,38579:26573,38580:26574,38581:26581,38582:26582,38583:26583,38584:26587,38585:26591,38586:26593,38587:26595,38588:26596,38589:26598,38590:26599,38591:26600,38592:26602,38593:26603,38594:26605,38595:26606,38596:26610,38597:26613,38598:26614,38599:26615,38600:26616,38601:26617,38602:26618,38603:26619,38604:26620,38605:26622,38606:26625,38607:26626,38608:26627,38609:26628,38610:26630,38611:26637,38612:26640,38613:26642,38614:26644,38615:26645,38616:26648,38617:26649,38618:26650,38619:26651,38620:26652,38621:26654,38622:26655,38623:26656,38624:26658,38625:26659,38626:26660,38627:26661,38628:26662,38629:26663,38630:26664,38631:26667,38632:26668,38633:26669,38634:26670,38635:26671,38636:26672,38637:26673,38638:26676,38639:26677,38640:26678,38641:26682,38642:26683,38643:26687,38644:26695,38645:26699,38646:26701,38647:26703,38648:26706,38649:26710,38650:26711,38651:26712,38652:26713,38653:26714,38654:26715,38720:26716,38721:26717,38722:26718,38723:26719,38724:26730,38725:26732,38726:26733,38727:26734,38728:26735,38729:26736,38730:26737,38731:26738,38732:26739,38733:26741,38734:26744,38735:26745,38736:26746,38737:26747,38738:26748,38739:26749,38740:26750,38741:26751,38742:26752,38743:26754,38744:26756,38745:26759,38746:26760,38747:26761,38748:26762,38749:26763,38750:26764,38751:26765,38752:26766,38753:26768,38754:26769,38755:26770,38756:26772,38757:26773,38758:26774,38759:26776,38760:26777,38761:26778,38762:26779,38763:26780,38764:26781,38765:26782,38766:26783,38767:26784,38768:26785,38769:26787,38770:26788,38771:26789,38772:26793,38773:26794,38774:26795,38775:26796,38776:26798,38777:26801,38778:26802,38779:26804,38780:26806,38781:26807,38782:26808,38784:26809,38785:26810,38786:26811,38787:26812,38788:26813,38789:26814,38790:26815,38791:26817,38792:26819,38793:26820,38794:26821,38795:26822,38796:26823,38797:26824,38798:26826,38799:26828,38800:26830,38801:26831,38802:26832,38803:26833,38804:26835,38805:26836,38806:26838,38807:26839,38808:26841,38809:26843,38810:26844,38811:26845,38812:26846,38813:26847,38814:26849,38815:26850,38816:26852,38817:26853,38818:26854,38819:26855,38820:26856,38821:26857,38822:26858,38823:26859,38824:26860,38825:26861,38826:26863,38827:26866,38828:26867,38829:26868,38830:26870,38831:26871,38832:26872,38833:26875,38834:26877,38835:26878,38836:26879,38837:26880,38838:26882,38839:26883,38840:26884,38841:26886,38842:26887,38843:26888,38844:26889,38845:26890,38846:26892,38847:26895,38848:26897,38849:26899,38850:26900,38851:26901,38852:26902,38853:26903,38854:26904,38855:26905,38856:26906,38857:26907,38858:26908,38859:26909,38860:26910,38861:26913,38862:26914,38863:26915,38864:26917,38865:26918,38866:26919,38867:26920,38868:26921,38869:26922,38870:26923,38871:26924,38872:26926,38873:26927,38874:26929,38875:26930,38876:26931,38877:26933,38878:26934,38879:26935,38880:26936,38881:26938,38882:26939,38883:26940,38884:26942,38885:26944,38886:26945,38887:26947,38888:26948,38889:26949,38890:26950,38891:26951,38892:26952,38893:26953,38894:26954,38895:26955,38896:26956,38897:26957,38898:26958,38899:26959,38900:26960,38901:26961,38902:26962,38903:26963,38904:26965,38905:26966,38906:26968,38907:26969,38908:26971,38909:26972,38910:26975,38976:26977,38977:26978,38978:26980,38979:26981,38980:26983,38981:26984,38982:26985,38983:26986,38984:26988,38985:26989,38986:26991,38987:26992,38988:26994,38989:26995,38990:26996,38991:26997,38992:26998,38993:27002,38994:27003,38995:27005,38996:27006,38997:27007,38998:27009,38999:27011,39000:27013,39001:27018,39002:27019,39003:27020,39004:27022,39005:27023,39006:27024,39007:27025,39008:27026,39009:27027,39010:27030,39011:27031,39012:27033,39013:27034,39014:27037,39015:27038,39016:27039,39017:27040,39018:27041,39019:27042,39020:27043,39021:27044,39022:27045,39023:27046,39024:27049,39025:27050,39026:27052,39027:27054,39028:27055,39029:27056,39030:27058,39031:27059,39032:27061,39033:27062,39034:27064,39035:27065,39036:27066,39037:27068,39038:27069,39040:27070,39041:27071,39042:27072,39043:27074,39044:27075,39045:27076,39046:27077,39047:27078,39048:27079,39049:27080,39050:27081,39051:27083,39052:27085,39053:27087,39054:27089,39055:27090,39056:27091,39057:27093,39058:27094,39059:27095,39060:27096,39061:27097,39062:27098,39063:27100,39064:27101,39065:27102,39066:27105,39067:27106,39068:27107,39069:27108,39070:27109,39071:27110,39072:27111,39073:27112,39074:27113,39075:27114,39076:27115,39077:27116,39078:27118,39079:27119,39080:27120,39081:27121,39082:27123,39083:27124,39084:27125,39085:27126,39086:27127,39087:27128,39088:27129,39089:27130,39090:27131,39091:27132,39092:27134,39093:27136,39094:27137,39095:27138,39096:27139,39097:27140,39098:27141,39099:27142,39100:27143,39101:27144,39102:27145,39103:27147,39104:27148,39105:27149,39106:27150,39107:27151,39108:27152,39109:27153,39110:27154,39111:27155,39112:27156,39113:27157,39114:27158,39115:27161,39116:27162,39117:27163,39118:27164,39119:27165,39120:27166,39121:27168,39122:27170,39123:27171,39124:27172,39125:27173,39126:27174,39127:27175,39128:27177,39129:27179,39130:27180,39131:27181,39132:27182,39133:27184,39134:27186,39135:27187,39136:27188,39137:27190,39138:27191,39139:27192,39140:27193,39141:27194,39142:27195,39143:27196,39144:27199,39145:27200,39146:27201,39147:27202,39148:27203,39149:27205,39150:27206,39151:27208,39152:27209,39153:27210,39154:27211,39155:27212,39156:27213,39157:27214,39158:27215,39159:27217,39160:27218,39161:27219,39162:27220,39163:27221,39164:27222,39165:27223,39166:27226,39232:27228,39233:27229,39234:27230,39235:27231,39236:27232,39237:27234,39238:27235,39239:27236,39240:27238,39241:27239,39242:27240,39243:27241,39244:27242,39245:27243,39246:27244,39247:27245,39248:27246,39249:27247,39250:27248,39251:27250,39252:27251,39253:27252,39254:27253,39255:27254,39256:27255,39257:27256,39258:27258,39259:27259,39260:27261,39261:27262,39262:27263,39263:27265,39264:27266,39265:27267,39266:27269,39267:27270,39268:27271,39269:27272,39270:27273,39271:27274,39272:27275,39273:27276,39274:27277,39275:27279,39276:27282,39277:27283,39278:27284,39279:27285,39280:27286,39281:27288,39282:27289,39283:27290,39284:27291,39285:27292,39286:27293,39287:27294,39288:27295,39289:27297,39290:27298,39291:27299,39292:27300,39293:27301,39294:27302,39296:27303,39297:27304,39298:27306,39299:27309,39300:27310,39301:27311,39302:27312,39303:27313,39304:27314,39305:27315,39306:27316,39307:27317,39308:27318,39309:27319,39310:27320,39311:27321,39312:27322,39313:27323,39314:27324,39315:27325,39316:27326,39317:27327,39318:27328,39319:27329,39320:27330,39321:27331,39322:27332,39323:27333,39324:27334,39325:27335,39326:27336,39327:27337,39328:27338,39329:27339,39330:27340,39331:27341,39332:27342,39333:27343,39334:27344,39335:27345,39336:27346,39337:27347,39338:27348,39339:27349,39340:27350,39341:27351,39342:27352,39343:27353,39344:27354,39345:27355,39346:27356,39347:27357,39348:27358,39349:27359,39350:27360,39351:27361,39352:27362,39353:27363,39354:27364,39355:27365,39356:27366,39357:27367,39358:27368,39359:27369,39360:27370,39361:27371,39362:27372,39363:27373,39364:27374,39365:27375,39366:27376,39367:27377,39368:27378,39369:27379,39370:27380,39371:27381,39372:27382,39373:27383,39374:27384,39375:27385,39376:27386,39377:27387,39378:27388,39379:27389,39380:27390,39381:27391,39382:27392,39383:27393,39384:27394,39385:27395,39386:27396,39387:27397,39388:27398,39389:27399,39390:27400,39391:27401,39392:27402,39393:27403,39394:27404,39395:27405,39396:27406,39397:27407,39398:27408,39399:27409,39400:27410,39401:27411,39402:27412,39403:27413,39404:27414,39405:27415,39406:27416,39407:27417,39408:27418,39409:27419,39410:27420,39411:27421,39412:27422,39413:27423,39414:27429,39415:27430,39416:27432,39417:27433,39418:27434,39419:27435,39420:27436,39421:27437,39422:27438,39488:27439,39489:27440,39490:27441,39491:27443,39492:27444,39493:27445,39494:27446,39495:27448,39496:27451,39497:27452,39498:27453,39499:27455,39500:27456,39501:27457,39502:27458,39503:27460,39504:27461,39505:27464,39506:27466,39507:27467,39508:27469,39509:27470,39510:27471,39511:27472,39512:27473,39513:27474,39514:27475,39515:27476,39516:27477,39517:27478,39518:27479,39519:27480,39520:27482,39521:27483,39522:27484,39523:27485,39524:27486,39525:27487,39526:27488,39527:27489,39528:27496,39529:27497,39530:27499,39531:27500,39532:27501,39533:27502,39534:27503,39535:27504,39536:27505,39537:27506,39538:27507,39539:27508,39540:27509,39541:27510,39542:27511,39543:27512,39544:27514,39545:27517,39546:27518,39547:27519,39548:27520,39549:27525,39550:27528,39552:27532,39553:27534,39554:27535,39555:27536,39556:27537,39557:27540,39558:27541,39559:27543,39560:27544,39561:27545,39562:27548,39563:27549,39564:27550,39565:27551,39566:27552,39567:27554,39568:27555,39569:27556,39570:27557,39571:27558,39572:27559,39573:27560,39574:27561,39575:27563,39576:27564,39577:27565,39578:27566,39579:27567,39580:27568,39581:27569,39582:27570,39583:27574,39584:27576,39585:27577,39586:27578,39587:27579,39588:27580,39589:27581,39590:27582,39591:27584,39592:27587,39593:27588,39594:27590,39595:27591,39596:27592,39597:27593,39598:27594,39599:27596,39600:27598,39601:27600,39602:27601,39603:27608,39604:27610,39605:27612,39606:27613,39607:27614,39608:27615,39609:27616,39610:27618,39611:27619,39612:27620,39613:27621,39614:27622,39615:27623,39616:27624,39617:27625,39618:27628,39619:27629,39620:27630,39621:27632,39622:27633,39623:27634,39624:27636,39625:27638,39626:27639,39627:27640,39628:27642,39629:27643,39630:27644,39631:27646,39632:27647,39633:27648,39634:27649,39635:27650,39636:27651,39637:27652,39638:27656,39639:27657,39640:27658,39641:27659,39642:27660,39643:27662,39644:27666,39645:27671,39646:27676,39647:27677,39648:27678,39649:27680,39650:27683,39651:27685,39652:27691,39653:27692,39654:27693,39655:27697,39656:27699,39657:27702,39658:27703,39659:27705,39660:27706,39661:27707,39662:27708,39663:27710,39664:27711,39665:27715,39666:27716,39667:27717,39668:27720,39669:27723,39670:27724,39671:27725,39672:27726,39673:27727,39674:27729,39675:27730,39676:27731,39677:27734,39678:27736,39744:27737,39745:27738,39746:27746,39747:27747,39748:27749,39749:27750,39750:27751,39751:27755,39752:27756,39753:27757,39754:27758,39755:27759,39756:27761,39757:27763,39758:27765,39759:27767,39760:27768,39761:27770,39762:27771,39763:27772,39764:27775,39765:27776,39766:27780,39767:27783,39768:27786,39769:27787,39770:27789,39771:27790,39772:27793,39773:27794,39774:27797,39775:27798,39776:27799,39777:27800,39778:27802,39779:27804,39780:27805,39781:27806,39782:27808,39783:27810,39784:27816,39785:27820,39786:27823,39787:27824,39788:27828,39789:27829,39790:27830,39791:27831,39792:27834,39793:27840,39794:27841,39795:27842,39796:27843,39797:27846,39798:27847,39799:27848,39800:27851,39801:27853,39802:27854,39803:27855,39804:27857,39805:27858,39806:27864,39808:27865,39809:27866,39810:27868,39811:27869,39812:27871,39813:27876,39814:27878,39815:27879,39816:27881,39817:27884,39818:27885,39819:27890,39820:27892,39821:27897,39822:27903,39823:27904,39824:27906,39825:27907,39826:27909,39827:27910,39828:27912,39829:27913,39830:27914,39831:27917,39832:27919,39833:27920,39834:27921,39835:27923,39836:27924,39837:27925,39838:27926,39839:27928,39840:27932,39841:27933,39842:27935,39843:27936,39844:27937,39845:27938,39846:27939,39847:27940,39848:27942,39849:27944,39850:27945,39851:27948,39852:27949,39853:27951,39854:27952,39855:27956,39856:27958,39857:27959,39858:27960,39859:27962,39860:27967,39861:27968,39862:27970,39863:27972,39864:27977,39865:27980,39866:27984,39867:27989,39868:27990,39869:27991,39870:27992,39871:27995,39872:27997,39873:27999,39874:28001,39875:28002,39876:28004,39877:28005,39878:28007,39879:28008,39880:28011,39881:28012,39882:28013,39883:28016,39884:28017,39885:28018,39886:28019,39887:28021,39888:28022,39889:28025,39890:28026,39891:28027,39892:28029,39893:28030,39894:28031,39895:28032,39896:28033,39897:28035,39898:28036,39899:28038,39900:28039,39901:28042,39902:28043,39903:28045,39904:28047,39905:28048,39906:28050,39907:28054,39908:28055,39909:28056,39910:28057,39911:28058,39912:28060,39913:28066,39914:28069,39915:28076,39916:28077,39917:28080,39918:28081,39919:28083,39920:28084,39921:28086,39922:28087,39923:28089,39924:28090,39925:28091,39926:28092,39927:28093,39928:28094,39929:28097,39930:28098,39931:28099,39932:28104,39933:28105,39934:28106,40000:28109,40001:28110,40002:28111,40003:28112,40004:28114,40005:28115,40006:28116,40007:28117,40008:28119,40009:28122,40010:28123,40011:28124,40012:28127,40013:28130,40014:28131,40015:28133,40016:28135,40017:28136,40018:28137,40019:28138,40020:28141,40021:28143,40022:28144,40023:28146,40024:28148,40025:28149,40026:28150,40027:28152,40028:28154,40029:28157,40030:28158,40031:28159,40032:28160,40033:28161,40034:28162,40035:28163,40036:28164,40037:28166,40038:28167,40039:28168,40040:28169,40041:28171,40042:28175,40043:28178,40044:28179,40045:28181,40046:28184,40047:28185,40048:28187,40049:28188,40050:28190,40051:28191,40052:28194,40053:28198,40054:28199,40055:28200,40056:28202,40057:28204,40058:28206,40059:28208,40060:28209,40061:28211,40062:28213,40064:28214,40065:28215,40066:28217,40067:28219,40068:28220,40069:28221,40070:28222,40071:28223,40072:28224,40073:28225,40074:28226,40075:28229,40076:28230,40077:28231,40078:28232,40079:28233,40080:28234,40081:28235,40082:28236,40083:28239,40084:28240,40085:28241,40086:28242,40087:28245,40088:28247,40089:28249,40090:28250,40091:28252,40092:28253,40093:28254,40094:28256,40095:28257,40096:28258,40097:28259,40098:28260,40099:28261,40100:28262,40101:28263,40102:28264,40103:28265,40104:28266,40105:28268,40106:28269,40107:28271,40108:28272,40109:28273,40110:28274,40111:28275,40112:28276,40113:28277,40114:28278,40115:28279,40116:28280,40117:28281,40118:28282,40119:28283,40120:28284,40121:28285,40122:28288,40123:28289,40124:28290,40125:28292,40126:28295,40127:28296,40128:28298,40129:28299,40130:28300,40131:28301,40132:28302,40133:28305,40134:28306,40135:28307,40136:28308,40137:28309,40138:28310,40139:28311,40140:28313,40141:28314,40142:28315,40143:28317,40144:28318,40145:28320,40146:28321,40147:28323,40148:28324,40149:28326,40150:28328,40151:28329,40152:28331,40153:28332,40154:28333,40155:28334,40156:28336,40157:28339,40158:28341,40159:28344,40160:28345,40161:28348,40162:28350,40163:28351,40164:28352,40165:28355,40166:28356,40167:28357,40168:28358,40169:28360,40170:28361,40171:28362,40172:28364,40173:28365,40174:28366,40175:28368,40176:28370,40177:28374,40178:28376,40179:28377,40180:28379,40181:28380,40182:28381,40183:28387,40184:28391,40185:28394,40186:28395,40187:28396,40188:28397,40189:28398,40190:28399,40256:28400,40257:28401,40258:28402,40259:28403,40260:28405,40261:28406,40262:28407,40263:28408,40264:28410,40265:28411,40266:28412,40267:28413,40268:28414,40269:28415,40270:28416,40271:28417,40272:28419,40273:28420,40274:28421,40275:28423,40276:28424,40277:28426,40278:28427,40279:28428,40280:28429,40281:28430,40282:28432,40283:28433,40284:28434,40285:28438,40286:28439,40287:28440,40288:28441,40289:28442,40290:28443,40291:28444,40292:28445,40293:28446,40294:28447,40295:28449,40296:28450,40297:28451,40298:28453,40299:28454,40300:28455,40301:28456,40302:28460,40303:28462,40304:28464,40305:28466,40306:28468,40307:28469,40308:28471,40309:28472,40310:28473,40311:28474,40312:28475,40313:28476,40314:28477,40315:28479,40316:28480,40317:28481,40318:28482,40320:28483,40321:28484,40322:28485,40323:28488,40324:28489,40325:28490,40326:28492,40327:28494,40328:28495,40329:28496,40330:28497,40331:28498,40332:28499,40333:28500,40334:28501,40335:28502,40336:28503,40337:28505,40338:28506,40339:28507,40340:28509,40341:28511,40342:28512,40343:28513,40344:28515,40345:28516,40346:28517,40347:28519,40348:28520,40349:28521,40350:28522,40351:28523,40352:28524,40353:28527,40354:28528,40355:28529,40356:28531,40357:28533,40358:28534,40359:28535,40360:28537,40361:28539,40362:28541,40363:28542,40364:28543,40365:28544,40366:28545,40367:28546,40368:28547,40369:28549,40370:28550,40371:28551,40372:28554,40373:28555,40374:28559,40375:28560,40376:28561,40377:28562,40378:28563,40379:28564,40380:28565,40381:28566,40382:28567,40383:28568,40384:28569,40385:28570,40386:28571,40387:28573,40388:28574,40389:28575,40390:28576,40391:28578,40392:28579,40393:28580,40394:28581,40395:28582,40396:28584,40397:28585,40398:28586,40399:28587,40400:28588,40401:28589,40402:28590,40403:28591,40404:28592,40405:28593,40406:28594,40407:28596,40408:28597,40409:28599,40410:28600,40411:28602,40412:28603,40413:28604,40414:28605,40415:28606,40416:28607,40417:28609,40418:28611,40419:28612,40420:28613,40421:28614,40422:28615,40423:28616,40424:28618,40425:28619,40426:28620,40427:28621,40428:28622,40429:28623,40430:28624,40431:28627,40432:28628,40433:28629,40434:28630,40435:28631,40436:28632,40437:28633,40438:28634,40439:28635,40440:28636,40441:28637,40442:28639,40443:28642,40444:28643,40445:28644,40446:28645,40512:28646,40513:28647,40514:28648,40515:28649,40516:28650,40517:28651,40518:28652,40519:28653,40520:28656,40521:28657,40522:28658,40523:28659,40524:28660,40525:28661,40526:28662,40527:28663,40528:28664,40529:28665,40530:28666,40531:28667,40532:28668,40533:28669,40534:28670,40535:28671,40536:28672,40537:28673,40538:28674,40539:28675,40540:28676,40541:28677,40542:28678,40543:28679,40544:28680,40545:28681,40546:28682,40547:28683,40548:28684,40549:28685,40550:28686,40551:28687,40552:28688,40553:28690,40554:28691,40555:28692,40556:28693,40557:28694,40558:28695,40559:28696,40560:28697,40561:28700,40562:28701,40563:28702,40564:28703,40565:28704,40566:28705,40567:28706,40568:28708,40569:28709,40570:28710,40571:28711,40572:28712,40573:28713,40574:28714,40576:28715,40577:28716,40578:28717,40579:28718,40580:28719,40581:28720,40582:28721,40583:28722,40584:28723,40585:28724,40586:28726,40587:28727,40588:28728,40589:28730,40590:28731,40591:28732,40592:28733,40593:28734,40594:28735,40595:28736,40596:28737,40597:28738,40598:28739,40599:28740,40600:28741,40601:28742,40602:28743,40603:28744,40604:28745,40605:28746,40606:28747,40607:28749,40608:28750,40609:28752,40610:28753,40611:28754,40612:28755,40613:28756,40614:28757,40615:28758,40616:28759,40617:28760,40618:28761,40619:28762,40620:28763,40621:28764,40622:28765,40623:28767,40624:28768,40625:28769,40626:28770,40627:28771,40628:28772,40629:28773,40630:28774,40631:28775,40632:28776,40633:28777,40634:28778,40635:28782,40636:28785,40637:28786,40638:28787,40639:28788,40640:28791,40641:28793,40642:28794,40643:28795,40644:28797,40645:28801,40646:28802,40647:28803,40648:28804,40649:28806,40650:28807,40651:28808,40652:28811,40653:28812,40654:28813,40655:28815,40656:28816,40657:28817,40658:28819,40659:28823,40660:28824,40661:28826,40662:28827,40663:28830,40664:28831,40665:28832,40666:28833,40667:28834,40668:28835,40669:28836,40670:28837,40671:28838,40672:28839,40673:28840,40674:28841,40675:28842,40676:28848,40677:28850,40678:28852,40679:28853,40680:28854,40681:28858,40682:28862,40683:28863,40684:28868,40685:28869,40686:28870,40687:28871,40688:28873,40689:28875,40690:28876,40691:28877,40692:28878,40693:28879,40694:28880,40695:28881,40696:28882,40697:28883,40698:28884,40699:28885,40700:28886,40701:28887,40702:28890,40768:28892,40769:28893,40770:28894,40771:28896,40772:28897,40773:28898,40774:28899,40775:28901,40776:28906,40777:28910,40778:28912,40779:28913,40780:28914,40781:28915,40782:28916,40783:28917,40784:28918,40785:28920,40786:28922,40787:28923,40788:28924,40789:28926,40790:28927,40791:28928,40792:28929,40793:28930,40794:28931,40795:28932,40796:28933,40797:28934,40798:28935,40799:28936,40800:28939,40801:28940,40802:28941,40803:28942,40804:28943,40805:28945,40806:28946,40807:28948,40808:28951,40809:28955,40810:28956,40811:28957,40812:28958,40813:28959,40814:28960,40815:28961,40816:28962,40817:28963,40818:28964,40819:28965,40820:28967,40821:28968,40822:28969,40823:28970,40824:28971,40825:28972,40826:28973,40827:28974,40828:28978,40829:28979,40830:28980,40832:28981,40833:28983,40834:28984,40835:28985,40836:28986,40837:28987,40838:28988,40839:28989,40840:28990,40841:28991,40842:28992,40843:28993,40844:28994,40845:28995,40846:28996,40847:28998,40848:28999,40849:29000,40850:29001,40851:29003,40852:29005,40853:29007,40854:29008,40855:29009,40856:29010,40857:29011,40858:29012,40859:29013,40860:29014,40861:29015,40862:29016,40863:29017,40864:29018,40865:29019,40866:29021,40867:29023,40868:29024,40869:29025,40870:29026,40871:29027,40872:29029,40873:29033,40874:29034,40875:29035,40876:29036,40877:29037,40878:29039,40879:29040,40880:29041,40881:29044,40882:29045,40883:29046,40884:29047,40885:29049,40886:29051,40887:29052,40888:29054,40889:29055,40890:29056,40891:29057,40892:29058,40893:29059,40894:29061,40895:29062,40896:29063,40897:29064,40898:29065,40899:29067,40900:29068,40901:29069,40902:29070,40903:29072,40904:29073,40905:29074,40906:29075,40907:29077,40908:29078,40909:29079,40910:29082,40911:29083,40912:29084,40913:29085,40914:29086,40915:29089,40916:29090,40917:29091,40918:29092,40919:29093,40920:29094,40921:29095,40922:29097,40923:29098,40924:29099,40925:29101,40926:29102,40927:29103,40928:29104,40929:29105,40930:29106,40931:29108,40932:29110,40933:29111,40934:29112,40935:29114,40936:29115,40937:29116,40938:29117,40939:29118,40940:29119,40941:29120,40942:29121,40943:29122,40944:29124,40945:29125,40946:29126,40947:29127,40948:29128,40949:29129,40950:29130,40951:29131,40952:29132,40953:29133,40954:29135,40955:29136,40956:29137,40957:29138,40958:29139,41024:29142,41025:29143,41026:29144,41027:29145,41028:29146,41029:29147,41030:29148,41031:29149,41032:29150,41033:29151,41034:29153,41035:29154,41036:29155,41037:29156,41038:29158,41039:29160,41040:29161,41041:29162,41042:29163,41043:29164,41044:29165,41045:29167,41046:29168,41047:29169,41048:29170,41049:29171,41050:29172,41051:29173,41052:29174,41053:29175,41054:29176,41055:29178,41056:29179,41057:29180,41058:29181,41059:29182,41060:29183,41061:29184,41062:29185,41063:29186,41064:29187,41065:29188,41066:29189,41067:29191,41068:29192,41069:29193,41070:29194,41071:29195,41072:29196,41073:29197,41074:29198,41075:29199,41076:29200,41077:29201,41078:29202,41079:29203,41080:29204,41081:29205,41082:29206,41083:29207,41084:29208,41085:29209,41086:29210,41088:29211,41089:29212,41090:29214,41091:29215,41092:29216,41093:29217,41094:29218,41095:29219,41096:29220,41097:29221,41098:29222,41099:29223,41100:29225,41101:29227,41102:29229,41103:29230,41104:29231,41105:29234,41106:29235,41107:29236,41108:29242,41109:29244,41110:29246,41111:29248,41112:29249,41113:29250,41114:29251,41115:29252,41116:29253,41117:29254,41118:29257,41119:29258,41120:29259,41121:29262,41122:29263,41123:29264,41124:29265,41125:29267,41126:29268,41127:29269,41128:29271,41129:29272,41130:29274,41131:29276,41132:29278,41133:29280,41134:29283,41135:29284,41136:29285,41137:29288,41138:29290,41139:29291,41140:29292,41141:29293,41142:29296,41143:29297,41144:29299,41145:29300,41146:29302,41147:29303,41148:29304,41149:29307,41150:29308,41151:29309,41152:29314,41153:29315,41154:29317,41155:29318,41156:29319,41157:29320,41158:29321,41159:29324,41160:29326,41161:29328,41162:29329,41163:29331,41164:29332,41165:29333,41166:29334,41167:29335,41168:29336,41169:29337,41170:29338,41171:29339,41172:29340,41173:29341,41174:29342,41175:29344,41176:29345,41177:29346,41178:29347,41179:29348,41180:29349,41181:29350,41182:29351,41183:29352,41184:29353,41185:29354,41186:29355,41187:29358,41188:29361,41189:29362,41190:29363,41191:29365,41192:29370,41193:29371,41194:29372,41195:29373,41196:29374,41197:29375,41198:29376,41199:29381,41200:29382,41201:29383,41202:29385,41203:29386,41204:29387,41205:29388,41206:29391,41207:29393,41208:29395,41209:29396,41210:29397,41211:29398,41212:29400,41213:29402,41214:29403,41280:58566,41281:58567,41282:58568,41283:58569,41284:58570,41285:58571,41286:58572,41287:58573,41288:58574,41289:58575,41290:58576,41291:58577,41292:58578,41293:58579,41294:58580,41295:58581,41296:58582,41297:58583,41298:58584,41299:58585,41300:58586,41301:58587,41302:58588,41303:58589,41304:58590,41305:58591,41306:58592,41307:58593,41308:58594,41309:58595,41310:58596,41311:58597,41312:58598,41313:58599,41314:58600,41315:58601,41316:58602,41317:58603,41318:58604,41319:58605,41320:58606,41321:58607,41322:58608,41323:58609,41324:58610,41325:58611,41326:58612,41327:58613,41328:58614,41329:58615,41330:58616,41331:58617,41332:58618,41333:58619,41334:58620,41335:58621,41336:58622,41337:58623,41338:58624,41339:58625,41340:58626,41341:58627,41342:58628,41344:58629,41345:58630,41346:58631,41347:58632,41348:58633,41349:58634,41350:58635,41351:58636,41352:58637,41353:58638,41354:58639,41355:58640,41356:58641,41357:58642,41358:58643,41359:58644,41360:58645,41361:58646,41362:58647,41363:58648,41364:58649,41365:58650,41366:58651,41367:58652,41368:58653,41369:58654,41370:58655,41371:58656,41372:58657,41373:58658,41374:58659,41375:58660,41376:58661,41377:12288,41378:12289,41379:12290,41380:183,41381:713,41382:711,41383:168,41384:12291,41385:12293,41386:8212,41387:65374,41388:8214,41389:8230,41390:8216,41391:8217,41392:8220,41393:8221,41394:12308,41395:12309,41396:12296,41397:12297,41398:12298,41399:12299,41400:12300,41401:12301,41402:12302,41403:12303,41404:12310,41405:12311,41406:12304,41407:12305,41408:177,41409:215,41410:247,41411:8758,41412:8743,41413:8744,41414:8721,41415:8719,41416:8746,41417:8745,41418:8712,41419:8759,41420:8730,41421:8869,41422:8741,41423:8736,41424:8978,41425:8857,41426:8747,41427:8750,41428:8801,41429:8780,41430:8776,41431:8765,41432:8733,41433:8800,41434:8814,41435:8815,41436:8804,41437:8805,41438:8734,41439:8757,41440:8756,41441:9794,41442:9792,41443:176,41444:8242,41445:8243,41446:8451,41447:65284,41448:164,41449:65504,41450:65505,41451:8240,41452:167,41453:8470,41454:9734,41455:9733,41456:9675,41457:9679,41458:9678,41459:9671,41460:9670,41461:9633,41462:9632,41463:9651,41464:9650,41465:8251,41466:8594,41467:8592,41468:8593,41469:8595,41470:12307,41536:58662,41537:58663,41538:58664,41539:58665,41540:58666,41541:58667,41542:58668,41543:58669,41544:58670,41545:58671,41546:58672,41547:58673,41548:58674,41549:58675,41550:58676,41551:58677,41552:58678,41553:58679,41554:58680,41555:58681,41556:58682,41557:58683,41558:58684,41559:58685,41560:58686,41561:58687,41562:58688,41563:58689,41564:58690,41565:58691,41566:58692,41567:58693,41568:58694,41569:58695,41570:58696,41571:58697,41572:58698,41573:58699,41574:58700,41575:58701,41576:58702,41577:58703,41578:58704,41579:58705,41580:58706,41581:58707,41582:58708,41583:58709,41584:58710,41585:58711,41586:58712,41587:58713,41588:58714,41589:58715,41590:58716,41591:58717,41592:58718,41593:58719,41594:58720,41595:58721,41596:58722,41597:58723,41598:58724,41600:58725,41601:58726,41602:58727,41603:58728,41604:58729,41605:58730,41606:58731,41607:58732,41608:58733,41609:58734,41610:58735,41611:58736,41612:58737,41613:58738,41614:58739,41615:58740,41616:58741,41617:58742,41618:58743,41619:58744,41620:58745,41621:58746,41622:58747,41623:58748,41624:58749,41625:58750,41626:58751,41627:58752,41628:58753,41629:58754,41630:58755,41631:58756,41632:58757,41633:8560,41634:8561,41635:8562,41636:8563,41637:8564,41638:8565,41639:8566,41640:8567,41641:8568,41642:8569,41643:59238,41644:59239,41645:59240,41646:59241,41647:59242,41648:59243,41649:9352,41650:9353,41651:9354,41652:9355,41653:9356,41654:9357,41655:9358,41656:9359,41657:9360,41658:9361,41659:9362,41660:9363,41661:9364,41662:9365,41663:9366,41664:9367,41665:9368,41666:9369,41667:9370,41668:9371,41669:9332,41670:9333,41671:9334,41672:9335,41673:9336,41674:9337,41675:9338,41676:9339,41677:9340,41678:9341,41679:9342,41680:9343,41681:9344,41682:9345,41683:9346,41684:9347,41685:9348,41686:9349,41687:9350,41688:9351,41689:9312,41690:9313,41691:9314,41692:9315,41693:9316,41694:9317,41695:9318,41696:9319,41697:9320,41698:9321,41699:8364,41700:59245,41701:12832,41702:12833,41703:12834,41704:12835,41705:12836,41706:12837,41707:12838,41708:12839,41709:12840,41710:12841,41711:59246,41712:59247,41713:8544,41714:8545,41715:8546,41716:8547,41717:8548,41718:8549,41719:8550,41720:8551,41721:8552,41722:8553,41723:8554,41724:8555,41725:59248,41726:59249,41792:58758,41793:58759,41794:58760,41795:58761,41796:58762,41797:58763,41798:58764,41799:58765,41800:58766,41801:58767,41802:58768,41803:58769,41804:58770,41805:58771,41806:58772,41807:58773,41808:58774,41809:58775,41810:58776,41811:58777,41812:58778,41813:58779,41814:58780,41815:58781,41816:58782,41817:58783,41818:58784,41819:58785,41820:58786,41821:58787,41822:58788,41823:58789,41824:58790,41825:58791,41826:58792,41827:58793,41828:58794,41829:58795,41830:58796,41831:58797,41832:58798,41833:58799,41834:58800,41835:58801,41836:58802,41837:58803,41838:58804,41839:58805,41840:58806,41841:58807,41842:58808,41843:58809,41844:58810,41845:58811,41846:58812,41847:58813,41848:58814,41849:58815,41850:58816,41851:58817,41852:58818,41853:58819,41854:58820,41856:58821,41857:58822,41858:58823,41859:58824,41860:58825,41861:58826,41862:58827,41863:58828,41864:58829,41865:58830,41866:58831,41867:58832,41868:58833,41869:58834,41870:58835,41871:58836,41872:58837,41873:58838,41874:58839,41875:58840,41876:58841,41877:58842,41878:58843,41879:58844,41880:58845,41881:58846,41882:58847,41883:58848,41884:58849,41885:58850,41886:58851,41887:58852,41888:58853,41889:65281,41890:65282,41891:65283,41892:65509,41893:65285,41894:65286,41895:65287,41896:65288,41897:65289,41898:65290,41899:65291,41900:65292,41901:65293,41902:65294,41903:65295,41904:65296,41905:65297,41906:65298,41907:65299,41908:65300,41909:65301,41910:65302,41911:65303,41912:65304,41913:65305,41914:65306,41915:65307,41916:65308,41917:65309,41918:65310,41919:65311,41920:65312,41921:65313,41922:65314,41923:65315,41924:65316,41925:65317,41926:65318,41927:65319,41928:65320,41929:65321,41930:65322,41931:65323,41932:65324,41933:65325,41934:65326,41935:65327,41936:65328,41937:65329,41938:65330,41939:65331,41940:65332,41941:65333,41942:65334,41943:65335,41944:65336,41945:65337,41946:65338,41947:65339,41948:65340,41949:65341,41950:65342,41951:65343,41952:65344,41953:65345,41954:65346,41955:65347,41956:65348,41957:65349,41958:65350,41959:65351,41960:65352,41961:65353,41962:65354,41963:65355,41964:65356,41965:65357,41966:65358,41967:65359,41968:65360,41969:65361,41970:65362,41971:65363,41972:65364,41973:65365,41974:65366,41975:65367,41976:65368,41977:65369,41978:65370,41979:65371,41980:65372,41981:65373,41982:65507,42048:58854,42049:58855,42050:58856,42051:58857,42052:58858,42053:58859,42054:58860,42055:58861,42056:58862,42057:58863,42058:58864,42059:58865,42060:58866,42061:58867,42062:58868,42063:58869,42064:58870,42065:58871,42066:58872,42067:58873,42068:58874,42069:58875,42070:58876,42071:58877,42072:58878,42073:58879,42074:58880,42075:58881,42076:58882,42077:58883,42078:58884,42079:58885,42080:58886,42081:58887,42082:58888,42083:58889,42084:58890,42085:58891,42086:58892,42087:58893,42088:58894,42089:58895,42090:58896,42091:58897,42092:58898,42093:58899,42094:58900,42095:58901,42096:58902,42097:58903,42098:58904,42099:58905,42100:58906,42101:58907,42102:58908,42103:58909,42104:58910,42105:58911,42106:58912,42107:58913,42108:58914,42109:58915,42110:58916,42112:58917,42113:58918,42114:58919,42115:58920,42116:58921,42117:58922,42118:58923,42119:58924,42120:58925,42121:58926,42122:58927,42123:58928,42124:58929,42125:58930,42126:58931,42127:58932,42128:58933,42129:58934,42130:58935,42131:58936,42132:58937,42133:58938,42134:58939,42135:58940,42136:58941,42137:58942,42138:58943,42139:58944,42140:58945,42141:58946,42142:58947,42143:58948,42144:58949,42145:12353,42146:12354,42147:12355,42148:12356,42149:12357,42150:12358,42151:12359,42152:12360,42153:12361,42154:12362,42155:12363,42156:12364,42157:12365,42158:12366,42159:12367,42160:12368,42161:12369,42162:12370,42163:12371,42164:12372,42165:12373,42166:12374,42167:12375,42168:12376,42169:12377,42170:12378,42171:12379,42172:12380,42173:12381,42174:12382,42175:12383,42176:12384,42177:12385,42178:12386,42179:12387,42180:12388,42181:12389,42182:12390,42183:12391,42184:12392,42185:12393,42186:12394,42187:12395,42188:12396,42189:12397,42190:12398,42191:12399,42192:12400,42193:12401,42194:12402,42195:12403,42196:12404,42197:12405,42198:12406,42199:12407,42200:12408,42201:12409,42202:12410,42203:12411,42204:12412,42205:12413,42206:12414,42207:12415,42208:12416,42209:12417,42210:12418,42211:12419,42212:12420,42213:12421,42214:12422,42215:12423,42216:12424,42217:12425,42218:12426,42219:12427,42220:12428,42221:12429,42222:12430,42223:12431,42224:12432,42225:12433,42226:12434,42227:12435,42228:59250,42229:59251,42230:59252,42231:59253,42232:59254,42233:59255,42234:59256,42235:59257,42236:59258,42237:59259,42238:59260,42304:58950,42305:58951,42306:58952,42307:58953,42308:58954,42309:58955,42310:58956,42311:58957,42312:58958,42313:58959,42314:58960,42315:58961,42316:58962,42317:58963,42318:58964,42319:58965,42320:58966,42321:58967,42322:58968,42323:58969,42324:58970,42325:58971,42326:58972,42327:58973,42328:58974,42329:58975,42330:58976,42331:58977,42332:58978,42333:58979,42334:58980,42335:58981,42336:58982,42337:58983,42338:58984,42339:58985,42340:58986,42341:58987,42342:58988,42343:58989,42344:58990,42345:58991,42346:58992,42347:58993,42348:58994,42349:58995,42350:58996,42351:58997,42352:58998,42353:58999,42354:59000,42355:59001,42356:59002,42357:59003,42358:59004,42359:59005,42360:59006,42361:59007,42362:59008,42363:59009,42364:59010,42365:59011,42366:59012,42368:59013,42369:59014,42370:59015,42371:59016,42372:59017,42373:59018,42374:59019,42375:59020,42376:59021,42377:59022,42378:59023,42379:59024,42380:59025,42381:59026,42382:59027,42383:59028,42384:59029,42385:59030,42386:59031,42387:59032,42388:59033,42389:59034,42390:59035,42391:59036,42392:59037,42393:59038,42394:59039,42395:59040,42396:59041,42397:59042,42398:59043,42399:59044,42400:59045,42401:12449,42402:12450,42403:12451,42404:12452,42405:12453,42406:12454,42407:12455,42408:12456,42409:12457,42410:12458,42411:12459,42412:12460,42413:12461,42414:12462,42415:12463,42416:12464,42417:12465,42418:12466,42419:12467,42420:12468,42421:12469,42422:12470,42423:12471,42424:12472,42425:12473,42426:12474,42427:12475,42428:12476,42429:12477,42430:12478,42431:12479,42432:12480,42433:12481,42434:12482,42435:12483,42436:12484,42437:12485,42438:12486,42439:12487,42440:12488,42441:12489,42442:12490,42443:12491,42444:12492,42445:12493,42446:12494,42447:12495,42448:12496,42449:12497,42450:12498,42451:12499,42452:12500,42453:12501,42454:12502,42455:12503,42456:12504,42457:12505,42458:12506,42459:12507,42460:12508,42461:12509,42462:12510,42463:12511,42464:12512,42465:12513,42466:12514,42467:12515,42468:12516,42469:12517,42470:12518,42471:12519,42472:12520,42473:12521,42474:12522,42475:12523,42476:12524,42477:12525,42478:12526,42479:12527,42480:12528,42481:12529,42482:12530,42483:12531,42484:12532,42485:12533,42486:12534,42487:59261,42488:59262,42489:59263,42490:59264,42491:59265,42492:59266,42493:59267,42494:59268,42560:59046,42561:59047,42562:59048,42563:59049,42564:59050,42565:59051,42566:59052,42567:59053,42568:59054,42569:59055,42570:59056,42571:59057,42572:59058,42573:59059,42574:59060,42575:59061,42576:59062,42577:59063,42578:59064,42579:59065,42580:59066,42581:59067,42582:59068,42583:59069,42584:59070,42585:59071,42586:59072,42587:59073,42588:59074,42589:59075,42590:59076,42591:59077,42592:59078,42593:59079,42594:59080,42595:59081,42596:59082,42597:59083,42598:59084,42599:59085,42600:59086,42601:59087,42602:59088,42603:59089,42604:59090,42605:59091,42606:59092,42607:59093,42608:59094,42609:59095,42610:59096,42611:59097,42612:59098,42613:59099,42614:59100,42615:59101,42616:59102,42617:59103,42618:59104,42619:59105,42620:59106,42621:59107,42622:59108,42624:59109,42625:59110,42626:59111,42627:59112,42628:59113,42629:59114,42630:59115,42631:59116,42632:59117,42633:59118,42634:59119,42635:59120,42636:59121,42637:59122,42638:59123,42639:59124,42640:59125,42641:59126,42642:59127,42643:59128,42644:59129,42645:59130,42646:59131,42647:59132,42648:59133,42649:59134,42650:59135,42651:59136,42652:59137,42653:59138,42654:59139,42655:59140,42656:59141,42657:913,42658:914,42659:915,42660:916,42661:917,42662:918,42663:919,42664:920,42665:921,42666:922,42667:923,42668:924,42669:925,42670:926,42671:927,42672:928,42673:929,42674:931,42675:932,42676:933,42677:934,42678:935,42679:936,42680:937,42681:59269,42682:59270,42683:59271,42684:59272,42685:59273,42686:59274,42687:59275,42688:59276,42689:945,42690:946,42691:947,42692:948,42693:949,42694:950,42695:951,42696:952,42697:953,42698:954,42699:955,42700:956,42701:957,42702:958,42703:959,42704:960,42705:961,42706:963,42707:964,42708:965,42709:966,42710:967,42711:968,42712:969,42713:59277,42714:59278,42715:59279,42716:59280,42717:59281,42718:59282,42719:59283,42720:65077,42721:65078,42722:65081,42723:65082,42724:65087,42725:65088,42726:65085,42727:65086,42728:65089,42729:65090,42730:65091,42731:65092,42732:59284,42733:59285,42734:65083,42735:65084,42736:65079,42737:65080,42738:65073,42739:59286,42740:65075,42741:65076,42742:59287,42743:59288,42744:59289,42745:59290,42746:59291,42747:59292,42748:59293,42749:59294,42750:59295,42816:59142,42817:59143,42818:59144,42819:59145,42820:59146,42821:59147,42822:59148,42823:59149,42824:59150,42825:59151,42826:59152,42827:59153,42828:59154,42829:59155,42830:59156,42831:59157,42832:59158,42833:59159,42834:59160,42835:59161,42836:59162,42837:59163,42838:59164,42839:59165,42840:59166,42841:59167,42842:59168,42843:59169,42844:59170,42845:59171,42846:59172,42847:59173,42848:59174,42849:59175,42850:59176,42851:59177,42852:59178,42853:59179,42854:59180,42855:59181,42856:59182,42857:59183,42858:59184,42859:59185,42860:59186,42861:59187,42862:59188,42863:59189,42864:59190,42865:59191,42866:59192,42867:59193,42868:59194,42869:59195,42870:59196,42871:59197,42872:59198,42873:59199,42874:59200,42875:59201,42876:59202,42877:59203,42878:59204,42880:59205,42881:59206,42882:59207,42883:59208,42884:59209,42885:59210,42886:59211,42887:59212,42888:59213,42889:59214,42890:59215,42891:59216,42892:59217,42893:59218,42894:59219,42895:59220,42896:59221,42897:59222,42898:59223,42899:59224,42900:59225,42901:59226,42902:59227,42903:59228,42904:59229,42905:59230,42906:59231,42907:59232,42908:59233,42909:59234,42910:59235,42911:59236,42912:59237,42913:1040,42914:1041,42915:1042,42916:1043,42917:1044,42918:1045,42919:1025,42920:1046,42921:1047,42922:1048,42923:1049,42924:1050,42925:1051,42926:1052,42927:1053,42928:1054,42929:1055,42930:1056,42931:1057,42932:1058,42933:1059,42934:1060,42935:1061,42936:1062,42937:1063,42938:1064,42939:1065,42940:1066,42941:1067,42942:1068,42943:1069,42944:1070,42945:1071,42946:59296,42947:59297,42948:59298,42949:59299,42950:59300,42951:59301,42952:59302,42953:59303,42954:59304,42955:59305,42956:59306,42957:59307,42958:59308,42959:59309,42960:59310,42961:1072,42962:1073,42963:1074,42964:1075,42965:1076,42966:1077,42967:1105,42968:1078,42969:1079,42970:1080,42971:1081,42972:1082,42973:1083,42974:1084,42975:1085,42976:1086,42977:1087,42978:1088,42979:1089,42980:1090,42981:1091,42982:1092,42983:1093,42984:1094,42985:1095,42986:1096,42987:1097,42988:1098,42989:1099,42990:1100,42991:1101,42992:1102,42993:1103,42994:59311,42995:59312,42996:59313,42997:59314,42998:59315,42999:59316,43000:59317,43001:59318,43002:59319,43003:59320,43004:59321,43005:59322,43006:59323,43072:714,43073:715,43074:729,43075:8211,43076:8213,43077:8229,43078:8245,43079:8453,43080:8457,43081:8598,43082:8599,43083:8600,43084:8601,43085:8725,43086:8735,43087:8739,43088:8786,43089:8806,43090:8807,43091:8895,43092:9552,43093:9553,43094:9554,43095:9555,43096:9556,43097:9557,43098:9558,43099:9559,43100:9560,43101:9561,43102:9562,43103:9563,43104:9564,43105:9565,43106:9566,43107:9567,43108:9568,43109:9569,43110:9570,43111:9571,43112:9572,43113:9573,43114:9574,43115:9575,43116:9576,43117:9577,43118:9578,43119:9579,43120:9580,43121:9581,43122:9582,43123:9583,43124:9584,43125:9585,43126:9586,43127:9587,43128:9601,43129:9602,43130:9603,43131:9604,43132:9605,43133:9606,43134:9607,43136:9608,43137:9609,43138:9610,43139:9611,43140:9612,43141:9613,43142:9614,43143:9615,43144:9619,43145:9620,43146:9621,43147:9660,43148:9661,43149:9698,43150:9699,43151:9700,43152:9701,43153:9737,43154:8853,43155:12306,43156:12317,43157:12318,43158:59324,43159:59325,43160:59326,43161:59327,43162:59328,43163:59329,43164:59330,43165:59331,43166:59332,43167:59333,43168:59334,43169:257,43170:225,43171:462,43172:224,43173:275,43174:233,43175:283,43176:232,43177:299,43178:237,43179:464,43180:236,43181:333,43182:243,43183:466,43184:242,43185:363,43186:250,43187:468,43188:249,43189:470,43190:472,43191:474,43192:476,43193:252,43194:234,43195:593,43196:59335,43197:324,43198:328,43199:505,43200:609,43201:59337,43202:59338,43203:59339,43204:59340,43205:12549,43206:12550,43207:12551,43208:12552,43209:12553,43210:12554,43211:12555,43212:12556,43213:12557,43214:12558,43215:12559,43216:12560,43217:12561,43218:12562,43219:12563,43220:12564,43221:12565,43222:12566,43223:12567,43224:12568,43225:12569,43226:12570,43227:12571,43228:12572,43229:12573,43230:12574,43231:12575,43232:12576,43233:12577,43234:12578,43235:12579,43236:12580,43237:12581,43238:12582,43239:12583,43240:12584,43241:12585,43242:59341,43243:59342,43244:59343,43245:59344,43246:59345,43247:59346,43248:59347,43249:59348,43250:59349,43251:59350,43252:59351,43253:59352,43254:59353,43255:59354,43256:59355,43257:59356,43258:59357,43259:59358,43260:59359,43261:59360,43262:59361,43328:12321,43329:12322,43330:12323,43331:12324,43332:12325,43333:12326,43334:12327,43335:12328,43336:12329,43337:12963,43338:13198,43339:13199,43340:13212,43341:13213,43342:13214,43343:13217,43344:13252,43345:13262,43346:13265,43347:13266,43348:13269,43349:65072,43350:65506,43351:65508,43352:59362,43353:8481,43354:12849,43355:59363,43356:8208,43357:59364,43358:59365,43359:59366,43360:12540,43361:12443,43362:12444,43363:12541,43364:12542,43365:12294,43366:12445,43367:12446,43368:65097,43369:65098,43370:65099,43371:65100,43372:65101,43373:65102,43374:65103,43375:65104,43376:65105,43377:65106,43378:65108,43379:65109,43380:65110,43381:65111,43382:65113,43383:65114,43384:65115,43385:65116,43386:65117,43387:65118,43388:65119,43389:65120,43390:65121,43392:65122,43393:65123,43394:65124,43395:65125,43396:65126,43397:65128,43398:65129,43399:65130,43400:65131,43401:12350,43402:12272,43403:12273,43404:12274,43405:12275,43406:12276,43407:12277,43408:12278,43409:12279,43410:12280,43411:12281,43412:12282,43413:12283,43414:12295,43415:59380,43416:59381,43417:59382,43418:59383,43419:59384,43420:59385,43421:59386,43422:59387,43423:59388,43424:59389,43425:59390,43426:59391,43427:59392,43428:9472,43429:9473,43430:9474,43431:9475,43432:9476,43433:9477,43434:9478,43435:9479,43436:9480,43437:9481,43438:9482,43439:9483,43440:9484,43441:9485,43442:9486,43443:9487,43444:9488,43445:9489,43446:9490,43447:9491,43448:9492,43449:9493,43450:9494,43451:9495,43452:9496,43453:9497,43454:9498,43455:9499,43456:9500,43457:9501,43458:9502,43459:9503,43460:9504,43461:9505,43462:9506,43463:9507,43464:9508,43465:9509,43466:9510,43467:9511,43468:9512,43469:9513,43470:9514,43471:9515,43472:9516,43473:9517,43474:9518,43475:9519,43476:9520,43477:9521,43478:9522,43479:9523,43480:9524,43481:9525,43482:9526,43483:9527,43484:9528,43485:9529,43486:9530,43487:9531,43488:9532,43489:9533,43490:9534,43491:9535,43492:9536,43493:9537,43494:9538,43495:9539,43496:9540,43497:9541,43498:9542,43499:9543,43500:9544,43501:9545,43502:9546,43503:9547,43504:59393,43505:59394,43506:59395,43507:59396,43508:59397,43509:59398,43510:59399,43511:59400,43512:59401,43513:59402,43514:59403,43515:59404,43516:59405,43517:59406,43518:59407,43584:29404,43585:29405,43586:29407,43587:29410,43588:29411,43589:29412,43590:29413,43591:29414,43592:29415,43593:29418,43594:29419,43595:29429,43596:29430,43597:29433,43598:29437,43599:29438,43600:29439,43601:29440,43602:29442,43603:29444,43604:29445,43605:29446,43606:29447,43607:29448,43608:29449,43609:29451,43610:29452,43611:29453,43612:29455,43613:29456,43614:29457,43615:29458,43616:29460,43617:29464,43618:29465,43619:29466,43620:29471,43621:29472,43622:29475,43623:29476,43624:29478,43625:29479,43626:29480,43627:29485,43628:29487,43629:29488,43630:29490,43631:29491,43632:29493,43633:29494,43634:29498,43635:29499,43636:29500,43637:29501,43638:29504,43639:29505,43640:29506,43641:29507,43642:29508,43643:29509,43644:29510,43645:29511,43646:29512,43648:29513,43649:29514,43650:29515,43651:29516,43652:29518,43653:29519,43654:29521,43655:29523,43656:29524,43657:29525,43658:29526,43659:29528,43660:29529,43661:29530,43662:29531,43663:29532,43664:29533,43665:29534,43666:29535,43667:29537,43668:29538,43669:29539,43670:29540,43671:29541,43672:29542,43673:29543,43674:29544,43675:29545,43676:29546,43677:29547,43678:29550,43679:29552,43680:29553,43681:57344,43682:57345,43683:57346,43684:57347,43685:57348,43686:57349,43687:57350,43688:57351,43689:57352,43690:57353,43691:57354,43692:57355,43693:57356,43694:57357,43695:57358,43696:57359,43697:57360,43698:57361,43699:57362,43700:57363,43701:57364,43702:57365,43703:57366,43704:57367,43705:57368,43706:57369,43707:57370,43708:57371,43709:57372,43710:57373,43711:57374,43712:57375,43713:57376,43714:57377,43715:57378,43716:57379,43717:57380,43718:57381,43719:57382,43720:57383,43721:57384,43722:57385,43723:57386,43724:57387,43725:57388,43726:57389,43727:57390,43728:57391,43729:57392,43730:57393,43731:57394,43732:57395,43733:57396,43734:57397,43735:57398,43736:57399,43737:57400,43738:57401,43739:57402,43740:57403,43741:57404,43742:57405,43743:57406,43744:57407,43745:57408,43746:57409,43747:57410,43748:57411,43749:57412,43750:57413,43751:57414,43752:57415,43753:57416,43754:57417,43755:57418,43756:57419,43757:57420,43758:57421,43759:57422,43760:57423,43761:57424,43762:57425,43763:57426,43764:57427,43765:57428,43766:57429,43767:57430,43768:57431,43769:57432,43770:57433,43771:57434,43772:57435,43773:57436,43774:57437,43840:29554,43841:29555,43842:29556,43843:29557,43844:29558,43845:29559,43846:29560,43847:29561,43848:29562,43849:29563,43850:29564,43851:29565,43852:29567,43853:29568,43854:29569,43855:29570,43856:29571,43857:29573,43858:29574,43859:29576,43860:29578,43861:29580,43862:29581,43863:29583,43864:29584,43865:29586,43866:29587,43867:29588,43868:29589,43869:29591,43870:29592,43871:29593,43872:29594,43873:29596,43874:29597,43875:29598,43876:29600,43877:29601,43878:29603,43879:29604,43880:29605,43881:29606,43882:29607,43883:29608,43884:29610,43885:29612,43886:29613,43887:29617,43888:29620,43889:29621,43890:29622,43891:29624,43892:29625,43893:29628,43894:29629,43895:29630,43896:29631,43897:29633,43898:29635,43899:29636,43900:29637,43901:29638,43902:29639,43904:29643,43905:29644,43906:29646,43907:29650,43908:29651,43909:29652,43910:29653,43911:29654,43912:29655,43913:29656,43914:29658,43915:29659,43916:29660,43917:29661,43918:29663,43919:29665,43920:29666,43921:29667,43922:29668,43923:29670,43924:29672,43925:29674,43926:29675,43927:29676,43928:29678,43929:29679,43930:29680,43931:29681,43932:29683,43933:29684,43934:29685,43935:29686,43936:29687,43937:57438,43938:57439,43939:57440,43940:57441,43941:57442,43942:57443,43943:57444,43944:57445,43945:57446,43946:57447,43947:57448,43948:57449,43949:57450,43950:57451,43951:57452,43952:57453,43953:57454,43954:57455,43955:57456,43956:57457,43957:57458,43958:57459,43959:57460,43960:57461,43961:57462,43962:57463,43963:57464,43964:57465,43965:57466,43966:57467,43967:57468,43968:57469,43969:57470,43970:57471,43971:57472,43972:57473,43973:57474,43974:57475,43975:57476,43976:57477,43977:57478,43978:57479,43979:57480,43980:57481,43981:57482,43982:57483,43983:57484,43984:57485,43985:57486,43986:57487,43987:57488,43988:57489,43989:57490,43990:57491,43991:57492,43992:57493,43993:57494,43994:57495,43995:57496,43996:57497,43997:57498,43998:57499,43999:57500,44000:57501,44001:57502,44002:57503,44003:57504,44004:57505,44005:57506,44006:57507,44007:57508,44008:57509,44009:57510,44010:57511,44011:57512,44012:57513,44013:57514,44014:57515,44015:57516,44016:57517,44017:57518,44018:57519,44019:57520,44020:57521,44021:57522,44022:57523,44023:57524,44024:57525,44025:57526,44026:57527,44027:57528,44028:57529,44029:57530,44030:57531,44096:29688,44097:29689,44098:29690,44099:29691,44100:29692,44101:29693,44102:29694,44103:29695,44104:29696,44105:29697,44106:29698,44107:29700,44108:29703,44109:29704,44110:29707,44111:29708,44112:29709,44113:29710,44114:29713,44115:29714,44116:29715,44117:29716,44118:29717,44119:29718,44120:29719,44121:29720,44122:29721,44123:29724,44124:29725,44125:29726,44126:29727,44127:29728,44128:29729,44129:29731,44130:29732,44131:29735,44132:29737,44133:29739,44134:29741,44135:29743,44136:29745,44137:29746,44138:29751,44139:29752,44140:29753,44141:29754,44142:29755,44143:29757,44144:29758,44145:29759,44146:29760,44147:29762,44148:29763,44149:29764,44150:29765,44151:29766,44152:29767,44153:29768,44154:29769,44155:29770,44156:29771,44157:29772,44158:29773,44160:29774,44161:29775,44162:29776,44163:29777,44164:29778,44165:29779,44166:29780,44167:29782,44168:29784,44169:29789,44170:29792,44171:29793,44172:29794,44173:29795,44174:29796,44175:29797,44176:29798,44177:29799,44178:29800,44179:29801,44180:29802,44181:29803,44182:29804,44183:29806,44184:29807,44185:29809,44186:29810,44187:29811,44188:29812,44189:29813,44190:29816,44191:29817,44192:29818,44193:57532,44194:57533,44195:57534,44196:57535,44197:57536,44198:57537,44199:57538,44200:57539,44201:57540,44202:57541,44203:57542,44204:57543,44205:57544,44206:57545,44207:57546,44208:57547,44209:57548,44210:57549,44211:57550,44212:57551,44213:57552,44214:57553,44215:57554,44216:57555,44217:57556,44218:57557,44219:57558,44220:57559,44221:57560,44222:57561,44223:57562,44224:57563,44225:57564,44226:57565,44227:57566,44228:57567,44229:57568,44230:57569,44231:57570,44232:57571,44233:57572,44234:57573,44235:57574,44236:57575,44237:57576,44238:57577,44239:57578,44240:57579,44241:57580,44242:57581,44243:57582,44244:57583,44245:57584,44246:57585,44247:57586,44248:57587,44249:57588,44250:57589,44251:57590,44252:57591,44253:57592,44254:57593,44255:57594,44256:57595,44257:57596,44258:57597,44259:57598,44260:57599,44261:57600,44262:57601,44263:57602,44264:57603,44265:57604,44266:57605,44267:57606,44268:57607,44269:57608,44270:57609,44271:57610,44272:57611,44273:57612,44274:57613,44275:57614,44276:57615,44277:57616,44278:57617,44279:57618,44280:57619,44281:57620,44282:57621,44283:57622,44284:57623,44285:57624,44286:57625,44352:29819,44353:29820,44354:29821,44355:29823,44356:29826,44357:29828,44358:29829,44359:29830,44360:29832,44361:29833,44362:29834,44363:29836,44364:29837,44365:29839,44366:29841,44367:29842,44368:29843,44369:29844,44370:29845,44371:29846,44372:29847,44373:29848,44374:29849,44375:29850,44376:29851,44377:29853,44378:29855,44379:29856,44380:29857,44381:29858,44382:29859,44383:29860,44384:29861,44385:29862,44386:29866,44387:29867,44388:29868,44389:29869,44390:29870,44391:29871,44392:29872,44393:29873,44394:29874,44395:29875,44396:29876,44397:29877,44398:29878,44399:29879,44400:29880,44401:29881,44402:29883,44403:29884,44404:29885,44405:29886,44406:29887,44407:29888,44408:29889,44409:29890,44410:29891,44411:29892,44412:29893,44413:29894,44414:29895,44416:29896,44417:29897,44418:29898,44419:29899,44420:29900,44421:29901,44422:29902,44423:29903,44424:29904,44425:29905,44426:29907,44427:29908,44428:29909,44429:29910,44430:29911,44431:29912,44432:29913,44433:29914,44434:29915,44435:29917,44436:29919,44437:29921,44438:29925,44439:29927,44440:29928,44441:29929,44442:29930,44443:29931,44444:29932,44445:29933,44446:29936,44447:29937,44448:29938,44449:57626,44450:57627,44451:57628,44452:57629,44453:57630,44454:57631,44455:57632,44456:57633,44457:57634,44458:57635,44459:57636,44460:57637,44461:57638,44462:57639,44463:57640,44464:57641,44465:57642,44466:57643,44467:57644,44468:57645,44469:57646,44470:57647,44471:57648,44472:57649,44473:57650,44474:57651,44475:57652,44476:57653,44477:57654,44478:57655,44479:57656,44480:57657,44481:57658,44482:57659,44483:57660,44484:57661,44485:57662,44486:57663,44487:57664,44488:57665,44489:57666,44490:57667,44491:57668,44492:57669,44493:57670,44494:57671,44495:57672,44496:57673,44497:57674,44498:57675,44499:57676,44500:57677,44501:57678,44502:57679,44503:57680,44504:57681,44505:57682,44506:57683,44507:57684,44508:57685,44509:57686,44510:57687,44511:57688,44512:57689,44513:57690,44514:57691,44515:57692,44516:57693,44517:57694,44518:57695,44519:57696,44520:57697,44521:57698,44522:57699,44523:57700,44524:57701,44525:57702,44526:57703,44527:57704,44528:57705,44529:57706,44530:57707,44531:57708,44532:57709,44533:57710,44534:57711,44535:57712,44536:57713,44537:57714,44538:57715,44539:57716,44540:57717,44541:57718,44542:57719,44608:29939,44609:29941,44610:29944,44611:29945,44612:29946,44613:29947,44614:29948,44615:29949,44616:29950,44617:29952,44618:29953,44619:29954,44620:29955,44621:29957,44622:29958,44623:29959,44624:29960,44625:29961,44626:29962,44627:29963,44628:29964,44629:29966,44630:29968,44631:29970,44632:29972,44633:29973,44634:29974,44635:29975,44636:29979,44637:29981,44638:29982,44639:29984,44640:29985,44641:29986,44642:29987,44643:29988,44644:29990,44645:29991,44646:29994,44647:29998,44648:30004,44649:30006,44650:30009,44651:30012,44652:30013,44653:30015,44654:30017,44655:30018,44656:30019,44657:30020,44658:30022,44659:30023,44660:30025,44661:30026,44662:30029,44663:30032,44664:30033,44665:30034,44666:30035,44667:30037,44668:30038,44669:30039,44670:30040,44672:30045,44673:30046,44674:30047,44675:30048,44676:30049,44677:30050,44678:30051,44679:30052,44680:30055,44681:30056,44682:30057,44683:30059,44684:30060,44685:30061,44686:30062,44687:30063,44688:30064,44689:30065,44690:30067,44691:30069,44692:30070,44693:30071,44694:30074,44695:30075,44696:30076,44697:30077,44698:30078,44699:30080,44700:30081,44701:30082,44702:30084,44703:30085,44704:30087,44705:57720,44706:57721,44707:57722,44708:57723,44709:57724,44710:57725,44711:57726,44712:57727,44713:57728,44714:57729,44715:57730,44716:57731,44717:57732,44718:57733,44719:57734,44720:57735,44721:57736,44722:57737,44723:57738,44724:57739,44725:57740,44726:57741,44727:57742,44728:57743,44729:57744,44730:57745,44731:57746,44732:57747,44733:57748,44734:57749,44735:57750,44736:57751,44737:57752,44738:57753,44739:57754,44740:57755,44741:57756,44742:57757,44743:57758,44744:57759,44745:57760,44746:57761,44747:57762,44748:57763,44749:57764,44750:57765,44751:57766,44752:57767,44753:57768,44754:57769,44755:57770,44756:57771,44757:57772,44758:57773,44759:57774,44760:57775,44761:57776,44762:57777,44763:57778,44764:57779,44765:57780,44766:57781,44767:57782,44768:57783,44769:57784,44770:57785,44771:57786,44772:57787,44773:57788,44774:57789,44775:57790,44776:57791,44777:57792,44778:57793,44779:57794,44780:57795,44781:57796,44782:57797,44783:57798,44784:57799,44785:57800,44786:57801,44787:57802,44788:57803,44789:57804,44790:57805,44791:57806,44792:57807,44793:57808,44794:57809,44795:57810,44796:57811,44797:57812,44798:57813,44864:30088,44865:30089,44866:30090,44867:30092,44868:30093,44869:30094,44870:30096,44871:30099,44872:30101,44873:30104,44874:30107,44875:30108,44876:30110,44877:30114,44878:30118,44879:30119,44880:30120,44881:30121,44882:30122,44883:30125,44884:30134,44885:30135,44886:30138,44887:30139,44888:30143,44889:30144,44890:30145,44891:30150,44892:30155,44893:30156,44894:30158,44895:30159,44896:30160,44897:30161,44898:30163,44899:30167,44900:30169,44901:30170,44902:30172,44903:30173,44904:30175,44905:30176,44906:30177,44907:30181,44908:30185,44909:30188,44910:30189,44911:30190,44912:30191,44913:30194,44914:30195,44915:30197,44916:30198,44917:30199,44918:30200,44919:30202,44920:30203,44921:30205,44922:30206,44923:30210,44924:30212,44925:30214,44926:30215,44928:30216,44929:30217,44930:30219,44931:30221,44932:30222,44933:30223,44934:30225,44935:30226,44936:30227,44937:30228,44938:30230,44939:30234,44940:30236,44941:30237,44942:30238,44943:30241,44944:30243,44945:30247,44946:30248,44947:30252,44948:30254,44949:30255,44950:30257,44951:30258,44952:30262,44953:30263,44954:30265,44955:30266,44956:30267,44957:30269,44958:30273,44959:30274,44960:30276,44961:57814,44962:57815,44963:57816,44964:57817,44965:57818,44966:57819,44967:57820,44968:57821,44969:57822,44970:57823,44971:57824,44972:57825,44973:57826,44974:57827,44975:57828,44976:57829,44977:57830,44978:57831,44979:57832,44980:57833,44981:57834,44982:57835,44983:57836,44984:57837,44985:57838,44986:57839,44987:57840,44988:57841,44989:57842,44990:57843,44991:57844,44992:57845,44993:57846,44994:57847,44995:57848,44996:57849,44997:57850,44998:57851,44999:57852,45000:57853,45001:57854,45002:57855,45003:57856,45004:57857,45005:57858,45006:57859,45007:57860,45008:57861,45009:57862,45010:57863,45011:57864,45012:57865,45013:57866,45014:57867,45015:57868,45016:57869,45017:57870,45018:57871,45019:57872,45020:57873,45021:57874,45022:57875,45023:57876,45024:57877,45025:57878,45026:57879,45027:57880,45028:57881,45029:57882,45030:57883,45031:57884,45032:57885,45033:57886,45034:57887,45035:57888,45036:57889,45037:57890,45038:57891,45039:57892,45040:57893,45041:57894,45042:57895,45043:57896,45044:57897,45045:57898,45046:57899,45047:57900,45048:57901,45049:57902,45050:57903,45051:57904,45052:57905,45053:57906,45054:57907,45120:30277,45121:30278,45122:30279,45123:30280,45124:30281,45125:30282,45126:30283,45127:30286,45128:30287,45129:30288,45130:30289,45131:30290,45132:30291,45133:30293,45134:30295,45135:30296,45136:30297,45137:30298,45138:30299,45139:30301,45140:30303,45141:30304,45142:30305,45143:30306,45144:30308,45145:30309,45146:30310,45147:30311,45148:30312,45149:30313,45150:30314,45151:30316,45152:30317,45153:30318,45154:30320,45155:30321,45156:30322,45157:30323,45158:30324,45159:30325,45160:30326,45161:30327,45162:30329,45163:30330,45164:30332,45165:30335,45166:30336,45167:30337,45168:30339,45169:30341,45170:30345,45171:30346,45172:30348,45173:30349,45174:30351,45175:30352,45176:30354,45177:30356,45178:30357,45179:30359,45180:30360,45181:30362,45182:30363,45184:30364,45185:30365,45186:30366,45187:30367,45188:30368,45189:30369,45190:30370,45191:30371,45192:30373,45193:30374,45194:30375,45195:30376,45196:30377,45197:30378,45198:30379,45199:30380,45200:30381,45201:30383,45202:30384,45203:30387,45204:30389,45205:30390,45206:30391,45207:30392,45208:30393,45209:30394,45210:30395,45211:30396,45212:30397,45213:30398,45214:30400,45215:30401,45216:30403,45217:21834,45218:38463,45219:22467,45220:25384,45221:21710,45222:21769,45223:21696,45224:30353,45225:30284,45226:34108,45227:30702,45228:33406,45229:30861,45230:29233,45231:38552,45232:38797,45233:27688,45234:23433,45235:20474,45236:25353,45237:26263,45238:23736,45239:33018,45240:26696,45241:32942,45242:26114,45243:30414,45244:20985,45245:25942,45246:29100,45247:32753,45248:34948,45249:20658,45250:22885,45251:25034,45252:28595,45253:33453,45254:25420,45255:25170,45256:21485,45257:21543,45258:31494,45259:20843,45260:30116,45261:24052,45262:25300,45263:36299,45264:38774,45265:25226,45266:32793,45267:22365,45268:38712,45269:32610,45270:29240,45271:30333,45272:26575,45273:30334,45274:25670,45275:20336,45276:36133,45277:25308,45278:31255,45279:26001,45280:29677,45281:25644,45282:25203,45283:33324,45284:39041,45285:26495,45286:29256,45287:25198,45288:25292,45289:20276,45290:29923,45291:21322,45292:21150,45293:32458,45294:37030,45295:24110,45296:26758,45297:27036,45298:33152,45299:32465,45300:26834,45301:30917,45302:34444,45303:38225,45304:20621,45305:35876,45306:33502,45307:32990,45308:21253,45309:35090,45310:21093,45376:30404,45377:30407,45378:30409,45379:30411,45380:30412,45381:30419,45382:30421,45383:30425,45384:30426,45385:30428,45386:30429,45387:30430,45388:30432,45389:30433,45390:30434,45391:30435,45392:30436,45393:30438,45394:30439,45395:30440,45396:30441,45397:30442,45398:30443,45399:30444,45400:30445,45401:30448,45402:30451,45403:30453,45404:30454,45405:30455,45406:30458,45407:30459,45408:30461,45409:30463,45410:30464,45411:30466,45412:30467,45413:30469,45414:30470,45415:30474,45416:30476,45417:30478,45418:30479,45419:30480,45420:30481,45421:30482,45422:30483,45423:30484,45424:30485,45425:30486,45426:30487,45427:30488,45428:30491,45429:30492,45430:30493,45431:30494,45432:30497,45433:30499,45434:30500,45435:30501,45436:30503,45437:30506,45438:30507,45440:30508,45441:30510,45442:30512,45443:30513,45444:30514,45445:30515,45446:30516,45447:30521,45448:30523,45449:30525,45450:30526,45451:30527,45452:30530,45453:30532,45454:30533,45455:30534,45456:30536,45457:30537,45458:30538,45459:30539,45460:30540,45461:30541,45462:30542,45463:30543,45464:30546,45465:30547,45466:30548,45467:30549,45468:30550,45469:30551,45470:30552,45471:30553,45472:30556,45473:34180,45474:38649,45475:20445,45476:22561,45477:39281,45478:23453,45479:25265,45480:25253,45481:26292,45482:35961,45483:40077,45484:29190,45485:26479,45486:30865,45487:24754,45488:21329,45489:21271,45490:36744,45491:32972,45492:36125,45493:38049,45494:20493,45495:29384,45496:22791,45497:24811,45498:28953,45499:34987,45500:22868,45501:33519,45502:26412,45503:31528,45504:23849,45505:32503,45506:29997,45507:27893,45508:36454,45509:36856,45510:36924,45511:40763,45512:27604,45513:37145,45514:31508,45515:24444,45516:30887,45517:34006,45518:34109,45519:27605,45520:27609,45521:27606,45522:24065,45523:24199,45524:30201,45525:38381,45526:25949,45527:24330,45528:24517,45529:36767,45530:22721,45531:33218,45532:36991,45533:38491,45534:38829,45535:36793,45536:32534,45537:36140,45538:25153,45539:20415,45540:21464,45541:21342,45542:36776,45543:36777,45544:36779,45545:36941,45546:26631,45547:24426,45548:33176,45549:34920,45550:40150,45551:24971,45552:21035,45553:30250,45554:24428,45555:25996,45556:28626,45557:28392,45558:23486,45559:25672,45560:20853,45561:20912,45562:26564,45563:19993,45564:31177,45565:39292,45566:28851,45632:30557,45633:30558,45634:30559,45635:30560,45636:30564,45637:30567,45638:30569,45639:30570,45640:30573,45641:30574,45642:30575,45643:30576,45644:30577,45645:30578,45646:30579,45647:30580,45648:30581,45649:30582,45650:30583,45651:30584,45652:30586,45653:30587,45654:30588,45655:30593,45656:30594,45657:30595,45658:30598,45659:30599,45660:30600,45661:30601,45662:30602,45663:30603,45664:30607,45665:30608,45666:30611,45667:30612,45668:30613,45669:30614,45670:30615,45671:30616,45672:30617,45673:30618,45674:30619,45675:30620,45676:30621,45677:30622,45678:30625,45679:30627,45680:30628,45681:30630,45682:30632,45683:30635,45684:30637,45685:30638,45686:30639,45687:30641,45688:30642,45689:30644,45690:30646,45691:30647,45692:30648,45693:30649,45694:30650,45696:30652,45697:30654,45698:30656,45699:30657,45700:30658,45701:30659,45702:30660,45703:30661,45704:30662,45705:30663,45706:30664,45707:30665,45708:30666,45709:30667,45710:30668,45711:30670,45712:30671,45713:30672,45714:30673,45715:30674,45716:30675,45717:30676,45718:30677,45719:30678,45720:30680,45721:30681,45722:30682,45723:30685,45724:30686,45725:30687,45726:30688,45727:30689,45728:30692,45729:30149,45730:24182,45731:29627,45732:33760,45733:25773,45734:25320,45735:38069,45736:27874,45737:21338,45738:21187,45739:25615,45740:38082,45741:31636,45742:20271,45743:24091,45744:33334,45745:33046,45746:33162,45747:28196,45748:27850,45749:39539,45750:25429,45751:21340,45752:21754,45753:34917,45754:22496,45755:19981,45756:24067,45757:27493,45758:31807,45759:37096,45760:24598,45761:25830,45762:29468,45763:35009,45764:26448,45765:25165,45766:36130,45767:30572,45768:36393,45769:37319,45770:24425,45771:33756,45772:34081,45773:39184,45774:21442,45775:34453,45776:27531,45777:24813,45778:24808,45779:28799,45780:33485,45781:33329,45782:20179,45783:27815,45784:34255,45785:25805,45786:31961,45787:27133,45788:26361,45789:33609,45790:21397,45791:31574,45792:20391,45793:20876,45794:27979,45795:23618,45796:36461,45797:25554,45798:21449,45799:33580,45800:33590,45801:26597,45802:30900,45803:25661,45804:23519,45805:23700,45806:24046,45807:35815,45808:25286,45809:26612,45810:35962,45811:25600,45812:25530,45813:34633,45814:39307,45815:35863,45816:32544,45817:38130,45818:20135,45819:38416,45820:39076,45821:26124,45822:29462,45888:30694,45889:30696,45890:30698,45891:30703,45892:30704,45893:30705,45894:30706,45895:30708,45896:30709,45897:30711,45898:30713,45899:30714,45900:30715,45901:30716,45902:30723,45903:30724,45904:30725,45905:30726,45906:30727,45907:30728,45908:30730,45909:30731,45910:30734,45911:30735,45912:30736,45913:30739,45914:30741,45915:30745,45916:30747,45917:30750,45918:30752,45919:30753,45920:30754,45921:30756,45922:30760,45923:30762,45924:30763,45925:30766,45926:30767,45927:30769,45928:30770,45929:30771,45930:30773,45931:30774,45932:30781,45933:30783,45934:30785,45935:30786,45936:30787,45937:30788,45938:30790,45939:30792,45940:30793,45941:30794,45942:30795,45943:30797,45944:30799,45945:30801,45946:30803,45947:30804,45948:30808,45949:30809,45950:30810,45952:30811,45953:30812,45954:30814,45955:30815,45956:30816,45957:30817,45958:30818,45959:30819,45960:30820,45961:30821,45962:30822,45963:30823,45964:30824,45965:30825,45966:30831,45967:30832,45968:30833,45969:30834,45970:30835,45971:30836,45972:30837,45973:30838,45974:30840,45975:30841,45976:30842,45977:30843,45978:30845,45979:30846,45980:30847,45981:30848,45982:30849,45983:30850,45984:30851,45985:22330,45986:23581,45987:24120,45988:38271,45989:20607,45990:32928,45991:21378,45992:25950,45993:30021,45994:21809,45995:20513,45996:36229,45997:25220,45998:38046,45999:26397,46000:22066,46001:28526,46002:24034,46003:21557,46004:28818,46005:36710,46006:25199,46007:25764,46008:25507,46009:24443,46010:28552,46011:37108,46012:33251,46013:36784,46014:23576,46015:26216,46016:24561,46017:27785,46018:38472,46019:36225,46020:34924,46021:25745,46022:31216,46023:22478,46024:27225,46025:25104,46026:21576,46027:20056,46028:31243,46029:24809,46030:28548,46031:35802,46032:25215,46033:36894,46034:39563,46035:31204,46036:21507,46037:30196,46038:25345,46039:21273,46040:27744,46041:36831,46042:24347,46043:39536,46044:32827,46045:40831,46046:20360,46047:23610,46048:36196,46049:32709,46050:26021,46051:28861,46052:20805,46053:20914,46054:34411,46055:23815,46056:23456,46057:25277,46058:37228,46059:30068,46060:36364,46061:31264,46062:24833,46063:31609,46064:20167,46065:32504,46066:30597,46067:19985,46068:33261,46069:21021,46070:20986,46071:27249,46072:21416,46073:36487,46074:38148,46075:38607,46076:28353,46077:38500,46078:26970,46144:30852,46145:30853,46146:30854,46147:30856,46148:30858,46149:30859,46150:30863,46151:30864,46152:30866,46153:30868,46154:30869,46155:30870,46156:30873,46157:30877,46158:30878,46159:30880,46160:30882,46161:30884,46162:30886,46163:30888,46164:30889,46165:30890,46166:30891,46167:30892,46168:30893,46169:30894,46170:30895,46171:30901,46172:30902,46173:30903,46174:30904,46175:30906,46176:30907,46177:30908,46178:30909,46179:30911,46180:30912,46181:30914,46182:30915,46183:30916,46184:30918,46185:30919,46186:30920,46187:30924,46188:30925,46189:30926,46190:30927,46191:30929,46192:30930,46193:30931,46194:30934,46195:30935,46196:30936,46197:30938,46198:30939,46199:30940,46200:30941,46201:30942,46202:30943,46203:30944,46204:30945,46205:30946,46206:30947,46208:30948,46209:30949,46210:30950,46211:30951,46212:30953,46213:30954,46214:30955,46215:30957,46216:30958,46217:30959,46218:30960,46219:30961,46220:30963,46221:30965,46222:30966,46223:30968,46224:30969,46225:30971,46226:30972,46227:30973,46228:30974,46229:30975,46230:30976,46231:30978,46232:30979,46233:30980,46234:30982,46235:30983,46236:30984,46237:30985,46238:30986,46239:30987,46240:30988,46241:30784,46242:20648,46243:30679,46244:25616,46245:35302,46246:22788,46247:25571,46248:24029,46249:31359,46250:26941,46251:20256,46252:33337,46253:21912,46254:20018,46255:30126,46256:31383,46257:24162,46258:24202,46259:38383,46260:21019,46261:21561,46262:28810,46263:25462,46264:38180,46265:22402,46266:26149,46267:26943,46268:37255,46269:21767,46270:28147,46271:32431,46272:34850,46273:25139,46274:32496,46275:30133,46276:33576,46277:30913,46278:38604,46279:36766,46280:24904,46281:29943,46282:35789,46283:27492,46284:21050,46285:36176,46286:27425,46287:32874,46288:33905,46289:22257,46290:21254,46291:20174,46292:19995,46293:20945,46294:31895,46295:37259,46296:31751,46297:20419,46298:36479,46299:31713,46300:31388,46301:25703,46302:23828,46303:20652,46304:33030,46305:30209,46306:31929,46307:28140,46308:32736,46309:26449,46310:23384,46311:23544,46312:30923,46313:25774,46314:25619,46315:25514,46316:25387,46317:38169,46318:25645,46319:36798,46320:31572,46321:30249,46322:25171,46323:22823,46324:21574,46325:27513,46326:20643,46327:25140,46328:24102,46329:27526,46330:20195,46331:36151,46332:34955,46333:24453,46334:36910,46400:30989,46401:30990,46402:30991,46403:30992,46404:30993,46405:30994,46406:30996,46407:30997,46408:30998,46409:30999,46410:31000,46411:31001,46412:31002,46413:31003,46414:31004,46415:31005,46416:31007,46417:31008,46418:31009,46419:31010,46420:31011,46421:31013,46422:31014,46423:31015,46424:31016,46425:31017,46426:31018,46427:31019,46428:31020,46429:31021,46430:31022,46431:31023,46432:31024,46433:31025,46434:31026,46435:31027,46436:31029,46437:31030,46438:31031,46439:31032,46440:31033,46441:31037,46442:31039,46443:31042,46444:31043,46445:31044,46446:31045,46447:31047,46448:31050,46449:31051,46450:31052,46451:31053,46452:31054,46453:31055,46454:31056,46455:31057,46456:31058,46457:31060,46458:31061,46459:31064,46460:31065,46461:31073,46462:31075,46464:31076,46465:31078,46466:31081,46467:31082,46468:31083,46469:31084,46470:31086,46471:31088,46472:31089,46473:31090,46474:31091,46475:31092,46476:31093,46477:31094,46478:31097,46479:31099,46480:31100,46481:31101,46482:31102,46483:31103,46484:31106,46485:31107,46486:31110,46487:31111,46488:31112,46489:31113,46490:31115,46491:31116,46492:31117,46493:31118,46494:31120,46495:31121,46496:31122,46497:24608,46498:32829,46499:25285,46500:20025,46501:21333,46502:37112,46503:25528,46504:32966,46505:26086,46506:27694,46507:20294,46508:24814,46509:28129,46510:35806,46511:24377,46512:34507,46513:24403,46514:25377,46515:20826,46516:33633,46517:26723,46518:20992,46519:25443,46520:36424,46521:20498,46522:23707,46523:31095,46524:23548,46525:21040,46526:31291,46527:24764,46528:36947,46529:30423,46530:24503,46531:24471,46532:30340,46533:36460,46534:28783,46535:30331,46536:31561,46537:30634,46538:20979,46539:37011,46540:22564,46541:20302,46542:28404,46543:36842,46544:25932,46545:31515,46546:29380,46547:28068,46548:32735,46549:23265,46550:25269,46551:24213,46552:22320,46553:33922,46554:31532,46555:24093,46556:24351,46557:36882,46558:32532,46559:39072,46560:25474,46561:28359,46562:30872,46563:28857,46564:20856,46565:38747,46566:22443,46567:30005,46568:20291,46569:30008,46570:24215,46571:24806,46572:22880,46573:28096,46574:27583,46575:30857,46576:21500,46577:38613,46578:20939,46579:20993,46580:25481,46581:21514,46582:38035,46583:35843,46584:36300,46585:29241,46586:30879,46587:34678,46588:36845,46589:35853,46590:21472,46656:31123,46657:31124,46658:31125,46659:31126,46660:31127,46661:31128,46662:31129,46663:31131,46664:31132,46665:31133,46666:31134,46667:31135,46668:31136,46669:31137,46670:31138,46671:31139,46672:31140,46673:31141,46674:31142,46675:31144,46676:31145,46677:31146,46678:31147,46679:31148,46680:31149,46681:31150,46682:31151,46683:31152,46684:31153,46685:31154,46686:31156,46687:31157,46688:31158,46689:31159,46690:31160,46691:31164,46692:31167,46693:31170,46694:31172,46695:31173,46696:31175,46697:31176,46698:31178,46699:31180,46700:31182,46701:31183,46702:31184,46703:31187,46704:31188,46705:31190,46706:31191,46707:31193,46708:31194,46709:31195,46710:31196,46711:31197,46712:31198,46713:31200,46714:31201,46715:31202,46716:31205,46717:31208,46718:31210,46720:31212,46721:31214,46722:31217,46723:31218,46724:31219,46725:31220,46726:31221,46727:31222,46728:31223,46729:31225,46730:31226,46731:31228,46732:31230,46733:31231,46734:31233,46735:31236,46736:31237,46737:31239,46738:31240,46739:31241,46740:31242,46741:31244,46742:31247,46743:31248,46744:31249,46745:31250,46746:31251,46747:31253,46748:31254,46749:31256,46750:31257,46751:31259,46752:31260,46753:19969,46754:30447,46755:21486,46756:38025,46757:39030,46758:40718,46759:38189,46760:23450,46761:35746,46762:20002,46763:19996,46764:20908,46765:33891,46766:25026,46767:21160,46768:26635,46769:20375,46770:24683,46771:20923,46772:27934,46773:20828,46774:25238,46775:26007,46776:38497,46777:35910,46778:36887,46779:30168,46780:37117,46781:30563,46782:27602,46783:29322,46784:29420,46785:35835,46786:22581,46787:30585,46788:36172,46789:26460,46790:38208,46791:32922,46792:24230,46793:28193,46794:22930,46795:31471,46796:30701,46797:38203,46798:27573,46799:26029,46800:32526,46801:22534,46802:20817,46803:38431,46804:23545,46805:22697,46806:21544,46807:36466,46808:25958,46809:39039,46810:22244,46811:38045,46812:30462,46813:36929,46814:25479,46815:21702,46816:22810,46817:22842,46818:22427,46819:36530,46820:26421,46821:36346,46822:33333,46823:21057,46824:24816,46825:22549,46826:34558,46827:23784,46828:40517,46829:20420,46830:39069,46831:35769,46832:23077,46833:24694,46834:21380,46835:25212,46836:36943,46837:37122,46838:39295,46839:24681,46840:32780,46841:20799,46842:32819,46843:23572,46844:39285,46845:27953,46846:20108,46912:31261,46913:31263,46914:31265,46915:31266,46916:31268,46917:31269,46918:31270,46919:31271,46920:31272,46921:31273,46922:31274,46923:31275,46924:31276,46925:31277,46926:31278,46927:31279,46928:31280,46929:31281,46930:31282,46931:31284,46932:31285,46933:31286,46934:31288,46935:31290,46936:31294,46937:31296,46938:31297,46939:31298,46940:31299,46941:31300,46942:31301,46943:31303,46944:31304,46945:31305,46946:31306,46947:31307,46948:31308,46949:31309,46950:31310,46951:31311,46952:31312,46953:31314,46954:31315,46955:31316,46956:31317,46957:31318,46958:31320,46959:31321,46960:31322,46961:31323,46962:31324,46963:31325,46964:31326,46965:31327,46966:31328,46967:31329,46968:31330,46969:31331,46970:31332,46971:31333,46972:31334,46973:31335,46974:31336,46976:31337,46977:31338,46978:31339,46979:31340,46980:31341,46981:31342,46982:31343,46983:31345,46984:31346,46985:31347,46986:31349,46987:31355,46988:31356,46989:31357,46990:31358,46991:31362,46992:31365,46993:31367,46994:31369,46995:31370,46996:31371,46997:31372,46998:31374,46999:31375,47000:31376,47001:31379,47002:31380,47003:31385,47004:31386,47005:31387,47006:31390,47007:31393,47008:31394,47009:36144,47010:21457,47011:32602,47012:31567,47013:20240,47014:20047,47015:38400,47016:27861,47017:29648,47018:34281,47019:24070,47020:30058,47021:32763,47022:27146,47023:30718,47024:38034,47025:32321,47026:20961,47027:28902,47028:21453,47029:36820,47030:33539,47031:36137,47032:29359,47033:39277,47034:27867,47035:22346,47036:33459,47037:26041,47038:32938,47039:25151,47040:38450,47041:22952,47042:20223,47043:35775,47044:32442,47045:25918,47046:33778,47047:38750,47048:21857,47049:39134,47050:32933,47051:21290,47052:35837,47053:21536,47054:32954,47055:24223,47056:27832,47057:36153,47058:33452,47059:37210,47060:21545,47061:27675,47062:20998,47063:32439,47064:22367,47065:28954,47066:27774,47067:31881,47068:22859,47069:20221,47070:24575,47071:24868,47072:31914,47073:20016,47074:23553,47075:26539,47076:34562,47077:23792,47078:38155,47079:39118,47080:30127,47081:28925,47082:36898,47083:20911,47084:32541,47085:35773,47086:22857,47087:20964,47088:20315,47089:21542,47090:22827,47091:25975,47092:32932,47093:23413,47094:25206,47095:25282,47096:36752,47097:24133,47098:27679,47099:31526,47100:20239,47101:20440,47102:26381,47168:31395,47169:31396,47170:31399,47171:31401,47172:31402,47173:31403,47174:31406,47175:31407,47176:31408,47177:31409,47178:31410,47179:31412,47180:31413,47181:31414,47182:31415,47183:31416,47184:31417,47185:31418,47186:31419,47187:31420,47188:31421,47189:31422,47190:31424,47191:31425,47192:31426,47193:31427,47194:31428,47195:31429,47196:31430,47197:31431,47198:31432,47199:31433,47200:31434,47201:31436,47202:31437,47203:31438,47204:31439,47205:31440,47206:31441,47207:31442,47208:31443,47209:31444,47210:31445,47211:31447,47212:31448,47213:31450,47214:31451,47215:31452,47216:31453,47217:31457,47218:31458,47219:31460,47220:31463,47221:31464,47222:31465,47223:31466,47224:31467,47225:31468,47226:31470,47227:31472,47228:31473,47229:31474,47230:31475,47232:31476,47233:31477,47234:31478,47235:31479,47236:31480,47237:31483,47238:31484,47239:31486,47240:31488,47241:31489,47242:31490,47243:31493,47244:31495,47245:31497,47246:31500,47247:31501,47248:31502,47249:31504,47250:31506,47251:31507,47252:31510,47253:31511,47254:31512,47255:31514,47256:31516,47257:31517,47258:31519,47259:31521,47260:31522,47261:31523,47262:31527,47263:31529,47264:31533,47265:28014,47266:28074,47267:31119,47268:34993,47269:24343,47270:29995,47271:25242,47272:36741,47273:20463,47274:37340,47275:26023,47276:33071,47277:33105,47278:24220,47279:33104,47280:36212,47281:21103,47282:35206,47283:36171,47284:22797,47285:20613,47286:20184,47287:38428,47288:29238,47289:33145,47290:36127,47291:23500,47292:35747,47293:38468,47294:22919,47295:32538,47296:21648,47297:22134,47298:22030,47299:35813,47300:25913,47301:27010,47302:38041,47303:30422,47304:28297,47305:24178,47306:29976,47307:26438,47308:26577,47309:31487,47310:32925,47311:36214,47312:24863,47313:31174,47314:25954,47315:36195,47316:20872,47317:21018,47318:38050,47319:32568,47320:32923,47321:32434,47322:23703,47323:28207,47324:26464,47325:31705,47326:30347,47327:39640,47328:33167,47329:32660,47330:31957,47331:25630,47332:38224,47333:31295,47334:21578,47335:21733,47336:27468,47337:25601,47338:25096,47339:40509,47340:33011,47341:30105,47342:21106,47343:38761,47344:33883,47345:26684,47346:34532,47347:38401,47348:38548,47349:38124,47350:20010,47351:21508,47352:32473,47353:26681,47354:36319,47355:32789,47356:26356,47357:24218,47358:32697,47424:31535,47425:31536,47426:31538,47427:31540,47428:31541,47429:31542,47430:31543,47431:31545,47432:31547,47433:31549,47434:31551,47435:31552,47436:31553,47437:31554,47438:31555,47439:31556,47440:31558,47441:31560,47442:31562,47443:31565,47444:31566,47445:31571,47446:31573,47447:31575,47448:31577,47449:31580,47450:31582,47451:31583,47452:31585,47453:31587,47454:31588,47455:31589,47456:31590,47457:31591,47458:31592,47459:31593,47460:31594,47461:31595,47462:31596,47463:31597,47464:31599,47465:31600,47466:31603,47467:31604,47468:31606,47469:31608,47470:31610,47471:31612,47472:31613,47473:31615,47474:31617,47475:31618,47476:31619,47477:31620,47478:31622,47479:31623,47480:31624,47481:31625,47482:31626,47483:31627,47484:31628,47485:31630,47486:31631,47488:31633,47489:31634,47490:31635,47491:31638,47492:31640,47493:31641,47494:31642,47495:31643,47496:31646,47497:31647,47498:31648,47499:31651,47500:31652,47501:31653,47502:31662,47503:31663,47504:31664,47505:31666,47506:31667,47507:31669,47508:31670,47509:31671,47510:31673,47511:31674,47512:31675,47513:31676,47514:31677,47515:31678,47516:31679,47517:31680,47518:31682,47519:31683,47520:31684,47521:22466,47522:32831,47523:26775,47524:24037,47525:25915,47526:21151,47527:24685,47528:40858,47529:20379,47530:36524,47531:20844,47532:23467,47533:24339,47534:24041,47535:27742,47536:25329,47537:36129,47538:20849,47539:38057,47540:21246,47541:27807,47542:33503,47543:29399,47544:22434,47545:26500,47546:36141,47547:22815,47548:36764,47549:33735,47550:21653,47551:31629,47552:20272,47553:27837,47554:23396,47555:22993,47556:40723,47557:21476,47558:34506,47559:39592,47560:35895,47561:32929,47562:25925,47563:39038,47564:22266,47565:38599,47566:21038,47567:29916,47568:21072,47569:23521,47570:25346,47571:35074,47572:20054,47573:25296,47574:24618,47575:26874,47576:20851,47577:23448,47578:20896,47579:35266,47580:31649,47581:39302,47582:32592,47583:24815,47584:28748,47585:36143,47586:20809,47587:24191,47588:36891,47589:29808,47590:35268,47591:22317,47592:30789,47593:24402,47594:40863,47595:38394,47596:36712,47597:39740,47598:35809,47599:30328,47600:26690,47601:26588,47602:36330,47603:36149,47604:21053,47605:36746,47606:28378,47607:26829,47608:38149,47609:37101,47610:22269,47611:26524,47612:35065,47613:36807,47614:21704,47680:31685,47681:31688,47682:31689,47683:31690,47684:31691,47685:31693,47686:31694,47687:31695,47688:31696,47689:31698,47690:31700,47691:31701,47692:31702,47693:31703,47694:31704,47695:31707,47696:31708,47697:31710,47698:31711,47699:31712,47700:31714,47701:31715,47702:31716,47703:31719,47704:31720,47705:31721,47706:31723,47707:31724,47708:31725,47709:31727,47710:31728,47711:31730,47712:31731,47713:31732,47714:31733,47715:31734,47716:31736,47717:31737,47718:31738,47719:31739,47720:31741,47721:31743,47722:31744,47723:31745,47724:31746,47725:31747,47726:31748,47727:31749,47728:31750,47729:31752,47730:31753,47731:31754,47732:31757,47733:31758,47734:31760,47735:31761,47736:31762,47737:31763,47738:31764,47739:31765,47740:31767,47741:31768,47742:31769,47744:31770,47745:31771,47746:31772,47747:31773,47748:31774,47749:31776,47750:31777,47751:31778,47752:31779,47753:31780,47754:31781,47755:31784,47756:31785,47757:31787,47758:31788,47759:31789,47760:31790,47761:31791,47762:31792,47763:31793,47764:31794,47765:31795,47766:31796,47767:31797,47768:31798,47769:31799,47770:31801,47771:31802,47772:31803,47773:31804,47774:31805,47775:31806,47776:31810,47777:39608,47778:23401,47779:28023,47780:27686,47781:20133,47782:23475,47783:39559,47784:37219,47785:25000,47786:37039,47787:38889,47788:21547,47789:28085,47790:23506,47791:20989,47792:21898,47793:32597,47794:32752,47795:25788,47796:25421,47797:26097,47798:25022,47799:24717,47800:28938,47801:27735,47802:27721,47803:22831,47804:26477,47805:33322,47806:22741,47807:22158,47808:35946,47809:27627,47810:37085,47811:22909,47812:32791,47813:21495,47814:28009,47815:21621,47816:21917,47817:33655,47818:33743,47819:26680,47820:31166,47821:21644,47822:20309,47823:21512,47824:30418,47825:35977,47826:38402,47827:27827,47828:28088,47829:36203,47830:35088,47831:40548,47832:36154,47833:22079,47834:40657,47835:30165,47836:24456,47837:29408,47838:24680,47839:21756,47840:20136,47841:27178,47842:34913,47843:24658,47844:36720,47845:21700,47846:28888,47847:34425,47848:40511,47849:27946,47850:23439,47851:24344,47852:32418,47853:21897,47854:20399,47855:29492,47856:21564,47857:21402,47858:20505,47859:21518,47860:21628,47861:20046,47862:24573,47863:29786,47864:22774,47865:33899,47866:32993,47867:34676,47868:29392,47869:31946,47870:28246,47936:31811,47937:31812,47938:31813,47939:31814,47940:31815,47941:31816,47942:31817,47943:31818,47944:31819,47945:31820,47946:31822,47947:31823,47948:31824,47949:31825,47950:31826,47951:31827,47952:31828,47953:31829,47954:31830,47955:31831,47956:31832,47957:31833,47958:31834,47959:31835,47960:31836,47961:31837,47962:31838,47963:31839,47964:31840,47965:31841,47966:31842,47967:31843,47968:31844,47969:31845,47970:31846,47971:31847,47972:31848,47973:31849,47974:31850,47975:31851,47976:31852,47977:31853,47978:31854,47979:31855,47980:31856,47981:31857,47982:31858,47983:31861,47984:31862,47985:31863,47986:31864,47987:31865,47988:31866,47989:31870,47990:31871,47991:31872,47992:31873,47993:31874,47994:31875,47995:31876,47996:31877,47997:31878,47998:31879,48000:31880,48001:31882,48002:31883,48003:31884,48004:31885,48005:31886,48006:31887,48007:31888,48008:31891,48009:31892,48010:31894,48011:31897,48012:31898,48013:31899,48014:31904,48015:31905,48016:31907,48017:31910,48018:31911,48019:31912,48020:31913,48021:31915,48022:31916,48023:31917,48024:31919,48025:31920,48026:31924,48027:31925,48028:31926,48029:31927,48030:31928,48031:31930,48032:31931,48033:24359,48034:34382,48035:21804,48036:25252,48037:20114,48038:27818,48039:25143,48040:33457,48041:21719,48042:21326,48043:29502,48044:28369,48045:30011,48046:21010,48047:21270,48048:35805,48049:27088,48050:24458,48051:24576,48052:28142,48053:22351,48054:27426,48055:29615,48056:26707,48057:36824,48058:32531,48059:25442,48060:24739,48061:21796,48062:30186,48063:35938,48064:28949,48065:28067,48066:23462,48067:24187,48068:33618,48069:24908,48070:40644,48071:30970,48072:34647,48073:31783,48074:30343,48075:20976,48076:24822,48077:29004,48078:26179,48079:24140,48080:24653,48081:35854,48082:28784,48083:25381,48084:36745,48085:24509,48086:24674,48087:34516,48088:22238,48089:27585,48090:24724,48091:24935,48092:21321,48093:24800,48094:26214,48095:36159,48096:31229,48097:20250,48098:28905,48099:27719,48100:35763,48101:35826,48102:32472,48103:33636,48104:26127,48105:23130,48106:39746,48107:27985,48108:28151,48109:35905,48110:27963,48111:20249,48112:28779,48113:33719,48114:25110,48115:24785,48116:38669,48117:36135,48118:31096,48119:20987,48120:22334,48121:22522,48122:26426,48123:30072,48124:31293,48125:31215,48126:31637,48192:31935,48193:31936,48194:31938,48195:31939,48196:31940,48197:31942,48198:31945,48199:31947,48200:31950,48201:31951,48202:31952,48203:31953,48204:31954,48205:31955,48206:31956,48207:31960,48208:31962,48209:31963,48210:31965,48211:31966,48212:31969,48213:31970,48214:31971,48215:31972,48216:31973,48217:31974,48218:31975,48219:31977,48220:31978,48221:31979,48222:31980,48223:31981,48224:31982,48225:31984,48226:31985,48227:31986,48228:31987,48229:31988,48230:31989,48231:31990,48232:31991,48233:31993,48234:31994,48235:31996,48236:31997,48237:31998,48238:31999,48239:32000,48240:32001,48241:32002,48242:32003,48243:32004,48244:32005,48245:32006,48246:32007,48247:32008,48248:32009,48249:32011,48250:32012,48251:32013,48252:32014,48253:32015,48254:32016,48256:32017,48257:32018,48258:32019,48259:32020,48260:32021,48261:32022,48262:32023,48263:32024,48264:32025,48265:32026,48266:32027,48267:32028,48268:32029,48269:32030,48270:32031,48271:32033,48272:32035,48273:32036,48274:32037,48275:32038,48276:32040,48277:32041,48278:32042,48279:32044,48280:32045,48281:32046,48282:32048,48283:32049,48284:32050,48285:32051,48286:32052,48287:32053,48288:32054,48289:32908,48290:39269,48291:36857,48292:28608,48293:35749,48294:40481,48295:23020,48296:32489,48297:32521,48298:21513,48299:26497,48300:26840,48301:36753,48302:31821,48303:38598,48304:21450,48305:24613,48306:30142,48307:27762,48308:21363,48309:23241,48310:32423,48311:25380,48312:20960,48313:33034,48314:24049,48315:34015,48316:25216,48317:20864,48318:23395,48319:20238,48320:31085,48321:21058,48322:24760,48323:27982,48324:23492,48325:23490,48326:35745,48327:35760,48328:26082,48329:24524,48330:38469,48331:22931,48332:32487,48333:32426,48334:22025,48335:26551,48336:22841,48337:20339,48338:23478,48339:21152,48340:33626,48341:39050,48342:36158,48343:30002,48344:38078,48345:20551,48346:31292,48347:20215,48348:26550,48349:39550,48350:23233,48351:27516,48352:30417,48353:22362,48354:23574,48355:31546,48356:38388,48357:29006,48358:20860,48359:32937,48360:33392,48361:22904,48362:32516,48363:33575,48364:26816,48365:26604,48366:30897,48367:30839,48368:25315,48369:25441,48370:31616,48371:20461,48372:21098,48373:20943,48374:33616,48375:27099,48376:37492,48377:36341,48378:36145,48379:35265,48380:38190,48381:31661,48382:20214,48448:32055,48449:32056,48450:32057,48451:32058,48452:32059,48453:32060,48454:32061,48455:32062,48456:32063,48457:32064,48458:32065,48459:32066,48460:32067,48461:32068,48462:32069,48463:32070,48464:32071,48465:32072,48466:32073,48467:32074,48468:32075,48469:32076,48470:32077,48471:32078,48472:32079,48473:32080,48474:32081,48475:32082,48476:32083,48477:32084,48478:32085,48479:32086,48480:32087,48481:32088,48482:32089,48483:32090,48484:32091,48485:32092,48486:32093,48487:32094,48488:32095,48489:32096,48490:32097,48491:32098,48492:32099,48493:32100,48494:32101,48495:32102,48496:32103,48497:32104,48498:32105,48499:32106,48500:32107,48501:32108,48502:32109,48503:32111,48504:32112,48505:32113,48506:32114,48507:32115,48508:32116,48509:32117,48510:32118,48512:32120,48513:32121,48514:32122,48515:32123,48516:32124,48517:32125,48518:32126,48519:32127,48520:32128,48521:32129,48522:32130,48523:32131,48524:32132,48525:32133,48526:32134,48527:32135,48528:32136,48529:32137,48530:32138,48531:32139,48532:32140,48533:32141,48534:32142,48535:32143,48536:32144,48537:32145,48538:32146,48539:32147,48540:32148,48541:32149,48542:32150,48543:32151,48544:32152,48545:20581,48546:33328,48547:21073,48548:39279,48549:28176,48550:28293,48551:28071,48552:24314,48553:20725,48554:23004,48555:23558,48556:27974,48557:27743,48558:30086,48559:33931,48560:26728,48561:22870,48562:35762,48563:21280,48564:37233,48565:38477,48566:34121,48567:26898,48568:30977,48569:28966,48570:33014,48571:20132,48572:37066,48573:27975,48574:39556,48575:23047,48576:22204,48577:25605,48578:38128,48579:30699,48580:20389,48581:33050,48582:29409,48583:35282,48584:39290,48585:32564,48586:32478,48587:21119,48588:25945,48589:37237,48590:36735,48591:36739,48592:21483,48593:31382,48594:25581,48595:25509,48596:30342,48597:31224,48598:34903,48599:38454,48600:25130,48601:21163,48602:33410,48603:26708,48604:26480,48605:25463,48606:30571,48607:31469,48608:27905,48609:32467,48610:35299,48611:22992,48612:25106,48613:34249,48614:33445,48615:30028,48616:20511,48617:20171,48618:30117,48619:35819,48620:23626,48621:24062,48622:31563,48623:26020,48624:37329,48625:20170,48626:27941,48627:35167,48628:32039,48629:38182,48630:20165,48631:35880,48632:36827,48633:38771,48634:26187,48635:31105,48636:36817,48637:28908,48638:28024,48704:32153,48705:32154,48706:32155,48707:32156,48708:32157,48709:32158,48710:32159,48711:32160,48712:32161,48713:32162,48714:32163,48715:32164,48716:32165,48717:32167,48718:32168,48719:32169,48720:32170,48721:32171,48722:32172,48723:32173,48724:32175,48725:32176,48726:32177,48727:32178,48728:32179,48729:32180,48730:32181,48731:32182,48732:32183,48733:32184,48734:32185,48735:32186,48736:32187,48737:32188,48738:32189,48739:32190,48740:32191,48741:32192,48742:32193,48743:32194,48744:32195,48745:32196,48746:32197,48747:32198,48748:32199,48749:32200,48750:32201,48751:32202,48752:32203,48753:32204,48754:32205,48755:32206,48756:32207,48757:32208,48758:32209,48759:32210,48760:32211,48761:32212,48762:32213,48763:32214,48764:32215,48765:32216,48766:32217,48768:32218,48769:32219,48770:32220,48771:32221,48772:32222,48773:32223,48774:32224,48775:32225,48776:32226,48777:32227,48778:32228,48779:32229,48780:32230,48781:32231,48782:32232,48783:32233,48784:32234,48785:32235,48786:32236,48787:32237,48788:32238,48789:32239,48790:32240,48791:32241,48792:32242,48793:32243,48794:32244,48795:32245,48796:32246,48797:32247,48798:32248,48799:32249,48800:32250,48801:23613,48802:21170,48803:33606,48804:20834,48805:33550,48806:30555,48807:26230,48808:40120,48809:20140,48810:24778,48811:31934,48812:31923,48813:32463,48814:20117,48815:35686,48816:26223,48817:39048,48818:38745,48819:22659,48820:25964,48821:38236,48822:24452,48823:30153,48824:38742,48825:31455,48826:31454,48827:20928,48828:28847,48829:31384,48830:25578,48831:31350,48832:32416,48833:29590,48834:38893,48835:20037,48836:28792,48837:20061,48838:37202,48839:21417,48840:25937,48841:26087,48842:33276,48843:33285,48844:21646,48845:23601,48846:30106,48847:38816,48848:25304,48849:29401,48850:30141,48851:23621,48852:39545,48853:33738,48854:23616,48855:21632,48856:30697,48857:20030,48858:27822,48859:32858,48860:25298,48861:25454,48862:24040,48863:20855,48864:36317,48865:36382,48866:38191,48867:20465,48868:21477,48869:24807,48870:28844,48871:21095,48872:25424,48873:40515,48874:23071,48875:20518,48876:30519,48877:21367,48878:32482,48879:25733,48880:25899,48881:25225,48882:25496,48883:20500,48884:29237,48885:35273,48886:20915,48887:35776,48888:32477,48889:22343,48890:33740,48891:38055,48892:20891,48893:21531,48894:23803,48960:32251,48961:32252,48962:32253,48963:32254,48964:32255,48965:32256,48966:32257,48967:32258,48968:32259,48969:32260,48970:32261,48971:32262,48972:32263,48973:32264,48974:32265,48975:32266,48976:32267,48977:32268,48978:32269,48979:32270,48980:32271,48981:32272,48982:32273,48983:32274,48984:32275,48985:32276,48986:32277,48987:32278,48988:32279,48989:32280,48990:32281,48991:32282,48992:32283,48993:32284,48994:32285,48995:32286,48996:32287,48997:32288,48998:32289,48999:32290,49000:32291,49001:32292,49002:32293,49003:32294,49004:32295,49005:32296,49006:32297,49007:32298,49008:32299,49009:32300,49010:32301,49011:32302,49012:32303,49013:32304,49014:32305,49015:32306,49016:32307,49017:32308,49018:32309,49019:32310,49020:32311,49021:32312,49022:32313,49024:32314,49025:32316,49026:32317,49027:32318,49028:32319,49029:32320,49030:32322,49031:32323,49032:32324,49033:32325,49034:32326,49035:32328,49036:32329,49037:32330,49038:32331,49039:32332,49040:32333,49041:32334,49042:32335,49043:32336,49044:32337,49045:32338,49046:32339,49047:32340,49048:32341,49049:32342,49050:32343,49051:32344,49052:32345,49053:32346,49054:32347,49055:32348,49056:32349,49057:20426,49058:31459,49059:27994,49060:37089,49061:39567,49062:21888,49063:21654,49064:21345,49065:21679,49066:24320,49067:25577,49068:26999,49069:20975,49070:24936,49071:21002,49072:22570,49073:21208,49074:22350,49075:30733,49076:30475,49077:24247,49078:24951,49079:31968,49080:25179,49081:25239,49082:20130,49083:28821,49084:32771,49085:25335,49086:28900,49087:38752,49088:22391,49089:33499,49090:26607,49091:26869,49092:30933,49093:39063,49094:31185,49095:22771,49096:21683,49097:21487,49098:28212,49099:20811,49100:21051,49101:23458,49102:35838,49103:32943,49104:21827,49105:22438,49106:24691,49107:22353,49108:21549,49109:31354,49110:24656,49111:23380,49112:25511,49113:25248,49114:21475,49115:25187,49116:23495,49117:26543,49118:21741,49119:31391,49120:33510,49121:37239,49122:24211,49123:35044,49124:22840,49125:22446,49126:25358,49127:36328,49128:33007,49129:22359,49130:31607,49131:20393,49132:24555,49133:23485,49134:27454,49135:21281,49136:31568,49137:29378,49138:26694,49139:30719,49140:30518,49141:26103,49142:20917,49143:20111,49144:30420,49145:23743,49146:31397,49147:33909,49148:22862,49149:39745,49150:20608,49216:32350,49217:32351,49218:32352,49219:32353,49220:32354,49221:32355,49222:32356,49223:32357,49224:32358,49225:32359,49226:32360,49227:32361,49228:32362,49229:32363,49230:32364,49231:32365,49232:32366,49233:32367,49234:32368,49235:32369,49236:32370,49237:32371,49238:32372,49239:32373,49240:32374,49241:32375,49242:32376,49243:32377,49244:32378,49245:32379,49246:32380,49247:32381,49248:32382,49249:32383,49250:32384,49251:32385,49252:32387,49253:32388,49254:32389,49255:32390,49256:32391,49257:32392,49258:32393,49259:32394,49260:32395,49261:32396,49262:32397,49263:32398,49264:32399,49265:32400,49266:32401,49267:32402,49268:32403,49269:32404,49270:32405,49271:32406,49272:32407,49273:32408,49274:32409,49275:32410,49276:32412,49277:32413,49278:32414,49280:32430,49281:32436,49282:32443,49283:32444,49284:32470,49285:32484,49286:32492,49287:32505,49288:32522,49289:32528,49290:32542,49291:32567,49292:32569,49293:32571,49294:32572,49295:32573,49296:32574,49297:32575,49298:32576,49299:32577,49300:32579,49301:32582,49302:32583,49303:32584,49304:32585,49305:32586,49306:32587,49307:32588,49308:32589,49309:32590,49310:32591,49311:32594,49312:32595,49313:39304,49314:24871,49315:28291,49316:22372,49317:26118,49318:25414,49319:22256,49320:25324,49321:25193,49322:24275,49323:38420,49324:22403,49325:25289,49326:21895,49327:34593,49328:33098,49329:36771,49330:21862,49331:33713,49332:26469,49333:36182,49334:34013,49335:23146,49336:26639,49337:25318,49338:31726,49339:38417,49340:20848,49341:28572,49342:35888,49343:25597,49344:35272,49345:25042,49346:32518,49347:28866,49348:28389,49349:29701,49350:27028,49351:29436,49352:24266,49353:37070,49354:26391,49355:28010,49356:25438,49357:21171,49358:29282,49359:32769,49360:20332,49361:23013,49362:37226,49363:28889,49364:28061,49365:21202,49366:20048,49367:38647,49368:38253,49369:34174,49370:30922,49371:32047,49372:20769,49373:22418,49374:25794,49375:32907,49376:31867,49377:27882,49378:26865,49379:26974,49380:20919,49381:21400,49382:26792,49383:29313,49384:40654,49385:31729,49386:29432,49387:31163,49388:28435,49389:29702,49390:26446,49391:37324,49392:40100,49393:31036,49394:33673,49395:33620,49396:21519,49397:26647,49398:20029,49399:21385,49400:21169,49401:30782,49402:21382,49403:21033,49404:20616,49405:20363,49406:20432,49472:32598,49473:32601,49474:32603,49475:32604,49476:32605,49477:32606,49478:32608,49479:32611,49480:32612,49481:32613,49482:32614,49483:32615,49484:32619,49485:32620,49486:32621,49487:32623,49488:32624,49489:32627,49490:32629,49491:32630,49492:32631,49493:32632,49494:32634,49495:32635,49496:32636,49497:32637,49498:32639,49499:32640,49500:32642,49501:32643,49502:32644,49503:32645,49504:32646,49505:32647,49506:32648,49507:32649,49508:32651,49509:32653,49510:32655,49511:32656,49512:32657,49513:32658,49514:32659,49515:32661,49516:32662,49517:32663,49518:32664,49519:32665,49520:32667,49521:32668,49522:32672,49523:32674,49524:32675,49525:32677,49526:32678,49527:32680,49528:32681,49529:32682,49530:32683,49531:32684,49532:32685,49533:32686,49534:32689,49536:32691,49537:32692,49538:32693,49539:32694,49540:32695,49541:32698,49542:32699,49543:32702,49544:32704,49545:32706,49546:32707,49547:32708,49548:32710,49549:32711,49550:32712,49551:32713,49552:32715,49553:32717,49554:32719,49555:32720,49556:32721,49557:32722,49558:32723,49559:32726,49560:32727,49561:32729,49562:32730,49563:32731,49564:32732,49565:32733,49566:32734,49567:32738,49568:32739,49569:30178,49570:31435,49571:31890,49572:27813,49573:38582,49574:21147,49575:29827,49576:21737,49577:20457,49578:32852,49579:33714,49580:36830,49581:38256,49582:24265,49583:24604,49584:28063,49585:24088,49586:25947,49587:33080,49588:38142,49589:24651,49590:28860,49591:32451,49592:31918,49593:20937,49594:26753,49595:31921,49596:33391,49597:20004,49598:36742,49599:37327,49600:26238,49601:20142,49602:35845,49603:25769,49604:32842,49605:20698,49606:30103,49607:29134,49608:23525,49609:36797,49610:28518,49611:20102,49612:25730,49613:38243,49614:24278,49615:26009,49616:21015,49617:35010,49618:28872,49619:21155,49620:29454,49621:29747,49622:26519,49623:30967,49624:38678,49625:20020,49626:37051,49627:40158,49628:28107,49629:20955,49630:36161,49631:21533,49632:25294,49633:29618,49634:33777,49635:38646,49636:40836,49637:38083,49638:20278,49639:32666,49640:20940,49641:28789,49642:38517,49643:23725,49644:39046,49645:21478,49646:20196,49647:28316,49648:29705,49649:27060,49650:30827,49651:39311,49652:30041,49653:21016,49654:30244,49655:27969,49656:26611,49657:20845,49658:40857,49659:32843,49660:21657,49661:31548,49662:31423,49728:32740,49729:32743,49730:32744,49731:32746,49732:32747,49733:32748,49734:32749,49735:32751,49736:32754,49737:32756,49738:32757,49739:32758,49740:32759,49741:32760,49742:32761,49743:32762,49744:32765,49745:32766,49746:32767,49747:32770,49748:32775,49749:32776,49750:32777,49751:32778,49752:32782,49753:32783,49754:32785,49755:32787,49756:32794,49757:32795,49758:32797,49759:32798,49760:32799,49761:32801,49762:32803,49763:32804,49764:32811,49765:32812,49766:32813,49767:32814,49768:32815,49769:32816,49770:32818,49771:32820,49772:32825,49773:32826,49774:32828,49775:32830,49776:32832,49777:32833,49778:32836,49779:32837,49780:32839,49781:32840,49782:32841,49783:32846,49784:32847,49785:32848,49786:32849,49787:32851,49788:32853,49789:32854,49790:32855,49792:32857,49793:32859,49794:32860,49795:32861,49796:32862,49797:32863,49798:32864,49799:32865,49800:32866,49801:32867,49802:32868,49803:32869,49804:32870,49805:32871,49806:32872,49807:32875,49808:32876,49809:32877,49810:32878,49811:32879,49812:32880,49813:32882,49814:32883,49815:32884,49816:32885,49817:32886,49818:32887,49819:32888,49820:32889,49821:32890,49822:32891,49823:32892,49824:32893,49825:38534,49826:22404,49827:25314,49828:38471,49829:27004,49830:23044,49831:25602,49832:31699,49833:28431,49834:38475,49835:33446,49836:21346,49837:39045,49838:24208,49839:28809,49840:25523,49841:21348,49842:34383,49843:40065,49844:40595,49845:30860,49846:38706,49847:36335,49848:36162,49849:40575,49850:28510,49851:31108,49852:24405,49853:38470,49854:25134,49855:39540,49856:21525,49857:38109,49858:20387,49859:26053,49860:23653,49861:23649,49862:32533,49863:34385,49864:27695,49865:24459,49866:29575,49867:28388,49868:32511,49869:23782,49870:25371,49871:23402,49872:28390,49873:21365,49874:20081,49875:25504,49876:30053,49877:25249,49878:36718,49879:20262,49880:20177,49881:27814,49882:32438,49883:35770,49884:33821,49885:34746,49886:32599,49887:36923,49888:38179,49889:31657,49890:39585,49891:35064,49892:33853,49893:27931,49894:39558,49895:32476,49896:22920,49897:40635,49898:29595,49899:30721,49900:34434,49901:39532,49902:39554,49903:22043,49904:21527,49905:22475,49906:20080,49907:40614,49908:21334,49909:36808,49910:33033,49911:30610,49912:39314,49913:34542,49914:28385,49915:34067,49916:26364,49917:24930,49918:28459,49984:32894,49985:32897,49986:32898,49987:32901,49988:32904,49989:32906,49990:32909,49991:32910,49992:32911,49993:32912,49994:32913,49995:32914,49996:32916,49997:32917,49998:32919,49999:32921,50000:32926,50001:32931,50002:32934,50003:32935,50004:32936,50005:32940,50006:32944,50007:32947,50008:32949,50009:32950,50010:32952,50011:32953,50012:32955,50013:32965,50014:32967,50015:32968,50016:32969,50017:32970,50018:32971,50019:32975,50020:32976,50021:32977,50022:32978,50023:32979,50024:32980,50025:32981,50026:32984,50027:32991,50028:32992,50029:32994,50030:32995,50031:32998,50032:33006,50033:33013,50034:33015,50035:33017,50036:33019,50037:33022,50038:33023,50039:33024,50040:33025,50041:33027,50042:33028,50043:33029,50044:33031,50045:33032,50046:33035,50048:33036,50049:33045,50050:33047,50051:33049,50052:33051,50053:33052,50054:33053,50055:33055,50056:33056,50057:33057,50058:33058,50059:33059,50060:33060,50061:33061,50062:33062,50063:33063,50064:33064,50065:33065,50066:33066,50067:33067,50068:33069,50069:33070,50070:33072,50071:33075,50072:33076,50073:33077,50074:33079,50075:33081,50076:33082,50077:33083,50078:33084,50079:33085,50080:33087,50081:35881,50082:33426,50083:33579,50084:30450,50085:27667,50086:24537,50087:33725,50088:29483,50089:33541,50090:38170,50091:27611,50092:30683,50093:38086,50094:21359,50095:33538,50096:20882,50097:24125,50098:35980,50099:36152,50100:20040,50101:29611,50102:26522,50103:26757,50104:37238,50105:38665,50106:29028,50107:27809,50108:30473,50109:23186,50110:38209,50111:27599,50112:32654,50113:26151,50114:23504,50115:22969,50116:23194,50117:38376,50118:38391,50119:20204,50120:33804,50121:33945,50122:27308,50123:30431,50124:38192,50125:29467,50126:26790,50127:23391,50128:30511,50129:37274,50130:38753,50131:31964,50132:36855,50133:35868,50134:24357,50135:31859,50136:31192,50137:35269,50138:27852,50139:34588,50140:23494,50141:24130,50142:26825,50143:30496,50144:32501,50145:20885,50146:20813,50147:21193,50148:23081,50149:32517,50150:38754,50151:33495,50152:25551,50153:30596,50154:34256,50155:31186,50156:28218,50157:24217,50158:22937,50159:34065,50160:28781,50161:27665,50162:25279,50163:30399,50164:25935,50165:24751,50166:38397,50167:26126,50168:34719,50169:40483,50170:38125,50171:21517,50172:21629,50173:35884,50174:25720,50240:33088,50241:33089,50242:33090,50243:33091,50244:33092,50245:33093,50246:33095,50247:33097,50248:33101,50249:33102,50250:33103,50251:33106,50252:33110,50253:33111,50254:33112,50255:33115,50256:33116,50257:33117,50258:33118,50259:33119,50260:33121,50261:33122,50262:33123,50263:33124,50264:33126,50265:33128,50266:33130,50267:33131,50268:33132,50269:33135,50270:33138,50271:33139,50272:33141,50273:33142,50274:33143,50275:33144,50276:33153,50277:33155,50278:33156,50279:33157,50280:33158,50281:33159,50282:33161,50283:33163,50284:33164,50285:33165,50286:33166,50287:33168,50288:33170,50289:33171,50290:33172,50291:33173,50292:33174,50293:33175,50294:33177,50295:33178,50296:33182,50297:33183,50298:33184,50299:33185,50300:33186,50301:33188,50302:33189,50304:33191,50305:33193,50306:33195,50307:33196,50308:33197,50309:33198,50310:33199,50311:33200,50312:33201,50313:33202,50314:33204,50315:33205,50316:33206,50317:33207,50318:33208,50319:33209,50320:33212,50321:33213,50322:33214,50323:33215,50324:33220,50325:33221,50326:33223,50327:33224,50328:33225,50329:33227,50330:33229,50331:33230,50332:33231,50333:33232,50334:33233,50335:33234,50336:33235,50337:25721,50338:34321,50339:27169,50340:33180,50341:30952,50342:25705,50343:39764,50344:25273,50345:26411,50346:33707,50347:22696,50348:40664,50349:27819,50350:28448,50351:23518,50352:38476,50353:35851,50354:29279,50355:26576,50356:25287,50357:29281,50358:20137,50359:22982,50360:27597,50361:22675,50362:26286,50363:24149,50364:21215,50365:24917,50366:26408,50367:30446,50368:30566,50369:29287,50370:31302,50371:25343,50372:21738,50373:21584,50374:38048,50375:37027,50376:23068,50377:32435,50378:27670,50379:20035,50380:22902,50381:32784,50382:22856,50383:21335,50384:30007,50385:38590,50386:22218,50387:25376,50388:33041,50389:24700,50390:38393,50391:28118,50392:21602,50393:39297,50394:20869,50395:23273,50396:33021,50397:22958,50398:38675,50399:20522,50400:27877,50401:23612,50402:25311,50403:20320,50404:21311,50405:33147,50406:36870,50407:28346,50408:34091,50409:25288,50410:24180,50411:30910,50412:25781,50413:25467,50414:24565,50415:23064,50416:37247,50417:40479,50418:23615,50419:25423,50420:32834,50421:23421,50422:21870,50423:38218,50424:38221,50425:28037,50426:24744,50427:26592,50428:29406,50429:20957,50430:23425,50496:33236,50497:33237,50498:33238,50499:33239,50500:33240,50501:33241,50502:33242,50503:33243,50504:33244,50505:33245,50506:33246,50507:33247,50508:33248,50509:33249,50510:33250,50511:33252,50512:33253,50513:33254,50514:33256,50515:33257,50516:33259,50517:33262,50518:33263,50519:33264,50520:33265,50521:33266,50522:33269,50523:33270,50524:33271,50525:33272,50526:33273,50527:33274,50528:33277,50529:33279,50530:33283,50531:33287,50532:33288,50533:33289,50534:33290,50535:33291,50536:33294,50537:33295,50538:33297,50539:33299,50540:33301,50541:33302,50542:33303,50543:33304,50544:33305,50545:33306,50546:33309,50547:33312,50548:33316,50549:33317,50550:33318,50551:33319,50552:33321,50553:33326,50554:33330,50555:33338,50556:33340,50557:33341,50558:33343,50560:33344,50561:33345,50562:33346,50563:33347,50564:33349,50565:33350,50566:33352,50567:33354,50568:33356,50569:33357,50570:33358,50571:33360,50572:33361,50573:33362,50574:33363,50575:33364,50576:33365,50577:33366,50578:33367,50579:33369,50580:33371,50581:33372,50582:33373,50583:33374,50584:33376,50585:33377,50586:33378,50587:33379,50588:33380,50589:33381,50590:33382,50591:33383,50592:33385,50593:25319,50594:27870,50595:29275,50596:25197,50597:38062,50598:32445,50599:33043,50600:27987,50601:20892,50602:24324,50603:22900,50604:21162,50605:24594,50606:22899,50607:26262,50608:34384,50609:30111,50610:25386,50611:25062,50612:31983,50613:35834,50614:21734,50615:27431,50616:40485,50617:27572,50618:34261,50619:21589,50620:20598,50621:27812,50622:21866,50623:36276,50624:29228,50625:24085,50626:24597,50627:29750,50628:25293,50629:25490,50630:29260,50631:24472,50632:28227,50633:27966,50634:25856,50635:28504,50636:30424,50637:30928,50638:30460,50639:30036,50640:21028,50641:21467,50642:20051,50643:24222,50644:26049,50645:32810,50646:32982,50647:25243,50648:21638,50649:21032,50650:28846,50651:34957,50652:36305,50653:27873,50654:21624,50655:32986,50656:22521,50657:35060,50658:36180,50659:38506,50660:37197,50661:20329,50662:27803,50663:21943,50664:30406,50665:30768,50666:25256,50667:28921,50668:28558,50669:24429,50670:34028,50671:26842,50672:30844,50673:31735,50674:33192,50675:26379,50676:40527,50677:25447,50678:30896,50679:22383,50680:30738,50681:38713,50682:25209,50683:25259,50684:21128,50685:29749,50686:27607,50752:33386,50753:33387,50754:33388,50755:33389,50756:33393,50757:33397,50758:33398,50759:33399,50760:33400,50761:33403,50762:33404,50763:33408,50764:33409,50765:33411,50766:33413,50767:33414,50768:33415,50769:33417,50770:33420,50771:33424,50772:33427,50773:33428,50774:33429,50775:33430,50776:33434,50777:33435,50778:33438,50779:33440,50780:33442,50781:33443,50782:33447,50783:33458,50784:33461,50785:33462,50786:33466,50787:33467,50788:33468,50789:33471,50790:33472,50791:33474,50792:33475,50793:33477,50794:33478,50795:33481,50796:33488,50797:33494,50798:33497,50799:33498,50800:33501,50801:33506,50802:33511,50803:33512,50804:33513,50805:33514,50806:33516,50807:33517,50808:33518,50809:33520,50810:33522,50811:33523,50812:33525,50813:33526,50814:33528,50816:33530,50817:33532,50818:33533,50819:33534,50820:33535,50821:33536,50822:33546,50823:33547,50824:33549,50825:33552,50826:33554,50827:33555,50828:33558,50829:33560,50830:33561,50831:33565,50832:33566,50833:33567,50834:33568,50835:33569,50836:33570,50837:33571,50838:33572,50839:33573,50840:33574,50841:33577,50842:33578,50843:33582,50844:33584,50845:33586,50846:33591,50847:33595,50848:33597,50849:21860,50850:33086,50851:30130,50852:30382,50853:21305,50854:30174,50855:20731,50856:23617,50857:35692,50858:31687,50859:20559,50860:29255,50861:39575,50862:39128,50863:28418,50864:29922,50865:31080,50866:25735,50867:30629,50868:25340,50869:39057,50870:36139,50871:21697,50872:32856,50873:20050,50874:22378,50875:33529,50876:33805,50877:24179,50878:20973,50879:29942,50880:35780,50881:23631,50882:22369,50883:27900,50884:39047,50885:23110,50886:30772,50887:39748,50888:36843,50889:31893,50890:21078,50891:25169,50892:38138,50893:20166,50894:33670,50895:33889,50896:33769,50897:33970,50898:22484,50899:26420,50900:22275,50901:26222,50902:28006,50903:35889,50904:26333,50905:28689,50906:26399,50907:27450,50908:26646,50909:25114,50910:22971,50911:19971,50912:20932,50913:28422,50914:26578,50915:27791,50916:20854,50917:26827,50918:22855,50919:27495,50920:30054,50921:23822,50922:33040,50923:40784,50924:26071,50925:31048,50926:31041,50927:39569,50928:36215,50929:23682,50930:20062,50931:20225,50932:21551,50933:22865,50934:30732,50935:22120,50936:27668,50937:36804,50938:24323,50939:27773,50940:27875,50941:35755,50942:25488,51008:33598,51009:33599,51010:33601,51011:33602,51012:33604,51013:33605,51014:33608,51015:33610,51016:33611,51017:33612,51018:33613,51019:33614,51020:33619,51021:33621,51022:33622,51023:33623,51024:33624,51025:33625,51026:33629,51027:33634,51028:33648,51029:33649,51030:33650,51031:33651,51032:33652,51033:33653,51034:33654,51035:33657,51036:33658,51037:33662,51038:33663,51039:33664,51040:33665,51041:33666,51042:33667,51043:33668,51044:33671,51045:33672,51046:33674,51047:33675,51048:33676,51049:33677,51050:33679,51051:33680,51052:33681,51053:33684,51054:33685,51055:33686,51056:33687,51057:33689,51058:33690,51059:33693,51060:33695,51061:33697,51062:33698,51063:33699,51064:33700,51065:33701,51066:33702,51067:33703,51068:33708,51069:33709,51070:33710,51072:33711,51073:33717,51074:33723,51075:33726,51076:33727,51077:33730,51078:33731,51079:33732,51080:33734,51081:33736,51082:33737,51083:33739,51084:33741,51085:33742,51086:33744,51087:33745,51088:33746,51089:33747,51090:33749,51091:33751,51092:33753,51093:33754,51094:33755,51095:33758,51096:33762,51097:33763,51098:33764,51099:33766,51100:33767,51101:33768,51102:33771,51103:33772,51104:33773,51105:24688,51106:27965,51107:29301,51108:25190,51109:38030,51110:38085,51111:21315,51112:36801,51113:31614,51114:20191,51115:35878,51116:20094,51117:40660,51118:38065,51119:38067,51120:21069,51121:28508,51122:36963,51123:27973,51124:35892,51125:22545,51126:23884,51127:27424,51128:27465,51129:26538,51130:21595,51131:33108,51132:32652,51133:22681,51134:34103,51135:24378,51136:25250,51137:27207,51138:38201,51139:25970,51140:24708,51141:26725,51142:30631,51143:20052,51144:20392,51145:24039,51146:38808,51147:25772,51148:32728,51149:23789,51150:20431,51151:31373,51152:20999,51153:33540,51154:19988,51155:24623,51156:31363,51157:38054,51158:20405,51159:20146,51160:31206,51161:29748,51162:21220,51163:33465,51164:25810,51165:31165,51166:23517,51167:27777,51168:38738,51169:36731,51170:27682,51171:20542,51172:21375,51173:28165,51174:25806,51175:26228,51176:27696,51177:24773,51178:39031,51179:35831,51180:24198,51181:29756,51182:31351,51183:31179,51184:19992,51185:37041,51186:29699,51187:27714,51188:22234,51189:37195,51190:27845,51191:36235,51192:21306,51193:34502,51194:26354,51195:36527,51196:23624,51197:39537,51198:28192,51264:33774,51265:33775,51266:33779,51267:33780,51268:33781,51269:33782,51270:33783,51271:33786,51272:33787,51273:33788,51274:33790,51275:33791,51276:33792,51277:33794,51278:33797,51279:33799,51280:33800,51281:33801,51282:33802,51283:33808,51284:33810,51285:33811,51286:33812,51287:33813,51288:33814,51289:33815,51290:33817,51291:33818,51292:33819,51293:33822,51294:33823,51295:33824,51296:33825,51297:33826,51298:33827,51299:33833,51300:33834,51301:33835,51302:33836,51303:33837,51304:33838,51305:33839,51306:33840,51307:33842,51308:33843,51309:33844,51310:33845,51311:33846,51312:33847,51313:33849,51314:33850,51315:33851,51316:33854,51317:33855,51318:33856,51319:33857,51320:33858,51321:33859,51322:33860,51323:33861,51324:33863,51325:33864,51326:33865,51328:33866,51329:33867,51330:33868,51331:33869,51332:33870,51333:33871,51334:33872,51335:33874,51336:33875,51337:33876,51338:33877,51339:33878,51340:33880,51341:33885,51342:33886,51343:33887,51344:33888,51345:33890,51346:33892,51347:33893,51348:33894,51349:33895,51350:33896,51351:33898,51352:33902,51353:33903,51354:33904,51355:33906,51356:33908,51357:33911,51358:33913,51359:33915,51360:33916,51361:21462,51362:23094,51363:40843,51364:36259,51365:21435,51366:22280,51367:39079,51368:26435,51369:37275,51370:27849,51371:20840,51372:30154,51373:25331,51374:29356,51375:21048,51376:21149,51377:32570,51378:28820,51379:30264,51380:21364,51381:40522,51382:27063,51383:30830,51384:38592,51385:35033,51386:32676,51387:28982,51388:29123,51389:20873,51390:26579,51391:29924,51392:22756,51393:25880,51394:22199,51395:35753,51396:39286,51397:25200,51398:32469,51399:24825,51400:28909,51401:22764,51402:20161,51403:20154,51404:24525,51405:38887,51406:20219,51407:35748,51408:20995,51409:22922,51410:32427,51411:25172,51412:20173,51413:26085,51414:25102,51415:33592,51416:33993,51417:33635,51418:34701,51419:29076,51420:28342,51421:23481,51422:32466,51423:20887,51424:25545,51425:26580,51426:32905,51427:33593,51428:34837,51429:20754,51430:23418,51431:22914,51432:36785,51433:20083,51434:27741,51435:20837,51436:35109,51437:36719,51438:38446,51439:34122,51440:29790,51441:38160,51442:38384,51443:28070,51444:33509,51445:24369,51446:25746,51447:27922,51448:33832,51449:33134,51450:40131,51451:22622,51452:36187,51453:19977,51454:21441,51520:33917,51521:33918,51522:33919,51523:33920,51524:33921,51525:33923,51526:33924,51527:33925,51528:33926,51529:33930,51530:33933,51531:33935,51532:33936,51533:33937,51534:33938,51535:33939,51536:33940,51537:33941,51538:33942,51539:33944,51540:33946,51541:33947,51542:33949,51543:33950,51544:33951,51545:33952,51546:33954,51547:33955,51548:33956,51549:33957,51550:33958,51551:33959,51552:33960,51553:33961,51554:33962,51555:33963,51556:33964,51557:33965,51558:33966,51559:33968,51560:33969,51561:33971,51562:33973,51563:33974,51564:33975,51565:33979,51566:33980,51567:33982,51568:33984,51569:33986,51570:33987,51571:33989,51572:33990,51573:33991,51574:33992,51575:33995,51576:33996,51577:33998,51578:33999,51579:34002,51580:34004,51581:34005,51582:34007,51584:34008,51585:34009,51586:34010,51587:34011,51588:34012,51589:34014,51590:34017,51591:34018,51592:34020,51593:34023,51594:34024,51595:34025,51596:34026,51597:34027,51598:34029,51599:34030,51600:34031,51601:34033,51602:34034,51603:34035,51604:34036,51605:34037,51606:34038,51607:34039,51608:34040,51609:34041,51610:34042,51611:34043,51612:34045,51613:34046,51614:34048,51615:34049,51616:34050,51617:20254,51618:25955,51619:26705,51620:21971,51621:20007,51622:25620,51623:39578,51624:25195,51625:23234,51626:29791,51627:33394,51628:28073,51629:26862,51630:20711,51631:33678,51632:30722,51633:26432,51634:21049,51635:27801,51636:32433,51637:20667,51638:21861,51639:29022,51640:31579,51641:26194,51642:29642,51643:33515,51644:26441,51645:23665,51646:21024,51647:29053,51648:34923,51649:38378,51650:38485,51651:25797,51652:36193,51653:33203,51654:21892,51655:27733,51656:25159,51657:32558,51658:22674,51659:20260,51660:21830,51661:36175,51662:26188,51663:19978,51664:23578,51665:35059,51666:26786,51667:25422,51668:31245,51669:28903,51670:33421,51671:21242,51672:38902,51673:23569,51674:21736,51675:37045,51676:32461,51677:22882,51678:36170,51679:34503,51680:33292,51681:33293,51682:36198,51683:25668,51684:23556,51685:24913,51686:28041,51687:31038,51688:35774,51689:30775,51690:30003,51691:21627,51692:20280,51693:36523,51694:28145,51695:23072,51696:32453,51697:31070,51698:27784,51699:23457,51700:23158,51701:29978,51702:32958,51703:24910,51704:28183,51705:22768,51706:29983,51707:29989,51708:29298,51709:21319,51710:32499,51776:34051,51777:34052,51778:34053,51779:34054,51780:34055,51781:34056,51782:34057,51783:34058,51784:34059,51785:34061,51786:34062,51787:34063,51788:34064,51789:34066,51790:34068,51791:34069,51792:34070,51793:34072,51794:34073,51795:34075,51796:34076,51797:34077,51798:34078,51799:34080,51800:34082,51801:34083,51802:34084,51803:34085,51804:34086,51805:34087,51806:34088,51807:34089,51808:34090,51809:34093,51810:34094,51811:34095,51812:34096,51813:34097,51814:34098,51815:34099,51816:34100,51817:34101,51818:34102,51819:34110,51820:34111,51821:34112,51822:34113,51823:34114,51824:34116,51825:34117,51826:34118,51827:34119,51828:34123,51829:34124,51830:34125,51831:34126,51832:34127,51833:34128,51834:34129,51835:34130,51836:34131,51837:34132,51838:34133,51840:34135,51841:34136,51842:34138,51843:34139,51844:34140,51845:34141,51846:34143,51847:34144,51848:34145,51849:34146,51850:34147,51851:34149,51852:34150,51853:34151,51854:34153,51855:34154,51856:34155,51857:34156,51858:34157,51859:34158,51860:34159,51861:34160,51862:34161,51863:34163,51864:34165,51865:34166,51866:34167,51867:34168,51868:34172,51869:34173,51870:34175,51871:34176,51872:34177,51873:30465,51874:30427,51875:21097,51876:32988,51877:22307,51878:24072,51879:22833,51880:29422,51881:26045,51882:28287,51883:35799,51884:23608,51885:34417,51886:21313,51887:30707,51888:25342,51889:26102,51890:20160,51891:39135,51892:34432,51893:23454,51894:35782,51895:21490,51896:30690,51897:20351,51898:23630,51899:39542,51900:22987,51901:24335,51902:31034,51903:22763,51904:19990,51905:26623,51906:20107,51907:25325,51908:35475,51909:36893,51910:21183,51911:26159,51912:21980,51913:22124,51914:36866,51915:20181,51916:20365,51917:37322,51918:39280,51919:27663,51920:24066,51921:24643,51922:23460,51923:35270,51924:35797,51925:25910,51926:25163,51927:39318,51928:23432,51929:23551,51930:25480,51931:21806,51932:21463,51933:30246,51934:20861,51935:34092,51936:26530,51937:26803,51938:27530,51939:25234,51940:36755,51941:21460,51942:33298,51943:28113,51944:30095,51945:20070,51946:36174,51947:23408,51948:29087,51949:34223,51950:26257,51951:26329,51952:32626,51953:34560,51954:40653,51955:40736,51956:23646,51957:26415,51958:36848,51959:26641,51960:26463,51961:25101,51962:31446,51963:22661,51964:24246,51965:25968,51966:28465,52032:34178,52033:34179,52034:34182,52035:34184,52036:34185,52037:34186,52038:34187,52039:34188,52040:34189,52041:34190,52042:34192,52043:34193,52044:34194,52045:34195,52046:34196,52047:34197,52048:34198,52049:34199,52050:34200,52051:34201,52052:34202,52053:34205,52054:34206,52055:34207,52056:34208,52057:34209,52058:34210,52059:34211,52060:34213,52061:34214,52062:34215,52063:34217,52064:34219,52065:34220,52066:34221,52067:34225,52068:34226,52069:34227,52070:34228,52071:34229,52072:34230,52073:34232,52074:34234,52075:34235,52076:34236,52077:34237,52078:34238,52079:34239,52080:34240,52081:34242,52082:34243,52083:34244,52084:34245,52085:34246,52086:34247,52087:34248,52088:34250,52089:34251,52090:34252,52091:34253,52092:34254,52093:34257,52094:34258,52096:34260,52097:34262,52098:34263,52099:34264,52100:34265,52101:34266,52102:34267,52103:34269,52104:34270,52105:34271,52106:34272,52107:34273,52108:34274,52109:34275,52110:34277,52111:34278,52112:34279,52113:34280,52114:34282,52115:34283,52116:34284,52117:34285,52118:34286,52119:34287,52120:34288,52121:34289,52122:34290,52123:34291,52124:34292,52125:34293,52126:34294,52127:34295,52128:34296,52129:24661,52130:21047,52131:32781,52132:25684,52133:34928,52134:29993,52135:24069,52136:26643,52137:25332,52138:38684,52139:21452,52140:29245,52141:35841,52142:27700,52143:30561,52144:31246,52145:21550,52146:30636,52147:39034,52148:33308,52149:35828,52150:30805,52151:26388,52152:28865,52153:26031,52154:25749,52155:22070,52156:24605,52157:31169,52158:21496,52159:19997,52160:27515,52161:32902,52162:23546,52163:21987,52164:22235,52165:20282,52166:20284,52167:39282,52168:24051,52169:26494,52170:32824,52171:24578,52172:39042,52173:36865,52174:23435,52175:35772,52176:35829,52177:25628,52178:33368,52179:25822,52180:22013,52181:33487,52182:37221,52183:20439,52184:32032,52185:36895,52186:31903,52187:20723,52188:22609,52189:28335,52190:23487,52191:35785,52192:32899,52193:37240,52194:33948,52195:31639,52196:34429,52197:38539,52198:38543,52199:32485,52200:39635,52201:30862,52202:23681,52203:31319,52204:36930,52205:38567,52206:31071,52207:23385,52208:25439,52209:31499,52210:34001,52211:26797,52212:21766,52213:32553,52214:29712,52215:32034,52216:38145,52217:25152,52218:22604,52219:20182,52220:23427,52221:22905,52222:22612,52288:34297,52289:34298,52290:34300,52291:34301,52292:34302,52293:34304,52294:34305,52295:34306,52296:34307,52297:34308,52298:34310,52299:34311,52300:34312,52301:34313,52302:34314,52303:34315,52304:34316,52305:34317,52306:34318,52307:34319,52308:34320,52309:34322,52310:34323,52311:34324,52312:34325,52313:34327,52314:34328,52315:34329,52316:34330,52317:34331,52318:34332,52319:34333,52320:34334,52321:34335,52322:34336,52323:34337,52324:34338,52325:34339,52326:34340,52327:34341,52328:34342,52329:34344,52330:34346,52331:34347,52332:34348,52333:34349,52334:34350,52335:34351,52336:34352,52337:34353,52338:34354,52339:34355,52340:34356,52341:34357,52342:34358,52343:34359,52344:34361,52345:34362,52346:34363,52347:34365,52348:34366,52349:34367,52350:34368,52352:34369,52353:34370,52354:34371,52355:34372,52356:34373,52357:34374,52358:34375,52359:34376,52360:34377,52361:34378,52362:34379,52363:34380,52364:34386,52365:34387,52366:34389,52367:34390,52368:34391,52369:34392,52370:34393,52371:34395,52372:34396,52373:34397,52374:34399,52375:34400,52376:34401,52377:34403,52378:34404,52379:34405,52380:34406,52381:34407,52382:34408,52383:34409,52384:34410,52385:29549,52386:25374,52387:36427,52388:36367,52389:32974,52390:33492,52391:25260,52392:21488,52393:27888,52394:37214,52395:22826,52396:24577,52397:27760,52398:22349,52399:25674,52400:36138,52401:30251,52402:28393,52403:22363,52404:27264,52405:30192,52406:28525,52407:35885,52408:35848,52409:22374,52410:27631,52411:34962,52412:30899,52413:25506,52414:21497,52415:28845,52416:27748,52417:22616,52418:25642,52419:22530,52420:26848,52421:33179,52422:21776,52423:31958,52424:20504,52425:36538,52426:28108,52427:36255,52428:28907,52429:25487,52430:28059,52431:28372,52432:32486,52433:33796,52434:26691,52435:36867,52436:28120,52437:38518,52438:35752,52439:22871,52440:29305,52441:34276,52442:33150,52443:30140,52444:35466,52445:26799,52446:21076,52447:36386,52448:38161,52449:25552,52450:39064,52451:36420,52452:21884,52453:20307,52454:26367,52455:22159,52456:24789,52457:28053,52458:21059,52459:23625,52460:22825,52461:28155,52462:22635,52463:30000,52464:29980,52465:24684,52466:33300,52467:33094,52468:25361,52469:26465,52470:36834,52471:30522,52472:36339,52473:36148,52474:38081,52475:24086,52476:21381,52477:21548,52478:28867,52544:34413,52545:34415,52546:34416,52547:34418,52548:34419,52549:34420,52550:34421,52551:34422,52552:34423,52553:34424,52554:34435,52555:34436,52556:34437,52557:34438,52558:34439,52559:34440,52560:34441,52561:34446,52562:34447,52563:34448,52564:34449,52565:34450,52566:34452,52567:34454,52568:34455,52569:34456,52570:34457,52571:34458,52572:34459,52573:34462,52574:34463,52575:34464,52576:34465,52577:34466,52578:34469,52579:34470,52580:34475,52581:34477,52582:34478,52583:34482,52584:34483,52585:34487,52586:34488,52587:34489,52588:34491,52589:34492,52590:34493,52591:34494,52592:34495,52593:34497,52594:34498,52595:34499,52596:34501,52597:34504,52598:34508,52599:34509,52600:34514,52601:34515,52602:34517,52603:34518,52604:34519,52605:34522,52606:34524,52608:34525,52609:34528,52610:34529,52611:34530,52612:34531,52613:34533,52614:34534,52615:34535,52616:34536,52617:34538,52618:34539,52619:34540,52620:34543,52621:34549,52622:34550,52623:34551,52624:34554,52625:34555,52626:34556,52627:34557,52628:34559,52629:34561,52630:34564,52631:34565,52632:34566,52633:34571,52634:34572,52635:34574,52636:34575,52637:34576,52638:34577,52639:34580,52640:34582,52641:27712,52642:24311,52643:20572,52644:20141,52645:24237,52646:25402,52647:33351,52648:36890,52649:26704,52650:37230,52651:30643,52652:21516,52653:38108,52654:24420,52655:31461,52656:26742,52657:25413,52658:31570,52659:32479,52660:30171,52661:20599,52662:25237,52663:22836,52664:36879,52665:20984,52666:31171,52667:31361,52668:22270,52669:24466,52670:36884,52671:28034,52672:23648,52673:22303,52674:21520,52675:20820,52676:28237,52677:22242,52678:25512,52679:39059,52680:33151,52681:34581,52682:35114,52683:36864,52684:21534,52685:23663,52686:33216,52687:25302,52688:25176,52689:33073,52690:40501,52691:38464,52692:39534,52693:39548,52694:26925,52695:22949,52696:25299,52697:21822,52698:25366,52699:21703,52700:34521,52701:27964,52702:23043,52703:29926,52704:34972,52705:27498,52706:22806,52707:35916,52708:24367,52709:28286,52710:29609,52711:39037,52712:20024,52713:28919,52714:23436,52715:30871,52716:25405,52717:26202,52718:30358,52719:24779,52720:23451,52721:23113,52722:19975,52723:33109,52724:27754,52725:29579,52726:20129,52727:26505,52728:32593,52729:24448,52730:26106,52731:26395,52732:24536,52733:22916,52734:23041,52800:34585,52801:34587,52802:34589,52803:34591,52804:34592,52805:34596,52806:34598,52807:34599,52808:34600,52809:34602,52810:34603,52811:34604,52812:34605,52813:34607,52814:34608,52815:34610,52816:34611,52817:34613,52818:34614,52819:34616,52820:34617,52821:34618,52822:34620,52823:34621,52824:34624,52825:34625,52826:34626,52827:34627,52828:34628,52829:34629,52830:34630,52831:34634,52832:34635,52833:34637,52834:34639,52835:34640,52836:34641,52837:34642,52838:34644,52839:34645,52840:34646,52841:34648,52842:34650,52843:34651,52844:34652,52845:34653,52846:34654,52847:34655,52848:34657,52849:34658,52850:34662,52851:34663,52852:34664,52853:34665,52854:34666,52855:34667,52856:34668,52857:34669,52858:34671,52859:34673,52860:34674,52861:34675,52862:34677,52864:34679,52865:34680,52866:34681,52867:34682,52868:34687,52869:34688,52870:34689,52871:34692,52872:34694,52873:34695,52874:34697,52875:34698,52876:34700,52877:34702,52878:34703,52879:34704,52880:34705,52881:34706,52882:34708,52883:34709,52884:34710,52885:34712,52886:34713,52887:34714,52888:34715,52889:34716,52890:34717,52891:34718,52892:34720,52893:34721,52894:34722,52895:34723,52896:34724,52897:24013,52898:24494,52899:21361,52900:38886,52901:36829,52902:26693,52903:22260,52904:21807,52905:24799,52906:20026,52907:28493,52908:32500,52909:33479,52910:33806,52911:22996,52912:20255,52913:20266,52914:23614,52915:32428,52916:26410,52917:34074,52918:21619,52919:30031,52920:32963,52921:21890,52922:39759,52923:20301,52924:28205,52925:35859,52926:23561,52927:24944,52928:21355,52929:30239,52930:28201,52931:34442,52932:25991,52933:38395,52934:32441,52935:21563,52936:31283,52937:32010,52938:38382,52939:21985,52940:32705,52941:29934,52942:25373,52943:34583,52944:28065,52945:31389,52946:25105,52947:26017,52948:21351,52949:25569,52950:27779,52951:24043,52952:21596,52953:38056,52954:20044,52955:27745,52956:35820,52957:23627,52958:26080,52959:33436,52960:26791,52961:21566,52962:21556,52963:27595,52964:27494,52965:20116,52966:25410,52967:21320,52968:33310,52969:20237,52970:20398,52971:22366,52972:25098,52973:38654,52974:26212,52975:29289,52976:21247,52977:21153,52978:24735,52979:35823,52980:26132,52981:29081,52982:26512,52983:35199,52984:30802,52985:30717,52986:26224,52987:22075,52988:21560,52989:38177,52990:29306,53056:34725,53057:34726,53058:34727,53059:34729,53060:34730,53061:34734,53062:34736,53063:34737,53064:34738,53065:34740,53066:34742,53067:34743,53068:34744,53069:34745,53070:34747,53071:34748,53072:34750,53073:34751,53074:34753,53075:34754,53076:34755,53077:34756,53078:34757,53079:34759,53080:34760,53081:34761,53082:34764,53083:34765,53084:34766,53085:34767,53086:34768,53087:34772,53088:34773,53089:34774,53090:34775,53091:34776,53092:34777,53093:34778,53094:34780,53095:34781,53096:34782,53097:34783,53098:34785,53099:34786,53100:34787,53101:34788,53102:34790,53103:34791,53104:34792,53105:34793,53106:34795,53107:34796,53108:34797,53109:34799,53110:34800,53111:34801,53112:34802,53113:34803,53114:34804,53115:34805,53116:34806,53117:34807,53118:34808,53120:34810,53121:34811,53122:34812,53123:34813,53124:34815,53125:34816,53126:34817,53127:34818,53128:34820,53129:34821,53130:34822,53131:34823,53132:34824,53133:34825,53134:34827,53135:34828,53136:34829,53137:34830,53138:34831,53139:34832,53140:34833,53141:34834,53142:34836,53143:34839,53144:34840,53145:34841,53146:34842,53147:34844,53148:34845,53149:34846,53150:34847,53151:34848,53152:34851,53153:31232,53154:24687,53155:24076,53156:24713,53157:33181,53158:22805,53159:24796,53160:29060,53161:28911,53162:28330,53163:27728,53164:29312,53165:27268,53166:34989,53167:24109,53168:20064,53169:23219,53170:21916,53171:38115,53172:27927,53173:31995,53174:38553,53175:25103,53176:32454,53177:30606,53178:34430,53179:21283,53180:38686,53181:36758,53182:26247,53183:23777,53184:20384,53185:29421,53186:19979,53187:21414,53188:22799,53189:21523,53190:25472,53191:38184,53192:20808,53193:20185,53194:40092,53195:32420,53196:21688,53197:36132,53198:34900,53199:33335,53200:38386,53201:28046,53202:24358,53203:23244,53204:26174,53205:38505,53206:29616,53207:29486,53208:21439,53209:33146,53210:39301,53211:32673,53212:23466,53213:38519,53214:38480,53215:32447,53216:30456,53217:21410,53218:38262,53219:39321,53220:31665,53221:35140,53222:28248,53223:20065,53224:32724,53225:31077,53226:35814,53227:24819,53228:21709,53229:20139,53230:39033,53231:24055,53232:27233,53233:20687,53234:21521,53235:35937,53236:33831,53237:30813,53238:38660,53239:21066,53240:21742,53241:22179,53242:38144,53243:28040,53244:23477,53245:28102,53246:26195,53312:34852,53313:34853,53314:34854,53315:34855,53316:34856,53317:34857,53318:34858,53319:34859,53320:34860,53321:34861,53322:34862,53323:34863,53324:34864,53325:34865,53326:34867,53327:34868,53328:34869,53329:34870,53330:34871,53331:34872,53332:34874,53333:34875,53334:34877,53335:34878,53336:34879,53337:34881,53338:34882,53339:34883,53340:34886,53341:34887,53342:34888,53343:34889,53344:34890,53345:34891,53346:34894,53347:34895,53348:34896,53349:34897,53350:34898,53351:34899,53352:34901,53353:34902,53354:34904,53355:34906,53356:34907,53357:34908,53358:34909,53359:34910,53360:34911,53361:34912,53362:34918,53363:34919,53364:34922,53365:34925,53366:34927,53367:34929,53368:34931,53369:34932,53370:34933,53371:34934,53372:34936,53373:34937,53374:34938,53376:34939,53377:34940,53378:34944,53379:34947,53380:34950,53381:34951,53382:34953,53383:34954,53384:34956,53385:34958,53386:34959,53387:34960,53388:34961,53389:34963,53390:34964,53391:34965,53392:34967,53393:34968,53394:34969,53395:34970,53396:34971,53397:34973,53398:34974,53399:34975,53400:34976,53401:34977,53402:34979,53403:34981,53404:34982,53405:34983,53406:34984,53407:34985,53408:34986,53409:23567,53410:23389,53411:26657,53412:32918,53413:21880,53414:31505,53415:25928,53416:26964,53417:20123,53418:27463,53419:34638,53420:38795,53421:21327,53422:25375,53423:25658,53424:37034,53425:26012,53426:32961,53427:35856,53428:20889,53429:26800,53430:21368,53431:34809,53432:25032,53433:27844,53434:27899,53435:35874,53436:23633,53437:34218,53438:33455,53439:38156,53440:27427,53441:36763,53442:26032,53443:24571,53444:24515,53445:20449,53446:34885,53447:26143,53448:33125,53449:29481,53450:24826,53451:20852,53452:21009,53453:22411,53454:24418,53455:37026,53456:34892,53457:37266,53458:24184,53459:26447,53460:24615,53461:22995,53462:20804,53463:20982,53464:33016,53465:21256,53466:27769,53467:38596,53468:29066,53469:20241,53470:20462,53471:32670,53472:26429,53473:21957,53474:38152,53475:31168,53476:34966,53477:32483,53478:22687,53479:25100,53480:38656,53481:34394,53482:22040,53483:39035,53484:24464,53485:35768,53486:33988,53487:37207,53488:21465,53489:26093,53490:24207,53491:30044,53492:24676,53493:32110,53494:23167,53495:32490,53496:32493,53497:36713,53498:21927,53499:23459,53500:24748,53501:26059,53502:29572,53568:34988,53569:34990,53570:34991,53571:34992,53572:34994,53573:34995,53574:34996,53575:34997,53576:34998,53577:35000,53578:35001,53579:35002,53580:35003,53581:35005,53582:35006,53583:35007,53584:35008,53585:35011,53586:35012,53587:35015,53588:35016,53589:35018,53590:35019,53591:35020,53592:35021,53593:35023,53594:35024,53595:35025,53596:35027,53597:35030,53598:35031,53599:35034,53600:35035,53601:35036,53602:35037,53603:35038,53604:35040,53605:35041,53606:35046,53607:35047,53608:35049,53609:35050,53610:35051,53611:35052,53612:35053,53613:35054,53614:35055,53615:35058,53616:35061,53617:35062,53618:35063,53619:35066,53620:35067,53621:35069,53622:35071,53623:35072,53624:35073,53625:35075,53626:35076,53627:35077,53628:35078,53629:35079,53630:35080,53632:35081,53633:35083,53634:35084,53635:35085,53636:35086,53637:35087,53638:35089,53639:35092,53640:35093,53641:35094,53642:35095,53643:35096,53644:35100,53645:35101,53646:35102,53647:35103,53648:35104,53649:35106,53650:35107,53651:35108,53652:35110,53653:35111,53654:35112,53655:35113,53656:35116,53657:35117,53658:35118,53659:35119,53660:35121,53661:35122,53662:35123,53663:35125,53664:35127,53665:36873,53666:30307,53667:30505,53668:32474,53669:38772,53670:34203,53671:23398,53672:31348,53673:38634,53674:34880,53675:21195,53676:29071,53677:24490,53678:26092,53679:35810,53680:23547,53681:39535,53682:24033,53683:27529,53684:27739,53685:35757,53686:35759,53687:36874,53688:36805,53689:21387,53690:25276,53691:40486,53692:40493,53693:21568,53694:20011,53695:33469,53696:29273,53697:34460,53698:23830,53699:34905,53700:28079,53701:38597,53702:21713,53703:20122,53704:35766,53705:28937,53706:21693,53707:38409,53708:28895,53709:28153,53710:30416,53711:20005,53712:30740,53713:34578,53714:23721,53715:24310,53716:35328,53717:39068,53718:38414,53719:28814,53720:27839,53721:22852,53722:25513,53723:30524,53724:34893,53725:28436,53726:33395,53727:22576,53728:29141,53729:21388,53730:30746,53731:38593,53732:21761,53733:24422,53734:28976,53735:23476,53736:35866,53737:39564,53738:27523,53739:22830,53740:40495,53741:31207,53742:26472,53743:25196,53744:20335,53745:30113,53746:32650,53747:27915,53748:38451,53749:27687,53750:20208,53751:30162,53752:20859,53753:26679,53754:28478,53755:36992,53756:33136,53757:22934,53758:29814,53824:35128,53825:35129,53826:35130,53827:35131,53828:35132,53829:35133,53830:35134,53831:35135,53832:35136,53833:35138,53834:35139,53835:35141,53836:35142,53837:35143,53838:35144,53839:35145,53840:35146,53841:35147,53842:35148,53843:35149,53844:35150,53845:35151,53846:35152,53847:35153,53848:35154,53849:35155,53850:35156,53851:35157,53852:35158,53853:35159,53854:35160,53855:35161,53856:35162,53857:35163,53858:35164,53859:35165,53860:35168,53861:35169,53862:35170,53863:35171,53864:35172,53865:35173,53866:35175,53867:35176,53868:35177,53869:35178,53870:35179,53871:35180,53872:35181,53873:35182,53874:35183,53875:35184,53876:35185,53877:35186,53878:35187,53879:35188,53880:35189,53881:35190,53882:35191,53883:35192,53884:35193,53885:35194,53886:35196,53888:35197,53889:35198,53890:35200,53891:35202,53892:35204,53893:35205,53894:35207,53895:35208,53896:35209,53897:35210,53898:35211,53899:35212,53900:35213,53901:35214,53902:35215,53903:35216,53904:35217,53905:35218,53906:35219,53907:35220,53908:35221,53909:35222,53910:35223,53911:35224,53912:35225,53913:35226,53914:35227,53915:35228,53916:35229,53917:35230,53918:35231,53919:35232,53920:35233,53921:25671,53922:23591,53923:36965,53924:31377,53925:35875,53926:23002,53927:21676,53928:33280,53929:33647,53930:35201,53931:32768,53932:26928,53933:22094,53934:32822,53935:29239,53936:37326,53937:20918,53938:20063,53939:39029,53940:25494,53941:19994,53942:21494,53943:26355,53944:33099,53945:22812,53946:28082,53947:19968,53948:22777,53949:21307,53950:25558,53951:38129,53952:20381,53953:20234,53954:34915,53955:39056,53956:22839,53957:36951,53958:31227,53959:20202,53960:33008,53961:30097,53962:27778,53963:23452,53964:23016,53965:24413,53966:26885,53967:34433,53968:20506,53969:24050,53970:20057,53971:30691,53972:20197,53973:33402,53974:25233,53975:26131,53976:37009,53977:23673,53978:20159,53979:24441,53980:33222,53981:36920,53982:32900,53983:30123,53984:20134,53985:35028,53986:24847,53987:27589,53988:24518,53989:20041,53990:30410,53991:28322,53992:35811,53993:35758,53994:35850,53995:35793,53996:24322,53997:32764,53998:32716,53999:32462,54000:33589,54001:33643,54002:22240,54003:27575,54004:38899,54005:38452,54006:23035,54007:21535,54008:38134,54009:28139,54010:23493,54011:39278,54012:23609,54013:24341,54014:38544,54080:35234,54081:35235,54082:35236,54083:35237,54084:35238,54085:35239,54086:35240,54087:35241,54088:35242,54089:35243,54090:35244,54091:35245,54092:35246,54093:35247,54094:35248,54095:35249,54096:35250,54097:35251,54098:35252,54099:35253,54100:35254,54101:35255,54102:35256,54103:35257,54104:35258,54105:35259,54106:35260,54107:35261,54108:35262,54109:35263,54110:35264,54111:35267,54112:35277,54113:35283,54114:35284,54115:35285,54116:35287,54117:35288,54118:35289,54119:35291,54120:35293,54121:35295,54122:35296,54123:35297,54124:35298,54125:35300,54126:35303,54127:35304,54128:35305,54129:35306,54130:35308,54131:35309,54132:35310,54133:35312,54134:35313,54135:35314,54136:35316,54137:35317,54138:35318,54139:35319,54140:35320,54141:35321,54142:35322,54144:35323,54145:35324,54146:35325,54147:35326,54148:35327,54149:35329,54150:35330,54151:35331,54152:35332,54153:35333,54154:35334,54155:35336,54156:35337,54157:35338,54158:35339,54159:35340,54160:35341,54161:35342,54162:35343,54163:35344,54164:35345,54165:35346,54166:35347,54167:35348,54168:35349,54169:35350,54170:35351,54171:35352,54172:35353,54173:35354,54174:35355,54175:35356,54176:35357,54177:21360,54178:33521,54179:27185,54180:23156,54181:40560,54182:24212,54183:32552,54184:33721,54185:33828,54186:33829,54187:33639,54188:34631,54189:36814,54190:36194,54191:30408,54192:24433,54193:39062,54194:30828,54195:26144,54196:21727,54197:25317,54198:20323,54199:33219,54200:30152,54201:24248,54202:38605,54203:36362,54204:34553,54205:21647,54206:27891,54207:28044,54208:27704,54209:24703,54210:21191,54211:29992,54212:24189,54213:20248,54214:24736,54215:24551,54216:23588,54217:30001,54218:37038,54219:38080,54220:29369,54221:27833,54222:28216,54223:37193,54224:26377,54225:21451,54226:21491,54227:20305,54228:37321,54229:35825,54230:21448,54231:24188,54232:36802,54233:28132,54234:20110,54235:30402,54236:27014,54237:34398,54238:24858,54239:33286,54240:20313,54241:20446,54242:36926,54243:40060,54244:24841,54245:28189,54246:28180,54247:38533,54248:20104,54249:23089,54250:38632,54251:19982,54252:23679,54253:31161,54254:23431,54255:35821,54256:32701,54257:29577,54258:22495,54259:33419,54260:37057,54261:21505,54262:36935,54263:21947,54264:23786,54265:24481,54266:24840,54267:27442,54268:29425,54269:32946,54270:35465,54336:35358,54337:35359,54338:35360,54339:35361,54340:35362,54341:35363,54342:35364,54343:35365,54344:35366,54345:35367,54346:35368,54347:35369,54348:35370,54349:35371,54350:35372,54351:35373,54352:35374,54353:35375,54354:35376,54355:35377,54356:35378,54357:35379,54358:35380,54359:35381,54360:35382,54361:35383,54362:35384,54363:35385,54364:35386,54365:35387,54366:35388,54367:35389,54368:35391,54369:35392,54370:35393,54371:35394,54372:35395,54373:35396,54374:35397,54375:35398,54376:35399,54377:35401,54378:35402,54379:35403,54380:35404,54381:35405,54382:35406,54383:35407,54384:35408,54385:35409,54386:35410,54387:35411,54388:35412,54389:35413,54390:35414,54391:35415,54392:35416,54393:35417,54394:35418,54395:35419,54396:35420,54397:35421,54398:35422,54400:35423,54401:35424,54402:35425,54403:35426,54404:35427,54405:35428,54406:35429,54407:35430,54408:35431,54409:35432,54410:35433,54411:35434,54412:35435,54413:35436,54414:35437,54415:35438,54416:35439,54417:35440,54418:35441,54419:35442,54420:35443,54421:35444,54422:35445,54423:35446,54424:35447,54425:35448,54426:35450,54427:35451,54428:35452,54429:35453,54430:35454,54431:35455,54432:35456,54433:28020,54434:23507,54435:35029,54436:39044,54437:35947,54438:39533,54439:40499,54440:28170,54441:20900,54442:20803,54443:22435,54444:34945,54445:21407,54446:25588,54447:36757,54448:22253,54449:21592,54450:22278,54451:29503,54452:28304,54453:32536,54454:36828,54455:33489,54456:24895,54457:24616,54458:38498,54459:26352,54460:32422,54461:36234,54462:36291,54463:38053,54464:23731,54465:31908,54466:26376,54467:24742,54468:38405,54469:32792,54470:20113,54471:37095,54472:21248,54473:38504,54474:20801,54475:36816,54476:34164,54477:37213,54478:26197,54479:38901,54480:23381,54481:21277,54482:30776,54483:26434,54484:26685,54485:21705,54486:28798,54487:23472,54488:36733,54489:20877,54490:22312,54491:21681,54492:25874,54493:26242,54494:36190,54495:36163,54496:33039,54497:33900,54498:36973,54499:31967,54500:20991,54501:34299,54502:26531,54503:26089,54504:28577,54505:34468,54506:36481,54507:22122,54508:36896,54509:30338,54510:28790,54511:29157,54512:36131,54513:25321,54514:21017,54515:27901,54516:36156,54517:24590,54518:22686,54519:24974,54520:26366,54521:36192,54522:25166,54523:21939,54524:28195,54525:26413,54526:36711,54592:35457,54593:35458,54594:35459,54595:35460,54596:35461,54597:35462,54598:35463,54599:35464,54600:35467,54601:35468,54602:35469,54603:35470,54604:35471,54605:35472,54606:35473,54607:35474,54608:35476,54609:35477,54610:35478,54611:35479,54612:35480,54613:35481,54614:35482,54615:35483,54616:35484,54617:35485,54618:35486,54619:35487,54620:35488,54621:35489,54622:35490,54623:35491,54624:35492,54625:35493,54626:35494,54627:35495,54628:35496,54629:35497,54630:35498,54631:35499,54632:35500,54633:35501,54634:35502,54635:35503,54636:35504,54637:35505,54638:35506,54639:35507,54640:35508,54641:35509,54642:35510,54643:35511,54644:35512,54645:35513,54646:35514,54647:35515,54648:35516,54649:35517,54650:35518,54651:35519,54652:35520,54653:35521,54654:35522,54656:35523,54657:35524,54658:35525,54659:35526,54660:35527,54661:35528,54662:35529,54663:35530,54664:35531,54665:35532,54666:35533,54667:35534,54668:35535,54669:35536,54670:35537,54671:35538,54672:35539,54673:35540,54674:35541,54675:35542,54676:35543,54677:35544,54678:35545,54679:35546,54680:35547,54681:35548,54682:35549,54683:35550,54684:35551,54685:35552,54686:35553,54687:35554,54688:35555,54689:38113,54690:38392,54691:30504,54692:26629,54693:27048,54694:21643,54695:20045,54696:28856,54697:35784,54698:25688,54699:25995,54700:23429,54701:31364,54702:20538,54703:23528,54704:30651,54705:27617,54706:35449,54707:31896,54708:27838,54709:30415,54710:26025,54711:36759,54712:23853,54713:23637,54714:34360,54715:26632,54716:21344,54717:25112,54718:31449,54719:28251,54720:32509,54721:27167,54722:31456,54723:24432,54724:28467,54725:24352,54726:25484,54727:28072,54728:26454,54729:19976,54730:24080,54731:36134,54732:20183,54733:32960,54734:30260,54735:38556,54736:25307,54737:26157,54738:25214,54739:27836,54740:36213,54741:29031,54742:32617,54743:20806,54744:32903,54745:21484,54746:36974,54747:25240,54748:21746,54749:34544,54750:36761,54751:32773,54752:38167,54753:34071,54754:36825,54755:27993,54756:29645,54757:26015,54758:30495,54759:29956,54760:30759,54761:33275,54762:36126,54763:38024,54764:20390,54765:26517,54766:30137,54767:35786,54768:38663,54769:25391,54770:38215,54771:38453,54772:33976,54773:25379,54774:30529,54775:24449,54776:29424,54777:20105,54778:24596,54779:25972,54780:25327,54781:27491,54782:25919,54848:35556,54849:35557,54850:35558,54851:35559,54852:35560,54853:35561,54854:35562,54855:35563,54856:35564,54857:35565,54858:35566,54859:35567,54860:35568,54861:35569,54862:35570,54863:35571,54864:35572,54865:35573,54866:35574,54867:35575,54868:35576,54869:35577,54870:35578,54871:35579,54872:35580,54873:35581,54874:35582,54875:35583,54876:35584,54877:35585,54878:35586,54879:35587,54880:35588,54881:35589,54882:35590,54883:35592,54884:35593,54885:35594,54886:35595,54887:35596,54888:35597,54889:35598,54890:35599,54891:35600,54892:35601,54893:35602,54894:35603,54895:35604,54896:35605,54897:35606,54898:35607,54899:35608,54900:35609,54901:35610,54902:35611,54903:35612,54904:35613,54905:35614,54906:35615,54907:35616,54908:35617,54909:35618,54910:35619,54912:35620,54913:35621,54914:35623,54915:35624,54916:35625,54917:35626,54918:35627,54919:35628,54920:35629,54921:35630,54922:35631,54923:35632,54924:35633,54925:35634,54926:35635,54927:35636,54928:35637,54929:35638,54930:35639,54931:35640,54932:35641,54933:35642,54934:35643,54935:35644,54936:35645,54937:35646,54938:35647,54939:35648,54940:35649,54941:35650,54942:35651,54943:35652,54944:35653,54945:24103,54946:30151,54947:37073,54948:35777,54949:33437,54950:26525,54951:25903,54952:21553,54953:34584,54954:30693,54955:32930,54956:33026,54957:27713,54958:20043,54959:32455,54960:32844,54961:30452,54962:26893,54963:27542,54964:25191,54965:20540,54966:20356,54967:22336,54968:25351,54969:27490,54970:36286,54971:21482,54972:26088,54973:32440,54974:24535,54975:25370,54976:25527,54977:33267,54978:33268,54979:32622,54980:24092,54981:23769,54982:21046,54983:26234,54984:31209,54985:31258,54986:36136,54987:28825,54988:30164,54989:28382,54990:27835,54991:31378,54992:20013,54993:30405,54994:24544,54995:38047,54996:34935,54997:32456,54998:31181,54999:32959,55000:37325,55001:20210,55002:20247,55003:33311,55004:21608,55005:24030,55006:27954,55007:35788,55008:31909,55009:36724,55010:32920,55011:24090,55012:21650,55013:30385,55014:23449,55015:26172,55016:39588,55017:29664,55018:26666,55019:34523,55020:26417,55021:29482,55022:35832,55023:35803,55024:36880,55025:31481,55026:28891,55027:29038,55028:25284,55029:30633,55030:22065,55031:20027,55032:33879,55033:26609,55034:21161,55035:34496,55036:36142,55037:38136,55038:31569,55104:35654,55105:35655,55106:35656,55107:35657,55108:35658,55109:35659,55110:35660,55111:35661,55112:35662,55113:35663,55114:35664,55115:35665,55116:35666,55117:35667,55118:35668,55119:35669,55120:35670,55121:35671,55122:35672,55123:35673,55124:35674,55125:35675,55126:35676,55127:35677,55128:35678,55129:35679,55130:35680,55131:35681,55132:35682,55133:35683,55134:35684,55135:35685,55136:35687,55137:35688,55138:35689,55139:35690,55140:35691,55141:35693,55142:35694,55143:35695,55144:35696,55145:35697,55146:35698,55147:35699,55148:35700,55149:35701,55150:35702,55151:35703,55152:35704,55153:35705,55154:35706,55155:35707,55156:35708,55157:35709,55158:35710,55159:35711,55160:35712,55161:35713,55162:35714,55163:35715,55164:35716,55165:35717,55166:35718,55168:35719,55169:35720,55170:35721,55171:35722,55172:35723,55173:35724,55174:35725,55175:35726,55176:35727,55177:35728,55178:35729,55179:35730,55180:35731,55181:35732,55182:35733,55183:35734,55184:35735,55185:35736,55186:35737,55187:35738,55188:35739,55189:35740,55190:35741,55191:35742,55192:35743,55193:35756,55194:35761,55195:35771,55196:35783,55197:35792,55198:35818,55199:35849,55200:35870,55201:20303,55202:27880,55203:31069,55204:39547,55205:25235,55206:29226,55207:25341,55208:19987,55209:30742,55210:36716,55211:25776,55212:36186,55213:31686,55214:26729,55215:24196,55216:35013,55217:22918,55218:25758,55219:22766,55220:29366,55221:26894,55222:38181,55223:36861,55224:36184,55225:22368,55226:32512,55227:35846,55228:20934,55229:25417,55230:25305,55231:21331,55232:26700,55233:29730,55234:33537,55235:37196,55236:21828,55237:30528,55238:28796,55239:27978,55240:20857,55241:21672,55242:36164,55243:23039,55244:28363,55245:28100,55246:23388,55247:32043,55248:20180,55249:31869,55250:28371,55251:23376,55252:33258,55253:28173,55254:23383,55255:39683,55256:26837,55257:36394,55258:23447,55259:32508,55260:24635,55261:32437,55262:37049,55263:36208,55264:22863,55265:25549,55266:31199,55267:36275,55268:21330,55269:26063,55270:31062,55271:35781,55272:38459,55273:32452,55274:38075,55275:32386,55276:22068,55277:37257,55278:26368,55279:32618,55280:23562,55281:36981,55282:26152,55283:24038,55284:20304,55285:26590,55286:20570,55287:20316,55288:22352,55289:24231,55290:59408,55291:59409,55292:59410,55293:59411,55294:59412,55360:35896,55361:35897,55362:35898,55363:35899,55364:35900,55365:35901,55366:35902,55367:35903,55368:35904,55369:35906,55370:35907,55371:35908,55372:35909,55373:35912,55374:35914,55375:35915,55376:35917,55377:35918,55378:35919,55379:35920,55380:35921,55381:35922,55382:35923,55383:35924,55384:35926,55385:35927,55386:35928,55387:35929,55388:35931,55389:35932,55390:35933,55391:35934,55392:35935,55393:35936,55394:35939,55395:35940,55396:35941,55397:35942,55398:35943,55399:35944,55400:35945,55401:35948,55402:35949,55403:35950,55404:35951,55405:35952,55406:35953,55407:35954,55408:35956,55409:35957,55410:35958,55411:35959,55412:35963,55413:35964,55414:35965,55415:35966,55416:35967,55417:35968,55418:35969,55419:35971,55420:35972,55421:35974,55422:35975,55424:35976,55425:35979,55426:35981,55427:35982,55428:35983,55429:35984,55430:35985,55431:35986,55432:35987,55433:35989,55434:35990,55435:35991,55436:35993,55437:35994,55438:35995,55439:35996,55440:35997,55441:35998,55442:35999,55443:36000,55444:36001,55445:36002,55446:36003,55447:36004,55448:36005,55449:36006,55450:36007,55451:36008,55452:36009,55453:36010,55454:36011,55455:36012,55456:36013,55457:20109,55458:19980,55459:20800,55460:19984,55461:24319,55462:21317,55463:19989,55464:20120,55465:19998,55466:39730,55467:23404,55468:22121,55469:20008,55470:31162,55471:20031,55472:21269,55473:20039,55474:22829,55475:29243,55476:21358,55477:27664,55478:22239,55479:32996,55480:39319,55481:27603,55482:30590,55483:40727,55484:20022,55485:20127,55486:40720,55487:20060,55488:20073,55489:20115,55490:33416,55491:23387,55492:21868,55493:22031,55494:20164,55495:21389,55496:21405,55497:21411,55498:21413,55499:21422,55500:38757,55501:36189,55502:21274,55503:21493,55504:21286,55505:21294,55506:21310,55507:36188,55508:21350,55509:21347,55510:20994,55511:21000,55512:21006,55513:21037,55514:21043,55515:21055,55516:21056,55517:21068,55518:21086,55519:21089,55520:21084,55521:33967,55522:21117,55523:21122,55524:21121,55525:21136,55526:21139,55527:20866,55528:32596,55529:20155,55530:20163,55531:20169,55532:20162,55533:20200,55534:20193,55535:20203,55536:20190,55537:20251,55538:20211,55539:20258,55540:20324,55541:20213,55542:20261,55543:20263,55544:20233,55545:20267,55546:20318,55547:20327,55548:25912,55549:20314,55550:20317,55616:36014,55617:36015,55618:36016,55619:36017,55620:36018,55621:36019,55622:36020,55623:36021,55624:36022,55625:36023,55626:36024,55627:36025,55628:36026,55629:36027,55630:36028,55631:36029,55632:36030,55633:36031,55634:36032,55635:36033,55636:36034,55637:36035,55638:36036,55639:36037,55640:36038,55641:36039,55642:36040,55643:36041,55644:36042,55645:36043,55646:36044,55647:36045,55648:36046,55649:36047,55650:36048,55651:36049,55652:36050,55653:36051,55654:36052,55655:36053,55656:36054,55657:36055,55658:36056,55659:36057,55660:36058,55661:36059,55662:36060,55663:36061,55664:36062,55665:36063,55666:36064,55667:36065,55668:36066,55669:36067,55670:36068,55671:36069,55672:36070,55673:36071,55674:36072,55675:36073,55676:36074,55677:36075,55678:36076,55680:36077,55681:36078,55682:36079,55683:36080,55684:36081,55685:36082,55686:36083,55687:36084,55688:36085,55689:36086,55690:36087,55691:36088,55692:36089,55693:36090,55694:36091,55695:36092,55696:36093,55697:36094,55698:36095,55699:36096,55700:36097,55701:36098,55702:36099,55703:36100,55704:36101,55705:36102,55706:36103,55707:36104,55708:36105,55709:36106,55710:36107,55711:36108,55712:36109,55713:20319,55714:20311,55715:20274,55716:20285,55717:20342,55718:20340,55719:20369,55720:20361,55721:20355,55722:20367,55723:20350,55724:20347,55725:20394,55726:20348,55727:20396,55728:20372,55729:20454,55730:20456,55731:20458,55732:20421,55733:20442,55734:20451,55735:20444,55736:20433,55737:20447,55738:20472,55739:20521,55740:20556,55741:20467,55742:20524,55743:20495,55744:20526,55745:20525,55746:20478,55747:20508,55748:20492,55749:20517,55750:20520,55751:20606,55752:20547,55753:20565,55754:20552,55755:20558,55756:20588,55757:20603,55758:20645,55759:20647,55760:20649,55761:20666,55762:20694,55763:20742,55764:20717,55765:20716,55766:20710,55767:20718,55768:20743,55769:20747,55770:20189,55771:27709,55772:20312,55773:20325,55774:20430,55775:40864,55776:27718,55777:31860,55778:20846,55779:24061,55780:40649,55781:39320,55782:20865,55783:22804,55784:21241,55785:21261,55786:35335,55787:21264,55788:20971,55789:22809,55790:20821,55791:20128,55792:20822,55793:20147,55794:34926,55795:34980,55796:20149,55797:33044,55798:35026,55799:31104,55800:23348,55801:34819,55802:32696,55803:20907,55804:20913,55805:20925,55806:20924,55872:36110,55873:36111,55874:36112,55875:36113,55876:36114,55877:36115,55878:36116,55879:36117,55880:36118,55881:36119,55882:36120,55883:36121,55884:36122,55885:36123,55886:36124,55887:36128,55888:36177,55889:36178,55890:36183,55891:36191,55892:36197,55893:36200,55894:36201,55895:36202,55896:36204,55897:36206,55898:36207,55899:36209,55900:36210,55901:36216,55902:36217,55903:36218,55904:36219,55905:36220,55906:36221,55907:36222,55908:36223,55909:36224,55910:36226,55911:36227,55912:36230,55913:36231,55914:36232,55915:36233,55916:36236,55917:36237,55918:36238,55919:36239,55920:36240,55921:36242,55922:36243,55923:36245,55924:36246,55925:36247,55926:36248,55927:36249,55928:36250,55929:36251,55930:36252,55931:36253,55932:36254,55933:36256,55934:36257,55936:36258,55937:36260,55938:36261,55939:36262,55940:36263,55941:36264,55942:36265,55943:36266,55944:36267,55945:36268,55946:36269,55947:36270,55948:36271,55949:36272,55950:36274,55951:36278,55952:36279,55953:36281,55954:36283,55955:36285,55956:36288,55957:36289,55958:36290,55959:36293,55960:36295,55961:36296,55962:36297,55963:36298,55964:36301,55965:36304,55966:36306,55967:36307,55968:36308,55969:20935,55970:20886,55971:20898,55972:20901,55973:35744,55974:35750,55975:35751,55976:35754,55977:35764,55978:35765,55979:35767,55980:35778,55981:35779,55982:35787,55983:35791,55984:35790,55985:35794,55986:35795,55987:35796,55988:35798,55989:35800,55990:35801,55991:35804,55992:35807,55993:35808,55994:35812,55995:35816,55996:35817,55997:35822,55998:35824,55999:35827,56000:35830,56001:35833,56002:35836,56003:35839,56004:35840,56005:35842,56006:35844,56007:35847,56008:35852,56009:35855,56010:35857,56011:35858,56012:35860,56013:35861,56014:35862,56015:35865,56016:35867,56017:35864,56018:35869,56019:35871,56020:35872,56021:35873,56022:35877,56023:35879,56024:35882,56025:35883,56026:35886,56027:35887,56028:35890,56029:35891,56030:35893,56031:35894,56032:21353,56033:21370,56034:38429,56035:38434,56036:38433,56037:38449,56038:38442,56039:38461,56040:38460,56041:38466,56042:38473,56043:38484,56044:38495,56045:38503,56046:38508,56047:38514,56048:38516,56049:38536,56050:38541,56051:38551,56052:38576,56053:37015,56054:37019,56055:37021,56056:37017,56057:37036,56058:37025,56059:37044,56060:37043,56061:37046,56062:37050,56128:36309,56129:36312,56130:36313,56131:36316,56132:36320,56133:36321,56134:36322,56135:36325,56136:36326,56137:36327,56138:36329,56139:36333,56140:36334,56141:36336,56142:36337,56143:36338,56144:36340,56145:36342,56146:36348,56147:36350,56148:36351,56149:36352,56150:36353,56151:36354,56152:36355,56153:36356,56154:36358,56155:36359,56156:36360,56157:36363,56158:36365,56159:36366,56160:36368,56161:36369,56162:36370,56163:36371,56164:36373,56165:36374,56166:36375,56167:36376,56168:36377,56169:36378,56170:36379,56171:36380,56172:36384,56173:36385,56174:36388,56175:36389,56176:36390,56177:36391,56178:36392,56179:36395,56180:36397,56181:36400,56182:36402,56183:36403,56184:36404,56185:36406,56186:36407,56187:36408,56188:36411,56189:36412,56190:36414,56192:36415,56193:36419,56194:36421,56195:36422,56196:36428,56197:36429,56198:36430,56199:36431,56200:36432,56201:36435,56202:36436,56203:36437,56204:36438,56205:36439,56206:36440,56207:36442,56208:36443,56209:36444,56210:36445,56211:36446,56212:36447,56213:36448,56214:36449,56215:36450,56216:36451,56217:36452,56218:36453,56219:36455,56220:36456,56221:36458,56222:36459,56223:36462,56224:36465,56225:37048,56226:37040,56227:37071,56228:37061,56229:37054,56230:37072,56231:37060,56232:37063,56233:37075,56234:37094,56235:37090,56236:37084,56237:37079,56238:37083,56239:37099,56240:37103,56241:37118,56242:37124,56243:37154,56244:37150,56245:37155,56246:37169,56247:37167,56248:37177,56249:37187,56250:37190,56251:21005,56252:22850,56253:21154,56254:21164,56255:21165,56256:21182,56257:21759,56258:21200,56259:21206,56260:21232,56261:21471,56262:29166,56263:30669,56264:24308,56265:20981,56266:20988,56267:39727,56268:21430,56269:24321,56270:30042,56271:24047,56272:22348,56273:22441,56274:22433,56275:22654,56276:22716,56277:22725,56278:22737,56279:22313,56280:22316,56281:22314,56282:22323,56283:22329,56284:22318,56285:22319,56286:22364,56287:22331,56288:22338,56289:22377,56290:22405,56291:22379,56292:22406,56293:22396,56294:22395,56295:22376,56296:22381,56297:22390,56298:22387,56299:22445,56300:22436,56301:22412,56302:22450,56303:22479,56304:22439,56305:22452,56306:22419,56307:22432,56308:22485,56309:22488,56310:22490,56311:22489,56312:22482,56313:22456,56314:22516,56315:22511,56316:22520,56317:22500,56318:22493,56384:36467,56385:36469,56386:36471,56387:36472,56388:36473,56389:36474,56390:36475,56391:36477,56392:36478,56393:36480,56394:36482,56395:36483,56396:36484,56397:36486,56398:36488,56399:36489,56400:36490,56401:36491,56402:36492,56403:36493,56404:36494,56405:36497,56406:36498,56407:36499,56408:36501,56409:36502,56410:36503,56411:36504,56412:36505,56413:36506,56414:36507,56415:36509,56416:36511,56417:36512,56418:36513,56419:36514,56420:36515,56421:36516,56422:36517,56423:36518,56424:36519,56425:36520,56426:36521,56427:36522,56428:36525,56429:36526,56430:36528,56431:36529,56432:36531,56433:36532,56434:36533,56435:36534,56436:36535,56437:36536,56438:36537,56439:36539,56440:36540,56441:36541,56442:36542,56443:36543,56444:36544,56445:36545,56446:36546,56448:36547,56449:36548,56450:36549,56451:36550,56452:36551,56453:36552,56454:36553,56455:36554,56456:36555,56457:36556,56458:36557,56459:36559,56460:36560,56461:36561,56462:36562,56463:36563,56464:36564,56465:36565,56466:36566,56467:36567,56468:36568,56469:36569,56470:36570,56471:36571,56472:36572,56473:36573,56474:36574,56475:36575,56476:36576,56477:36577,56478:36578,56479:36579,56480:36580,56481:22539,56482:22541,56483:22525,56484:22509,56485:22528,56486:22558,56487:22553,56488:22596,56489:22560,56490:22629,56491:22636,56492:22657,56493:22665,56494:22682,56495:22656,56496:39336,56497:40729,56498:25087,56499:33401,56500:33405,56501:33407,56502:33423,56503:33418,56504:33448,56505:33412,56506:33422,56507:33425,56508:33431,56509:33433,56510:33451,56511:33464,56512:33470,56513:33456,56514:33480,56515:33482,56516:33507,56517:33432,56518:33463,56519:33454,56520:33483,56521:33484,56522:33473,56523:33449,56524:33460,56525:33441,56526:33450,56527:33439,56528:33476,56529:33486,56530:33444,56531:33505,56532:33545,56533:33527,56534:33508,56535:33551,56536:33543,56537:33500,56538:33524,56539:33490,56540:33496,56541:33548,56542:33531,56543:33491,56544:33553,56545:33562,56546:33542,56547:33556,56548:33557,56549:33504,56550:33493,56551:33564,56552:33617,56553:33627,56554:33628,56555:33544,56556:33682,56557:33596,56558:33588,56559:33585,56560:33691,56561:33630,56562:33583,56563:33615,56564:33607,56565:33603,56566:33631,56567:33600,56568:33559,56569:33632,56570:33581,56571:33594,56572:33587,56573:33638,56574:33637,56640:36581,56641:36582,56642:36583,56643:36584,56644:36585,56645:36586,56646:36587,56647:36588,56648:36589,56649:36590,56650:36591,56651:36592,56652:36593,56653:36594,56654:36595,56655:36596,56656:36597,56657:36598,56658:36599,56659:36600,56660:36601,56661:36602,56662:36603,56663:36604,56664:36605,56665:36606,56666:36607,56667:36608,56668:36609,56669:36610,56670:36611,56671:36612,56672:36613,56673:36614,56674:36615,56675:36616,56676:36617,56677:36618,56678:36619,56679:36620,56680:36621,56681:36622,56682:36623,56683:36624,56684:36625,56685:36626,56686:36627,56687:36628,56688:36629,56689:36630,56690:36631,56691:36632,56692:36633,56693:36634,56694:36635,56695:36636,56696:36637,56697:36638,56698:36639,56699:36640,56700:36641,56701:36642,56702:36643,56704:36644,56705:36645,56706:36646,56707:36647,56708:36648,56709:36649,56710:36650,56711:36651,56712:36652,56713:36653,56714:36654,56715:36655,56716:36656,56717:36657,56718:36658,56719:36659,56720:36660,56721:36661,56722:36662,56723:36663,56724:36664,56725:36665,56726:36666,56727:36667,56728:36668,56729:36669,56730:36670,56731:36671,56732:36672,56733:36673,56734:36674,56735:36675,56736:36676,56737:33640,56738:33563,56739:33641,56740:33644,56741:33642,56742:33645,56743:33646,56744:33712,56745:33656,56746:33715,56747:33716,56748:33696,56749:33706,56750:33683,56751:33692,56752:33669,56753:33660,56754:33718,56755:33705,56756:33661,56757:33720,56758:33659,56759:33688,56760:33694,56761:33704,56762:33722,56763:33724,56764:33729,56765:33793,56766:33765,56767:33752,56768:22535,56769:33816,56770:33803,56771:33757,56772:33789,56773:33750,56774:33820,56775:33848,56776:33809,56777:33798,56778:33748,56779:33759,56780:33807,56781:33795,56782:33784,56783:33785,56784:33770,56785:33733,56786:33728,56787:33830,56788:33776,56789:33761,56790:33884,56791:33873,56792:33882,56793:33881,56794:33907,56795:33927,56796:33928,56797:33914,56798:33929,56799:33912,56800:33852,56801:33862,56802:33897,56803:33910,56804:33932,56805:33934,56806:33841,56807:33901,56808:33985,56809:33997,56810:34000,56811:34022,56812:33981,56813:34003,56814:33994,56815:33983,56816:33978,56817:34016,56818:33953,56819:33977,56820:33972,56821:33943,56822:34021,56823:34019,56824:34060,56825:29965,56826:34104,56827:34032,56828:34105,56829:34079,56830:34106,56896:36677,56897:36678,56898:36679,56899:36680,56900:36681,56901:36682,56902:36683,56903:36684,56904:36685,56905:36686,56906:36687,56907:36688,56908:36689,56909:36690,56910:36691,56911:36692,56912:36693,56913:36694,56914:36695,56915:36696,56916:36697,56917:36698,56918:36699,56919:36700,56920:36701,56921:36702,56922:36703,56923:36704,56924:36705,56925:36706,56926:36707,56927:36708,56928:36709,56929:36714,56930:36736,56931:36748,56932:36754,56933:36765,56934:36768,56935:36769,56936:36770,56937:36772,56938:36773,56939:36774,56940:36775,56941:36778,56942:36780,56943:36781,56944:36782,56945:36783,56946:36786,56947:36787,56948:36788,56949:36789,56950:36791,56951:36792,56952:36794,56953:36795,56954:36796,56955:36799,56956:36800,56957:36803,56958:36806,56960:36809,56961:36810,56962:36811,56963:36812,56964:36813,56965:36815,56966:36818,56967:36822,56968:36823,56969:36826,56970:36832,56971:36833,56972:36835,56973:36839,56974:36844,56975:36847,56976:36849,56977:36850,56978:36852,56979:36853,56980:36854,56981:36858,56982:36859,56983:36860,56984:36862,56985:36863,56986:36871,56987:36872,56988:36876,56989:36878,56990:36883,56991:36885,56992:36888,56993:34134,56994:34107,56995:34047,56996:34044,56997:34137,56998:34120,56999:34152,57000:34148,57001:34142,57002:34170,57003:30626,57004:34115,57005:34162,57006:34171,57007:34212,57008:34216,57009:34183,57010:34191,57011:34169,57012:34222,57013:34204,57014:34181,57015:34233,57016:34231,57017:34224,57018:34259,57019:34241,57020:34268,57021:34303,57022:34343,57023:34309,57024:34345,57025:34326,57026:34364,57027:24318,57028:24328,57029:22844,57030:22849,57031:32823,57032:22869,57033:22874,57034:22872,57035:21263,57036:23586,57037:23589,57038:23596,57039:23604,57040:25164,57041:25194,57042:25247,57043:25275,57044:25290,57045:25306,57046:25303,57047:25326,57048:25378,57049:25334,57050:25401,57051:25419,57052:25411,57053:25517,57054:25590,57055:25457,57056:25466,57057:25486,57058:25524,57059:25453,57060:25516,57061:25482,57062:25449,57063:25518,57064:25532,57065:25586,57066:25592,57067:25568,57068:25599,57069:25540,57070:25566,57071:25550,57072:25682,57073:25542,57074:25534,57075:25669,57076:25665,57077:25611,57078:25627,57079:25632,57080:25612,57081:25638,57082:25633,57083:25694,57084:25732,57085:25709,57086:25750,57152:36889,57153:36892,57154:36899,57155:36900,57156:36901,57157:36903,57158:36904,57159:36905,57160:36906,57161:36907,57162:36908,57163:36912,57164:36913,57165:36914,57166:36915,57167:36916,57168:36919,57169:36921,57170:36922,57171:36925,57172:36927,57173:36928,57174:36931,57175:36933,57176:36934,57177:36936,57178:36937,57179:36938,57180:36939,57181:36940,57182:36942,57183:36948,57184:36949,57185:36950,57186:36953,57187:36954,57188:36956,57189:36957,57190:36958,57191:36959,57192:36960,57193:36961,57194:36964,57195:36966,57196:36967,57197:36969,57198:36970,57199:36971,57200:36972,57201:36975,57202:36976,57203:36977,57204:36978,57205:36979,57206:36982,57207:36983,57208:36984,57209:36985,57210:36986,57211:36987,57212:36988,57213:36990,57214:36993,57216:36996,57217:36997,57218:36998,57219:36999,57220:37001,57221:37002,57222:37004,57223:37005,57224:37006,57225:37007,57226:37008,57227:37010,57228:37012,57229:37014,57230:37016,57231:37018,57232:37020,57233:37022,57234:37023,57235:37024,57236:37028,57237:37029,57238:37031,57239:37032,57240:37033,57241:37035,57242:37037,57243:37042,57244:37047,57245:37052,57246:37053,57247:37055,57248:37056,57249:25722,57250:25783,57251:25784,57252:25753,57253:25786,57254:25792,57255:25808,57256:25815,57257:25828,57258:25826,57259:25865,57260:25893,57261:25902,57262:24331,57263:24530,57264:29977,57265:24337,57266:21343,57267:21489,57268:21501,57269:21481,57270:21480,57271:21499,57272:21522,57273:21526,57274:21510,57275:21579,57276:21586,57277:21587,57278:21588,57279:21590,57280:21571,57281:21537,57282:21591,57283:21593,57284:21539,57285:21554,57286:21634,57287:21652,57288:21623,57289:21617,57290:21604,57291:21658,57292:21659,57293:21636,57294:21622,57295:21606,57296:21661,57297:21712,57298:21677,57299:21698,57300:21684,57301:21714,57302:21671,57303:21670,57304:21715,57305:21716,57306:21618,57307:21667,57308:21717,57309:21691,57310:21695,57311:21708,57312:21721,57313:21722,57314:21724,57315:21673,57316:21674,57317:21668,57318:21725,57319:21711,57320:21726,57321:21787,57322:21735,57323:21792,57324:21757,57325:21780,57326:21747,57327:21794,57328:21795,57329:21775,57330:21777,57331:21799,57332:21802,57333:21863,57334:21903,57335:21941,57336:21833,57337:21869,57338:21825,57339:21845,57340:21823,57341:21840,57342:21820,57408:37058,57409:37059,57410:37062,57411:37064,57412:37065,57413:37067,57414:37068,57415:37069,57416:37074,57417:37076,57418:37077,57419:37078,57420:37080,57421:37081,57422:37082,57423:37086,57424:37087,57425:37088,57426:37091,57427:37092,57428:37093,57429:37097,57430:37098,57431:37100,57432:37102,57433:37104,57434:37105,57435:37106,57436:37107,57437:37109,57438:37110,57439:37111,57440:37113,57441:37114,57442:37115,57443:37116,57444:37119,57445:37120,57446:37121,57447:37123,57448:37125,57449:37126,57450:37127,57451:37128,57452:37129,57453:37130,57454:37131,57455:37132,57456:37133,57457:37134,57458:37135,57459:37136,57460:37137,57461:37138,57462:37139,57463:37140,57464:37141,57465:37142,57466:37143,57467:37144,57468:37146,57469:37147,57470:37148,57472:37149,57473:37151,57474:37152,57475:37153,57476:37156,57477:37157,57478:37158,57479:37159,57480:37160,57481:37161,57482:37162,57483:37163,57484:37164,57485:37165,57486:37166,57487:37168,57488:37170,57489:37171,57490:37172,57491:37173,57492:37174,57493:37175,57494:37176,57495:37178,57496:37179,57497:37180,57498:37181,57499:37182,57500:37183,57501:37184,57502:37185,57503:37186,57504:37188,57505:21815,57506:21846,57507:21877,57508:21878,57509:21879,57510:21811,57511:21808,57512:21852,57513:21899,57514:21970,57515:21891,57516:21937,57517:21945,57518:21896,57519:21889,57520:21919,57521:21886,57522:21974,57523:21905,57524:21883,57525:21983,57526:21949,57527:21950,57528:21908,57529:21913,57530:21994,57531:22007,57532:21961,57533:22047,57534:21969,57535:21995,57536:21996,57537:21972,57538:21990,57539:21981,57540:21956,57541:21999,57542:21989,57543:22002,57544:22003,57545:21964,57546:21965,57547:21992,57548:22005,57549:21988,57550:36756,57551:22046,57552:22024,57553:22028,57554:22017,57555:22052,57556:22051,57557:22014,57558:22016,57559:22055,57560:22061,57561:22104,57562:22073,57563:22103,57564:22060,57565:22093,57566:22114,57567:22105,57568:22108,57569:22092,57570:22100,57571:22150,57572:22116,57573:22129,57574:22123,57575:22139,57576:22140,57577:22149,57578:22163,57579:22191,57580:22228,57581:22231,57582:22237,57583:22241,57584:22261,57585:22251,57586:22265,57587:22271,57588:22276,57589:22282,57590:22281,57591:22300,57592:24079,57593:24089,57594:24084,57595:24081,57596:24113,57597:24123,57598:24124,57664:37189,57665:37191,57666:37192,57667:37201,57668:37203,57669:37204,57670:37205,57671:37206,57672:37208,57673:37209,57674:37211,57675:37212,57676:37215,57677:37216,57678:37222,57679:37223,57680:37224,57681:37227,57682:37229,57683:37235,57684:37242,57685:37243,57686:37244,57687:37248,57688:37249,57689:37250,57690:37251,57691:37252,57692:37254,57693:37256,57694:37258,57695:37262,57696:37263,57697:37267,57698:37268,57699:37269,57700:37270,57701:37271,57702:37272,57703:37273,57704:37276,57705:37277,57706:37278,57707:37279,57708:37280,57709:37281,57710:37284,57711:37285,57712:37286,57713:37287,57714:37288,57715:37289,57716:37291,57717:37292,57718:37296,57719:37297,57720:37298,57721:37299,57722:37302,57723:37303,57724:37304,57725:37305,57726:37307,57728:37308,57729:37309,57730:37310,57731:37311,57732:37312,57733:37313,57734:37314,57735:37315,57736:37316,57737:37317,57738:37318,57739:37320,57740:37323,57741:37328,57742:37330,57743:37331,57744:37332,57745:37333,57746:37334,57747:37335,57748:37336,57749:37337,57750:37338,57751:37339,57752:37341,57753:37342,57754:37343,57755:37344,57756:37345,57757:37346,57758:37347,57759:37348,57760:37349,57761:24119,57762:24132,57763:24148,57764:24155,57765:24158,57766:24161,57767:23692,57768:23674,57769:23693,57770:23696,57771:23702,57772:23688,57773:23704,57774:23705,57775:23697,57776:23706,57777:23708,57778:23733,57779:23714,57780:23741,57781:23724,57782:23723,57783:23729,57784:23715,57785:23745,57786:23735,57787:23748,57788:23762,57789:23780,57790:23755,57791:23781,57792:23810,57793:23811,57794:23847,57795:23846,57796:23854,57797:23844,57798:23838,57799:23814,57800:23835,57801:23896,57802:23870,57803:23860,57804:23869,57805:23916,57806:23899,57807:23919,57808:23901,57809:23915,57810:23883,57811:23882,57812:23913,57813:23924,57814:23938,57815:23961,57816:23965,57817:35955,57818:23991,57819:24005,57820:24435,57821:24439,57822:24450,57823:24455,57824:24457,57825:24460,57826:24469,57827:24473,57828:24476,57829:24488,57830:24493,57831:24501,57832:24508,57833:34914,57834:24417,57835:29357,57836:29360,57837:29364,57838:29367,57839:29368,57840:29379,57841:29377,57842:29390,57843:29389,57844:29394,57845:29416,57846:29423,57847:29417,57848:29426,57849:29428,57850:29431,57851:29441,57852:29427,57853:29443,57854:29434,57920:37350,57921:37351,57922:37352,57923:37353,57924:37354,57925:37355,57926:37356,57927:37357,57928:37358,57929:37359,57930:37360,57931:37361,57932:37362,57933:37363,57934:37364,57935:37365,57936:37366,57937:37367,57938:37368,57939:37369,57940:37370,57941:37371,57942:37372,57943:37373,57944:37374,57945:37375,57946:37376,57947:37377,57948:37378,57949:37379,57950:37380,57951:37381,57952:37382,57953:37383,57954:37384,57955:37385,57956:37386,57957:37387,57958:37388,57959:37389,57960:37390,57961:37391,57962:37392,57963:37393,57964:37394,57965:37395,57966:37396,57967:37397,57968:37398,57969:37399,57970:37400,57971:37401,57972:37402,57973:37403,57974:37404,57975:37405,57976:37406,57977:37407,57978:37408,57979:37409,57980:37410,57981:37411,57982:37412,57984:37413,57985:37414,57986:37415,57987:37416,57988:37417,57989:37418,57990:37419,57991:37420,57992:37421,57993:37422,57994:37423,57995:37424,57996:37425,57997:37426,57998:37427,57999:37428,58000:37429,58001:37430,58002:37431,58003:37432,58004:37433,58005:37434,58006:37435,58007:37436,58008:37437,58009:37438,58010:37439,58011:37440,58012:37441,58013:37442,58014:37443,58015:37444,58016:37445,58017:29435,58018:29463,58019:29459,58020:29473,58021:29450,58022:29470,58023:29469,58024:29461,58025:29474,58026:29497,58027:29477,58028:29484,58029:29496,58030:29489,58031:29520,58032:29517,58033:29527,58034:29536,58035:29548,58036:29551,58037:29566,58038:33307,58039:22821,58040:39143,58041:22820,58042:22786,58043:39267,58044:39271,58045:39272,58046:39273,58047:39274,58048:39275,58049:39276,58050:39284,58051:39287,58052:39293,58053:39296,58054:39300,58055:39303,58056:39306,58057:39309,58058:39312,58059:39313,58060:39315,58061:39316,58062:39317,58063:24192,58064:24209,58065:24203,58066:24214,58067:24229,58068:24224,58069:24249,58070:24245,58071:24254,58072:24243,58073:36179,58074:24274,58075:24273,58076:24283,58077:24296,58078:24298,58079:33210,58080:24516,58081:24521,58082:24534,58083:24527,58084:24579,58085:24558,58086:24580,58087:24545,58088:24548,58089:24574,58090:24581,58091:24582,58092:24554,58093:24557,58094:24568,58095:24601,58096:24629,58097:24614,58098:24603,58099:24591,58100:24589,58101:24617,58102:24619,58103:24586,58104:24639,58105:24609,58106:24696,58107:24697,58108:24699,58109:24698,58110:24642,58176:37446,58177:37447,58178:37448,58179:37449,58180:37450,58181:37451,58182:37452,58183:37453,58184:37454,58185:37455,58186:37456,58187:37457,58188:37458,58189:37459,58190:37460,58191:37461,58192:37462,58193:37463,58194:37464,58195:37465,58196:37466,58197:37467,58198:37468,58199:37469,58200:37470,58201:37471,58202:37472,58203:37473,58204:37474,58205:37475,58206:37476,58207:37477,58208:37478,58209:37479,58210:37480,58211:37481,58212:37482,58213:37483,58214:37484,58215:37485,58216:37486,58217:37487,58218:37488,58219:37489,58220:37490,58221:37491,58222:37493,58223:37494,58224:37495,58225:37496,58226:37497,58227:37498,58228:37499,58229:37500,58230:37501,58231:37502,58232:37503,58233:37504,58234:37505,58235:37506,58236:37507,58237:37508,58238:37509,58240:37510,58241:37511,58242:37512,58243:37513,58244:37514,58245:37515,58246:37516,58247:37517,58248:37519,58249:37520,58250:37521,58251:37522,58252:37523,58253:37524,58254:37525,58255:37526,58256:37527,58257:37528,58258:37529,58259:37530,58260:37531,58261:37532,58262:37533,58263:37534,58264:37535,58265:37536,58266:37537,58267:37538,58268:37539,58269:37540,58270:37541,58271:37542,58272:37543,58273:24682,58274:24701,58275:24726,58276:24730,58277:24749,58278:24733,58279:24707,58280:24722,58281:24716,58282:24731,58283:24812,58284:24763,58285:24753,58286:24797,58287:24792,58288:24774,58289:24794,58290:24756,58291:24864,58292:24870,58293:24853,58294:24867,58295:24820,58296:24832,58297:24846,58298:24875,58299:24906,58300:24949,58301:25004,58302:24980,58303:24999,58304:25015,58305:25044,58306:25077,58307:24541,58308:38579,58309:38377,58310:38379,58311:38385,58312:38387,58313:38389,58314:38390,58315:38396,58316:38398,58317:38403,58318:38404,58319:38406,58320:38408,58321:38410,58322:38411,58323:38412,58324:38413,58325:38415,58326:38418,58327:38421,58328:38422,58329:38423,58330:38425,58331:38426,58332:20012,58333:29247,58334:25109,58335:27701,58336:27732,58337:27740,58338:27722,58339:27811,58340:27781,58341:27792,58342:27796,58343:27788,58344:27752,58345:27753,58346:27764,58347:27766,58348:27782,58349:27817,58350:27856,58351:27860,58352:27821,58353:27895,58354:27896,58355:27889,58356:27863,58357:27826,58358:27872,58359:27862,58360:27898,58361:27883,58362:27886,58363:27825,58364:27859,58365:27887,58366:27902,58432:37544,58433:37545,58434:37546,58435:37547,58436:37548,58437:37549,58438:37551,58439:37552,58440:37553,58441:37554,58442:37555,58443:37556,58444:37557,58445:37558,58446:37559,58447:37560,58448:37561,58449:37562,58450:37563,58451:37564,58452:37565,58453:37566,58454:37567,58455:37568,58456:37569,58457:37570,58458:37571,58459:37572,58460:37573,58461:37574,58462:37575,58463:37577,58464:37578,58465:37579,58466:37580,58467:37581,58468:37582,58469:37583,58470:37584,58471:37585,58472:37586,58473:37587,58474:37588,58475:37589,58476:37590,58477:37591,58478:37592,58479:37593,58480:37594,58481:37595,58482:37596,58483:37597,58484:37598,58485:37599,58486:37600,58487:37601,58488:37602,58489:37603,58490:37604,58491:37605,58492:37606,58493:37607,58494:37608,58496:37609,58497:37610,58498:37611,58499:37612,58500:37613,58501:37614,58502:37615,58503:37616,58504:37617,58505:37618,58506:37619,58507:37620,58508:37621,58509:37622,58510:37623,58511:37624,58512:37625,58513:37626,58514:37627,58515:37628,58516:37629,58517:37630,58518:37631,58519:37632,58520:37633,58521:37634,58522:37635,58523:37636,58524:37637,58525:37638,58526:37639,58527:37640,58528:37641,58529:27961,58530:27943,58531:27916,58532:27971,58533:27976,58534:27911,58535:27908,58536:27929,58537:27918,58538:27947,58539:27981,58540:27950,58541:27957,58542:27930,58543:27983,58544:27986,58545:27988,58546:27955,58547:28049,58548:28015,58549:28062,58550:28064,58551:27998,58552:28051,58553:28052,58554:27996,58555:28000,58556:28028,58557:28003,58558:28186,58559:28103,58560:28101,58561:28126,58562:28174,58563:28095,58564:28128,58565:28177,58566:28134,58567:28125,58568:28121,58569:28182,58570:28075,58571:28172,58572:28078,58573:28203,58574:28270,58575:28238,58576:28267,58577:28338,58578:28255,58579:28294,58580:28243,58581:28244,58582:28210,58583:28197,58584:28228,58585:28383,58586:28337,58587:28312,58588:28384,58589:28461,58590:28386,58591:28325,58592:28327,58593:28349,58594:28347,58595:28343,58596:28375,58597:28340,58598:28367,58599:28303,58600:28354,58601:28319,58602:28514,58603:28486,58604:28487,58605:28452,58606:28437,58607:28409,58608:28463,58609:28470,58610:28491,58611:28532,58612:28458,58613:28425,58614:28457,58615:28553,58616:28557,58617:28556,58618:28536,58619:28530,58620:28540,58621:28538,58622:28625,58688:37642,58689:37643,58690:37644,58691:37645,58692:37646,58693:37647,58694:37648,58695:37649,58696:37650,58697:37651,58698:37652,58699:37653,58700:37654,58701:37655,58702:37656,58703:37657,58704:37658,58705:37659,58706:37660,58707:37661,58708:37662,58709:37663,58710:37664,58711:37665,58712:37666,58713:37667,58714:37668,58715:37669,58716:37670,58717:37671,58718:37672,58719:37673,58720:37674,58721:37675,58722:37676,58723:37677,58724:37678,58725:37679,58726:37680,58727:37681,58728:37682,58729:37683,58730:37684,58731:37685,58732:37686,58733:37687,58734:37688,58735:37689,58736:37690,58737:37691,58738:37692,58739:37693,58740:37695,58741:37696,58742:37697,58743:37698,58744:37699,58745:37700,58746:37701,58747:37702,58748:37703,58749:37704,58750:37705,58752:37706,58753:37707,58754:37708,58755:37709,58756:37710,58757:37711,58758:37712,58759:37713,58760:37714,58761:37715,58762:37716,58763:37717,58764:37718,58765:37719,58766:37720,58767:37721,58768:37722,58769:37723,58770:37724,58771:37725,58772:37726,58773:37727,58774:37728,58775:37729,58776:37730,58777:37731,58778:37732,58779:37733,58780:37734,58781:37735,58782:37736,58783:37737,58784:37739,58785:28617,58786:28583,58787:28601,58788:28598,58789:28610,58790:28641,58791:28654,58792:28638,58793:28640,58794:28655,58795:28698,58796:28707,58797:28699,58798:28729,58799:28725,58800:28751,58801:28766,58802:23424,58803:23428,58804:23445,58805:23443,58806:23461,58807:23480,58808:29999,58809:39582,58810:25652,58811:23524,58812:23534,58813:35120,58814:23536,58815:36423,58816:35591,58817:36790,58818:36819,58819:36821,58820:36837,58821:36846,58822:36836,58823:36841,58824:36838,58825:36851,58826:36840,58827:36869,58828:36868,58829:36875,58830:36902,58831:36881,58832:36877,58833:36886,58834:36897,58835:36917,58836:36918,58837:36909,58838:36911,58839:36932,58840:36945,58841:36946,58842:36944,58843:36968,58844:36952,58845:36962,58846:36955,58847:26297,58848:36980,58849:36989,58850:36994,58851:37000,58852:36995,58853:37003,58854:24400,58855:24407,58856:24406,58857:24408,58858:23611,58859:21675,58860:23632,58861:23641,58862:23409,58863:23651,58864:23654,58865:32700,58866:24362,58867:24361,58868:24365,58869:33396,58870:24380,58871:39739,58872:23662,58873:22913,58874:22915,58875:22925,58876:22953,58877:22954,58878:22947,58944:37740,58945:37741,58946:37742,58947:37743,58948:37744,58949:37745,58950:37746,58951:37747,58952:37748,58953:37749,58954:37750,58955:37751,58956:37752,58957:37753,58958:37754,58959:37755,58960:37756,58961:37757,58962:37758,58963:37759,58964:37760,58965:37761,58966:37762,58967:37763,58968:37764,58969:37765,58970:37766,58971:37767,58972:37768,58973:37769,58974:37770,58975:37771,58976:37772,58977:37773,58978:37774,58979:37776,58980:37777,58981:37778,58982:37779,58983:37780,58984:37781,58985:37782,58986:37783,58987:37784,58988:37785,58989:37786,58990:37787,58991:37788,58992:37789,58993:37790,58994:37791,58995:37792,58996:37793,58997:37794,58998:37795,58999:37796,59000:37797,59001:37798,59002:37799,59003:37800,59004:37801,59005:37802,59006:37803,59008:37804,59009:37805,59010:37806,59011:37807,59012:37808,59013:37809,59014:37810,59015:37811,59016:37812,59017:37813,59018:37814,59019:37815,59020:37816,59021:37817,59022:37818,59023:37819,59024:37820,59025:37821,59026:37822,59027:37823,59028:37824,59029:37825,59030:37826,59031:37827,59032:37828,59033:37829,59034:37830,59035:37831,59036:37832,59037:37833,59038:37835,59039:37836,59040:37837,59041:22935,59042:22986,59043:22955,59044:22942,59045:22948,59046:22994,59047:22962,59048:22959,59049:22999,59050:22974,59051:23045,59052:23046,59053:23005,59054:23048,59055:23011,59056:23000,59057:23033,59058:23052,59059:23049,59060:23090,59061:23092,59062:23057,59063:23075,59064:23059,59065:23104,59066:23143,59067:23114,59068:23125,59069:23100,59070:23138,59071:23157,59072:33004,59073:23210,59074:23195,59075:23159,59076:23162,59077:23230,59078:23275,59079:23218,59080:23250,59081:23252,59082:23224,59083:23264,59084:23267,59085:23281,59086:23254,59087:23270,59088:23256,59089:23260,59090:23305,59091:23319,59092:23318,59093:23346,59094:23351,59095:23360,59096:23573,59097:23580,59098:23386,59099:23397,59100:23411,59101:23377,59102:23379,59103:23394,59104:39541,59105:39543,59106:39544,59107:39546,59108:39551,59109:39549,59110:39552,59111:39553,59112:39557,59113:39560,59114:39562,59115:39568,59116:39570,59117:39571,59118:39574,59119:39576,59120:39579,59121:39580,59122:39581,59123:39583,59124:39584,59125:39586,59126:39587,59127:39589,59128:39591,59129:32415,59130:32417,59131:32419,59132:32421,59133:32424,59134:32425,59200:37838,59201:37839,59202:37840,59203:37841,59204:37842,59205:37843,59206:37844,59207:37845,59208:37847,59209:37848,59210:37849,59211:37850,59212:37851,59213:37852,59214:37853,59215:37854,59216:37855,59217:37856,59218:37857,59219:37858,59220:37859,59221:37860,59222:37861,59223:37862,59224:37863,59225:37864,59226:37865,59227:37866,59228:37867,59229:37868,59230:37869,59231:37870,59232:37871,59233:37872,59234:37873,59235:37874,59236:37875,59237:37876,59238:37877,59239:37878,59240:37879,59241:37880,59242:37881,59243:37882,59244:37883,59245:37884,59246:37885,59247:37886,59248:37887,59249:37888,59250:37889,59251:37890,59252:37891,59253:37892,59254:37893,59255:37894,59256:37895,59257:37896,59258:37897,59259:37898,59260:37899,59261:37900,59262:37901,59264:37902,59265:37903,59266:37904,59267:37905,59268:37906,59269:37907,59270:37908,59271:37909,59272:37910,59273:37911,59274:37912,59275:37913,59276:37914,59277:37915,59278:37916,59279:37917,59280:37918,59281:37919,59282:37920,59283:37921,59284:37922,59285:37923,59286:37924,59287:37925,59288:37926,59289:37927,59290:37928,59291:37929,59292:37930,59293:37931,59294:37932,59295:37933,59296:37934,59297:32429,59298:32432,59299:32446,59300:32448,59301:32449,59302:32450,59303:32457,59304:32459,59305:32460,59306:32464,59307:32468,59308:32471,59309:32475,59310:32480,59311:32481,59312:32488,59313:32491,59314:32494,59315:32495,59316:32497,59317:32498,59318:32525,59319:32502,59320:32506,59321:32507,59322:32510,59323:32513,59324:32514,59325:32515,59326:32519,59327:32520,59328:32523,59329:32524,59330:32527,59331:32529,59332:32530,59333:32535,59334:32537,59335:32540,59336:32539,59337:32543,59338:32545,59339:32546,59340:32547,59341:32548,59342:32549,59343:32550,59344:32551,59345:32554,59346:32555,59347:32556,59348:32557,59349:32559,59350:32560,59351:32561,59352:32562,59353:32563,59354:32565,59355:24186,59356:30079,59357:24027,59358:30014,59359:37013,59360:29582,59361:29585,59362:29614,59363:29602,59364:29599,59365:29647,59366:29634,59367:29649,59368:29623,59369:29619,59370:29632,59371:29641,59372:29640,59373:29669,59374:29657,59375:39036,59376:29706,59377:29673,59378:29671,59379:29662,59380:29626,59381:29682,59382:29711,59383:29738,59384:29787,59385:29734,59386:29733,59387:29736,59388:29744,59389:29742,59390:29740,59456:37935,59457:37936,59458:37937,59459:37938,59460:37939,59461:37940,59462:37941,59463:37942,59464:37943,59465:37944,59466:37945,59467:37946,59468:37947,59469:37948,59470:37949,59471:37951,59472:37952,59473:37953,59474:37954,59475:37955,59476:37956,59477:37957,59478:37958,59479:37959,59480:37960,59481:37961,59482:37962,59483:37963,59484:37964,59485:37965,59486:37966,59487:37967,59488:37968,59489:37969,59490:37970,59491:37971,59492:37972,59493:37973,59494:37974,59495:37975,59496:37976,59497:37977,59498:37978,59499:37979,59500:37980,59501:37981,59502:37982,59503:37983,59504:37984,59505:37985,59506:37986,59507:37987,59508:37988,59509:37989,59510:37990,59511:37991,59512:37992,59513:37993,59514:37994,59515:37996,59516:37997,59517:37998,59518:37999,59520:38000,59521:38001,59522:38002,59523:38003,59524:38004,59525:38005,59526:38006,59527:38007,59528:38008,59529:38009,59530:38010,59531:38011,59532:38012,59533:38013,59534:38014,59535:38015,59536:38016,59537:38017,59538:38018,59539:38019,59540:38020,59541:38033,59542:38038,59543:38040,59544:38087,59545:38095,59546:38099,59547:38100,59548:38106,59549:38118,59550:38139,59551:38172,59552:38176,59553:29723,59554:29722,59555:29761,59556:29788,59557:29783,59558:29781,59559:29785,59560:29815,59561:29805,59562:29822,59563:29852,59564:29838,59565:29824,59566:29825,59567:29831,59568:29835,59569:29854,59570:29864,59571:29865,59572:29840,59573:29863,59574:29906,59575:29882,59576:38890,59577:38891,59578:38892,59579:26444,59580:26451,59581:26462,59582:26440,59583:26473,59584:26533,59585:26503,59586:26474,59587:26483,59588:26520,59589:26535,59590:26485,59591:26536,59592:26526,59593:26541,59594:26507,59595:26487,59596:26492,59597:26608,59598:26633,59599:26584,59600:26634,59601:26601,59602:26544,59603:26636,59604:26585,59605:26549,59606:26586,59607:26547,59608:26589,59609:26624,59610:26563,59611:26552,59612:26594,59613:26638,59614:26561,59615:26621,59616:26674,59617:26675,59618:26720,59619:26721,59620:26702,59621:26722,59622:26692,59623:26724,59624:26755,59625:26653,59626:26709,59627:26726,59628:26689,59629:26727,59630:26688,59631:26686,59632:26698,59633:26697,59634:26665,59635:26805,59636:26767,59637:26740,59638:26743,59639:26771,59640:26731,59641:26818,59642:26990,59643:26876,59644:26911,59645:26912,59646:26873,59712:38183,59713:38195,59714:38205,59715:38211,59716:38216,59717:38219,59718:38229,59719:38234,59720:38240,59721:38254,59722:38260,59723:38261,59724:38263,59725:38264,59726:38265,59727:38266,59728:38267,59729:38268,59730:38269,59731:38270,59732:38272,59733:38273,59734:38274,59735:38275,59736:38276,59737:38277,59738:38278,59739:38279,59740:38280,59741:38281,59742:38282,59743:38283,59744:38284,59745:38285,59746:38286,59747:38287,59748:38288,59749:38289,59750:38290,59751:38291,59752:38292,59753:38293,59754:38294,59755:38295,59756:38296,59757:38297,59758:38298,59759:38299,59760:38300,59761:38301,59762:38302,59763:38303,59764:38304,59765:38305,59766:38306,59767:38307,59768:38308,59769:38309,59770:38310,59771:38311,59772:38312,59773:38313,59774:38314,59776:38315,59777:38316,59778:38317,59779:38318,59780:38319,59781:38320,59782:38321,59783:38322,59784:38323,59785:38324,59786:38325,59787:38326,59788:38327,59789:38328,59790:38329,59791:38330,59792:38331,59793:38332,59794:38333,59795:38334,59796:38335,59797:38336,59798:38337,59799:38338,59800:38339,59801:38340,59802:38341,59803:38342,59804:38343,59805:38344,59806:38345,59807:38346,59808:38347,59809:26916,59810:26864,59811:26891,59812:26881,59813:26967,59814:26851,59815:26896,59816:26993,59817:26937,59818:26976,59819:26946,59820:26973,59821:27012,59822:26987,59823:27008,59824:27032,59825:27000,59826:26932,59827:27084,59828:27015,59829:27016,59830:27086,59831:27017,59832:26982,59833:26979,59834:27001,59835:27035,59836:27047,59837:27067,59838:27051,59839:27053,59840:27092,59841:27057,59842:27073,59843:27082,59844:27103,59845:27029,59846:27104,59847:27021,59848:27135,59849:27183,59850:27117,59851:27159,59852:27160,59853:27237,59854:27122,59855:27204,59856:27198,59857:27296,59858:27216,59859:27227,59860:27189,59861:27278,59862:27257,59863:27197,59864:27176,59865:27224,59866:27260,59867:27281,59868:27280,59869:27305,59870:27287,59871:27307,59872:29495,59873:29522,59874:27521,59875:27522,59876:27527,59877:27524,59878:27538,59879:27539,59880:27533,59881:27546,59882:27547,59883:27553,59884:27562,59885:36715,59886:36717,59887:36721,59888:36722,59889:36723,59890:36725,59891:36726,59892:36728,59893:36727,59894:36729,59895:36730,59896:36732,59897:36734,59898:36737,59899:36738,59900:36740,59901:36743,59902:36747,59968:38348,59969:38349,59970:38350,59971:38351,59972:38352,59973:38353,59974:38354,59975:38355,59976:38356,59977:38357,59978:38358,59979:38359,59980:38360,59981:38361,59982:38362,59983:38363,59984:38364,59985:38365,59986:38366,59987:38367,59988:38368,59989:38369,59990:38370,59991:38371,59992:38372,59993:38373,59994:38374,59995:38375,59996:38380,59997:38399,59998:38407,59999:38419,60000:38424,60001:38427,60002:38430,60003:38432,60004:38435,60005:38436,60006:38437,60007:38438,60008:38439,60009:38440,60010:38441,60011:38443,60012:38444,60013:38445,60014:38447,60015:38448,60016:38455,60017:38456,60018:38457,60019:38458,60020:38462,60021:38465,60022:38467,60023:38474,60024:38478,60025:38479,60026:38481,60027:38482,60028:38483,60029:38486,60030:38487,60032:38488,60033:38489,60034:38490,60035:38492,60036:38493,60037:38494,60038:38496,60039:38499,60040:38501,60041:38502,60042:38507,60043:38509,60044:38510,60045:38511,60046:38512,60047:38513,60048:38515,60049:38520,60050:38521,60051:38522,60052:38523,60053:38524,60054:38525,60055:38526,60056:38527,60057:38528,60058:38529,60059:38530,60060:38531,60061:38532,60062:38535,60063:38537,60064:38538,60065:36749,60066:36750,60067:36751,60068:36760,60069:36762,60070:36558,60071:25099,60072:25111,60073:25115,60074:25119,60075:25122,60076:25121,60077:25125,60078:25124,60079:25132,60080:33255,60081:29935,60082:29940,60083:29951,60084:29967,60085:29969,60086:29971,60087:25908,60088:26094,60089:26095,60090:26096,60091:26122,60092:26137,60093:26482,60094:26115,60095:26133,60096:26112,60097:28805,60098:26359,60099:26141,60100:26164,60101:26161,60102:26166,60103:26165,60104:32774,60105:26207,60106:26196,60107:26177,60108:26191,60109:26198,60110:26209,60111:26199,60112:26231,60113:26244,60114:26252,60115:26279,60116:26269,60117:26302,60118:26331,60119:26332,60120:26342,60121:26345,60122:36146,60123:36147,60124:36150,60125:36155,60126:36157,60127:36160,60128:36165,60129:36166,60130:36168,60131:36169,60132:36167,60133:36173,60134:36181,60135:36185,60136:35271,60137:35274,60138:35275,60139:35276,60140:35278,60141:35279,60142:35280,60143:35281,60144:29294,60145:29343,60146:29277,60147:29286,60148:29295,60149:29310,60150:29311,60151:29316,60152:29323,60153:29325,60154:29327,60155:29330,60156:25352,60157:25394,60158:25520,60224:38540,60225:38542,60226:38545,60227:38546,60228:38547,60229:38549,60230:38550,60231:38554,60232:38555,60233:38557,60234:38558,60235:38559,60236:38560,60237:38561,60238:38562,60239:38563,60240:38564,60241:38565,60242:38566,60243:38568,60244:38569,60245:38570,60246:38571,60247:38572,60248:38573,60249:38574,60250:38575,60251:38577,60252:38578,60253:38580,60254:38581,60255:38583,60256:38584,60257:38586,60258:38587,60259:38591,60260:38594,60261:38595,60262:38600,60263:38602,60264:38603,60265:38608,60266:38609,60267:38611,60268:38612,60269:38614,60270:38615,60271:38616,60272:38617,60273:38618,60274:38619,60275:38620,60276:38621,60277:38622,60278:38623,60279:38625,60280:38626,60281:38627,60282:38628,60283:38629,60284:38630,60285:38631,60286:38635,60288:38636,60289:38637,60290:38638,60291:38640,60292:38641,60293:38642,60294:38644,60295:38645,60296:38648,60297:38650,60298:38651,60299:38652,60300:38653,60301:38655,60302:38658,60303:38659,60304:38661,60305:38666,60306:38667,60307:38668,60308:38672,60309:38673,60310:38674,60311:38676,60312:38677,60313:38679,60314:38680,60315:38681,60316:38682,60317:38683,60318:38685,60319:38687,60320:38688,60321:25663,60322:25816,60323:32772,60324:27626,60325:27635,60326:27645,60327:27637,60328:27641,60329:27653,60330:27655,60331:27654,60332:27661,60333:27669,60334:27672,60335:27673,60336:27674,60337:27681,60338:27689,60339:27684,60340:27690,60341:27698,60342:25909,60343:25941,60344:25963,60345:29261,60346:29266,60347:29270,60348:29232,60349:34402,60350:21014,60351:32927,60352:32924,60353:32915,60354:32956,60355:26378,60356:32957,60357:32945,60358:32939,60359:32941,60360:32948,60361:32951,60362:32999,60363:33000,60364:33001,60365:33002,60366:32987,60367:32962,60368:32964,60369:32985,60370:32973,60371:32983,60372:26384,60373:32989,60374:33003,60375:33009,60376:33012,60377:33005,60378:33037,60379:33038,60380:33010,60381:33020,60382:26389,60383:33042,60384:35930,60385:33078,60386:33054,60387:33068,60388:33048,60389:33074,60390:33096,60391:33100,60392:33107,60393:33140,60394:33113,60395:33114,60396:33137,60397:33120,60398:33129,60399:33148,60400:33149,60401:33133,60402:33127,60403:22605,60404:23221,60405:33160,60406:33154,60407:33169,60408:28373,60409:33187,60410:33194,60411:33228,60412:26406,60413:33226,60414:33211,60480:38689,60481:38690,60482:38691,60483:38692,60484:38693,60485:38694,60486:38695,60487:38696,60488:38697,60489:38699,60490:38700,60491:38702,60492:38703,60493:38705,60494:38707,60495:38708,60496:38709,60497:38710,60498:38711,60499:38714,60500:38715,60501:38716,60502:38717,60503:38719,60504:38720,60505:38721,60506:38722,60507:38723,60508:38724,60509:38725,60510:38726,60511:38727,60512:38728,60513:38729,60514:38730,60515:38731,60516:38732,60517:38733,60518:38734,60519:38735,60520:38736,60521:38737,60522:38740,60523:38741,60524:38743,60525:38744,60526:38746,60527:38748,60528:38749,60529:38751,60530:38755,60531:38756,60532:38758,60533:38759,60534:38760,60535:38762,60536:38763,60537:38764,60538:38765,60539:38766,60540:38767,60541:38768,60542:38769,60544:38770,60545:38773,60546:38775,60547:38776,60548:38777,60549:38778,60550:38779,60551:38781,60552:38782,60553:38783,60554:38784,60555:38785,60556:38786,60557:38787,60558:38788,60559:38790,60560:38791,60561:38792,60562:38793,60563:38794,60564:38796,60565:38798,60566:38799,60567:38800,60568:38803,60569:38805,60570:38806,60571:38807,60572:38809,60573:38810,60574:38811,60575:38812,60576:38813,60577:33217,60578:33190,60579:27428,60580:27447,60581:27449,60582:27459,60583:27462,60584:27481,60585:39121,60586:39122,60587:39123,60588:39125,60589:39129,60590:39130,60591:27571,60592:24384,60593:27586,60594:35315,60595:26000,60596:40785,60597:26003,60598:26044,60599:26054,60600:26052,60601:26051,60602:26060,60603:26062,60604:26066,60605:26070,60606:28800,60607:28828,60608:28822,60609:28829,60610:28859,60611:28864,60612:28855,60613:28843,60614:28849,60615:28904,60616:28874,60617:28944,60618:28947,60619:28950,60620:28975,60621:28977,60622:29043,60623:29020,60624:29032,60625:28997,60626:29042,60627:29002,60628:29048,60629:29050,60630:29080,60631:29107,60632:29109,60633:29096,60634:29088,60635:29152,60636:29140,60637:29159,60638:29177,60639:29213,60640:29224,60641:28780,60642:28952,60643:29030,60644:29113,60645:25150,60646:25149,60647:25155,60648:25160,60649:25161,60650:31035,60651:31040,60652:31046,60653:31049,60654:31067,60655:31068,60656:31059,60657:31066,60658:31074,60659:31063,60660:31072,60661:31087,60662:31079,60663:31098,60664:31109,60665:31114,60666:31130,60667:31143,60668:31155,60669:24529,60670:24528,60736:38814,60737:38815,60738:38817,60739:38818,60740:38820,60741:38821,60742:38822,60743:38823,60744:38824,60745:38825,60746:38826,60747:38828,60748:38830,60749:38832,60750:38833,60751:38835,60752:38837,60753:38838,60754:38839,60755:38840,60756:38841,60757:38842,60758:38843,60759:38844,60760:38845,60761:38846,60762:38847,60763:38848,60764:38849,60765:38850,60766:38851,60767:38852,60768:38853,60769:38854,60770:38855,60771:38856,60772:38857,60773:38858,60774:38859,60775:38860,60776:38861,60777:38862,60778:38863,60779:38864,60780:38865,60781:38866,60782:38867,60783:38868,60784:38869,60785:38870,60786:38871,60787:38872,60788:38873,60789:38874,60790:38875,60791:38876,60792:38877,60793:38878,60794:38879,60795:38880,60796:38881,60797:38882,60798:38883,60800:38884,60801:38885,60802:38888,60803:38894,60804:38895,60805:38896,60806:38897,60807:38898,60808:38900,60809:38903,60810:38904,60811:38905,60812:38906,60813:38907,60814:38908,60815:38909,60816:38910,60817:38911,60818:38912,60819:38913,60820:38914,60821:38915,60822:38916,60823:38917,60824:38918,60825:38919,60826:38920,60827:38921,60828:38922,60829:38923,60830:38924,60831:38925,60832:38926,60833:24636,60834:24669,60835:24666,60836:24679,60837:24641,60838:24665,60839:24675,60840:24747,60841:24838,60842:24845,60843:24925,60844:25001,60845:24989,60846:25035,60847:25041,60848:25094,60849:32896,60850:32895,60851:27795,60852:27894,60853:28156,60854:30710,60855:30712,60856:30720,60857:30729,60858:30743,60859:30744,60860:30737,60861:26027,60862:30765,60863:30748,60864:30749,60865:30777,60866:30778,60867:30779,60868:30751,60869:30780,60870:30757,60871:30764,60872:30755,60873:30761,60874:30798,60875:30829,60876:30806,60877:30807,60878:30758,60879:30800,60880:30791,60881:30796,60882:30826,60883:30875,60884:30867,60885:30874,60886:30855,60887:30876,60888:30881,60889:30883,60890:30898,60891:30905,60892:30885,60893:30932,60894:30937,60895:30921,60896:30956,60897:30962,60898:30981,60899:30964,60900:30995,60901:31012,60902:31006,60903:31028,60904:40859,60905:40697,60906:40699,60907:40700,60908:30449,60909:30468,60910:30477,60911:30457,60912:30471,60913:30472,60914:30490,60915:30498,60916:30489,60917:30509,60918:30502,60919:30517,60920:30520,60921:30544,60922:30545,60923:30535,60924:30531,60925:30554,60926:30568,60992:38927,60993:38928,60994:38929,60995:38930,60996:38931,60997:38932,60998:38933,60999:38934,61000:38935,61001:38936,61002:38937,61003:38938,61004:38939,61005:38940,61006:38941,61007:38942,61008:38943,61009:38944,61010:38945,61011:38946,61012:38947,61013:38948,61014:38949,61015:38950,61016:38951,61017:38952,61018:38953,61019:38954,61020:38955,61021:38956,61022:38957,61023:38958,61024:38959,61025:38960,61026:38961,61027:38962,61028:38963,61029:38964,61030:38965,61031:38966,61032:38967,61033:38968,61034:38969,61035:38970,61036:38971,61037:38972,61038:38973,61039:38974,61040:38975,61041:38976,61042:38977,61043:38978,61044:38979,61045:38980,61046:38981,61047:38982,61048:38983,61049:38984,61050:38985,61051:38986,61052:38987,61053:38988,61054:38989,61056:38990,61057:38991,61058:38992,61059:38993,61060:38994,61061:38995,61062:38996,61063:38997,61064:38998,61065:38999,61066:39000,61067:39001,61068:39002,61069:39003,61070:39004,61071:39005,61072:39006,61073:39007,61074:39008,61075:39009,61076:39010,61077:39011,61078:39012,61079:39013,61080:39014,61081:39015,61082:39016,61083:39017,61084:39018,61085:39019,61086:39020,61087:39021,61088:39022,61089:30562,61090:30565,61091:30591,61092:30605,61093:30589,61094:30592,61095:30604,61096:30609,61097:30623,61098:30624,61099:30640,61100:30645,61101:30653,61102:30010,61103:30016,61104:30030,61105:30027,61106:30024,61107:30043,61108:30066,61109:30073,61110:30083,61111:32600,61112:32609,61113:32607,61114:35400,61115:32616,61116:32628,61117:32625,61118:32633,61119:32641,61120:32638,61121:30413,61122:30437,61123:34866,61124:38021,61125:38022,61126:38023,61127:38027,61128:38026,61129:38028,61130:38029,61131:38031,61132:38032,61133:38036,61134:38039,61135:38037,61136:38042,61137:38043,61138:38044,61139:38051,61140:38052,61141:38059,61142:38058,61143:38061,61144:38060,61145:38063,61146:38064,61147:38066,61148:38068,61149:38070,61150:38071,61151:38072,61152:38073,61153:38074,61154:38076,61155:38077,61156:38079,61157:38084,61158:38088,61159:38089,61160:38090,61161:38091,61162:38092,61163:38093,61164:38094,61165:38096,61166:38097,61167:38098,61168:38101,61169:38102,61170:38103,61171:38105,61172:38104,61173:38107,61174:38110,61175:38111,61176:38112,61177:38114,61178:38116,61179:38117,61180:38119,61181:38120,61182:38122,61248:39023,61249:39024,61250:39025,61251:39026,61252:39027,61253:39028,61254:39051,61255:39054,61256:39058,61257:39061,61258:39065,61259:39075,61260:39080,61261:39081,61262:39082,61263:39083,61264:39084,61265:39085,61266:39086,61267:39087,61268:39088,61269:39089,61270:39090,61271:39091,61272:39092,61273:39093,61274:39094,61275:39095,61276:39096,61277:39097,61278:39098,61279:39099,61280:39100,61281:39101,61282:39102,61283:39103,61284:39104,61285:39105,61286:39106,61287:39107,61288:39108,61289:39109,61290:39110,61291:39111,61292:39112,61293:39113,61294:39114,61295:39115,61296:39116,61297:39117,61298:39119,61299:39120,61300:39124,61301:39126,61302:39127,61303:39131,61304:39132,61305:39133,61306:39136,61307:39137,61308:39138,61309:39139,61310:39140,61312:39141,61313:39142,61314:39145,61315:39146,61316:39147,61317:39148,61318:39149,61319:39150,61320:39151,61321:39152,61322:39153,61323:39154,61324:39155,61325:39156,61326:39157,61327:39158,61328:39159,61329:39160,61330:39161,61331:39162,61332:39163,61333:39164,61334:39165,61335:39166,61336:39167,61337:39168,61338:39169,61339:39170,61340:39171,61341:39172,61342:39173,61343:39174,61344:39175,61345:38121,61346:38123,61347:38126,61348:38127,61349:38131,61350:38132,61351:38133,61352:38135,61353:38137,61354:38140,61355:38141,61356:38143,61357:38147,61358:38146,61359:38150,61360:38151,61361:38153,61362:38154,61363:38157,61364:38158,61365:38159,61366:38162,61367:38163,61368:38164,61369:38165,61370:38166,61371:38168,61372:38171,61373:38173,61374:38174,61375:38175,61376:38178,61377:38186,61378:38187,61379:38185,61380:38188,61381:38193,61382:38194,61383:38196,61384:38198,61385:38199,61386:38200,61387:38204,61388:38206,61389:38207,61390:38210,61391:38197,61392:38212,61393:38213,61394:38214,61395:38217,61396:38220,61397:38222,61398:38223,61399:38226,61400:38227,61401:38228,61402:38230,61403:38231,61404:38232,61405:38233,61406:38235,61407:38238,61408:38239,61409:38237,61410:38241,61411:38242,61412:38244,61413:38245,61414:38246,61415:38247,61416:38248,61417:38249,61418:38250,61419:38251,61420:38252,61421:38255,61422:38257,61423:38258,61424:38259,61425:38202,61426:30695,61427:30700,61428:38601,61429:31189,61430:31213,61431:31203,61432:31211,61433:31238,61434:23879,61435:31235,61436:31234,61437:31262,61438:31252,61504:39176,61505:39177,61506:39178,61507:39179,61508:39180,61509:39182,61510:39183,61511:39185,61512:39186,61513:39187,61514:39188,61515:39189,61516:39190,61517:39191,61518:39192,61519:39193,61520:39194,61521:39195,61522:39196,61523:39197,61524:39198,61525:39199,61526:39200,61527:39201,61528:39202,61529:39203,61530:39204,61531:39205,61532:39206,61533:39207,61534:39208,61535:39209,61536:39210,61537:39211,61538:39212,61539:39213,61540:39215,61541:39216,61542:39217,61543:39218,61544:39219,61545:39220,61546:39221,61547:39222,61548:39223,61549:39224,61550:39225,61551:39226,61552:39227,61553:39228,61554:39229,61555:39230,61556:39231,61557:39232,61558:39233,61559:39234,61560:39235,61561:39236,61562:39237,61563:39238,61564:39239,61565:39240,61566:39241,61568:39242,61569:39243,61570:39244,61571:39245,61572:39246,61573:39247,61574:39248,61575:39249,61576:39250,61577:39251,61578:39254,61579:39255,61580:39256,61581:39257,61582:39258,61583:39259,61584:39260,61585:39261,61586:39262,61587:39263,61588:39264,61589:39265,61590:39266,61591:39268,61592:39270,61593:39283,61594:39288,61595:39289,61596:39291,61597:39294,61598:39298,61599:39299,61600:39305,61601:31289,61602:31287,61603:31313,61604:40655,61605:39333,61606:31344,61607:30344,61608:30350,61609:30355,61610:30361,61611:30372,61612:29918,61613:29920,61614:29996,61615:40480,61616:40482,61617:40488,61618:40489,61619:40490,61620:40491,61621:40492,61622:40498,61623:40497,61624:40502,61625:40504,61626:40503,61627:40505,61628:40506,61629:40510,61630:40513,61631:40514,61632:40516,61633:40518,61634:40519,61635:40520,61636:40521,61637:40523,61638:40524,61639:40526,61640:40529,61641:40533,61642:40535,61643:40538,61644:40539,61645:40540,61646:40542,61647:40547,61648:40550,61649:40551,61650:40552,61651:40553,61652:40554,61653:40555,61654:40556,61655:40561,61656:40557,61657:40563,61658:30098,61659:30100,61660:30102,61661:30112,61662:30109,61663:30124,61664:30115,61665:30131,61666:30132,61667:30136,61668:30148,61669:30129,61670:30128,61671:30147,61672:30146,61673:30166,61674:30157,61675:30179,61676:30184,61677:30182,61678:30180,61679:30187,61680:30183,61681:30211,61682:30193,61683:30204,61684:30207,61685:30224,61686:30208,61687:30213,61688:30220,61689:30231,61690:30218,61691:30245,61692:30232,61693:30229,61694:30233,61760:39308,61761:39310,61762:39322,61763:39323,61764:39324,61765:39325,61766:39326,61767:39327,61768:39328,61769:39329,61770:39330,61771:39331,61772:39332,61773:39334,61774:39335,61775:39337,61776:39338,61777:39339,61778:39340,61779:39341,61780:39342,61781:39343,61782:39344,61783:39345,61784:39346,61785:39347,61786:39348,61787:39349,61788:39350,61789:39351,61790:39352,61791:39353,61792:39354,61793:39355,61794:39356,61795:39357,61796:39358,61797:39359,61798:39360,61799:39361,61800:39362,61801:39363,61802:39364,61803:39365,61804:39366,61805:39367,61806:39368,61807:39369,61808:39370,61809:39371,61810:39372,61811:39373,61812:39374,61813:39375,61814:39376,61815:39377,61816:39378,61817:39379,61818:39380,61819:39381,61820:39382,61821:39383,61822:39384,61824:39385,61825:39386,61826:39387,61827:39388,61828:39389,61829:39390,61830:39391,61831:39392,61832:39393,61833:39394,61834:39395,61835:39396,61836:39397,61837:39398,61838:39399,61839:39400,61840:39401,61841:39402,61842:39403,61843:39404,61844:39405,61845:39406,61846:39407,61847:39408,61848:39409,61849:39410,61850:39411,61851:39412,61852:39413,61853:39414,61854:39415,61855:39416,61856:39417,61857:30235,61858:30268,61859:30242,61860:30240,61861:30272,61862:30253,61863:30256,61864:30271,61865:30261,61866:30275,61867:30270,61868:30259,61869:30285,61870:30302,61871:30292,61872:30300,61873:30294,61874:30315,61875:30319,61876:32714,61877:31462,61878:31352,61879:31353,61880:31360,61881:31366,61882:31368,61883:31381,61884:31398,61885:31392,61886:31404,61887:31400,61888:31405,61889:31411,61890:34916,61891:34921,61892:34930,61893:34941,61894:34943,61895:34946,61896:34978,61897:35014,61898:34999,61899:35004,61900:35017,61901:35042,61902:35022,61903:35043,61904:35045,61905:35057,61906:35098,61907:35068,61908:35048,61909:35070,61910:35056,61911:35105,61912:35097,61913:35091,61914:35099,61915:35082,61916:35124,61917:35115,61918:35126,61919:35137,61920:35174,61921:35195,61922:30091,61923:32997,61924:30386,61925:30388,61926:30684,61927:32786,61928:32788,61929:32790,61930:32796,61931:32800,61932:32802,61933:32805,61934:32806,61935:32807,61936:32809,61937:32808,61938:32817,61939:32779,61940:32821,61941:32835,61942:32838,61943:32845,61944:32850,61945:32873,61946:32881,61947:35203,61948:39032,61949:39040,61950:39043,62016:39418,62017:39419,62018:39420,62019:39421,62020:39422,62021:39423,62022:39424,62023:39425,62024:39426,62025:39427,62026:39428,62027:39429,62028:39430,62029:39431,62030:39432,62031:39433,62032:39434,62033:39435,62034:39436,62035:39437,62036:39438,62037:39439,62038:39440,62039:39441,62040:39442,62041:39443,62042:39444,62043:39445,62044:39446,62045:39447,62046:39448,62047:39449,62048:39450,62049:39451,62050:39452,62051:39453,62052:39454,62053:39455,62054:39456,62055:39457,62056:39458,62057:39459,62058:39460,62059:39461,62060:39462,62061:39463,62062:39464,62063:39465,62064:39466,62065:39467,62066:39468,62067:39469,62068:39470,62069:39471,62070:39472,62071:39473,62072:39474,62073:39475,62074:39476,62075:39477,62076:39478,62077:39479,62078:39480,62080:39481,62081:39482,62082:39483,62083:39484,62084:39485,62085:39486,62086:39487,62087:39488,62088:39489,62089:39490,62090:39491,62091:39492,62092:39493,62093:39494,62094:39495,62095:39496,62096:39497,62097:39498,62098:39499,62099:39500,62100:39501,62101:39502,62102:39503,62103:39504,62104:39505,62105:39506,62106:39507,62107:39508,62108:39509,62109:39510,62110:39511,62111:39512,62112:39513,62113:39049,62114:39052,62115:39053,62116:39055,62117:39060,62118:39066,62119:39067,62120:39070,62121:39071,62122:39073,62123:39074,62124:39077,62125:39078,62126:34381,62127:34388,62128:34412,62129:34414,62130:34431,62131:34426,62132:34428,62133:34427,62134:34472,62135:34445,62136:34443,62137:34476,62138:34461,62139:34471,62140:34467,62141:34474,62142:34451,62143:34473,62144:34486,62145:34500,62146:34485,62147:34510,62148:34480,62149:34490,62150:34481,62151:34479,62152:34505,62153:34511,62154:34484,62155:34537,62156:34545,62157:34546,62158:34541,62159:34547,62160:34512,62161:34579,62162:34526,62163:34548,62164:34527,62165:34520,62166:34513,62167:34563,62168:34567,62169:34552,62170:34568,62171:34570,62172:34573,62173:34569,62174:34595,62175:34619,62176:34590,62177:34597,62178:34606,62179:34586,62180:34622,62181:34632,62182:34612,62183:34609,62184:34601,62185:34615,62186:34623,62187:34690,62188:34594,62189:34685,62190:34686,62191:34683,62192:34656,62193:34672,62194:34636,62195:34670,62196:34699,62197:34643,62198:34659,62199:34684,62200:34660,62201:34649,62202:34661,62203:34707,62204:34735,62205:34728,62206:34770,62272:39514,62273:39515,62274:39516,62275:39517,62276:39518,62277:39519,62278:39520,62279:39521,62280:39522,62281:39523,62282:39524,62283:39525,62284:39526,62285:39527,62286:39528,62287:39529,62288:39530,62289:39531,62290:39538,62291:39555,62292:39561,62293:39565,62294:39566,62295:39572,62296:39573,62297:39577,62298:39590,62299:39593,62300:39594,62301:39595,62302:39596,62303:39597,62304:39598,62305:39599,62306:39602,62307:39603,62308:39604,62309:39605,62310:39609,62311:39611,62312:39613,62313:39614,62314:39615,62315:39619,62316:39620,62317:39622,62318:39623,62319:39624,62320:39625,62321:39626,62322:39629,62323:39630,62324:39631,62325:39632,62326:39634,62327:39636,62328:39637,62329:39638,62330:39639,62331:39641,62332:39642,62333:39643,62334:39644,62336:39645,62337:39646,62338:39648,62339:39650,62340:39651,62341:39652,62342:39653,62343:39655,62344:39656,62345:39657,62346:39658,62347:39660,62348:39662,62349:39664,62350:39665,62351:39666,62352:39667,62353:39668,62354:39669,62355:39670,62356:39671,62357:39672,62358:39674,62359:39676,62360:39677,62361:39678,62362:39679,62363:39680,62364:39681,62365:39682,62366:39684,62367:39685,62368:39686,62369:34758,62370:34696,62371:34693,62372:34733,62373:34711,62374:34691,62375:34731,62376:34789,62377:34732,62378:34741,62379:34739,62380:34763,62381:34771,62382:34749,62383:34769,62384:34752,62385:34762,62386:34779,62387:34794,62388:34784,62389:34798,62390:34838,62391:34835,62392:34814,62393:34826,62394:34843,62395:34849,62396:34873,62397:34876,62398:32566,62399:32578,62400:32580,62401:32581,62402:33296,62403:31482,62404:31485,62405:31496,62406:31491,62407:31492,62408:31509,62409:31498,62410:31531,62411:31503,62412:31559,62413:31544,62414:31530,62415:31513,62416:31534,62417:31537,62418:31520,62419:31525,62420:31524,62421:31539,62422:31550,62423:31518,62424:31576,62425:31578,62426:31557,62427:31605,62428:31564,62429:31581,62430:31584,62431:31598,62432:31611,62433:31586,62434:31602,62435:31601,62436:31632,62437:31654,62438:31655,62439:31672,62440:31660,62441:31645,62442:31656,62443:31621,62444:31658,62445:31644,62446:31650,62447:31659,62448:31668,62449:31697,62450:31681,62451:31692,62452:31709,62453:31706,62454:31717,62455:31718,62456:31722,62457:31756,62458:31742,62459:31740,62460:31759,62461:31766,62462:31755,62528:39687,62529:39689,62530:39690,62531:39691,62532:39692,62533:39693,62534:39694,62535:39696,62536:39697,62537:39698,62538:39700,62539:39701,62540:39702,62541:39703,62542:39704,62543:39705,62544:39706,62545:39707,62546:39708,62547:39709,62548:39710,62549:39712,62550:39713,62551:39714,62552:39716,62553:39717,62554:39718,62555:39719,62556:39720,62557:39721,62558:39722,62559:39723,62560:39724,62561:39725,62562:39726,62563:39728,62564:39729,62565:39731,62566:39732,62567:39733,62568:39734,62569:39735,62570:39736,62571:39737,62572:39738,62573:39741,62574:39742,62575:39743,62576:39744,62577:39750,62578:39754,62579:39755,62580:39756,62581:39758,62582:39760,62583:39762,62584:39763,62585:39765,62586:39766,62587:39767,62588:39768,62589:39769,62590:39770,62592:39771,62593:39772,62594:39773,62595:39774,62596:39775,62597:39776,62598:39777,62599:39778,62600:39779,62601:39780,62602:39781,62603:39782,62604:39783,62605:39784,62606:39785,62607:39786,62608:39787,62609:39788,62610:39789,62611:39790,62612:39791,62613:39792,62614:39793,62615:39794,62616:39795,62617:39796,62618:39797,62619:39798,62620:39799,62621:39800,62622:39801,62623:39802,62624:39803,62625:31775,62626:31786,62627:31782,62628:31800,62629:31809,62630:31808,62631:33278,62632:33281,62633:33282,62634:33284,62635:33260,62636:34884,62637:33313,62638:33314,62639:33315,62640:33325,62641:33327,62642:33320,62643:33323,62644:33336,62645:33339,62646:33331,62647:33332,62648:33342,62649:33348,62650:33353,62651:33355,62652:33359,62653:33370,62654:33375,62655:33384,62656:34942,62657:34949,62658:34952,62659:35032,62660:35039,62661:35166,62662:32669,62663:32671,62664:32679,62665:32687,62666:32688,62667:32690,62668:31868,62669:25929,62670:31889,62671:31901,62672:31900,62673:31902,62674:31906,62675:31922,62676:31932,62677:31933,62678:31937,62679:31943,62680:31948,62681:31949,62682:31944,62683:31941,62684:31959,62685:31976,62686:33390,62687:26280,62688:32703,62689:32718,62690:32725,62691:32741,62692:32737,62693:32742,62694:32745,62695:32750,62696:32755,62697:31992,62698:32119,62699:32166,62700:32174,62701:32327,62702:32411,62703:40632,62704:40628,62705:36211,62706:36228,62707:36244,62708:36241,62709:36273,62710:36199,62711:36205,62712:35911,62713:35913,62714:37194,62715:37200,62716:37198,62717:37199,62718:37220,62784:39804,62785:39805,62786:39806,62787:39807,62788:39808,62789:39809,62790:39810,62791:39811,62792:39812,62793:39813,62794:39814,62795:39815,62796:39816,62797:39817,62798:39818,62799:39819,62800:39820,62801:39821,62802:39822,62803:39823,62804:39824,62805:39825,62806:39826,62807:39827,62808:39828,62809:39829,62810:39830,62811:39831,62812:39832,62813:39833,62814:39834,62815:39835,62816:39836,62817:39837,62818:39838,62819:39839,62820:39840,62821:39841,62822:39842,62823:39843,62824:39844,62825:39845,62826:39846,62827:39847,62828:39848,62829:39849,62830:39850,62831:39851,62832:39852,62833:39853,62834:39854,62835:39855,62836:39856,62837:39857,62838:39858,62839:39859,62840:39860,62841:39861,62842:39862,62843:39863,62844:39864,62845:39865,62846:39866,62848:39867,62849:39868,62850:39869,62851:39870,62852:39871,62853:39872,62854:39873,62855:39874,62856:39875,62857:39876,62858:39877,62859:39878,62860:39879,62861:39880,62862:39881,62863:39882,62864:39883,62865:39884,62866:39885,62867:39886,62868:39887,62869:39888,62870:39889,62871:39890,62872:39891,62873:39892,62874:39893,62875:39894,62876:39895,62877:39896,62878:39897,62879:39898,62880:39899,62881:37218,62882:37217,62883:37232,62884:37225,62885:37231,62886:37245,62887:37246,62888:37234,62889:37236,62890:37241,62891:37260,62892:37253,62893:37264,62894:37261,62895:37265,62896:37282,62897:37283,62898:37290,62899:37293,62900:37294,62901:37295,62902:37301,62903:37300,62904:37306,62905:35925,62906:40574,62907:36280,62908:36331,62909:36357,62910:36441,62911:36457,62912:36277,62913:36287,62914:36284,62915:36282,62916:36292,62917:36310,62918:36311,62919:36314,62920:36318,62921:36302,62922:36303,62923:36315,62924:36294,62925:36332,62926:36343,62927:36344,62928:36323,62929:36345,62930:36347,62931:36324,62932:36361,62933:36349,62934:36372,62935:36381,62936:36383,62937:36396,62938:36398,62939:36387,62940:36399,62941:36410,62942:36416,62943:36409,62944:36405,62945:36413,62946:36401,62947:36425,62948:36417,62949:36418,62950:36433,62951:36434,62952:36426,62953:36464,62954:36470,62955:36476,62956:36463,62957:36468,62958:36485,62959:36495,62960:36500,62961:36496,62962:36508,62963:36510,62964:35960,62965:35970,62966:35978,62967:35973,62968:35992,62969:35988,62970:26011,62971:35286,62972:35294,62973:35290,62974:35292,63040:39900,63041:39901,63042:39902,63043:39903,63044:39904,63045:39905,63046:39906,63047:39907,63048:39908,63049:39909,63050:39910,63051:39911,63052:39912,63053:39913,63054:39914,63055:39915,63056:39916,63057:39917,63058:39918,63059:39919,63060:39920,63061:39921,63062:39922,63063:39923,63064:39924,63065:39925,63066:39926,63067:39927,63068:39928,63069:39929,63070:39930,63071:39931,63072:39932,63073:39933,63074:39934,63075:39935,63076:39936,63077:39937,63078:39938,63079:39939,63080:39940,63081:39941,63082:39942,63083:39943,63084:39944,63085:39945,63086:39946,63087:39947,63088:39948,63089:39949,63090:39950,63091:39951,63092:39952,63093:39953,63094:39954,63095:39955,63096:39956,63097:39957,63098:39958,63099:39959,63100:39960,63101:39961,63102:39962,63104:39963,63105:39964,63106:39965,63107:39966,63108:39967,63109:39968,63110:39969,63111:39970,63112:39971,63113:39972,63114:39973,63115:39974,63116:39975,63117:39976,63118:39977,63119:39978,63120:39979,63121:39980,63122:39981,63123:39982,63124:39983,63125:39984,63126:39985,63127:39986,63128:39987,63129:39988,63130:39989,63131:39990,63132:39991,63133:39992,63134:39993,63135:39994,63136:39995,63137:35301,63138:35307,63139:35311,63140:35390,63141:35622,63142:38739,63143:38633,63144:38643,63145:38639,63146:38662,63147:38657,63148:38664,63149:38671,63150:38670,63151:38698,63152:38701,63153:38704,63154:38718,63155:40832,63156:40835,63157:40837,63158:40838,63159:40839,63160:40840,63161:40841,63162:40842,63163:40844,63164:40702,63165:40715,63166:40717,63167:38585,63168:38588,63169:38589,63170:38606,63171:38610,63172:30655,63173:38624,63174:37518,63175:37550,63176:37576,63177:37694,63178:37738,63179:37834,63180:37775,63181:37950,63182:37995,63183:40063,63184:40066,63185:40069,63186:40070,63187:40071,63188:40072,63189:31267,63190:40075,63191:40078,63192:40080,63193:40081,63194:40082,63195:40084,63196:40085,63197:40090,63198:40091,63199:40094,63200:40095,63201:40096,63202:40097,63203:40098,63204:40099,63205:40101,63206:40102,63207:40103,63208:40104,63209:40105,63210:40107,63211:40109,63212:40110,63213:40112,63214:40113,63215:40114,63216:40115,63217:40116,63218:40117,63219:40118,63220:40119,63221:40122,63222:40123,63223:40124,63224:40125,63225:40132,63226:40133,63227:40134,63228:40135,63229:40138,63230:40139,63296:39996,63297:39997,63298:39998,63299:39999,63300:40000,63301:40001,63302:40002,63303:40003,63304:40004,63305:40005,63306:40006,63307:40007,63308:40008,63309:40009,63310:40010,63311:40011,63312:40012,63313:40013,63314:40014,63315:40015,63316:40016,63317:40017,63318:40018,63319:40019,63320:40020,63321:40021,63322:40022,63323:40023,63324:40024,63325:40025,63326:40026,63327:40027,63328:40028,63329:40029,63330:40030,63331:40031,63332:40032,63333:40033,63334:40034,63335:40035,63336:40036,63337:40037,63338:40038,63339:40039,63340:40040,63341:40041,63342:40042,63343:40043,63344:40044,63345:40045,63346:40046,63347:40047,63348:40048,63349:40049,63350:40050,63351:40051,63352:40052,63353:40053,63354:40054,63355:40055,63356:40056,63357:40057,63358:40058,63360:40059,63361:40061,63362:40062,63363:40064,63364:40067,63365:40068,63366:40073,63367:40074,63368:40076,63369:40079,63370:40083,63371:40086,63372:40087,63373:40088,63374:40089,63375:40093,63376:40106,63377:40108,63378:40111,63379:40121,63380:40126,63381:40127,63382:40128,63383:40129,63384:40130,63385:40136,63386:40137,63387:40145,63388:40146,63389:40154,63390:40155,63391:40160,63392:40161,63393:40140,63394:40141,63395:40142,63396:40143,63397:40144,63398:40147,63399:40148,63400:40149,63401:40151,63402:40152,63403:40153,63404:40156,63405:40157,63406:40159,63407:40162,63408:38780,63409:38789,63410:38801,63411:38802,63412:38804,63413:38831,63414:38827,63415:38819,63416:38834,63417:38836,63418:39601,63419:39600,63420:39607,63421:40536,63422:39606,63423:39610,63424:39612,63425:39617,63426:39616,63427:39621,63428:39618,63429:39627,63430:39628,63431:39633,63432:39749,63433:39747,63434:39751,63435:39753,63436:39752,63437:39757,63438:39761,63439:39144,63440:39181,63441:39214,63442:39253,63443:39252,63444:39647,63445:39649,63446:39654,63447:39663,63448:39659,63449:39675,63450:39661,63451:39673,63452:39688,63453:39695,63454:39699,63455:39711,63456:39715,63457:40637,63458:40638,63459:32315,63460:40578,63461:40583,63462:40584,63463:40587,63464:40594,63465:37846,63466:40605,63467:40607,63468:40667,63469:40668,63470:40669,63471:40672,63472:40671,63473:40674,63474:40681,63475:40679,63476:40677,63477:40682,63478:40687,63479:40738,63480:40748,63481:40751,63482:40761,63483:40759,63484:40765,63485:40766,63486:40772,63552:40163,63553:40164,63554:40165,63555:40166,63556:40167,63557:40168,63558:40169,63559:40170,63560:40171,63561:40172,63562:40173,63563:40174,63564:40175,63565:40176,63566:40177,63567:40178,63568:40179,63569:40180,63570:40181,63571:40182,63572:40183,63573:40184,63574:40185,63575:40186,63576:40187,63577:40188,63578:40189,63579:40190,63580:40191,63581:40192,63582:40193,63583:40194,63584:40195,63585:40196,63586:40197,63587:40198,63588:40199,63589:40200,63590:40201,63591:40202,63592:40203,63593:40204,63594:40205,63595:40206,63596:40207,63597:40208,63598:40209,63599:40210,63600:40211,63601:40212,63602:40213,63603:40214,63604:40215,63605:40216,63606:40217,63607:40218,63608:40219,63609:40220,63610:40221,63611:40222,63612:40223,63613:40224,63614:40225,63616:40226,63617:40227,63618:40228,63619:40229,63620:40230,63621:40231,63622:40232,63623:40233,63624:40234,63625:40235,63626:40236,63627:40237,63628:40238,63629:40239,63630:40240,63631:40241,63632:40242,63633:40243,63634:40244,63635:40245,63636:40246,63637:40247,63638:40248,63639:40249,63640:40250,63641:40251,63642:40252,63643:40253,63644:40254,63645:40255,63646:40256,63647:40257,63648:40258,63649:57908,63650:57909,63651:57910,63652:57911,63653:57912,63654:57913,63655:57914,63656:57915,63657:57916,63658:57917,63659:57918,63660:57919,63661:57920,63662:57921,63663:57922,63664:57923,63665:57924,63666:57925,63667:57926,63668:57927,63669:57928,63670:57929,63671:57930,63672:57931,63673:57932,63674:57933,63675:57934,63676:57935,63677:57936,63678:57937,63679:57938,63680:57939,63681:57940,63682:57941,63683:57942,63684:57943,63685:57944,63686:57945,63687:57946,63688:57947,63689:57948,63690:57949,63691:57950,63692:57951,63693:57952,63694:57953,63695:57954,63696:57955,63697:57956,63698:57957,63699:57958,63700:57959,63701:57960,63702:57961,63703:57962,63704:57963,63705:57964,63706:57965,63707:57966,63708:57967,63709:57968,63710:57969,63711:57970,63712:57971,63713:57972,63714:57973,63715:57974,63716:57975,63717:57976,63718:57977,63719:57978,63720:57979,63721:57980,63722:57981,63723:57982,63724:57983,63725:57984,63726:57985,63727:57986,63728:57987,63729:57988,63730:57989,63731:57990,63732:57991,63733:57992,63734:57993,63735:57994,63736:57995,63737:57996,63738:57997,63739:57998,63740:57999,63741:58000,63742:58001,63808:40259,63809:40260,63810:40261,63811:40262,63812:40263,63813:40264,63814:40265,63815:40266,63816:40267,63817:40268,63818:40269,63819:40270,63820:40271,63821:40272,63822:40273,63823:40274,63824:40275,63825:40276,63826:40277,63827:40278,63828:40279,63829:40280,63830:40281,63831:40282,63832:40283,63833:40284,63834:40285,63835:40286,63836:40287,63837:40288,63838:40289,63839:40290,63840:40291,63841:40292,63842:40293,63843:40294,63844:40295,63845:40296,63846:40297,63847:40298,63848:40299,63849:40300,63850:40301,63851:40302,63852:40303,63853:40304,63854:40305,63855:40306,63856:40307,63857:40308,63858:40309,63859:40310,63860:40311,63861:40312,63862:40313,63863:40314,63864:40315,63865:40316,63866:40317,63867:40318,63868:40319,63869:40320,63870:40321,63872:40322,63873:40323,63874:40324,63875:40325,63876:40326,63877:40327,63878:40328,63879:40329,63880:40330,63881:40331,63882:40332,63883:40333,63884:40334,63885:40335,63886:40336,63887:40337,63888:40338,63889:40339,63890:40340,63891:40341,63892:40342,63893:40343,63894:40344,63895:40345,63896:40346,63897:40347,63898:40348,63899:40349,63900:40350,63901:40351,63902:40352,63903:40353,63904:40354,63905:58002,63906:58003,63907:58004,63908:58005,63909:58006,63910:58007,63911:58008,63912:58009,63913:58010,63914:58011,63915:58012,63916:58013,63917:58014,63918:58015,63919:58016,63920:58017,63921:58018,63922:58019,63923:58020,63924:58021,63925:58022,63926:58023,63927:58024,63928:58025,63929:58026,63930:58027,63931:58028,63932:58029,63933:58030,63934:58031,63935:58032,63936:58033,63937:58034,63938:58035,63939:58036,63940:58037,63941:58038,63942:58039,63943:58040,63944:58041,63945:58042,63946:58043,63947:58044,63948:58045,63949:58046,63950:58047,63951:58048,63952:58049,63953:58050,63954:58051,63955:58052,63956:58053,63957:58054,63958:58055,63959:58056,63960:58057,63961:58058,63962:58059,63963:58060,63964:58061,63965:58062,63966:58063,63967:58064,63968:58065,63969:58066,63970:58067,63971:58068,63972:58069,63973:58070,63974:58071,63975:58072,63976:58073,63977:58074,63978:58075,63979:58076,63980:58077,63981:58078,63982:58079,63983:58080,63984:58081,63985:58082,63986:58083,63987:58084,63988:58085,63989:58086,63990:58087,63991:58088,63992:58089,63993:58090,63994:58091,63995:58092,63996:58093,63997:58094,63998:58095,64064:40355,64065:40356,64066:40357,64067:40358,64068:40359,64069:40360,64070:40361,64071:40362,64072:40363,64073:40364,64074:40365,64075:40366,64076:40367,64077:40368,64078:40369,64079:40370,64080:40371,64081:40372,64082:40373,64083:40374,64084:40375,64085:40376,64086:40377,64087:40378,64088:40379,64089:40380,64090:40381,64091:40382,64092:40383,64093:40384,64094:40385,64095:40386,64096:40387,64097:40388,64098:40389,64099:40390,64100:40391,64101:40392,64102:40393,64103:40394,64104:40395,64105:40396,64106:40397,64107:40398,64108:40399,64109:40400,64110:40401,64111:40402,64112:40403,64113:40404,64114:40405,64115:40406,64116:40407,64117:40408,64118:40409,64119:40410,64120:40411,64121:40412,64122:40413,64123:40414,64124:40415,64125:40416,64126:40417,64128:40418,64129:40419,64130:40420,64131:40421,64132:40422,64133:40423,64134:40424,64135:40425,64136:40426,64137:40427,64138:40428,64139:40429,64140:40430,64141:40431,64142:40432,64143:40433,64144:40434,64145:40435,64146:40436,64147:40437,64148:40438,64149:40439,64150:40440,64151:40441,64152:40442,64153:40443,64154:40444,64155:40445,64156:40446,64157:40447,64158:40448,64159:40449,64160:40450,64161:58096,64162:58097,64163:58098,64164:58099,64165:58100,64166:58101,64167:58102,64168:58103,64169:58104,64170:58105,64171:58106,64172:58107,64173:58108,64174:58109,64175:58110,64176:58111,64177:58112,64178:58113,64179:58114,64180:58115,64181:58116,64182:58117,64183:58118,64184:58119,64185:58120,64186:58121,64187:58122,64188:58123,64189:58124,64190:58125,64191:58126,64192:58127,64193:58128,64194:58129,64195:58130,64196:58131,64197:58132,64198:58133,64199:58134,64200:58135,64201:58136,64202:58137,64203:58138,64204:58139,64205:58140,64206:58141,64207:58142,64208:58143,64209:58144,64210:58145,64211:58146,64212:58147,64213:58148,64214:58149,64215:58150,64216:58151,64217:58152,64218:58153,64219:58154,64220:58155,64221:58156,64222:58157,64223:58158,64224:58159,64225:58160,64226:58161,64227:58162,64228:58163,64229:58164,64230:58165,64231:58166,64232:58167,64233:58168,64234:58169,64235:58170,64236:58171,64237:58172,64238:58173,64239:58174,64240:58175,64241:58176,64242:58177,64243:58178,64244:58179,64245:58180,64246:58181,64247:58182,64248:58183,64249:58184,64250:58185,64251:58186,64252:58187,64253:58188,64254:58189,64320:40451,64321:40452,64322:40453,64323:40454,64324:40455,64325:40456,64326:40457,64327:40458,64328:40459,64329:40460,64330:40461,64331:40462,64332:40463,64333:40464,64334:40465,64335:40466,64336:40467,64337:40468,64338:40469,64339:40470,64340:40471,64341:40472,64342:40473,64343:40474,64344:40475,64345:40476,64346:40477,64347:40478,64348:40484,64349:40487,64350:40494,64351:40496,64352:40500,64353:40507,64354:40508,64355:40512,64356:40525,64357:40528,64358:40530,64359:40531,64360:40532,64361:40534,64362:40537,64363:40541,64364:40543,64365:40544,64366:40545,64367:40546,64368:40549,64369:40558,64370:40559,64371:40562,64372:40564,64373:40565,64374:40566,64375:40567,64376:40568,64377:40569,64378:40570,64379:40571,64380:40572,64381:40573,64382:40576,64384:40577,64385:40579,64386:40580,64387:40581,64388:40582,64389:40585,64390:40586,64391:40588,64392:40589,64393:40590,64394:40591,64395:40592,64396:40593,64397:40596,64398:40597,64399:40598,64400:40599,64401:40600,64402:40601,64403:40602,64404:40603,64405:40604,64406:40606,64407:40608,64408:40609,64409:40610,64410:40611,64411:40612,64412:40613,64413:40615,64414:40616,64415:40617,64416:40618,64417:58190,64418:58191,64419:58192,64420:58193,64421:58194,64422:58195,64423:58196,64424:58197,64425:58198,64426:58199,64427:58200,64428:58201,64429:58202,64430:58203,64431:58204,64432:58205,64433:58206,64434:58207,64435:58208,64436:58209,64437:58210,64438:58211,64439:58212,64440:58213,64441:58214,64442:58215,64443:58216,64444:58217,64445:58218,64446:58219,64447:58220,64448:58221,64449:58222,64450:58223,64451:58224,64452:58225,64453:58226,64454:58227,64455:58228,64456:58229,64457:58230,64458:58231,64459:58232,64460:58233,64461:58234,64462:58235,64463:58236,64464:58237,64465:58238,64466:58239,64467:58240,64468:58241,64469:58242,64470:58243,64471:58244,64472:58245,64473:58246,64474:58247,64475:58248,64476:58249,64477:58250,64478:58251,64479:58252,64480:58253,64481:58254,64482:58255,64483:58256,64484:58257,64485:58258,64486:58259,64487:58260,64488:58261,64489:58262,64490:58263,64491:58264,64492:58265,64493:58266,64494:58267,64495:58268,64496:58269,64497:58270,64498:58271,64499:58272,64500:58273,64501:58274,64502:58275,64503:58276,64504:58277,64505:58278,64506:58279,64507:58280,64508:58281,64509:58282,64510:58283,64576:40619,64577:40620,64578:40621,64579:40622,64580:40623,64581:40624,64582:40625,64583:40626,64584:40627,64585:40629,64586:40630,64587:40631,64588:40633,64589:40634,64590:40636,64591:40639,64592:40640,64593:40641,64594:40642,64595:40643,64596:40645,64597:40646,64598:40647,64599:40648,64600:40650,64601:40651,64602:40652,64603:40656,64604:40658,64605:40659,64606:40661,64607:40662,64608:40663,64609:40665,64610:40666,64611:40670,64612:40673,64613:40675,64614:40676,64615:40678,64616:40680,64617:40683,64618:40684,64619:40685,64620:40686,64621:40688,64622:40689,64623:40690,64624:40691,64625:40692,64626:40693,64627:40694,64628:40695,64629:40696,64630:40698,64631:40701,64632:40703,64633:40704,64634:40705,64635:40706,64636:40707,64637:40708,64638:40709,64640:40710,64641:40711,64642:40712,64643:40713,64644:40714,64645:40716,64646:40719,64647:40721,64648:40722,64649:40724,64650:40725,64651:40726,64652:40728,64653:40730,64654:40731,64655:40732,64656:40733,64657:40734,64658:40735,64659:40737,64660:40739,64661:40740,64662:40741,64663:40742,64664:40743,64665:40744,64666:40745,64667:40746,64668:40747,64669:40749,64670:40750,64671:40752,64672:40753,64673:58284,64674:58285,64675:58286,64676:58287,64677:58288,64678:58289,64679:58290,64680:58291,64681:58292,64682:58293,64683:58294,64684:58295,64685:58296,64686:58297,64687:58298,64688:58299,64689:58300,64690:58301,64691:58302,64692:58303,64693:58304,64694:58305,64695:58306,64696:58307,64697:58308,64698:58309,64699:58310,64700:58311,64701:58312,64702:58313,64703:58314,64704:58315,64705:58316,64706:58317,64707:58318,64708:58319,64709:58320,64710:58321,64711:58322,64712:58323,64713:58324,64714:58325,64715:58326,64716:58327,64717:58328,64718:58329,64719:58330,64720:58331,64721:58332,64722:58333,64723:58334,64724:58335,64725:58336,64726:58337,64727:58338,64728:58339,64729:58340,64730:58341,64731:58342,64732:58343,64733:58344,64734:58345,64735:58346,64736:58347,64737:58348,64738:58349,64739:58350,64740:58351,64741:58352,64742:58353,64743:58354,64744:58355,64745:58356,64746:58357,64747:58358,64748:58359,64749:58360,64750:58361,64751:58362,64752:58363,64753:58364,64754:58365,64755:58366,64756:58367,64757:58368,64758:58369,64759:58370,64760:58371,64761:58372,64762:58373,64763:58374,64764:58375,64765:58376,64766:58377,64832:40754,64833:40755,64834:40756,64835:40757,64836:40758,64837:40760,64838:40762,64839:40764,64840:40767,64841:40768,64842:40769,64843:40770,64844:40771,64845:40773,64846:40774,64847:40775,64848:40776,64849:40777,64850:40778,64851:40779,64852:40780,64853:40781,64854:40782,64855:40783,64856:40786,64857:40787,64858:40788,64859:40789,64860:40790,64861:40791,64862:40792,64863:40793,64864:40794,64865:40795,64866:40796,64867:40797,64868:40798,64869:40799,64870:40800,64871:40801,64872:40802,64873:40803,64874:40804,64875:40805,64876:40806,64877:40807,64878:40808,64879:40809,64880:40810,64881:40811,64882:40812,64883:40813,64884:40814,64885:40815,64886:40816,64887:40817,64888:40818,64889:40819,64890:40820,64891:40821,64892:40822,64893:40823,64894:40824,64896:40825,64897:40826,64898:40827,64899:40828,64900:40829,64901:40830,64902:40833,64903:40834,64904:40845,64905:40846,64906:40847,64907:40848,64908:40849,64909:40850,64910:40851,64911:40852,64912:40853,64913:40854,64914:40855,64915:40856,64916:40860,64917:40861,64918:40862,64919:40865,64920:40866,64921:40867,64922:40868,64923:40869,64924:63788,64925:63865,64926:63893,64927:63975,64928:63985,64929:58378,64930:58379,64931:58380,64932:58381,64933:58382,64934:58383,64935:58384,64936:58385,64937:58386,64938:58387,64939:58388,64940:58389,64941:58390,64942:58391,64943:58392,64944:58393,64945:58394,64946:58395,64947:58396,64948:58397,64949:58398,64950:58399,64951:58400,64952:58401,64953:58402,64954:58403,64955:58404,64956:58405,64957:58406,64958:58407,64959:58408,64960:58409,64961:58410,64962:58411,64963:58412,64964:58413,64965:58414,64966:58415,64967:58416,64968:58417,64969:58418,64970:58419,64971:58420,64972:58421,64973:58422,64974:58423,64975:58424,64976:58425,64977:58426,64978:58427,64979:58428,64980:58429,64981:58430,64982:58431,64983:58432,64984:58433,64985:58434,64986:58435,64987:58436,64988:58437,64989:58438,64990:58439,64991:58440,64992:58441,64993:58442,64994:58443,64995:58444,64996:58445,64997:58446,64998:58447,64999:58448,65000:58449,65001:58450,65002:58451,65003:58452,65004:58453,65005:58454,65006:58455,65007:58456,65008:58457,65009:58458,65010:58459,65011:58460,65012:58461,65013:58462,65014:58463,65015:58464,65016:58465,65017:58466,65018:58467,65019:58468,65020:58469,65021:58470,65022:58471,65088:64012,65089:64013,65090:64014,65091:64015,65092:64017,65093:64019,65094:64020,65095:64024,65096:64031,65097:64032,65098:64033,65099:64035,65100:64036,65101:64039,65102:64040,65103:64041,65104:11905,65105:59414,65106:59415,65107:59416,65108:11908,65109:13427,65110:13383,65111:11912,65112:11915,65113:59422,65114:13726,65115:13850,65116:13838,65117:11916,65118:11927,65119:14702,65120:14616,65121:59430,65122:14799,65123:14815,65124:14963,65125:14800,65126:59435,65127:59436,65128:15182,65129:15470,65130:15584,65131:11943,65132:59441,65133:59442,65134:11946,65135:16470,65136:16735,65137:11950,65138:17207,65139:11955,65140:11958,65141:11959,65142:59451,65143:17329,65144:17324,65145:11963,65146:17373,65147:17622,65148:18017,65149:17996,65150:59459,65152:18211,65153:18217,65154:18300,65155:18317,65156:11978,65157:18759,65158:18810,65159:18813,65160:18818,65161:18819,65162:18821,65163:18822,65164:18847,65165:18843,65166:18871,65167:18870,65168:59476,65169:59477,65170:19619,65171:19615,65172:19616,65173:19617,65174:19575,65175:19618,65176:19731,65177:19732,65178:19733,65179:19734,65180:19735,65181:19736,65182:19737,65183:19886,65184:59492,65185:58472,65186:58473,65187:58474,65188:58475,65189:58476,65190:58477,65191:58478,65192:58479,65193:58480,65194:58481,65195:58482,65196:58483,65197:58484,65198:58485,65199:58486,65200:58487,65201:58488,65202:58489,65203:58490,65204:58491,65205:58492,65206:58493,65207:58494,65208:58495,65209:58496,65210:58497,65211:58498,65212:58499,65213:58500,65214:58501,65215:58502,65216:58503,65217:58504,65218:58505,65219:58506,65220:58507,65221:58508,65222:58509,65223:58510,65224:58511,65225:58512,65226:58513,65227:58514,65228:58515,65229:58516,65230:58517,65231:58518,65232:58519,65233:58520,65234:58521,65235:58522,65236:58523,65237:58524,65238:58525,65239:58526,65240:58527,65241:58528,65242:58529,65243:58530,65244:58531,65245:58532,65246:58533,65247:58534,65248:58535,65249:58536,65250:58537,65251:58538,65252:58539,65253:58540,65254:58541,65255:58542,65256:58543,65257:58544,65258:58545,65259:58546,65260:58547,65261:58548,65262:58549,65263:58550,65264:58551,65265:58552,65266:58553,65267:58554,65268:58555,65269:58556,65270:58557,65271:58558,65272:58559,65273:58560,65274:58561,65275:58562,65276:58563,65277:58564,65278:58565} \ No newline at end of file diff --git a/node_modules/iconv-lite/generation/generate-big5-table.js b/node_modules/iconv-lite/generation/generate-big5-table.js new file mode 100644 index 0000000..909e433 --- /dev/null +++ b/node_modules/iconv-lite/generation/generate-big5-table.js @@ -0,0 +1,25 @@ +var http = require('http'); +var fs = require('fs'); +// BIG5 +var cp950_b2u = {host:'moztw.org',path:'/docs/big5/table/cp950-b2u.txt'}, + cp950_u2b = {host:'moztw.org',path:'/docs/big5/table/cp950-u2b.txt'}, + cp950_moz18_b2u = {host:'moztw.org',path:'/docs/big5/table/moz18-b2u.txt'}; + +http.get(cp950_moz18_b2u, function(res) { + var data = ''; + res.on('data', function(chunk) { + data += chunk; + }); + res.on('end', function() { + var table = {}; + data = data.split('\n').slice(1); + data.forEach(function(line, idx) { + var pair = line.split(' '); + var key = parseInt(pair[0]); + var val = parseInt(pair[1]); + table[key] = val; + }); + fs.createWriteSync('encodings/table/big5.js', + 'module.exports = ' + JSON.stringify(table) + ';'); + }); +}); diff --git a/node_modules/iconv-lite/generation/generate-singlebyte.js b/node_modules/iconv-lite/generation/generate-singlebyte.js new file mode 100644 index 0000000..2cbebec --- /dev/null +++ b/node_modules/iconv-lite/generation/generate-singlebyte.js @@ -0,0 +1,142 @@ +var fs = require("fs"); +var Iconv = require("iconv").Iconv; + + +var encodingFamilies = [ + { + // Windows code pages + encodings: [1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258], + convert: function(cp) { + return { + name: "windows-"+cp, + aliases: ["win"+cp, "cp"+cp, ""+cp], + } + } + }, + { + // ISO-8859 code pages + encodings: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16], + convert: function(i) { + return { + name: "iso-8859-"+i, + aliases: ["cp"+(28590+i), (28590+i)], + } + } + }, + { + // IBM/DOS code pages + encodings: [437, 737, 775, 850, 852, 855, 857, 858, 860, 861, 862, 863, 864, 865, 866, 869], + convert: function(cp) { + return { + name: "CP"+cp, + aliases: ["ibm"+cp, ""+cp], + } + } + }, + { + // Macintosh code pages + encodings: ["macCroatian", "macCyrillic", "macGreek", + "macIceland", "macRoman", "macRomania", + "macThai", "macTurkish", "macUkraine"], + }, + { + // KOI8 code pages + encodings: ["KOI8-R", "KOI8-U"], + }, +]; + + +var encodings = { + // Aliases. + "ascii8bit": "ascii", + "usascii": "ascii", + + "latin1": "iso88591", + "latin2": "iso88592", + "latin3": "iso88593", + "latin4": "iso88594", + "latin6": "iso885910", + "latin7": "iso885913", + "latin8": "iso885914", + "latin9": "iso885915", + "latin10": "iso885916", + + "cp819": "iso88951", + "arabic": "iso88596", + "arabic8": "iso88596", + "greek" : "iso88597", + "greek8" : "iso88597", + "hebrew": "iso88598", + "hebrew8": "iso88598", + "turkish": "iso88599", + "turkish8": "iso88599", + "thai": "iso885911", + "thai8": "iso885911", + "tis620": "iso885911", + "windows874": "iso885911", + "win874": "iso885911", + "cp874": "iso885911", + "874": "iso885911", + "celtic": "iso885914", + "celtic8": "iso885914", + + "cp20866": "koi8r", + "20866": "koi8r", + "ibm878": "koi8r", + "cp21866": "koi8u", + "21866": "koi8u", + "ibm1168": "koi8u", + +}; + +// Add all encodings from encodingFamilies. +encodingFamilies.forEach(function(family){ + family.encodings.forEach(function(encoding){ + if (family.convert) + encoding = family.convert(encoding); + + var encodingIconvName = encoding.name ? encoding.name : encoding; + var encodingName = encodingIconvName.replace(/[-_]/g, "").toLowerCase(); + + encodings[encodingName] = { + type: "singlebyte", + chars: generateCharsString(encodingIconvName) + }; + + if (encoding.aliases) + encoding.aliases.forEach(function(alias){ + encodings[alias] = encodingName; + }); + }); +}); + +// Write encodings. +fs.writeFileSync("encodings/singlebyte.js", + "module.exports = " + JSON.stringify(encodings, undefined, " ") + ";"); + + +function generateCharsString(encoding) { + console.log("Generate encoding for " + encoding); + var iconvToUtf8 = new Iconv(encoding, "UTF-8"); + var chars = ""; + + for (var b = 0x80; b < 0x100; b++) { + + try { + var convertedChar = iconvToUtf8.convert(new Buffer([b])).toString(); + + if (convertedChar.length != 1) + throw new Error("Single-byte encoding error: Must return single char."); + } catch (exception) { + if (exception.code === "EILSEQ") { + convertedChar = "\ufffd"; + } else { + throw exception; + } + } + + chars += convertedChar; + } + + return chars; +} diff --git a/node_modules/iconv-lite/index.js b/node_modules/iconv-lite/index.js new file mode 100644 index 0000000..a55691b --- /dev/null +++ b/node_modules/iconv-lite/index.js @@ -0,0 +1,231 @@ +var RE_SPACEDASH = /[- ]/g; +// Module exports +var iconv = module.exports = { + toEncoding: function(str, encoding) { + return iconv.getCodec(encoding).toEncoding(str); + }, + fromEncoding: function(buf, encoding) { + return iconv.getCodec(encoding).fromEncoding(buf); + }, + encodingExists: function(enc) { + loadEncodings(); + enc = enc.replace(RE_SPACEDASH, "").toLowerCase(); + return (iconv.encodings[enc] !== undefined); + }, + + defaultCharUnicode: '�', + defaultCharSingleByte: '?', + + encodingsLoaded: false, + + // Get correct codec for given encoding. + getCodec: function(encoding) { + loadEncodings(); + var enc = encoding || "utf8"; + var codecOptions = undefined; + while (1) { + if (getType(enc) === "String") + enc = enc.replace(RE_SPACEDASH, "").toLowerCase(); + var codec = iconv.encodings[enc]; + var type = getType(codec); + if (type === "String") { + // Link to other encoding. + codecOptions = {originalEncoding: enc}; + enc = codec; + } + else if (type === "Object" && codec.type != undefined) { + // Options for other encoding. + codecOptions = codec; + enc = codec.type; + } + else if (type === "Function") + // Codec itself. + return codec(codecOptions); + else + throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '"+enc+"')"); + } + }, + + // Define basic encodings + encodings: { + internal: function(options) { + return { + toEncoding: toInternalEncoding, + fromEncoding: fromInternalEncoding, + options: options + }; + }, + utf8: "internal", + ucs2: "internal", + binary: "internal", + ascii: "internal", + base64: "internal", + + // Codepage single-byte encodings. + singlebyte: function(options) { + // Prepare chars if needed + if (!options.charsBuf) { + if (!options.chars || (options.chars.length !== 128 && options.chars.length !== 256)) + throw new Error("Encoding '"+options.type+"' has incorrect 'chars' (must be of len 128 or 256)"); + + if (options.chars.length === 128) + options.chars = asciiString + options.chars; + + options.charsBuf = new Buffer(options.chars, 'ucs2'); + } + + if (!options.revCharsBuf) { + options.revCharsBuf = new Buffer(65536); + var defChar = iconv.defaultCharSingleByte.charCodeAt(0); + for (var i = 0; i < options.revCharsBuf.length; i++) + options.revCharsBuf[i] = defChar; + for (var i = 0; i < options.chars.length; i++) + options.revCharsBuf[options.chars.charCodeAt(i)] = i; + } + + return { + toEncoding: toSingleByteEncoding, + fromEncoding: fromSingleByteEncoding, + options: options, + }; + }, + + // Codepage double-byte encodings. + table: function(options) { + if (!options.table) { + throw new Error("Encoding '" + options.type + "' has incorect 'table' option"); + } + if (!options.revCharsTable) { + var revCharsTable = options.revCharsTable = {}; + for (var i = 0; i <= 0xFFFF; i++) { + revCharsTable[i] = 0; + } + + var table = options.table; + for (var key in table) { + revCharsTable[table[key]] = +key; + } + } + + return { + toEncoding: toTableEncoding, + fromEncoding: fromTableEncoding, + options: options, + }; + } + } +}; + +function toInternalEncoding(str) { + return new Buffer(ensureString(str), this.options.originalEncoding); +} + +function fromInternalEncoding(buf) { + return ensureBuffer(buf).toString(this.options.originalEncoding); +} + +function toTableEncoding(str) { + str = ensureString(str); + var strLen = str.length; + var revCharsTable = this.options.revCharsTable; + var newBuf = new Buffer(strLen*2), gbkcode, unicode, + defaultChar = revCharsTable[iconv.defaultCharUnicode.charCodeAt(0)]; + + for (var i = 0, j = 0; i < strLen; i++) { + unicode = str.charCodeAt(i); + if (unicode >> 7) { + gbkcode = revCharsTable[unicode] || defaultChar; + newBuf[j++] = gbkcode >> 8; //high byte; + newBuf[j++] = gbkcode & 0xFF; //low byte + } else {//ascii + newBuf[j++] = unicode; + } + } + return newBuf.slice(0, j); +} + +function fromTableEncoding(buf) { + buf = ensureBuffer(buf); + var bufLen = buf.length; + var table = this.options.table; + var newBuf = new Buffer(bufLen*2), unicode, gbkcode, + defaultChar = iconv.defaultCharUnicode.charCodeAt(0); + + for (var i = 0, j = 0; i < bufLen; i++, j+=2) { + gbkcode = buf[i]; + if (gbkcode & 0x80) { + gbkcode = (gbkcode << 8) + buf[++i]; + unicode = table[gbkcode] || defaultChar; + } else { + unicode = gbkcode; + } + newBuf[j] = unicode & 0xFF; //low byte + newBuf[j+1] = unicode >> 8; //high byte + } + return newBuf.slice(0, j).toString('ucs2'); +} + +function toSingleByteEncoding(str) { + str = ensureString(str); + + var buf = new Buffer(str.length); + var revCharsBuf = this.options.revCharsBuf; + for (var i = 0; i < str.length; i++) + buf[i] = revCharsBuf[str.charCodeAt(i)]; + + return buf; +} + +function fromSingleByteEncoding(buf) { + buf = ensureBuffer(buf); + + // Strings are immutable in JS -> we use ucs2 buffer to speed up computations. + var charsBuf = this.options.charsBuf; + var newBuf = new Buffer(buf.length*2); + var idx1 = 0, idx2 = 0; + for (var i = 0, _len = buf.length; i < _len; i++) { + idx1 = buf[i]*2; idx2 = i*2; + newBuf[idx2] = charsBuf[idx1]; + newBuf[idx2+1] = charsBuf[idx1+1]; + } + return newBuf.toString('ucs2'); +} + +// Add aliases to convert functions +iconv.encode = iconv.toEncoding; +iconv.decode = iconv.fromEncoding; + +// Load other encodings manually from files in /encodings dir. +function loadEncodings() { + if (!iconv.encodingsLoaded) { + [ require('./encodings/singlebyte'), + require('./encodings/gbk'), + require('./encodings/big5') + ].forEach(function(encodings) { + for (var key in encodings) + iconv.encodings[key] = encodings[key] + }); + iconv.encodingsLoaded = true; + } +} + + + +// Utilities +var asciiString = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'+ + ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f'; + +var ensureBuffer = function(buf) { + buf = buf || new Buffer(0); + return (buf instanceof Buffer) ? buf : new Buffer(""+buf, "binary"); +} + +var ensureString = function(str) { + str = str || ""; + return (str instanceof Buffer) ? str.toString('utf8') : (""+str); +} + +var getType = function(obj) { + return Object.prototype.toString.call(obj).slice(8, -1); +} + diff --git a/node_modules/iconv-lite/package.json b/node_modules/iconv-lite/package.json new file mode 100644 index 0000000..d0bd008 --- /dev/null +++ b/node_modules/iconv-lite/package.json @@ -0,0 +1,131 @@ +{ + "_args": [ + [ + { + "raw": "iconv-lite@~0.2.11", + "scope": null, + "escapedName": "iconv-lite", + "name": "iconv-lite", + "rawSpec": "~0.2.11", + "spec": ">=0.2.11 <0.3.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt" + ] + ], + "_from": "iconv-lite@>=0.2.11 <0.3.0", + "_id": "iconv-lite@0.2.11", + "_inCache": true, + "_location": "/iconv-lite", + "_npmUser": { + "name": "ashtuchkin", + "email": "ashtuchkin@gmail.com" + }, + "_npmVersion": "1.3.2", + "_phantomChildren": {}, + "_requested": { + "raw": "iconv-lite@~0.2.11", + "scope": null, + "escapedName": "iconv-lite", + "name": "iconv-lite", + "rawSpec": "~0.2.11", + "spec": ">=0.2.11 <0.3.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt" + ], + "_resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz", + "_shasum": "1ce60a3a57864a292d1321ff4609ca4bb965adc8", + "_shrinkwrap": null, + "_spec": "iconv-lite@~0.2.11", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt", + "author": { + "name": "Alexander Shtuchkin", + "email": "ashtuchkin@gmail.com" + }, + "bugs": { + "url": "https://github.com/ashtuchkin/iconv-lite/issues" + }, + "contributors": [ + { + "name": "Jinwu Zhan", + "url": "https://github.com/jenkinv" + }, + { + "name": "Adamansky Anton", + "url": "https://github.com/adamansky" + }, + { + "name": "George Stagas", + "url": "https://github.com/stagas" + }, + { + "name": "Mike D Pilsbury", + "url": "https://github.com/pekim" + }, + { + "name": "Niggler", + "url": "https://github.com/Niggler" + }, + { + "name": "wychi", + "url": "https://github.com/wychi" + }, + { + "name": "David Kuo", + "url": "https://github.com/david50407" + }, + { + "name": "ChangZhuo Chen", + "url": "https://github.com/czchen" + }, + { + "name": "Lee Treveil", + "url": "https://github.com/leetreveil" + }, + { + "name": "Brian White", + "url": "https://github.com/mscdex" + } + ], + "dependencies": {}, + "description": "Convert character encodings in pure javascript.", + "devDependencies": { + "iconv": ">=1.1", + "vows": "" + }, + "directories": {}, + "dist": { + "shasum": "1ce60a3a57864a292d1321ff4609ca4bb965adc8", + "tarball": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz" + }, + "engines": { + "node": ">=0.4.0" + }, + "homepage": "https://github.com/ashtuchkin/iconv-lite", + "keywords": [ + "iconv", + "convert", + "charset" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "ashtuchkin", + "email": "ashtuchkin@gmail.com" + } + ], + "name": "iconv-lite", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/ashtuchkin/iconv-lite.git" + }, + "scripts": { + "test": "vows --spec" + }, + "version": "0.2.11" +} diff --git a/node_modules/iconv-lite/test/big5-test.js b/node_modules/iconv-lite/test/big5-test.js new file mode 100644 index 0000000..f3fe1a8 --- /dev/null +++ b/node_modules/iconv-lite/test/big5-test.js @@ -0,0 +1,36 @@ +var vows = require('vows'), + fs = require('fs'), + assert = require('assert'), + iconv = require(__dirname + '/../'); + +var testString = "中文abc", //unicode contains Big5-code and ascii + testStringBig5Buffer = new Buffer([0xa4,0xa4,0xa4,0xe5,0x61,0x62,0x63]), + testString2 = '測試', + testStringBig5Buffer2 = new Buffer([0xb4, 0xfa, 0xb8, 0xd5]); + +vows.describe("Big5 tests").addBatch({ + "Big5 correctly encoded/decoded": function() { + assert.strictEqual(iconv.toEncoding(testString, "big5").toString('binary'), testStringBig5Buffer.toString('binary')); + assert.strictEqual(iconv.fromEncoding(testStringBig5Buffer, "big5"), testString); + assert.strictEqual(iconv.toEncoding(testString2, 'big5').toString('binary'), testStringBig5Buffer2.toString('binary')); + assert.strictEqual(iconv.fromEncoding(testStringBig5Buffer2, 'big5'), testString2); + }, + "cp950 correctly encoded/decoded": function() { + assert.strictEqual(iconv.toEncoding(testString, "cp950").toString('binary'), testStringBig5Buffer.toString('binary')); + assert.strictEqual(iconv.fromEncoding(testStringBig5Buffer, "cp950"), testString); + }, + "Big5 file read decoded,compare with iconv result": function() { + var contentBuffer = fs.readFileSync(__dirname+"/big5File.txt"); + var str = iconv.fromEncoding(contentBuffer, "big5"); + var iconvc = new (require('iconv').Iconv)('big5','utf8'); + assert.strictEqual(iconvc.convert(contentBuffer).toString(), str); + }, + "Big5 correctly decodes and encodes characters · and ×": function() { + // https://github.com/ashtuchkin/iconv-lite/issues/13 + // Reference: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT + var chars = "·×"; + var big5Chars = new Buffer([0xA1, 0x50, 0xA1, 0xD1]); + assert.strictEqual(iconv.toEncoding(chars, "big5").toString('binary'), big5Chars.toString('binary')); + assert.strictEqual(iconv.fromEncoding(big5Chars, "big5"), chars) + }, +}).export(module) diff --git a/node_modules/iconv-lite/test/big5File.txt b/node_modules/iconv-lite/test/big5File.txt new file mode 100644 index 0000000..9c13042 --- /dev/null +++ b/node_modules/iconv-lite/test/big5File.txt @@ -0,0 +1,13 @@ + + + meta ҪϥΡG + + + + +oO@c餤I
          +(This page uses big5 character set.)
          +charset=big5 + + + \ No newline at end of file diff --git a/node_modules/iconv-lite/test/cyrillic-test.js b/node_modules/iconv-lite/test/cyrillic-test.js new file mode 100644 index 0000000..259d283 --- /dev/null +++ b/node_modules/iconv-lite/test/cyrillic-test.js @@ -0,0 +1,86 @@ +var vows = require('vows'), + assert = require('assert'), + iconv = require(__dirname+'/../'); + +var baseStrings = { + empty: "", + hi: "Привет!", + ascii: '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'+ + ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f', + rus: "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя", + additional1: "ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋЏђ‘’“”•–—™љ›њќћџ ЎўЈ¤Ґ¦§Ё©Є«¬\xAD®Ї°±Ііґµ¶·ё№є»јЅѕї", + additional2: "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ё╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡Ё╢╣╤╥╦╧╨╩╪╫╬©", + additional3: " ЁЂЃЄЅІЇЈЉЊЋЌ­ЎЏ№ёђѓєѕіїјљњћќ§ўџ", + untranslatable: "£Åçþÿ¿", +}; + +var encodings = [{ + name: "Win-1251", + variations: ['win1251', 'Windows-1251', 'windows1251', 'CP1251', 1251], + encodedStrings: { + empty: new Buffer(''), + hi: new Buffer('\xcf\xf0\xe8\xe2\xe5\xf2!', 'binary'), + ascii: new Buffer(baseStrings.ascii, 'binary'), + rus: new Buffer('\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff', 'binary'), + additional1: new Buffer('\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf','binary'), + } +}, { + name: "Koi8-R", + variations: ['koi8r', 'KOI8-R', 'cp20866', 20866], + encodedStrings: { + empty: new Buffer(''), + hi: new Buffer('\xf0\xd2\xc9\xd7\xc5\xd4!', 'binary'), + ascii: new Buffer(baseStrings.ascii, 'binary'), + rus: new Buffer('\xe1\xe2\xf7\xe7\xe4\xe5\xf6\xfa\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf2\xf3\xf4\xf5\xe6\xe8\xe3\xfe\xfb\xfd\xff\xf9\xf8\xfc\xe0\xf1\xc1\xc2\xd7\xc7\xc4\xc5\xd6\xda\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd2\xd3\xd4\xd5\xc6\xc8\xc3\xde\xdb\xdd\xdf\xd9\xd8\xdc\xc0\xd1', 'binary'), + additional2: new Buffer('\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf', 'binary'), + } +}, { + name: "ISO 8859-5", + variations: ['iso88595', 'ISO-8859-5', 'ISO 8859-5', 'cp28595', 28595], + encodedStrings: { + empty: new Buffer(''), + hi: new Buffer('\xbf\xe0\xd8\xd2\xd5\xe2!', 'binary'), + ascii: new Buffer(baseStrings.ascii, 'binary'), + rus: new Buffer('\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef', 'binary'), + additional3: new Buffer('\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff', 'binary'), + } +}]; + +var testsBatch = {}; +encodings.forEach(function(encoding) { + var enc = encoding.variations[0]; + var key = "hi"; + var tests = { + "Convert to empty buffer": function() { + assert.strictEqual(iconv.toEncoding("", enc).toString('binary'), new Buffer('').toString('binary')); + }, + "Convert from empty buffer": function() { + assert.strictEqual(iconv.fromEncoding(new Buffer(''), enc), ""); + }, + "Convert from buffer": function() { + for (var key in encoding.encodedStrings) + assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), + baseStrings[key]); + }, + "Convert to buffer": function() { + for (var key in encoding.encodedStrings) + assert.strictEqual(iconv.toEncoding(baseStrings[key], enc).toString('binary'), + encoding.encodedStrings[key].toString('binary')); + }, + "Try different variations of encoding": function() { + encoding.variations.forEach(function(enc) { + assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), baseStrings[key]); + assert.strictEqual(iconv.toEncoding(baseStrings[key], enc).toString('binary'), encoding.encodedStrings[key].toString('binary')); + }); + }, + "Untranslatable chars are converted to defaultCharSingleByte": function() { + var expected = baseStrings.untranslatable.split('').map(function(c) {return iconv.defaultCharSingleByte; }).join(''); + assert.strictEqual(iconv.toEncoding(baseStrings.untranslatable, enc).toString('binary'), expected); // Only '?' characters. + } + }; + + testsBatch[encoding.name+":"] = tests; +}); + +vows.describe("Test Cyrillic encodings").addBatch(testsBatch).export(module); + diff --git a/node_modules/iconv-lite/test/gbk-test.js b/node_modules/iconv-lite/test/gbk-test.js new file mode 100644 index 0000000..7b2e47b --- /dev/null +++ b/node_modules/iconv-lite/test/gbk-test.js @@ -0,0 +1,38 @@ +var vows = require('vows'), + fs = require('fs'), + assert = require('assert'), + iconv = require(__dirname+'/../'); + +var testString = "中国abc",//unicode contains GBK-code and ascii + testStringGBKBuffer = new Buffer([0xd6,0xd0,0xb9,0xfa,0x61,0x62,0x63]); + +vows.describe("GBK tests").addBatch({ + "Vows is working": function() {}, + "Return values are of correct types": function() { + assert.ok(iconv.toEncoding(testString, "utf8") instanceof Buffer); + var s = iconv.fromEncoding(new Buffer(testString), "utf8"); + assert.strictEqual(Object.prototype.toString.call(s), "[object String]"); + }, + "GBK correctly encoded/decoded": function() { + assert.strictEqual(iconv.toEncoding(testString, "GBK").toString('binary'), testStringGBKBuffer.toString('binary')); + assert.strictEqual(iconv.fromEncoding(testStringGBKBuffer, "GBK"), testString); + }, + "GB2312 correctly encoded/decoded": function() { + assert.strictEqual(iconv.toEncoding(testString, "GB2312").toString('binary'), testStringGBKBuffer.toString('binary')); + assert.strictEqual(iconv.fromEncoding(testStringGBKBuffer, "GB2312"), testString); + }, + "GBK file read decoded,compare with iconv result": function() { + var contentBuffer = fs.readFileSync(__dirname+"/gbkFile.txt"); + var str = iconv.fromEncoding(contentBuffer, "GBK"); + var iconvc = new (require('iconv').Iconv)('GBK','utf8'); + assert.strictEqual(iconvc.convert(contentBuffer).toString(), str); + }, + "GBK correctly decodes and encodes characters · and ×": function() { + // https://github.com/ashtuchkin/iconv-lite/issues/13 + // Reference: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT + var chars = "·×"; + var gbkChars = new Buffer([0xA1, 0xA4, 0xA1, 0xC1]); + assert.strictEqual(iconv.toEncoding(chars, "GBK").toString('binary'), gbkChars.toString('binary')); + assert.strictEqual(iconv.fromEncoding(gbkChars, "GBK"), chars) + }, +}).export(module) diff --git a/node_modules/iconv-lite/test/gbkFile.txt b/node_modules/iconv-lite/test/gbkFile.txt new file mode 100644 index 0000000..345b5d0 --- /dev/null +++ b/node_modules/iconv-lite/test/gbkFile.txt @@ -0,0 +1,14 @@ +ٶһ£֪ + + +
           | ¼
          + + + + + + + + \ No newline at end of file diff --git a/node_modules/iconv-lite/test/greek-test.js b/node_modules/iconv-lite/test/greek-test.js new file mode 100644 index 0000000..0394ee6 --- /dev/null +++ b/node_modules/iconv-lite/test/greek-test.js @@ -0,0 +1,79 @@ +var vows = require('vows'), + assert = require('assert'), + iconv = require(__dirname+'/../'); + +var baseStrings = { + empty: "", + hi: "Γειά!", + ascii: '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'+ + ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f', + greek: "αβγδεζηθικλμνξοπρστυφχψωΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩάέήίόύώΆΈΉΊΌΎΏϊϋΪΫ", + untranslatable: "Åçþÿ¿" +}; + +var encodings = [{ + name: "windows1253", + variations: ['windows-1253', 'win-1253', 'win1253', 'cp1253', 'cp-1253', 1253], + encodedStrings: { + empty: new Buffer(''), + hi: new Buffer('\xc3\xe5\xe9\xdc!', 'binary'), + ascii: new Buffer(baseStrings.ascii, 'binary'), + greek: new Buffer('\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xdc\xdd\xde\xdf\xfc\xfd\xfe\xa2\xb8\xb9\xba\xbc\xbe\xbf\xfa\xfb\xda\xdb', 'binary'), + } +}, { + name: "iso88597", + variations: ['iso-8859-7', 'greek', 'greek8', 'cp28597', 'cp-28597', 28597], + encodedStrings: { + empty: new Buffer(''), + hi: new Buffer('\xc3\xe5\xe9\xdc!', 'binary'), + ascii: new Buffer(baseStrings.ascii, 'binary'), + greek: new Buffer('\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xdc\xdd\xde\xdf\xfc\xfd\xfe\xb6\xb8\xb9\xba\xbc\xbe\xbf\xfa\xfb\xda\xdb', 'binary'), + } +}, { + name: "cp737", + variations: ['cp-737', 737], + encodedStrings: { + empty: new Buffer(''), + hi: new Buffer('\x82\x9c\xa0\xe1!', 'binary'), + ascii: new Buffer(baseStrings.ascii, 'binary'), + greek: new Buffer('\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xab\xac\xad\xae\xaf\xe0\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\xe1\xe2\xe3\xe5\xe6\xe7\xe9\xea\xeb\xec\xed\xee\xef\xf0\xe4\xe8\xf4\xf5', 'binary'), + } +}]; + +var testsBatch = {}; +encodings.forEach(function(encoding) { + var enc = encoding.variations[0]; + var key = "hi"; + var tests = { + "Convert to empty buffer": function() { + assert.strictEqual(iconv.toEncoding("", enc).toString('binary'), new Buffer('').toString('binary')); + }, + "Convert from empty buffer": function() { + assert.strictEqual(iconv.fromEncoding(new Buffer(''), enc), ""); + }, + "Convert from buffer": function() { + for (var key in encoding.encodedStrings) + assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), + baseStrings[key]); + }, + "Convert to buffer": function() { + for (var key in encoding.encodedStrings) + assert.strictEqual(iconv.toEncoding(baseStrings[key], enc).toString('binary'), + encoding.encodedStrings[key].toString('binary')); + }, + "Try different variations of encoding": function() { + encoding.variations.forEach(function(enc) { + assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), baseStrings[key]); + assert.strictEqual(iconv.toEncoding(baseStrings[key], enc).toString('binary'), encoding.encodedStrings[key].toString('binary')); + }); + }, + "Untranslatable chars are converted to defaultCharSingleByte": function() { + var expected = baseStrings.untranslatable.split('').map(function(c) {return iconv.defaultCharSingleByte; }).join(''); + assert.strictEqual(iconv.toEncoding(baseStrings.untranslatable, enc).toString('binary'), expected); // Only '?' characters. + } + }; + + testsBatch[encoding.name+":"] = tests; +}); + +vows.describe("Test Greek encodings").addBatch(testsBatch).export(module); diff --git a/node_modules/iconv-lite/test/main-test.js b/node_modules/iconv-lite/test/main-test.js new file mode 100644 index 0000000..50177f2 --- /dev/null +++ b/node_modules/iconv-lite/test/main-test.js @@ -0,0 +1,55 @@ +var vows = require('vows'), + assert = require('assert'), + iconv = require(__dirname+'/../'); + +var testString = "Hello123!"; +var testStringLatin1 = "Hello123!£Å÷×çþÿ¿®"; +var testStringBase64 = "SGVsbG8xMjMh"; + +vows.describe("Generic UTF8-UCS2 tests").addBatch({ + "Vows is working": function() {}, + "Return values are of correct types": function() { + assert.ok(iconv.toEncoding(testString, "utf8") instanceof Buffer); + + var s = iconv.fromEncoding(new Buffer(testString), "utf8"); + assert.strictEqual(Object.prototype.toString.call(s), "[object String]"); + }, + "Internal encodings all correctly encoded/decoded": function() { + ['utf8', "UTF-8", "UCS2", "binary", ""].forEach(function(enc) { + assert.strictEqual(iconv.toEncoding(testStringLatin1, enc).toString(enc), testStringLatin1); + assert.strictEqual(iconv.fromEncoding(new Buffer(testStringLatin1, enc), enc), testStringLatin1); + }); + }, + "Base64 correctly encoded/decoded": function() { + assert.strictEqual(iconv.toEncoding(testStringBase64, "base64").toString("binary"), testString); + assert.strictEqual(iconv.fromEncoding(new Buffer(testString, "binary"), "base64"), testStringBase64); + }, + "Latin1 correctly encoded/decoded": function() { + assert.strictEqual(iconv.toEncoding(testStringLatin1, "latin1").toString("binary"), testStringLatin1); + assert.strictEqual(iconv.fromEncoding(new Buffer(testStringLatin1, "binary"), "latin1"), testStringLatin1); + }, + "Convert from string, not buffer (binary encoding used)": function() { + assert.strictEqual(iconv.fromEncoding(testStringLatin1, "binary"), testStringLatin1); + }, + "Convert to string, not buffer (utf8 used)": function() { + var res = iconv.toEncoding(new Buffer(testStringLatin1, "utf8")); + assert.ok(res instanceof Buffer); + assert.strictEqual(res.toString("utf8"), testStringLatin1); + }, + "Throws on unknown encodings": function() { + assert.throws(function() { iconv.toEncoding("a", "xxx"); }); + assert.throws(function() { iconv.fromEncoding("a", "xxx"); }); + }, + "Convert non-strings and non-buffers": function() { + assert.strictEqual(iconv.toEncoding({}, "utf8").toString(), "[object Object]"); + assert.strictEqual(iconv.toEncoding(10, "utf8").toString(), "10"); + assert.strictEqual(iconv.toEncoding(undefined, "utf8").toString(), ""); + assert.strictEqual(iconv.fromEncoding({}, "utf8"), "[object Object]"); + assert.strictEqual(iconv.fromEncoding(10, "utf8"), "10"); + assert.strictEqual(iconv.fromEncoding(undefined, "utf8"), ""); + }, + "Aliases encode and decode work the same as toEncoding and fromEncoding": function() { + assert.strictEqual(iconv.toEncoding(testString, "latin1").toString("binary"), iconv.encode(testString, "latin1").toString("binary")); + assert.strictEqual(iconv.fromEncoding(testStringLatin1, "latin1"), iconv.decode(testStringLatin1, "latin1")); + }, +}).export(module) diff --git a/node_modules/iconv-lite/test/performance.js b/node_modules/iconv-lite/test/performance.js new file mode 100644 index 0000000..835deac --- /dev/null +++ b/node_modules/iconv-lite/test/performance.js @@ -0,0 +1,67 @@ + +var iconv = require('iconv'); +var iconv_lite = require("../index"); + +var encoding = process.argv[2] || "windows-1251"; +var convertTimes = 10000; + +var encodingStrings = { + 'windows-1251': 'This is a test string 32 chars..', + 'gbk': '这是中文字符测试。。!@¥%12', + 'utf8': '这是中文字符测试。。!@¥%12This is a test string 48 chars..', +}; +// Test encoding. +var str = encodingStrings[encoding]; +if (!str) { + throw new Error('Don\'t support ' + encoding + ' performance test.'); +} +for (var i = 0; i < 13; i++) { + str = str + str; +} + +console.log('\n' + encoding + ' charset performance test:'); +console.log("\nEncoding "+str.length+" chars "+convertTimes+" times:"); + +var start = Date.now(); +var converter = new iconv.Iconv("utf8", encoding); +for (var i = 0; i < convertTimes; i++) { + var b = converter.convert(str); +} +var duration = Date.now() - start; +var mbs = convertTimes*b.length/duration/1024; + +console.log("iconv: "+duration+"ms, "+mbs.toFixed(2)+" Mb/s."); + +var start = Date.now(); +for (var i = 0; i < convertTimes; i++) { + var b = iconv_lite.encode(str, encoding); +} +var duration = Date.now() - start; +var mbs = convertTimes*b.length/duration/1024; + +console.log("iconv-lite: "+duration+"ms, "+mbs.toFixed(2)+" Mb/s."); + + +// Test decoding. +var buf = iconv_lite.encode(str, encoding); +console.log("\nDecoding "+buf.length+" bytes "+convertTimes+" times:"); + +var start = Date.now(); +var converter = new iconv.Iconv(encoding, "utf8"); +for (var i = 0; i < convertTimes; i++) { + var s = converter.convert(buf).toString(); +} +var duration = Date.now() - start; +var mbs = convertTimes*buf.length/duration/1024; + +console.log("iconv: "+duration+"ms, "+mbs.toFixed(2)+" Mb/s."); + +var start = Date.now(); +for (var i = 0; i < convertTimes; i++) { + var s = iconv_lite.decode(buf, encoding); +} +var duration = Date.now() - start; +var mbs = convertTimes*buf.length/duration/1024; + +console.log("iconv-lite: "+duration+"ms, "+mbs.toFixed(2)+" Mb/s."); + diff --git a/node_modules/iconv-lite/test/turkish-test.js b/node_modules/iconv-lite/test/turkish-test.js new file mode 100644 index 0000000..b2eb68e --- /dev/null +++ b/node_modules/iconv-lite/test/turkish-test.js @@ -0,0 +1,90 @@ +var vows = require('vows'), + assert = require('assert'), + iconv = require(__dirname+'/../'); + +var ascii = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'+ + ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f'; + +var encodings = [{ + name: "windows1254", + variations: ['windows-1254', 'win-1254', 'win1254', 'cp1254', 'cp-1254', 1254], + strings: { + empty: "", + ascii: ascii, + turkish: "€‚ƒ„…†‡ˆ‰Š‹Œ‘’“”•–—˜™š›œŸ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ", + untranslatable: "\x81\x8d\x8e\x8f\x90\x9d\x9e" + }, + encodedStrings: { + empty: new Buffer(''), + ascii: new Buffer(ascii, 'binary'), + turkish: new Buffer( + '\x80\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c' + + '\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9f' + + '\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xae\xaf' + + '\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf' + + '\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf' + + '\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf' + + '\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef' + + '\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff', + 'binary'), + } +}, { + name: "iso88599", + variations: ['iso-8859-9', 'turkish', 'turkish8', 'cp28599', 'cp-28599', 28599], + strings: { + empty: "", + ascii: ascii, + turkish: "\xa0¡¢£¤¥¦§¨©ª«¬\xad®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ", + untranslatable: '' + }, + encodedStrings: { + empty: new Buffer(''), + ascii: new Buffer(ascii, 'binary'), + turkish: new Buffer( + '\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf' + + '\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf' + + '\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf' + + '\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf' + + '\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef' + + '\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff', + 'binary') + } +}]; + +var testsBatch = {}; +encodings.forEach(function(encoding) { + var enc = encoding.variations[0]; + var key = "turkish"; + var tests = { + "Convert to empty buffer": function() { + assert.strictEqual(iconv.toEncoding("", enc).toString('binary'), new Buffer('').toString('binary')); + }, + "Convert from empty buffer": function() { + assert.strictEqual(iconv.fromEncoding(new Buffer(''), enc), ""); + }, + "Convert from buffer": function() { + for (var key in encoding.encodedStrings) + assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), + encoding.strings[key]); + }, + "Convert to buffer": function() { + for (var key in encoding.encodedStrings) + assert.strictEqual(iconv.toEncoding(encoding.strings[key], enc).toString('binary'), + encoding.encodedStrings[key].toString('binary')); + }, + "Try different variations of encoding": function() { + encoding.variations.forEach(function(enc) { + assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), encoding.strings[key]); + assert.strictEqual(iconv.toEncoding(encoding.strings[key], enc).toString('binary'), encoding.encodedStrings[key].toString('binary')); + }); + }, + "Untranslatable chars are converted to defaultCharSingleByte": function() { + var expected = encoding.strings.untranslatable.split('').map(function(c) {return iconv.defaultCharSingleByte; }).join(''); + assert.strictEqual(iconv.toEncoding(encoding.strings.untranslatable, enc).toString('binary'), expected); // Only '?' characters. + } + }; + + testsBatch[encoding.name+":"] = tests; +}); + +vows.describe("Test Turkish encodings").addBatch(testsBatch).export(module); diff --git a/node_modules/indent-string/index.js b/node_modules/indent-string/index.js new file mode 100644 index 0000000..4a21687 --- /dev/null +++ b/node_modules/indent-string/index.js @@ -0,0 +1,20 @@ +'use strict'; +var repeating = require('repeating'); + +module.exports = function (str, indent, count) { + if (typeof str !== 'string' || typeof indent !== 'string') { + throw new TypeError('`string` and `indent` should be strings'); + } + + if (count != null && typeof count !== 'number') { + throw new TypeError('`count` should be a number'); + } + + if (count === 0) { + return str; + } + + indent = count > 1 ? repeating(indent, count) : indent; + + return str.replace(/^(?!\s*$)/mg, indent); +}; diff --git a/node_modules/indent-string/license b/node_modules/indent-string/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/indent-string/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/indent-string/package.json b/node_modules/indent-string/package.json new file mode 100644 index 0000000..1f41c59 --- /dev/null +++ b/node_modules/indent-string/package.json @@ -0,0 +1,99 @@ +{ + "_args": [ + [ + { + "raw": "indent-string@^2.1.0", + "scope": null, + "escapedName": "indent-string", + "name": "indent-string", + "rawSpec": "^2.1.0", + "spec": ">=2.1.0 <3.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/redent" + ] + ], + "_from": "indent-string@>=2.1.0 <3.0.0", + "_id": "indent-string@2.1.0", + "_inCache": true, + "_location": "/indent-string", + "_nodeVersion": "3.0.0", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.13.3", + "_phantomChildren": {}, + "_requested": { + "raw": "indent-string@^2.1.0", + "scope": null, + "escapedName": "indent-string", + "name": "indent-string", + "rawSpec": "^2.1.0", + "spec": ">=2.1.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/redent" + ], + "_resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "_shasum": "8e2d48348742121b4a8218b7a137e9a52049dc80", + "_shrinkwrap": null, + "_spec": "indent-string@^2.1.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/redent", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/indent-string/issues" + }, + "dependencies": { + "repeating": "^2.0.0" + }, + "description": "Indent each line in a string", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "8e2d48348742121b4a8218b7a137e9a52049dc80", + "tarball": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "649f7560df23a8fd8ea330bead5d7d0058efc6b6", + "homepage": "https://github.com/sindresorhus/indent-string#readme", + "keywords": [ + "indent", + "string", + "str", + "pad", + "align", + "line", + "text" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "indent-string", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/indent-string.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "2.1.0" +} diff --git a/node_modules/indent-string/readme.md b/node_modules/indent-string/readme.md new file mode 100644 index 0000000..89f14ac --- /dev/null +++ b/node_modules/indent-string/readme.md @@ -0,0 +1,58 @@ +# indent-string [![Build Status](https://travis-ci.org/sindresorhus/indent-string.svg?branch=master)](https://travis-ci.org/sindresorhus/indent-string) + +> Indent each line in a string + + +## Install + +``` +$ npm install --save indent-string +``` + + +## Usage + +```js +var indentString = require('indent-string'); + +indentString('Unicorns\nRainbows', '♥', 4); +//=> ♥♥♥♥Unicorns +//=> ♥♥♥♥Rainbows +``` + + +## API + +### indentString(string, indent, count) + +#### string + +**Required** +Type: `string` + +The string you want to indent. + +#### indent + +**Required** +Type: `string` + +The string to use for the indent. + +#### count + +Type: `number` +Default: `1` + +How many times you want `indent` repeated. + + +## Related + +- [indent-string-cli](https://github.com/sindresorhus/indent-string-cli) - CLI for this module +- [strip-indent](https://github.com/sindresorhus/strip-indent) - Strip leading whitespace from every line in a string + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/inflight/LICENSE b/node_modules/inflight/LICENSE new file mode 100644 index 0000000..05eeeb8 --- /dev/null +++ b/node_modules/inflight/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/inflight/README.md b/node_modules/inflight/README.md new file mode 100644 index 0000000..6dc8929 --- /dev/null +++ b/node_modules/inflight/README.md @@ -0,0 +1,37 @@ +# inflight + +Add callbacks to requests in flight to avoid async duplication + +## USAGE + +```javascript +var inflight = require('inflight') + +// some request that does some stuff +function req(key, callback) { + // key is any random string. like a url or filename or whatever. + // + // will return either a falsey value, indicating that the + // request for this key is already in flight, or a new callback + // which when called will call all callbacks passed to inflightk + // with the same key + callback = inflight(key, callback) + + // If we got a falsey value back, then there's already a req going + if (!callback) return + + // this is where you'd fetch the url or whatever + // callback is also once()-ified, so it can safely be assigned + // to multiple events etc. First call wins. + setTimeout(function() { + callback(null, key) + }, 100) +} + +// only assigns a single setTimeout +// when it dings, all cbs get called +req('foo', cb1) +req('foo', cb2) +req('foo', cb3) +req('foo', cb4) +``` diff --git a/node_modules/inflight/inflight.js b/node_modules/inflight/inflight.js new file mode 100644 index 0000000..48202b3 --- /dev/null +++ b/node_modules/inflight/inflight.js @@ -0,0 +1,54 @@ +var wrappy = require('wrappy') +var reqs = Object.create(null) +var once = require('once') + +module.exports = wrappy(inflight) + +function inflight (key, cb) { + if (reqs[key]) { + reqs[key].push(cb) + return null + } else { + reqs[key] = [cb] + return makeres(key) + } +} + +function makeres (key) { + return once(function RES () { + var cbs = reqs[key] + var len = cbs.length + var args = slice(arguments) + + // XXX It's somewhat ambiguous whether a new callback added in this + // pass should be queued for later execution if something in the + // list of callbacks throws, or if it should just be discarded. + // However, it's such an edge case that it hardly matters, and either + // choice is likely as surprising as the other. + // As it happens, we do go ahead and schedule it for later execution. + try { + for (var i = 0; i < len; i++) { + cbs[i].apply(null, args) + } + } finally { + if (cbs.length > len) { + // added more in the interim. + // de-zalgo, just in case, but don't call again. + cbs.splice(0, len) + process.nextTick(function () { + RES.apply(null, args) + }) + } else { + delete reqs[key] + } + } + }) +} + +function slice (args) { + var length = args.length + var array = [] + + for (var i = 0; i < length; i++) array[i] = args[i] + return array +} diff --git a/node_modules/inflight/package.json b/node_modules/inflight/package.json new file mode 100644 index 0000000..ac21d06 --- /dev/null +++ b/node_modules/inflight/package.json @@ -0,0 +1,108 @@ +{ + "_args": [ + [ + { + "raw": "inflight@^1.0.4", + "scope": null, + "escapedName": "inflight", + "name": "inflight", + "rawSpec": "^1.0.4", + "spec": ">=1.0.4 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt-contrib-clean/node_modules/glob" + ] + ], + "_from": "inflight@>=1.0.4 <2.0.0", + "_id": "inflight@1.0.6", + "_inCache": true, + "_location": "/inflight", + "_nodeVersion": "6.5.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/inflight-1.0.6.tgz_1476330807696_0.10388551792129874" + }, + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "3.10.7", + "_phantomChildren": {}, + "_requested": { + "raw": "inflight@^1.0.4", + "scope": null, + "escapedName": "inflight", + "name": "inflight", + "rawSpec": "^1.0.4", + "spec": ">=1.0.4 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/cli/glob", + "/grunt-contrib-clean/glob", + "/grunt-sftp-deploy/findup-sync/glob", + "/grunt-sftp-deploy/glob" + ], + "_resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "_shasum": "49bd6331d7d02d0c09bc910a1075ba8165b56df9", + "_shrinkwrap": null, + "_spec": "inflight@^1.0.4", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt-contrib-clean/node_modules/glob", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/inflight/issues" + }, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + }, + "description": "Add callbacks to requests in flight to avoid async duplication", + "devDependencies": { + "tap": "^7.1.2" + }, + "directories": {}, + "dist": { + "shasum": "49bd6331d7d02d0c09bc910a1075ba8165b56df9", + "tarball": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + }, + "files": [ + "inflight.js" + ], + "gitHead": "a547881738c8f57b27795e584071d67cf6ac1a57", + "homepage": "https://github.com/isaacs/inflight", + "license": "ISC", + "main": "inflight.js", + "maintainers": [ + { + "name": "iarna", + "email": "me@re-becca.org" + }, + { + "name": "isaacs", + "email": "i@izs.me" + }, + { + "name": "othiym23", + "email": "ogd@aoaioxxysz.net" + }, + { + "name": "zkat", + "email": "kat@sykosomatic.org" + } + ], + "name": "inflight", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/inflight.git" + }, + "scripts": { + "test": "tap test.js --100" + }, + "version": "1.0.6" +} diff --git a/node_modules/inherits/LICENSE b/node_modules/inherits/LICENSE new file mode 100644 index 0000000..dea3013 --- /dev/null +++ b/node_modules/inherits/LICENSE @@ -0,0 +1,16 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + diff --git a/node_modules/inherits/README.md b/node_modules/inherits/README.md new file mode 100644 index 0000000..b1c5665 --- /dev/null +++ b/node_modules/inherits/README.md @@ -0,0 +1,42 @@ +Browser-friendly inheritance fully compatible with standard node.js +[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor). + +This package exports standard `inherits` from node.js `util` module in +node environment, but also provides alternative browser-friendly +implementation through [browser +field](https://gist.github.com/shtylman/4339901). Alternative +implementation is a literal copy of standard one located in standalone +module to avoid requiring of `util`. It also has a shim for old +browsers with no `Object.create` support. + +While keeping you sure you are using standard `inherits` +implementation in node.js environment, it allows bundlers such as +[browserify](https://github.com/substack/node-browserify) to not +include full `util` package to your client code if all you need is +just `inherits` function. It worth, because browser shim for `util` +package is large and `inherits` is often the single function you need +from it. + +It's recommended to use this package instead of +`require('util').inherits` for any code that has chances to be used +not only in node.js but in browser too. + +## usage + +```js +var inherits = require('inherits'); +// then use exactly as the standard one +``` + +## note on version ~1.0 + +Version ~1.0 had completely different motivation and is not compatible +neither with 2.0 nor with standard node.js `inherits`. + +If you are using version ~1.0 and planning to switch to ~2.0, be +careful: + +* new version uses `super_` instead of `super` for referencing + superclass +* new version overwrites current prototype while old one preserves any + existing fields on it diff --git a/node_modules/inherits/inherits.js b/node_modules/inherits/inherits.js new file mode 100644 index 0000000..3b94763 --- /dev/null +++ b/node_modules/inherits/inherits.js @@ -0,0 +1,7 @@ +try { + var util = require('util'); + if (typeof util.inherits !== 'function') throw ''; + module.exports = util.inherits; +} catch (e) { + module.exports = require('./inherits_browser.js'); +} diff --git a/node_modules/inherits/inherits_browser.js b/node_modules/inherits/inherits_browser.js new file mode 100644 index 0000000..c1e78a7 --- /dev/null +++ b/node_modules/inherits/inherits_browser.js @@ -0,0 +1,23 @@ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} diff --git a/node_modules/inherits/package.json b/node_modules/inherits/package.json new file mode 100644 index 0000000..8d70239 --- /dev/null +++ b/node_modules/inherits/package.json @@ -0,0 +1,104 @@ +{ + "_args": [ + [ + { + "raw": "inherits@2", + "scope": null, + "escapedName": "inherits", + "name": "inherits", + "rawSpec": "2", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/findup-sync/node_modules/glob" + ] + ], + "_from": "inherits@>=2.0.0 <3.0.0", + "_id": "inherits@2.0.3", + "_inCache": true, + "_location": "/inherits", + "_nodeVersion": "6.5.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/inherits-2.0.3.tgz_1473295776489_0.08142363070510328" + }, + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "3.10.7", + "_phantomChildren": {}, + "_requested": { + "raw": "inherits@2", + "scope": null, + "escapedName": "inherits", + "name": "inherits", + "rawSpec": "2", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/cli/glob", + "/concat-stream", + "/concat-stream/readable-stream", + "/findup-sync/glob", + "/grunt-contrib-clean/glob", + "/grunt-sftp-deploy/findup-sync/glob", + "/grunt-sftp-deploy/glob", + "/readable-stream" + ], + "_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "_shasum": "633c2c83e3da42a502f52466022480f4208261de", + "_shrinkwrap": null, + "_spec": "inherits@2", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/findup-sync/node_modules/glob", + "browser": "./inherits_browser.js", + "bugs": { + "url": "https://github.com/isaacs/inherits/issues" + }, + "dependencies": {}, + "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()", + "devDependencies": { + "tap": "^7.1.0" + }, + "directories": {}, + "dist": { + "shasum": "633c2c83e3da42a502f52466022480f4208261de", + "tarball": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + }, + "files": [ + "inherits.js", + "inherits_browser.js" + ], + "gitHead": "e05d0fb27c61a3ec687214f0476386b765364d5f", + "homepage": "https://github.com/isaacs/inherits#readme", + "keywords": [ + "inheritance", + "class", + "klass", + "oop", + "object-oriented", + "inherits", + "browser", + "browserify" + ], + "license": "ISC", + "main": "./inherits.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "inherits", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/inherits.git" + }, + "scripts": { + "test": "node test" + }, + "version": "2.0.3" +} diff --git a/node_modules/is-arrayish/.editorconfig b/node_modules/is-arrayish/.editorconfig new file mode 100644 index 0000000..4c017f8 --- /dev/null +++ b/node_modules/is-arrayish/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +indent_style = tab +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.coffee] +indent_style = space + +[{package.json,*.yml}] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false diff --git a/node_modules/is-arrayish/.istanbul.yml b/node_modules/is-arrayish/.istanbul.yml new file mode 100644 index 0000000..19fbec3 --- /dev/null +++ b/node_modules/is-arrayish/.istanbul.yml @@ -0,0 +1,4 @@ +instrumentation: + excludes: + - test.js + - test/**/* diff --git a/node_modules/is-arrayish/.npmignore b/node_modules/is-arrayish/.npmignore new file mode 100644 index 0000000..8d5eacb --- /dev/null +++ b/node_modules/is-arrayish/.npmignore @@ -0,0 +1,5 @@ +/coverage/ +/test.js +/test/ +*.sw[a-p] +/node_modules/ diff --git a/node_modules/is-arrayish/.travis.yml b/node_modules/is-arrayish/.travis.yml new file mode 100644 index 0000000..5a04243 --- /dev/null +++ b/node_modules/is-arrayish/.travis.yml @@ -0,0 +1,17 @@ +language: node_js + +script: + - node_modules/.bin/istanbul cover node_modules/.bin/_mocha -- --compilers coffee:coffee-script/register + - cat coverage/lcov.info | node_modules/.bin/coveralls +node_js: + - "0.10" + - "0.11" + - "0.12" + - "iojs" +os: + - linux + - osx + +notifications: + slack: + secure: oOt8QGzdrPDsTMcyahtIq5Q+0U1iwfgJgFCxBLsomQ0bpIMn+y5m4viJydA2UinHPGc944HS3LMZS9iKQyv+DjTgbhUyNXqeVjtxCwRe37f5rKQlXVvdfmjHk2kln4H8DcK3r5Qd/+2hd9BeMsp2GImTrkRSud1CZQlhhe5IgZOboSoWpGVMMy1iazWT06tAtiB2LRVhmsdUaFZDWAhGZ+UAvCPf+mnBOAylIj+U0GDrofhfTi25RK0gddG2f/p2M1HCu49O6wECGWkt2hVei233DkNJyLLLJVcvmhf+aXkV5TjMyaoxh/HdcV4DrA7KvYuWmWWKsINa9hlwAsdd/FYmJ6PjRkKWas2JoQ1C+qOzDxyQvn3CaUZFKD99pdsq0rBBZujqXQKZZ/hWb/CE74BI6fKmqQkiEPaD/7uADj04FEg6HVBZaMCyauOaK5b3VC97twbALZ1qVxYV6mU+zSEvnUbpnjjvRO0fSl9ZHA+rzkW73kX3GmHY0wAozEZbSy7QLuZlQ2QtHmBLr+APaGMdL1sFF9qFfzqKy0WDbSE0WS6hpAEJpTsjYmeBrnI8UmK3m++iEgyQPvZoH9LhUT+ek7XIfHZMe04BmC6wuO24/RfpmR6bQK9VMarFCYlBiWxg/z30vkP0KTpUi3o/cqFm7/Noxc0i2LVqM3E0Sy4= diff --git a/node_modules/is-arrayish/LICENSE b/node_modules/is-arrayish/LICENSE new file mode 100644 index 0000000..0a5f461 --- /dev/null +++ b/node_modules/is-arrayish/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 JD Ballard + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/is-arrayish/README.md b/node_modules/is-arrayish/README.md new file mode 100644 index 0000000..7d36072 --- /dev/null +++ b/node_modules/is-arrayish/README.md @@ -0,0 +1,16 @@ +# node-is-arrayish [![Travis-CI.org Build Status](https://img.shields.io/travis/Qix-/node-is-arrayish.svg?style=flat-square)](https://travis-ci.org/Qix-/node-is-arrayish) [![Coveralls.io Coverage Rating](https://img.shields.io/coveralls/Qix-/node-is-arrayish.svg?style=flat-square)](https://coveralls.io/r/Qix-/node-is-arrayish) +> Determines if an object can be used like an Array + +## Example +```javascript +var isArrayish = require('is-arrayish'); + +isArrayish([]); // true +isArrayish({__proto__: []}); // true +isArrayish({}); // false +isArrayish({length:10}); // false +``` + +## License +Licensed under the [MIT License](http://opensource.org/licenses/MIT). +You can find a copy of it in [LICENSE](LICENSE). diff --git a/node_modules/is-arrayish/index.js b/node_modules/is-arrayish/index.js new file mode 100644 index 0000000..5b97186 --- /dev/null +++ b/node_modules/is-arrayish/index.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function isArrayish(obj) { + if (!obj) { + return false; + } + + return obj instanceof Array || Array.isArray(obj) || + (obj.length >= 0 && obj.splice instanceof Function); +}; diff --git a/node_modules/is-arrayish/package.json b/node_modules/is-arrayish/package.json new file mode 100644 index 0000000..0df1f22 --- /dev/null +++ b/node_modules/is-arrayish/package.json @@ -0,0 +1,98 @@ +{ + "_args": [ + [ + { + "raw": "is-arrayish@^0.2.1", + "scope": null, + "escapedName": "is-arrayish", + "name": "is-arrayish", + "rawSpec": "^0.2.1", + "spec": ">=0.2.1 <0.3.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/error-ex" + ] + ], + "_from": "is-arrayish@>=0.2.1 <0.3.0", + "_id": "is-arrayish@0.2.1", + "_inCache": true, + "_location": "/is-arrayish", + "_nodeVersion": "0.12.7", + "_npmUser": { + "name": "qix", + "email": "i.am.qix@gmail.com" + }, + "_npmVersion": "3.2.2", + "_phantomChildren": {}, + "_requested": { + "raw": "is-arrayish@^0.2.1", + "scope": null, + "escapedName": "is-arrayish", + "name": "is-arrayish", + "rawSpec": "^0.2.1", + "spec": ">=0.2.1 <0.3.0", + "type": "range" + }, + "_requiredBy": [ + "/error-ex" + ], + "_resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "_shasum": "77c99840527aa8ecb1a8ba697b80645a7a926a9d", + "_shrinkwrap": null, + "_spec": "is-arrayish@^0.2.1", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/error-ex", + "author": { + "name": "Qix", + "url": "http://github.com/qix-" + }, + "bugs": { + "url": "https://github.com/qix-/node-is-arrayish/issues" + }, + "dependencies": {}, + "description": "Determines if an object can be used as an array", + "devDependencies": { + "coffee-script": "^1.9.3", + "coveralls": "^2.11.2", + "istanbul": "^0.3.17", + "mocha": "^2.2.5", + "should": "^7.0.1", + "xo": "^0.6.1" + }, + "directories": {}, + "dist": { + "shasum": "77c99840527aa8ecb1a8ba697b80645a7a926a9d", + "tarball": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + }, + "gitHead": "53f22aa6ce557d7d31a3d1152a590a2df220df9d", + "homepage": "https://github.com/qix-/node-is-arrayish#readme", + "keywords": [ + "is", + "array", + "duck", + "type", + "arrayish", + "similar", + "proto", + "prototype", + "type" + ], + "license": "MIT", + "maintainers": [ + { + "name": "qix", + "email": "i.am.qix@gmail.com" + } + ], + "name": "is-arrayish", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/qix-/node-is-arrayish.git" + }, + "scripts": { + "pretest": "xo", + "test": "mocha --compilers coffee:coffee-script/register" + }, + "version": "0.2.1" +} diff --git a/node_modules/is-buffer/.travis.yml b/node_modules/is-buffer/.travis.yml new file mode 100644 index 0000000..24885a3 --- /dev/null +++ b/node_modules/is-buffer/.travis.yml @@ -0,0 +1,8 @@ +sudo: false +language: node_js +node_js: + - node +env: + global: + - secure: du27W3wTgZ3G183axW7w0I01lOIurx8kilMH9p45VMfNXCu8lo6FLtLIQZxJ1FYMoJLQ1yfJTu2G0rq39SotDfJumsk6tF7BjTY/HKCocZaHqCMgw0W2bcylb5kMAdLhBNPlzejpPoWa1x1axbAHNFOLQNVosG/Bavu3/kuIIps= + - secure: Ax/5aekM40o67NuTkvQqx1DhfP86ZlHTtKbv5yI+WFmbjD3FQM8b8G1J/o7doaBDev7Mp+1zDJOK2pFGtt+JGRl0lM2JUmLh6yh/b28obXyei5iuUkqzKJLfKZHMbY5QW/1i4DUM+zSXe6Kava0qnqYg5wBBnrF6gLdsVsCGNQk= diff --git a/node_modules/is-buffer/.zuul.yml b/node_modules/is-buffer/.zuul.yml new file mode 100644 index 0000000..eb3cae6 --- /dev/null +++ b/node_modules/is-buffer/.zuul.yml @@ -0,0 +1,14 @@ +ui: tape +browsers: + - name: chrome + version: 39..latest + - name: firefox + version: 34..latest + - name: safari + version: 5..latest + - name: microsoftedge + version: latest + - name: ie + version: 8..latest + - name: android + version: 5.0..latest diff --git a/node_modules/is-buffer/LICENSE b/node_modules/is-buffer/LICENSE new file mode 100644 index 0000000..0c068ce --- /dev/null +++ b/node_modules/is-buffer/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Feross Aboukhadijeh + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/is-buffer/README.md b/node_modules/is-buffer/README.md new file mode 100644 index 0000000..cb6f356 --- /dev/null +++ b/node_modules/is-buffer/README.md @@ -0,0 +1,49 @@ +# is-buffer [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][npm-url] + +#### Determine if an object is a [`Buffer`](http://nodejs.org/api/buffer.html) (including the [browserify Buffer](https://github.com/feross/buffer)) + +[![saucelabs][saucelabs-image]][saucelabs-url] + +[travis-image]: https://img.shields.io/travis/feross/is-buffer/master.svg +[travis-url]: https://travis-ci.org/feross/is-buffer +[npm-image]: https://img.shields.io/npm/v/is-buffer.svg +[npm-url]: https://npmjs.org/package/is-buffer +[downloads-image]: https://img.shields.io/npm/dm/is-buffer.svg +[saucelabs-image]: https://saucelabs.com/browser-matrix/is-buffer.svg +[saucelabs-url]: https://saucelabs.com/u/is-buffer + +## Why not use `Buffer.isBuffer`? + +This module lets you check if an object is a `Buffer` without using `Buffer.isBuffer` (which includes the whole [buffer](https://github.com/feross/buffer) module in [browserify](http://browserify.org/)). + +It's future-proof and works in node too! + +## install + +```bash +npm install is-buffer +``` + +## usage + +```js +var isBuffer = require('is-buffer') + +isBuffer(new Buffer(4)) // true + +isBuffer(undefined) // false +isBuffer(null) // false +isBuffer('') // false +isBuffer(true) // false +isBuffer(false) // false +isBuffer(0) // false +isBuffer(1) // false +isBuffer(1.0) // false +isBuffer('string') // false +isBuffer({}) // false +isBuffer(function foo () {}) // false +``` + +## license + +MIT. Copyright (C) [Feross Aboukhadijeh](http://feross.org). diff --git a/node_modules/is-buffer/index.js b/node_modules/is-buffer/index.js new file mode 100644 index 0000000..36c808e --- /dev/null +++ b/node_modules/is-buffer/index.js @@ -0,0 +1,21 @@ +/*! + * Determine if an object is a Buffer + * + * @author Feross Aboukhadijeh + * @license MIT + */ + +// The _isBuffer check is for Safari 5-7 support, because it's missing +// Object.prototype.constructor. Remove this eventually +module.exports = function (obj) { + return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) +} + +function isBuffer (obj) { + return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) +} + +// For Node v0.10 support. Remove this eventually. +function isSlowBuffer (obj) { + return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) +} diff --git a/node_modules/is-buffer/package.json b/node_modules/is-buffer/package.json new file mode 100644 index 0000000..a0a6b45 --- /dev/null +++ b/node_modules/is-buffer/package.json @@ -0,0 +1,112 @@ +{ + "_args": [ + [ + { + "raw": "is-buffer@^1.0.2", + "scope": null, + "escapedName": "is-buffer", + "name": "is-buffer", + "rawSpec": "^1.0.2", + "spec": ">=1.0.2 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/kind-of" + ] + ], + "_from": "is-buffer@>=1.0.2 <2.0.0", + "_id": "is-buffer@1.1.4", + "_inCache": true, + "_location": "/is-buffer", + "_nodeVersion": "0.10.46", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/is-buffer-1.1.4.tgz_1470267365943_0.6724087686743587" + }, + "_npmUser": { + "name": "feross", + "email": "feross@feross.org" + }, + "_npmVersion": "2.15.1", + "_phantomChildren": {}, + "_requested": { + "raw": "is-buffer@^1.0.2", + "scope": null, + "escapedName": "is-buffer", + "name": "is-buffer", + "rawSpec": "^1.0.2", + "spec": ">=1.0.2 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/kind-of" + ], + "_resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.4.tgz", + "_shasum": "cfc86ccd5dc5a52fa80489111c6920c457e2d98b", + "_shrinkwrap": null, + "_spec": "is-buffer@^1.0.2", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/kind-of", + "author": { + "name": "Feross Aboukhadijeh", + "email": "feross@feross.org", + "url": "http://feross.org/" + }, + "bugs": { + "url": "https://github.com/feross/is-buffer/issues" + }, + "dependencies": {}, + "description": "Determine if an object is a Buffer", + "devDependencies": { + "standard": "^7.0.0", + "tape": "^4.0.0", + "zuul": "^3.0.0" + }, + "directories": {}, + "dist": { + "shasum": "cfc86ccd5dc5a52fa80489111c6920c457e2d98b", + "tarball": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.4.tgz" + }, + "gitHead": "fd1a429f6ab8092f2e39cb5cc7175b5d9a986c31", + "homepage": "https://github.com/feross/is-buffer#readme", + "keywords": [ + "buffer", + "buffers", + "type", + "core buffer", + "browser buffer", + "browserify", + "typed array", + "uint32array", + "int16array", + "int32array", + "float32array", + "float64array", + "browser", + "arraybuffer", + "dataview" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "feross", + "email": "feross@feross.org" + } + ], + "name": "is-buffer", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/feross/is-buffer.git" + }, + "scripts": { + "test": "standard && npm run test-node && npm run test-browser", + "test-browser": "zuul -- test/*.js", + "test-browser-local": "zuul --local -- test/*.js", + "test-node": "tape test/*.js" + }, + "testling": { + "files": "test/*.js" + }, + "version": "1.1.4" +} diff --git a/node_modules/is-buffer/test/basic.js b/node_modules/is-buffer/test/basic.js new file mode 100644 index 0000000..43b7c82 --- /dev/null +++ b/node_modules/is-buffer/test/basic.js @@ -0,0 +1,25 @@ +var buffer = require('buffer') +var isBuffer = require('../') +var test = require('tape') + +test('is-buffer', function (t) { + t.equal(isBuffer(new Buffer(4)), true, 'new Buffer(4)') + t.equal(isBuffer(buffer.SlowBuffer(100)), true, 'SlowBuffer(100)') + + t.equal(isBuffer(undefined), false, 'undefined') + t.equal(isBuffer(null), false, 'null') + t.equal(isBuffer(''), false, 'empty string') + t.equal(isBuffer(true), false, 'true') + t.equal(isBuffer(false), false, 'false') + t.equal(isBuffer(0), false, '0') + t.equal(isBuffer(1), false, '1') + t.equal(isBuffer(1.0), false, '1.0') + t.equal(isBuffer('string'), false, 'string') + t.equal(isBuffer({}), false, '{}') + t.equal(isBuffer([]), false, '[]') + t.equal(isBuffer(function foo () {}), false, 'function foo () {}') + t.equal(isBuffer({ isBuffer: null }), false, '{ isBuffer: null }') + t.equal(isBuffer({ isBuffer: function () { throw new Error() } }), false, '{ isBuffer: function () { throw new Error() } }') + + t.end() +}) diff --git a/node_modules/is-builtin-module/index.js b/node_modules/is-builtin-module/index.js new file mode 100644 index 0000000..b6cfa61 --- /dev/null +++ b/node_modules/is-builtin-module/index.js @@ -0,0 +1,10 @@ +'use strict'; +var builtinModules = require('builtin-modules'); + +module.exports = function (str) { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); + } + + return builtinModules.indexOf(str) !== -1; +}; diff --git a/node_modules/is-builtin-module/license b/node_modules/is-builtin-module/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/is-builtin-module/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/is-builtin-module/package.json b/node_modules/is-builtin-module/package.json new file mode 100644 index 0000000..e9f34dd --- /dev/null +++ b/node_modules/is-builtin-module/package.json @@ -0,0 +1,106 @@ +{ + "_args": [ + [ + { + "raw": "is-builtin-module@^1.0.0", + "scope": null, + "escapedName": "is-builtin-module", + "name": "is-builtin-module", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/normalize-package-data" + ] + ], + "_from": "is-builtin-module@>=1.0.0 <2.0.0", + "_id": "is-builtin-module@1.0.0", + "_inCache": true, + "_location": "/is-builtin-module", + "_nodeVersion": "0.12.2", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.7.4", + "_phantomChildren": {}, + "_requested": { + "raw": "is-builtin-module@^1.0.0", + "scope": null, + "escapedName": "is-builtin-module", + "name": "is-builtin-module", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/normalize-package-data" + ], + "_resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "_shasum": "540572d34f7ac3119f8f76c30cbc1b1e037affbe", + "_shrinkwrap": null, + "_spec": "is-builtin-module@^1.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/normalize-package-data", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/is-builtin-module/issues" + }, + "dependencies": { + "builtin-modules": "^1.0.0" + }, + "description": "Check if a string matches the name of a Node.js builtin module", + "devDependencies": { + "ava": "0.0.4" + }, + "directories": {}, + "dist": { + "shasum": "540572d34f7ac3119f8f76c30cbc1b1e037affbe", + "tarball": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "da55ebf031f3864c5d309e25e49ed816957d70a2", + "homepage": "https://github.com/sindresorhus/is-builtin-module", + "keywords": [ + "builtin", + "built-in", + "builtins", + "node", + "modules", + "core", + "bundled", + "list", + "array", + "names", + "is", + "detect", + "check", + "match" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "is-builtin-module", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/is-builtin-module.git" + }, + "scripts": { + "test": "node test.js" + }, + "version": "1.0.0" +} diff --git a/node_modules/is-builtin-module/readme.md b/node_modules/is-builtin-module/readme.md new file mode 100644 index 0000000..798dcf4 --- /dev/null +++ b/node_modules/is-builtin-module/readme.md @@ -0,0 +1,33 @@ +# is-builtin-module [![Build Status](https://travis-ci.org/sindresorhus/is-builtin-module.svg?branch=master)](https://travis-ci.org/sindresorhus/is-builtin-module) + +> Check if a string matches the name of a Node.js builtin module + + +## Install + +``` +$ npm install --save is-builtin-module +``` + + +## Usage + +```js +var isBuiltinModule = require('is-builtin-module'); + +isBuiltinModule('fs'); +//=> true + +isBuiltinModule('unicorn'); +//=> false :( +``` + + +## Related + +- [builtin-modules](https://github.com/sindresorhus/builtin-modules) - List of the Node.js builtin modules + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/is-finite/index.js b/node_modules/is-finite/index.js new file mode 100644 index 0000000..8067387 --- /dev/null +++ b/node_modules/is-finite/index.js @@ -0,0 +1,6 @@ +'use strict'; +var numberIsNan = require('number-is-nan'); + +module.exports = Number.isFinite || function (val) { + return !(typeof val !== 'number' || numberIsNan(val) || val === Infinity || val === -Infinity); +}; diff --git a/node_modules/is-finite/license b/node_modules/is-finite/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/is-finite/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/is-finite/package.json b/node_modules/is-finite/package.json new file mode 100644 index 0000000..576c919 --- /dev/null +++ b/node_modules/is-finite/package.json @@ -0,0 +1,103 @@ +{ + "_args": [ + [ + { + "raw": "is-finite@^1.0.0", + "scope": null, + "escapedName": "is-finite", + "name": "is-finite", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/repeating" + ] + ], + "_from": "is-finite@>=1.0.0 <2.0.0", + "_id": "is-finite@1.0.2", + "_inCache": true, + "_location": "/is-finite", + "_nodeVersion": "4.5.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/is-finite-1.0.2.tgz_1475221456713_0.784205764066428" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.15.9", + "_phantomChildren": {}, + "_requested": { + "raw": "is-finite@^1.0.0", + "scope": null, + "escapedName": "is-finite", + "name": "is-finite", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/repeating" + ], + "_resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "_shasum": "cc6677695602be550ef11e8b4aa6305342b6d0aa", + "_shrinkwrap": null, + "_spec": "is-finite@^1.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/repeating", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/is-finite/issues" + }, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "description": "ES2015 Number.isFinite() ponyfill", + "devDependencies": { + "ava": "*" + }, + "directories": {}, + "dist": { + "shasum": "cc6677695602be550ef11e8b4aa6305342b6d0aa", + "tarball": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "43f8bb814834d8573d11ba4a631d19006d0c8897", + "homepage": "https://github.com/sindresorhus/is-finite#readme", + "keywords": [ + "es2015", + "ponyfill", + "polyfill", + "shim", + "number", + "finite", + "is" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "is-finite", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/is-finite.git" + }, + "scripts": { + "test": "ava" + }, + "version": "1.0.2" +} diff --git a/node_modules/is-finite/readme.md b/node_modules/is-finite/readme.md new file mode 100644 index 0000000..567710c --- /dev/null +++ b/node_modules/is-finite/readme.md @@ -0,0 +1,28 @@ +# is-finite [![Build Status](https://travis-ci.org/sindresorhus/is-finite.svg?branch=master)](https://travis-ci.org/sindresorhus/is-finite) + +> ES2015 [`Number.isFinite()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite) [ponyfill](https://ponyfill.com) + + +## Install + +```sh +$ npm install --save is-finite +``` + + +## Usage + +```js +var numIsFinite = require('is-finite'); + +numIsFinite(4); +//=> true + +numIsFinite(Infinity); +//=> false +``` + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/is-utf8/LICENSE b/node_modules/is-utf8/LICENSE new file mode 100644 index 0000000..2c8d4b9 --- /dev/null +++ b/node_modules/is-utf8/LICENSE @@ -0,0 +1,9 @@ +The MIT License (MIT) + +Copyright (C) 2014 Wei Fanzhe + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +   +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/is-utf8/README.md b/node_modules/is-utf8/README.md new file mode 100644 index 0000000..b62ddde --- /dev/null +++ b/node_modules/is-utf8/README.md @@ -0,0 +1,16 @@ +#utf8 detector + +Detect if a Buffer is utf8 encoded. +It need The minimum amount of bytes is 4. + + +```javascript + var fs = require('fs'); + var isUtf8 = require('is-utf8'); + var ansi = fs.readFileSync('ansi.txt'); + var utf8 = fs.readFileSync('utf8.txt'); + + console.log('ansi.txt is utf8: '+isUtf8(ansi)); //false + console.log('utf8.txt is utf8: '+isUtf8(utf8)); //true +``` + diff --git a/node_modules/is-utf8/is-utf8.js b/node_modules/is-utf8/is-utf8.js new file mode 100644 index 0000000..8a5f15d --- /dev/null +++ b/node_modules/is-utf8/is-utf8.js @@ -0,0 +1,76 @@ + +exports = module.exports = function(bytes) +{ + var i = 0; + while(i < bytes.length) + { + if( (// ASCII + bytes[i] == 0x09 || + bytes[i] == 0x0A || + bytes[i] == 0x0D || + (0x20 <= bytes[i] && bytes[i] <= 0x7E) + ) + ) { + i += 1; + continue; + } + + if( (// non-overlong 2-byte + (0xC2 <= bytes[i] && bytes[i] <= 0xDF) && + (0x80 <= bytes[i+1] && bytes[i+1] <= 0xBF) + ) + ) { + i += 2; + continue; + } + + if( (// excluding overlongs + bytes[i] == 0xE0 && + (0xA0 <= bytes[i + 1] && bytes[i + 1] <= 0xBF) && + (0x80 <= bytes[i + 2] && bytes[i + 2] <= 0xBF) + ) || + (// straight 3-byte + ((0xE1 <= bytes[i] && bytes[i] <= 0xEC) || + bytes[i] == 0xEE || + bytes[i] == 0xEF) && + (0x80 <= bytes[i + 1] && bytes[i+1] <= 0xBF) && + (0x80 <= bytes[i+2] && bytes[i+2] <= 0xBF) + ) || + (// excluding surrogates + bytes[i] == 0xED && + (0x80 <= bytes[i+1] && bytes[i+1] <= 0x9F) && + (0x80 <= bytes[i+2] && bytes[i+2] <= 0xBF) + ) + ) { + i += 3; + continue; + } + + if( (// planes 1-3 + bytes[i] == 0xF0 && + (0x90 <= bytes[i + 1] && bytes[i + 1] <= 0xBF) && + (0x80 <= bytes[i + 2] && bytes[i + 2] <= 0xBF) && + (0x80 <= bytes[i + 3] && bytes[i + 3] <= 0xBF) + ) || + (// planes 4-15 + (0xF1 <= bytes[i] && bytes[i] <= 0xF3) && + (0x80 <= bytes[i + 1] && bytes[i + 1] <= 0xBF) && + (0x80 <= bytes[i + 2] && bytes[i + 2] <= 0xBF) && + (0x80 <= bytes[i + 3] && bytes[i + 3] <= 0xBF) + ) || + (// plane 16 + bytes[i] == 0xF4 && + (0x80 <= bytes[i + 1] && bytes[i + 1] <= 0x8F) && + (0x80 <= bytes[i + 2] && bytes[i + 2] <= 0xBF) && + (0x80 <= bytes[i + 3] && bytes[i + 3] <= 0xBF) + ) + ) { + i += 4; + continue; + } + + return false; + } + + return true; +} diff --git a/node_modules/is-utf8/package.json b/node_modules/is-utf8/package.json new file mode 100644 index 0000000..989f4d6 --- /dev/null +++ b/node_modules/is-utf8/package.json @@ -0,0 +1,86 @@ +{ + "_args": [ + [ + { + "raw": "is-utf8@^0.2.0", + "scope": null, + "escapedName": "is-utf8", + "name": "is-utf8", + "rawSpec": "^0.2.0", + "spec": ">=0.2.0 <0.3.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/strip-bom" + ] + ], + "_from": "is-utf8@>=0.2.0 <0.3.0", + "_id": "is-utf8@0.2.1", + "_inCache": true, + "_location": "/is-utf8", + "_nodeVersion": "2.3.4", + "_npmUser": { + "name": "wayfind", + "email": "whyer1@gmail.com" + }, + "_npmVersion": "2.12.1", + "_phantomChildren": {}, + "_requested": { + "raw": "is-utf8@^0.2.0", + "scope": null, + "escapedName": "is-utf8", + "name": "is-utf8", + "rawSpec": "^0.2.0", + "spec": ">=0.2.0 <0.3.0", + "type": "range" + }, + "_requiredBy": [ + "/strip-bom" + ], + "_resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "_shasum": "4b0da1442104d1b336340e80797e865cf39f7d72", + "_shrinkwrap": null, + "_spec": "is-utf8@^0.2.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/strip-bom", + "author": { + "name": "wayfind" + }, + "bugs": { + "url": "https://github.com/wayfind/is-utf8/issues" + }, + "dependencies": {}, + "description": "Detect if a buffer is utf8 encoded.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "4b0da1442104d1b336340e80797e865cf39f7d72", + "tarball": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz" + }, + "files": [ + "is-utf8.js" + ], + "gitHead": "709df7202f9c3f93cdc2463b352dd80d8de9ce0b", + "homepage": "https://github.com/wayfind/is-utf8#readme", + "keywords": [ + "utf8", + "charset" + ], + "license": "MIT", + "main": "is-utf8.js", + "maintainers": [ + { + "name": "wayfind", + "email": "whyer1@gmail.com" + } + ], + "name": "is-utf8", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/wayfind/is-utf8.git" + }, + "scripts": { + "test": "node test.js" + }, + "version": "0.2.1" +} diff --git a/node_modules/isarray/README.md b/node_modules/isarray/README.md new file mode 100644 index 0000000..052a62b --- /dev/null +++ b/node_modules/isarray/README.md @@ -0,0 +1,54 @@ + +# isarray + +`Array#isArray` for older browsers. + +## Usage + +```js +var isArray = require('isarray'); + +console.log(isArray([])); // => true +console.log(isArray({})); // => false +``` + +## Installation + +With [npm](http://npmjs.org) do + +```bash +$ npm install isarray +``` + +Then bundle for the browser with +[browserify](https://github.com/substack/browserify). + +With [component](http://component.io) do + +```bash +$ component install juliangruber/isarray +``` + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/isarray/build/build.js b/node_modules/isarray/build/build.js new file mode 100644 index 0000000..ec58596 --- /dev/null +++ b/node_modules/isarray/build/build.js @@ -0,0 +1,209 @@ + +/** + * Require the given path. + * + * @param {String} path + * @return {Object} exports + * @api public + */ + +function require(path, parent, orig) { + var resolved = require.resolve(path); + + // lookup failed + if (null == resolved) { + orig = orig || path; + parent = parent || 'root'; + var err = new Error('Failed to require "' + orig + '" from "' + parent + '"'); + err.path = orig; + err.parent = parent; + err.require = true; + throw err; + } + + var module = require.modules[resolved]; + + // perform real require() + // by invoking the module's + // registered function + if (!module.exports) { + module.exports = {}; + module.client = module.component = true; + module.call(this, module.exports, require.relative(resolved), module); + } + + return module.exports; +} + +/** + * Registered modules. + */ + +require.modules = {}; + +/** + * Registered aliases. + */ + +require.aliases = {}; + +/** + * Resolve `path`. + * + * Lookup: + * + * - PATH/index.js + * - PATH.js + * - PATH + * + * @param {String} path + * @return {String} path or null + * @api private + */ + +require.resolve = function(path) { + if (path.charAt(0) === '/') path = path.slice(1); + var index = path + '/index.js'; + + var paths = [ + path, + path + '.js', + path + '.json', + path + '/index.js', + path + '/index.json' + ]; + + for (var i = 0; i < paths.length; i++) { + var path = paths[i]; + if (require.modules.hasOwnProperty(path)) return path; + } + + if (require.aliases.hasOwnProperty(index)) { + return require.aliases[index]; + } +}; + +/** + * Normalize `path` relative to the current path. + * + * @param {String} curr + * @param {String} path + * @return {String} + * @api private + */ + +require.normalize = function(curr, path) { + var segs = []; + + if ('.' != path.charAt(0)) return path; + + curr = curr.split('/'); + path = path.split('/'); + + for (var i = 0; i < path.length; ++i) { + if ('..' == path[i]) { + curr.pop(); + } else if ('.' != path[i] && '' != path[i]) { + segs.push(path[i]); + } + } + + return curr.concat(segs).join('/'); +}; + +/** + * Register module at `path` with callback `definition`. + * + * @param {String} path + * @param {Function} definition + * @api private + */ + +require.register = function(path, definition) { + require.modules[path] = definition; +}; + +/** + * Alias a module definition. + * + * @param {String} from + * @param {String} to + * @api private + */ + +require.alias = function(from, to) { + if (!require.modules.hasOwnProperty(from)) { + throw new Error('Failed to alias "' + from + '", it does not exist'); + } + require.aliases[to] = from; +}; + +/** + * Return a require function relative to the `parent` path. + * + * @param {String} parent + * @return {Function} + * @api private + */ + +require.relative = function(parent) { + var p = require.normalize(parent, '..'); + + /** + * lastIndexOf helper. + */ + + function lastIndexOf(arr, obj) { + var i = arr.length; + while (i--) { + if (arr[i] === obj) return i; + } + return -1; + } + + /** + * The relative require() itself. + */ + + function localRequire(path) { + var resolved = localRequire.resolve(path); + return require(resolved, parent, path); + } + + /** + * Resolve relative to the parent. + */ + + localRequire.resolve = function(path) { + var c = path.charAt(0); + if ('/' == c) return path.slice(1); + if ('.' == c) return require.normalize(p, path); + + // resolve deps by returning + // the dep in the nearest "deps" + // directory + var segs = parent.split('/'); + var i = lastIndexOf(segs, 'deps') + 1; + if (!i) i = 0; + path = segs.slice(0, i + 1).join('/') + '/deps/' + path; + return path; + }; + + /** + * Check if module is defined at `path`. + */ + + localRequire.exists = function(path) { + return require.modules.hasOwnProperty(localRequire.resolve(path)); + }; + + return localRequire; +}; +require.register("isarray/index.js", function(exports, require, module){ +module.exports = Array.isArray || function (arr) { + return Object.prototype.toString.call(arr) == '[object Array]'; +}; + +}); +require.alias("isarray/index.js", "isarray/index.js"); + diff --git a/node_modules/isarray/component.json b/node_modules/isarray/component.json new file mode 100644 index 0000000..9e31b68 --- /dev/null +++ b/node_modules/isarray/component.json @@ -0,0 +1,19 @@ +{ + "name" : "isarray", + "description" : "Array#isArray for older browsers", + "version" : "0.0.1", + "repository" : "juliangruber/isarray", + "homepage": "https://github.com/juliangruber/isarray", + "main" : "index.js", + "scripts" : [ + "index.js" + ], + "dependencies" : {}, + "keywords": ["browser","isarray","array"], + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "license": "MIT" +} diff --git a/node_modules/isarray/index.js b/node_modules/isarray/index.js new file mode 100644 index 0000000..5f5ad45 --- /dev/null +++ b/node_modules/isarray/index.js @@ -0,0 +1,3 @@ +module.exports = Array.isArray || function (arr) { + return Object.prototype.toString.call(arr) == '[object Array]'; +}; diff --git a/node_modules/isarray/package.json b/node_modules/isarray/package.json new file mode 100644 index 0000000..1176f0f --- /dev/null +++ b/node_modules/isarray/package.json @@ -0,0 +1,86 @@ +{ + "_args": [ + [ + { + "raw": "isarray@0.0.1", + "scope": null, + "escapedName": "isarray", + "name": "isarray", + "rawSpec": "0.0.1", + "spec": "0.0.1", + "type": "version" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/readable-stream" + ] + ], + "_from": "isarray@0.0.1", + "_id": "isarray@0.0.1", + "_inCache": true, + "_location": "/isarray", + "_npmUser": { + "name": "juliangruber", + "email": "julian@juliangruber.com" + }, + "_npmVersion": "1.2.18", + "_phantomChildren": {}, + "_requested": { + "raw": "isarray@0.0.1", + "scope": null, + "escapedName": "isarray", + "name": "isarray", + "rawSpec": "0.0.1", + "spec": "0.0.1", + "type": "version" + }, + "_requiredBy": [ + "/readable-stream" + ], + "_resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "_shasum": "8a18acfca9a8f4177e09abfc6038939b05d1eedf", + "_shrinkwrap": null, + "_spec": "isarray@0.0.1", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/readable-stream", + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "bugs": { + "url": "https://github.com/juliangruber/isarray/issues" + }, + "dependencies": {}, + "description": "Array#isArray for older browsers", + "devDependencies": { + "tap": "*" + }, + "directories": {}, + "dist": { + "shasum": "8a18acfca9a8f4177e09abfc6038939b05d1eedf", + "tarball": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "homepage": "https://github.com/juliangruber/isarray", + "keywords": [ + "browser", + "isarray", + "array" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "juliangruber", + "email": "julian@juliangruber.com" + } + ], + "name": "isarray", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/isarray.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "version": "0.0.1" +} diff --git a/node_modules/isexe/.npmignore b/node_modules/isexe/.npmignore new file mode 100644 index 0000000..c1cb757 --- /dev/null +++ b/node_modules/isexe/.npmignore @@ -0,0 +1,2 @@ +.nyc_output/ +coverage/ diff --git a/node_modules/isexe/LICENSE b/node_modules/isexe/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/node_modules/isexe/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/isexe/README.md b/node_modules/isexe/README.md new file mode 100644 index 0000000..30995ad --- /dev/null +++ b/node_modules/isexe/README.md @@ -0,0 +1,51 @@ +# isexe + +Minimal module to check if a file is executable. + +Uses `fs.access` if available, and tests against the `PATHEXT` +environment variable on Windows. + +## USAGE + +```javascript +var isexe = require('isexe') +isexe('some-file-name', function (err, isExe) { + if (err) { + console.error('probably file does not exist or something', err) + } else if (isExe) { + console.error('this thing can be run') + } else { + console.error('cannot be run') + } +}) + +// same thing but synchronous, throws errors +var isExe = isexe.sync('some-file-name') + +// treat errors as just "not executable" +isexe('maybe-missing-file', { ignoreErrors: true }, callback) +var isExe = isexe.sync('maybe-missing-file', { ignoreErrors: true }) +``` + +## API + +### `isexe(path, [options], [callback])` + +Check if the path is executable. If no callback provided, and a +global `Promise` object is available, then a Promise will be returned. + +Will raise whatever errors may be raised by `fs.access` or `fs.stat`, +unless `options.ignoreErrors` is set to true. + +### `isexe.sync(path, [options])` + +Same as `isexe` but returns the value and throws any errors raised. + +### Options + +* `ignoreErrors` Treat all errors as "no, this is not executable", but + don't raise them. +* `uid` Number to use as the user id when using the `mode` approach. +* `gid` Number to use as the group id when using the `mode` approach. +* `pathExt` List of path extensions to use instead of `PATHEXT` + environment variable on Windows. diff --git a/node_modules/isexe/access.js b/node_modules/isexe/access.js new file mode 100644 index 0000000..e67b28b --- /dev/null +++ b/node_modules/isexe/access.js @@ -0,0 +1,15 @@ +module.exports = isexe +isexe.sync = sync + +var fs = require('fs') + +function isexe (path, _, cb) { + fs.access(path, fs.X_OK, function (er) { + cb(er, !er) + }) +} + +function sync (path, _) { + fs.accessSync(path, fs.X_OK) + return true +} diff --git a/node_modules/isexe/index.js b/node_modules/isexe/index.js new file mode 100644 index 0000000..ff8ef11 --- /dev/null +++ b/node_modules/isexe/index.js @@ -0,0 +1,59 @@ +var fs = require('fs') +var core +if (process.platform === 'win32' || global.TESTING_WINDOWS) { + core = require('./windows.js') +} else if (typeof fs.access === 'function') { + core = require('./access.js') +} else { + core = require('./mode.js') +} + +module.exports = isexe +isexe.sync = sync + +function isexe (path, options, cb) { + if (typeof options === 'function') { + cb = options + options = {} + } + + if (!cb) { + if (typeof Promise !== 'function') { + throw new TypeError('callback not provided') + } + + return new Promise(function (resolve, reject) { + isexe(path, options || {}, function (er, is) { + if (er) { + reject(er) + } else { + resolve(is) + } + }) + }) + } + + core(path, options || {}, function (er, is) { + // ignore EACCES because that just means we aren't allowed to run it + if (er) { + if (er.code === 'EACCES' || options && options.ignoreErrors) { + er = null + is = false + } + } + cb(er, is) + }) +} + +function sync (path, options) { + // my kingdom for a filtered catch + try { + return core.sync(path, options || {}) + } catch (er) { + if (options && options.ignoreErrors || er.code === 'EACCES') { + return false + } else { + throw er + } + } +} diff --git a/node_modules/isexe/mode.js b/node_modules/isexe/mode.js new file mode 100644 index 0000000..2044280 --- /dev/null +++ b/node_modules/isexe/mode.js @@ -0,0 +1,37 @@ +module.exports = isexe +isexe.sync = sync + +var fs = require('fs') + +function isexe (path, options, cb) { + fs.stat(path, function (er, st) { + cb(er, er ? false : checkMode(st, options)) + }) +} + +function sync (path, options) { + return checkMode(fs.statSync(path), options) +} + +function checkMode (stat, options) { + var mod = stat.mode + var uid = stat.uid + var gid = stat.gid + + var myUid = options.uid !== undefined ? + options.uid : process.getuid && process.getuid() + var myGid = options.gid !== undefined ? + options.gid : process.getgid && process.getgid() + + var u = parseInt('100', 8) + var g = parseInt('010', 8) + var o = parseInt('001', 8) + var ug = u | g + + var ret = (mod & o) || + (mod & g) && gid === myGid || + (mod & u) && uid === myUid || + (mod & ug) && myUid === 0 + + return ret +} diff --git a/node_modules/isexe/package.json b/node_modules/isexe/package.json new file mode 100644 index 0000000..4f3aa61 --- /dev/null +++ b/node_modules/isexe/package.json @@ -0,0 +1,92 @@ +{ + "_args": [ + [ + { + "raw": "isexe@^1.1.1", + "scope": null, + "escapedName": "isexe", + "name": "isexe", + "rawSpec": "^1.1.1", + "spec": ">=1.1.1 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt-sftp-deploy/node_modules/which" + ] + ], + "_from": "isexe@>=1.1.1 <2.0.0", + "_id": "isexe@1.1.2", + "_inCache": true, + "_location": "/isexe", + "_nodeVersion": "4.0.0", + "_npmOperationalInternal": { + "host": "packages-9-west.internal.npmjs.com", + "tmp": "tmp/isexe-1.1.2.tgz_1454992795963_0.7608721863944083" + }, + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "3.7.0", + "_phantomChildren": {}, + "_requested": { + "raw": "isexe@^1.1.1", + "scope": null, + "escapedName": "isexe", + "name": "isexe", + "rawSpec": "^1.1.1", + "spec": ">=1.1.1 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt-sftp-deploy/which" + ], + "_resolved": "https://registry.npmjs.org/isexe/-/isexe-1.1.2.tgz", + "_shasum": "36f3e22e60750920f5e7241a476a8c6a42275ad0", + "_shrinkwrap": null, + "_spec": "isexe@^1.1.1", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt-sftp-deploy/node_modules/which", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/isexe/issues" + }, + "dependencies": {}, + "description": "Minimal module to check if a file is executable.", + "devDependencies": { + "mkdirp": "^0.5.1", + "rimraf": "^2.5.0", + "tap": "^5.1.2" + }, + "directories": { + "test": "test" + }, + "dist": { + "shasum": "36f3e22e60750920f5e7241a476a8c6a42275ad0", + "tarball": "https://registry.npmjs.org/isexe/-/isexe-1.1.2.tgz" + }, + "gitHead": "1882eed72c2ba152f4dd1336d857b0755ae306d9", + "homepage": "https://github.com/isaacs/isexe#readme", + "keywords": [], + "license": "ISC", + "main": "index.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "isexe", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/isaacs/isexe.git" + }, + "scripts": { + "test": "tap test/*.js --branches=100 --statements=100 --functions=100 --lines=100" + }, + "version": "1.1.2" +} diff --git a/node_modules/isexe/test/basic.js b/node_modules/isexe/test/basic.js new file mode 100644 index 0000000..969fc9a --- /dev/null +++ b/node_modules/isexe/test/basic.js @@ -0,0 +1,211 @@ +var t = require('tap') +var fs = require('fs') +var path = require('path') +var fixture = path.resolve(__dirname, 'fixtures') +var meow = fixture + '/meow.cat' +var mine = fixture + '/mine.cat' +var ours = fixture + '/ours.cat' +var fail = fixture + '/fail.false' +var noent = fixture + '/enoent.exe' +var mkdirp = require('mkdirp') +var rimraf = require('rimraf') + +var isWindows = process.platform === 'win32' +var hasAccess = typeof fs.access === 'function' +var winSkip = isWindows && 'windows' +var accessSkip = !hasAccess && 'no fs.access function' +var hasPromise = typeof Promise === 'function' +var promiseSkip = !hasPromise && 'no global Promise' + +function reset () { + delete require.cache[require.resolve('../')] + return require('../') +} + +t.test('setup fixtures', function (t) { + rimraf.sync(fixture) + mkdirp.sync(fixture) + fs.writeFileSync(meow, '#!/usr/bin/env cat\nmeow\n') + fs.chmodSync(meow, parseInt('0755', 8)) + fs.writeFileSync(fail, '#!/usr/bin/env false\n') + fs.chmodSync(fail, parseInt('0644', 8)) + fs.writeFileSync(mine, '#!/usr/bin/env cat\nmine\n') + fs.chmodSync(mine, parseInt('0744', 8)) + fs.writeFileSync(ours, '#!/usr/bin/env cat\nours\n') + fs.chmodSync(ours, parseInt('0754', 8)) + t.end() +}) + +t.test('promise', { skip: promiseSkip }, function (t) { + var isexe = reset() + t.test('meow async', function (t) { + isexe(meow).then(function (is) { + t.ok(is) + t.end() + }) + }) + t.test('fail async', function (t) { + isexe(fail).then(function (is) { + t.notOk(is) + t.end() + }) + }) + t.test('noent async', function (t) { + isexe(noent).catch(function (er) { + t.ok(er) + t.end() + }) + }) + t.test('noent ignore async', function (t) { + isexe(noent, { ignoreErrors: true }).then(function (is) { + t.notOk(is) + t.end() + }) + }) + t.end() +}) + +t.test('no promise', function (t) { + global.Promise = null + var isexe = reset() + t.throws('try to meow a promise', function () { + isexe(meow) + }) + t.end() +}) + +t.test('access', { skip: accessSkip || winSkip }, function (t) { + runTest(t) +}) + +t.test('mode', { skip: winSkip }, function (t) { + delete fs.access + delete fs.accessSync + var isexe = reset() + t.ok(isexe.sync(ours, { uid: 0, gid: 0 })) + t.ok(isexe.sync(mine, { uid: 0, gid: 0 })) + runTest(t) +}) + +t.test('windows', function (t) { + global.TESTING_WINDOWS = true + var pathExt = '.EXE;.CAT;.CMD;.COM' + t.test('pathExt option', function (t) { + runTest(t, { pathExt: '.EXE;.CAT;.CMD;.COM' }) + }) + t.test('pathExt env', function (t) { + process.env.PATHEXT = pathExt + runTest(t) + }) + t.test('no pathExt', function (t) { + // with a pathExt of '', any filename is fine. + // so the "fail" one would still pass. + runTest(t, { pathExt: '', skipFail: true }) + }) + t.test('pathext with empty entry', function (t) { + // with a pathExt of '', any filename is fine. + // so the "fail" one would still pass. + runTest(t, { pathExt: ';' + pathExt, skipFail: true }) + }) + t.end() +}) + +t.test('cleanup', function (t) { + rimraf.sync(fixture) + t.end() +}) + +function runTest (t, options) { + var isexe = reset() + + var optionsIgnore = Object.create(options || {}) + optionsIgnore.ignoreErrors = true + + if (!options || !options.skipFail) { + t.notOk(isexe.sync(fail, options)) + } + t.notOk(isexe.sync(noent, optionsIgnore)) + if (!options) { + t.ok(isexe.sync(meow)) + } else { + t.ok(isexe.sync(meow, options)) + } + + t.ok(isexe.sync(mine, options)) + t.ok(isexe.sync(ours, options)) + t.throws(function () { + isexe.sync(noent, options) + }) + + t.test('meow async', function (t) { + if (!options) { + isexe(meow, function (er, is) { + if (er) { + throw er + } + t.ok(is) + t.end() + }) + } else { + isexe(meow, options, function (er, is) { + if (er) { + throw er + } + t.ok(is) + t.end() + }) + } + }) + + t.test('mine async', function (t) { + isexe(mine, options, function (er, is) { + if (er) { + throw er + } + t.ok(is) + t.end() + }) + }) + + t.test('ours async', function (t) { + isexe(ours, options, function (er, is) { + if (er) { + throw er + } + t.ok(is) + t.end() + }) + }) + + if (!options || !options.skipFail) { + t.test('fail async', function (t) { + isexe(fail, options, function (er, is) { + if (er) { + throw er + } + t.notOk(is) + t.end() + }) + }) + } + + t.test('noent async', function (t) { + isexe(noent, options, function (er, is) { + t.ok(er) + t.notOk(is) + t.end() + }) + }) + + t.test('noent ignore async', function (t) { + isexe(noent, optionsIgnore, function (er, is) { + if (er) { + throw er + } + t.notOk(is) + t.end() + }) + }) + + t.end() +} diff --git a/node_modules/isexe/windows.js b/node_modules/isexe/windows.js new file mode 100644 index 0000000..aba8561 --- /dev/null +++ b/node_modules/isexe/windows.js @@ -0,0 +1,36 @@ +module.exports = isexe +isexe.sync = sync + +var fs = require('fs') + +function checkPathExt (path, options) { + var pathext = options.pathExt !== undefined ? + options.pathExt : process.env.PATHEXT + + if (!pathext) { + return true + } + + pathext = pathext.split(';') + if (pathext.indexOf('') !== -1) { + return true + } + for (var i = 0; i < pathext.length; i++) { + var p = pathext[i].toLowerCase() + if (p && path.substr(-p.length).toLowerCase() === p) { + return true + } + } + return false +} + +function isexe (path, options, cb) { + fs.stat(path, function (er, st) { + cb(er, er ? false : checkPathExt(path, options)) + }) +} + +function sync (path, options) { + fs.statSync(path) + return checkPathExt(path, options) +} diff --git a/node_modules/isstream/.jshintrc b/node_modules/isstream/.jshintrc new file mode 100644 index 0000000..c8ef3ca --- /dev/null +++ b/node_modules/isstream/.jshintrc @@ -0,0 +1,59 @@ +{ + "predef": [ ] + , "bitwise": false + , "camelcase": false + , "curly": false + , "eqeqeq": false + , "forin": false + , "immed": false + , "latedef": false + , "noarg": true + , "noempty": true + , "nonew": true + , "plusplus": false + , "quotmark": true + , "regexp": false + , "undef": true + , "unused": true + , "strict": false + , "trailing": true + , "maxlen": 120 + , "asi": true + , "boss": true + , "debug": true + , "eqnull": true + , "esnext": true + , "evil": true + , "expr": true + , "funcscope": false + , "globalstrict": false + , "iterator": false + , "lastsemic": true + , "laxbreak": true + , "laxcomma": true + , "loopfunc": true + , "multistr": false + , "onecase": false + , "proto": false + , "regexdash": false + , "scripturl": true + , "smarttabs": false + , "shadow": false + , "sub": true + , "supernew": false + , "validthis": true + , "browser": true + , "couch": false + , "devel": false + , "dojo": false + , "mootools": false + , "node": true + , "nonstandard": true + , "prototypejs": false + , "rhino": false + , "worker": true + , "wsh": false + , "nomen": false + , "onevar": false + , "passfail": false +} \ No newline at end of file diff --git a/node_modules/isstream/.npmignore b/node_modules/isstream/.npmignore new file mode 100644 index 0000000..aa1ec1e --- /dev/null +++ b/node_modules/isstream/.npmignore @@ -0,0 +1 @@ +*.tgz diff --git a/node_modules/isstream/.travis.yml b/node_modules/isstream/.travis.yml new file mode 100644 index 0000000..1fec2ab --- /dev/null +++ b/node_modules/isstream/.travis.yml @@ -0,0 +1,12 @@ +language: node_js +node_js: + - "0.8" + - "0.10" + - "0.11" +branches: + only: + - master +notifications: + email: + - rod@vagg.org +script: npm test diff --git a/node_modules/isstream/LICENSE.md b/node_modules/isstream/LICENSE.md new file mode 100644 index 0000000..43f7153 --- /dev/null +++ b/node_modules/isstream/LICENSE.md @@ -0,0 +1,11 @@ +The MIT License (MIT) +===================== + +Copyright (c) 2015 Rod Vagg +--------------------------- + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/isstream/README.md b/node_modules/isstream/README.md new file mode 100644 index 0000000..06770e8 --- /dev/null +++ b/node_modules/isstream/README.md @@ -0,0 +1,66 @@ +# isStream + +[![Build Status](https://secure.travis-ci.org/rvagg/isstream.png)](http://travis-ci.org/rvagg/isstream) + +**Test if an object is a `Stream`** + +[![NPM](https://nodei.co/npm/isstream.svg)](https://nodei.co/npm/isstream/) + +The missing `Stream.isStream(obj)`: determine if an object is standard Node.js `Stream`. Works for Node-core `Stream` objects (for 0.8, 0.10, 0.11, and in theory, older and newer versions) and all versions of **[readable-stream](https://github.com/isaacs/readable-stream)**. + +## Usage: + +```js +var isStream = require('isstream') +var Stream = require('stream') + +isStream(new Stream()) // true + +isStream({}) // false + +isStream(new Stream.Readable()) // true +isStream(new Stream.Writable()) // true +isStream(new Stream.Duplex()) // true +isStream(new Stream.Transform()) // true +isStream(new Stream.PassThrough()) // true +``` + +## But wait! There's more! + +You can also test for `isReadable(obj)`, `isWritable(obj)` and `isDuplex(obj)` to test for implementations of Streams2 (and Streams3) base classes. + +```js +var isReadable = require('isstream').isReadable +var isWritable = require('isstream').isWritable +var isDuplex = require('isstream').isDuplex +var Stream = require('stream') + +isReadable(new Stream()) // false +isWritable(new Stream()) // false +isDuplex(new Stream()) // false + +isReadable(new Stream.Readable()) // true +isReadable(new Stream.Writable()) // false +isReadable(new Stream.Duplex()) // true +isReadable(new Stream.Transform()) // true +isReadable(new Stream.PassThrough()) // true + +isWritable(new Stream.Readable()) // false +isWritable(new Stream.Writable()) // true +isWritable(new Stream.Duplex()) // true +isWritable(new Stream.Transform()) // true +isWritable(new Stream.PassThrough()) // true + +isDuplex(new Stream.Readable()) // false +isDuplex(new Stream.Writable()) // false +isDuplex(new Stream.Duplex()) // true +isDuplex(new Stream.Transform()) // true +isDuplex(new Stream.PassThrough()) // true +``` + +*Reminder: when implementing your own streams, please [use **readable-stream** rather than core streams](http://r.va.gg/2014/06/why-i-dont-use-nodes-core-stream-module.html).* + + +## License + +**isStream** is Copyright (c) 2015 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE.md file for more details. diff --git a/node_modules/isstream/isstream.js b/node_modules/isstream/isstream.js new file mode 100644 index 0000000..a1d104a --- /dev/null +++ b/node_modules/isstream/isstream.js @@ -0,0 +1,27 @@ +var stream = require('stream') + + +function isStream (obj) { + return obj instanceof stream.Stream +} + + +function isReadable (obj) { + return isStream(obj) && typeof obj._read == 'function' && typeof obj._readableState == 'object' +} + + +function isWritable (obj) { + return isStream(obj) && typeof obj._write == 'function' && typeof obj._writableState == 'object' +} + + +function isDuplex (obj) { + return isReadable(obj) && isWritable(obj) +} + + +module.exports = isStream +module.exports.isReadable = isReadable +module.exports.isWritable = isWritable +module.exports.isDuplex = isDuplex diff --git a/node_modules/isstream/package.json b/node_modules/isstream/package.json new file mode 100644 index 0000000..e930b3e --- /dev/null +++ b/node_modules/isstream/package.json @@ -0,0 +1,93 @@ +{ + "_args": [ + [ + { + "raw": "isstream@0.1.x", + "scope": null, + "escapedName": "isstream", + "name": "isstream", + "rawSpec": "0.1.x", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/winston" + ] + ], + "_from": "isstream@>=0.1.0 <0.2.0", + "_id": "isstream@0.1.2", + "_inCache": true, + "_location": "/isstream", + "_nodeVersion": "1.4.3", + "_npmUser": { + "name": "rvagg", + "email": "rod@vagg.org" + }, + "_npmVersion": "2.6.1", + "_phantomChildren": {}, + "_requested": { + "raw": "isstream@0.1.x", + "scope": null, + "escapedName": "isstream", + "name": "isstream", + "rawSpec": "0.1.x", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/winston" + ], + "_resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "_shasum": "47e63f7af55afa6f92e1500e690eb8b8529c099a", + "_shrinkwrap": null, + "_spec": "isstream@0.1.x", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/winston", + "author": { + "name": "Rod Vagg", + "email": "rod@vagg.org" + }, + "bugs": { + "url": "https://github.com/rvagg/isstream/issues" + }, + "dependencies": {}, + "description": "Determine if an object is a Stream", + "devDependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x", + "tape": "~2.12.3" + }, + "directories": {}, + "dist": { + "shasum": "47e63f7af55afa6f92e1500e690eb8b8529c099a", + "tarball": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" + }, + "gitHead": "cd39cba6da939b4fc9110825203adc506422c3dc", + "homepage": "https://github.com/rvagg/isstream", + "keywords": [ + "stream", + "type", + "streams", + "readable-stream", + "hippo" + ], + "license": "MIT", + "main": "isstream.js", + "maintainers": [ + { + "name": "rvagg", + "email": "rod@vagg.org" + } + ], + "name": "isstream", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/rvagg/isstream.git" + }, + "scripts": { + "test": "tar --xform 's/^package/readable-stream-1.0/' -zxf readable-stream-1.0.*.tgz && tar --xform 's/^package/readable-stream-1.1/' -zxf readable-stream-1.1.*.tgz && node test.js; rm -rf readable-stream-1.?/" + }, + "version": "0.1.2" +} diff --git a/node_modules/isstream/test.js b/node_modules/isstream/test.js new file mode 100644 index 0000000..8c950c5 --- /dev/null +++ b/node_modules/isstream/test.js @@ -0,0 +1,168 @@ +var tape = require('tape') + , EE = require('events').EventEmitter + , util = require('util') + + + , isStream = require('./') + , isReadable = require('./').isReadable + , isWritable = require('./').isWritable + , isDuplex = require('./').isDuplex + + , CoreStreams = require('stream') + , ReadableStream10 = require('./readable-stream-1.0/') + , ReadableStream11 = require('./readable-stream-1.1/') + + +function test (pass, type, stream) { + tape('isStream(' + type + ')', function (t) { + t.plan(1) + t.ok(pass === isStream(stream), type) + }) +} + + +function testReadable (pass, type, stream) { + tape('isReadable(' + type + ')', function (t) { + t.plan(1) + t.ok(pass === isReadable(stream), type) + }) +} + + +function testWritable (pass, type, stream) { + tape('isWritable(' + type + ')', function (t) { + t.plan(1) + t.ok(pass === isWritable(stream), type) + }) +} + + +function testDuplex (pass, type, stream) { + tape('isDuplex(' + type + ')', function (t) { + t.plan(1) + t.ok(pass === isDuplex(stream), type) + }) +} + + +[ undefined, null, '', true, false, 0, 1, 1.0, 'string', {}, function foo () {} ].forEach(function (o) { + test(false, 'non-stream / primitive: ' + (JSON.stringify(o) || (o && o.toString()) || o), o) +}) + + +test(false, 'fake stream obj', { pipe: function () {} }) + + +;(function () { + + // looks like a stream! + + function Stream () { + EE.call(this) + } + util.inherits(Stream, EE) + Stream.prototype.pipe = function () {} + Stream.Stream = Stream + + test(false, 'fake stream "new Stream()"', new Stream()) + +}()) + + +test(true, 'CoreStreams.Stream', new (CoreStreams.Stream)()) +test(true, 'CoreStreams.Readable', new (CoreStreams.Readable)()) +test(true, 'CoreStreams.Writable', new (CoreStreams.Writable)()) +test(true, 'CoreStreams.Duplex', new (CoreStreams.Duplex)()) +test(true, 'CoreStreams.Transform', new (CoreStreams.Transform)()) +test(true, 'CoreStreams.PassThrough', new (CoreStreams.PassThrough)()) + +test(true, 'ReadableStream10.Readable', new (ReadableStream10.Readable)()) +test(true, 'ReadableStream10.Writable', new (ReadableStream10.Writable)()) +test(true, 'ReadableStream10.Duplex', new (ReadableStream10.Duplex)()) +test(true, 'ReadableStream10.Transform', new (ReadableStream10.Transform)()) +test(true, 'ReadableStream10.PassThrough', new (ReadableStream10.PassThrough)()) + +test(true, 'ReadableStream11.Readable', new (ReadableStream11.Readable)()) +test(true, 'ReadableStream11.Writable', new (ReadableStream11.Writable)()) +test(true, 'ReadableStream11.Duplex', new (ReadableStream11.Duplex)()) +test(true, 'ReadableStream11.Transform', new (ReadableStream11.Transform)()) +test(true, 'ReadableStream11.PassThrough', new (ReadableStream11.PassThrough)()) + + +testReadable(false, 'CoreStreams.Stream', new (CoreStreams.Stream)()) +testReadable(true, 'CoreStreams.Readable', new (CoreStreams.Readable)()) +testReadable(false, 'CoreStreams.Writable', new (CoreStreams.Writable)()) +testReadable(true, 'CoreStreams.Duplex', new (CoreStreams.Duplex)()) +testReadable(true, 'CoreStreams.Transform', new (CoreStreams.Transform)()) +testReadable(true, 'CoreStreams.PassThrough', new (CoreStreams.PassThrough)()) + +testReadable(true, 'ReadableStream10.Readable', new (ReadableStream10.Readable)()) +testReadable(false, 'ReadableStream10.Writable', new (ReadableStream10.Writable)()) +testReadable(true, 'ReadableStream10.Duplex', new (ReadableStream10.Duplex)()) +testReadable(true, 'ReadableStream10.Transform', new (ReadableStream10.Transform)()) +testReadable(true, 'ReadableStream10.PassThrough', new (ReadableStream10.PassThrough)()) + +testReadable(true, 'ReadableStream11.Readable', new (ReadableStream11.Readable)()) +testReadable(false, 'ReadableStream11.Writable', new (ReadableStream11.Writable)()) +testReadable(true, 'ReadableStream11.Duplex', new (ReadableStream11.Duplex)()) +testReadable(true, 'ReadableStream11.Transform', new (ReadableStream11.Transform)()) +testReadable(true, 'ReadableStream11.PassThrough', new (ReadableStream11.PassThrough)()) + + +testWritable(false, 'CoreStreams.Stream', new (CoreStreams.Stream)()) +testWritable(false, 'CoreStreams.Readable', new (CoreStreams.Readable)()) +testWritable(true, 'CoreStreams.Writable', new (CoreStreams.Writable)()) +testWritable(true, 'CoreStreams.Duplex', new (CoreStreams.Duplex)()) +testWritable(true, 'CoreStreams.Transform', new (CoreStreams.Transform)()) +testWritable(true, 'CoreStreams.PassThrough', new (CoreStreams.PassThrough)()) + +testWritable(false, 'ReadableStream10.Readable', new (ReadableStream10.Readable)()) +testWritable(true, 'ReadableStream10.Writable', new (ReadableStream10.Writable)()) +testWritable(true, 'ReadableStream10.Duplex', new (ReadableStream10.Duplex)()) +testWritable(true, 'ReadableStream10.Transform', new (ReadableStream10.Transform)()) +testWritable(true, 'ReadableStream10.PassThrough', new (ReadableStream10.PassThrough)()) + +testWritable(false, 'ReadableStream11.Readable', new (ReadableStream11.Readable)()) +testWritable(true, 'ReadableStream11.Writable', new (ReadableStream11.Writable)()) +testWritable(true, 'ReadableStream11.Duplex', new (ReadableStream11.Duplex)()) +testWritable(true, 'ReadableStream11.Transform', new (ReadableStream11.Transform)()) +testWritable(true, 'ReadableStream11.PassThrough', new (ReadableStream11.PassThrough)()) + + +testDuplex(false, 'CoreStreams.Stream', new (CoreStreams.Stream)()) +testDuplex(false, 'CoreStreams.Readable', new (CoreStreams.Readable)()) +testDuplex(false, 'CoreStreams.Writable', new (CoreStreams.Writable)()) +testDuplex(true, 'CoreStreams.Duplex', new (CoreStreams.Duplex)()) +testDuplex(true, 'CoreStreams.Transform', new (CoreStreams.Transform)()) +testDuplex(true, 'CoreStreams.PassThrough', new (CoreStreams.PassThrough)()) + +testDuplex(false, 'ReadableStream10.Readable', new (ReadableStream10.Readable)()) +testDuplex(false, 'ReadableStream10.Writable', new (ReadableStream10.Writable)()) +testDuplex(true, 'ReadableStream10.Duplex', new (ReadableStream10.Duplex)()) +testDuplex(true, 'ReadableStream10.Transform', new (ReadableStream10.Transform)()) +testDuplex(true, 'ReadableStream10.PassThrough', new (ReadableStream10.PassThrough)()) + +testDuplex(false, 'ReadableStream11.Readable', new (ReadableStream11.Readable)()) +testDuplex(false, 'ReadableStream11.Writable', new (ReadableStream11.Writable)()) +testDuplex(true, 'ReadableStream11.Duplex', new (ReadableStream11.Duplex)()) +testDuplex(true, 'ReadableStream11.Transform', new (ReadableStream11.Transform)()) +testDuplex(true, 'ReadableStream11.PassThrough', new (ReadableStream11.PassThrough)()) + + +;[ CoreStreams, ReadableStream10, ReadableStream11 ].forEach(function (p) { + [ 'Stream', 'Readable', 'Writable', 'Duplex', 'Transform', 'PassThrough' ].forEach(function (k) { + if (!p[k]) + return + + function SubStream () { + p[k].call(this) + } + util.inherits(SubStream, p[k]) + + test(true, 'Stream subclass: ' + p.name + '.' + k, new SubStream()) + + }) +}) + + + diff --git a/node_modules/js-yaml/HISTORY.md b/node_modules/js-yaml/HISTORY.md new file mode 100644 index 0000000..dfc48c2 --- /dev/null +++ b/node_modules/js-yaml/HISTORY.md @@ -0,0 +1,155 @@ +2.0.5 / 2013-04-26 +------------------ + +* Close security issue in !!js/function constructor. + Big thanks to @nealpoole for security audit. + + +2.0.4 / 2013-04-08 +------------------ + +* Updated .npmignore to reduce package size + + +2.0.3 / 2013-02-26 +------------------ + +* Fixed dumping of empty arrays ans objects. ([] and {} instead of null) + + +2.0.2 / 2013-02-15 +------------------ + +* Fixed input validation: tabs are printable characters. + + +2.0.1 / 2013-02-09 +------------------ + +* Fixed error, when options not passed to function cass + + +2.0.0 / 2013-02-09 +------------------ + +* Full rewrite. New architecture. Fast one-stage parsing. +* Changed custom types API. +* Added YAML dumper. + + +1.0.3 / 2012-11-05 +------------------ + +* Fixed utf-8 files loading. + + +1.0.2 / 2012-08-02 +------------------ + +* Pull out hand-written shims. Use ES5-Shims for old browsers support. See #44. +* Fix timstamps incorectly parsed in local time when no time part specified. + + +1.0.1 / 2012-07-07 +------------------ + +* Fixes `TypeError: 'undefined' is not an object` under Safari. Thanks Phuong. +* Fix timestamps incorrectly parsed in local time. Thanks @caolan. Closes #46. + + +1.0.0 / 2012-07-01 +------------------ + +* `y`, `yes`, `n`, `no`, `on`, `off` are not converted to Booleans anymore. + Fixes #42. +* `require(filename)` now returns a single document and throws an Error if + file contains more than one document. +* CLI was merged back from js-yaml.bin + + +0.3.7 / 2012-02-28 +------------------ + +* Fix export of `addConstructor()`. Closes #39. + + +0.3.6 / 2012-02-22 +------------------ + +* Removed AMD parts - too buggy to use. Need help to rewrite from scratch +* Removed YUI compressor warning (renamed `double` variable). Closes #40. + + +0.3.5 / 2012-01-10 +------------------ + +* Workagound for .npmignore fuckup under windows. Thanks to airportyh. + + +0.3.4 / 2011-12-24 +------------------ + +* Fixes str[] for oldIEs support. +* Adds better has change support for browserified demo. +* improves compact output of Error. Closes #33. + + +0.3.3 / 2011-12-20 +------------------ + +* jsyaml executable moved to separate module. +* adds `compact` stringification of Errors. + + +0.3.2 / 2011-12-16 +------------------ + +* Fixes ug with block style scalars. Closes #26. +* All sources are passing JSLint now. +* Fixes bug in Safari. Closes #28. +* Fixes bug in Opers. Closes #29. +* Improves browser support. Closes #20. +* Added jsyaml executable. +* Added !!js/function support. Closes #12. + + +0.3.1 / 2011-11-18 +------------------ + +* Added AMD support for browserified version. +* Wrapped browserified js-yaml into closure. +* Fixed the resolvement of non-specific tags. Closes #17. +* Added permalinks for online demo YAML snippets. Now we have YPaste service, lol. +* Added !!js/regexp and !!js/undefined types. Partially solves #12. +* Fixed !!set mapping. +* Fixed month parse in dates. Closes #19. + + +0.3.0 / 2011-11-09 +------------------ + +* Removed JS.Class dependency. Closes #3. +* Added browserified version. Closes #13. +* Added live demo of browserified version. +* Ported some of the PyYAML tests. See #14. +* Fixed timestamp bug when fraction was given. + + +0.2.2 / 2011-11-06 +------------------ + +* Fixed crash on docs without ---. Closes #8. +* Fixed miltiline string parse +* Fixed tests/comments for using array as key + + +0.2.1 / 2011-11-02 +------------------ + +* Fixed short file read (<4k). Closes #9. + + +0.2.0 / 2011-11-02 +------------------ + +* First public release diff --git a/node_modules/js-yaml/LICENSE b/node_modules/js-yaml/LICENSE new file mode 100644 index 0000000..0f16ee9 --- /dev/null +++ b/node_modules/js-yaml/LICENSE @@ -0,0 +1,21 @@ +(The MIT License) + +Copyright (C) 2011, 2013 by Vitaly Puzrin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/js-yaml/README.md b/node_modules/js-yaml/README.md new file mode 100644 index 0000000..e326d60 --- /dev/null +++ b/node_modules/js-yaml/README.md @@ -0,0 +1,249 @@ +JS-YAML - YAML 1.2 parser and serializer for JavaScript +======================================================= + +[![Build Status](https://secure.travis-ci.org/nodeca/js-yaml.png)](http://travis-ci.org/nodeca/js-yaml) + +[Online Demo](http://nodeca.github.com/js-yaml/) + + +This is an implementation of [YAML](http://yaml.org/), a human friendly data +serialization language. Started as [PyYAML](http://pyyaml.org/) port, it was +completely rewritten from scratch. Now it's very fast, and supports 1.2 spec. + + +Breaking changes in 1.x.x -> 2.0.x +---------------------------------- + +If your have not used __custom__ tags or loader classes - no changes needed. Just +upgrade library and enjoy high parse speed. + +In other case, you should rewrite your tag constructors and custom loader +classes, to conform new schema-based API. See +[examples](https://github.com/nodeca/js-yaml/tree/master/examples) and +[wiki](https://github.com/nodeca/js-yaml/wiki) for details. +Note, that parser internals were completely rewritten. + + +Installation +------------ + +### YAML module for node.js + +``` +npm install js-yaml +``` + + +### CLI executable + +If you want to inspect your YAML files from CLI, install js-yaml globally: + +``` +npm install js-yaml -g +``` + +#### Usage + +``` +usage: js-yaml [-h] [-v] [-c] [-j] [-t] file + +Positional arguments: + file File with YAML document(s) + +Optional arguments: + -h, --help Show this help message and exit. + -v, --version Show program's version number and exit. + -c, --compact Display errors in compact mode + -j, --to-json Output a non-funky boring JSON + -t, --trace Show stack trace on error +``` + + +### Bundled YAML library for browsers + +``` html + + +``` + +Browser support was done mostly for online demo. If you find any errors - feel +free to send pull requests with fixes. Also note, that IE and other old browsers +needs [es5-shims](https://github.com/kriskowal/es5-shim) to operate. + + +API +--- + +Here we cover the most 'useful' methods. If you need advanced details (creating +your own tags), see [wiki](https://github.com/nodeca/js-yaml/wiki) and +[examples](https://github.com/nodeca/js-yaml/tree/master/examples) for more +info. + +In node.js JS-YAML automatically registers handlers for `.yml` and `.yaml` +files. You can load them just with `require`. That's mostly equivalent to +calling `load()` on fetched content of a file. Just with one string! + +``` javascript +require('js-yaml'); + +// Get document, or throw exception on error +try { + var doc = require('/home/ixti/example.yml'); + console.log(doc); +} catch (e) { + console.log(e); +} +``` + + +### load (string [ , options ]) + +Parses `string` as single YAML document. Returns a JavaScript object or throws +`YAMLException` on error. + +NOTE: This function **does not** understands multi-document sources, it throws +exception on those. + +options: + +- `filename` _(default: null)_ - string to be used as a file path in + error/warning messages. +- `strict` _(default - false)_ makes the loader to throw errors instead of + warnings. +- `schema` _(default: `DEFAULT_SCHEMA`)_ - specifies a schema to use. + + +### loadAll (string, iterator [ , options ]) + +Same as `load()`, but understands multi-document sources and apply `iterator` to +each document. + +``` javascript +var yaml = require('js-yaml'); + +yaml.loadAll(data, function (doc) { + console.log(doc); +}); +``` + + +### safeLoad (string [ , options ]) + +Same as `load()` but uses `SAFE_SCHEMA` by default - only recommended tags of +YAML specification (no JavaScript-specific tags, e.g. `!!js/regexp`). + + +### safeLoadAll (string, iterator [ , options ]) + +Same as `loadAll()` but uses `SAFE_SCHEMA` by default - only recommended tags of +YAML specification (no JavaScript-specific tags, e.g. `!!js/regexp`). + + +### dump (object [ , options ]) + +Serializes `object` as YAML document. + +options: + +- `indent` _(default: 2)_ - indentation width to use (in spaces). +- `flowLevel` (default: -1) - specifies level of nesting, when to switch from + block to flow style for collections. -1 means block style everwhere +- `styles` - "tag" => "style" map. Each tag may have own set of styles. +- `schema` _(default: `DEFAULT_SCHEMA`)_ specifies a schema to use. + +styles: + +``` none +!!null + "canonical" => "~" + +!!int + "binary" => "0b1", "0b101010", "0b1110001111010" + "octal" => "01", "052", "016172" + "decimal" => "1", "42", "7290" + "hexadecimal" => "0x1", "0x2A", "0x1C7A" + +!!null, !!bool, !!float + "lowercase" => "null", "true", "false", ".nan", '.inf' + "uppercase" => "NULL", "TRUE", "FALSE", ".NAN", '.INF' + "camelcase" => "Null", "True", "False", ".NaN", '.Inf' +``` + +By default, !!int uses `decimal`, and !!null, !!bool, !!float use `lowercase`. + + +### safeDump (object [ , options ]) + +Same as `dump()` but uses `SAFE_SCHEMA` by default - only recommended tags of +YAML specification (no JavaScript-specific tags, e.g. `!!js/regexp`). + + +Supported YAML types +-------------------- + +The list of standard YAML tags and corresponding JavaScipt types. See also +[YAML tag discussion](http://pyyaml.org/wiki/YAMLTagDiscussion) and +[YAML types repository](http://yaml.org/type/). + +``` +!!null '' # null +!!bool 'yes' # bool +!!int '3...' # number +!!float '3.14...' # number +!!binary '...base64...' # buffer +!!timestamp 'YYYY-...' # date +!!omap [ ... ] # array of key-value pairs +!!pairs [ ... ] # array or array pairs +!!set { ... } # array of objects with given keys and null values +!!str '...' # string +!!seq [ ... ] # array +!!map { ... } # object +``` + +**JavaScript-specific tags** + +``` +!!js/regexp /pattern/gim # RegExp +!!js/undefined '' # Undefined +!!js/function 'function () {...}' # Function +``` + + + + +## Caveats + +Note, that you use arrays or objects as key in JS-YAML. JS do not allows objects +or array as keys, and stringifies (by calling .toString method) them at the +moment of adding them. + +``` yaml +--- +? [ foo, bar ] +: - baz +? { foo: bar } +: - baz + - baz +``` + +``` javascript +{ "foo,bar": ["baz"], "[object Object]": ["baz", "baz"] } +``` + +Also, reading of properties on implicit block mapping keys is not supported yet. +So, the following YAML document cannot be loaded. + +``` yaml +&anchor foo: + foo: bar + *anchor: duplicate key + baz: bat + *anchor: duplicate key +``` + +## License + +View the [LICENSE](https://github.com/nodeca/js-yaml/blob/master/LICENSE) file +(MIT). diff --git a/node_modules/js-yaml/bin/js-yaml.js b/node_modules/js-yaml/bin/js-yaml.js new file mode 100644 index 0000000..5110a4c --- /dev/null +++ b/node_modules/js-yaml/bin/js-yaml.js @@ -0,0 +1,125 @@ +#!/usr/bin/env node + + +'use strict'; + + +// stdlib +var fs = require('fs'); +var util = require('util'); + + +// 3rd-party +var ArgumentParser = require('argparse').ArgumentParser; + + +// internal +var yaml = require('..'); + + +//////////////////////////////////////////////////////////////////////////////// + + +var cli = new ArgumentParser({ + prog: 'js-yaml', + version: require('../package.json').version, + addHelp: true +}); + + +cli.addArgument(['-c', '--compact'], { + help: 'Display errors in compact mode', + action: 'storeTrue' +}); + + +cli.addArgument(['-j', '--to-json'], { + help: 'Output a non-funky boring JSON', + dest: 'json', + action: 'storeTrue' +}); + + +cli.addArgument(['-t', '--trace'], { + help: 'Show stack trace on error', + action: 'storeTrue' +}); + + +cli.addArgument(['file'], { + help: 'File to read' +}); + + +//////////////////////////////////////////////////////////////////////////////// + + +var options = cli.parseArgs(); + + +//////////////////////////////////////////////////////////////////////////////// + + +fs.readFile(options.file, 'utf8', function (error, input) { + var output, isYaml; + + if (error) { + if ('ENOENT' === error.code) { + console.error('File not found: ' + options.file); + process.exit(2); + } + + console.error( + options.trace && error.stack || + error.message || + String(error)); + + process.exit(1); + } + + try { + output = JSON.parse(input); + isYaml = false; + } catch (error) { + if (error instanceof SyntaxError) { + try { + output = []; + yaml.loadAll(input, function (doc) { output.push(doc); }, {}); + isYaml = true; + + if (0 === output.length) { + output = null; + } else if (1 === output.length) { + output = output[0]; + } + } catch (error) { + if (options.trace && error.stack) { + console.error(error.stack); + } else { + console.error(error.toString(options.compact)); + } + + process.exit(1); + } + } else { + console.error( + options.trace && error.stack || + error.message || + String(error)); + + process.exit(1); + } + } + + if (isYaml) { + if (options.json) { + console.log(JSON.stringify(output, null, ' ')); + } else { + console.log("\n" + util.inspect(output, false, 10, true) + "\n"); + } + } else { + console.log(yaml.dump(output)); + } + + process.exit(0); +}); diff --git a/node_modules/js-yaml/examples/custom_types.js b/node_modules/js-yaml/examples/custom_types.js new file mode 100644 index 0000000..1cb987c --- /dev/null +++ b/node_modules/js-yaml/examples/custom_types.js @@ -0,0 +1,104 @@ +'use strict'; + + +var fs = require('fs'); +var path = require('path'); +var util = require('util'); +var yaml = require('../lib/js-yaml'); + + +// Let define a couple of classes... + +function Point(x, y, z) { + this.klass = 'Point'; + this.x = x; + this.y = y; + this.z = z; +} + + +function Space(height, width, points) { + if (points) { + if (!points.every(function (point) { return point instanceof Point; })) { + throw new Error('A non-Point inside a points array!'); + } + } + + this.klass = 'Space'; + this.height = height; + this.width = width; + this.points = points; +} + + +// Let define YAML types to load and dump our Point/Space objects. + +var pointYamlType = new yaml.Type('!point', { + // The information used to load a Point. + loader: { + kind: 'array', // It must be an array. (sequence in YAML) + resolver: function (object) { + // It must contain exactly tree elements. + if (3 === object.length) { + return new Point(object[0], object[1], object[2]); + + // Otherwise, it is NOT a Point. + } else { + return yaml.NIL; + } + } + }, + // The information used to dump a Point. + dumper: { + kind: 'object', // It must be an object but not an array. + instanceOf: Point, // Also, it must be an instance of Point class. + representer: function (point) { + // And it should be represented in YAML as three-element sequence. + return [ point.x, point.y, point.z ]; + } + } +}); + + +var spaceYamlType = new yaml.Type('!space', { + loader: { + kind: 'object', // 'object' here means 'mapping' in YAML. + resolver: function (object) { + return new Space(object.height, object.width, object.points); + } + }, + dumper: { + kind: 'object', + instanceOf: Space + // The representer is omitted here. So, Space objects will be dumped as is. + // That is regular mapping with three key-value pairs but with !space tag. + } +}); + + +// After our types are defined, it's time to join them into a schema. + +var SPACE_SCHEMA = yaml.Schema.create([ spaceYamlType, pointYamlType ]); + + +// And read a document using that schema. + +fs.readFile(path.join(__dirname, 'custom_types.yaml'), 'utf8', function (error, data) { + var loaded; + + if (!error) { + loaded = yaml.load(data, { schema: SPACE_SCHEMA }); + console.log(util.inspect(loaded, false, 20, true)); + } else { + console.error(error.stack || error.message || String(error)); + } +}); + + +// There are some exports to play with this example interactively. + +module.exports.Point = Point; +module.exports.Space = Space; +module.exports.pointYamlType = pointYamlType; +module.exports.spaceYamlType = spaceYamlType; +module.exports.SPACE_SCHEMA = SPACE_SCHEMA; diff --git a/node_modules/js-yaml/examples/custom_types.yaml b/node_modules/js-yaml/examples/custom_types.yaml new file mode 100644 index 0000000..033134f --- /dev/null +++ b/node_modules/js-yaml/examples/custom_types.yaml @@ -0,0 +1,18 @@ +subject: Custom types in JS-YAML +spaces: +- !space + height: 1000 + width: 1000 + points: + - !point [ 10, 43, 23 ] + - !point [ 165, 0, 50 ] + - !point [ 100, 100, 100 ] + +- !space + height: 64 + width: 128 + points: + - !point [ 12, 43, 0 ] + - !point [ 1, 4, 90 ] + +- !space {} # An empty space diff --git a/node_modules/js-yaml/examples/dumper.js b/node_modules/js-yaml/examples/dumper.js new file mode 100644 index 0000000..7952b18 --- /dev/null +++ b/node_modules/js-yaml/examples/dumper.js @@ -0,0 +1,31 @@ +'use strict'; + + +var yaml = require('../lib/js-yaml'); +var object = require('./dumper.json'); + + +console.log(yaml.dump(object, { + flowLevel: 3, + styles: { + '!!int' : 'hexadecimal', + '!!null' : 'camelcase' + } +})); + + +// Output: +//============================================================================== +// name: Wizzard +// level: 0x11 +// sanity: Null +// inventory: +// - name: Hat +// features: [magic, pointed] +// traits: {} +// - name: Staff +// features: [] +// traits: {damage: 0xA} +// - name: Cloak +// features: [old] +// traits: {defence: 0x0, comfort: 0x3} diff --git a/node_modules/js-yaml/examples/dumper.json b/node_modules/js-yaml/examples/dumper.json new file mode 100644 index 0000000..9f54c05 --- /dev/null +++ b/node_modules/js-yaml/examples/dumper.json @@ -0,0 +1,22 @@ +{ + "name" : "Wizzard", + "level" : 17, + "sanity" : null, + "inventory" : [ + { + "name" : "Hat", + "features" : [ "magic", "pointed" ], + "traits" : {} + }, + { + "name" : "Staff", + "features" : [], + "traits" : { "damage" : 10 } + }, + { + "name" : "Cloak", + "features" : [ "old" ], + "traits" : { "defence" : 0, "comfort" : 3 } + } + ] +} diff --git a/node_modules/js-yaml/examples/sample_document.js b/node_modules/js-yaml/examples/sample_document.js new file mode 100644 index 0000000..1ce370d --- /dev/null +++ b/node_modules/js-yaml/examples/sample_document.js @@ -0,0 +1,15 @@ +'use strict'; + + +var inspect = require('util').inspect; + +// just require jsyaml +require('../lib/js-yaml'); + + +try { + var doc = require(__dirname + '/sample_document.yaml'); + console.log(inspect(doc, false, 10, true)); +} catch (e) { + console.log(e.stack || e.toString()); +} diff --git a/node_modules/js-yaml/examples/sample_document.yaml b/node_modules/js-yaml/examples/sample_document.yaml new file mode 100644 index 0000000..4479ee9 --- /dev/null +++ b/node_modules/js-yaml/examples/sample_document.yaml @@ -0,0 +1,197 @@ +--- +# Collection Types ############################################################# +################################################################################ + +# http://yaml.org/type/map.html -----------------------------------------------# + +map: + # Unordered set of key: value pairs. + Block style: !!map + Clark : Evans + Ingy : döt Net + Oren : Ben-Kiki + Flow style: !!map { Clark: Evans, Ingy: döt Net, Oren: Ben-Kiki } + +# http://yaml.org/type/omap.html ----------------------------------------------# + +omap: + # Explicitly typed ordered map (dictionary). + Bestiary: !!omap + - aardvark: African pig-like ant eater. Ugly. + - anteater: South-American ant eater. Two species. + - anaconda: South-American constrictor snake. Scaly. + # Etc. + # Flow style + Numbers: !!omap [ one: 1, two: 2, three : 3 ] + +# http://yaml.org/type/pairs.html ---------------------------------------------# + +pairs: + # Explicitly typed pairs. + Block tasks: !!pairs + - meeting: with team. + - meeting: with boss. + - break: lunch. + - meeting: with client. + Flow tasks: !!pairs [ meeting: with team, meeting: with boss ] + +# http://yaml.org/type/set.html -----------------------------------------------# + +set: + # Explicitly typed set. + baseball players: !!set + ? Mark McGwire + ? Sammy Sosa + ? Ken Griffey + # Flow style + baseball teams: !!set { Boston Red Sox, Detroit Tigers, New York Yankees } + +# http://yaml.org/type/seq.html -----------------------------------------------# + +seq: + # Ordered sequence of nodes + Block style: !!seq + - Mercury # Rotates - no light/dark sides. + - Venus # Deadliest. Aptly named. + - Earth # Mostly dirt. + - Mars # Seems empty. + - Jupiter # The king. + - Saturn # Pretty. + - Uranus # Where the sun hardly shines. + - Neptune # Boring. No rings. + - Pluto # You call this a planet? + Flow style: !!seq [ Mercury, Venus, Earth, Mars, # Rocks + Jupiter, Saturn, Uranus, Neptune, # Gas + Pluto ] # Overrated + + +# Scalar Types ################################################################# +################################################################################ + +# http://yaml.org/type/binary.html --------------------------------------------# + +binary: + canonical: !!binary "\ + R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\ + OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\ + +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\ + AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=" + generic: !!binary | + R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 + OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ + +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC + AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= + description: + The binary value above is a tiny arrow encoded as a gif image. + +# http://yaml.org/type/bool.html ----------------------------------------------# + +bool: + - true + - True + - TRUE + - false + - False + - FALSE + +# http://yaml.org/type/float.html ---------------------------------------------# + +float: + canonical: 6.8523015e+5 + exponentioal: 685.230_15e+03 + fixed: 685_230.15 + sexagesimal: 190:20:30.15 + negative infinity: -.inf + not a number: .NaN + +# http://yaml.org/type/int.html -----------------------------------------------# + +int: + canonical: 685230 + decimal: +685_230 + octal: 02472256 + hexadecimal: 0x_0A_74_AE + binary: 0b1010_0111_0100_1010_1110 + sexagesimal: 190:20:30 + +# http://yaml.org/type/merge.html ---------------------------------------------# + +merge: + - &CENTER { x: 1, y: 2 } + - &LEFT { x: 0, y: 2 } + - &BIG { r: 10 } + - &SMALL { r: 1 } + + # All the following maps are equal: + + - # Explicit keys + x: 1 + y: 2 + r: 10 + label: nothing + + - # Merge one map + << : *CENTER + r: 10 + label: center + + - # Merge multiple maps + << : [ *CENTER, *BIG ] + label: center/big + + - # Override + << : [ *BIG, *LEFT, *SMALL ] + x: 1 + label: big/left/small + +# http://yaml.org/type/null.html ----------------------------------------------# + +null: + # This mapping has four keys, + # one has a value. + empty: + canonical: ~ + english: null + ~: null key + # This sequence has five + # entries, two have values. + sparse: + - ~ + - 2nd entry + - + - 4th entry + - Null + +# http://yaml.org/type/str.html -----------------------------------------------# + +string: abcd + +# http://yaml.org/type/timestamp.html -----------------------------------------# + +timestamp: + canonical: 2001-12-15T02:59:43.1Z + valid iso8601: 2001-12-14t21:59:43.10-05:00 + space separated: 2001-12-14 21:59:43.10 -5 + no time zone (Z): 2001-12-15 2:59:43.10 + date (00:00:00Z): 2002-12-14 + + +# JavaScript Specific Types #################################################### +################################################################################ + +# https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp + +regexp: + simple: !!js/regexp foobar + modifiers: !!js/regexp /foobar/mi + +# https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/undefined + +undefined: !!js/undefined ~ + +# https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function + +function: !!js/function > + function foobar() { + return 'Wow! JS-YAML Rocks!'; + } diff --git a/node_modules/js-yaml/index.js b/node_modules/js-yaml/index.js new file mode 100644 index 0000000..40606dd --- /dev/null +++ b/node_modules/js-yaml/index.js @@ -0,0 +1 @@ +module.exports = require('./lib/js-yaml.js'); diff --git a/node_modules/js-yaml/lib/js-yaml.js b/node_modules/js-yaml/lib/js-yaml.js new file mode 100644 index 0000000..a5146a3 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml.js @@ -0,0 +1,33 @@ +'use strict'; + + +var loader = require('./js-yaml/loader'); +var dumper = require('./js-yaml/dumper'); + + +function deprecated(name) { + return function () { + throw new Error('Function ' + name + ' is deprecated and cannot be used.'); + }; +} + + +module.exports.Type = require('./js-yaml/type'); +module.exports.Schema = require('./js-yaml/schema'); +module.exports.MINIMAL_SCHEMA = require('./js-yaml/schema/minimal'); +module.exports.SAFE_SCHEMA = require('./js-yaml/schema/safe'); +module.exports.DEFAULT_SCHEMA = require('./js-yaml/schema/default'); +module.exports.load = loader.load; +module.exports.loadAll = loader.loadAll; +module.exports.safeLoad = loader.safeLoad; +module.exports.safeLoadAll = loader.safeLoadAll; +module.exports.dump = dumper.dump; +module.exports.safeDump = dumper.safeDump; +module.exports.YAMLException = require('./js-yaml/exception'); +module.exports.scan = deprecated('scan'); +module.exports.parse = deprecated('parse'); +module.exports.compose = deprecated('compose'); +module.exports.addConstructor = deprecated('addConstructor'); + + +require('./js-yaml/require'); diff --git a/node_modules/js-yaml/lib/js-yaml/common.js b/node_modules/js-yaml/lib/js-yaml/common.js new file mode 100644 index 0000000..cc7f824 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/common.js @@ -0,0 +1,60 @@ +'use strict'; + + +var NIL = {}; + + +function isNothing(subject) { + return (undefined === subject) || (null === subject); +} + + +function isObject(subject) { + return ('object' === typeof subject) && (null !== subject); +} + + +function toArray(sequence) { + if (Array.isArray(sequence)) { + return sequence; + } else if (isNothing(sequence)) { + return []; + } else { + return [ sequence ]; + } +} + + +function extend(target, source) { + var index, length, key, sourceKeys; + + if (source) { + sourceKeys = Object.keys(source); + + for (index = 0, length = sourceKeys.length; index < length; index += 1) { + key = sourceKeys[index]; + target[key] = source[key]; + } + } + + return target; +} + + +function repeat(string, count) { + var result = '', cycle; + + for (cycle = 0; cycle < count; cycle += 1) { + result += string; + } + + return result; +} + + +module.exports.NIL = NIL; +module.exports.isNothing = isNothing; +module.exports.isObject = isObject; +module.exports.toArray = toArray; +module.exports.repeat = repeat; +module.exports.extend = extend; diff --git a/node_modules/js-yaml/lib/js-yaml/dumper.js b/node_modules/js-yaml/lib/js-yaml/dumper.js new file mode 100644 index 0000000..2385f56 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/dumper.js @@ -0,0 +1,437 @@ +'use strict'; + + +var common = require('./common'); +var NIL = common.NIL; +var YAMLException = require('./exception'); +var DEFAULT_SCHEMA = require('./schema/default'); +var SAFE_SCHEMA = require('./schema/safe'); + + +var _hasOwnProperty = Object.prototype.hasOwnProperty; + + +var CHAR_TAB = 0x09; /* Tab */ +var CHAR_LINE_FEED = 0x0A; /* LF */ +var CHAR_CARRIAGE_RETURN = 0x0D; /* CR */ +var CHAR_SPACE = 0x20; /* Space */ +var CHAR_EXCLAMATION = 0x21; /* ! */ +var CHAR_DOUBLE_QUOTE = 0x22; /* " */ +var CHAR_SHARP = 0x23; /* # */ +var CHAR_PERCENT = 0x25; /* % */ +var CHAR_AMPERSAND = 0x26; /* & */ +var CHAR_SINGLE_QUOTE = 0x27; /* ' */ +var CHAR_ASTERISK = 0x2A; /* * */ +var CHAR_COMMA = 0x2C; /* , */ +var CHAR_MINUS = 0x2D; /* - */ +var CHAR_COLON = 0x3A; /* : */ +var CHAR_GREATER_THAN = 0x3E; /* > */ +var CHAR_QUESTION = 0x3F; /* ? */ +var CHAR_COMMERCIAL_AT = 0x40; /* @ */ +var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ +var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ +var CHAR_GRAVE_ACCENT = 0x60; /* ` */ +var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ +var CHAR_VERTICAL_LINE = 0x7C; /* | */ +var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ + + +var ESCAPE_SEQUENCES = {}; + +ESCAPE_SEQUENCES[0x00] = '\\0'; +ESCAPE_SEQUENCES[0x07] = '\\a'; +ESCAPE_SEQUENCES[0x08] = '\\b'; +ESCAPE_SEQUENCES[0x09] = '\\t'; +ESCAPE_SEQUENCES[0x0A] = '\\n'; +ESCAPE_SEQUENCES[0x0B] = '\\v'; +ESCAPE_SEQUENCES[0x0C] = '\\f'; +ESCAPE_SEQUENCES[0x0D] = '\\r'; +ESCAPE_SEQUENCES[0x1B] = '\\e'; +ESCAPE_SEQUENCES[0x22] = '\\"'; +ESCAPE_SEQUENCES[0x5C] = '\\\\'; +ESCAPE_SEQUENCES[0x85] = '\\N'; +ESCAPE_SEQUENCES[0xA0] = '\\_'; +ESCAPE_SEQUENCES[0x2028] = '\\L'; +ESCAPE_SEQUENCES[0x2029] = '\\P'; + + +function kindOf(object) { + var kind = typeof object; + + if (null === object) { + return 'null'; + } else if ('number' === kind) { + return 0 === object % 1 ? 'integer' : 'float'; + } else if ('object' === kind && Array.isArray(object)) { + return 'array'; + } else { + return kind; + } +} + + +function compileStyleMap(schema, map) { + var result, keys, index, length, tag, style, type; + + if (null === map) { + return {}; + } + + result = {}; + keys = Object.keys(map); + + for (index = 0, length = keys.length; index < length; index += 1) { + tag = keys[index]; + style = String(map[tag]); + + if ('!!' === tag.slice(0, 2)) { + tag = 'tag:yaml.org,2002:' + tag.slice(2); + } + + type = schema.compiledTypeMap[tag]; + + if (type && type.dumper) { + if (_hasOwnProperty.call(type.dumper.styleAliases, style)) { + style = type.dumper.styleAliases[style]; + } + } + + result[tag] = style; + } + + return result; +} + + +function encodeHex(character) { + var string, handle, length; + + string = character.toString(16).toUpperCase(); + + if (character <= 0xFF) { + handle = 'x'; + length = 2; + } else if (character <= 0xFFFF) { + handle = 'u'; + length = 4; + } else if (character <= 0xFFFFFFFF) { + handle = 'U'; + length = 8; + } else { + throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF'); + } + + return '\\' + handle + common.repeat('0', length - string.length) + string; +} + + +function dump(input, options) { + options = options || {}; + + var schema = options['schema'] || DEFAULT_SCHEMA, + indent = Math.max(1, (options['indent'] || 2)), + flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']), + styleMap = compileStyleMap(schema, options['styles'] || null), + + implicitTypes = schema.compiledImplicit, + explicitTypes = schema.compiledExplicit, + + kind, + tag, + result; + + function generateNextLine(level) { + return '\n' + common.repeat(' ', indent * level); + } + + function testImplicitResolving(object) { + var index, length, type; + + for (index = 0, length = implicitTypes.length; index < length; index += 1) { + type = implicitTypes[index]; + + if (null !== type.loader && + NIL !== type.loader.resolver(object, false)) { + return true; + } + } + + return false; + } + + function writeScalar(object) { + var isQuoted, checkpoint, position, length, character; + + result = ''; + isQuoted = false; + checkpoint = 0; + + if (0 === object.length || + CHAR_SPACE === object.charCodeAt(0) || + CHAR_SPACE === object.charCodeAt(object.length - 1)) { + isQuoted = true; + } + + for (position = 0, length = object.length; position < length; position += 1) { + character = object.charCodeAt(position); + + if (!isQuoted) { + if (CHAR_TAB === character || + CHAR_LINE_FEED === character || + CHAR_CARRIAGE_RETURN === character || + CHAR_COMMA === character || + CHAR_LEFT_SQUARE_BRACKET === character || + CHAR_RIGHT_SQUARE_BRACKET === character || + CHAR_LEFT_CURLY_BRACKET === character || + CHAR_RIGHT_CURLY_BRACKET === character || + CHAR_SHARP === character || + CHAR_AMPERSAND === character || + CHAR_ASTERISK === character || + CHAR_EXCLAMATION === character || + CHAR_VERTICAL_LINE === character || + CHAR_GREATER_THAN === character || + CHAR_SINGLE_QUOTE === character || + CHAR_DOUBLE_QUOTE === character || + CHAR_PERCENT === character || + CHAR_COMMERCIAL_AT === character || + CHAR_GRAVE_ACCENT === character || + CHAR_QUESTION === character || + CHAR_COLON === character || + CHAR_MINUS === character) { + isQuoted = true; + } + } + + if (ESCAPE_SEQUENCES[character] || + !((0x00020 <= character && character <= 0x00007E) || + (0x00085 === character) || + (0x000A0 <= character && character <= 0x00D7FF) || + (0x0E000 <= character && character <= 0x00FFFD) || + (0x10000 <= character && character <= 0x10FFFF))) { + result += object.slice(checkpoint, position); + result += ESCAPE_SEQUENCES[character] || encodeHex(character); + checkpoint = position + 1; + isQuoted = true; + } + } + + if (checkpoint < position) { + result += object.slice(checkpoint, position); + } + + if (!isQuoted && testImplicitResolving(result)) { + isQuoted = true; + } + + if (isQuoted) { + result = '"' + result + '"'; + } + } + + function writeFlowSequence(level, object) { + var _result = '', + _tag = tag, + index, + length; + + for (index = 0, length = object.length; index < length; index += 1) { + if (0 !== index) { + _result += ', '; + } + + writeNode(level, object[index], false, false); + _result += result; + } + + tag = _tag; + result = '[' + _result + ']'; + } + + function writeBlockSequence(level, object, compact) { + var _result = '', + _tag = tag, + index, + length; + + for (index = 0, length = object.length; index < length; index += 1) { + if (!compact || 0 !== index) { + _result += generateNextLine(level); + } + + writeNode(level + 1, object[index], true, true); + _result += '- ' + result; + } + + tag = _tag; + result = _result; + } + + function writeFlowMapping(level, object) { + var _result = '', + _tag = tag, + objectKeyList = Object.keys(object), + index, + length, + objectKey, + objectValue; + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + if (0 !== index) { + _result += ', '; + } + + objectKey = objectKeyList[index]; + objectValue = object[objectKey]; + + writeNode(level, objectKey, false, false); + + if (result.length > 1024) { + _result += '? '; + } + + _result += result + ': '; + writeNode(level, objectValue, false, false); + _result += result; + } + + tag = _tag; + result = '{' + _result + '}'; + } + + function writeBlockMapping(level, object, compact) { + var _result = '', + _tag = tag, + objectKeyList = Object.keys(object), + index, + length, + objectKey, + objectValue, + explicitPair; + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + if (!compact || 0 !== index) { + _result += generateNextLine(level); + } + + objectKey = objectKeyList[index]; + objectValue = object[objectKey]; + + writeNode(level + 1, objectKey, true, true); + explicitPair = (null !== tag && '?' !== tag && result.length <= 1024); + + if (explicitPair) { + _result += '? '; + } + + _result += result; + + if (explicitPair) { + _result += generateNextLine(level); + } + + writeNode(level + 1, objectValue, true, explicitPair); + _result += ': ' + result; + } + + tag = _tag; + result = _result; + } + + function detectType(object, explicit) { + var _result, typeList, index, length, type, style; + + typeList = explicit ? explicitTypes : implicitTypes; + kind = kindOf(object); + + for (index = 0, length = typeList.length; index < length; index += 1) { + type = typeList[index]; + + if ((null !== type.dumper) && + (null === type.dumper.kind || kind === type.dumper.kind) && + (null === type.dumper.instanceOf || object instanceof type.dumper.instanceOf) && + (null === type.dumper.predicate || type.dumper.predicate(object))) { + tag = explicit ? type.tag : '?'; + + if (null !== type.dumper.representer) { + style = styleMap[type.tag] || type.dumper.defaultStyle; + + if ('function' === typeof type.dumper.representer) { + _result = type.dumper.representer(object, style); + } else if (_hasOwnProperty.call(type.dumper.representer, style)) { + _result = type.dumper.representer[style](object, style); + } else { + throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style'); + } + + if (NIL !== _result) { + kind = kindOf(_result); + result = _result; + } else { + if (explicit) { + throw new YAMLException('cannot represent an object of !<' + type.tag + '> type'); + } else { + continue; + } + } + } + + return true; + } + } + + return false; + } + + function writeNode(level, object, block, compact) { + tag = null; + result = object; + + if (!detectType(object, false)) { + detectType(object, true); + } + + if (block) { + block = (0 > flowLevel || flowLevel > level); + } + + if ((null !== tag && '?' !== tag) || (2 !== indent && level > 0)) { + compact = false; + } + + if ('object' === kind) { + if (block && (0 !== Object.keys(result).length)) { + writeBlockMapping(level, result, compact); + } else { + writeFlowMapping(level, result); + } + } else if ('array' === kind) { + if (block && (0 !== result.length)) { + writeBlockSequence(level, result, compact); + } else { + writeFlowSequence(level, result); + } + } else if ('string' === kind) { + if ('?' !== tag) { + writeScalar(result); + } + } else { + throw new YAMLException('unacceptabe kind of an object to dump (' + kind + ')'); + } + + if (null !== tag && '?' !== tag) { + result = '!<' + tag + '> ' + result; + } + } + + writeNode(0, input, true, true); + return result + '\n'; +} + + +function safeDump(input, options) { + return dump(input, common.extend({ schema: SAFE_SCHEMA }, options)); +} + + +module.exports.dump = dump; +module.exports.safeDump = safeDump; diff --git a/node_modules/js-yaml/lib/js-yaml/exception.js b/node_modules/js-yaml/lib/js-yaml/exception.js new file mode 100644 index 0000000..479ba88 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/exception.js @@ -0,0 +1,25 @@ +'use strict'; + + +function YAMLException(reason, mark) { + this.name = 'YAMLException'; + this.reason = reason; + this.mark = mark; + this.message = this.toString(false); +} + + +YAMLException.prototype.toString = function toString(compact) { + var result; + + result = 'JS-YAML: ' + (this.reason || '(unknown reason)'); + + if (!compact && this.mark) { + result += ' ' + this.mark.toString(); + } + + return result; +}; + + +module.exports = YAMLException; diff --git a/node_modules/js-yaml/lib/js-yaml/loader.js b/node_modules/js-yaml/lib/js-yaml/loader.js new file mode 100644 index 0000000..bdc71d1 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/loader.js @@ -0,0 +1,1549 @@ +'use strict'; + + +var common = require('./common'); +var YAMLException = require('./exception'); +var Mark = require('./mark'); +var NIL = common.NIL; +var SAFE_SCHEMA = require('./schema/safe'); +var DEFAULT_SCHEMA = require('./schema/default'); + + +var _hasOwnProperty = Object.prototype.hasOwnProperty; + + +var KIND_STRING = 'string'; +var KIND_ARRAY = 'array'; +var KIND_OBJECT = 'object'; + + +var CONTEXT_FLOW_IN = 1; +var CONTEXT_FLOW_OUT = 2; +var CONTEXT_BLOCK_IN = 3; +var CONTEXT_BLOCK_OUT = 4; + + +var CHOMPING_CLIP = 1; +var CHOMPING_STRIP = 2; +var CHOMPING_KEEP = 3; + + +var CHAR_TAB = 0x09; /* Tab */ +var CHAR_LINE_FEED = 0x0A; /* LF */ +var CHAR_CARRIAGE_RETURN = 0x0D; /* CR */ +var CHAR_SPACE = 0x20; /* Space */ +var CHAR_EXCLAMATION = 0x21; /* ! */ +var CHAR_DOUBLE_QUOTE = 0x22; /* " */ +var CHAR_SHARP = 0x23; /* # */ +var CHAR_PERCENT = 0x25; /* % */ +var CHAR_AMPERSAND = 0x26; /* & */ +var CHAR_SINGLE_QUOTE = 0x27; /* ' */ +var CHAR_ASTERISK = 0x2A; /* * */ +var CHAR_PLUS = 0x2B; /* + */ +var CHAR_COMMA = 0x2C; /* , */ +var CHAR_MINUS = 0x2D; /* - */ +var CHAR_DOT = 0x2E; /* . */ +var CHAR_SLASH = 0x2F; /* / */ +var CHAR_DIGIT_ZERO = 0x30; /* 0 */ +var CHAR_DIGIT_ONE = 0x31; /* 1 */ +var CHAR_DIGIT_NINE = 0x39; /* 9 */ +var CHAR_COLON = 0x3A; /* : */ +var CHAR_LESS_THAN = 0x3C; /* < */ +var CHAR_GREATER_THAN = 0x3E; /* > */ +var CHAR_QUESTION = 0x3F; /* ? */ +var CHAR_COMMERCIAL_AT = 0x40; /* @ */ +var CHAR_CAPITAL_A = 0x41; /* A */ +var CHAR_CAPITAL_F = 0x46; /* F */ +var CHAR_CAPITAL_L = 0x4C; /* L */ +var CHAR_CAPITAL_N = 0x4E; /* N */ +var CHAR_CAPITAL_P = 0x50; /* P */ +var CHAR_CAPITAL_U = 0x55; /* U */ +var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ +var CHAR_BACKSLASH = 0x5C; /* \ */ +var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ +var CHAR_UNDERSCORE = 0x5F; /* _ */ +var CHAR_GRAVE_ACCENT = 0x60; /* ` */ +var CHAR_SMALL_A = 0x61; /* a */ +var CHAR_SMALL_B = 0x62; /* b */ +var CHAR_SMALL_E = 0x65; /* e */ +var CHAR_SMALL_F = 0x66; /* f */ +var CHAR_SMALL_N = 0x6E; /* n */ +var CHAR_SMALL_R = 0x72; /* r */ +var CHAR_SMALL_T = 0x74; /* t */ +var CHAR_SMALL_U = 0x75; /* u */ +var CHAR_SMALL_V = 0x76; /* v */ +var CHAR_SMALL_X = 0x78; /* x */ +var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ +var CHAR_VERTICAL_LINE = 0x7C; /* | */ +var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ + + +var SIMPLE_ESCAPE_SEQUENCES = {}; + +SIMPLE_ESCAPE_SEQUENCES[CHAR_DIGIT_ZERO] = '\x00'; +SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_A] = '\x07'; +SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_B] = '\x08'; +SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_T] = '\x09'; +SIMPLE_ESCAPE_SEQUENCES[CHAR_TAB] = '\x09'; +SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_N] = '\x0A'; +SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_V] = '\x0B'; +SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_F] = '\x0C'; +SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_R] = '\x0D'; +SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_E] = '\x1B'; +SIMPLE_ESCAPE_SEQUENCES[CHAR_SPACE] = ' '; +SIMPLE_ESCAPE_SEQUENCES[CHAR_DOUBLE_QUOTE] = '\x22'; +SIMPLE_ESCAPE_SEQUENCES[CHAR_SLASH] = '/'; +SIMPLE_ESCAPE_SEQUENCES[CHAR_BACKSLASH] = '\x5C'; +SIMPLE_ESCAPE_SEQUENCES[CHAR_CAPITAL_N] = '\x85'; +SIMPLE_ESCAPE_SEQUENCES[CHAR_UNDERSCORE] = '\xA0'; +SIMPLE_ESCAPE_SEQUENCES[CHAR_CAPITAL_L] = '\u2028'; +SIMPLE_ESCAPE_SEQUENCES[CHAR_CAPITAL_P] = '\u2029'; + + +var HEXADECIMAL_ESCAPE_SEQUENCES = {}; + +HEXADECIMAL_ESCAPE_SEQUENCES[CHAR_SMALL_X] = 2; +HEXADECIMAL_ESCAPE_SEQUENCES[CHAR_SMALL_U] = 4; +HEXADECIMAL_ESCAPE_SEQUENCES[CHAR_CAPITAL_U] = 8; + + +var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uD800-\uDFFF\uFFFE\uFFFF]/; +var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/; +var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/; +var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i; +var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; + + +function loadAll(input, output, options) { + options = options || {}; + + var filename = options['filename'] || null, + schema = options['schema'] || DEFAULT_SCHEMA, + resolve = options['resolve'] || true, + validate = options['validate'] || true, + strict = options['strict'] || false, + legacy = options['legacy'] || false, + + directiveHandlers = {}, + implicitTypes = schema.compiledImplicit, + typeMap = schema.compiledTypeMap, + + length = input.length, + position = 0, + line = 0, + lineStart = 0, + lineIndent = 0, + character = input.charCodeAt(position), + + version, + checkLineBreaks, + tagMap, + anchorMap, + tag, + anchor, + kind, + result; + + function generateError(message) { + return new YAMLException( + message, + new Mark(filename, input, position, line, (position - lineStart))); + } + + function throwError(message) { + throw generateError(message); + } + + function throwWarning(message) { + var error = generateError(message); + + if (strict) { + throw error; + } else { + console.warn(error.toString()); + } + } + + directiveHandlers['YAML'] = function handleYamlDirective(name, args) { + var match, major, minor; + + if (null !== version) { + throwError('duplication of %YAML directive'); + } + + if (1 !== args.length) { + throwError('YAML directive accepts exactly one argument'); + } + + match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]); + + if (null === match) { + throwError('ill-formed argument of the YAML directive'); + } + + major = parseInt(match[1], 10); + minor = parseInt(match[2], 10); + + if (1 !== major) { + throwError('unacceptable YAML version of the document'); + } + + version = args[0]; + checkLineBreaks = (minor < 2); + + if (1 !== minor && 2 !== minor) { + throwWarning('unsupported YAML version of the document'); + } + }; + + directiveHandlers['TAG'] = function handleTagDirective(name, args) { + var handle, prefix; + + if (2 !== args.length) { + throwError('TAG directive accepts exactly two arguments'); + } + + handle = args[0]; + prefix = args[1]; + + if (!PATTERN_TAG_HANDLE.test(handle)) { + throwError('ill-formed tag handle (first argument) of the TAG directive'); + } + + if (_hasOwnProperty.call(tagMap, handle)) { + throwError('there is a previously declared suffix for "' + handle + '" tag handle'); + } + + if (!PATTERN_TAG_URI.test(prefix)) { + throwError('ill-formed tag prefix (second argument) of the TAG directive'); + } + + tagMap[handle] = prefix; + }; + + function captureSegment(start, end, checkJson) { + var _position, _length, _character, _result; + + if (start < end) { + _result = input.slice(start, end); + + if (checkJson && validate) { + for (_position = 0, _length = _result.length; + _position < _length; + _position += 1) { + _character = _result.charCodeAt(_position); + if (!(0x09 === _character || + 0x20 <= _character && _character <= 0x10FFFF)) { + throwError('expected valid JSON character'); + } + } + } + + result += _result; + } + } + + function mergeMappings(destination, source) { + var sourceKeys, key, index, quantity; + + if (!common.isObject(source)) { + throwError('cannot merge mappings; the provided source object is unacceptable'); + } + + sourceKeys = Object.keys(source); + + for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) { + key = sourceKeys[index]; + + if (!_hasOwnProperty.call(destination, key)) { + destination[key] = source[key]; + } + } + } + + function storeMappingPair(_result, keyTag, keyNode, valueNode) { + var index, quantity; + + keyNode = String(keyNode); + + if (null === _result) { + _result = {}; + } + + if ('tag:yaml.org,2002:merge' === keyTag) { + if (Array.isArray(valueNode)) { + for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { + mergeMappings(_result, valueNode[index]); + } + } else { + mergeMappings(_result, valueNode); + } + } else { + _result[keyNode] = valueNode; + } + + return _result; + } + + function readLineBreak() { + if (CHAR_LINE_FEED === character) { + position += 1; + } else if (CHAR_CARRIAGE_RETURN === character) { + if (CHAR_LINE_FEED === input.charCodeAt(position + 1)) { + position += 2; + } else { + position += 1; + } + } else { + throwError('a line break is expected'); + } + + line += 1; + lineStart = position; + character = input.charCodeAt(position); + } + + function skipSeparationSpace(allowComments, checkIndent) { + var lineBreaks = 0; + + while (position < length) { + while (CHAR_SPACE === character || CHAR_TAB === character) { + character = input.charCodeAt(++position); + } + + if (allowComments && CHAR_SHARP === character) { + do { character = input.charCodeAt(++position); } + while (position < length && + CHAR_LINE_FEED !== character && + CHAR_CARRIAGE_RETURN !== character); + } + + if (CHAR_LINE_FEED === character || CHAR_CARRIAGE_RETURN === character) { + readLineBreak(); + lineBreaks += 1; + lineIndent = 0; + + while (CHAR_SPACE === character) { + lineIndent += 1; + character = input.charCodeAt(++position); + } + + if (lineIndent < checkIndent) { + throwWarning('deficient indentation'); + } + } else { + break; + } + } + + return lineBreaks; + } + + function testDocumentSeparator() { + var _position, _character; + + if (position === lineStart && + (CHAR_MINUS === character || CHAR_DOT === character) && + input.charCodeAt(position + 1) === character && + input.charCodeAt(position + 2) === character) { + + _position = position + 3; + _character = input.charCodeAt(_position); + + if (_position >= length || + CHAR_SPACE === _character || + CHAR_TAB === _character || + CHAR_LINE_FEED === _character || + CHAR_CARRIAGE_RETURN === _character) { + return true; + } + } + + return false; + } + + function writeFoldedLines(count) { + if (1 === count) { + result += ' '; + } else if (count > 1) { + result += common.repeat('\n', count - 1); + } + } + + function readPlainScalar(nodeIndent, withinFlowCollection) { + var preceding, + following, + captureStart, + captureEnd, + hasPendingContent, + _line, + _lineStart, + _lineIndent, + _kind = kind, + _result = result; + + if (CHAR_SPACE === character || + CHAR_TAB === character || + CHAR_LINE_FEED === character || + CHAR_CARRIAGE_RETURN === character || + CHAR_COMMA === character || + CHAR_LEFT_SQUARE_BRACKET === character || + CHAR_RIGHT_SQUARE_BRACKET === character || + CHAR_LEFT_CURLY_BRACKET === character || + CHAR_RIGHT_CURLY_BRACKET === character || + CHAR_SHARP === character || + CHAR_AMPERSAND === character || + CHAR_ASTERISK === character || + CHAR_EXCLAMATION === character || + CHAR_VERTICAL_LINE === character || + CHAR_GREATER_THAN === character || + CHAR_SINGLE_QUOTE === character || + CHAR_DOUBLE_QUOTE === character || + CHAR_PERCENT === character || + CHAR_COMMERCIAL_AT === character || + CHAR_GRAVE_ACCENT === character) { + return false; + } + + if (CHAR_QUESTION === character || + CHAR_MINUS === character) { + following = input.charCodeAt(position + 1); + + if (CHAR_SPACE === following || + CHAR_TAB === following || + CHAR_LINE_FEED === following || + CHAR_CARRIAGE_RETURN === following || + withinFlowCollection && + (CHAR_COMMA === following || + CHAR_LEFT_SQUARE_BRACKET === following || + CHAR_RIGHT_SQUARE_BRACKET === following || + CHAR_LEFT_CURLY_BRACKET === following || + CHAR_RIGHT_CURLY_BRACKET === following)) { + return false; + } + } + + kind = KIND_STRING; + result = ''; + captureStart = captureEnd = position; + hasPendingContent = false; + + while (position < length) { + if (CHAR_COLON === character) { + following = input.charCodeAt(position + 1); + + if (CHAR_SPACE === following || + CHAR_TAB === following || + CHAR_LINE_FEED === following || + CHAR_CARRIAGE_RETURN === following || + withinFlowCollection && + (CHAR_COMMA === following || + CHAR_LEFT_SQUARE_BRACKET === following || + CHAR_RIGHT_SQUARE_BRACKET === following || + CHAR_LEFT_CURLY_BRACKET === following || + CHAR_RIGHT_CURLY_BRACKET === following)) { + break; + } + + } else if (CHAR_SHARP === character) { + preceding = input.charCodeAt(position - 1); + + if (CHAR_SPACE === preceding || + CHAR_TAB === preceding || + CHAR_LINE_FEED === preceding || + CHAR_CARRIAGE_RETURN === preceding) { + break; + } + + } else if ((position === lineStart && testDocumentSeparator()) || + withinFlowCollection && + (CHAR_COMMA === character || + CHAR_LEFT_SQUARE_BRACKET === character || + CHAR_RIGHT_SQUARE_BRACKET === character || + CHAR_LEFT_CURLY_BRACKET === character || + CHAR_RIGHT_CURLY_BRACKET === character)) { + break; + + } else if (CHAR_LINE_FEED === character || + CHAR_CARRIAGE_RETURN === character) { + _line = line; + _lineStart = lineStart; + _lineIndent = lineIndent; + skipSeparationSpace(false, -1); + + if (lineIndent >= nodeIndent) { + hasPendingContent = true; + continue; + } else { + position = captureEnd; + line = _line; + lineStart = _lineStart; + lineIndent = _lineIndent; + character = input.charCodeAt(position); + break; + } + } + + if (hasPendingContent) { + captureSegment(captureStart, captureEnd, false); + writeFoldedLines(line - _line); + captureStart = captureEnd = position; + hasPendingContent = false; + } + + if (CHAR_SPACE !== character && CHAR_TAB !== character) { + captureEnd = position + 1; + } + + character = input.charCodeAt(++position); + } + + captureSegment(captureStart, captureEnd, false); + + if (result) { + return true; + } else { + kind = _kind; + result = _result; + return false; + } + } + + function readSingleQuotedScalar(nodeIndent) { + var captureStart, captureEnd; + + if (CHAR_SINGLE_QUOTE !== character) { + return false; + } + + kind = KIND_STRING; + result = ''; + character = input.charCodeAt(++position); + captureStart = captureEnd = position; + + while (position < length) { + if (CHAR_SINGLE_QUOTE === character) { + captureSegment(captureStart, position, true); + character = input.charCodeAt(++position); + + if (CHAR_SINGLE_QUOTE === character) { + captureStart = captureEnd = position; + character = input.charCodeAt(++position); + } else { + return true; + } + + } else if (CHAR_LINE_FEED === character || + CHAR_CARRIAGE_RETURN === character) { + captureSegment(captureStart, captureEnd, true); + writeFoldedLines(skipSeparationSpace(false, nodeIndent)); + captureStart = captureEnd = position; + character = input.charCodeAt(position); + + } else if (position === lineStart && testDocumentSeparator()) { + throwError('unexpected end of the document within a single quoted scalar'); + + } else { + character = input.charCodeAt(++position); + captureEnd = position; + } + } + + throwError('unexpected end of the stream within a single quoted scalar'); + } + + function readDoubleQuotedScalar(nodeIndent) { + var captureStart, + captureEnd, + hexLength, + hexIndex, + hexOffset, + hexResult; + + if (CHAR_DOUBLE_QUOTE !== character) { + return false; + } + + kind = KIND_STRING; + result = ''; + character = input.charCodeAt(++position); + captureStart = captureEnd = position; + + while (position < length) { + if (CHAR_DOUBLE_QUOTE === character) { + captureSegment(captureStart, position, true); + character = input.charCodeAt(++position); + return true; + + } else if (CHAR_BACKSLASH === character) { + captureSegment(captureStart, position, true); + character = input.charCodeAt(++position); + + if (CHAR_LINE_FEED === character || + CHAR_CARRIAGE_RETURN === character) { + skipSeparationSpace(false, nodeIndent); + + } else if (SIMPLE_ESCAPE_SEQUENCES[character]) { + result += SIMPLE_ESCAPE_SEQUENCES[character]; + character = input.charCodeAt(++position); + + } else if (HEXADECIMAL_ESCAPE_SEQUENCES[character]) { + hexLength = HEXADECIMAL_ESCAPE_SEQUENCES[character]; + hexResult = 0; + + for (hexIndex = 1; hexIndex <= hexLength; hexIndex += 1) { + hexOffset = (hexLength - hexIndex) * 4; + character = input.charCodeAt(++position); + + if (CHAR_DIGIT_ZERO <= character && character <= CHAR_DIGIT_NINE) { + hexResult |= (character - CHAR_DIGIT_ZERO) << hexOffset; + + } else if (CHAR_CAPITAL_A <= character && character <= CHAR_CAPITAL_F) { + hexResult |= (character - CHAR_CAPITAL_A + 10) << hexOffset; + + } else if (CHAR_SMALL_A <= character && character <= CHAR_SMALL_F) { + hexResult |= (character - CHAR_SMALL_A + 10) << hexOffset; + + } else { + throwError('expected hexadecimal character'); + } + } + + result += String.fromCharCode(hexResult); + character = input.charCodeAt(++position); + + } else { + throwError('unknown escape sequence'); + } + + captureStart = captureEnd = position; + + } else if (CHAR_LINE_FEED === character || + CHAR_CARRIAGE_RETURN === character) { + captureSegment(captureStart, captureEnd, true); + writeFoldedLines(skipSeparationSpace(false, nodeIndent)); + captureStart = captureEnd = position; + character = input.charCodeAt(position); + + } else if (position === lineStart && testDocumentSeparator()) { + throwError('unexpected end of the document within a double quoted scalar'); + + } else { + character = input.charCodeAt(++position); + captureEnd = position; + } + } + + throwError('unexpected end of the stream within a double quoted scalar'); + } + + function readFlowCollection(nodeIndent) { + var readNext = true, + _line, + _tag = tag, + _result, + following, + terminator, + isPair, + isExplicitPair, + isMapping, + keyNode, + keyTag, + valueNode; + + switch (character) { + case CHAR_LEFT_SQUARE_BRACKET: + terminator = CHAR_RIGHT_SQUARE_BRACKET; + isMapping = false; + _result = []; + break; + + case CHAR_LEFT_CURLY_BRACKET: + terminator = CHAR_RIGHT_CURLY_BRACKET; + isMapping = true; + _result = {}; + break; + + default: + return false; + } + + if (null !== anchor) { + anchorMap[anchor] = _result; + } + + character = input.charCodeAt(++position); + + while (position < length) { + skipSeparationSpace(true, nodeIndent); + + if (character === terminator) { + character = input.charCodeAt(++position); + tag = _tag; + kind = isMapping ? KIND_OBJECT : KIND_ARRAY; + result = _result; + return true; + } else if (!readNext) { + throwError('missed comma between flow collection entries'); + } + + keyTag = keyNode = valueNode = null; + isPair = isExplicitPair = false; + + if (CHAR_QUESTION === character) { + following = input.charCodeAt(position + 1); + + if (CHAR_SPACE === following || + CHAR_TAB === following || + CHAR_LINE_FEED === following || + CHAR_CARRIAGE_RETURN === following) { + isPair = isExplicitPair = true; + position += 1; + character = following; + skipSeparationSpace(true, nodeIndent); + } + } + + _line = line; + composeNode(nodeIndent, CONTEXT_FLOW_IN, false, true); + keyTag = tag; + keyNode = result; + + if ((isExplicitPair || line === _line) && CHAR_COLON === character) { + isPair = true; + character = input.charCodeAt(++position); + skipSeparationSpace(true, nodeIndent); + composeNode(nodeIndent, CONTEXT_FLOW_IN, false, true); + valueNode = result; + } + + if (isMapping) { + storeMappingPair(_result, keyTag, keyNode, valueNode); + } else if (isPair) { + _result.push(storeMappingPair(null, keyTag, keyNode, valueNode)); + } else { + _result.push(keyNode); + } + + skipSeparationSpace(true, nodeIndent); + + if (CHAR_COMMA === character) { + readNext = true; + character = input.charCodeAt(++position); + } else { + readNext = false; + } + } + + throwError('unexpected end of the stream within a flow collection'); + } + + function readBlockScalar(nodeIndent) { + var captureStart, + folding, + chomping = CHOMPING_CLIP, + detectedIndent = false, + textIndent = nodeIndent, + emptyLines = -1; + + switch (character) { + case CHAR_VERTICAL_LINE: + folding = false; + break; + + case CHAR_GREATER_THAN: + folding = true; + break; + + default: + return false; + } + + kind = KIND_STRING; + result = ''; + + while (position < length) { + character = input.charCodeAt(++position); + + if (CHAR_PLUS === character || CHAR_MINUS === character) { + if (CHOMPING_CLIP === chomping) { + chomping = (CHAR_PLUS === character) ? CHOMPING_KEEP : CHOMPING_STRIP; + } else { + throwError('repeat of a chomping mode identifier'); + } + + } else if (CHAR_DIGIT_ZERO <= character && character <= CHAR_DIGIT_NINE) { + if (CHAR_DIGIT_ZERO === character) { + throwError('bad explicit indentation width of a block scalar; it cannot be less than one'); + } else if (!detectedIndent) { + textIndent = nodeIndent + (character - CHAR_DIGIT_ONE); + detectedIndent = true; + } else { + throwError('repeat of an indentation width identifier'); + } + + } else { + break; + } + } + + if (CHAR_SPACE === character || CHAR_TAB === character) { + do { character = input.charCodeAt(++position); } + while (CHAR_SPACE === character || CHAR_TAB === character); + + if (CHAR_SHARP === character) { + do { character = input.charCodeAt(++position); } + while (position < length && + CHAR_LINE_FEED !== character && + CHAR_CARRIAGE_RETURN !== character); + } + } + + while (position < length) { + readLineBreak(); + lineIndent = 0; + + while ((!detectedIndent || lineIndent < textIndent) && + (CHAR_SPACE === character)) { + lineIndent += 1; + character = input.charCodeAt(++position); + } + + if (!detectedIndent && lineIndent > textIndent) { + textIndent = lineIndent; + } + + if (CHAR_LINE_FEED === character || CHAR_CARRIAGE_RETURN === character) { + emptyLines += 1; + continue; + } + + // End of the scalar. Perform the chomping. + if (lineIndent < textIndent) { + if (CHOMPING_KEEP === chomping) { + result += common.repeat('\n', emptyLines + 1); + } else if (CHOMPING_CLIP === chomping) { + result += '\n'; + } + break; + } + + detectedIndent = true; + + if (folding) { + if (CHAR_SPACE === character || CHAR_TAB === character) { + result += common.repeat('\n', emptyLines + 1); + emptyLines = 1; + } else if (0 === emptyLines) { + result += ' '; + emptyLines = 0; + } else { + result += common.repeat('\n', emptyLines); + emptyLines = 0; + } + } else { + result += common.repeat('\n', emptyLines + 1); + emptyLines = 0; + } + + captureStart = position; + + do { character = input.charCodeAt(++position); } + while (position < length && + CHAR_LINE_FEED !== character && + CHAR_CARRIAGE_RETURN !== character); + + captureSegment(captureStart, position, false); + } + + return true; + } + + function readBlockSequence(nodeIndent) { + var _line, + _tag = tag, + _result = [], + following, + detected = false; + + if (null !== anchor) { + anchorMap[anchor] = _result; + } + + while (position < length) { + if (CHAR_MINUS !== character) { + break; + } + + following = input.charCodeAt(position + 1); + + if (CHAR_SPACE !== following && + CHAR_TAB !== following && + CHAR_LINE_FEED !== following && + CHAR_CARRIAGE_RETURN !== following) { + break; + } + + detected = true; + position += 1; + character = following; + + if (skipSeparationSpace(true, -1)) { + if (lineIndent <= nodeIndent) { + _result.push(null); + continue; + } + } + + _line = line; + composeNode(nodeIndent, CONTEXT_BLOCK_IN, false, true); + _result.push(result); + skipSeparationSpace(true, -1); + + if ((line === _line || lineIndent > nodeIndent) && position < length) { + throwError('bad indentation of a sequence entry'); + } else if (lineIndent < nodeIndent) { + break; + } + } + + if (detected) { + tag = _tag; + kind = KIND_ARRAY; + result = _result; + return true; + } else { + return false; + } + } + + function readBlockMapping(nodeIndent) { + var following, + allowCompact, + _line, + _tag = tag, + _result = {}, + keyTag = null, + keyNode = null, + valueNode = null, + atExplicitKey = false, + detected = false; + + if (null !== anchor) { + anchorMap[anchor] = _result; + } + + while (position < length) { + following = input.charCodeAt(position + 1); + _line = line; // Save the current line. + + if ((CHAR_QUESTION === character || + CHAR_COLON === character) && + (CHAR_SPACE === following || + CHAR_TAB === following || + CHAR_LINE_FEED === following || + CHAR_CARRIAGE_RETURN === following)) { + + if (CHAR_QUESTION === character) { + if (atExplicitKey) { + storeMappingPair(_result, keyTag, keyNode, null); + keyTag = keyNode = valueNode = null; + } + + detected = true; + atExplicitKey = true; + allowCompact = true; + + } else if (atExplicitKey) { + // i.e. CHAR_COLON === character after the explicit key. + atExplicitKey = false; + allowCompact = true; + + } else { + throwError('incomplete explicit mapping pair; a key node is missed'); + } + + position += 1; + character = following; + + } else if (composeNode(nodeIndent, CONTEXT_FLOW_OUT, false, true)) { + if (line === _line) { + // TODO: Remove this cycle when the flow readers will consume + // trailing whitespaces like the block readers. + while (CHAR_SPACE === character || + CHAR_TAB === character) { + character = input.charCodeAt(++position); + } + + if (CHAR_COLON === character) { + character = input.charCodeAt(++position); + + if (CHAR_SPACE !== character && + CHAR_TAB !== character && + CHAR_LINE_FEED !== character && + CHAR_CARRIAGE_RETURN !== character) { + throwError('a whitespace character is expected after the key-value separator within a block mapping'); + } + + if (atExplicitKey) { + storeMappingPair(_result, keyTag, keyNode, null); + keyTag = keyNode = valueNode = null; + } + + detected = true; + atExplicitKey = false; + allowCompact = false; + keyTag = tag; + keyNode = result; + + } else if (detected) { + throwError('can not read an implicit mapping pair; a colon is missed'); + + } else { + tag = _tag; + return true; // Keep the result of `composeNode`. + } + + } else if (detected) { + throwError('can not read a block mapping entry; a multiline key may not be an implicit key'); + + } else { + tag = _tag; + return true; // Keep the result of `composeNode`. + } + + } else { + break; + } + + if (line === _line || lineIndent > nodeIndent) { + if (composeNode(nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) { + if (atExplicitKey) { + keyNode = result; + } else { + valueNode = result; + } + } + + if (!atExplicitKey) { + storeMappingPair(_result, keyTag, keyNode, valueNode); + keyTag = keyNode = valueNode = null; + } + + // TODO: It is needed only for flow node readers. It should be removed + // when the flow readers will consume trailing whitespaces as well as + // the block readers. + skipSeparationSpace(true, -1); + } + + if (lineIndent > nodeIndent && position < length) { + throwError('bad indentation of a mapping entry'); + } else if (lineIndent < nodeIndent) { + break; + } + } + + if (atExplicitKey) { + storeMappingPair(_result, keyTag, keyNode, null); + } + + if (detected) { + tag = _tag; + kind = KIND_OBJECT; + result = _result; + } + + return detected; + } + + function readTagProperty() { + var _position, + isVerbatim = false, + isNamed = false, + tagHandle, + tagName; + + if (CHAR_EXCLAMATION !== character) { + return false; + } + + if (null !== tag) { + throwError('duplication of a tag property'); + } + + character = input.charCodeAt(++position); + + if (CHAR_LESS_THAN === character) { + isVerbatim = true; + character = input.charCodeAt(++position); + + } else if (CHAR_EXCLAMATION === character) { + isNamed = true; + tagHandle = '!!'; + character = input.charCodeAt(++position); + + } else { + tagHandle = '!'; + } + + _position = position; + + if (isVerbatim) { + do { character = input.charCodeAt(++position); } + while (position < length && CHAR_GREATER_THAN !== character); + + if (position < length) { + tagName = input.slice(_position, position); + character = input.charCodeAt(++position); + } else { + throwError('unexpected end of the stream within a verbatim tag'); + } + } else { + while (position < length && + CHAR_SPACE !== character && + CHAR_TAB !== character && + CHAR_LINE_FEED !== character && + CHAR_CARRIAGE_RETURN !== character) { + + if (CHAR_EXCLAMATION === character) { + if (!isNamed) { + tagHandle = input.slice(_position - 1, position + 1); + + if (validate && !PATTERN_TAG_HANDLE.test(tagHandle)) { + throwError('named tag handle cannot contain such characters'); + } + + isNamed = true; + _position = position + 1; + } else { + throwError('tag suffix cannot contain exclamation marks'); + } + } + + character = input.charCodeAt(++position); + } + + tagName = input.slice(_position, position); + + if (validate && PATTERN_FLOW_INDICATORS.test(tagName)) { + throwError('tag suffix cannot contain flow indicator characters'); + } + } + + if (validate && tagName && !PATTERN_TAG_URI.test(tagName)) { + throwError('tag name cannot contain such characters: ' + tagName); + } + + if (isVerbatim) { + tag = tagName; + + } else if (_hasOwnProperty.call(tagMap, tagHandle)) { + tag = tagMap[tagHandle] + tagName; + + } else if ('!' === tagHandle) { + tag = '!' + tagName; + + } else if ('!!' === tagHandle) { + tag = 'tag:yaml.org,2002:' + tagName; + + } else { + throwError('undeclared tag handle "' + tagHandle + '"'); + } + + return true; + } + + function readAnchorProperty() { + var _position; + + if (CHAR_AMPERSAND !== character) { + return false; + } + + if (null !== anchor) { + throwError('duplication of an anchor property'); + } + + character = input.charCodeAt(++position); + _position = position; + + while (position < length && + CHAR_SPACE !== character && + CHAR_TAB !== character && + CHAR_LINE_FEED !== character && + CHAR_CARRIAGE_RETURN !== character && + CHAR_COMMA !== character && + CHAR_LEFT_SQUARE_BRACKET !== character && + CHAR_RIGHT_SQUARE_BRACKET !== character && + CHAR_LEFT_CURLY_BRACKET !== character && + CHAR_RIGHT_CURLY_BRACKET !== character) { + character = input.charCodeAt(++position); + } + + if (position === _position) { + throwError('name of an anchor node must contain at least one character'); + } + + anchor = input.slice(_position, position); + return true; + } + + function readAlias() { + var _position, alias; + + if (CHAR_ASTERISK !== character) { + return false; + } + + character = input.charCodeAt(++position); + _position = position; + + while (position < length && + CHAR_SPACE !== character && + CHAR_TAB !== character && + CHAR_LINE_FEED !== character && + CHAR_CARRIAGE_RETURN !== character && + CHAR_COMMA !== character && + CHAR_LEFT_SQUARE_BRACKET !== character && + CHAR_RIGHT_SQUARE_BRACKET !== character && + CHAR_LEFT_CURLY_BRACKET !== character && + CHAR_RIGHT_CURLY_BRACKET !== character) { + character = input.charCodeAt(++position); + } + + if (position === _position) { + throwError('name of an alias node must contain at least one character'); + } + + alias = input.slice(_position, position); + + if (!anchorMap.hasOwnProperty(alias)) { + throwError('unidentified alias "' + alias + '"'); + } + + result = anchorMap[alias]; + skipSeparationSpace(true, -1); + return true; + } + + function composeNode(parentIndent, nodeContext, allowToSeek, allowCompact) { + var allowBlockStyles, + allowBlockScalars, + allowBlockCollections, + atNewLine = false, + isIndented = true, + hasContent = false, + typeIndex, + typeQuantity, + type, + typeLoader, + flowIndent, + blockIndent, + _result; + + tag = null; + anchor = null; + kind = null; + result = null; + + allowBlockStyles = allowBlockScalars = allowBlockCollections = + CONTEXT_BLOCK_OUT === nodeContext || + CONTEXT_BLOCK_IN === nodeContext; + + if (allowToSeek) { + if (skipSeparationSpace(true, -1)) { + atNewLine = true; + + if (lineIndent === parentIndent) { + isIndented = false; + + } else if (lineIndent > parentIndent) { + isIndented = true; + + } else { + return false; + } + } + } + + if (isIndented) { + while (readTagProperty() || readAnchorProperty()) { + if (skipSeparationSpace(true, -1)) { + atNewLine = true; + + if (lineIndent > parentIndent) { + isIndented = true; + allowBlockCollections = allowBlockStyles; + + } else if (lineIndent === parentIndent) { + isIndented = false; + allowBlockCollections = allowBlockStyles; + + } else { + return true; + } + } else { + allowBlockCollections = false; + } + } + } + + if (allowBlockCollections) { + allowBlockCollections = atNewLine || allowCompact; + } + + if (isIndented || CONTEXT_BLOCK_OUT === nodeContext) { + if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) { + flowIndent = parentIndent; + } else { + flowIndent = parentIndent + 1; + } + + blockIndent = position - lineStart; + + if (isIndented) { + if (allowBlockCollections && + (readBlockSequence(blockIndent) || + readBlockMapping(blockIndent)) || + readFlowCollection(flowIndent)) { + hasContent = true; + } else { + if ((allowBlockScalars && readBlockScalar(flowIndent)) || + readSingleQuotedScalar(flowIndent) || + readDoubleQuotedScalar(flowIndent)) { + hasContent = true; + + } else if (readAlias()) { + hasContent = true; + + if (null !== tag || null !== anchor) { + throwError('alias node should not have any properties'); + } + + } else if (readPlainScalar(flowIndent, CONTEXT_FLOW_IN === nodeContext)) { + hasContent = true; + + if (null === tag) { + tag = '?'; + } + } + + if (null !== anchor) { + anchorMap[anchor] = result; + } + } + } else { + hasContent = allowBlockCollections && readBlockSequence(blockIndent); + } + } + + if (null !== tag && '!' !== tag) { + if ('?' === tag) { + if (resolve) { + for (typeIndex = 0, typeQuantity = implicitTypes.length; + typeIndex < typeQuantity; + typeIndex += 1) { + type = implicitTypes[typeIndex]; + + // Implicit resolving is not allowed for non-scalar types, and '?' + // non-specific tag is only assigned to plain scalars. So, it isn't + // needed to check for 'kind' conformity. + _result = type.loader.resolver(result, false); + + if (NIL !== _result) { + tag = type.tag; + result = _result; + break; + } + } + } + } else if (_hasOwnProperty.call(typeMap, tag)) { + typeLoader = typeMap[tag].loader; + + if (null !== result && typeLoader.kind !== kind) { + throwError('unacceptable node kind for !<' + tag + '> tag; it should be "' + typeLoader.kind + '", not "' + kind + '"'); + } + + if (typeLoader.resolver) { + _result = typeLoader.resolver(result, true); + + if (NIL !== _result) { + result = _result; + } else { + throwError('cannot resolve a node with !<' + tag + '> explicit tag'); + } + } + } else { + throwWarning('unknown tag !<' + tag + '>'); + } + } + + return null !== tag || null !== anchor || hasContent; + } + + function readDocument() { + var documentStart = position, + _position, + directiveName, + directiveArgs, + hasDirectives = false; + + version = null; + checkLineBreaks = legacy; + tagMap = {}; + anchorMap = {}; + + while (position < length) { + skipSeparationSpace(true, -1); + + if (lineIndent > 0 || CHAR_PERCENT !== character) { + break; + } + + hasDirectives = true; + character = input.charCodeAt(++position); + _position = position; + + while (position < length && + CHAR_SPACE !== character && + CHAR_TAB !== character && + CHAR_LINE_FEED !== character && + CHAR_CARRIAGE_RETURN !== character) { + character = input.charCodeAt(++position); + } + + directiveName = input.slice(_position, position); + directiveArgs = []; + + if (directiveName.length < 1) { + throwError('directive name must not be less than one character in length'); + } + + while (position < length) { + while (CHAR_SPACE === character || CHAR_TAB === character) { + character = input.charCodeAt(++position); + } + + if (CHAR_SHARP === character) { + do { character = input.charCodeAt(++position); } + while (position < length && + CHAR_LINE_FEED !== character && + CHAR_CARRIAGE_RETURN !== character); + break; + } + + if (CHAR_LINE_FEED === character || CHAR_CARRIAGE_RETURN === character) { + break; + } + + _position = position; + + while (position < length && + CHAR_SPACE !== character && + CHAR_TAB !== character && + CHAR_LINE_FEED !== character && + CHAR_CARRIAGE_RETURN !== character) { + character = input.charCodeAt(++position); + } + + directiveArgs.push(input.slice(_position, position)); + } + + if (position < length) { + readLineBreak(); + } + + if (_hasOwnProperty.call(directiveHandlers, directiveName)) { + directiveHandlers[directiveName](directiveName, directiveArgs); + } else { + throwWarning('unknown document directive "' + directiveName + '"'); + } + } + + skipSeparationSpace(true, -1); + + if (0 === lineIndent && + CHAR_MINUS === character && + CHAR_MINUS === input.charCodeAt(position + 1) && + CHAR_MINUS === input.charCodeAt(position + 2)) { + position += 3; + character = input.charCodeAt(position); + skipSeparationSpace(true, -1); + + } else if (hasDirectives) { + throwError('directives end mark is expected'); + } + + composeNode(lineIndent - 1, CONTEXT_BLOCK_OUT, false, true); + skipSeparationSpace(true, -1); + + if (validate && checkLineBreaks && + PATTERN_NON_ASCII_LINE_BREAKS.test(input.slice(documentStart, position))) { + throwWarning('non-ASCII line breaks are interpreted as content'); + } + + output(result); + + if (position === lineStart && testDocumentSeparator()) { + if (CHAR_DOT === character) { + position += 3; + character = input.charCodeAt(position); + skipSeparationSpace(true, -1); + } + return; + } + + if (position < length) { + throwError('end of the stream or a document separator is expected'); + } else { + return; + } + } + + if (validate && PATTERN_NON_PRINTABLE.test(input)) { + throwError('the stream contains non-printable characters'); + } + + while (CHAR_SPACE === character) { + lineIndent += 1; + character = input.charCodeAt(++position); + } + + while (position < length) { + readDocument(); + } +} + + +function load(input, options) { + var result = null, received = false; + + function callback(data) { + if (!received) { + result = data; + received = true; + } else { + throw new YAMLException('expected a single document in the stream, but found more'); + } + } + + loadAll(input, callback, options); + + return result; +} + + +function safeLoadAll(input, output, options) { + loadAll(input, output, common.extend({ schema: SAFE_SCHEMA }, options)); +} + + +function safeLoad(input, options) { + return load(input, common.extend({ schema: SAFE_SCHEMA }, options)); +} + + +module.exports.loadAll = loadAll; +module.exports.load = load; +module.exports.safeLoadAll = safeLoadAll; +module.exports.safeLoad = safeLoad; diff --git a/node_modules/js-yaml/lib/js-yaml/mark.js b/node_modules/js-yaml/lib/js-yaml/mark.js new file mode 100644 index 0000000..bfe279b --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/mark.js @@ -0,0 +1,78 @@ +'use strict'; + + +var common = require('./common'); + + +function Mark(name, buffer, position, line, column) { + this.name = name; + this.buffer = buffer; + this.position = position; + this.line = line; + this.column = column; +} + + +Mark.prototype.getSnippet = function getSnippet(indent, maxLength) { + var head, start, tail, end, snippet; + + if (!this.buffer) { + return null; + } + + indent = indent || 4; + maxLength = maxLength || 75; + + head = ''; + start = this.position; + + while (start > 0 && -1 === '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(start - 1))) { + start -= 1; + if (this.position - start > (maxLength / 2 - 1)) { + head = ' ... '; + start += 5; + break; + } + } + + tail = ''; + end = this.position; + + while (end < this.buffer.length && -1 === '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(end))) { + end += 1; + if (end - this.position > (maxLength / 2 - 1)) { + tail = ' ... '; + end -= 5; + break; + } + } + + snippet = this.buffer.slice(start, end); + + return common.repeat(' ', indent) + head + snippet + tail + '\n' + + common.repeat(' ', indent + this.position - start + head.length) + '^'; +}; + + +Mark.prototype.toString = function toString(compact) { + var snippet, where = ''; + + if (this.name) { + where += 'in "' + this.name + '" '; + } + + where += 'at line ' + (this.line + 1) + ', column ' + (this.column + 1); + + if (!compact) { + snippet = this.getSnippet(); + + if (snippet) { + where += ':\n' + snippet; + } + } + + return where; +}; + + +module.exports = Mark; diff --git a/node_modules/js-yaml/lib/js-yaml/require.js b/node_modules/js-yaml/lib/js-yaml/require.js new file mode 100644 index 0000000..47b77e3 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/require.js @@ -0,0 +1,23 @@ +'use strict'; + + +var fs = require('fs'); +var loader = require('./loader'); + + +function yamlRequireHandler(module, filename) { + var content = fs.readFileSync(filename, 'utf8'); + + // fill in documents + module.exports = loader.load(content, { filename: filename }); +} + +// register require extensions only if we're on node.js +// hack for browserify +if (undefined !== require.extensions) { + require.extensions['.yml'] = yamlRequireHandler; + require.extensions['.yaml'] = yamlRequireHandler; +} + + +module.exports = require; diff --git a/node_modules/js-yaml/lib/js-yaml/schema.js b/node_modules/js-yaml/lib/js-yaml/schema.js new file mode 100644 index 0000000..ce21391 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/schema.js @@ -0,0 +1,103 @@ +'use strict'; + + +var common = require('./common'); +var YAMLException = require('./exception'); +var Type = require('./type'); + + +function compileList(schema, name, result) { + var exclude = []; + + schema.include.forEach(function (includedSchema) { + result = compileList(includedSchema, name, result); + }); + + schema[name].forEach(function (currentType) { + result.forEach(function (previousType, previousIndex) { + if (previousType.tag === currentType.tag) { + exclude.push(previousIndex); + } + }); + + result.push(currentType); + }); + + return result.filter(function (type, index) { + return -1 === exclude.indexOf(index); + }); +} + + +function compileMap(/* lists... */) { + var result = {}, index, length; + + function collectType(type) { + result[type.tag] = type; + } + + for (index = 0, length = arguments.length; index < length; index += 1) { + arguments[index].forEach(collectType); + } + + return result; +} + + +function Schema(definition) { + this.include = definition.include || []; + this.implicit = definition.implicit || []; + this.explicit = definition.explicit || []; + + this.implicit.forEach(function (type) { + if (null !== type.loader && 'string' !== type.loader.kind) { + throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.'); + } + }); + + this.compiledImplicit = compileList(this, 'implicit', []); + this.compiledExplicit = compileList(this, 'explicit', []); + this.compiledTypeMap = compileMap(this.compiledImplicit, this.compiledExplicit); +} + + +Schema.DEFAULT = null; + + +Schema.create = function createSchema() { + var schemas, types; + + switch (arguments.length) { + case 1: + schemas = Schema.DEFAULT; + types = arguments[0]; + break; + + case 2: + schemas = arguments[0]; + types = arguments[1]; + break; + + default: + throw new YAMLException('Wrong number of arguments for Schema.create function'); + } + + schemas = common.toArray(schemas); + types = common.toArray(types); + + if (!schemas.every(function (schema) { return schema instanceof Schema; })) { + throw new YAMLException('Specified list of super schemas (or a single Schema object) contains a non-Schema object.'); + } + + if (!types.every(function (type) { return type instanceof Type; })) { + throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.'); + } + + return new Schema({ + include: schemas, + explicit: types + }); +}; + + +module.exports = Schema; diff --git a/node_modules/js-yaml/lib/js-yaml/schema/default.js b/node_modules/js-yaml/lib/js-yaml/schema/default.js new file mode 100644 index 0000000..71bb3fc --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/schema/default.js @@ -0,0 +1,16 @@ +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = Schema.DEFAULT = new Schema({ + include: [ + require('./safe') + ], + explicit: [ + require('../type/js/undefined'), + require('../type/js/regexp'), + require('../type/js/function') + ] +}); diff --git a/node_modules/js-yaml/lib/js-yaml/schema/minimal.js b/node_modules/js-yaml/lib/js-yaml/schema/minimal.js new file mode 100644 index 0000000..7a6ebbe --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/schema/minimal.js @@ -0,0 +1,13 @@ +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + explicit: [ + require('../type/str'), + require('../type/seq'), + require('../type/map') + ] +}); diff --git a/node_modules/js-yaml/lib/js-yaml/schema/safe.js b/node_modules/js-yaml/lib/js-yaml/schema/safe.js new file mode 100644 index 0000000..856b7c4 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/schema/safe.js @@ -0,0 +1,25 @@ +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + include: [ + require('./minimal') + ], + implicit: [ + require('../type/null'), + require('../type/bool'), + require('../type/int'), + require('../type/float'), + require('../type/timestamp'), + require('../type/merge') + ], + explicit: [ + require('../type/binary'), + require('../type/omap'), + require('../type/pairs'), + require('../type/set') + ] +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type.js b/node_modules/js-yaml/lib/js-yaml/type.js new file mode 100644 index 0000000..e0124f2 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type.js @@ -0,0 +1,82 @@ +'use strict'; + + +var YAMLException = require('./exception'); + + +// TODO: Add tag format check. +function Type(tag, options) { + options = options || {}; + + this.tag = tag; + this.loader = options['loader'] || null; + this.dumper = options['dumper'] || null; + + if (null === this.loader && null === this.dumper) { + throw new YAMLException('Incomplete YAML type definition. "loader" or "dumper" setting must be specified.'); + } + + if (null !== this.loader) { + this.loader = new Type.Loader(this.loader); + } + + if (null !== this.dumper) { + this.dumper = new Type.Dumper(this.dumper); + } +} + + +Type.Loader = function TypeLoader(options) { + options = options || {}; + + this.kind = options['kind'] || null; + this.resolver = options['resolver'] || null; + + if ('string' !== this.kind && + 'array' !== this.kind && + 'object' !== this.kind) { + throw new YAMLException('Unacceptable "kind" setting of a type loader.'); + } +}; + + +function compileAliases(map) { + var result = {}; + + if (null !== map) { + Object.keys(map).forEach(function (style) { + map[style].forEach(function (alias) { + result[String(alias)] = style; + }); + }); + } + + return result; +} + + +Type.Dumper = function TypeDumper(options) { + options = options || {}; + + this.kind = options['kind'] || null; + this.defaultStyle = options['defaultStyle'] || null; + this.instanceOf = options['instanceOf'] || null; + this.predicate = options['predicate'] || null; + this.representer = options['representer'] || null; + this.styleAliases = compileAliases(options['styleAliases'] || null); + + if ('undefined' !== this.kind && + 'null' !== this.kind && + 'boolean' !== this.kind && + 'integer' !== this.kind && + 'float' !== this.kind && + 'string' !== this.kind && + 'array' !== this.kind && + 'object' !== this.kind && + 'function' !== this.kind) { + throw new YAMLException('Unacceptable "kind" setting of a type dumper.'); + } +}; + + +module.exports = Type; diff --git a/node_modules/js-yaml/lib/js-yaml/type/binary.js b/node_modules/js-yaml/lib/js-yaml/type/binary.js new file mode 100644 index 0000000..37b4bc7 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/binary.js @@ -0,0 +1,118 @@ +// Modified from: +// https://raw.github.com/kanaka/noVNC/d890e8640f20fba3215ba7be8e0ff145aeb8c17c/include/base64.js + +'use strict'; + + +var NodeBuffer = require('buffer').Buffer; // A trick for browserified version. +var common = require('../common'); +var NIL = common.NIL; +var Type = require('../type'); + + + +var BASE64_PADDING = '='; + +var BASE64_BINTABLE = [ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 +]; + +var BASE64_CHARTABLE = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); + + +function resolveYamlBinary(object /*, explicit*/) { + var value, code, idx = 0, result = [], leftbits, leftdata; + + leftbits = 0; // number of bits decoded, but yet to be appended + leftdata = 0; // bits decoded, but yet to be appended + + // Convert one by one. + for (idx = 0; idx < object.length; idx += 1) { + code = object.charCodeAt(idx); + value = BASE64_BINTABLE[code & 0x7F]; + + // Skip LF(NL) || CR + if (0x0A !== code && 0x0D !== code) { + // Fail on illegal characters + if (-1 === value) { + return NIL; + } + + // Collect data into leftdata, update bitcount + leftdata = (leftdata << 6) | value; + leftbits += 6; + + // If we have 8 or more bits, append 8 bits to the result + if (leftbits >= 8) { + leftbits -= 8; + + // Append if not padding. + if (BASE64_PADDING !== object.charAt(idx)) { + result.push((leftdata >> leftbits) & 0xFF); + } + + leftdata &= (1 << leftbits) - 1; + } + } + } + + // If there are any bits left, the base64 string was corrupted + if (leftbits) { + return NIL; + } else { + return new NodeBuffer(result); + } +} + + +function representYamlBinary(object /*, style*/) { + var result = '', index, length, rest; + + // Convert every three bytes to 4 ASCII characters. + for (index = 0, length = object.length - 2; index < length; index += 3) { + result += BASE64_CHARTABLE[object[index + 0] >> 2]; + result += BASE64_CHARTABLE[((object[index + 0] & 0x03) << 4) + (object[index + 1] >> 4)]; + result += BASE64_CHARTABLE[((object[index + 1] & 0x0F) << 2) + (object[index + 2] >> 6)]; + result += BASE64_CHARTABLE[object[index + 2] & 0x3F]; + } + + rest = object.length % 3; + + // Convert the remaining 1 or 2 bytes, padding out to 4 characters. + if (0 !== rest) { + index = object.length - rest; + result += BASE64_CHARTABLE[object[index + 0] >> 2]; + + if (2 === rest) { + result += BASE64_CHARTABLE[((object[index + 0] & 0x03) << 4) + (object[index + 1] >> 4)]; + result += BASE64_CHARTABLE[(object[index + 1] & 0x0F) << 2]; + result += BASE64_PADDING; + } else { + result += BASE64_CHARTABLE[(object[index + 0] & 0x03) << 4]; + result += BASE64_PADDING + BASE64_PADDING; + } + } + + return result; +} + + +module.exports = new Type('tag:yaml.org,2002:binary', { + loader: { + kind: 'string', + resolver: resolveYamlBinary + }, + dumper: { + kind: 'object', + instanceOf: NodeBuffer, + representer: representYamlBinary + } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/bool.js b/node_modules/js-yaml/lib/js-yaml/type/bool.js new file mode 100644 index 0000000..987a9e6 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/bool.js @@ -0,0 +1,74 @@ +'use strict'; + + +var NIL = require('../common').NIL; +var Type = require('../type'); + + +var YAML_IMPLICIT_BOOLEAN_MAP = { + 'true' : true, + 'True' : true, + 'TRUE' : true, + 'false' : false, + 'False' : false, + 'FALSE' : false +}; + +var YAML_EXPLICIT_BOOLEAN_MAP = { + 'true' : true, + 'True' : true, + 'TRUE' : true, + 'false' : false, + 'False' : false, + 'FALSE' : false, + 'y' : true, + 'Y' : true, + 'yes' : true, + 'Yes' : true, + 'YES' : true, + 'n' : false, + 'N' : false, + 'no' : false, + 'No' : false, + 'NO' : false, + 'on' : true, + 'On' : true, + 'ON' : true, + 'off' : false, + 'Off' : false, + 'OFF' : false +}; + + +function resolveYamlBoolean(object, explicit) { + if (explicit) { + if (YAML_EXPLICIT_BOOLEAN_MAP.hasOwnProperty(object)) { + return YAML_EXPLICIT_BOOLEAN_MAP[object]; + } else { + return NIL; + } + } else { + if (YAML_IMPLICIT_BOOLEAN_MAP.hasOwnProperty(object)) { + return YAML_IMPLICIT_BOOLEAN_MAP[object]; + } else { + return NIL; + } + } +} + + +module.exports = new Type('tag:yaml.org,2002:bool', { + loader: { + kind: 'string', + resolver: resolveYamlBoolean + }, + dumper: { + kind: 'boolean', + defaultStyle: 'lowercase', + representer: { + lowercase: function (object) { return object ? 'true' : 'false'; }, + uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; }, + camelcase: function (object) { return object ? 'True' : 'False'; } + } + } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/float.js b/node_modules/js-yaml/lib/js-yaml/type/float.js new file mode 100644 index 0000000..edb5fcb --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/float.js @@ -0,0 +1,102 @@ +'use strict'; + + +var NIL = require('../common').NIL; +var Type = require('../type'); + + +var YAML_FLOAT_PATTERN = new RegExp( + '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' + + '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' + + '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' + + '|[-+]?\\.(?:inf|Inf|INF)' + + '|\\.(?:nan|NaN|NAN))$'); + + +function resolveYamlFloat(object /*, explicit*/) { + var value, sign, base, digits; + + if (!YAML_FLOAT_PATTERN.test(object)) { + return NIL; + } + + value = object.replace(/_/g, '').toLowerCase(); + sign = '-' === value[0] ? -1 : 1; + digits = []; + + if (0 <= '+-'.indexOf(value[0])) { + value = value.slice(1); + } + + if ('.inf' === value) { + return (1 === sign) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; + + } else if ('.nan' === value) { + return NaN; + + } else if (0 <= value.indexOf(':')) { + value.split(':').forEach(function (v) { + digits.unshift(parseFloat(v, 10)); + }); + + value = 0.0; + base = 1; + + digits.forEach(function (d) { + value += d * base; + base *= 60; + }); + + return sign * value; + + } else { + return sign * parseFloat(value, 10); + } +} + + +function representYamlFloat(object, style) { + if (isNaN(object)) { + switch (style) { + case 'lowercase': + return '.nan'; + case 'uppercase': + return '.NAN'; + case 'camelcase': + return '.NaN'; + } + } else if (Number.POSITIVE_INFINITY === object) { + switch (style) { + case 'lowercase': + return '.inf'; + case 'uppercase': + return '.INF'; + case 'camelcase': + return '.Inf'; + } + } else if (Number.NEGATIVE_INFINITY === object) { + switch (style) { + case 'lowercase': + return '-.inf'; + case 'uppercase': + return '-.INF'; + case 'camelcase': + return '-.Inf'; + } + } else { + return object.toString(10); + } +} + + +module.exports = new Type('tag:yaml.org,2002:float', { + loader: { + kind: 'string', + resolver: resolveYamlFloat + }, + dumper: { + kind: 'float', + defaultStyle: 'lowercase', + representer: representYamlFloat + } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/int.js b/node_modules/js-yaml/lib/js-yaml/type/int.js new file mode 100644 index 0000000..f5e1e7e --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/int.js @@ -0,0 +1,85 @@ +'use strict'; + + +var NIL = require('../common').NIL; +var Type = require('../type'); + + +var YAML_INTEGER_PATTERN = new RegExp( + '^(?:[-+]?0b[0-1_]+' + + '|[-+]?0[0-7_]+' + + '|[-+]?(?:0|[1-9][0-9_]*)' + + '|[-+]?0x[0-9a-fA-F_]+' + + '|[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$'); + + +function resolveYamlInteger(object /*, explicit*/) { + var value, sign, base, digits; + + if (!YAML_INTEGER_PATTERN.test(object)) { + return NIL; + } + + value = object.replace(/_/g, ''); + sign = '-' === value[0] ? -1 : 1; + digits = []; + + if (0 <= '+-'.indexOf(value[0])) { + value = value.slice(1); + } + + if ('0' === value) { + return 0; + + } else if (/^0b/.test(value)) { + return sign * parseInt(value.slice(2), 2); + + } else if (/^0x/.test(value)) { + return sign * parseInt(value, 16); + + } else if ('0' === value[0]) { + return sign * parseInt(value, 8); + + } else if (0 <= value.indexOf(':')) { + value.split(':').forEach(function (v) { + digits.unshift(parseInt(v, 10)); + }); + + value = 0; + base = 1; + + digits.forEach(function (d) { + value += (d * base); + base *= 60; + }); + + return sign * value; + + } else { + return sign * parseInt(value, 10); + } +} + + +module.exports = new Type('tag:yaml.org,2002:int', { + loader: { + kind: 'string', + resolver: resolveYamlInteger + }, + dumper: { + kind: 'integer', + defaultStyle: 'decimal', + representer: { + binary: function (object) { return '0b' + object.toString(2); }, + octal: function (object) { return '0' + object.toString(8); }, + decimal: function (object) { return object.toString(10); }, + hexadecimal: function (object) { return '0x' + object.toString(16).toUpperCase(); } + }, + styleAliases: { + binary: [ 2, 'bin' ], + octal: [ 8, 'oct' ], + decimal: [ 10, 'dec' ], + hexadecimal: [ 16, 'hex' ] + } + } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/js/function.js b/node_modules/js-yaml/lib/js-yaml/type/js/function.js new file mode 100644 index 0000000..4b3b3ca --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/js/function.js @@ -0,0 +1,56 @@ +'use strict'; + + +var esprima = require('esprima'); + + +var NIL = require('../../common').NIL; +var Type = require('../../type'); + + +function resolveJavascriptFunction(object /*, explicit*/) { + /*jslint evil:true*/ + + try { + var source = '(' + object + ')', + ast = esprima.parse(source, { range: true }), + params = [], + body; + + if ('Program' !== ast.type || + 1 !== ast.body.length || + 'ExpressionStatement' !== ast.body[0].type || + 'FunctionExpression' !== ast.body[0].expression.type) { + return NIL; + } + + ast.body[0].expression.params.forEach(function (param) { + params.push(param.name); + }); + + body = ast.body[0].expression.body.range; + + // Esprima's ranges include the first '{' and the last '}' characters on + // function expressions. So cut them out. + return new Function(params, source.slice(body[0]+1, body[1]-1)); + } catch (err) { + return NIL; + } +} + + +function representJavascriptFunction(object /*, style*/) { + return object.toString(); +} + + +module.exports = new Type('tag:yaml.org,2002:js/function', { + loader: { + kind: 'string', + resolver: resolveJavascriptFunction + }, + dumper: { + kind: 'function', + representer: representJavascriptFunction, + } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js b/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js new file mode 100644 index 0000000..9f4f89e --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js @@ -0,0 +1,56 @@ +'use strict'; + + +var NIL = require('../../common').NIL; +var Type = require('../../type'); + + +function resolveJavascriptRegExp(object /*, explicit*/) { + var regexp = object, + tail = /\/([gim]*)$/.exec(object), + modifiers; + + // `/foo/gim` - tail can be maximum 4 chars + if ('/' === regexp[0] && tail && 4 >= tail[0].length) { + regexp = regexp.slice(1, regexp.length - tail[0].length); + modifiers = tail[1]; + } + + try { + return new RegExp(regexp, modifiers); + } catch (error) { + return NIL; + } +} + + +function representJavascriptRegExp(object /*, style*/) { + var result = '/' + object.source + '/'; + + if (object.global) { + result += 'g'; + } + + if (object.multiline) { + result += 'm'; + } + + if (object.ignoreCase) { + result += 'i'; + } + + return result; +} + + +module.exports = new Type('tag:yaml.org,2002:js/regexp', { + loader: { + kind: 'string', + resolver: resolveJavascriptRegExp + }, + dumper: { + kind: 'object', + instanceOf: RegExp, + representer: representJavascriptRegExp + } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js b/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js new file mode 100644 index 0000000..8d2835e --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js @@ -0,0 +1,28 @@ +'use strict'; + + +var Type = require('../../type'); + + +function resolveJavascriptUndefined(/*object, explicit*/) { + var undef; + + return undef; +} + + +function representJavascriptUndefined(/*object, explicit*/) { + return ''; +} + + +module.exports = new Type('tag:yaml.org,2002:js/undefined', { + loader: { + kind: 'string', + resolver: resolveJavascriptUndefined + }, + dumper: { + kind: 'undefined', + representer: representJavascriptUndefined + } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/map.js b/node_modules/js-yaml/lib/js-yaml/type/map.js new file mode 100644 index 0000000..5cda6de --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/map.js @@ -0,0 +1,11 @@ +'use strict'; + + +var Type = require('../type'); + + +module.exports = new Type('tag:yaml.org,2002:map', { + loader: { + kind: 'object' + } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/merge.js b/node_modules/js-yaml/lib/js-yaml/type/merge.js new file mode 100644 index 0000000..8facc70 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/merge.js @@ -0,0 +1,18 @@ +'use strict'; + + +var NIL = require('../common').NIL; +var Type = require('../type'); + + +function resolveYamlMerge(object /*, explicit*/) { + return '<<' === object ? object : NIL; +} + + +module.exports = new Type('tag:yaml.org,2002:merge', { + loader: { + kind: 'string', + resolver: resolveYamlMerge + } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/null.js b/node_modules/js-yaml/lib/js-yaml/type/null.js new file mode 100644 index 0000000..796e1af --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/null.js @@ -0,0 +1,36 @@ +'use strict'; + + +var NIL = require('../common').NIL; +var Type = require('../type'); + + +var YAML_NULL_MAP = { + '~' : true, + 'null' : true, + 'Null' : true, + 'NULL' : true +}; + + +function resolveYamlNull(object /*, explicit*/) { + return YAML_NULL_MAP[object] ? null : NIL; +} + + +module.exports = new Type('tag:yaml.org,2002:null', { + loader: { + kind: 'string', + resolver: resolveYamlNull + }, + dumper: { + kind: 'null', + defaultStyle: 'lowercase', + representer: { + canonical: function () { return '~'; }, + lowercase: function () { return 'null'; }, + uppercase: function () { return 'NULL'; }, + camelcase: function () { return 'Null'; }, + } + } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/omap.js b/node_modules/js-yaml/lib/js-yaml/type/omap.js new file mode 100644 index 0000000..f7c248d --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/omap.js @@ -0,0 +1,53 @@ +'use strict'; + + +var NIL = require('../common').NIL; +var Type = require('../type'); + + +var _hasOwnProperty = Object.prototype.hasOwnProperty; +var _toString = Object.prototype.toString; + + +function resolveYamlOmap(object /*, explicit*/) { + var objectKeys = [], index, length, pair, pairKey, pairHasKey; + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + pairHasKey = false; + + if ('[object Object]' !== _toString.call(pair)) { + return NIL; + } + + for (pairKey in pair) { + if (_hasOwnProperty.call(pair, pairKey)) { + if (!pairHasKey) { + pairHasKey = true; + } else { + return NIL; + } + } + } + + if (!pairHasKey) { + return NIL; + } + + if (-1 === objectKeys.indexOf(pairKey)) { + objectKeys.push(pairKey); + } else { + return NIL; + } + } + + return object; +} + + +module.exports = new Type('tag:yaml.org,2002:omap', { + loader: { + kind: 'array', + resolver: resolveYamlOmap + } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/pairs.js b/node_modules/js-yaml/lib/js-yaml/type/pairs.js new file mode 100644 index 0000000..828ff1b --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/pairs.js @@ -0,0 +1,41 @@ +'use strict'; + + +var NIL = require('../common').NIL; +var Type = require('../type'); + + +var _toString = Object.prototype.toString; + + +function resolveYamlPairs(object /*, explicit*/) { + var index, length, pair, keys, result; + + result = new Array(object.length); + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + + if ('[object Object]' !== _toString.call(pair)) { + return NIL; + } + + keys = Object.keys(pair); + + if (1 !== keys.length) { + return NIL; + } + + result[index] = [ keys[0], pair[keys[0]] ]; + } + + return result; +} + + +module.exports = new Type('tag:yaml.org,2002:pairs', { + loader: { + kind: 'array', + resolver: resolveYamlPairs + } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/seq.js b/node_modules/js-yaml/lib/js-yaml/type/seq.js new file mode 100644 index 0000000..80a7cf0 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/seq.js @@ -0,0 +1,11 @@ +'use strict'; + + +var Type = require('../type'); + + +module.exports = new Type('tag:yaml.org,2002:seq', { + loader: { + kind: 'array' + } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/set.js b/node_modules/js-yaml/lib/js-yaml/type/set.js new file mode 100644 index 0000000..64bdc66 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/set.js @@ -0,0 +1,31 @@ +'use strict'; + + +var NIL = require('../common').NIL; +var Type = require('../type'); + + +var _hasOwnProperty = Object.prototype.hasOwnProperty; + + +function resolveYamlSet(object /*, explicit*/) { + var key; + + for (key in object) { + if (_hasOwnProperty.call(object, key)) { + if (null !== object[key]) { + return NIL; + } + } + } + + return object; +} + + +module.exports = new Type('tag:yaml.org,2002:set', { + loader: { + kind: 'object', + resolver: resolveYamlSet + } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/str.js b/node_modules/js-yaml/lib/js-yaml/type/str.js new file mode 100644 index 0000000..384f14e --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/str.js @@ -0,0 +1,11 @@ +'use strict'; + + +var Type = require('../type'); + + +module.exports = new Type('tag:yaml.org,2002:str', { + loader: { + kind: 'string' + } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/timestamp.js b/node_modules/js-yaml/lib/js-yaml/type/timestamp.js new file mode 100644 index 0000000..24da9e2 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/timestamp.js @@ -0,0 +1,91 @@ +'use strict'; + + +var NIL = require('../common').NIL; +var Type = require('../type'); + + +var YAML_TIMESTAMP_REGEXP = new RegExp( + '^([0-9][0-9][0-9][0-9])' + // [1] year + '-([0-9][0-9]?)' + // [2] month + '-([0-9][0-9]?)' + // [3] day + '(?:(?:[Tt]|[ \\t]+)' + // ... + '([0-9][0-9]?)' + // [4] hour + ':([0-9][0-9])' + // [5] minute + ':([0-9][0-9])' + // [6] second + '(?:\\.([0-9]*))?' + // [7] fraction + '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour + '(?::([0-9][0-9]))?))?)?$'); // [11] tz_minute + + +function resolveYamlTimestamp(object /*, explicit*/) { + var match, year, month, day, hour, minute, second, fraction = 0, + delta = null, tz_hour, tz_minute, data; + + match = YAML_TIMESTAMP_REGEXP.exec(object); + + if (null === match) { + return NIL; + } + + // match: [1] year [2] month [3] day + + year = +(match[1]); + month = +(match[2]) - 1; // JS month starts with 0 + day = +(match[3]); + + if (!match[4]) { // no hour + return new Date(Date.UTC(year, month, day)); + } + + // match: [4] hour [5] minute [6] second [7] fraction + + hour = +(match[4]); + minute = +(match[5]); + second = +(match[6]); + + if (match[7]) { + fraction = match[7].slice(0, 3); + while (fraction.length < 3) { // milli-seconds + fraction += '0'; + } + fraction = +fraction; + } + + // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute + + if (match[9]) { + tz_hour = +(match[10]); + tz_minute = +(match[11] || 0); + delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds + if ('-' === match[9]) { + delta = -delta; + } + } + + data = new Date(Date.UTC(year, month, day, hour, minute, second, fraction)); + + if (delta) { + data.setTime(data.getTime() - delta); + } + + return data; +} + + +function representYamlTimestamp(object /*, style*/) { + return object.toISOString(); +} + + +module.exports = new Type('tag:yaml.org,2002:timestamp', { + loader: { + kind: 'string', + resolver: resolveYamlTimestamp + }, + dumper: { + kind: 'object', + instanceOf: Date, + representer: representYamlTimestamp + } +}); diff --git a/node_modules/js-yaml/package.json b/node_modules/js-yaml/package.json new file mode 100644 index 0000000..0e08920 --- /dev/null +++ b/node_modules/js-yaml/package.json @@ -0,0 +1,110 @@ +{ + "_args": [ + [ + { + "raw": "js-yaml@~2.0.5", + "scope": null, + "escapedName": "js-yaml", + "name": "js-yaml", + "rawSpec": "~2.0.5", + "spec": ">=2.0.5 <2.1.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt" + ] + ], + "_from": "js-yaml@>=2.0.5 <2.1.0", + "_id": "js-yaml@2.0.5", + "_inCache": true, + "_location": "/js-yaml", + "_npmUser": { + "name": "vitaly", + "email": "vitaly@rcdesign.ru" + }, + "_npmVersion": "1.2.14", + "_phantomChildren": {}, + "_requested": { + "raw": "js-yaml@~2.0.5", + "scope": null, + "escapedName": "js-yaml", + "name": "js-yaml", + "rawSpec": "~2.0.5", + "spec": ">=2.0.5 <2.1.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt" + ], + "_resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz", + "_shasum": "a25ae6509999e97df278c6719da11bd0687743a8", + "_shrinkwrap": null, + "_spec": "js-yaml@~2.0.5", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt", + "author": { + "name": "Dervus Grim", + "email": "dervus@lavabit.com" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + }, + "bugs": { + "url": "https://github.com/nodeca/js-yaml/issues" + }, + "contributors": [ + { + "name": "Aleksey V Zapparov", + "email": "ixti@member.fsf.org", + "url": "http://www.ixti.net/" + }, + { + "name": "Martin Grenfell", + "email": "martin.grenfell@gmail.com", + "url": "http://got-ravings.blogspot.com" + } + ], + "dependencies": { + "argparse": "~ 0.1.11", + "esprima": "~ 1.0.2" + }, + "description": "YAML 1.2 parser and serializer", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "a25ae6509999e97df278c6719da11bd0687743a8", + "tarball": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz" + }, + "engines": { + "node": ">= 0.6.0" + }, + "homepage": "https://github.com/nodeca/js-yaml", + "keywords": [ + "yaml", + "parser", + "serializer", + "pyyaml" + ], + "license": { + "type": "MIT", + "url": "https://github.com/nodeca/js-yaml/blob/master/LICENSE" + }, + "main": "./index.js", + "maintainers": [ + { + "name": "vitaly", + "email": "vitaly@rcdesign.ru" + } + ], + "name": "js-yaml", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/nodeca/js-yaml.git" + }, + "scripts": { + "test": "make test" + }, + "version": "2.0.5" +} diff --git a/node_modules/jsftp/.editorconfig b/node_modules/jsftp/.editorconfig new file mode 100644 index 0000000..fd76ab5 --- /dev/null +++ b/node_modules/jsftp/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] + +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false diff --git a/node_modules/jsftp/.eslintrc b/node_modules/jsftp/.eslintrc new file mode 100644 index 0000000..2b72bed --- /dev/null +++ b/node_modules/jsftp/.eslintrc @@ -0,0 +1,184 @@ +{ + "env": { + "node": true, + "mocha": true + }, + "rules": { + "no-cond-assign": 1, // disallow assignment in conditional expressions + "no-console": 0, // disallow use of console: should use nuclide-logging instead + "no-constant-condition": 1, // disallow use of constant expressions in conditions + "no-control-regex": 1, // disallow control characters in regular expressions + "no-debugger": 1, // disallow use of debugger + "no-dupe-keys": 1, // disallow duplicate keys when creating object literals + "no-dupe-args": 1, // disallow duplicate arguments in functions + "no-duplicate-case": 1, // disallow a duplicate case label + "no-empty": 0, // disallow empty statements + "no-empty-character-class": 1, // disallow the use of empty character classes in regular expressions + "no-ex-assign": 1, // disallow assigning to the exception in a catch block + "no-extra-boolean-cast": 1, // disallow double-negation boolean casts in a boolean context + "no-extra-semi": 1, // disallow unnecessary semicolons + "no-func-assign": 1, // disallow overwriting functions written as function declarations + "no-inner-declarations": 0, // disallow function or variable declarations in nested blocks + "no-invalid-regexp": 1, // disallow invalid regular expression strings in the RegExp constructor + "no-negated-in-lhs": 1, // disallow negation of the left operand of an in expression + "no-obj-calls": 1, // disallow the use of object properties of the global object (Math and JSON) as functions + "no-regex-spaces": 1, // disallow multiple spaces in a regular expression literal + "no-reserved-keys": 0, // disallow reserved words being used as object literal keys + "no-sparse-arrays": 1, // disallow sparse arrays + "no-unreachable": 1, // disallow unreachable statements after a return, throw, continue, or break statement + "use-isnan": 1, // disallow comparisons with the value NaN + "valid-jsdoc": 0, // Ensure JSDoc comments are valid + "valid-typeof": 1, // Ensure that the results of typeof are compared against a valid string + + // Best Practices (designed to prevent you from making mistakes) + + "block-scoped-var": 0, // treat var statements as if they were block scoped + "complexity": 0, // specify the maximum cyclomatic complexity allowed in a program + "consistent-return": 0, // require return statements to either always or never specify values + "curly": 1, // specify curly brace conventions for all control statements + "default-case": 0, // require default case in switch statements + "dot-notation": 0, // dot notation encouraged except for foreign properties that cannot be renamed (i.e., Closure Compiler rules) + "eqeqeq": [1, "allow-null"], // require the use of === and !== + "guard-for-in": 1, // make sure for-in loops have an if statement + "no-alert": 1, // disallow the use of alert, confirm, and prompt + "no-caller": 1, // disallow use of arguments.caller or arguments.callee + "no-div-regex": 1, // disallow division operators explicitly at beginning of regular expression + "no-else-return": 0, // disallow else after a return in an if +<<<<<<< HEAD + "no-labels": 1, // disallow use of labels for anything other then loops and switches +======= + "no-empty-label": 1, // disallow use of labels for anything other then loops and switches +>>>>>>> Switch to a Node.js server for testing, cleanup tests and small fixes + "no-eq-null": 0, // disallow comparisons to null without a type-checking operator + "no-eval": 1, // disallow use of eval() + "no-extend-native": 1, // disallow adding to native types + "no-extra-bind": 1, // disallow unnecessary function binding + "no-fallthrough": 1, // disallow fallthrough of case statements + "no-floating-decimal": 1, // disallow the use of leading or trailing decimal points in numeric literals + "no-implied-eval": 1, // disallow use of eval()-like methods + "no-labels": 1, // disallow use of labeled statements + "no-iterator": 1, // disallow usage of __iterator__ property + "no-lone-blocks": 1, // disallow unnecessary nested blocks + "no-loop-func": 0, // disallow creation of functions within loops + "no-multi-str": 0, // disallow use of multiline strings + "no-native-reassign": 0, // disallow reassignments of native objects + "no-new": 1, // disallow use of new operator when not part of the assignment or comparison + "no-new-func": 1, // disallow use of new operator for Function object + "no-new-wrappers": 1, // disallows creating new instances of String,Number, and Boolean + "no-octal": 1, // disallow use of octal literals + "no-octal-escape": 1, // disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251"; + "no-proto": 1, // disallow usage of __proto__ property + "no-redeclare": 1, // disallow declaring the same variable more then once + "no-return-assign": 1, // disallow use of assignment in return statement + "no-script-url": 1, // disallow use of javascript: urls. + "no-self-compare": 1, // disallow comparisons where both sides are exactly the same + "no-sequences": 1, // disallow use of comma operator + "no-unused-expressions": 0, // disallow usage of expressions in statement position + "no-void": 1, // disallow use of void operator + "no-warning-comments": 0, // disallow usage of configurable warning terms in comments e.g. TODO or FIXME + "no-with": 1, // disallow use of the with statement + "radix": 1, // require use of the second argument for parseInt() + "vars-on-top": 0, // requires to declare all vars on top of their containing scope + "wrap-iife": 0, // require immediate function invocation to be wrapped in parentheses + "yoda": 1, // require or disallow Yoda conditions + "strict": 0, // this rule conflicts with 'use-babel' so we'll just disable it + + // Variables + + "no-catch-shadow": 1, // disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment) + "no-delete-var": 1, // disallow deletion of variables + "no-label-var": 1, // disallow labels that share a name with a variable + "no-shadow": 0, // disallow declaration of variables already declared in the outer scope + "no-shadow-restricted-names": 1, // disallow shadowing of names such as arguments + "no-undef": 1, // disallow undeclared variables + "no-undefined": 0, // disallow use of undefined variable + "no-undef-init": 0, // disallow use of undefined when initializing variables + "no-unused-vars": ["error", { "args": "none" }], // disallow declaration of variables that are not used in the code + "no-use-before-define": 0, // disallow use of variables before they are defined + + // Node.js + + "handle-callback-err": 1, // enforces error handling in callbacks + "no-mixed-requires": 1, // disallow mixing regular variable and require declarations + "no-new-require": 1, // disallow use of new operator with the require function + "no-path-concat": 1, // disallow string concatenation with __dirname and __filename + "no-process-exit": 0, // disallow process.exit() + "no-restricted-modules": 1, // restrict usage of specified node modules + "no-sync": 0, // disallow use of synchronous methods + + // Stylistic (these rules are purely matters of style and are quite subjective) + + "key-spacing": 0, + "comma-spacing": 0, + "no-multi-spaces": 0, + "brace-style": [ // enforce one true brace style + 1, "1tbs", { + "allowSingleLine": false + } + ], + "camelcase": [ // require camel case names + 1, {"properties": "never"} + ], + "consistent-this": [1, "self"], // enforces consistent naming when capturing the current execution context + "eol-last": 1, // enforce newline at the end of file, with no multiple empty lines + "func-names": 0, // require function expressions to have a name + "func-style": 0, // enforces use of function declarations or expressions + "new-cap": 0, // require a capital letter for constructors + "new-parens": 1, // disallow the omission of parentheses when invoking a constructor with no arguments + "no-nested-ternary": 0, // disallow nested ternary expressions + "no-array-constructor": 1, // disallow use of the Array constructor + "no-lonely-if": 0, // disallow if as the only statement in an else block + "no-new-object": 1, // disallow use of the Object constructor + "no-spaced-func": 1, // disallow space between function identifier and application + "semi-spacing": 1, // disallow space before semicolon + "no-ternary": 0, // disallow the use of ternary operators + "no-trailing-spaces": 1, // disallow trailing whitespace at the end of lines + "no-underscore-dangle": 0, // disallow dangling underscores in identifiers + "no-extra-parens": [1, "functions"], // disallow wrapping of non-IIFE statements in parens + "no-mixed-spaces-and-tabs": 1, // disallow mixed spaces and tabs for indentation + "indent": [1, 2, {"SwitchCase": 1}], // indentation should be two spaces + "quotes": [ // enforce single quotes, allow double to avoid escaping ("don't escape" instead of 'don\'t escape') + 1, "single", "avoid-escape" + ], + "quote-props": [1, "as-needed"], // require quotes around object literal property names + "semi": 1, // require or disallow use of semicolons instead of ASI + "sort-vars": 0, // sort variables within the same declaration block +<<<<<<< HEAD + "keyword-spacing": 1, // require a space after certain keywords +======= + "space-after-keywords": 1, // require a space after certain keywords +>>>>>>> Switch to a Node.js server for testing, cleanup tests and small fixes + "space-before-blocks": 1, // require a space before blocks + "space-before-function-paren": [ // disallow a space before function parenthesis + 1, "never" + ], + "array-bracket-spacing": [ // disallow spaces inside of curly braces in array literals + 1, "never" + ], + "space-in-parens": 1, // require or disallow spaces inside parentheses + "space-infix-ops": 1, // require spaces around operators +<<<<<<< HEAD +======= + "space-return-throw-case": 1, // require a space after return, throw, and case +>>>>>>> Switch to a Node.js server for testing, cleanup tests and small fixes + "space-unary-ops": 1, // require a space around word operators such as typeof + "max-nested-callbacks": 0, // specify the maximum depth callbacks can be nested + "one-var": [1, "never"], // allow just one var statement per function + "wrap-regex": 0, // require regex literals to be wrapped in parentheses + + // Legacy (included for compatibility with JSHint and JSLint. While the names of the rules may not match up with the JSHint/JSLint counterpart, the functionality is the same) + + "max-depth": 0, // specify the maximum depth that blocks can be nested + //"max-len": [ // specify the maximum length of a line in your program [warning level, max line length, number of characters to treat a tab as] + // 1, 100, 2, { + // "ignoreUrls": true, + // "ignorePattern": "^\\s*(import\\s[^{]+from|(var|const|let)\\s[^{]+=\\s*require\\s*\\()" + // } + //], + "max-params": 0, // limits the number of parameters that can be used in the function declaration. + "max-statements": 0, // specify the maximum number of statement allowed in a function + "no-bitwise": 0, // disallow use of bitwise operators + "no-plusplus": 0 // disallow use of unary operators, ++ and -- + + } +} diff --git a/node_modules/jsftp/.npmignore b/node_modules/jsftp/.npmignore new file mode 100644 index 0000000..cb921b2 --- /dev/null +++ b/node_modules/jsftp/.npmignore @@ -0,0 +1,7 @@ +coverage.html +*.un~ +lib-cov +reports +.c9revisions +test +node_modules diff --git a/node_modules/jsftp/.travis.yml b/node_modules/jsftp/.travis.yml new file mode 100644 index 0000000..d8173b0 --- /dev/null +++ b/node_modules/jsftp/.travis.yml @@ -0,0 +1,11 @@ +language: node_js +node_js: + - "0.12" + - "4.5.0" + - "6.6.0" +os: + - linux + - osx +before_script: + - "npm install --dev" + diff --git a/node_modules/jsftp/.vscode/launch.json b/node_modules/jsftp/.vscode/launch.json new file mode 100644 index 0000000..7b8f2b2 --- /dev/null +++ b/node_modules/jsftp/.vscode/launch.json @@ -0,0 +1,37 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch", + "type": "node", + "request": "launch", + "program": "${workspaceRoot}/jsftp.js", + "stopOnEntry": false, + "args": [], + "cwd": "${workspaceRoot}", + "preLaunchTask": null, + "runtimeExecutable": null, + "runtimeArgs": [ + "--nolazy" + ], + "env": { + "NODE_ENV": "development" + }, + "externalConsole": false, + "sourceMaps": false, + "outDir": null + }, + { + "name": "Attach", + "type": "node", + "request": "attach", + "port": 5858, + "address": "localhost", + "restart": false, + "sourceMaps": false, + "outDir": null, + "localRoot": "${workspaceRoot}", + "remoteRoot": null + } + ] +} \ No newline at end of file diff --git a/node_modules/jsftp/CHANGELOG.md b/node_modules/jsftp/CHANGELOG.md new file mode 100644 index 0000000..697cda5 --- /dev/null +++ b/node_modules/jsftp/CHANGELOG.md @@ -0,0 +1,10 @@ +## Change Log + +### v1.5.1 (2015/03/24) +- [Issue 103](https://github.com/sergi/jsftp/issues/103) Fix potential problem + with PASV requests never return. +- Small documentation improvements + +### v1.3.9 (2014/12/23) +- [Issue 106](https://github.com/sergi/jsftp/issues/106) jsftp intermittently skips `end` event on socket (@sergi) +- Code improvements to the response parser diff --git a/node_modules/jsftp/LICENSE b/node_modules/jsftp/LICENSE new file mode 100644 index 0000000..8a34f6d --- /dev/null +++ b/node_modules/jsftp/LICENSE @@ -0,0 +1,22 @@ +The MIT License + +Copyright(c) 2011 Ajax.org B.V. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/node_modules/jsftp/Makefile b/node_modules/jsftp/Makefile new file mode 100644 index 0000000..4f89538 --- /dev/null +++ b/node_modules/jsftp/Makefile @@ -0,0 +1,25 @@ +# use the tools as dev dependencies rather than installing them globaly +# it lets you handle specific versions of the tooling for each of your projects +MOCHA=node_modules/.bin/mocha +ISTANBUL=node_modules/.bin/istanbul +JSHINT=node_modules/.bin/jshint + +# test files must end with ".test.js" +TESTS=$(shell find test/ -name "*.test.js") + +_MOCHA="node_modules/.bin/_mocha" +coverage: + @# check if reports folder exists, if not create it + @test -d reports || mkdir reports + $(ISTANBUL) cover --report lcovonly --dir ./reports $(_MOCHA) -- -R spec --colors $(TESTS) + genhtml reports/lcov.info --output-directory reports/ + +jshint: + $(JSHINT) lib test --show-non-errors + +checkstyle: + @# check if reports folder exists, if not create it + @test -d reports || mkdir reports + $(JSHINT) lib test --reporter=checkstyle > reports/checkstyle.xml + +.PHONY: clean test coverage jshint checkstyle diff --git a/node_modules/jsftp/README.md b/node_modules/jsftp/README.md new file mode 100644 index 0000000..727c99e --- /dev/null +++ b/node_modules/jsftp/README.md @@ -0,0 +1,280 @@ +# jsftp [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![js-semistandard-style][semistandard-image]][semistandard-url] + +[travis-image]: https://img.shields.io/travis/sergi/jsftp.svg?style=flat +[travis-url]: https://travis-ci.org/sergi/jsftp +[npm-image]: https://img.shields.io/npm/v/jsftp.svg?style=flat +[npm-url]: https://npmjs.org/package/jsftp +[downloads-image]: https://img.shields.io/npm/dm/jsftp.svg?style=flat +[downloads-url]: https://npmjs.org/package/jsftp +[semistandard-image]: https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg?style=flat-square +[semistandard-url]: https://github.com/Flet/semistandard + +A client FTP library for NodeJS that focuses on correctness, clarity +and conciseness. It doesn't get in the way and plays nice with streaming APIs. + +Starting it up +-------------- + +```javascript +var JSFtp = require("jsftp"); + +var Ftp = new JSFtp({ + host: "myserver.com", + port: 3331, // defaults to 21 + user: "user", // defaults to "anonymous" + pass: "1234" // defaults to "@anonymous" +}); +``` + +jsftp gives you access to all the raw commands of the FTP protocol in form of +methods in the `Ftp` object. It also provides several convenience methods for +actions that require complex chains of commands (e.g. uploading and retrieving +files, passive operations), as shown below. + +When raw commands succeed they always pass the response of the server to the +callback, in the form of an object that contains two properties: `code`, which +is the response code of the FTP operation, and `text`, which is the complete +text of the response. + +Raw (or native) commands are accessible in the form `Ftp.raw["command"](params, callback)` + +Thus, a command like `QUIT` will be called like this: + +```javascript +Ftp.raw.quit(function(err, data) { + if (err) return console.error(err); + + console.log("Bye!"); +}); +``` + +and a command like `MKD` (make directory), which accepts parameters, looks like this: + +```javascript +Ftp.raw.mkd("/new_dir", function(err, data) { + if (err) return console.error(err); + + console.log(data.text); // Show the FTP response text to the user + console.log(data.code); // Show the FTP response code to the user +}); +``` + +API and examples +---------------- + +#### new Ftp(options) + - `options` is an object with the following properties: + + ```javascript + { + host: 'localhost', // Host name for the current FTP server. + port: 3333, // Port number for the current FTP server (defaults to 21). + user: 'user', // Username + pass: 'pass', // Password + } + ``` + +Creates a new Ftp instance. + + +#### Ftp.host + +Host name for the current FTP server. + +#### Ftp.port + +Port number for the current FTP server (defaults to 21). + +#### Ftp.socket + +NodeJS socket for the current FTP server. + +#### Ftp.features + +Array of feature names for the current FTP server. It is +generated when the user authenticates with the `auth` method. + +#### Ftp.system + +Contains the system identification string for the remote FTP server. + + +### Methods + +#### Ftp.raw(command, callback) +With the `raw` method you can send any FTP command to the server. The method accepts a callback +with the signature `err, data`, in which `err` is the error response coming +from the server (usually a 4xx or 5xx error code) and the data is an object +that contains two properties: `code` and `text`. `code` is an integer indicating +the response code of the response and `text` is the response string itself. + +#### Ftp.auth(username, password, callback) +Authenticates the user with the given username and password. If null or empty +values are passed for those, `auth` will use anonymous credentials. `callback` +will be called with the response text in case of successful login or with an +error as a first parameter, in normal Node fashion. + +#### Ftp.ls(filePath, callback) +Lists information about files or directories and yields an array of file objects +with parsed file properties to the `callback`. You should use this function +instead of `stat` or `list` in case you need to do something with the individual +file properties. + +```javascript +ftp.ls(".", function(err, res) { + res.forEach(function(file) { + console.log(file.name); + }); +}); +``` + +#### Ftp.list(filePath, callback) +Lists `filePath` contents using a passive connection. Calls callback with a +string containing the directory contents in long list format. + +```javascript +ftp.list(remoteCWD, function(err, res) { + console.log(res); + // Prints something like + // -rw-r--r-- 1 sergi staff 4 Jun 03 09:32 testfile1.txt + // -rw-r--r-- 1 sergi staff 4 Jun 03 09:31 testfile2.txt + // -rw-r--r-- 1 sergi staff 0 May 29 13:05 testfile3.txt + // ... +}); +``` + +#### Ftp.get(remotePath, callback) +Gives back a paused socket with the file contents ready to be streamed, +or calls the callback with an error if not successful. + +```javascript + var str = ""; // Will store the contents of the file + ftp.get('remote/path/file.txt', function(err, socket) { + if (err) return; + + socket.on("data", function(d) { str += d.toString(); }) + socket.on("close", function(hadErr) { + if (hadErr) + console.error('There was an error retrieving the file.'); + }); + socket.resume(); + }); +``` + +#### Ftp.get(remotePath, localPath, callback) +Stores the remote file directly in the given local path. + +```javascript + ftp.get('remote/file.txt', 'local/file.txt', function(hadErr) { + if (hadErr) + console.error('There was an error retrieving the file.'); + else + console.log('File copied successfully!'); + }); +``` + +#### Ftp.put(source, remotePath, callback) +Uploads a file to `filePath`. It accepts a string with the local path for the +file or a `Buffer` as a `source` parameter. + +```javascript +ftp.put(buffer, 'path/to/remote/file.txt', function(hadError) { + if (!hadError) + console.log("File transferred successfully!"); +}); +``` + +#### Ftp.rename(from, to, callback) +Renames a file in the server. `from` and `to` are both filepaths. + +```javascript +ftp.rename(from, to, function(err, res) { + if (!err) + console.log("Renaming successful!"); +}); +``` + +#### Ftp.keepAlive([wait]) +Refreshes the interval thats keep the server connection active. `wait` is an optional time period (in milliseconds) to wait between intervals. + +You can find more usage examples in the [unit tests](https://github.com/sergi/jsftp/blob/master/test/jsftp_test.js). This documentation +will grow as jsftp evolves. + + +Debugging +--------- + +In order to enable debug mode in a FTP connection, a `debugMode` parameter can +be used in the constructors's config object: + +```javascript +var Ftp = new JSFtp({ + host: "myserver.com", + port: 3331, + user: "user", + pass: "1234", + debugMode: true +}); +``` + +It can also be activated or deactivated by calling the `setDebugMode` method: + +```javascript +Ftp.setDebugMode(true); // Debug Mode on +Ftp.setDebugMode(false); // Debug mode off +``` + +If the debug mode is on, the jsftp instance will emit `jsftp_debug` events with +two parameters: the first is the type of the event and the second and object +including data related to the event. There are 3 possible types of events: + +- `response` events: These are response from the FTP server to the user's FTP + commands + +- `user_command` events: These are commands that the user issues to the + FTP server. + +- `event:{event name}` events: These are other events mostly related to the server + connection, such as `timeout`, `connect` or `disconnect`. For example, + a timeout event will have the name `event:timeout`. + +In order to react to print all debug events (for example), we would listen to the +debug messages like this: + +```javascript +Ftp.on('jsftp_debug', function(eventType, data) { + console.log('DEBUG: ', eventType); + console.log(JSON.stringify(data, null, 2)); +}); +``` + +Installation +------------ + + npm install jsftp + +Test coverage +------------- + +In order to run coverage reports: + + npm install --dev + make coverage + + Current overall coverage rate: + lines......: 95.5% (278 of 291 lines) + functions..: 100% (69 of 69 functions) + + +Tests +----- + +To run tests: + + npm install --dev + npm test + +License +------- + +See LICENSE. diff --git a/node_modules/jsftp/index.js b/node_modules/jsftp/index.js new file mode 100644 index 0000000..f03f905 --- /dev/null +++ b/node_modules/jsftp/index.js @@ -0,0 +1,2 @@ +var libpath = process.env['VFS_FTP_COV'] ? './lib-cov' : './lib'; +module.exports = require(libpath + "/jsftp"); diff --git a/node_modules/jsftp/lib/jsftp.js b/node_modules/jsftp/lib/jsftp.js new file mode 100644 index 0000000..b6af5f7 --- /dev/null +++ b/node_modules/jsftp/lib/jsftp.js @@ -0,0 +1,777 @@ +/* vim:set ts=2 sw=2 sts=2 expandtab */ +/*global require: true module: true */ +/* + * @package jsftp + * @copyright Copyright(c) 2012 Ajax.org B.V. + * @author Sergi Mansilla + * @license https://github.com/sergi/jsFTP/blob/master/LICENSE MIT License + */ + +'use strict'; + +var Net = require('net'); +var EventEmitter = require('events').EventEmitter; +var util = require('util'); +var fs = require('fs'); +var combine = require('stream-combiner'); + +var ResponseParser = require('ftp-response-parser'); +var ListingParser = require('parse-listing'); +var once = require('once'); +var unorm = require('unorm'); + +var debug = require('debug')('jsftp:general'); +var dbgCommand = require('debug')('jsftp:command'); +var dbgResponse = require('debug')('jsftp:response'); + +var FTP_PORT = 21; +var TIMEOUT = 10 * 60 * 1000; +var IDLE_TIME = 30000; +var NOOP = function() { }; +var COMMANDS = [ + // Commands without parameters + 'abor', 'pwd', 'cdup', 'feat', 'noop', 'quit', 'pasv', 'syst', + // Commands with one or more parameters + 'appe', 'cwd', 'dele', 'list', 'mdtm', 'mkd', 'mode', 'nlst', 'pass', 'retr', 'rmd', + 'rnfr', 'rnto', 'site', 'stat', 'stor', 'type', 'user', 'xrmd', 'opts', 'rest', + // Extended features + 'chmod', 'size', 'mlst', 'mlsd', +]; + +var expectedMarks = { + marks: [125, 150], + ignore: 226, +}; + +var RE_PASV = /([-\d]+,[-\d]+,[-\d]+,[-\d]+),([-\d]+),([-\d]+)/; +var FTP_NEWLINE = /\r\n|\n/; + +function getPasvPort(text) { + var match = RE_PASV.exec(text); + if (!match) { + return null; + } + + return { + host: match[1].replace(/,/g, '.'), + port: (parseInt(match[2], 10) & 255) * 256 + (parseInt(match[3], 10) & 255), + }; +} + +function runCmd() { + var callback = NOOP; + var args = [].slice.call(arguments); + var completeCmd = args.shift(); + + if (typeof args[args.length - 1] === 'function') { + callback = args.pop(); + } + + completeCmd += ' ' + args.join(' '); + this.execute(completeCmd.trim(), callback); +} + +var Ftp = module.exports = function(cfg) { + this.host = cfg.host || 'localhost'; + this.port = cfg.port || FTP_PORT; + this.user = cfg.user || 'anonymous'; + this.pass = cfg.pass || '@anonymous'; + // True if the server doesn't support the `stat` command. Since listing a + // directory or retrieving file properties is quite a common operation, it is + // more efficient to avoid the round-trip to the server. + this.useList = cfg.useList || false; + + this.commandQueue = []; + + EventEmitter.call(this); + + var self = this; + // Generate generic methods from parameter names. they can easily be + // overriden if we need special behavior. they accept any parameters given, + // it is the responsibility of the user to validate the parameters. + this.raw = function() { + return runCmd.apply(self, arguments); + }; + + COMMANDS.forEach(function(cmd) { + self.raw[cmd] = util.deprecate( + runCmd.bind(self, cmd), + 'Ftp.raw[' + cmd + '](args): Use Ftp.raw(\'' + cmd + ' args\') instead.'); + }); + + this.on('data', dbgResponse); + + this._createSocket(this.port, this.host); +}; + +util.inherits(Ftp, EventEmitter); + +Ftp.prototype.reemit = function(event) { + var self = this; + return function(data) { + self.emit(event, data); + debug('event:' + event, data || {}); + }; +}; + +Ftp.prototype._createSocket = function(port, host, firstAction) { + if (this.socket && this.socket.destroy) { + this.socket.destroy(); + } + + if (this.resParser) { + this.resParser.end(); + } + this.resParser = new ResponseParser(); + + this.authenticated = false; + this.socket = Net.createConnection(port, host, firstAction || NOOP); + this.socket.on('connect', this.reemit('connect')); + this.socket.on('timeout', this.reemit('timeout')); + + this.pipeline = combine(this.socket, this.resParser); + + var self = this; + + this.pipeline.on('data', function(data) { + self.emit('data', data); + dbgResponse(data.text); + self.parseResponse(data); + }); + this.pipeline.on('error', this.reemit('error')); +}; + +Ftp.prototype.parseResponse = function(response) { + if (this.commandQueue.length === 0) { + return; + } + if ([220].indexOf(response.code) > -1) { + return; + } + + var next = this.commandQueue[0].callback; + if (response.isMark) { + // If we receive a Mark and it is not expected, we ignore that command + if (!next.expectsMark || + next.expectsMark.marks.indexOf(response.code) === -1) { + return; + } + + // We might have to ignore the command that comes after the mark. + if (next.expectsMark.ignore) { + this.ignoreCmdCode = next.expectsMark.ignore; + } + } + + if (this.ignoreCmdCode === response.code) { + this.ignoreCmdCode = null; + return; + } + + this.parse(response, this.commandQueue.shift()); +}; + +/** + * Sends a new command to the server. + * + * @param {String} command Command to write in the FTP socket + */ +Ftp.prototype.send = function(command) { + if (!command) { + return; + } + + dbgCommand(command); + this.pipeline.write(command + '\r\n'); + + dbgCommand(command); +}; + +Ftp.prototype.nextCmd = function() { + var cmd = this.commandQueue[0]; + if (!this.inProgress && cmd) { + this.send(cmd.action); + this.inProgress = true; + } +}; + +/** + * Check whether the ftp user is authenticated at the moment of the + * enqueing. ideally this should happen in the `push` method, just + * before writing to the socket, but that would be complicated, + * since we would have to 'unshift' the auth chain into the queue + * or play the raw auth commands (that is, without enqueuing in + * order to not mess up the queue order. ideally, that would be + * built into the queue object. all this explanation to justify a + * slight slopiness in the code flow. + * + * @param {string} action + * @param {function} callback + */ +Ftp.prototype.execute = function(action, callback) { + if (this.socket && this.socket.writable) { + return this.runCommand(action, callback || NOOP); + } + + var self = this; + this.authenticated = false; + this._createSocket(this.port, this.host, function() { + self.runCommand(action, callback || NOOP); + }); +}; + +Ftp.prototype.runCommand = function(action, callback) { + var cmd = { + action: action, + callback: callback, + }; + + if (this.authenticated || /^(feat|syst|user|pass)/.test(action)) { + this.commandQueue.push(cmd); + this.nextCmd(); + return; + } + + var self = this; + this.getFeatures(function() { + self.auth(self.user, self.pass, function() { + self.commandQueue.push(cmd); + self.nextCmd(); + }); + }); +}; + +/** + * Parse is called each time that a comand and a request are paired + * together. That is, each time that there is a round trip of actions + * between the client and the server. + * + * @param {Object} response Response from the server (contains text and code) + * @param {Array} command Contains the command executed and a callback (if any) + */ +Ftp.prototype.parse = function(response, command) { + var err = null; + if (response.isError) { + err = new Error(response.text || 'Unknown FTP error.'); + err.code = response.code; + } + + command.callback(err, response); + this.inProgress = false; + this.nextCmd(); +}; + +/** + * Returns true if the current server has the requested feature. + * + * @param {String} feature Feature to look for + * @return {Boolean} Whether the current server has the feature + */ +Ftp.prototype.hasFeat = function(feature) { + return !!feature && this.features.indexOf(feature.toLowerCase()) > -1; +}; + +/** + * Returns an array of features supported by the current FTP server + * + * @param {String} features Server response for the 'FEAT' command + * @return {String[]} Array of feature names + */ +Ftp.prototype._parseFeats = function(features) { + // Split and ignore header and footer + var featureLines = features.split(FTP_NEWLINE).slice(1, -1); + return featureLines + .map(function(feat) { + return feat.trim().toLowerCase(); + }) + .filter(function(feat) { + return !!feat; + }); +}; + +// Below this point all the methods are action helpers for FTP that compose +// several actions in one command +Ftp.prototype.getFeatures = function(callback) { + if (this.features) { + return callback(null, this.features); + } + + var self = this; + this.raw.feat(function(err, response) { + self.features = err ? [] : self._parseFeats(response.text); + self.raw.syst(function(err, res) { + if (!err && res.code === 215) { + self.system = res.text.toLowerCase(); + } + + callback(null, self.features); + }); + }); +}; + +/** + * Authenticates the user. + * + * @param {String} user Username + * @param {String} pass Password + * @param {Function} callback Follow-up function. + */ +Ftp.prototype.auth = function(user, pass, callback) { + var self = this; + + if (this.authenticating === true) { + return callback(new Error('This client is already authenticating')); + } + + if (!user) { + user = 'anonymous'; + } + if (!pass) { + pass = '@anonymous'; + } + + this.authenticating = true; + self.raw.user(user, function(err, res) { + if (err || [230, 331, 332].indexOf(res.code) === -1) { + self.authenticating = false; + callback(err); + return; + } + self.raw.pass(pass, function(err, res) { + self.authenticating = false; + + if (err) { + callback(err); + } else if ([230, 202].indexOf(res.code) > -1) { + self.authenticated = true; + self.user = user; + self.pass = pass; + self.raw.type('I', function() { + callback(undefined, res); + }); + } else if (res.code === 332) { + self.raw.acct(''); // ACCT not really supported + } + }); + }); +}; + +Ftp.prototype.setType = function(type, callback) { + type = type.toUpperCase(); + if (this.type === type) { + return callback(); + } + + var self = this; + this.raw.type(type, function(err, data) { + if (!err) { + self.type = type; + } + + callback(err, data); + }); +}; + +/** + * Lists a folder's contents using a passive connection. + * + * @param {String} path Remote path for the file/folder to retrieve + * @param {Function} callback Function to call with errors or results + */ +Ftp.prototype.list = function(path, callback) { + if (arguments.length === 1) { + callback = arguments[0]; + path = ''; + } + + var self = this; + var listing = ''; + callback = once(callback); + + self.getPasvSocket(function(err, socket) { + if (err) { + return callback(err); + } + + socket.setEncoding('utf8'); + socket.on('data', function(data) { + listing += data; + }); + + self.pasvTimeout(socket, callback); + + socket.once('close', function(err) { + callback(err, listing); + }); + socket.once('error', callback); + + function cmdCallback(err, res) { + if (err) { + return callback(err); + } + + var isExpectedMark = expectedMarks.marks.some(function(mark) { + return mark === res.code; + }); + + if (!isExpectedMark) { + callback(new Error( + 'Expected marks ' + expectedMarks.toString() + ' instead of: ' + + res.text)); + } + } + + cmdCallback.expectsMark = expectedMarks; + + self.execute('list ' + (path || ''), cmdCallback); + }); +}; + +Ftp.prototype.emitProgress = function(data) { + this.emit('progress', { + filename: data.filename, + action: data.action, + total: data.totalSize || 0, + transferred: data.socket[data.action === 'get' ? 'bytesRead' : 'bytesWritten'] + }); +}; + +/** + * Depending on the number of parameters, returns the content of the specified + * file or directly saves a file into the specified destination. In the latter + * case, an optional callback can be provided, which will receive the error in + * case the operation was not successful. + * + * @param {String} remotePath File to be retrieved from the FTP server + * @param {Function|String} localPath Local path where we create the new file + * @param {Function} [callback] Gets called on either success or failure + */ +Ftp.prototype.get = function(remotePath, localPath, callback) { + var self = this; + var finalCallback; + + if (typeof localPath === 'function') { + finalCallback = once(localPath || NOOP); + } else { + callback = once(callback || NOOP); + finalCallback = function(err, socket) { + if (err) { + return callback(err); + } + + var writeStream = fs.createWriteStream(localPath); + writeStream.on('error', callback); + + socket.on('readable', function() { + self.emitProgress({ + filename: remotePath, + action: 'get', + socket: socket + }); + }); + + // This ensures that any expected outcome is handled. There is no + // danger of the callback being executed several times, because it is + // wrapped in `once`. + socket.on('error', callback); + socket.on('end', callback); + socket.on('close', callback); + + socket.pipe(writeStream); + }; + } + + this.getGetSocket(remotePath, finalCallback); +}; + +/** + * Returns a socket for a get (RETR) on a path. The socket is ready to be + * streamed, but it is returned in a paused state. It is left to the user to + * resume it. + * + * @param {String} path Path to the file to be retrieved + * @param {Function} callback Function to call when finalized, with the socket + * as a parameter + */ +Ftp.prototype.getGetSocket = function(path, callback) { + var self = this; + callback = once(callback); + this.getPasvSocket(function(err, socket) { + if (err) { + return cmdCallback(err); + } + + socket.on('error', function(err) { + if (err.code === 'ECONNREFUSED') { + err.msg = 'Probably trying a PASV operation while one is in progress'; + } + cmdCallback(err); + }); + + self.pasvTimeout(socket, cmdCallback); + socket.pause(); + + function cmdCallback(err, res) { + if (err) { + return callback(err); + } + + if (!socket) { + return callback(new Error('Error when retrieving PASV socket')); + } + + if (res.code === 125 || res.code === 150) { + return callback(null, socket); + } + + return callback(new Error('Unexpected command ' + res.text)); + } + + cmdCallback.expectsMark = expectedMarks; + self.execute('retr ' + path, cmdCallback); + }); +}; + +/** + * Uploads contents on a FTP server. The `from` parameter can be a Buffer or the + * path for a local file to be uploaded. + * + * @param {String|Buffer} from Contents to be uploaded. + * @param {String} to path for the remote destination. + * @param {Function} callback Function to execute on error or success. + */ +Ftp.prototype.put = function(from, to, callback) { + var self = this; + + function putReadable(from, to, totalSize, callback) { + from.on('readable', function() { + self.emitProgress({ + filename: to, + action: 'put', + socket: from, + totalSize: totalSize + }); + }); + + self.getPutSocket(to, function(err, socket) { + if (!err) { + from.pipe(socket); + } + }, callback); + } + + if (from instanceof Buffer) { + this.getPutSocket(to, function(err, socket) { + if (!err) { + socket.end(from); + } + }, callback); + } else if (typeof from === 'string') { + fs.stat(from, function(err, stats) { + if (err && err.code === 'ENOENT') { + return callback(new Error("Local file doesn't exist.")); + } + + if (stats.isDirectory()) { + return callback(new Error('Local path cannot be a directory')); + } + + var totalSize = err ? 0 : stats.size; + var localFileStream = fs.createReadStream(from, { + bufferSize: 4 * 1024 + }); + putReadable(localFileStream, to, totalSize, callback); + }); + } else { // `from` is a readable stream + putReadable(from, to, from.size, callback); + } +}; + +Ftp.prototype.getPutSocket = function(path, callback, doneCallback) { + if (!callback) { + throw new Error('A callback argument is required.'); + } + + doneCallback = once(doneCallback || NOOP); + var _callback = once(function(err, _socket) { + if (err) { + callback(err); + return doneCallback(err); + } + return callback(null, _socket); + }); + + var self = this; + this.getPasvSocket(function(err, socket) { + if (err) { + return _callback(err); + } + socket.on('close', doneCallback); + socket.on('error', doneCallback); + + var putCallback = once(function putCallback(err, res) { + if (err) { + return _callback(err); + } + + // Mark 150 indicates that the 'STOR' socket is ready to receive data. + // Anything else is not relevant. + if (res.code === 125 || res.code === 150) { + self.pasvTimeout(socket, doneCallback); + return _callback(null, socket); + } + + return _callback(new Error('Unexpected command ' + res.text)); + }); + + putCallback.expectsMark = expectedMarks; + + self.execute('stor ' + path, putCallback); + }); +}; + +Ftp.prototype.pasvTimeout = function(socket, callback) { + var self = this; + socket.once('timeout', function() { + debug('PASV socket timeout'); + self.emit('timeout'); + socket.end(); + callback(new Error('Passive socket timeout')); + }); +}; + +Ftp.prototype.getPasvSocket = function(callback) { + var self = this; + callback = once(callback || NOOP); + + this.execute('pasv', function(err, res) { + if (err) { + return callback(err); + } + + var options = getPasvPort(res.text); + if (!options) { + return callback(new Error('Bad passive host/port combination')); + } + + var socket = self._pasvSocket = Net.createConnection(options); + socket.setTimeout(self.timeout || TIMEOUT); + socket.once('close', function() { + self._pasvSocket = undefined; + }); + + callback(null, socket); + }); +}; + +/** + * Provides information about files. It lists a directory contents or + * a single file and yields an array of file objects. The file objects + * contain several properties. The main difference between this method and + * 'list' or 'stat' is that it returns objects with the file properties + * already parsed. + * + * Example of file object: + * + * { + * name: 'README.txt', + * type: 0, + * time: 996052680000, + * size: '2582', + * owner: 'sergi', + * group: 'staff', + * userPermissions: { read: true, write: true, exec: false }, + * groupPermissions: { read: true, write: false, exec: false }, + * otherPermissions: { read: true, write: false, exec: false } + * } + * + * The constants used in the object are defined in ftpParser.js + * + * @param {String} filePath Path to the file or directory to list + * @param {Function} callback Function to call with the proper data when + * the listing is finished. + */ +Ftp.prototype.ls = function(filePath, callback) { + function entriesToList(err, entries) { + if (err) { + return callback(err); + } + + ListingParser.parseFtpEntries(entries.text || entries, function(err, files) { + if (err) { + return callback(err); + } + + files.forEach(function(file) { + // Normalize UTF8 doing canonical decomposition, followed by + // canonical Composition + file.name = unorm.nfc(file.name); + }); + callback(null, files); + }); + } + + if (this.useList) { + this.list(filePath, entriesToList); + } else { + var self = this; + this.raw.stat(filePath, function(err, data) { + // We might be connected to a server that doesn't support the + // 'STAT' command, which is set as default. We use 'LIST' instead, + // and we set the variable `useList` to true, to avoid extra round + // trips to the server to check. + var errored = (err && (err.code === 502 || err.code === 500)); + var isHummingbird = self.system && self.system.indexOf('hummingbird') > -1; + if (errored || isHummingbird) { + // Not sure if the 'hummingbird' system check ^^^ is still + // necessary. If they support any standards, the 500 error + // should have us covered. Let's leave it for now. + self.useList = true; + self.list(filePath, entriesToList); + } else { + entriesToList(err, data); + } + }); + } +}; + +Ftp.prototype.rename = function(from, to, callback) { + var self = this; + this.raw.rnfr(from, function(err) { + if (err) { + return callback(err); + } + self.raw.rnto(to, callback); + }); +}; + +Ftp.prototype.keepAlive = function(wait) { + var self = this; + if (this._keepAliveInterval) { + clearInterval(this._keepAliveInterval); + } + + this._keepAliveInterval = setInterval(self.raw.noop, wait || IDLE_TIME); +}; + +Ftp.prototype.destroy = function() { + if (this._keepAliveInterval) { + clearInterval(this._keepAliveInterval); + } + + if (this.socket && this.socket.writable) { + this.socket.end(); + } + + if (this._pasvSocket && this._pasvSocket.writable) { + this._pasvSocket.end(); + } + + this.resParser.end(); + + this.socket = undefined; + this._pasvSocket = undefined; + + this.features = null; + this.authenticated = false; +}; diff --git a/node_modules/jsftp/package.json b/node_modules/jsftp/package.json new file mode 100644 index 0000000..2cc745b --- /dev/null +++ b/node_modules/jsftp/package.json @@ -0,0 +1,114 @@ +{ + "_args": [ + [ + { + "raw": "jsftp@^1.3.1", + "scope": null, + "escapedName": "jsftp", + "name": "jsftp", + "rawSpec": "^1.3.1", + "spec": ">=1.3.1 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt-ftp-deploy" + ] + ], + "_from": "jsftp@>=1.3.1 <2.0.0", + "_id": "jsftp@1.5.5", + "_inCache": true, + "_location": "/jsftp", + "_nodeVersion": "6.9.1", + "_npmOperationalInternal": { + "host": "packages-18-east.internal.npmjs.com", + "tmp": "tmp/jsftp-1.5.5.tgz_1477479952453_0.3058321129065007" + }, + "_npmUser": { + "name": "sergi", + "email": "sergi.mansilla@gmail.com" + }, + "_npmVersion": "3.10.8", + "_phantomChildren": {}, + "_requested": { + "raw": "jsftp@^1.3.1", + "scope": null, + "escapedName": "jsftp", + "name": "jsftp", + "rawSpec": "^1.3.1", + "spec": ">=1.3.1 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt-ftp-deploy" + ], + "_resolved": "https://registry.npmjs.org/jsftp/-/jsftp-1.5.5.tgz", + "_shasum": "3d034569a58221c8ffc67d088688f59d2e995cee", + "_shrinkwrap": null, + "_spec": "jsftp@^1.3.1", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt-ftp-deploy", + "author": { + "name": "Sergi Mansilla", + "email": "sergi.mansilla@gmail.com", + "url": "http://sergimansilla.com" + }, + "bugs": { + "url": "https://github.com/sergi/jsftp/issues" + }, + "dependencies": { + "debug": "^2.2.0", + "ftp-response-parser": "^1.0.1", + "once": "^1.3.3", + "parse-listing": "^1.1.3", + "stream-combiner": "^0.2.2", + "unorm": "^1.4.1" + }, + "description": "A sane FTP client implementation for NodeJS", + "devDependencies": { + "concat-stream": "^1.5.0", + "ftp-test-server": "0.0.2", + "ftpd": "^0.2.15", + "istanbul": "^0.3.22", + "mocha": "^1.21.4", + "mocha-istanbul": "0.2.0", + "rimraf": "^2.2.8", + "sinon": "^1.17.1" + }, + "directories": {}, + "dist": { + "shasum": "3d034569a58221c8ffc67d088688f59d2e995cee", + "tarball": "https://registry.npmjs.org/jsftp/-/jsftp-1.5.5.tgz" + }, + "engines": { + "node": ">=0.10" + }, + "gitHead": "e26e162e438ae0f1e6815e0ad4aa476a185a5f71", + "homepage": "https://github.com/sergi/jsftp", + "id": "jsftp", + "keywords": [ + "ftp", + "protocol", + "files", + "server", + "client", + "async" + ], + "license": "MIT", + "main": "lib/jsftp.js", + "maintainers": [ + { + "name": "sergi", + "email": "sergi.mansilla@gmail.com" + } + ], + "name": "jsftp", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sergi/jsftp.git" + }, + "scripts": { + "clean": "rm -rf reports", + "test": "mocha -R spec -t 5000" + }, + "version": "1.5.5" +} diff --git a/node_modules/jsftp/yarn.lock b/node_modules/jsftp/yarn.lock new file mode 100644 index 0000000..fd38ccd --- /dev/null +++ b/node_modules/jsftp/yarn.lock @@ -0,0 +1,676 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 +abbrev@1, abbrev@1.0.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +amdefine@>=0.0.4: + version "1.0.0" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.0.tgz#fd17474700cb5cc9c2b709f0be9d23ce3c198c33" + +argparse@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + dependencies: + sprintf-js "~1.0.2" + +async@^1.4.0, async@1.x: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +async@~0.2.6: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + +balanced-match@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + +brace-expansion@^1.0.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" + dependencies: + balanced-match "^0.4.1" + concat-map "0.0.1" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +commander@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06" + +commander@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +concat-stream@^1.5.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266" + dependencies: + inherits "~2.0.1" + readable-stream "~2.0.0" + typedarray "~0.0.5" + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +dateformat@1.0.7-1.2.3: + version "1.0.7-1.2.3" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.7-1.2.3.tgz#ebb561bb7214ee57a8dc2687adab1d555de9419c" + +debug@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + +debug@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.0.0.tgz#89bd9df6732b51256bc6705342bba02ed12131ef" + dependencies: + ms "0.6.2" + +decamelize@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +deep-is@~0.1.2, deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +diff@1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/diff/-/diff-1.0.8.tgz#343276308ec991b7bc82267ed55bc1411f971666" + +duplexer@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + +escape-string-regexp@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1" + +escodegen@1.7.x: + version "1.7.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.7.1.tgz#30ecfcf66ca98dc67cd2fd162abeb6eafa8ce6fc" + dependencies: + esprima "^1.2.2" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.5.0" + optionalDependencies: + source-map "~0.2.0" + +escodegen@1.8.x: + version "1.8.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + dependencies: + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + +esprima@^1.2.2: + version "1.2.5" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.2.5.tgz#0993502feaf668138325756f30f9a51feeec11e9" + +esprima@^2.6.0, esprima@^2.7.1, esprima@2.7.x: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + +esprima@2.5.x: + version "2.5.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.5.0.tgz#f387a46fd344c1b1a39baf8c20bfb43b6d0058cc" + +estraverse@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +fast-levenshtein@~1.0.0: + version "1.0.7" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-1.0.7.tgz#0178dcdee023b92905193af0959e8a7639cfdcb9" + +fast-levenshtein@~2.0.4: + version "2.0.5" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.5.tgz#bd33145744519ab1c36c3ee9f31f08e9079b67f2" + +fileset@0.2.x: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fileset/-/fileset-0.2.1.tgz#588ef8973c6623b2a76df465105696b96aac8067" + dependencies: + glob "5.x" + minimatch "2.x" + +formatio@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.1.1.tgz#5ed3ccd636551097383465d996199100e86161e9" + dependencies: + samsam "~1.1" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +ftp-response-parser@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ftp-response-parser/-/ftp-response-parser-1.0.1.tgz#3b9d33f8edd5fb8e4700b8f778c462e5b1581f89" + dependencies: + readable-stream "^1.0.31" + +ftp-test-server@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/ftp-test-server/-/ftp-test-server-0.0.2.tgz#38e8fdfd2772ea0a20afbffd8caf1b3f16cbd31f" + +ftpd@^0.2.15: + version "0.2.15" + resolved "https://registry.yarnpkg.com/ftpd/-/ftpd-0.2.15.tgz#877ead07ce6b5bd8b4c6e9ea270510924bbd099d" + dependencies: + dateformat "1.0.7-1.2.3" + +glob@^5.0.15, glob@5.x: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.5: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.3.tgz#e313eeb249c7affaa5c475286b0e115b59839467" + dependencies: + graceful-fs "~2.0.0" + inherits "2" + minimatch "~0.2.11" + +graceful-fs@~2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-2.0.3.tgz#7cd2cdb228a4a3f36e95efa6cc142de7d1a136d0" + +growl@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.8.1.tgz#4b2dec8d907e93db336624dcec0183502f8c9428" + +handlebars@^4.0.1: + version "4.0.5" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.5.tgz#92c6ed6bb164110c50d4d8d0fbddc70806c6f8e7" + dependencies: + async "^1.4.0" + optimist "^0.6.1" + source-map "^0.4.4" + optionalDependencies: + uglify-js "^2.6" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@~2.0.1, inherits@2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + +is-buffer@^1.0.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + +isexe@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-1.1.2.tgz#36f3e22e60750920f5e7241a476a8c6a42275ad0" + +istanbul@*: + version "0.4.5" + resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" + dependencies: + abbrev "1.0.x" + async "1.x" + escodegen "1.8.x" + esprima "2.7.x" + glob "^5.0.15" + handlebars "^4.0.1" + js-yaml "3.x" + mkdirp "0.5.x" + nopt "3.x" + once "1.x" + resolve "1.1.x" + supports-color "^3.1.0" + which "^1.1.1" + wordwrap "^1.0.0" + +istanbul@^0.3.22: + version "0.3.22" + resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.3.22.tgz#3e164d85021fe19c985d1f0e7ef0c3e22d012eb6" + dependencies: + abbrev "1.0.x" + async "1.x" + escodegen "1.7.x" + esprima "2.5.x" + fileset "0.2.x" + handlebars "^4.0.1" + js-yaml "3.x" + mkdirp "0.5.x" + nopt "3.x" + once "1.x" + resolve "1.1.x" + supports-color "^3.1.0" + which "^1.1.1" + wordwrap "^1.0.0" + +jade@0.26.3: + version "0.26.3" + resolved "https://registry.yarnpkg.com/jade/-/jade-0.26.3.tgz#8f10d7977d8d79f2f6ff862a81b0513ccb25686c" + dependencies: + commander "0.6.1" + mkdirp "0.3.0" + +js-yaml@3.x: + version "3.6.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.6.1.tgz#6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30" + dependencies: + argparse "^1.0.7" + esprima "^2.6.0" + +kind-of@^3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.0.4.tgz#7b8ecf18a4e17f8269d73b501c9f232c96887a74" + dependencies: + is-buffer "^1.0.2" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +levn@~0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.2.5.tgz#ba8d339d0ca4a610e3a3f145b9caf48807155054" + dependencies: + prelude-ls "~1.1.0" + type-check "~0.3.1" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lolex@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.3.2.tgz#7c3da62ffcb30f0f5a80a2566ca24e45d8a01f31" + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + +lru-cache@2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + +minimatch@^3.0.2, "minimatch@2 || 3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" + dependencies: + brace-expansion "^1.0.0" + +minimatch@~0.2.11: + version "0.2.14" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +minimatch@2.x: + version "2.0.10" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" + dependencies: + brace-expansion "^1.0.0" + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +mkdirp@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" + +mkdirp@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12" + dependencies: + minimist "0.0.8" + +mkdirp@0.5.x: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +mocha-istanbul@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/mocha-istanbul/-/mocha-istanbul-0.2.0.tgz#efb0b01f953115ffa6563f9cde6f4ed145d42f63" + dependencies: + istanbul "*" + +mocha@^1.21.4: + version "1.21.5" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-1.21.5.tgz#7c58b09174df976e434a23b1e8d639873fc529e9" + dependencies: + commander "2.3.0" + debug "2.0.0" + diff "1.0.8" + escape-string-regexp "1.0.2" + glob "3.2.3" + growl "1.8.1" + jade "0.26.3" + mkdirp "0.5.0" + +ms@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.6.2.tgz#d89c2124c6fdc1353d65a8b77bf1aac4b193708c" + +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + +nopt@3.x: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + dependencies: + abbrev "1" + +once@^1.3.0, once@^1.3.3, once@1.x: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +optionator@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.5.0.tgz#b75a8995a2d417df25b6e4e3862f50aa88651368" + dependencies: + deep-is "~0.1.2" + fast-levenshtein "~1.0.0" + levn "~0.2.5" + prelude-ls "~1.1.1" + type-check "~0.3.1" + wordwrap "~0.0.2" + +optionator@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +parse-listing@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/parse-listing/-/parse-listing-1.1.3.tgz#aa546f57fdc129cfbf9945cd4b757b14b06182dd" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +prelude-ls@~1.1.0, prelude-ls@~1.1.1, prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +readable-stream@^1.0.31: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~2.0.0: + version "2.0.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +resolve@1.1.x: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + +rimraf@^2.2.8: + version "2.5.4" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04" + dependencies: + glob "^7.0.5" + +samsam@~1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.3.tgz#9f5087419b4d091f232571e7fa52e90b0f552621" + +samsam@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.2.tgz#bec11fdc83a9fda063401210e40176c3024d1567" + +sigmund@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + +sinon@^1.17.1: + version "1.17.6" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-1.17.6.tgz#a43116db59577c8296356afee13fafc2332e58e1" + dependencies: + formatio "1.1.1" + lolex "1.3.2" + samsam "1.1.2" + util ">=0.10.3 <1" + +source-map@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + dependencies: + amdefine ">=0.0.4" + +source-map@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + dependencies: + amdefine ">=0.0.4" + +source-map@~0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +stream-combiner: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858" + dependencies: + duplexer "~0.1.1" + through "~2.3.4" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + +supports-color@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" + dependencies: + has-flag "^1.0.0" + +through@~2.3.4: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +type-check@~0.3.1, type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +typedarray@~0.0.5: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +uglify-js@^2.6: + version "2.7.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.7.4.tgz#a295a0de12b6a650c031c40deb0dc40b14568bd2" + dependencies: + async "~0.2.6" + source-map "~0.5.1" + uglify-to-browserify "~1.0.0" + yargs "~3.10.0" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + +unorm@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.4.1.tgz#364200d5f13646ca8bcd44490271335614792300" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +"util@>=0.10.3 <1": + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + dependencies: + inherits "2.0.1" + +which@^1.1.1: + version "1.2.11" + resolved "https://registry.yarnpkg.com/which/-/which-1.2.11.tgz#c8b2eeea6b8c1659fa7c1dd4fdaabe9533dc5e8b" + dependencies: + isexe "^1.1.1" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + +wordwrap@^1.0.0, wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" + diff --git a/node_modules/jshint/CHANGELOG.md b/node_modules/jshint/CHANGELOG.md new file mode 100644 index 0000000..8bdca22 --- /dev/null +++ b/node_modules/jshint/CHANGELOG.md @@ -0,0 +1,1132 @@ + +## [2.9.4](https://github.com/jshint/jshint/compare/2.9.3...v2.9.4) (2016-10-20) + + +### Bug Fixes + +* Allow RegExp literal as `yield` operand (#3011) ([b646aea](https://github.com/jshint/jshint/commit/b646aea)) +* Allow W100 to be ignored during lookahead ([a2b3881](https://github.com/jshint/jshint/commit/a2b3881)), closes [#3013](https://github.com/jshint/jshint/issues/3013) +* Avoid crashing on invalid input (#3046) ([bec152c](https://github.com/jshint/jshint/commit/bec152c)) +* Correct interpretation of ASI (#3045) ([9803e11](https://github.com/jshint/jshint/commit/9803e11)) +* Do not duplicate reported warnings/errors ([dc4a4fe](https://github.com/jshint/jshint/commit/dc4a4fe)) +* Enforce TDZ within initializer of lexical declaration [8e9d406](https://github.com/jshint/jshint/commit/8e9d406)), closes [#2637](https://github.com/jshint/jshint/issues/2637) +* Enforce TDZ within class heritage definition [8e9d406](https://github.com/jshint/jshint/commit/8e9d406)) +* Enforce TDZ within for in/of head [8e9d406](https://github.com/jshint/jshint/commit/8e9d406)), closes [#2693](https://github.com/jshint/jshint/issues/2693) +* Offset line no.s of errors from eval code ([2a31c94](https://github.com/jshint/jshint/commit/2a31c94)) +* Remove `null` value from `errors` array (#3049) ([f7eb3d7](https://github.com/jshint/jshint/commit/f7eb3d7)) +* Report error for offending token value ([3b06d01](https://github.com/jshint/jshint/commit/3b06d01)) + + + + +## [2.9.3](https://github.com/jshint/jshint/compare/2.9.2...v2.9.3) (2016-08-18) + + +### Bug Fixes + +* Add TypedArray globals for ES2015 ([ee0acab](https://github.com/jshint/jshint/commit/ee0acab)) +* Allow Expression within for-in head ([56c95d0](https://github.com/jshint/jshint/commit/56c95d0)) +* Avoid crash when peeking past end of prog (#2937) ([330d429](https://github.com/jshint/jshint/commit/330d429)) +* Correct behavior of singleGroups (#2951) ([97fefb7](https://github.com/jshint/jshint/commit/97fefb7)) +* Correct interpretation of ASI (#2977) ([3ef7a03](https://github.com/jshint/jshint/commit/3ef7a03)) +* Correctly recognize asi after directives ([039ee2e](https://github.com/jshint/jshint/commit/039ee2e)), closes [#2714](https://github.com/jshint/jshint/issues/2714) +* Disallow Import declarations below top lvl ([d800e44](https://github.com/jshint/jshint/commit/d800e44)) +* Support `y` RegExp flag in ES2015 code (#2999) ([a801433](https://github.com/jshint/jshint/commit/a801433)) +* Support semicolons within arrow fn params (#3003) ([179a9d6](https://github.com/jshint/jshint/commit/179a9d6)) + +### Features + +* Error for literals on rhs of `instanceof` ([e3e745b](https://github.com/jshint/jshint/commit/e3e745b)), closes [#2777](https://github.com/jshint/jshint/issues/2777) + + + + +## [2.9.2](https://github.com/jshint/jshint/compare/2.9.1...v2.9.2) (2016-04-19) + +This release contains a number of bug fixes. As always, we thank everyone who +reported issues and submitted patches; those contributions are essential to the +continuing improvement of the project. We hope you'll keep it up! + +### Bug Fixes + +* (cli - extract) lines can end with "\\r\\n", not "\\n\\r" ([93818f3](https://github.com/jshint/jshint/commit/93818f3)), closes [#2825](https://github.com/jshint/jshint/issues/2825) +* Account for implied closures ([c3b4d63](https://github.com/jshint/jshint/commit/c3b4d63)) +* Add CompositionEvent to browser globals ([56515cf](https://github.com/jshint/jshint/commit/56515cf)) +* Allow destructuring in setter parameter ([97d0ac1](https://github.com/jshint/jshint/commit/97d0ac1)) +* Allow parentheses around object destructuring assignment. ([7a0bd70](https://github.com/jshint/jshint/commit/7a0bd70)), closes [#2775](https://github.com/jshint/jshint/issues/2775) +* Allow regex inside template literal ([5dd9c90](https://github.com/jshint/jshint/commit/5dd9c90)), closes [#2791](https://github.com/jshint/jshint/issues/2791) +* Allow regexp literal after 'instanceof' ([caa30e6](https://github.com/jshint/jshint/commit/caa30e6)), closes [#2773](https://github.com/jshint/jshint/issues/2773) +* Correct CLI's indentation offset logic ([47daf76](https://github.com/jshint/jshint/commit/47daf76)), closes [#2778](https://github.com/jshint/jshint/issues/2778) +* Do not crash on invalid input ([2e0026f](https://github.com/jshint/jshint/commit/2e0026f)) +* Do not fail on valid configurations ([2fb3c24](https://github.com/jshint/jshint/commit/2fb3c24)) +* Don't throw E056 for vars used in two functions ([fd91d4a](https://github.com/jshint/jshint/commit/fd91d4a)), closes [#2838](https://github.com/jshint/jshint/issues/2838) +* Emit correct token value from "module" API ([4a43fb9](https://github.com/jshint/jshint/commit/4a43fb9)) +* Expand forms accepted in dstr. assignment ([8bbd537](https://github.com/jshint/jshint/commit/8bbd537)) +* Improve binding power for tagged templates ([9cf2ff0](https://github.com/jshint/jshint/commit/9cf2ff0)) +* Improve reporting of "Bad assignment." ([08df19e](https://github.com/jshint/jshint/commit/08df19e)) +* Make the 'freeze' option less strict ([b76447c](https://github.com/jshint/jshint/commit/b76447c)), closes [#1600](https://github.com/jshint/jshint/issues/1600) +* Report "Bad assignment." in destructuring ([fe559ed](https://github.com/jshint/jshint/commit/fe559ed)) +* Report character position for camelcase errors ([480252a](https://github.com/jshint/jshint/commit/480252a)), closes [#2845](https://github.com/jshint/jshint/issues/2845) +* Reserve `await` keyword in ES6 module code ([b1c8d5b](https://github.com/jshint/jshint/commit/b1c8d5b)) + + + +## [2.9.1](https://github.com/jshint/jshint/compare/2.9.1-rc3...v2.9.1) (2016-01-14) + +Following the revocation of version 2.9.0, we observed an extended "release +candidate" phase where we encouraged users to vet JSHint for undesirable +changes in behavior. During that time, we identified and resolved a number of +such regressions. This release comprises all changes from the release candidate +phase along with the improvements initially released as version 2.9.0. This +release does not itself contain any changes to the codebase. If you are +upgrading from version 2.8.0 or earlier, please refer to the +previously-published release notes for details on bug fixes and features--these +can be found in the project's `CHANGELOG.md` file and on the project's website. + + + +## [2.9.1-rc3](https://github.com/jshint/jshint/compare/2.9.1-rc2...v2.9.1-rc3) (2016-01-12) + + +### Bug Fixes + +* Do not require global USD for any envs ([3fa9ece](https://github.com/jshint/jshint/commit/3fa9ece)) + + + + +## [2.9.1-rc2](https://github.com/jshint/jshint/compare/2.9.1-rc1...v2.9.1-rc2) (2015-12-22) + + +### Bug Fixes + +* Abort in the presence of invalid config ([767c47d](https://github.com/jshint/jshint/commit/767c47d)) +* Allow ignoring W020 and W021 ([46db923](https://github.com/jshint/jshint/commit/46db923)), closes [#2761](https://github.com/jshint/jshint/issues/2761) +* Correct `unused` for function-scoped vars ([91fa9fc](https://github.com/jshint/jshint/commit/91fa9fc)) +* Disallow ambiguous configuration values ([eb54a4c](https://github.com/jshint/jshint/commit/eb54a4c)) +* Do not disable ES6 when `moz` is set ([97dfd90](https://github.com/jshint/jshint/commit/97dfd90)) +* Don't throw '(NaN% scanned)' ([903b698](https://github.com/jshint/jshint/commit/903b698)) + + + + +## [2.9.1-rc1](https://github.com/jshint/jshint/compare/2.9.0...v2.9.1-rc1) (2015-11-12) + +Version 2.9.0 was revoked shortly after its release due to a number of +regressions. Although the underlying issues have been resolved, we are +sensitive to the possibility that there may be still more; as mentioned in +2.9.0's release notes, the variable tracking system saw a significant +refactoring. + +In an effort to minimize friction with a new version, we're publishing a +release candidate and requesting feedback from early adopters. Please give it a +try in your projects and let us know about any surprising behavior! + +### Bug Fixes + +* `latedef` shouldn't warn when marking a var as exported ([c630994](https://github.com/jshint/jshint/commit/c630994)), closes [#2662](https://github.com/jshint/jshint/issues/2662) +* Add `File` and `FileList` to browser global variables ([7f2a729](https://github.com/jshint/jshint/commit/7f2a729)), closes [#2690](https://github.com/jshint/jshint/issues/2690) +* Allow comments and new lines after /* falls through */ ([3b1c925](https://github.com/jshint/jshint/commit/3b1c925)), closes [#2652](https://github.com/jshint/jshint/issues/2652) [#1660](https://github.com/jshint/jshint/issues/1660) +* Allow let and const to be in a block outside of a block ([84a9145](https://github.com/jshint/jshint/commit/84a9145)), closes [#2685](https://github.com/jshint/jshint/issues/2685) +* Always warn about missing "use strict" directive ([e85c2a1](https://github.com/jshint/jshint/commit/e85c2a1)), closes [#2668](https://github.com/jshint/jshint/issues/2668) +* Disallow incompatible option values ([72ba5ad](https://github.com/jshint/jshint/commit/72ba5ad)) +* Do not enable `newcap` within strict mode ([acaf3f7](https://github.com/jshint/jshint/commit/acaf3f7)) +* Don't throw W080 when the initializer starts with `undefined` ([0d87919](https://github.com/jshint/jshint/commit/0d87919)), closes [#2699](https://github.com/jshint/jshint/issues/2699) +* Don't warn that an exported function is used before it is defined. ([d0433d2](https://github.com/jshint/jshint/commit/d0433d2)), closes [#2658](https://github.com/jshint/jshint/issues/2658) +* Enforce Identifier restrictions lazily ([ceca549](https://github.com/jshint/jshint/commit/ceca549)) +* Global "use strict" regressions ([04b43d2](https://github.com/jshint/jshint/commit/04b43d2)), closes [#2657](https://github.com/jshint/jshint/issues/2657) [#2661](https://github.com/jshint/jshint/issues/2661) +* Support property assignment when destructure assigning ([b6df1f2](https://github.com/jshint/jshint/commit/b6df1f2)), closes [#2659](https://github.com/jshint/jshint/issues/2659) [#2660](https://github.com/jshint/jshint/issues/2660) +* Throw W119 instead of "Unexpected '`'" when using templates in ES5 mode. ([87064e8](https://github.com/jshint/jshint/commit/87064e8)) + +### Features + +* Support QUnit's global notOk ([73ac9b8](https://github.com/jshint/jshint/commit/73ac9b8)) + + + + +# [2.9.0](https://github.com/jshint/jshint/compare/2.8.0...v2.9.0) (2015-09-03) + +**Note** This release was revoked shortly following its publication. Please +refer to the release notes for version 2.9.1 for more information (found in the +project's `CHANGELOG.md` file and on the project's website). + +This release was a long time in the making, but it may not be the most exciting +version we've published. Most of the changes are internal refactorings that +were necessary to properly fix bugs. And fix bugs we did! Special thanks go to +Luke Page, the newest addition to the JSHint team. Luke is a maintainer of [the +Less CSS project](http://lesscss.org/), and he introduced himself to use by +overhauling JSHint's variable tracking logic. + +JSHint 3.0 is closer than ever. We're excited for the opportunity to break a +few things in order to make real strides forward. In fact, the hardest part +will be *limiting* ourselves (we don't want to make migrating to the new +version onerous). If you have any ideas along these lines, please submit them +on [the project's issue tracker](https://github.com/jshint/jshint/issues). +We'll mark them with [the label "Breaking +Change"](https://github.com/jshint/jshint/labels/Breaking%20Change), and as we +decide what's definitely "in" for 3.0, we'll add them to [the "v3.0.0" +milestone](https://github.com/jshint/jshint/milestones/v3.0.0). + +### Bug Fixes + +* Add `HTMLCollection` to browser environment. ([e92d375](https://github.com/jshint/jshint/commit/e92d375)), closes [#2443](https://github.com/jshint/jshint/issues/2443) +* Add `window.performance` to browser vars ([3ff1b05](https://github.com/jshint/jshint/commit/3ff1b05)), closes [#2461](https://github.com/jshint/jshint/issues/2461) +* Allow `__proto__` when using ES6 ([06b5764](https://github.com/jshint/jshint/commit/06b5764)), closes [#2371](https://github.com/jshint/jshint/issues/2371) +* Allow binary and octal numbers, and templates when using inline `esnext` ([b5ba7d6](https://github.com/jshint/jshint/commit/b5ba7d6)), closes [#2519](https://github.com/jshint/jshint/issues/2519) +* Allow default values in destructuring. ([04ace9a](https://github.com/jshint/jshint/commit/04ace9a)), closes [#1941](https://github.com/jshint/jshint/issues/1941) +* Allow destructuring in catch blocks parameter ([759644c](https://github.com/jshint/jshint/commit/759644c)), closes [#2526](https://github.com/jshint/jshint/issues/2526) +* Allow latedef in the initialiser of variable ([18f8775](https://github.com/jshint/jshint/commit/18f8775)), closes [#2628](https://github.com/jshint/jshint/issues/2628) +* Allow line breaking after yield if `asi: true` ([728c84b](https://github.com/jshint/jshint/commit/728c84b)), closes [#2530](https://github.com/jshint/jshint/issues/2530) +* Allow non-identifier PropertyNames in object destructuring. ([aa8a023](https://github.com/jshint/jshint/commit/aa8a023)), closes [#2467](https://github.com/jshint/jshint/issues/2467) +* Allow object destructuring assignment ([ae48966](https://github.com/jshint/jshint/commit/ae48966)), closes [#2269](https://github.com/jshint/jshint/issues/2269) +* Allow semicolon as string value in JSON ([ab73e01](https://github.com/jshint/jshint/commit/ab73e01)) +* block scope vars dont redefine in blocks ([9e74025](https://github.com/jshint/jshint/commit/9e74025)), closes [#2438](https://github.com/jshint/jshint/issues/2438) +* Catch blocks are no longer functions ([8a864f3](https://github.com/jshint/jshint/commit/8a864f3)), closes [#2510](https://github.com/jshint/jshint/issues/2510) +* Change imported variables to be constants ([94a6779](https://github.com/jshint/jshint/commit/94a6779)), closes [#2428](https://github.com/jshint/jshint/issues/2428) +* Classes are not hoisted ([87378cc](https://github.com/jshint/jshint/commit/87378cc)), closes [#1934](https://github.com/jshint/jshint/issues/1934) +* Correct exported AssignmentExpressions ([282b40e](https://github.com/jshint/jshint/commit/282b40e)) +* Correctly parse empty destructuring ([97c188b](https://github.com/jshint/jshint/commit/97c188b)), closes [#2513](https://github.com/jshint/jshint/issues/2513) +* Correctly parse exported generators ([0604816](https://github.com/jshint/jshint/commit/0604816)), closes [#2472](https://github.com/jshint/jshint/issues/2472) +* Declare `func` as a property of `state` ([3be8d36](https://github.com/jshint/jshint/commit/3be8d36)) +* default params can't reference future arg ([bc2741c](https://github.com/jshint/jshint/commit/bc2741c)), closes [#2422](https://github.com/jshint/jshint/issues/2422) +* Define "build" module ([2f98f91](https://github.com/jshint/jshint/commit/2f98f91)) +* Define npm scripts for each test suite ([5c33ded](https://github.com/jshint/jshint/commit/5c33ded)) +* Do not accept empty values for directives ([a5bfefb](https://github.com/jshint/jshint/commit/a5bfefb)) +* Do not crash if the forin check is block ([d1cbe84](https://github.com/jshint/jshint/commit/d1cbe84)), closes [#1920](https://github.com/jshint/jshint/issues/1920) +* Do not mark `ignore` directives as special ([f14c262](https://github.com/jshint/jshint/commit/f14c262)) +* Do not parse arrays which contain `for` as array comprehensions. ([d70876c](https://github.com/jshint/jshint/commit/d70876c)), closes [#1413](https://github.com/jshint/jshint/issues/1413) +* Don't crash on uncomplete typeof expression ([a32cf50](https://github.com/jshint/jshint/commit/a32cf50)), closes [#2506](https://github.com/jshint/jshint/issues/2506) +* Don't warn when Array() is used without 'new'. ([5f88aa7](https://github.com/jshint/jshint/commit/5f88aa7)), closes [#1987](https://github.com/jshint/jshint/issues/1987) +* Dont crash when testing x == keyword if eqnull is on ([6afd373](https://github.com/jshint/jshint/commit/6afd373)), closes [#2587](https://github.com/jshint/jshint/issues/2587) +* Dont warn twice in var redeclaration ([e32e17b](https://github.com/jshint/jshint/commit/e32e17b)) +* handle no 'home' environment variables ([946af3e](https://github.com/jshint/jshint/commit/946af3e)) +* Honor `ignore` directive more consistently ([0971608](https://github.com/jshint/jshint/commit/0971608)) +* Ignore directive should ignore max line length for comments ([f2f871a](https://github.com/jshint/jshint/commit/f2f871a)), closes [#1575](https://github.com/jshint/jshint/issues/1575) +* Immediately-invoked arrow funcs' param doesn't need parentheses ([d261071](https://github.com/jshint/jshint/commit/d261071)), closes [#2351](https://github.com/jshint/jshint/issues/2351) +* Improve support for `__proto__` identifier ([925a983](https://github.com/jshint/jshint/commit/925a983)) +* It is not un-necessary to assign undefined in a loop ([e8ce9bf](https://github.com/jshint/jshint/commit/e8ce9bf)), closes [#1191](https://github.com/jshint/jshint/issues/1191) +* labeled break and continue semantics ([da66f70](https://github.com/jshint/jshint/commit/da66f70)) +* Labels shadowing within a function is a syntax error ([124e00f](https://github.com/jshint/jshint/commit/124e00f)), closes [#2419](https://github.com/jshint/jshint/issues/2419) +* Load JSHint from package root ([92acdd1](https://github.com/jshint/jshint/commit/92acdd1)) +* Make `strict: func` have precedence over env options. ([d138db8](https://github.com/jshint/jshint/commit/d138db8)) +* Param destructuring should not effect max params ([9d021ee](https://github.com/jshint/jshint/commit/9d021ee)), closes [#2183](https://github.com/jshint/jshint/issues/2183) +* Params cannot always have the same name ([9f2b64c](https://github.com/jshint/jshint/commit/9f2b64c)), closes [#2492](https://github.com/jshint/jshint/issues/2492) +* Prevent regressions in bug fix ([477d3ad](https://github.com/jshint/jshint/commit/477d3ad)) +* Regular args can come after args with default ([f2a59f1](https://github.com/jshint/jshint/commit/f2a59f1)), closes [#1779](https://github.com/jshint/jshint/issues/1779) +* Relax restriction on `module` option ([56c19a5](https://github.com/jshint/jshint/commit/56c19a5)) +* Remove bad error E048 in for loop init ([a8fc16b](https://github.com/jshint/jshint/commit/a8fc16b)), closes [#1862](https://github.com/jshint/jshint/issues/1862) +* Remove module import declaration ([1749ac0](https://github.com/jshint/jshint/commit/1749ac0)) +* Report an error when a necessary semicolon is missing ([45d8e3e](https://github.com/jshint/jshint/commit/45d8e3e)), closes [#1327](https://github.com/jshint/jshint/issues/1327) +* report line numbers of destructured params ([7d25451](https://github.com/jshint/jshint/commit/7d25451)), closes [#2494](https://github.com/jshint/jshint/issues/2494) +* Report loopfunc for all function types ([4d4cfcd](https://github.com/jshint/jshint/commit/4d4cfcd)), closes [#2153](https://github.com/jshint/jshint/issues/2153) +* singleGroups: Allow grouping for integers ([8c265ca](https://github.com/jshint/jshint/commit/8c265ca)) +* Support `new.target` ([2fbf621](https://github.com/jshint/jshint/commit/2fbf621)) +* The `__iterator__` property is deprecated. ([7780613](https://github.com/jshint/jshint/commit/7780613)) +* Unify assign operation checks. ([06eb1d2](https://github.com/jshint/jshint/commit/06eb1d2)), closes [#2589](https://github.com/jshint/jshint/issues/2589) +* use of params is not capturing loopfunc ([827e335](https://github.com/jshint/jshint/commit/827e335)) +* Warn about using `var` inside `for (...)` when `varstmt: true` ([f1ab638](https://github.com/jshint/jshint/commit/f1ab638)), closes [#2627](https://github.com/jshint/jshint/issues/2627) + +### Features + +* Add `esversion` option ([cf5a699](https://github.com/jshint/jshint/commit/cf5a699)), closes [#2124](https://github.com/jshint/jshint/issues/2124) +* Add pending to Jasmine's globals ([02790b9](https://github.com/jshint/jshint/commit/02790b9)), closes [#2154](https://github.com/jshint/jshint/issues/2154) +* Add Window constructor to browser vars ([7f5806f](https://github.com/jshint/jshint/commit/7f5806f)), closes [#2132](https://github.com/jshint/jshint/issues/2132) +* Option to assume strict mode ([8de8247](https://github.com/jshint/jshint/commit/8de8247)), closes [#924](https://github.com/jshint/jshint/issues/924) +* Support multiple files in the exclude option ([bd4ec25](https://github.com/jshint/jshint/commit/bd4ec25)) + + + + +# [2.8.0](https://github.com/jshint/jshint/compare/2.7.0...2.8.0) (2015-05-31) + + +### Bug Fixes + +* add the "fetch" global for "browser" environment ([b3b41c8](https://github.com/jshint/jshint/commit/b3b41c8)), closes [#2355](https://github.com/jshint/jshint/issues/2355) +* Allow lexer to communicate completion ([a093f78](https://github.com/jshint/jshint/commit/a093f78)) +* Distinguish between directive and mode ([51059bd](https://github.com/jshint/jshint/commit/51059bd)) +* Don't throw "Duplicate class method" with computed method names ([ab12dfb](https://github.com/jshint/jshint/commit/ab12dfb)), closes [#2350](https://github.com/jshint/jshint/issues/2350) +* Ignore unused arrow-function parameters if unused: vars ([2ea9cb0](https://github.com/jshint/jshint/commit/2ea9cb0)), closes [#2345](https://github.com/jshint/jshint/issues/2345) +* Move helper methods to `state` object ([678da76](https://github.com/jshint/jshint/commit/678da76)) +* parse `const` declarations in ForIn/Of loops ([2b673d9](https://github.com/jshint/jshint/commit/2b673d9)), closes [#2334](https://github.com/jshint/jshint/issues/2334) [#2335](https://github.com/jshint/jshint/issues/2335) +* Parse semicolons in class bodies ([58c8e64](https://github.com/jshint/jshint/commit/58c8e64)) +* Prevent regression in `enforceall` ([6afcde4](https://github.com/jshint/jshint/commit/6afcde4)) +* Relax singleGroups restrictions: arrow fns ([4a4f522](https://github.com/jshint/jshint/commit/4a4f522)) +* Relax singleGroups restrictions: IIFEs ([9f55160](https://github.com/jshint/jshint/commit/9f55160)) +* Reset generator flag for each method definition ([2444a04](https://github.com/jshint/jshint/commit/2444a04)), closes [#2388](https://github.com/jshint/jshint/issues/2388) [#2389](https://github.com/jshint/jshint/issues/2389) + +### Features + +* Implement `module` option ([290280c](https://github.com/jshint/jshint/commit/290280c)) +* support destructuring in ForIn/Of loops, lint bad ForIn/Of LHS ([c0edd9f](https://github.com/jshint/jshint/commit/c0edd9f)), closes [#2341](https://github.com/jshint/jshint/issues/2341) + + + + +# [2.7.0](https://github.com/jshint/jshint/compare/2.6.3...2.7.0) (2015-04-10) + + +### Bug Fixes + +* Accept `get` and `set` as ID properties ([2ad235c](https://github.com/jshint/jshint/commit/2ad235c)) +* allow trailing comma in ArrayBindingPattern ([3477933](https://github.com/jshint/jshint/commit/3477933)), closes [#2222](https://github.com/jshint/jshint/issues/2222) +* allow typeof symbol === "symbol" ([7f7aac2](https://github.com/jshint/jshint/commit/7f7aac2)), closes [#2241](https://github.com/jshint/jshint/issues/2241) [#2242](https://github.com/jshint/jshint/issues/2242) +* Correctly enforce maxparams:0 ([011364e](https://github.com/jshint/jshint/commit/011364e)) +* default to empty string in src/cli.js loadIgnores ([0eeba14](https://github.com/jshint/jshint/commit/0eeba14)) +* disallow 'lone' rest operator in identifier() ([dd08f85](https://github.com/jshint/jshint/commit/dd08f85)), closes [#2222](https://github.com/jshint/jshint/issues/2222) +* emit I003 more carefully and less annoyingly ([757fb73](https://github.com/jshint/jshint/commit/757fb73)), closes [#2251](https://github.com/jshint/jshint/issues/2251) +* export all names for var/let/const declarations ([3ce1267](https://github.com/jshint/jshint/commit/3ce1267)), closes [#2248](https://github.com/jshint/jshint/issues/2248) [#2253](https://github.com/jshint/jshint/issues/2253) [#2252](https://github.com/jshint/jshint/issues/2252) +* Incorrect 'Unclosed string' when the closing quote is the first character after a newline ([b804e65](https://github.com/jshint/jshint/commit/b804e65)), closes [#1532](https://github.com/jshint/jshint/issues/1532) [#1532](https://github.com/jshint/jshint/issues/1532) [#1319](https://github.com/jshint/jshint/issues/1319) +* predefine HTMLTemplateElement in browser ([231557a](https://github.com/jshint/jshint/commit/231557a)), closes [#2246](https://github.com/jshint/jshint/issues/2246) +* Prevent incorrect warnings for relations ([64f85f3](https://github.com/jshint/jshint/commit/64f85f3)) +* Relax restrictions on `singleGroups` ([896bf82](https://github.com/jshint/jshint/commit/896bf82)) +* templates are operands, not operators ([162dee6](https://github.com/jshint/jshint/commit/162dee6)), closes [#2223](https://github.com/jshint/jshint/issues/2223) [#2224](https://github.com/jshint/jshint/issues/2224) + +### Features + +* add `varstmt` enforcement option to disallow use of VariableStatements ([59396f7](https://github.com/jshint/jshint/commit/59396f7)), closes [#1549](https://github.com/jshint/jshint/issues/1549) + + + + +## [2.6.3](https://github.com/jshint/jshint/compare/2.6.2...2.6.3) (2015-02-28) + + +### Bug Fixes + +* parse trailing comma in ObjectBindingPattern ([7a2b713](https://github.com/jshint/jshint/commit/7a2b713)), closes [#2220](https://github.com/jshint/jshint/issues/2220) + + + + +## [2.6.2](https://github.com/jshint/jshint/compare/2.6.1...2.6.2) (2015-02-28) + + +### Bug Fixes + +* Disable `futurehostile` option by default ([3cbd41f](https://github.com/jshint/jshint/commit/3cbd41f)) +* Make let variables in the closure shadow predefs ([cfd2e0b](https://github.com/jshint/jshint/commit/cfd2e0b)) + + + + +## [2.6.1](https://github.com/jshint/jshint/compare/2.6.0...2.6.1) (2015-02-27) + + +### Bug Fixes + +* Allow object-literals within template strings ([4f08b74](https://github.com/jshint/jshint/commit/4f08b74)), closes [#2082](https://github.com/jshint/jshint/issues/2082) +* Correct behavior of `singleGroups` ([6003c83](https://github.com/jshint/jshint/commit/6003c83)) +* Correct token reported by `singleGroups` ([bc857f3](https://github.com/jshint/jshint/commit/bc857f3)) +* Disambiguate argument ([d75ef69](https://github.com/jshint/jshint/commit/d75ef69)) +* Do not crash on improper use of `delete` ([35df49f](https://github.com/jshint/jshint/commit/35df49f)) +* ES6 modules respect undef and unused ([438d928](https://github.com/jshint/jshint/commit/438d928)) +* Fix false positives in 'nocomma' option ([33612f8](https://github.com/jshint/jshint/commit/33612f8)) +* Handle multi-line tokens after return or yield ([5c9c7fd](https://github.com/jshint/jshint/commit/5c9c7fd)), closes [#1814](https://github.com/jshint/jshint/issues/1814) [#2142](https://github.com/jshint/jshint/issues/2142) +* Miss xdescribe/xit/context/xcontext in mocha ([8fe6610](https://github.com/jshint/jshint/commit/8fe6610)) +* Parse nested templates ([3da1eaf](https://github.com/jshint/jshint/commit/3da1eaf)), closes [#2151](https://github.com/jshint/jshint/issues/2151) [#2152](https://github.com/jshint/jshint/issues/2152) +* Permit "eval" as object key ([b5f5d5d](https://github.com/jshint/jshint/commit/b5f5d5d)) +* Prevent beginning array from being confused for JSON ([813d97a](https://github.com/jshint/jshint/commit/813d97a)) +* Refactor `doFunction` ([06b5d40](https://github.com/jshint/jshint/commit/06b5d40)) +* Remove quotmark linting for NoSubstTemplates ([7e80490](https://github.com/jshint/jshint/commit/7e80490)) +* Remove tautological condition ([f0bff58](https://github.com/jshint/jshint/commit/f0bff58)) +* remove unused var ([e69acfe](https://github.com/jshint/jshint/commit/e69acfe)), closes [#2156](https://github.com/jshint/jshint/issues/2156) +* Simulate class scope for class expr names ([ac98a24](https://github.com/jshint/jshint/commit/ac98a24)) +* Support more cases of ES6 module usage ([776ed69](https://github.com/jshint/jshint/commit/776ed69)), closes [#2118](https://github.com/jshint/jshint/issues/2118) [#2143](https://github.com/jshint/jshint/issues/2143) +* Templates can not be directives ([20ff670](https://github.com/jshint/jshint/commit/20ff670)) +* Unfollowable path in lexer. ([065961a](https://github.com/jshint/jshint/commit/065961a)) + +### Features + +* Implement new option `futurehostile` ([da52aa0](https://github.com/jshint/jshint/commit/da52aa0)) +* parse and lint tagged template literals ([4816dbd](https://github.com/jshint/jshint/commit/4816dbd)), closes [#2000](https://github.com/jshint/jshint/issues/2000) + + + + +# [2.6.0](https://github.com/jshint/jshint/compare/2.5.11...2.6.0) (2015-01-21) + + +### Bug Fixes + +* Add missing globals to browser environment ([32f02e0](https://github.com/jshint/jshint/commit/32f02e0)) +* Allow array, grouping and string form to follow spread operator in function call args. ([437655a](https://github.com/jshint/jshint/commit/437655a)), closes [#2060](https://github.com/jshint/jshint/issues/2060) [#2060](https://github.com/jshint/jshint/issues/2060) +* Correct bug in enforcement of `singleGroups` ([5fedda6](https://github.com/jshint/jshint/commit/5fedda6)), closes [#2064](https://github.com/jshint/jshint/issues/2064) +* Remove dead code ([3b5d94a](https://github.com/jshint/jshint/commit/3b5d94a)), closes [#883](https://github.com/jshint/jshint/issues/883) +* Remove dead code for parameter parsing ([a1d5817](https://github.com/jshint/jshint/commit/a1d5817)) +* Revert unnecessary commit ([a70bbda](https://github.com/jshint/jshint/commit/a70bbda)) + +### Features + +* `elision` option to relax "Extra comma" warnings ([cbfc827](https://github.com/jshint/jshint/commit/cbfc827)), closes [#2062](https://github.com/jshint/jshint/issues/2062) +* Add new Jasmine 2.1 globals to "jasmine" option ([343c45e](https://github.com/jshint/jshint/commit/343c45e)), closes [#2023](https://github.com/jshint/jshint/issues/2023) +* Support generators in class body ([ee348c3](https://github.com/jshint/jshint/commit/ee348c3)) + + +### BREAKING CHANGES + +* In projects which do not enable ES3 mode, it is now an error by default to use elision array elements, +also known as empty array elements (such as `[1, , 3, , 5]`) + + + + +## [2.5.11](https://github.com/jshint/jshint/compare/2.5.10...2.5.11) (2014-12-18) + + + + + +## [2.5.10](https://github.com/jshint/jshint/compare/2.5.9...2.5.10) (2014-11-06) + + + + + +## [2.5.9](https://github.com/jshint/jshint/compare/2.5.8...2.5.9) (2014-11-06) + + + + + +## [2.5.8](https://github.com/jshint/jshint/compare/2.5.7...2.5.8) (2014-10-29) + + + + + +## [2.5.7](https://github.com/jshint/jshint/compare/2.5.6...2.5.7) (2014-10-28) + + + + + +## [2.5.6](https://github.com/jshint/jshint/compare/2.5.5...2.5.6) (2014-09-21) + + + + + +## [2.5.5](https://github.com/jshint/jshint/compare/2.5.4...2.5.5) (2014-08-24) + + + + + +## [2.5.4](https://github.com/jshint/jshint/compare/2.5.3...2.5.4) (2014-08-18) + + + + + +## [2.5.3](https://github.com/jshint/jshint/compare/2.5.2...2.5.3) (2014-08-08) + + + + + +## [2.5.2](https://github.com/jshint/jshint/compare/2.5.1...2.5.2) (2014-07-05) + + + + + +## [2.5.1](https://github.com/jshint/jshint/compare/2.5.0...2.5.1) (2014-05-16) + + + + + +# [2.5.0](https://github.com/jshint/jshint/compare/2.4.4...2.5.0) (2014-04-02) + + + + + +## [2.4.4](https://github.com/jshint/jshint/compare/2.4.3...2.4.4) (2014-02-21) + + + + + +## [2.4.3](https://github.com/jshint/jshint/compare/2.4.2...2.4.3) (2014-01-26) + + + + + +## [2.4.2](https://github.com/jshint/jshint/compare/2.4.1...2.4.2) (2014-01-21) + + + + + +## [2.4.1](https://github.com/jshint/jshint/compare/2.4.0...2.4.1) (2014-01-03) + + + + + +# [2.4.0](https://github.com/jshint/jshint/compare/2.3.0...2.4.0) (2013-12-25) + + + + + +# [2.3.0](https://github.com/jshint/jshint/compare/2.2.0...2.3.0) (2013-10-21) + + + + + +# [2.2.0](https://github.com/jshint/jshint/compare/2.1.11...2.2.0) (2013-10-18) + + + + + +## [2.1.11](https://github.com/jshint/jshint/compare/2.1.10...2.1.11) (2013-09-20) + + + + + +## [2.1.10](https://github.com/jshint/jshint/compare/2.1.9...2.1.10) (2013-08-15) + +Thanks to [Dave Camp](https://twitter.com/campd) JSHint now supports list +comprehensions, a declarative way of transforming a list: + + [ for (i of [ 1, 2, 3 ]) i + 2 ]; // Returns [ 3, 4, 5 ] + +Note: SpiderMonkey currently implements a slightly different syntax for list +comprehensions which is also supported by JSHint. + +### Patch summary + +* [ae96e5c](https://github.com/jshint/jshint/commit/ae96e5c1e0fb6a80921c8e9bd1eba8f3c96eaaee) + Fixed [#1220](https://github.com/jshint/jshint/issues/1220/): Add typed array + option, implied by 'node' option +* [27bd241](https://github.com/jshint/jshint/commit/27bd241c17e3bedb4e4b66f44e2612e6d4ef0041) + Fixed [#1222](https://github.com/jshint/jshint/issues/1222/): Update + PhantomJS globals to 1.7 API +* [6c5a085](https://github.com/jshint/jshint/commit/6c5a08553f1fcb2bbd89220b539aa0568ff99481) + Fixed [#1216](https://github.com/jshint/jshint/issues/1216/): Support for + array comprehensions using for-of (closed #1095) +* [83374ad](https://github.com/jshint/jshint/commit/83374adb3dad7c5bf708a8f6488d023d65232660) + No issue: Remove /stable/ subdirectories +* [1a3c47f](https://github.com/jshint/jshint/commit/1a3c47fb1278159e9db2a13e41f442f92e08a099) + Fixed [#1174](https://github.com/jshint/jshint/issues/1174/): Fixed a false + positive 'destructuring assignment' warning (closed #1177) +* [303c535](https://github.com/jshint/jshint/commit/303c53555d36651285a1decc7faacd94f400b7e8) + Fixed [#1183](https://github.com/jshint/jshint/issues/1183/): Fix an issue + with debugger warning pointing to a wrong line in some cases +* [a0b7181](https://github.com/jshint/jshint/commit/a0b7181578c2f07058bd1ff4f11fc622056005a3) + No issue: Add helper programs to apply and land patches from GitHub +* [9c2b8dd](https://github.com/jshint/jshint/commit/9c2b8dd55bcc131420b6326cc56cc2863d0b268f) + Fixed [#1194](https://github.com/jshint/jshint/issues/1194/): Don't look for + a config when input is /dev/stdin +* [a17ae9e](https://github.com/jshint/jshint/commit/a17ae9ed1e01ba465487b97066fdc2ba65ce109a) + Fixed [#1189](https://github.com/jshint/jshint/issues/1189/): Support spaces + in /*global ... */ +* [dcc1251](https://github.com/jshint/jshint/commit/dcc125147455556c8fbc4d51ed59b8afa7174ff3) + Fixed [#1197](https://github.com/jshint/jshint/issues/1197/): Make Rhino + wrapper to be more consistent with NPM package. +* [96ea1a8](https://github.com/jshint/jshint/commit/96ea1a88f19681f35ca534045aa6e990a39713ca) + No issue: Split make.js into bin/build and bin/changelog +* [4ac19fa](https://github.com/jshint/jshint/commit/4ac19fa53016dfc8686d0ec882da2269aee1e964) + No issue: Move JSHint config into package.json + +**Thanks** to Rob Wu, Ryan Cannon, Dave Camp, Amir Livneh, Josh Hoff, Nikolay +S. Frantsev, Lapo Luchini, Lukas Domnick for sending patches! + + + +## [2.1.9](https://github.com/jshint/jshint/compare/2.1.8...2.1.9) (2013-08-02) + + + + + +## [2.1.8](https://github.com/jshint/jshint/compare/2.1.7...2.1.8) (2013-08-01) + + + + + +## [2.1.7](https://github.com/jshint/jshint/compare/2.1.6...2.1.7) (2013-07-29) + + + + + +## [2.1.6](https://github.com/jshint/jshint/compare/2.1.5...2.1.6) (2013-07-29) + +**UPDATE:** We just published another version, 2.1.7, which contains only one +bugfix: [#1199](https://github.com/jshint/jshint/pull/1199). + +In this release we added two new arguments to our CLI program: `exclude` which +allows you to exclude directories from linting and `prereq` which allows you to +specify a file containing declarations of the global variables used throughout +your project. In addition to that, we added support for stdin. JSHint now +follows a UNIX convention where if a given file path is a dash (`-`) the the +program reads from stdin. + +We also extended our ES6 coverage by adding support for `yield` statements and +`import/export` declarations. JSHint is still **the only** linter that can +parse most ES6 and Mozilla-specific JavaScript code. + +For more changes, see the patch summary below. + +* [004dc61](https://github.com/jshint/jshint/commit/004dc619b263449ab8e05635428f0dabc80ae9b2) + Fixed [#1178](https://github.com/jshint/jshint/issues/1178/): Changed + 'predef' to 'globals' in the example .jshintrc +* [cd69f13](https://github.com/jshint/jshint/commit/cd69f1390bd40d02b6d8dc06abddc4d744310981) + Fixed [#1187](https://github.com/jshint/jshint/issues/1187/): Explicitly + define contents of our NPM package +* [c83caf3](https://github.com/jshint/jshint/commit/c83caf33a3c867e557039433b25bb57a5be6ae5f) + Fixed [#1166](https://github.com/jshint/jshint/issues/1166/): Tweaks to + import/export support +* [537dcbd](https://github.com/jshint/jshint/commit/537dcbd4be49f5b52ede08e98b23e49bbc5e4bbc) + Fixed [#1164](https://github.com/jshint/jshint/issues/1164/): Add codes to + errors generated by quit() +* [6aed7ed](https://github.com/jshint/jshint/commit/6aed7ede44f16dc5195831fa6d85ba9c75b40394) + Fixed [#1155](https://github.com/jshint/jshint/issues/1155/): Use shelljs + option in make.js +* [87df213](https://github.com/jshint/jshint/commit/87df213d19dffc75a30f4929d9302ab2e653e332) + Fixed [#1153](https://github.com/jshint/jshint/issues/1153/): Moved E037 and + E038 to the warnings section and changed their message. +* [dd060c7](https://github.com/jshint/jshint/commit/dd060c7373971cac2a965deee38d72ff5214d417) + Fixed [#779](https://github.com/jshint/jshint/issues/779/): Add support for + !pattern in the .jshintignore files +* [5de09c4](https://github.com/jshint/jshint/commit/5de09c434a62f9a63086959fd8ddb8d8d7369d50) + Fixed [#696](https://github.com/jshint/jshint/issues/696/): Add support for + `--exclude` arg +* [ee3d598](https://github.com/jshint/jshint/commit/ee3d59830b0cea0d7cb814e8ac654f25d9f38f03) + Fixed [#809](https://github.com/jshint/jshint/issues/809/): Added short + options to bin/jshint where it made sense +* [b937895](https://github.com/jshint/jshint/commit/b9378950554277c9b67ad01ab537d2ca94e59294) + Fixed [#810](https://github.com/jshint/jshint/issues/810/): Made --reporter + description in -h more straightforward +* [1c70362](https://github.com/jshint/jshint/commit/1c703625e26f95f1a77263e52dbdbcc494eeed01) + Fixed [#839](https://github.com/jshint/jshint/issues/839/): Add support for + prereq files +* [28dae4b](https://github.com/jshint/jshint/commit/28dae4baf2286d6044e96851b0acf52945262bb4) + Fixed [#741](https://github.com/jshint/jshint/issues/741/): expose loadConfig + from CLI +* [b39e2ac](https://github.com/jshint/jshint/commit/b39e2acea8ad53e9d288e1ec94d829dce26dfd5e) + Followup [#687](https://github.com/jshint/jshint/issues/687/): + eqnull +* [90b733b](https://github.com/jshint/jshint/commit/90b733bcf2c13e196039d994b8d374acbd0b5c28) + Followup [#687](https://github.com/jshint/jshint/issues/687/): Use '-' as a + marker for stding +* [68db0d8](https://github.com/jshint/jshint/commit/68db0d82d11426072a28409a1101ea180fa957eb) + Fixed [#687](https://github.com/jshint/jshint/issues/687/): Allow input via + stdin +* [5924b2a](https://github.com/jshint/jshint/commit/5924b2aa5aafdf8fede525b7156bd1962f824a14) + Fixed [#1157](https://github.com/jshint/jshint/issues/1157/): Add support for + import/export. +* [729cfd7](https://github.com/jshint/jshint/commit/729cfd718cf11585bd03713d314d1367d92ac7d7) + Fixed [#1154](https://github.com/jshint/jshint/issues/1154/): Add MouseEvent + and CustomEvent browser globals +* [9782fc8](https://github.com/jshint/jshint/commit/9782fc812703e60cfee8acae347aab4dd065844b) + Fixed [#1134](https://github.com/jshint/jshint/issues/1134/): Catch reserved + words in ES3 mode. +* [87e3e6c](https://github.com/jshint/jshint/commit/87e3e6ccfb3c37417a56946dce5904742bd43311) + Fixed [#1138](https://github.com/jshint/jshint/issues/1138/): Count ternary + and or operators for complexity +* [66f3e4c](https://github.com/jshint/jshint/commit/66f3e4c13434de9c9951dfff084b438db9ed525f) + Fixed [#1133](https://github.com/jshint/jshint/issues/1133/): Make shelljs + imply node. +* [79dc812](https://github.com/jshint/jshint/commit/79dc812bfd7510e196d811653db406d2001e159f) + Fixed [#704](https://github.com/jshint/jshint/issues/704/): Add config file + support for the Rhino wrappers. +* [88c862d](https://github.com/jshint/jshint/commit/88c862df3dba9e2cfa1e44d4be909099d8306c97) + Fixed [#1109](https://github.com/jshint/jshint/issues/1109/): Parse yield + expressions. + +**Thanks** to Terry Roe, Sindre Sorhus, Thomas Boyt, Nikolay S. Frantsev, +XhmikosR, Jacob Rask, Kevin Chu, Tim Ruffles, Stephen Mathieson, Lukas Domnick, +usrbincc for sending patches! + + +## [2.1.5](https://github.com/jshint/jshint/compare/2.1.4...2.1.5) (2013-07-27) + + + + + +## [2.1.4](https://github.com/jshint/jshint/compare/2.1.3...2.1.4) (2013-06-24) + + + + + +## [2.1.3](https://github.com/jshint/jshint/compare/2.1.2...2.1.3) (2013-06-03) + + + + + +## [2.1.2](https://github.com/jshint/jshint/compare/2.1.1...2.1.2) (2013-05-22) + + + + + +## [2.1.1](https://github.com/jshint/jshint/compare/2.1.0...2.1.1) (2013-05-21) + + + + + +# [2.1.0](https://github.com/jshint/jshint/compare/2.0.1...2.1.0) (2013-05-21) + +JSHint 2.1.0 is out. This releases adds support for ES6 `class` syntax and +fixes some issues with our parser. + +* Added support for ES6 `class` syntax. + ([#1048](https://github.com/jshint/jshint/pull/1048)) +* Added support for error code in the Checkstyle reporter. + ([#1088](https://github.com/jshint/jshint/pull/1088)) +* Added support for `do` statement bodies that are not block + statements. + ([#1062](https://github.com/jshint/jshint/pull/1062)) +* Fixed issues with JSHint not parsing comma expressions correctly. + ([#1084](https://github.com/jshint/jshint/pull/1084)) +* Fixed a bug with W080 no longer pointing to relevant identifiers. + ([#1070](https://github.com/jshint/jshint/pull/1070)) +* Fixed a potential issue with Node 0.10 and Windows. + ([#1065](https://github.com/jshint/jshint/pull/1065)) +* Fixed issues with JSHint not parsing assignments in `switch` + conditionals. + ([#1064](https://github.com/jshint/jshint/pull/1064)) +* Fixed an issue with `esnext` and `moz` modes turning off the + default `es5` mode. + ([#1068](https://github.com/jshint/jshint/issues/1068)) + +**Thanks** to usrbincc, James Allardice, Iraê Carvalho, Nick Schonning and +jklein for sending patches! + + +## [2.0.1](https://github.com/jshint/jshint/compare/2.0.0...2.0.1) (2013-05-08) + + + + + +# [2.0.0](https://github.com/jshint/jshint/compare/1.1.0...2.0.0) (2013-05-08) + +**WARNING:** This release introduces backwards incompatible changes. + +JSHint 2.0.0 is out! This version hits a pretty big milestone for the project: +this is the first JSHint release for which I'm not the biggest contributor. I +personally believe this fact validates JSHint as a successful *open source* +project. And I'm extremely thankful to all you who file bug reports and send +patches—you're all awesome. + +#### EcmaScript 5 + +The first and foremost: starting with this version JSHint will assume ES5 as +the default environment. Before, JSHint was checking all the code per ES3 +specification with an option to enable ES5 mode. Now ES5 mode is the default +mode and if you want to check your code against the ES3 specification (useful +when developing for super old browsers such as Internet Explorer 6) you will +have to use `es3:true`. + +Special thanks to Rick Waldron for championing this change. + +#### Partial support for Mozilla JavaScript extensions and ES6 + +Thanks to our newest core contributor, Bernard Pratz, JSHint now has partial +support for Mozilla JavaScript extensions (`moz` option) and ES6 (`esnext` +option): + +* Destructuring assignment +* `const` +* `let` blocks and expressions +* Generators and iterators +* List comprehension +* Try/catch filters and multiple catch blocks +* Concise method declaration +* `for ... of` loops +* Fat arrows + +We have more patches in queue that add support for classes and other nifty ES6 +things. Stay tuned! + +#### CLI + +* JSHint now looks for `.jshintrc` in the directory being linted. + ([#833](https://github.com/jshint/jshint/issues/833)) +* Various cross-platform fixes for our Node CLI module. +* New public method for the CLI export that allows third-parties to hook into + the file resolution logic. + ([#741](https://github.com/jshint/jshint/issues/741)) + +#### General + +* For non-Node system we upgraded to the latest version of Browserify. This + resolves some performance issues we had with Rhino. +* Added SVG globals to the browser environment. +* Option `smarttabs` now ignores mixed tabs and spaces within single- + and multi-line comments. +* Added a new pragma to unignore a warning: + + /*jshint -W096 */ + + // All warnings about keys producing unexpected results will + // be ignored here. + + /*jshint +W096 */ + + // But not here. + +* JSHint now ignores unrecognized JSLint options. +* Fixed a bug where `indent:false` was triggering indentation warnings. + ([#1035](https://github.com/jshint/jshint/issues/1035)) +* Fixed a regression bug where `unused` was not behaving correctly. + ([#996](https://github.com/jshint/jshint/issues/996)) +* Plus lots and lots of other, smaller bug fixes. + +#### New rapid release schedule + +And last but not least: starting with this version, I'm switching JSHint to a +more rapid release schedule. This simply means that I will be publishing new +versions of JSHint more often. I will try my best to follow +[semver](http://semver.org/) recommendations and ship working software. But as +our license says, no guarantees. + +**Thanks** to Bernarnd Pratz, Michelle Steigerwalt, Yuya Tanaka, Matthew +Flaschen, Juan Pablo Buritica, Matt Cheely, Steve Mosley, Stephen Sorensen, +Rick Waldron, Hugues Malphettes, Jeff Thompson, xzyfer, Lee Leathers, croensch, +Steven Benner, James Allardice, Sindre Sorhus, Jordan Harband, Stuart Knightley +and Kevin Locke for sending patches! + + +# [1.1.0](https://github.com/jshint/jshint/compare/1.0.0...1.1.0) (2013-03-06) + + + + + +# [1.0.0](https://github.com/jshint/jshint/compare/1.0.0-rc4...1.0.0) (2013-01-30) + + + + + +# [1.0.0-rc4](https://github.com/jshint/jshint/compare/1.0.0-rc3...1.0.0-rc4) (2013-01-18) + +JSHint 1.0.0 Release Candidate 4 is now out: + +* Fixes a bug with JSHint not allowing reserved words to be used as property + names. ([#768](https://github.com/jshint/jshint/issues/768)) +* Fixes a bug with JSHint lexer not recognizing `/` after `]`. + ([#803](https://github.com/jshint/jshint/issues/803)) +* Fixes a bug with JSHint not recognizing `predef` when its value is an array, + and not an object. ([#800](https://github.com/jshint/jshint/issues/800)) +* Fixes a bug with JSHint crashing on unrecoverable syntax errors such as + `if (name <) {}`. ([#818](https://github.com/jshint/jshint/issues/818)) + +Here's how you can install this release candidate: + + $ npm install https://github.com/jshint/jshint/archive/1.0.0-rc4.tar.gz + +For full 1.0.0 changelog please see our +[1.0.0 RC1 announcement](http://jshint.com/blog/2012-12-29/1-0-0-rc1/). + + +# [1.0.0-rc3](https://github.com/jshint/jshint/compare/1.0.0-rc2...1.0.0-rc3) (2013-01-02) + +JSHint 1.0.0 Release Candidate 3 is now out: + +* Fixes a bug with JSHint not allowing `new` and `debugger` to + appear after a comma. ([#793](https://github.com/jshint/jshint/issues/793)) +* Fixes a bug with JSHint not collecting file recursively. + ([#794](https://github.com/jshint/jshint/issues/794)) +* Fixes a bug with JSHint crashing when future reserved words are used as + identifiers. +* Adds a newline separator between files in the CLI output. +* Fixes a bug with JSHint not parsing `/*global global:true */` correctly. + ([#795](https://github.com/jshint/jshint/issues/795)) +* Fixes a bug with JSHint crashing when files can't be found. + +Here's how you can install this release candidate: + + $ npm install https://github.com/jshint/jshint/archive/1.0.0-rc3.tar.gz + +For full 1.0.0 changelog please see our [1.0.0 RC1 +announcement](http://jshint.com/blog/2012-12-29/1-0-0-rc1/). + + +# [1.0.0-rc2](https://github.com/jshint/jshint/compare/1.0.0-rc1...1.0.0-rc2) (2012-12-31) + +JSHint 1.0.0 Release Candidate 2 is now out: + +* Fixes a bug with JSHint not recognizing regular expressions after commas. + ([#792](https://github.com/jshint/jshint/pull/792)) +* Fixes two failed tests on Windows. + ([#790](https://github.com/jshint/jshint/pull/790)) +* Fixes a bug with JSHint builder failing when there is no dist/ directory. + ([#788](https://github.com/jshint/jshint/pull/788)) +* Adds JSHint binary to *package.json* so that JSHint could be, once again, + installed and used globally as a CLI program. + ([#787](https://github.com/jshint/jshint/pull/787)) + +Here's how you can install this release candidate: + + $ npm install https://github.com/jshint/jshint/archive/1.0.0-rc2.tar.gz + +For full 1.0.0 changelog please see our +[1.0.0 RC1 announcement](http://jshint.com/blog/2012-12-29/1-0-0-rc1/). + +Big thanks to Samuel Cole for submitting patches and finding bugs! + + +# 1.0.0-rc1 (2012-12-31) + +After three months and 100+ commits, JSHint 1.0.0 is ready for release. This +is the biggest release for JSHint so far, and that's why I've decided to run it +through a release candidate phase first. I tried my best to make it as +backwards compatible as possible, but there might be a small number of +incompatibilities depending on how you use JSHint. Please keep that in mind and +test your integration before updating to 1.0.0. + +One of the biggest changes is that node-jshint is now part of the main JSHint +project, which means that there will no longer be lag time between releasing a +new version and publishing it on NPM. **Node and NPM is now the main and +recommended way of using JSHint on all platforms.** This also means that +starting with "1.0.0", JSHint will start using the +[node-semver](https://github.com/isaacs/node-semver) versioning system instead +of the old rN system. + +In addition, this version drops support for non-ES5 environments. This means +that JavaScript engines that don't support the ES5 syntax will not even parse +JSHint's source code. (For example, the online interface for JSHint will not +work in older versions of IE.) + +I'm very excited to finally release this version and I encourage everyone to +try out the release candidate and report any bugs and issues you encounter. The +full changelog is provided below, with examples and links to relevant issues. + +#### Parser + +This version has a completely rewritten lexer. Since it's no longer a giant +regexp, the new lexer is more robust and easier to read. I'd like to thank the +authors of Esprima and Traceur since I borrowed some pieces from them. + +* This version **adds support for Unicode identifiers!** + ([#301](https://github.com/jshint/jshint/issues/301) and + [#716](https://github.com/jshint/jshint/issues/716/)) + + var π = 3.1415; + +* Adds support for the comma operator. ([#56](https://github.com/jshint/jshint/issues/56/)) + JSHint now parses code like the following (note the comma in the middle + expression): + + for (var i = 0, ch; ch = channels[i], i < channels.length; i++) { + // ... + } + +* Improves support for numbers. JSHint now understands numbers with leading + dots (e.g. .12) and doesn't generate false positives on invalid numbers (e.g. + 099). In case of invalid numbers the parser still parses them but marks as + malformed and generates a nice little warning. + +* Adds support for more relaxed JSHint directive syntax. JSHint now recognizes + space between `/*` and jshint/global/etc. and allows you to use single-line + comments for directives in addition to multi-line comments: + + Before: + /*jshint strict:true */ + + Now: + /*jshint strict:true */ + /* jshint strict:true */ (note the space) + //jshint strict:true + // jshint strict:true + + One potentially breaking change is that all lists inside JSHint directives + must be separated by commas from now on. So `/*jshint strict:true undef:true + */` won't fly anymore but `/*jshint strict:true, undef:true */` will (note + the comma). + +* Adds better parser for regular expressions. Previously, JSHint would check + the grammar of regular expressions using its own internal logic. Now, JSHint + compiles the parsed expressions using the native RegExp object to check + for grammar errors. + +* Adds support for a defensive semicolon before `[`. (Ticket + [#487](https://github.com/jshint/jshint/issues/487/)) + +* Adds support for unclosed multi-line strings and removes warnings about + unnecessary escaping for `\u` and `\x` in strings. + ([#494](https://github.com/jshint/jshint/issues/494/)) + +Bug fixes: + +* Fixes a bug with JSHint not warning about reserved words being used as + variable and function declaration identifiers. (Ticket + [#744](https://github.com/jshint/jshint/issues/744/)) + +* Fixes a bug with JSHint generating a false positive *Missing whitespace...* + warning on trailing commas. + ([#363](https://github.com/jshint/jshint/issues/363/)) + +* Fixes a bug with JSHint not being able to parse regular expressions preceded + by *typeof* (e.g. `typeof /[a-z]/`) and, in some cases, \*=, /=, etc. (e.g. + `if (x /= 2) { ... }`). + ([#657](https://github.com/jshint/jshint/issues/657/)) + +#### General + +* This version adds a unique numeric code to every warning and error message + produced by JSHint. That means that you can now **ignore any warning** + produced by JSHint even when there is no corresponding option for it. You can + do that using the special minus (-) operator. For example, here's how you + ignore all messages about trailing decimal points (W047): + + /*jshint -W047 */ + + or + + JSHINT(src, { "-W047": true }); + + Keep in mind that this syntax can't be used to ignore errors. + +* Due to popular demand, this version splits *indent* and *white* options + meaning that *indent* won't imply *white* anymore. + ([#667](https://github.com/jshint/jshint/issues/667/)) + +* Changes *node* option to not assume that all programs must be running in + strict mode. ([#721](https://github.com/jshint/jshint/issues/721/)) + +* Adds new globals for the *browser* option: Element and Uint8ClampedArray. + ([#707](https://github.com/jshint/jshint/issues/707/) and + [#766](https://github.com/jshint/jshint/issues/766/)) + +* Adds new global for the *node* option: DataView. + ([#773](https://github.com/jshint/jshint/issues/773/) and + [#774](https://github.com/jshint/jshint/issues/774/)) + +* Removes option *onecase*. + +* **Adds new directive: exported**. Use `/* exported ... ` for global variables + that are defined in the current file but used elsewhere to prevent + unnecessary *X is defined but never used* warnings. As before, you need to + declare those variables as global in the other files. + + ([#726](https://github.com/jshint/jshint/issues/726/) and + [#659](https://github.com/jshint/jshint/issues/659/)) + +* Removes a warning about missing *break* before *default* when *default* is + the first switch statement + ([#490](https://github.com/jshint/jshint/issues/490/)): + + switch (name) { + default: // No warning here + doSomething(); + break; + case "JSHint": + doSomethingElse(); + } + +* Improves support for [future reserved + keywords](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Reserved_Words#Words_reserved_for_possible_future_use). + JSHint now properly recognizes future reserved keywords both for ES3 and ES5 + environments with their corresponding rules. + ([#674](https://github.com/jshint/jshint/issues/674/)) + +* Changes behavior for *hasOwnProperty* + ([#770](https://github.com/jshint/jshint/issues/770/)): + + var hasOwnProperty = ...; // No warning + var obj = { hasOwnProperty: ... }; // Warning + obj.hasOwnProperty = ...; // Warning + obj['hasOwnProperty'] = ...; // Warning + +* Adds ability to disable option *unused* per function! + ([#639](https://github.com/jshint/jshint/issues/639/)) + + // jshint unused:true + var a; // Warning + + function foo(b) { // No warning + // jshint unused:false + return 1; + } + + foo(); + +Bug fixes: + +* Adds *scope* property to critical errors. + ([#714](https://github.com/jshint/jshint/issues/714/)) +* Fixes a regression bug with option *predef* making all global variables + writeable. ([#665](https://github.com/jshint/jshint/issues/665/)) +* Fixes a bug with JSHint not warning about potential typos on `return o.a = + 1`. ([#670](https://github.com/jshint/jshint/issues/670/)) +* Fixes a bug with *implied* property containing false positive data when + option *undef* is off. ([#668](https://github.com/jshint/jshint/issues/668/)) + + +#### CLI + +* This version **removes support for the JavaScriptCore shell** due to its + limited API. Note that this doesn't mean that JSHint no longer works in + Safari, it simply means that we removed the ability to use jshint via the + command line JSC shell. + +* This version also **removes support for Windows Script Host**. WSH support + was initially added due to Node not working well on Windows but, thanks to + Microsoft engineers, this is no longer true. So everyone is encouraged to use + JSHint with Node. + +* This version relies on ES5 syntax, so if you use JSHint with Rhino, please + make sure you have the latest version: 1.7R4. + +This version includes several improvements to the Node version of JSHint: + +* Adds a new flag, `--verbose`, that changes output to display message codes: + + $ jshint --verbose my.js + my.js: line 7, col 23, Extra comma. (...) (W070) + +* Makes `--config` raise an error if it can't find provided file or if the file + is invalid JSON. ([#691](https://github.com/jshint/jshint/issues/691/)) + +Bug fixes: + +* Fixes a bug with `.jshintignore` globbing not working properly. + ([#777](https://github.com/jshint/jshint/issues/777/) and + [#692](https://github.com/jshint/jshint/issues/692/)) + +* Fixes a bug with JSHint skipping over files with no extensions. + ([#690](https://github.com/jshint/jshint/issues/690/)) + + +#### What's next? + +I plan to test this release candidate for about a week before marking it as +stable and publishing on NPM. And, at the same time, I will be updating the +documentation and the [jshint.com](http://jshint.com/) website. If you notice +any bugs or unexpected backwards-incompatible changes, please file a bug. + +**RC3 is out:** [JSHint 1.0.0 RC3](http://jshint.com/blog/2013-01-01/1-0-0-rc3/). + +Here's how you can install this release candidate: + + $ npm install https://github.com/jshint/jshint/archive/1.0.0-rc1.tar.gz + +For Rhino wrapper, you will need to clone our repo and build jshint-rhino: + + $ node make.js build + $ rhino dist/jshint-rhino.js ... + +#### Contributors + +Thanks to Bernhard K. Weisshuhn, James Allardice, Mike MacCana, Stephen Fry, +Steven Olmsted, Leith Abdulla, Eric Promislow and Vlad Gurdiga for submitting +patches! diff --git a/node_modules/jshint/LICENSE b/node_modules/jshint/LICENSE new file mode 100644 index 0000000..0e247b1 --- /dev/null +++ b/node_modules/jshint/LICENSE @@ -0,0 +1,20 @@ +Copyright 2012 Anton Kovalyov (http://jshint.com) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/jshint/README.md b/node_modules/jshint/README.md new file mode 100644 index 0000000..e3b9db8 --- /dev/null +++ b/node_modules/jshint/README.md @@ -0,0 +1,117 @@ +# JSHint, A Static Code Analysis Tool for JavaScript + +\[ [Use it online](http://jshint.com/) • +[Docs](http://jshint.com/docs/) • [FAQ](http://jshint.com/docs/faq) • +[Install](http://jshint.com/install/) • +[Contribute](http://jshint.com/contribute/) • +[Blog](http://jshint.com/blog/) • [Twitter](https://twitter.com/jshint/) \] + +[![NPM version](https://img.shields.io/npm/v/jshint.svg?style=flat)](https://www.npmjs.com/package/jshint) +[![Linux Build Status](https://img.shields.io/travis/jshint/jshint/master.svg?style=flat&label=Linux%20build)](https://travis-ci.org/jshint/jshint) +[![Windows Build status](https://img.shields.io/appveyor/ci/jshint/jshint/master.svg?style=flat&label=Windows%20build)](https://ci.appveyor.com/project/jshint/jshint/branch/master) +[![Dependency Status](https://img.shields.io/david/jshint/jshint.svg?style=flat)](https://david-dm.org/jshint/jshint) +[![devDependency Status](https://img.shields.io/david/dev/jshint/jshint.svg?style=flat)](https://david-dm.org/jshint/jshint#info=devDependencies) +[![Coverage Status](https://img.shields.io/coveralls/jshint/jshint.svg?style=flat)](https://coveralls.io/r/jshint/jshint?branch=master) + +JSHint is a community-driven tool that detects errors and potential problems in +JavaScript code. Since JSHint is so flexible, you can easily adjust it in +the environment you expect your code to execute. JSHint is open source and +will always stay this way. + +## Our goal + +The project aims to help JavaScript developers write complex programs +without worrying about typos and language gotchas. + +Any code base eventually becomes huge at some point, so simple mistakes — that +would not show themselves when written — can become show stoppers and add +extra hours of debugging. So, static code analysis tools come into play +and help developers spot such problems. JSHint scans a program written in +JavaScript and reports about commonly made mistakes and potential bugs. The +potential problem could be a syntax error, a bug due to an implicit type +conversion, a leaking variable, or something else entirely. + +Only 15% of all programs linted on [jshint.com](http://jshint.com) pass the +JSHint checks. In all other cases, JSHint finds some red flags that could've +been bugs or potential problems. + +Please note, that while static code analysis tools can spot many different kind +of mistakes, it can't detect if your program is correct, fast or has memory +leaks. You should always combine tools like JSHint with unit and functional +tests as well as with code reviews. + +## Reporting a bug + +To report a bug simply create a +[new GitHub Issue](https://github.com/jshint/jshint/issues/new) and describe +your problem or suggestion. We welcome all kinds of feedback regarding +JSHint including but not limited to: + + * When JSHint doesn't work as expected + * When JSHint complains about valid JavaScript code that works in all browsers + * When you simply want a new option or feature + +Before reporting a bug, please look around to see if there are any open or closed tickets +that discuss your issue, and remember the wisdom: pull request > bug report > tweet. + +## Who uses JSHint? + +Engineers from these companies and projects use JSHint: + +* [Mozilla](https://www.mozilla.org/) +* [Wikipedia](https://wikipedia.org/) +* [Facebook](https://facebook.com/) +* [Twitter](https://twitter.com/) +* [Bootstrap](http://getbootstrap.com/) +* [Disqus](https://disqus.com/) +* [Medium](https://medium.com/) +* [Yahoo!](https://yahoo.com/) +* [SmugMug](http://smugmug.com/) +* [jQuery](http://jquery.com/) +* [PDF.js](http://mozilla.github.io/pdf.js) +* [Coursera](http://coursera.com/) +* [Adobe Brackets](http://brackets.io/) +* [Apache Cordova](http://cordova.io/) +* [RedHat](http://redhat.com/) +* [SoundCloud](http://soundcloud.com/) +* [Nodejitsu](http://nodejitsu.com/) +* [Yelp](https://yelp.com/) +* [Voxer](http://voxer.com/) +* [EnyoJS](http://enyojs.com/) +* [QuickenLoans](http://quickenloans.com/) +* [oDesk](http://www.odesk.com/) +* [Cloud9](http://c9.io/) +* [CodeClimate](https://codeclimate.com/) +* [Pandoo TEK](http://pandootek.com/) +* [Zendesk](http://zendesk.com/) +* [Apache CouchDB](http://couchdb.apache.org/) +* [Google](https://www.google.com/) + +And many more! + +## License + +Most files are published using [the standard MIT Expat +license](https://www.gnu.org/licenses/license-list.html#Expat). One file, +however, is provided under a slightly modified version of that license. The +so-called [JSON license](https://www.gnu.org/licenses/license-list.html#JSON) +is a non-free license, and unfortunately, we can't change it due to historical +reasons. This license is included as an in-line within the file it concerns. + +## The JSHint Team + +JSHint is currently maintained by [Rick Waldron](https://github.com/rwaldron/), +[Caitlin Potter](https://github.com/caitp/), [Mike +Pennisi](https://github.com/jugglinmike/), and [Luke +Page](https://github.com/lukeapage). + +## Previous Maintainers + +Originating from the JSLint project in 2010, JSHint has been maintained by a +number of dedicated individuals. In chronological order, they are: Douglas +Crockford, Anton Kovalyov, and Mike Sherov. We appreciate their long-term +commitment! + +## Thank you! + +We really appreciate all kinds of feedback and contributions. Thanks for using and supporting JSHint! diff --git a/node_modules/jshint/bin/apply b/node_modules/jshint/bin/apply new file mode 100644 index 0000000..35724fe --- /dev/null +++ b/node_modules/jshint/bin/apply @@ -0,0 +1,6 @@ +#!/usr/bin/env node + +var shjs = require("shelljs"); +var url = "https://github.com/jshint/jshint/pull/" + process.argv[2] + ".diff"; + +shjs.exec('curl "' + url + '" | git apply'); diff --git a/node_modules/jshint/bin/build b/node_modules/jshint/bin/build new file mode 100644 index 0000000..e5ae13a --- /dev/null +++ b/node_modules/jshint/bin/build @@ -0,0 +1,38 @@ +#!/usr/bin/env node +/*jshint shelljs:true */ + +"use strict"; + +var path = require("path"); +var build = require("../scripts/build"); +require("shelljs/make"); + +var distDir = path.join(__dirname, "../dist"); + +if (!test("-e", distDir)) + mkdir(distDir); + +build("web", function(err, version, src) { + if (err) { + console.error(err); + process.exit(1); + } + + src.to(distDir + "/jshint.js"); + console.log("Built: " + version + " (web)"); +}); + +build("rhino", function(err, version, src) { + var dest; + + if (err) { + console.error(err); + process.exit(1); + } + + dest = distDir + "/jshint-rhino.js"; + chmod("+x", dest); + + src.to(dest); + console.log("Built: " + version + " (Rhino)"); +}); diff --git a/node_modules/jshint/bin/jshint b/node_modules/jshint/bin/jshint new file mode 100644 index 0000000..f56105f --- /dev/null +++ b/node_modules/jshint/bin/jshint @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +require("../src/cli.js").interpret(process.argv); diff --git a/node_modules/jshint/bin/land b/node_modules/jshint/bin/land new file mode 100644 index 0000000..4ce15fe --- /dev/null +++ b/node_modules/jshint/bin/land @@ -0,0 +1,36 @@ +#!/usr/bin/env node + +"use strict"; + +var url = "https://github.com/jshint/jshint/pull/" + process.argv[2] + ".patch"; +var https = require("https"); +var shjs = require("shelljs"); +var opts = require("url").parse(url); +var msg = process.argv[3]; + +opts.rejectUnauthorized = false; +opts.agent = new https.Agent(opts); + +https.get(opts, succ).on("error", err); + +function succ(res) { + if (res.statusCode !== 200) + return void console.log("error:", res.statusCode); + + var data = ""; + res.on("data", function (chunk) { + data += chunk.toString(); + }); + + res.on("end", function () { + data = data.split("\n"); + data = data[1].replace(/^From\:\s/, ""); + data = data.replace(/"/g, ""); + + shjs.exec("git commit -s --author=\"" + data + "\" --message=\"" + msg + "\""); + }); +} + +function err(res) { + console.log("error:", res.message); +} diff --git a/node_modules/jshint/data/ascii-identifier-data.js b/node_modules/jshint/data/ascii-identifier-data.js new file mode 100644 index 0000000..00b5c64 --- /dev/null +++ b/node_modules/jshint/data/ascii-identifier-data.js @@ -0,0 +1,22 @@ +var identifierStartTable = []; + +for (var i = 0; i < 128; i++) { + identifierStartTable[i] = + i === 36 || // $ + i >= 65 && i <= 90 || // A-Z + i === 95 || // _ + i >= 97 && i <= 122; // a-z +} + +var identifierPartTable = []; + +for (var i = 0; i < 128; i++) { + identifierPartTable[i] = + identifierStartTable[i] || // $, _, A-Z, a-z + i >= 48 && i <= 57; // 0-9 +} + +module.exports = { + asciiIdentifierStartTable: identifierStartTable, + asciiIdentifierPartTable: identifierPartTable +}; diff --git a/node_modules/jshint/data/non-ascii-identifier-part-only.js b/node_modules/jshint/data/non-ascii-identifier-part-only.js new file mode 100644 index 0000000..979a7aa --- /dev/null +++ b/node_modules/jshint/data/non-ascii-identifier-part-only.js @@ -0,0 +1,5 @@ +var str = '768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,1155,1156,1157,1158,1159,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1471,1473,1474,1476,1477,1479,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1611,1612,1613,1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1648,1750,1751,1752,1753,1754,1755,1756,1759,1760,1761,1762,1763,1764,1767,1768,1770,1771,1772,1773,1776,1777,1778,1779,1780,1781,1782,1783,1784,1785,1809,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,2027,2028,2029,2030,2031,2032,2033,2034,2035,2070,2071,2072,2073,2075,2076,2077,2078,2079,2080,2081,2082,2083,2085,2086,2087,2089,2090,2091,2092,2093,2137,2138,2139,2276,2277,2278,2279,2280,2281,2282,2283,2284,2285,2286,2287,2288,2289,2290,2291,2292,2293,2294,2295,2296,2297,2298,2299,2300,2301,2302,2304,2305,2306,2307,2362,2363,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2385,2386,2387,2388,2389,2390,2391,2402,2403,2406,2407,2408,2409,2410,2411,2412,2413,2414,2415,2433,2434,2435,2492,2494,2495,2496,2497,2498,2499,2500,2503,2504,2507,2508,2509,2519,2530,2531,2534,2535,2536,2537,2538,2539,2540,2541,2542,2543,2561,2562,2563,2620,2622,2623,2624,2625,2626,2631,2632,2635,2636,2637,2641,2662,2663,2664,2665,2666,2667,2668,2669,2670,2671,2672,2673,2677,2689,2690,2691,2748,2750,2751,2752,2753,2754,2755,2756,2757,2759,2760,2761,2763,2764,2765,2786,2787,2790,2791,2792,2793,2794,2795,2796,2797,2798,2799,2817,2818,2819,2876,2878,2879,2880,2881,2882,2883,2884,2887,2888,2891,2892,2893,2902,2903,2914,2915,2918,2919,2920,2921,2922,2923,2924,2925,2926,2927,2946,3006,3007,3008,3009,3010,3014,3015,3016,3018,3019,3020,3021,3031,3046,3047,3048,3049,3050,3051,3052,3053,3054,3055,3073,3074,3075,3134,3135,3136,3137,3138,3139,3140,3142,3143,3144,3146,3147,3148,3149,3157,3158,3170,3171,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3202,3203,3260,3262,3263,3264,3265,3266,3267,3268,3270,3271,3272,3274,3275,3276,3277,3285,3286,3298,3299,3302,3303,3304,3305,3306,3307,3308,3309,3310,3311,3330,3331,3390,3391,3392,3393,3394,3395,3396,3398,3399,3400,3402,3403,3404,3405,3415,3426,3427,3430,3431,3432,3433,3434,3435,3436,3437,3438,3439,3458,3459,3530,3535,3536,3537,3538,3539,3540,3542,3544,3545,3546,3547,3548,3549,3550,3551,3570,3571,3633,3636,3637,3638,3639,3640,3641,3642,3655,3656,3657,3658,3659,3660,3661,3662,3664,3665,3666,3667,3668,3669,3670,3671,3672,3673,3761,3764,3765,3766,3767,3768,3769,3771,3772,3784,3785,3786,3787,3788,3789,3792,3793,3794,3795,3796,3797,3798,3799,3800,3801,3864,3865,3872,3873,3874,3875,3876,3877,3878,3879,3880,3881,3893,3895,3897,3902,3903,3953,3954,3955,3956,3957,3958,3959,3960,3961,3962,3963,3964,3965,3966,3967,3968,3969,3970,3971,3972,3974,3975,3981,3982,3983,3984,3985,3986,3987,3988,3989,3990,3991,3993,3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005,4006,4007,4008,4009,4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027,4028,4038,4139,4140,4141,4142,4143,4144,4145,4146,4147,4148,4149,4150,4151,4152,4153,4154,4155,4156,4157,4158,4160,4161,4162,4163,4164,4165,4166,4167,4168,4169,4182,4183,4184,4185,4190,4191,4192,4194,4195,4196,4199,4200,4201,4202,4203,4204,4205,4209,4210,4211,4212,4226,4227,4228,4229,4230,4231,4232,4233,4234,4235,4236,4237,4239,4240,4241,4242,4243,4244,4245,4246,4247,4248,4249,4250,4251,4252,4253,4957,4958,4959,5906,5907,5908,5938,5939,5940,5970,5971,6002,6003,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,6099,6109,6112,6113,6114,6115,6116,6117,6118,6119,6120,6121,6155,6156,6157,6160,6161,6162,6163,6164,6165,6166,6167,6168,6169,6313,6432,6433,6434,6435,6436,6437,6438,6439,6440,6441,6442,6443,6448,6449,6450,6451,6452,6453,6454,6455,6456,6457,6458,6459,6470,6471,6472,6473,6474,6475,6476,6477,6478,6479,6576,6577,6578,6579,6580,6581,6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6600,6601,6608,6609,6610,6611,6612,6613,6614,6615,6616,6617,6679,6680,6681,6682,6683,6741,6742,6743,6744,6745,6746,6747,6748,6749,6750,6752,6753,6754,6755,6756,6757,6758,6759,6760,6761,6762,6763,6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,6774,6775,6776,6777,6778,6779,6780,6783,6784,6785,6786,6787,6788,6789,6790,6791,6792,6793,6800,6801,6802,6803,6804,6805,6806,6807,6808,6809,6912,6913,6914,6915,6916,6964,6965,6966,6967,6968,6969,6970,6971,6972,6973,6974,6975,6976,6977,6978,6979,6980,6992,6993,6994,6995,6996,6997,6998,6999,7000,7001,7019,7020,7021,7022,7023,7024,7025,7026,7027,7040,7041,7042,7073,7074,7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7088,7089,7090,7091,7092,7093,7094,7095,7096,7097,7142,7143,7144,7145,7146,7147,7148,7149,7150,7151,7152,7153,7154,7155,7204,7205,7206,7207,7208,7209,7210,7211,7212,7213,7214,7215,7216,7217,7218,7219,7220,7221,7222,7223,7232,7233,7234,7235,7236,7237,7238,7239,7240,7241,7248,7249,7250,7251,7252,7253,7254,7255,7256,7257,7376,7377,7378,7380,7381,7382,7383,7384,7385,7386,7387,7388,7389,7390,7391,7392,7393,7394,7395,7396,7397,7398,7399,7400,7405,7410,7411,7412,7616,7617,7618,7619,7620,7621,7622,7623,7624,7625,7626,7627,7628,7629,7630,7631,7632,7633,7634,7635,7636,7637,7638,7639,7640,7641,7642,7643,7644,7645,7646,7647,7648,7649,7650,7651,7652,7653,7654,7676,7677,7678,7679,8204,8205,8255,8256,8276,8400,8401,8402,8403,8404,8405,8406,8407,8408,8409,8410,8411,8412,8417,8421,8422,8423,8424,8425,8426,8427,8428,8429,8430,8431,8432,11503,11504,11505,11647,11744,11745,11746,11747,11748,11749,11750,11751,11752,11753,11754,11755,11756,11757,11758,11759,11760,11761,11762,11763,11764,11765,11766,11767,11768,11769,11770,11771,11772,11773,11774,11775,12330,12331,12332,12333,12334,12335,12441,12442,42528,42529,42530,42531,42532,42533,42534,42535,42536,42537,42607,42612,42613,42614,42615,42616,42617,42618,42619,42620,42621,42655,42736,42737,43010,43014,43019,43043,43044,43045,43046,43047,43136,43137,43188,43189,43190,43191,43192,43193,43194,43195,43196,43197,43198,43199,43200,43201,43202,43203,43204,43216,43217,43218,43219,43220,43221,43222,43223,43224,43225,43232,43233,43234,43235,43236,43237,43238,43239,43240,43241,43242,43243,43244,43245,43246,43247,43248,43249,43264,43265,43266,43267,43268,43269,43270,43271,43272,43273,43302,43303,43304,43305,43306,43307,43308,43309,43335,43336,43337,43338,43339,43340,43341,43342,43343,43344,43345,43346,43347,43392,43393,43394,43395,43443,43444,43445,43446,43447,43448,43449,43450,43451,43452,43453,43454,43455,43456,43472,43473,43474,43475,43476,43477,43478,43479,43480,43481,43561,43562,43563,43564,43565,43566,43567,43568,43569,43570,43571,43572,43573,43574,43587,43596,43597,43600,43601,43602,43603,43604,43605,43606,43607,43608,43609,43643,43696,43698,43699,43700,43703,43704,43710,43711,43713,43755,43756,43757,43758,43759,43765,43766,44003,44004,44005,44006,44007,44008,44009,44010,44012,44013,44016,44017,44018,44019,44020,44021,44022,44023,44024,44025,64286,65024,65025,65026,65027,65028,65029,65030,65031,65032,65033,65034,65035,65036,65037,65038,65039,65056,65057,65058,65059,65060,65061,65062,65075,65076,65101,65102,65103,65296,65297,65298,65299,65300,65301,65302,65303,65304,65305,65343'; +var arr = str.split(',').map(function(code) { + return parseInt(code, 10); +}); +module.exports = arr; \ No newline at end of file diff --git a/node_modules/jshint/data/non-ascii-identifier-start.js b/node_modules/jshint/data/non-ascii-identifier-start.js new file mode 100644 index 0000000..7b5b799 --- /dev/null +++ b/node_modules/jshint/data/non-ascii-identifier-start.js @@ -0,0 +1,5 @@ +var str = '170,181,186,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,710,711,712,713,714,715,716,717,718,719,720,721,736,737,738,739,740,748,750,880,881,882,883,884,886,887,890,891,892,893,902,904,905,906,908,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1369,1377,1378,1379,1380,1381,1382,1383,1384,1385,1386,1387,1388,1389,1390,1391,1392,1393,1394,1395,1396,1397,1398,1399,1400,1401,1402,1403,1404,1405,1406,1407,1408,1409,1410,1411,1412,1413,1414,1415,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1520,1521,1522,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1646,1647,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660,1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1749,1765,1766,1774,1775,1786,1787,1788,1791,1808,1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,1839,1869,1870,1871,1872,1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883,1884,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,1896,1897,1898,1899,1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1969,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022,2023,2024,2025,2026,2036,2037,2042,2048,2049,2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,2060,2061,2062,2063,2064,2065,2066,2067,2068,2069,2074,2084,2088,2112,2113,2114,2115,2116,2117,2118,2119,2120,2121,2122,2123,2124,2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2208,2210,2211,2212,2213,2214,2215,2216,2217,2218,2219,2220,2308,2309,2310,2311,2312,2313,2314,2315,2316,2317,2318,2319,2320,2321,2322,2323,2324,2325,2326,2327,2328,2329,2330,2331,2332,2333,2334,2335,2336,2337,2338,2339,2340,2341,2342,2343,2344,2345,2346,2347,2348,2349,2350,2351,2352,2353,2354,2355,2356,2357,2358,2359,2360,2361,2365,2384,2392,2393,2394,2395,2396,2397,2398,2399,2400,2401,2417,2418,2419,2420,2421,2422,2423,2425,2426,2427,2428,2429,2430,2431,2437,2438,2439,2440,2441,2442,2443,2444,2447,2448,2451,2452,2453,2454,2455,2456,2457,2458,2459,2460,2461,2462,2463,2464,2465,2466,2467,2468,2469,2470,2471,2472,2474,2475,2476,2477,2478,2479,2480,2482,2486,2487,2488,2489,2493,2510,2524,2525,2527,2528,2529,2544,2545,2565,2566,2567,2568,2569,2570,2575,2576,2579,2580,2581,2582,2583,2584,2585,2586,2587,2588,2589,2590,2591,2592,2593,2594,2595,2596,2597,2598,2599,2600,2602,2603,2604,2605,2606,2607,2608,2610,2611,2613,2614,2616,2617,2649,2650,2651,2652,2654,2674,2675,2676,2693,2694,2695,2696,2697,2698,2699,2700,2701,2703,2704,2705,2707,2708,2709,2710,2711,2712,2713,2714,2715,2716,2717,2718,2719,2720,2721,2722,2723,2724,2725,2726,2727,2728,2730,2731,2732,2733,2734,2735,2736,2738,2739,2741,2742,2743,2744,2745,2749,2768,2784,2785,2821,2822,2823,2824,2825,2826,2827,2828,2831,2832,2835,2836,2837,2838,2839,2840,2841,2842,2843,2844,2845,2846,2847,2848,2849,2850,2851,2852,2853,2854,2855,2856,2858,2859,2860,2861,2862,2863,2864,2866,2867,2869,2870,2871,2872,2873,2877,2908,2909,2911,2912,2913,2929,2947,2949,2950,2951,2952,2953,2954,2958,2959,2960,2962,2963,2964,2965,2969,2970,2972,2974,2975,2979,2980,2984,2985,2986,2990,2991,2992,2993,2994,2995,2996,2997,2998,2999,3000,3001,3024,3077,3078,3079,3080,3081,3082,3083,3084,3086,3087,3088,3090,3091,3092,3093,3094,3095,3096,3097,3098,3099,3100,3101,3102,3103,3104,3105,3106,3107,3108,3109,3110,3111,3112,3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3125,3126,3127,3128,3129,3133,3160,3161,3168,3169,3205,3206,3207,3208,3209,3210,3211,3212,3214,3215,3216,3218,3219,3220,3221,3222,3223,3224,3225,3226,3227,3228,3229,3230,3231,3232,3233,3234,3235,3236,3237,3238,3239,3240,3242,3243,3244,3245,3246,3247,3248,3249,3250,3251,3253,3254,3255,3256,3257,3261,3294,3296,3297,3313,3314,3333,3334,3335,3336,3337,3338,3339,3340,3342,3343,3344,3346,3347,3348,3349,3350,3351,3352,3353,3354,3355,3356,3357,3358,3359,3360,3361,3362,3363,3364,3365,3366,3367,3368,3369,3370,3371,3372,3373,3374,3375,3376,3377,3378,3379,3380,3381,3382,3383,3384,3385,3386,3389,3406,3424,3425,3450,3451,3452,3453,3454,3455,3461,3462,3463,3464,3465,3466,3467,3468,3469,3470,3471,3472,3473,3474,3475,3476,3477,3478,3482,3483,3484,3485,3486,3487,3488,3489,3490,3491,3492,3493,3494,3495,3496,3497,3498,3499,3500,3501,3502,3503,3504,3505,3507,3508,3509,3510,3511,3512,3513,3514,3515,3517,3520,3521,3522,3523,3524,3525,3526,3585,3586,3587,3588,3589,3590,3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607,3608,3609,3610,3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,3621,3622,3623,3624,3625,3626,3627,3628,3629,3630,3631,3632,3634,3635,3648,3649,3650,3651,3652,3653,3654,3713,3714,3716,3719,3720,3722,3725,3732,3733,3734,3735,3737,3738,3739,3740,3741,3742,3743,3745,3746,3747,3749,3751,3754,3755,3757,3758,3759,3760,3762,3763,3773,3776,3777,3778,3779,3780,3782,3804,3805,3806,3807,3840,3904,3905,3906,3907,3908,3909,3910,3911,3913,3914,3915,3916,3917,3918,3919,3920,3921,3922,3923,3924,3925,3926,3927,3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,3939,3940,3941,3942,3943,3944,3945,3946,3947,3948,3976,3977,3978,3979,3980,4096,4097,4098,4099,4100,4101,4102,4103,4104,4105,4106,4107,4108,4109,4110,4111,4112,4113,4114,4115,4116,4117,4118,4119,4120,4121,4122,4123,4124,4125,4126,4127,4128,4129,4130,4131,4132,4133,4134,4135,4136,4137,4138,4159,4176,4177,4178,4179,4180,4181,4186,4187,4188,4189,4193,4197,4198,4206,4207,4208,4213,4214,4215,4216,4217,4218,4219,4220,4221,4222,4223,4224,4225,4238,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265,4266,4267,4268,4269,4270,4271,4272,4273,4274,4275,4276,4277,4278,4279,4280,4281,4282,4283,4284,4285,4286,4287,4288,4289,4290,4291,4292,4293,4295,4301,4304,4305,4306,4307,4308,4309,4310,4311,4312,4313,4314,4315,4316,4317,4318,4319,4320,4321,4322,4323,4324,4325,4326,4327,4328,4329,4330,4331,4332,4333,4334,4335,4336,4337,4338,4339,4340,4341,4342,4343,4344,4345,4346,4348,4349,4350,4351,4352,4353,4354,4355,4356,4357,4358,4359,4360,4361,4362,4363,4364,4365,4366,4367,4368,4369,4370,4371,4372,4373,4374,4375,4376,4377,4378,4379,4380,4381,4382,4383,4384,4385,4386,4387,4388,4389,4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403,4404,4405,4406,4407,4408,4409,4410,4411,4412,4413,4414,4415,4416,4417,4418,4419,4420,4421,4422,4423,4424,4425,4426,4427,4428,4429,4430,4431,4432,4433,4434,4435,4436,4437,4438,4439,4440,4441,4442,4443,4444,4445,4446,4447,4448,4449,4450,4451,4452,4453,4454,4455,4456,4457,4458,4459,4460,4461,4462,4463,4464,4465,4466,4467,4468,4469,4470,4471,4472,4473,4474,4475,4476,4477,4478,4479,4480,4481,4482,4483,4484,4485,4486,4487,4488,4489,4490,4491,4492,4493,4494,4495,4496,4497,4498,4499,4500,4501,4502,4503,4504,4505,4506,4507,4508,4509,4510,4511,4512,4513,4514,4515,4516,4517,4518,4519,4520,4521,4522,4523,4524,4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,4536,4537,4538,4539,4540,4541,4542,4543,4544,4545,4546,4547,4548,4549,4550,4551,4552,4553,4554,4555,4556,4557,4558,4559,4560,4561,4562,4563,4564,4565,4566,4567,4568,4569,4570,4571,4572,4573,4574,4575,4576,4577,4578,4579,4580,4581,4582,4583,4584,4585,4586,4587,4588,4589,4590,4591,4592,4593,4594,4595,4596,4597,4598,4599,4600,4601,4602,4603,4604,4605,4606,4607,4608,4609,4610,4611,4612,4613,4614,4615,4616,4617,4618,4619,4620,4621,4622,4623,4624,4625,4626,4627,4628,4629,4630,4631,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642,4643,4644,4645,4646,4647,4648,4649,4650,4651,4652,4653,4654,4655,4656,4657,4658,4659,4660,4661,4662,4663,4664,4665,4666,4667,4668,4669,4670,4671,4672,4673,4674,4675,4676,4677,4678,4679,4680,4682,4683,4684,4685,4688,4689,4690,4691,4692,4693,4694,4696,4698,4699,4700,4701,4704,4705,4706,4707,4708,4709,4710,4711,4712,4713,4714,4715,4716,4717,4718,4719,4720,4721,4722,4723,4724,4725,4726,4727,4728,4729,4730,4731,4732,4733,4734,4735,4736,4737,4738,4739,4740,4741,4742,4743,4744,4746,4747,4748,4749,4752,4753,4754,4755,4756,4757,4758,4759,4760,4761,4762,4763,4764,4765,4766,4767,4768,4769,4770,4771,4772,4773,4774,4775,4776,4777,4778,4779,4780,4781,4782,4783,4784,4786,4787,4788,4789,4792,4793,4794,4795,4796,4797,4798,4800,4802,4803,4804,4805,4808,4809,4810,4811,4812,4813,4814,4815,4816,4817,4818,4819,4820,4821,4822,4824,4825,4826,4827,4828,4829,4830,4831,4832,4833,4834,4835,4836,4837,4838,4839,4840,4841,4842,4843,4844,4845,4846,4847,4848,4849,4850,4851,4852,4853,4854,4855,4856,4857,4858,4859,4860,4861,4862,4863,4864,4865,4866,4867,4868,4869,4870,4871,4872,4873,4874,4875,4876,4877,4878,4879,4880,4882,4883,4884,4885,4888,4889,4890,4891,4892,4893,4894,4895,4896,4897,4898,4899,4900,4901,4902,4903,4904,4905,4906,4907,4908,4909,4910,4911,4912,4913,4914,4915,4916,4917,4918,4919,4920,4921,4922,4923,4924,4925,4926,4927,4928,4929,4930,4931,4932,4933,4934,4935,4936,4937,4938,4939,4940,4941,4942,4943,4944,4945,4946,4947,4948,4949,4950,4951,4952,4953,4954,4992,4993,4994,4995,4996,4997,4998,4999,5000,5001,5002,5003,5004,5005,5006,5007,5024,5025,5026,5027,5028,5029,5030,5031,5032,5033,5034,5035,5036,5037,5038,5039,5040,5041,5042,5043,5044,5045,5046,5047,5048,5049,5050,5051,5052,5053,5054,5055,5056,5057,5058,5059,5060,5061,5062,5063,5064,5065,5066,5067,5068,5069,5070,5071,5072,5073,5074,5075,5076,5077,5078,5079,5080,5081,5082,5083,5084,5085,5086,5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102,5103,5104,5105,5106,5107,5108,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133,5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149,5150,5151,5152,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164,5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,5176,5177,5178,5179,5180,5181,5182,5183,5184,5185,5186,5187,5188,5189,5190,5191,5192,5193,5194,5195,5196,5197,5198,5199,5200,5201,5202,5203,5204,5205,5206,5207,5208,5209,5210,5211,5212,5213,5214,5215,5216,5217,5218,5219,5220,5221,5222,5223,5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,5237,5238,5239,5240,5241,5242,5243,5244,5245,5246,5247,5248,5249,5250,5251,5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267,5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283,5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331,5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347,5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363,5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379,5380,5381,5382,5383,5384,5385,5386,5387,5388,5389,5390,5391,5392,5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408,5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440,5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456,5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472,5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488,5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504,5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520,5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536,5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552,5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568,5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584,5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600,5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616,5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632,5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648,5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664,5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680,5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696,5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712,5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728,5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5743,5744,5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776,5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5792,5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808,5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856,5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5870,5871,5872,5888,5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5902,5903,5904,5905,5920,5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936,5937,5952,5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968,5969,5984,5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5998,5999,6000,6016,6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032,6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6103,6108,6176,6177,6178,6179,6180,6181,6182,6183,6184,6185,6186,6187,6188,6189,6190,6191,6192,6193,6194,6195,6196,6197,6198,6199,6200,6201,6202,6203,6204,6205,6206,6207,6208,6209,6210,6211,6212,6213,6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6229,6230,6231,6232,6233,6234,6235,6236,6237,6238,6239,6240,6241,6242,6243,6244,6245,6246,6247,6248,6249,6250,6251,6252,6253,6254,6255,6256,6257,6258,6259,6260,6261,6262,6263,6272,6273,6274,6275,6276,6277,6278,6279,6280,6281,6282,6283,6284,6285,6286,6287,6288,6289,6290,6291,6292,6293,6294,6295,6296,6297,6298,6299,6300,6301,6302,6303,6304,6305,6306,6307,6308,6309,6310,6311,6312,6314,6320,6321,6322,6323,6324,6325,6326,6327,6328,6329,6330,6331,6332,6333,6334,6335,6336,6337,6338,6339,6340,6341,6342,6343,6344,6345,6346,6347,6348,6349,6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362,6363,6364,6365,6366,6367,6368,6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379,6380,6381,6382,6383,6384,6385,6386,6387,6388,6389,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411,6412,6413,6414,6415,6416,6417,6418,6419,6420,6421,6422,6423,6424,6425,6426,6427,6428,6480,6481,6482,6483,6484,6485,6486,6487,6488,6489,6490,6491,6492,6493,6494,6495,6496,6497,6498,6499,6500,6501,6502,6503,6504,6505,6506,6507,6508,6509,6512,6513,6514,6515,6516,6528,6529,6530,6531,6532,6533,6534,6535,6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548,6549,6550,6551,6552,6553,6554,6555,6556,6557,6558,6559,6560,6561,6562,6563,6564,6565,6566,6567,6568,6569,6570,6571,6593,6594,6595,6596,6597,6598,6599,6656,6657,6658,6659,6660,6661,6662,6663,6664,6665,6666,6667,6668,6669,6670,6671,6672,6673,6674,6675,6676,6677,6678,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,6698,6699,6700,6701,6702,6703,6704,6705,6706,6707,6708,6709,6710,6711,6712,6713,6714,6715,6716,6717,6718,6719,6720,6721,6722,6723,6724,6725,6726,6727,6728,6729,6730,6731,6732,6733,6734,6735,6736,6737,6738,6739,6740,6823,6917,6918,6919,6920,6921,6922,6923,6924,6925,6926,6927,6928,6929,6930,6931,6932,6933,6934,6935,6936,6937,6938,6939,6940,6941,6942,6943,6944,6945,6946,6947,6948,6949,6950,6951,6952,6953,6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6981,6982,6983,6984,6985,6986,6987,7043,7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058,7059,7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,7071,7072,7086,7087,7098,7099,7100,7101,7102,7103,7104,7105,7106,7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,7119,7120,7121,7122,7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,7134,7135,7136,7137,7138,7139,7140,7141,7168,7169,7170,7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183,7184,7185,7186,7187,7188,7189,7190,7191,7192,7193,7194,7195,7196,7197,7198,7199,7200,7201,7202,7203,7245,7246,7247,7258,7259,7260,7261,7262,7263,7264,7265,7266,7267,7268,7269,7270,7271,7272,7273,7274,7275,7276,7277,7278,7279,7280,7281,7282,7283,7284,7285,7286,7287,7288,7289,7290,7291,7292,7293,7401,7402,7403,7404,7406,7407,7408,7409,7413,7414,7424,7425,7426,7427,7428,7429,7430,7431,7432,7433,7434,7435,7436,7437,7438,7439,7440,7441,7442,7443,7444,7445,7446,7447,7448,7449,7450,7451,7452,7453,7454,7455,7456,7457,7458,7459,7460,7461,7462,7463,7464,7465,7466,7467,7468,7469,7470,7471,7472,7473,7474,7475,7476,7477,7478,7479,7480,7481,7482,7483,7484,7485,7486,7487,7488,7489,7490,7491,7492,7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,7503,7504,7505,7506,7507,7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519,7520,7521,7522,7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535,7536,7537,7538,7539,7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,7550,7551,7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,7566,7567,7568,7569,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,7580,7581,7582,7583,7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,7595,7596,7597,7598,7599,7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,7610,7611,7612,7613,7614,7615,7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690,7691,7692,7693,7694,7695,7696,7697,7698,7699,7700,7701,7702,7703,7704,7705,7706,7707,7708,7709,7710,7711,7712,7713,7714,7715,7716,7717,7718,7719,7720,7721,7722,7723,7724,7725,7726,7727,7728,7729,7730,7731,7732,7733,7734,7735,7736,7737,7738,7739,7740,7741,7742,7743,7744,7745,7746,7747,7748,7749,7750,7751,7752,7753,7754,7755,7756,7757,7758,7759,7760,7761,7762,7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,7777,7778,7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791,7792,7793,7794,7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,7806,7807,7808,7809,7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,7824,7825,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839,7840,7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855,7856,7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871,7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887,7888,7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903,7904,7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919,7920,7921,7922,7923,7924,7925,7926,7927,7928,7929,7930,7931,7932,7933,7934,7935,7936,7937,7938,7939,7940,7941,7942,7943,7944,7945,7946,7947,7948,7949,7950,7951,7952,7953,7954,7955,7956,7957,7960,7961,7962,7963,7964,7965,7968,7969,7970,7971,7972,7973,7974,7975,7976,7977,7978,7979,7980,7981,7982,7983,7984,7985,7986,7987,7988,7989,7990,7991,7992,7993,7994,7995,7996,7997,7998,7999,8000,8001,8002,8003,8004,8005,8008,8009,8010,8011,8012,8013,8016,8017,8018,8019,8020,8021,8022,8023,8025,8027,8029,8031,8032,8033,8034,8035,8036,8037,8038,8039,8040,8041,8042,8043,8044,8045,8046,8047,8048,8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111,8112,8113,8114,8115,8116,8118,8119,8120,8121,8122,8123,8124,8126,8130,8131,8132,8134,8135,8136,8137,8138,8139,8140,8144,8145,8146,8147,8150,8151,8152,8153,8154,8155,8160,8161,8162,8163,8164,8165,8166,8167,8168,8169,8170,8171,8172,8178,8179,8180,8182,8183,8184,8185,8186,8187,8188,8305,8319,8336,8337,8338,8339,8340,8341,8342,8343,8344,8345,8346,8347,8348,8450,8455,8458,8459,8460,8461,8462,8463,8464,8465,8466,8467,8469,8473,8474,8475,8476,8477,8484,8486,8488,8490,8491,8492,8493,8495,8496,8497,8498,8499,8500,8501,8502,8503,8504,8505,8508,8509,8510,8511,8517,8518,8519,8520,8521,8526,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,8555,8556,8557,8558,8559,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,8570,8571,8572,8573,8574,8575,8576,8577,8578,8579,8580,8581,8582,8583,8584,11264,11265,11266,11267,11268,11269,11270,11271,11272,11273,11274,11275,11276,11277,11278,11279,11280,11281,11282,11283,11284,11285,11286,11287,11288,11289,11290,11291,11292,11293,11294,11295,11296,11297,11298,11299,11300,11301,11302,11303,11304,11305,11306,11307,11308,11309,11310,11312,11313,11314,11315,11316,11317,11318,11319,11320,11321,11322,11323,11324,11325,11326,11327,11328,11329,11330,11331,11332,11333,11334,11335,11336,11337,11338,11339,11340,11341,11342,11343,11344,11345,11346,11347,11348,11349,11350,11351,11352,11353,11354,11355,11356,11357,11358,11360,11361,11362,11363,11364,11365,11366,11367,11368,11369,11370,11371,11372,11373,11374,11375,11376,11377,11378,11379,11380,11381,11382,11383,11384,11385,11386,11387,11388,11389,11390,11391,11392,11393,11394,11395,11396,11397,11398,11399,11400,11401,11402,11403,11404,11405,11406,11407,11408,11409,11410,11411,11412,11413,11414,11415,11416,11417,11418,11419,11420,11421,11422,11423,11424,11425,11426,11427,11428,11429,11430,11431,11432,11433,11434,11435,11436,11437,11438,11439,11440,11441,11442,11443,11444,11445,11446,11447,11448,11449,11450,11451,11452,11453,11454,11455,11456,11457,11458,11459,11460,11461,11462,11463,11464,11465,11466,11467,11468,11469,11470,11471,11472,11473,11474,11475,11476,11477,11478,11479,11480,11481,11482,11483,11484,11485,11486,11487,11488,11489,11490,11491,11492,11499,11500,11501,11502,11506,11507,11520,11521,11522,11523,11524,11525,11526,11527,11528,11529,11530,11531,11532,11533,11534,11535,11536,11537,11538,11539,11540,11541,11542,11543,11544,11545,11546,11547,11548,11549,11550,11551,11552,11553,11554,11555,11556,11557,11559,11565,11568,11569,11570,11571,11572,11573,11574,11575,11576,11577,11578,11579,11580,11581,11582,11583,11584,11585,11586,11587,11588,11589,11590,11591,11592,11593,11594,11595,11596,11597,11598,11599,11600,11601,11602,11603,11604,11605,11606,11607,11608,11609,11610,11611,11612,11613,11614,11615,11616,11617,11618,11619,11620,11621,11622,11623,11631,11648,11649,11650,11651,11652,11653,11654,11655,11656,11657,11658,11659,11660,11661,11662,11663,11664,11665,11666,11667,11668,11669,11670,11680,11681,11682,11683,11684,11685,11686,11688,11689,11690,11691,11692,11693,11694,11696,11697,11698,11699,11700,11701,11702,11704,11705,11706,11707,11708,11709,11710,11712,11713,11714,11715,11716,11717,11718,11720,11721,11722,11723,11724,11725,11726,11728,11729,11730,11731,11732,11733,11734,11736,11737,11738,11739,11740,11741,11742,11823,12293,12294,12295,12321,12322,12323,12324,12325,12326,12327,12328,12329,12337,12338,12339,12340,12341,12344,12345,12346,12347,12348,12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,12435,12436,12437,12438,12445,12446,12447,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,12535,12536,12537,12538,12540,12541,12542,12543,12549,12550,12551,12552,12553,12554,12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,12570,12571,12572,12573,12574,12575,12576,12577,12578,12579,12580,12581,12582,12583,12584,12585,12586,12587,12588,12589,12593,12594,12595,12596,12597,12598,12599,12600,12601,12602,12603,12604,12605,12606,12607,12608,12609,12610,12611,12612,12613,12614,12615,12616,12617,12618,12619,12620,12621,12622,12623,12624,12625,12626,12627,12628,12629,12630,12631,12632,12633,12634,12635,12636,12637,12638,12639,12640,12641,12642,12643,12644,12645,12646,12647,12648,12649,12650,12651,12652,12653,12654,12655,12656,12657,12658,12659,12660,12661,12662,12663,12664,12665,12666,12667,12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679,12680,12681,12682,12683,12684,12685,12686,12704,12705,12706,12707,12708,12709,12710,12711,12712,12713,12714,12715,12716,12717,12718,12719,12720,12721,12722,12723,12724,12725,12726,12727,12728,12729,12730,12784,12785,12786,12787,12788,12789,12790,12791,12792,12793,12794,12795,12796,12797,12798,12799,13312,13313,13314,13315,13316,13317,13318,13319,13320,13321,13322,13323,13324,13325,13326,13327,13328,13329,13330,13331,13332,13333,13334,13335,13336,13337,13338,13339,13340,13341,13342,13343,13344,13345,13346,13347,13348,13349,13350,13351,13352,13353,13354,13355,13356,13357,13358,13359,13360,13361,13362,13363,13364,13365,13366,13367,13368,13369,13370,13371,13372,13373,13374,13375,13376,13377,13378,13379,13380,13381,13382,13383,13384,13385,13386,13387,13388,13389,13390,13391,13392,13393,13394,13395,13396,13397,13398,13399,13400,13401,13402,13403,13404,13405,13406,13407,13408,13409,13410,13411,13412,13413,13414,13415,13416,13417,13418,13419,13420,13421,13422,13423,13424,13425,13426,13427,13428,13429,13430,13431,13432,13433,13434,13435,13436,13437,13438,13439,13440,13441,13442,13443,13444,13445,13446,13447,13448,13449,13450,13451,13452,13453,13454,13455,13456,13457,13458,13459,13460,13461,13462,13463,13464,13465,13466,13467,13468,13469,13470,13471,13472,13473,13474,13475,13476,13477,13478,13479,13480,13481,13482,13483,13484,13485,13486,13487,13488,13489,13490,13491,13492,13493,13494,13495,13496,13497,13498,13499,13500,13501,13502,13503,13504,13505,13506,13507,13508,13509,13510,13511,13512,13513,13514,13515,13516,13517,13518,13519,13520,13521,13522,13523,13524,13525,13526,13527,13528,13529,13530,13531,13532,13533,13534,13535,13536,13537,13538,13539,13540,13541,13542,13543,13544,13545,13546,13547,13548,13549,13550,13551,13552,13553,13554,13555,13556,13557,13558,13559,13560,13561,13562,13563,13564,13565,13566,13567,13568,13569,13570,13571,13572,13573,13574,13575,13576,13577,13578,13579,13580,13581,13582,13583,13584,13585,13586,13587,13588,13589,13590,13591,13592,13593,13594,13595,13596,13597,13598,13599,13600,13601,13602,13603,13604,13605,13606,13607,13608,13609,13610,13611,13612,13613,13614,13615,13616,13617,13618,13619,13620,13621,13622,13623,13624,13625,13626,13627,13628,13629,13630,13631,13632,13633,13634,13635,13636,13637,13638,13639,13640,13641,13642,13643,13644,13645,13646,13647,13648,13649,13650,13651,13652,13653,13654,13655,13656,13657,13658,13659,13660,13661,13662,13663,13664,13665,13666,13667,13668,13669,13670,13671,13672,13673,13674,13675,13676,13677,13678,13679,13680,13681,13682,13683,13684,13685,13686,13687,13688,13689,13690,13691,13692,13693,13694,13695,13696,13697,13698,13699,13700,13701,13702,13703,13704,13705,13706,13707,13708,13709,13710,13711,13712,13713,13714,13715,13716,13717,13718,13719,13720,13721,13722,13723,13724,13725,13726,13727,13728,13729,13730,13731,13732,13733,13734,13735,13736,13737,13738,13739,13740,13741,13742,13743,13744,13745,13746,13747,13748,13749,13750,13751,13752,13753,13754,13755,13756,13757,13758,13759,13760,13761,13762,13763,13764,13765,13766,13767,13768,13769,13770,13771,13772,13773,13774,13775,13776,13777,13778,13779,13780,13781,13782,13783,13784,13785,13786,13787,13788,13789,13790,13791,13792,13793,13794,13795,13796,13797,13798,13799,13800,13801,13802,13803,13804,13805,13806,13807,13808,13809,13810,13811,13812,13813,13814,13815,13816,13817,13818,13819,13820,13821,13822,13823,13824,13825,13826,13827,13828,13829,13830,13831,13832,13833,13834,13835,13836,13837,13838,13839,13840,13841,13842,13843,13844,13845,13846,13847,13848,13849,13850,13851,13852,13853,13854,13855,13856,13857,13858,13859,13860,13861,13862,13863,13864,13865,13866,13867,13868,13869,13870,13871,13872,13873,13874,13875,13876,13877,13878,13879,13880,13881,13882,13883,13884,13885,13886,13887,13888,13889,13890,13891,13892,13893,13894,13895,13896,13897,13898,13899,13900,13901,13902,13903,13904,13905,13906,13907,13908,13909,13910,13911,13912,13913,13914,13915,13916,13917,13918,13919,13920,13921,13922,13923,13924,13925,13926,13927,13928,13929,13930,13931,13932,13933,13934,13935,13936,13937,13938,13939,13940,13941,13942,13943,13944,13945,13946,13947,13948,13949,13950,13951,13952,13953,13954,13955,13956,13957,13958,13959,13960,13961,13962,13963,13964,13965,13966,13967,13968,13969,13970,13971,13972,13973,13974,13975,13976,13977,13978,13979,13980,13981,13982,13983,13984,13985,13986,13987,13988,13989,13990,13991,13992,13993,13994,13995,13996,13997,13998,13999,14000,14001,14002,14003,14004,14005,14006,14007,14008,14009,14010,14011,14012,14013,14014,14015,14016,14017,14018,14019,14020,14021,14022,14023,14024,14025,14026,14027,14028,14029,14030,14031,14032,14033,14034,14035,14036,14037,14038,14039,14040,14041,14042,14043,14044,14045,14046,14047,14048,14049,14050,14051,14052,14053,14054,14055,14056,14057,14058,14059,14060,14061,14062,14063,14064,14065,14066,14067,14068,14069,14070,14071,14072,14073,14074,14075,14076,14077,14078,14079,14080,14081,14082,14083,14084,14085,14086,14087,14088,14089,14090,14091,14092,14093,14094,14095,14096,14097,14098,14099,14100,14101,14102,14103,14104,14105,14106,14107,14108,14109,14110,14111,14112,14113,14114,14115,14116,14117,14118,14119,14120,14121,14122,14123,14124,14125,14126,14127,14128,14129,14130,14131,14132,14133,14134,14135,14136,14137,14138,14139,14140,14141,14142,14143,14144,14145,14146,14147,14148,14149,14150,14151,14152,14153,14154,14155,14156,14157,14158,14159,14160,14161,14162,14163,14164,14165,14166,14167,14168,14169,14170,14171,14172,14173,14174,14175,14176,14177,14178,14179,14180,14181,14182,14183,14184,14185,14186,14187,14188,14189,14190,14191,14192,14193,14194,14195,14196,14197,14198,14199,14200,14201,14202,14203,14204,14205,14206,14207,14208,14209,14210,14211,14212,14213,14214,14215,14216,14217,14218,14219,14220,14221,14222,14223,14224,14225,14226,14227,14228,14229,14230,14231,14232,14233,14234,14235,14236,14237,14238,14239,14240,14241,14242,14243,14244,14245,14246,14247,14248,14249,14250,14251,14252,14253,14254,14255,14256,14257,14258,14259,14260,14261,14262,14263,14264,14265,14266,14267,14268,14269,14270,14271,14272,14273,14274,14275,14276,14277,14278,14279,14280,14281,14282,14283,14284,14285,14286,14287,14288,14289,14290,14291,14292,14293,14294,14295,14296,14297,14298,14299,14300,14301,14302,14303,14304,14305,14306,14307,14308,14309,14310,14311,14312,14313,14314,14315,14316,14317,14318,14319,14320,14321,14322,14323,14324,14325,14326,14327,14328,14329,14330,14331,14332,14333,14334,14335,14336,14337,14338,14339,14340,14341,14342,14343,14344,14345,14346,14347,14348,14349,14350,14351,14352,14353,14354,14355,14356,14357,14358,14359,14360,14361,14362,14363,14364,14365,14366,14367,14368,14369,14370,14371,14372,14373,14374,14375,14376,14377,14378,14379,14380,14381,14382,14383,14384,14385,14386,14387,14388,14389,14390,14391,14392,14393,14394,14395,14396,14397,14398,14399,14400,14401,14402,14403,14404,14405,14406,14407,14408,14409,14410,14411,14412,14413,14414,14415,14416,14417,14418,14419,14420,14421,14422,14423,14424,14425,14426,14427,14428,14429,14430,14431,14432,14433,14434,14435,14436,14437,14438,14439,14440,14441,14442,14443,14444,14445,14446,14447,14448,14449,14450,14451,14452,14453,14454,14455,14456,14457,14458,14459,14460,14461,14462,14463,14464,14465,14466,14467,14468,14469,14470,14471,14472,14473,14474,14475,14476,14477,14478,14479,14480,14481,14482,14483,14484,14485,14486,14487,14488,14489,14490,14491,14492,14493,14494,14495,14496,14497,14498,14499,14500,14501,14502,14503,14504,14505,14506,14507,14508,14509,14510,14511,14512,14513,14514,14515,14516,14517,14518,14519,14520,14521,14522,14523,14524,14525,14526,14527,14528,14529,14530,14531,14532,14533,14534,14535,14536,14537,14538,14539,14540,14541,14542,14543,14544,14545,14546,14547,14548,14549,14550,14551,14552,14553,14554,14555,14556,14557,14558,14559,14560,14561,14562,14563,14564,14565,14566,14567,14568,14569,14570,14571,14572,14573,14574,14575,14576,14577,14578,14579,14580,14581,14582,14583,14584,14585,14586,14587,14588,14589,14590,14591,14592,14593,14594,14595,14596,14597,14598,14599,14600,14601,14602,14603,14604,14605,14606,14607,14608,14609,14610,14611,14612,14613,14614,14615,14616,14617,14618,14619,14620,14621,14622,14623,14624,14625,14626,14627,14628,14629,14630,14631,14632,14633,14634,14635,14636,14637,14638,14639,14640,14641,14642,14643,14644,14645,14646,14647,14648,14649,14650,14651,14652,14653,14654,14655,14656,14657,14658,14659,14660,14661,14662,14663,14664,14665,14666,14667,14668,14669,14670,14671,14672,14673,14674,14675,14676,14677,14678,14679,14680,14681,14682,14683,14684,14685,14686,14687,14688,14689,14690,14691,14692,14693,14694,14695,14696,14697,14698,14699,14700,14701,14702,14703,14704,14705,14706,14707,14708,14709,14710,14711,14712,14713,14714,14715,14716,14717,14718,14719,14720,14721,14722,14723,14724,14725,14726,14727,14728,14729,14730,14731,14732,14733,14734,14735,14736,14737,14738,14739,14740,14741,14742,14743,14744,14745,14746,14747,14748,14749,14750,14751,14752,14753,14754,14755,14756,14757,14758,14759,14760,14761,14762,14763,14764,14765,14766,14767,14768,14769,14770,14771,14772,14773,14774,14775,14776,14777,14778,14779,14780,14781,14782,14783,14784,14785,14786,14787,14788,14789,14790,14791,14792,14793,14794,14795,14796,14797,14798,14799,14800,14801,14802,14803,14804,14805,14806,14807,14808,14809,14810,14811,14812,14813,14814,14815,14816,14817,14818,14819,14820,14821,14822,14823,14824,14825,14826,14827,14828,14829,14830,14831,14832,14833,14834,14835,14836,14837,14838,14839,14840,14841,14842,14843,14844,14845,14846,14847,14848,14849,14850,14851,14852,14853,14854,14855,14856,14857,14858,14859,14860,14861,14862,14863,14864,14865,14866,14867,14868,14869,14870,14871,14872,14873,14874,14875,14876,14877,14878,14879,14880,14881,14882,14883,14884,14885,14886,14887,14888,14889,14890,14891,14892,14893,14894,14895,14896,14897,14898,14899,14900,14901,14902,14903,14904,14905,14906,14907,14908,14909,14910,14911,14912,14913,14914,14915,14916,14917,14918,14919,14920,14921,14922,14923,14924,14925,14926,14927,14928,14929,14930,14931,14932,14933,14934,14935,14936,14937,14938,14939,14940,14941,14942,14943,14944,14945,14946,14947,14948,14949,14950,14951,14952,14953,14954,14955,14956,14957,14958,14959,14960,14961,14962,14963,14964,14965,14966,14967,14968,14969,14970,14971,14972,14973,14974,14975,14976,14977,14978,14979,14980,14981,14982,14983,14984,14985,14986,14987,14988,14989,14990,14991,14992,14993,14994,14995,14996,14997,14998,14999,15000,15001,15002,15003,15004,15005,15006,15007,15008,15009,15010,15011,15012,15013,15014,15015,15016,15017,15018,15019,15020,15021,15022,15023,15024,15025,15026,15027,15028,15029,15030,15031,15032,15033,15034,15035,15036,15037,15038,15039,15040,15041,15042,15043,15044,15045,15046,15047,15048,15049,15050,15051,15052,15053,15054,15055,15056,15057,15058,15059,15060,15061,15062,15063,15064,15065,15066,15067,15068,15069,15070,15071,15072,15073,15074,15075,15076,15077,15078,15079,15080,15081,15082,15083,15084,15085,15086,15087,15088,15089,15090,15091,15092,15093,15094,15095,15096,15097,15098,15099,15100,15101,15102,15103,15104,15105,15106,15107,15108,15109,15110,15111,15112,15113,15114,15115,15116,15117,15118,15119,15120,15121,15122,15123,15124,15125,15126,15127,15128,15129,15130,15131,15132,15133,15134,15135,15136,15137,15138,15139,15140,15141,15142,15143,15144,15145,15146,15147,15148,15149,15150,15151,15152,15153,15154,15155,15156,15157,15158,15159,15160,15161,15162,15163,15164,15165,15166,15167,15168,15169,15170,15171,15172,15173,15174,15175,15176,15177,15178,15179,15180,15181,15182,15183,15184,15185,15186,15187,15188,15189,15190,15191,15192,15193,15194,15195,15196,15197,15198,15199,15200,15201,15202,15203,15204,15205,15206,15207,15208,15209,15210,15211,15212,15213,15214,15215,15216,15217,15218,15219,15220,15221,15222,15223,15224,15225,15226,15227,15228,15229,15230,15231,15232,15233,15234,15235,15236,15237,15238,15239,15240,15241,15242,15243,15244,15245,15246,15247,15248,15249,15250,15251,15252,15253,15254,15255,15256,15257,15258,15259,15260,15261,15262,15263,15264,15265,15266,15267,15268,15269,15270,15271,15272,15273,15274,15275,15276,15277,15278,15279,15280,15281,15282,15283,15284,15285,15286,15287,15288,15289,15290,15291,15292,15293,15294,15295,15296,15297,15298,15299,15300,15301,15302,15303,15304,15305,15306,15307,15308,15309,15310,15311,15312,15313,15314,15315,15316,15317,15318,15319,15320,15321,15322,15323,15324,15325,15326,15327,15328,15329,15330,15331,15332,15333,15334,15335,15336,15337,15338,15339,15340,15341,15342,15343,15344,15345,15346,15347,15348,15349,15350,15351,15352,15353,15354,15355,15356,15357,15358,15359,15360,15361,15362,15363,15364,15365,15366,15367,15368,15369,15370,15371,15372,15373,15374,15375,15376,15377,15378,15379,15380,15381,15382,15383,15384,15385,15386,15387,15388,15389,15390,15391,15392,15393,15394,15395,15396,15397,15398,15399,15400,15401,15402,15403,15404,15405,15406,15407,15408,15409,15410,15411,15412,15413,15414,15415,15416,15417,15418,15419,15420,15421,15422,15423,15424,15425,15426,15427,15428,15429,15430,15431,15432,15433,15434,15435,15436,15437,15438,15439,15440,15441,15442,15443,15444,15445,15446,15447,15448,15449,15450,15451,15452,15453,15454,15455,15456,15457,15458,15459,15460,15461,15462,15463,15464,15465,15466,15467,15468,15469,15470,15471,15472,15473,15474,15475,15476,15477,15478,15479,15480,15481,15482,15483,15484,15485,15486,15487,15488,15489,15490,15491,15492,15493,15494,15495,15496,15497,15498,15499,15500,15501,15502,15503,15504,15505,15506,15507,15508,15509,15510,15511,15512,15513,15514,15515,15516,15517,15518,15519,15520,15521,15522,15523,15524,15525,15526,15527,15528,15529,15530,15531,15532,15533,15534,15535,15536,15537,15538,15539,15540,15541,15542,15543,15544,15545,15546,15547,15548,15549,15550,15551,15552,15553,15554,15555,15556,15557,15558,15559,15560,15561,15562,15563,15564,15565,15566,15567,15568,15569,15570,15571,15572,15573,15574,15575,15576,15577,15578,15579,15580,15581,15582,15583,15584,15585,15586,15587,15588,15589,15590,15591,15592,15593,15594,15595,15596,15597,15598,15599,15600,15601,15602,15603,15604,15605,15606,15607,15608,15609,15610,15611,15612,15613,15614,15615,15616,15617,15618,15619,15620,15621,15622,15623,15624,15625,15626,15627,15628,15629,15630,15631,15632,15633,15634,15635,15636,15637,15638,15639,15640,15641,15642,15643,15644,15645,15646,15647,15648,15649,15650,15651,15652,15653,15654,15655,15656,15657,15658,15659,15660,15661,15662,15663,15664,15665,15666,15667,15668,15669,15670,15671,15672,15673,15674,15675,15676,15677,15678,15679,15680,15681,15682,15683,15684,15685,15686,15687,15688,15689,15690,15691,15692,15693,15694,15695,15696,15697,15698,15699,15700,15701,15702,15703,15704,15705,15706,15707,15708,15709,15710,15711,15712,15713,15714,15715,15716,15717,15718,15719,15720,15721,15722,15723,15724,15725,15726,15727,15728,15729,15730,15731,15732,15733,15734,15735,15736,15737,15738,15739,15740,15741,15742,15743,15744,15745,15746,15747,15748,15749,15750,15751,15752,15753,15754,15755,15756,15757,15758,15759,15760,15761,15762,15763,15764,15765,15766,15767,15768,15769,15770,15771,15772,15773,15774,15775,15776,15777,15778,15779,15780,15781,15782,15783,15784,15785,15786,15787,15788,15789,15790,15791,15792,15793,15794,15795,15796,15797,15798,15799,15800,15801,15802,15803,15804,15805,15806,15807,15808,15809,15810,15811,15812,15813,15814,15815,15816,15817,15818,15819,15820,15821,15822,15823,15824,15825,15826,15827,15828,15829,15830,15831,15832,15833,15834,15835,15836,15837,15838,15839,15840,15841,15842,15843,15844,15845,15846,15847,15848,15849,15850,15851,15852,15853,15854,15855,15856,15857,15858,15859,15860,15861,15862,15863,15864,15865,15866,15867,15868,15869,15870,15871,15872,15873,15874,15875,15876,15877,15878,15879,15880,15881,15882,15883,15884,15885,15886,15887,15888,15889,15890,15891,15892,15893,15894,15895,15896,15897,15898,15899,15900,15901,15902,15903,15904,15905,15906,15907,15908,15909,15910,15911,15912,15913,15914,15915,15916,15917,15918,15919,15920,15921,15922,15923,15924,15925,15926,15927,15928,15929,15930,15931,15932,15933,15934,15935,15936,15937,15938,15939,15940,15941,15942,15943,15944,15945,15946,15947,15948,15949,15950,15951,15952,15953,15954,15955,15956,15957,15958,15959,15960,15961,15962,15963,15964,15965,15966,15967,15968,15969,15970,15971,15972,15973,15974,15975,15976,15977,15978,15979,15980,15981,15982,15983,15984,15985,15986,15987,15988,15989,15990,15991,15992,15993,15994,15995,15996,15997,15998,15999,16000,16001,16002,16003,16004,16005,16006,16007,16008,16009,16010,16011,16012,16013,16014,16015,16016,16017,16018,16019,16020,16021,16022,16023,16024,16025,16026,16027,16028,16029,16030,16031,16032,16033,16034,16035,16036,16037,16038,16039,16040,16041,16042,16043,16044,16045,16046,16047,16048,16049,16050,16051,16052,16053,16054,16055,16056,16057,16058,16059,16060,16061,16062,16063,16064,16065,16066,16067,16068,16069,16070,16071,16072,16073,16074,16075,16076,16077,16078,16079,16080,16081,16082,16083,16084,16085,16086,16087,16088,16089,16090,16091,16092,16093,16094,16095,16096,16097,16098,16099,16100,16101,16102,16103,16104,16105,16106,16107,16108,16109,16110,16111,16112,16113,16114,16115,16116,16117,16118,16119,16120,16121,16122,16123,16124,16125,16126,16127,16128,16129,16130,16131,16132,16133,16134,16135,16136,16137,16138,16139,16140,16141,16142,16143,16144,16145,16146,16147,16148,16149,16150,16151,16152,16153,16154,16155,16156,16157,16158,16159,16160,16161,16162,16163,16164,16165,16166,16167,16168,16169,16170,16171,16172,16173,16174,16175,16176,16177,16178,16179,16180,16181,16182,16183,16184,16185,16186,16187,16188,16189,16190,16191,16192,16193,16194,16195,16196,16197,16198,16199,16200,16201,16202,16203,16204,16205,16206,16207,16208,16209,16210,16211,16212,16213,16214,16215,16216,16217,16218,16219,16220,16221,16222,16223,16224,16225,16226,16227,16228,16229,16230,16231,16232,16233,16234,16235,16236,16237,16238,16239,16240,16241,16242,16243,16244,16245,16246,16247,16248,16249,16250,16251,16252,16253,16254,16255,16256,16257,16258,16259,16260,16261,16262,16263,16264,16265,16266,16267,16268,16269,16270,16271,16272,16273,16274,16275,16276,16277,16278,16279,16280,16281,16282,16283,16284,16285,16286,16287,16288,16289,16290,16291,16292,16293,16294,16295,16296,16297,16298,16299,16300,16301,16302,16303,16304,16305,16306,16307,16308,16309,16310,16311,16312,16313,16314,16315,16316,16317,16318,16319,16320,16321,16322,16323,16324,16325,16326,16327,16328,16329,16330,16331,16332,16333,16334,16335,16336,16337,16338,16339,16340,16341,16342,16343,16344,16345,16346,16347,16348,16349,16350,16351,16352,16353,16354,16355,16356,16357,16358,16359,16360,16361,16362,16363,16364,16365,16366,16367,16368,16369,16370,16371,16372,16373,16374,16375,16376,16377,16378,16379,16380,16381,16382,16383,16384,16385,16386,16387,16388,16389,16390,16391,16392,16393,16394,16395,16396,16397,16398,16399,16400,16401,16402,16403,16404,16405,16406,16407,16408,16409,16410,16411,16412,16413,16414,16415,16416,16417,16418,16419,16420,16421,16422,16423,16424,16425,16426,16427,16428,16429,16430,16431,16432,16433,16434,16435,16436,16437,16438,16439,16440,16441,16442,16443,16444,16445,16446,16447,16448,16449,16450,16451,16452,16453,16454,16455,16456,16457,16458,16459,16460,16461,16462,16463,16464,16465,16466,16467,16468,16469,16470,16471,16472,16473,16474,16475,16476,16477,16478,16479,16480,16481,16482,16483,16484,16485,16486,16487,16488,16489,16490,16491,16492,16493,16494,16495,16496,16497,16498,16499,16500,16501,16502,16503,16504,16505,16506,16507,16508,16509,16510,16511,16512,16513,16514,16515,16516,16517,16518,16519,16520,16521,16522,16523,16524,16525,16526,16527,16528,16529,16530,16531,16532,16533,16534,16535,16536,16537,16538,16539,16540,16541,16542,16543,16544,16545,16546,16547,16548,16549,16550,16551,16552,16553,16554,16555,16556,16557,16558,16559,16560,16561,16562,16563,16564,16565,16566,16567,16568,16569,16570,16571,16572,16573,16574,16575,16576,16577,16578,16579,16580,16581,16582,16583,16584,16585,16586,16587,16588,16589,16590,16591,16592,16593,16594,16595,16596,16597,16598,16599,16600,16601,16602,16603,16604,16605,16606,16607,16608,16609,16610,16611,16612,16613,16614,16615,16616,16617,16618,16619,16620,16621,16622,16623,16624,16625,16626,16627,16628,16629,16630,16631,16632,16633,16634,16635,16636,16637,16638,16639,16640,16641,16642,16643,16644,16645,16646,16647,16648,16649,16650,16651,16652,16653,16654,16655,16656,16657,16658,16659,16660,16661,16662,16663,16664,16665,16666,16667,16668,16669,16670,16671,16672,16673,16674,16675,16676,16677,16678,16679,16680,16681,16682,16683,16684,16685,16686,16687,16688,16689,16690,16691,16692,16693,16694,16695,16696,16697,16698,16699,16700,16701,16702,16703,16704,16705,16706,16707,16708,16709,16710,16711,16712,16713,16714,16715,16716,16717,16718,16719,16720,16721,16722,16723,16724,16725,16726,16727,16728,16729,16730,16731,16732,16733,16734,16735,16736,16737,16738,16739,16740,16741,16742,16743,16744,16745,16746,16747,16748,16749,16750,16751,16752,16753,16754,16755,16756,16757,16758,16759,16760,16761,16762,16763,16764,16765,16766,16767,16768,16769,16770,16771,16772,16773,16774,16775,16776,16777,16778,16779,16780,16781,16782,16783,16784,16785,16786,16787,16788,16789,16790,16791,16792,16793,16794,16795,16796,16797,16798,16799,16800,16801,16802,16803,16804,16805,16806,16807,16808,16809,16810,16811,16812,16813,16814,16815,16816,16817,16818,16819,16820,16821,16822,16823,16824,16825,16826,16827,16828,16829,16830,16831,16832,16833,16834,16835,16836,16837,16838,16839,16840,16841,16842,16843,16844,16845,16846,16847,16848,16849,16850,16851,16852,16853,16854,16855,16856,16857,16858,16859,16860,16861,16862,16863,16864,16865,16866,16867,16868,16869,16870,16871,16872,16873,16874,16875,16876,16877,16878,16879,16880,16881,16882,16883,16884,16885,16886,16887,16888,16889,16890,16891,16892,16893,16894,16895,16896,16897,16898,16899,16900,16901,16902,16903,16904,16905,16906,16907,16908,16909,16910,16911,16912,16913,16914,16915,16916,16917,16918,16919,16920,16921,16922,16923,16924,16925,16926,16927,16928,16929,16930,16931,16932,16933,16934,16935,16936,16937,16938,16939,16940,16941,16942,16943,16944,16945,16946,16947,16948,16949,16950,16951,16952,16953,16954,16955,16956,16957,16958,16959,16960,16961,16962,16963,16964,16965,16966,16967,16968,16969,16970,16971,16972,16973,16974,16975,16976,16977,16978,16979,16980,16981,16982,16983,16984,16985,16986,16987,16988,16989,16990,16991,16992,16993,16994,16995,16996,16997,16998,16999,17000,17001,17002,17003,17004,17005,17006,17007,17008,17009,17010,17011,17012,17013,17014,17015,17016,17017,17018,17019,17020,17021,17022,17023,17024,17025,17026,17027,17028,17029,17030,17031,17032,17033,17034,17035,17036,17037,17038,17039,17040,17041,17042,17043,17044,17045,17046,17047,17048,17049,17050,17051,17052,17053,17054,17055,17056,17057,17058,17059,17060,17061,17062,17063,17064,17065,17066,17067,17068,17069,17070,17071,17072,17073,17074,17075,17076,17077,17078,17079,17080,17081,17082,17083,17084,17085,17086,17087,17088,17089,17090,17091,17092,17093,17094,17095,17096,17097,17098,17099,17100,17101,17102,17103,17104,17105,17106,17107,17108,17109,17110,17111,17112,17113,17114,17115,17116,17117,17118,17119,17120,17121,17122,17123,17124,17125,17126,17127,17128,17129,17130,17131,17132,17133,17134,17135,17136,17137,17138,17139,17140,17141,17142,17143,17144,17145,17146,17147,17148,17149,17150,17151,17152,17153,17154,17155,17156,17157,17158,17159,17160,17161,17162,17163,17164,17165,17166,17167,17168,17169,17170,17171,17172,17173,17174,17175,17176,17177,17178,17179,17180,17181,17182,17183,17184,17185,17186,17187,17188,17189,17190,17191,17192,17193,17194,17195,17196,17197,17198,17199,17200,17201,17202,17203,17204,17205,17206,17207,17208,17209,17210,17211,17212,17213,17214,17215,17216,17217,17218,17219,17220,17221,17222,17223,17224,17225,17226,17227,17228,17229,17230,17231,17232,17233,17234,17235,17236,17237,17238,17239,17240,17241,17242,17243,17244,17245,17246,17247,17248,17249,17250,17251,17252,17253,17254,17255,17256,17257,17258,17259,17260,17261,17262,17263,17264,17265,17266,17267,17268,17269,17270,17271,17272,17273,17274,17275,17276,17277,17278,17279,17280,17281,17282,17283,17284,17285,17286,17287,17288,17289,17290,17291,17292,17293,17294,17295,17296,17297,17298,17299,17300,17301,17302,17303,17304,17305,17306,17307,17308,17309,17310,17311,17312,17313,17314,17315,17316,17317,17318,17319,17320,17321,17322,17323,17324,17325,17326,17327,17328,17329,17330,17331,17332,17333,17334,17335,17336,17337,17338,17339,17340,17341,17342,17343,17344,17345,17346,17347,17348,17349,17350,17351,17352,17353,17354,17355,17356,17357,17358,17359,17360,17361,17362,17363,17364,17365,17366,17367,17368,17369,17370,17371,17372,17373,17374,17375,17376,17377,17378,17379,17380,17381,17382,17383,17384,17385,17386,17387,17388,17389,17390,17391,17392,17393,17394,17395,17396,17397,17398,17399,17400,17401,17402,17403,17404,17405,17406,17407,17408,17409,17410,17411,17412,17413,17414,17415,17416,17417,17418,17419,17420,17421,17422,17423,17424,17425,17426,17427,17428,17429,17430,17431,17432,17433,17434,17435,17436,17437,17438,17439,17440,17441,17442,17443,17444,17445,17446,17447,17448,17449,17450,17451,17452,17453,17454,17455,17456,17457,17458,17459,17460,17461,17462,17463,17464,17465,17466,17467,17468,17469,17470,17471,17472,17473,17474,17475,17476,17477,17478,17479,17480,17481,17482,17483,17484,17485,17486,17487,17488,17489,17490,17491,17492,17493,17494,17495,17496,17497,17498,17499,17500,17501,17502,17503,17504,17505,17506,17507,17508,17509,17510,17511,17512,17513,17514,17515,17516,17517,17518,17519,17520,17521,17522,17523,17524,17525,17526,17527,17528,17529,17530,17531,17532,17533,17534,17535,17536,17537,17538,17539,17540,17541,17542,17543,17544,17545,17546,17547,17548,17549,17550,17551,17552,17553,17554,17555,17556,17557,17558,17559,17560,17561,17562,17563,17564,17565,17566,17567,17568,17569,17570,17571,17572,17573,17574,17575,17576,17577,17578,17579,17580,17581,17582,17583,17584,17585,17586,17587,17588,17589,17590,17591,17592,17593,17594,17595,17596,17597,17598,17599,17600,17601,17602,17603,17604,17605,17606,17607,17608,17609,17610,17611,17612,17613,17614,17615,17616,17617,17618,17619,17620,17621,17622,17623,17624,17625,17626,17627,17628,17629,17630,17631,17632,17633,17634,17635,17636,17637,17638,17639,17640,17641,17642,17643,17644,17645,17646,17647,17648,17649,17650,17651,17652,17653,17654,17655,17656,17657,17658,17659,17660,17661,17662,17663,17664,17665,17666,17667,17668,17669,17670,17671,17672,17673,17674,17675,17676,17677,17678,17679,17680,17681,17682,17683,17684,17685,17686,17687,17688,17689,17690,17691,17692,17693,17694,17695,17696,17697,17698,17699,17700,17701,17702,17703,17704,17705,17706,17707,17708,17709,17710,17711,17712,17713,17714,17715,17716,17717,17718,17719,17720,17721,17722,17723,17724,17725,17726,17727,17728,17729,17730,17731,17732,17733,17734,17735,17736,17737,17738,17739,17740,17741,17742,17743,17744,17745,17746,17747,17748,17749,17750,17751,17752,17753,17754,17755,17756,17757,17758,17759,17760,17761,17762,17763,17764,17765,17766,17767,17768,17769,17770,17771,17772,17773,17774,17775,17776,17777,17778,17779,17780,17781,17782,17783,17784,17785,17786,17787,17788,17789,17790,17791,17792,17793,17794,17795,17796,17797,17798,17799,17800,17801,17802,17803,17804,17805,17806,17807,17808,17809,17810,17811,17812,17813,17814,17815,17816,17817,17818,17819,17820,17821,17822,17823,17824,17825,17826,17827,17828,17829,17830,17831,17832,17833,17834,17835,17836,17837,17838,17839,17840,17841,17842,17843,17844,17845,17846,17847,17848,17849,17850,17851,17852,17853,17854,17855,17856,17857,17858,17859,17860,17861,17862,17863,17864,17865,17866,17867,17868,17869,17870,17871,17872,17873,17874,17875,17876,17877,17878,17879,17880,17881,17882,17883,17884,17885,17886,17887,17888,17889,17890,17891,17892,17893,17894,17895,17896,17897,17898,17899,17900,17901,17902,17903,17904,17905,17906,17907,17908,17909,17910,17911,17912,17913,17914,17915,17916,17917,17918,17919,17920,17921,17922,17923,17924,17925,17926,17927,17928,17929,17930,17931,17932,17933,17934,17935,17936,17937,17938,17939,17940,17941,17942,17943,17944,17945,17946,17947,17948,17949,17950,17951,17952,17953,17954,17955,17956,17957,17958,17959,17960,17961,17962,17963,17964,17965,17966,17967,17968,17969,17970,17971,17972,17973,17974,17975,17976,17977,17978,17979,17980,17981,17982,17983,17984,17985,17986,17987,17988,17989,17990,17991,17992,17993,17994,17995,17996,17997,17998,17999,18000,18001,18002,18003,18004,18005,18006,18007,18008,18009,18010,18011,18012,18013,18014,18015,18016,18017,18018,18019,18020,18021,18022,18023,18024,18025,18026,18027,18028,18029,18030,18031,18032,18033,18034,18035,18036,18037,18038,18039,18040,18041,18042,18043,18044,18045,18046,18047,18048,18049,18050,18051,18052,18053,18054,18055,18056,18057,18058,18059,18060,18061,18062,18063,18064,18065,18066,18067,18068,18069,18070,18071,18072,18073,18074,18075,18076,18077,18078,18079,18080,18081,18082,18083,18084,18085,18086,18087,18088,18089,18090,18091,18092,18093,18094,18095,18096,18097,18098,18099,18100,18101,18102,18103,18104,18105,18106,18107,18108,18109,18110,18111,18112,18113,18114,18115,18116,18117,18118,18119,18120,18121,18122,18123,18124,18125,18126,18127,18128,18129,18130,18131,18132,18133,18134,18135,18136,18137,18138,18139,18140,18141,18142,18143,18144,18145,18146,18147,18148,18149,18150,18151,18152,18153,18154,18155,18156,18157,18158,18159,18160,18161,18162,18163,18164,18165,18166,18167,18168,18169,18170,18171,18172,18173,18174,18175,18176,18177,18178,18179,18180,18181,18182,18183,18184,18185,18186,18187,18188,18189,18190,18191,18192,18193,18194,18195,18196,18197,18198,18199,18200,18201,18202,18203,18204,18205,18206,18207,18208,18209,18210,18211,18212,18213,18214,18215,18216,18217,18218,18219,18220,18221,18222,18223,18224,18225,18226,18227,18228,18229,18230,18231,18232,18233,18234,18235,18236,18237,18238,18239,18240,18241,18242,18243,18244,18245,18246,18247,18248,18249,18250,18251,18252,18253,18254,18255,18256,18257,18258,18259,18260,18261,18262,18263,18264,18265,18266,18267,18268,18269,18270,18271,18272,18273,18274,18275,18276,18277,18278,18279,18280,18281,18282,18283,18284,18285,18286,18287,18288,18289,18290,18291,18292,18293,18294,18295,18296,18297,18298,18299,18300,18301,18302,18303,18304,18305,18306,18307,18308,18309,18310,18311,18312,18313,18314,18315,18316,18317,18318,18319,18320,18321,18322,18323,18324,18325,18326,18327,18328,18329,18330,18331,18332,18333,18334,18335,18336,18337,18338,18339,18340,18341,18342,18343,18344,18345,18346,18347,18348,18349,18350,18351,18352,18353,18354,18355,18356,18357,18358,18359,18360,18361,18362,18363,18364,18365,18366,18367,18368,18369,18370,18371,18372,18373,18374,18375,18376,18377,18378,18379,18380,18381,18382,18383,18384,18385,18386,18387,18388,18389,18390,18391,18392,18393,18394,18395,18396,18397,18398,18399,18400,18401,18402,18403,18404,18405,18406,18407,18408,18409,18410,18411,18412,18413,18414,18415,18416,18417,18418,18419,18420,18421,18422,18423,18424,18425,18426,18427,18428,18429,18430,18431,18432,18433,18434,18435,18436,18437,18438,18439,18440,18441,18442,18443,18444,18445,18446,18447,18448,18449,18450,18451,18452,18453,18454,18455,18456,18457,18458,18459,18460,18461,18462,18463,18464,18465,18466,18467,18468,18469,18470,18471,18472,18473,18474,18475,18476,18477,18478,18479,18480,18481,18482,18483,18484,18485,18486,18487,18488,18489,18490,18491,18492,18493,18494,18495,18496,18497,18498,18499,18500,18501,18502,18503,18504,18505,18506,18507,18508,18509,18510,18511,18512,18513,18514,18515,18516,18517,18518,18519,18520,18521,18522,18523,18524,18525,18526,18527,18528,18529,18530,18531,18532,18533,18534,18535,18536,18537,18538,18539,18540,18541,18542,18543,18544,18545,18546,18547,18548,18549,18550,18551,18552,18553,18554,18555,18556,18557,18558,18559,18560,18561,18562,18563,18564,18565,18566,18567,18568,18569,18570,18571,18572,18573,18574,18575,18576,18577,18578,18579,18580,18581,18582,18583,18584,18585,18586,18587,18588,18589,18590,18591,18592,18593,18594,18595,18596,18597,18598,18599,18600,18601,18602,18603,18604,18605,18606,18607,18608,18609,18610,18611,18612,18613,18614,18615,18616,18617,18618,18619,18620,18621,18622,18623,18624,18625,18626,18627,18628,18629,18630,18631,18632,18633,18634,18635,18636,18637,18638,18639,18640,18641,18642,18643,18644,18645,18646,18647,18648,18649,18650,18651,18652,18653,18654,18655,18656,18657,18658,18659,18660,18661,18662,18663,18664,18665,18666,18667,18668,18669,18670,18671,18672,18673,18674,18675,18676,18677,18678,18679,18680,18681,18682,18683,18684,18685,18686,18687,18688,18689,18690,18691,18692,18693,18694,18695,18696,18697,18698,18699,18700,18701,18702,18703,18704,18705,18706,18707,18708,18709,18710,18711,18712,18713,18714,18715,18716,18717,18718,18719,18720,18721,18722,18723,18724,18725,18726,18727,18728,18729,18730,18731,18732,18733,18734,18735,18736,18737,18738,18739,18740,18741,18742,18743,18744,18745,18746,18747,18748,18749,18750,18751,18752,18753,18754,18755,18756,18757,18758,18759,18760,18761,18762,18763,18764,18765,18766,18767,18768,18769,18770,18771,18772,18773,18774,18775,18776,18777,18778,18779,18780,18781,18782,18783,18784,18785,18786,18787,18788,18789,18790,18791,18792,18793,18794,18795,18796,18797,18798,18799,18800,18801,18802,18803,18804,18805,18806,18807,18808,18809,18810,18811,18812,18813,18814,18815,18816,18817,18818,18819,18820,18821,18822,18823,18824,18825,18826,18827,18828,18829,18830,18831,18832,18833,18834,18835,18836,18837,18838,18839,18840,18841,18842,18843,18844,18845,18846,18847,18848,18849,18850,18851,18852,18853,18854,18855,18856,18857,18858,18859,18860,18861,18862,18863,18864,18865,18866,18867,18868,18869,18870,18871,18872,18873,18874,18875,18876,18877,18878,18879,18880,18881,18882,18883,18884,18885,18886,18887,18888,18889,18890,18891,18892,18893,18894,18895,18896,18897,18898,18899,18900,18901,18902,18903,18904,18905,18906,18907,18908,18909,18910,18911,18912,18913,18914,18915,18916,18917,18918,18919,18920,18921,18922,18923,18924,18925,18926,18927,18928,18929,18930,18931,18932,18933,18934,18935,18936,18937,18938,18939,18940,18941,18942,18943,18944,18945,18946,18947,18948,18949,18950,18951,18952,18953,18954,18955,18956,18957,18958,18959,18960,18961,18962,18963,18964,18965,18966,18967,18968,18969,18970,18971,18972,18973,18974,18975,18976,18977,18978,18979,18980,18981,18982,18983,18984,18985,18986,18987,18988,18989,18990,18991,18992,18993,18994,18995,18996,18997,18998,18999,19000,19001,19002,19003,19004,19005,19006,19007,19008,19009,19010,19011,19012,19013,19014,19015,19016,19017,19018,19019,19020,19021,19022,19023,19024,19025,19026,19027,19028,19029,19030,19031,19032,19033,19034,19035,19036,19037,19038,19039,19040,19041,19042,19043,19044,19045,19046,19047,19048,19049,19050,19051,19052,19053,19054,19055,19056,19057,19058,19059,19060,19061,19062,19063,19064,19065,19066,19067,19068,19069,19070,19071,19072,19073,19074,19075,19076,19077,19078,19079,19080,19081,19082,19083,19084,19085,19086,19087,19088,19089,19090,19091,19092,19093,19094,19095,19096,19097,19098,19099,19100,19101,19102,19103,19104,19105,19106,19107,19108,19109,19110,19111,19112,19113,19114,19115,19116,19117,19118,19119,19120,19121,19122,19123,19124,19125,19126,19127,19128,19129,19130,19131,19132,19133,19134,19135,19136,19137,19138,19139,19140,19141,19142,19143,19144,19145,19146,19147,19148,19149,19150,19151,19152,19153,19154,19155,19156,19157,19158,19159,19160,19161,19162,19163,19164,19165,19166,19167,19168,19169,19170,19171,19172,19173,19174,19175,19176,19177,19178,19179,19180,19181,19182,19183,19184,19185,19186,19187,19188,19189,19190,19191,19192,19193,19194,19195,19196,19197,19198,19199,19200,19201,19202,19203,19204,19205,19206,19207,19208,19209,19210,19211,19212,19213,19214,19215,19216,19217,19218,19219,19220,19221,19222,19223,19224,19225,19226,19227,19228,19229,19230,19231,19232,19233,19234,19235,19236,19237,19238,19239,19240,19241,19242,19243,19244,19245,19246,19247,19248,19249,19250,19251,19252,19253,19254,19255,19256,19257,19258,19259,19260,19261,19262,19263,19264,19265,19266,19267,19268,19269,19270,19271,19272,19273,19274,19275,19276,19277,19278,19279,19280,19281,19282,19283,19284,19285,19286,19287,19288,19289,19290,19291,19292,19293,19294,19295,19296,19297,19298,19299,19300,19301,19302,19303,19304,19305,19306,19307,19308,19309,19310,19311,19312,19313,19314,19315,19316,19317,19318,19319,19320,19321,19322,19323,19324,19325,19326,19327,19328,19329,19330,19331,19332,19333,19334,19335,19336,19337,19338,19339,19340,19341,19342,19343,19344,19345,19346,19347,19348,19349,19350,19351,19352,19353,19354,19355,19356,19357,19358,19359,19360,19361,19362,19363,19364,19365,19366,19367,19368,19369,19370,19371,19372,19373,19374,19375,19376,19377,19378,19379,19380,19381,19382,19383,19384,19385,19386,19387,19388,19389,19390,19391,19392,19393,19394,19395,19396,19397,19398,19399,19400,19401,19402,19403,19404,19405,19406,19407,19408,19409,19410,19411,19412,19413,19414,19415,19416,19417,19418,19419,19420,19421,19422,19423,19424,19425,19426,19427,19428,19429,19430,19431,19432,19433,19434,19435,19436,19437,19438,19439,19440,19441,19442,19443,19444,19445,19446,19447,19448,19449,19450,19451,19452,19453,19454,19455,19456,19457,19458,19459,19460,19461,19462,19463,19464,19465,19466,19467,19468,19469,19470,19471,19472,19473,19474,19475,19476,19477,19478,19479,19480,19481,19482,19483,19484,19485,19486,19487,19488,19489,19490,19491,19492,19493,19494,19495,19496,19497,19498,19499,19500,19501,19502,19503,19504,19505,19506,19507,19508,19509,19510,19511,19512,19513,19514,19515,19516,19517,19518,19519,19520,19521,19522,19523,19524,19525,19526,19527,19528,19529,19530,19531,19532,19533,19534,19535,19536,19537,19538,19539,19540,19541,19542,19543,19544,19545,19546,19547,19548,19549,19550,19551,19552,19553,19554,19555,19556,19557,19558,19559,19560,19561,19562,19563,19564,19565,19566,19567,19568,19569,19570,19571,19572,19573,19574,19575,19576,19577,19578,19579,19580,19581,19582,19583,19584,19585,19586,19587,19588,19589,19590,19591,19592,19593,19594,19595,19596,19597,19598,19599,19600,19601,19602,19603,19604,19605,19606,19607,19608,19609,19610,19611,19612,19613,19614,19615,19616,19617,19618,19619,19620,19621,19622,19623,19624,19625,19626,19627,19628,19629,19630,19631,19632,19633,19634,19635,19636,19637,19638,19639,19640,19641,19642,19643,19644,19645,19646,19647,19648,19649,19650,19651,19652,19653,19654,19655,19656,19657,19658,19659,19660,19661,19662,19663,19664,19665,19666,19667,19668,19669,19670,19671,19672,19673,19674,19675,19676,19677,19678,19679,19680,19681,19682,19683,19684,19685,19686,19687,19688,19689,19690,19691,19692,19693,19694,19695,19696,19697,19698,19699,19700,19701,19702,19703,19704,19705,19706,19707,19708,19709,19710,19711,19712,19713,19714,19715,19716,19717,19718,19719,19720,19721,19722,19723,19724,19725,19726,19727,19728,19729,19730,19731,19732,19733,19734,19735,19736,19737,19738,19739,19740,19741,19742,19743,19744,19745,19746,19747,19748,19749,19750,19751,19752,19753,19754,19755,19756,19757,19758,19759,19760,19761,19762,19763,19764,19765,19766,19767,19768,19769,19770,19771,19772,19773,19774,19775,19776,19777,19778,19779,19780,19781,19782,19783,19784,19785,19786,19787,19788,19789,19790,19791,19792,19793,19794,19795,19796,19797,19798,19799,19800,19801,19802,19803,19804,19805,19806,19807,19808,19809,19810,19811,19812,19813,19814,19815,19816,19817,19818,19819,19820,19821,19822,19823,19824,19825,19826,19827,19828,19829,19830,19831,19832,19833,19834,19835,19836,19837,19838,19839,19840,19841,19842,19843,19844,19845,19846,19847,19848,19849,19850,19851,19852,19853,19854,19855,19856,19857,19858,19859,19860,19861,19862,19863,19864,19865,19866,19867,19868,19869,19870,19871,19872,19873,19874,19875,19876,19877,19878,19879,19880,19881,19882,19883,19884,19885,19886,19887,19888,19889,19890,19891,19892,19893,19968,19969,19970,19971,19972,19973,19974,19975,19976,19977,19978,19979,19980,19981,19982,19983,19984,19985,19986,19987,19988,19989,19990,19991,19992,19993,19994,19995,19996,19997,19998,19999,20000,20001,20002,20003,20004,20005,20006,20007,20008,20009,20010,20011,20012,20013,20014,20015,20016,20017,20018,20019,20020,20021,20022,20023,20024,20025,20026,20027,20028,20029,20030,20031,20032,20033,20034,20035,20036,20037,20038,20039,20040,20041,20042,20043,20044,20045,20046,20047,20048,20049,20050,20051,20052,20053,20054,20055,20056,20057,20058,20059,20060,20061,20062,20063,20064,20065,20066,20067,20068,20069,20070,20071,20072,20073,20074,20075,20076,20077,20078,20079,20080,20081,20082,20083,20084,20085,20086,20087,20088,20089,20090,20091,20092,20093,20094,20095,20096,20097,20098,20099,20100,20101,20102,20103,20104,20105,20106,20107,20108,20109,20110,20111,20112,20113,20114,20115,20116,20117,20118,20119,20120,20121,20122,20123,20124,20125,20126,20127,20128,20129,20130,20131,20132,20133,20134,20135,20136,20137,20138,20139,20140,20141,20142,20143,20144,20145,20146,20147,20148,20149,20150,20151,20152,20153,20154,20155,20156,20157,20158,20159,20160,20161,20162,20163,20164,20165,20166,20167,20168,20169,20170,20171,20172,20173,20174,20175,20176,20177,20178,20179,20180,20181,20182,20183,20184,20185,20186,20187,20188,20189,20190,20191,20192,20193,20194,20195,20196,20197,20198,20199,20200,20201,20202,20203,20204,20205,20206,20207,20208,20209,20210,20211,20212,20213,20214,20215,20216,20217,20218,20219,20220,20221,20222,20223,20224,20225,20226,20227,20228,20229,20230,20231,20232,20233,20234,20235,20236,20237,20238,20239,20240,20241,20242,20243,20244,20245,20246,20247,20248,20249,20250,20251,20252,20253,20254,20255,20256,20257,20258,20259,20260,20261,20262,20263,20264,20265,20266,20267,20268,20269,20270,20271,20272,20273,20274,20275,20276,20277,20278,20279,20280,20281,20282,20283,20284,20285,20286,20287,20288,20289,20290,20291,20292,20293,20294,20295,20296,20297,20298,20299,20300,20301,20302,20303,20304,20305,20306,20307,20308,20309,20310,20311,20312,20313,20314,20315,20316,20317,20318,20319,20320,20321,20322,20323,20324,20325,20326,20327,20328,20329,20330,20331,20332,20333,20334,20335,20336,20337,20338,20339,20340,20341,20342,20343,20344,20345,20346,20347,20348,20349,20350,20351,20352,20353,20354,20355,20356,20357,20358,20359,20360,20361,20362,20363,20364,20365,20366,20367,20368,20369,20370,20371,20372,20373,20374,20375,20376,20377,20378,20379,20380,20381,20382,20383,20384,20385,20386,20387,20388,20389,20390,20391,20392,20393,20394,20395,20396,20397,20398,20399,20400,20401,20402,20403,20404,20405,20406,20407,20408,20409,20410,20411,20412,20413,20414,20415,20416,20417,20418,20419,20420,20421,20422,20423,20424,20425,20426,20427,20428,20429,20430,20431,20432,20433,20434,20435,20436,20437,20438,20439,20440,20441,20442,20443,20444,20445,20446,20447,20448,20449,20450,20451,20452,20453,20454,20455,20456,20457,20458,20459,20460,20461,20462,20463,20464,20465,20466,20467,20468,20469,20470,20471,20472,20473,20474,20475,20476,20477,20478,20479,20480,20481,20482,20483,20484,20485,20486,20487,20488,20489,20490,20491,20492,20493,20494,20495,20496,20497,20498,20499,20500,20501,20502,20503,20504,20505,20506,20507,20508,20509,20510,20511,20512,20513,20514,20515,20516,20517,20518,20519,20520,20521,20522,20523,20524,20525,20526,20527,20528,20529,20530,20531,20532,20533,20534,20535,20536,20537,20538,20539,20540,20541,20542,20543,20544,20545,20546,20547,20548,20549,20550,20551,20552,20553,20554,20555,20556,20557,20558,20559,20560,20561,20562,20563,20564,20565,20566,20567,20568,20569,20570,20571,20572,20573,20574,20575,20576,20577,20578,20579,20580,20581,20582,20583,20584,20585,20586,20587,20588,20589,20590,20591,20592,20593,20594,20595,20596,20597,20598,20599,20600,20601,20602,20603,20604,20605,20606,20607,20608,20609,20610,20611,20612,20613,20614,20615,20616,20617,20618,20619,20620,20621,20622,20623,20624,20625,20626,20627,20628,20629,20630,20631,20632,20633,20634,20635,20636,20637,20638,20639,20640,20641,20642,20643,20644,20645,20646,20647,20648,20649,20650,20651,20652,20653,20654,20655,20656,20657,20658,20659,20660,20661,20662,20663,20664,20665,20666,20667,20668,20669,20670,20671,20672,20673,20674,20675,20676,20677,20678,20679,20680,20681,20682,20683,20684,20685,20686,20687,20688,20689,20690,20691,20692,20693,20694,20695,20696,20697,20698,20699,20700,20701,20702,20703,20704,20705,20706,20707,20708,20709,20710,20711,20712,20713,20714,20715,20716,20717,20718,20719,20720,20721,20722,20723,20724,20725,20726,20727,20728,20729,20730,20731,20732,20733,20734,20735,20736,20737,20738,20739,20740,20741,20742,20743,20744,20745,20746,20747,20748,20749,20750,20751,20752,20753,20754,20755,20756,20757,20758,20759,20760,20761,20762,20763,20764,20765,20766,20767,20768,20769,20770,20771,20772,20773,20774,20775,20776,20777,20778,20779,20780,20781,20782,20783,20784,20785,20786,20787,20788,20789,20790,20791,20792,20793,20794,20795,20796,20797,20798,20799,20800,20801,20802,20803,20804,20805,20806,20807,20808,20809,20810,20811,20812,20813,20814,20815,20816,20817,20818,20819,20820,20821,20822,20823,20824,20825,20826,20827,20828,20829,20830,20831,20832,20833,20834,20835,20836,20837,20838,20839,20840,20841,20842,20843,20844,20845,20846,20847,20848,20849,20850,20851,20852,20853,20854,20855,20856,20857,20858,20859,20860,20861,20862,20863,20864,20865,20866,20867,20868,20869,20870,20871,20872,20873,20874,20875,20876,20877,20878,20879,20880,20881,20882,20883,20884,20885,20886,20887,20888,20889,20890,20891,20892,20893,20894,20895,20896,20897,20898,20899,20900,20901,20902,20903,20904,20905,20906,20907,20908,20909,20910,20911,20912,20913,20914,20915,20916,20917,20918,20919,20920,20921,20922,20923,20924,20925,20926,20927,20928,20929,20930,20931,20932,20933,20934,20935,20936,20937,20938,20939,20940,20941,20942,20943,20944,20945,20946,20947,20948,20949,20950,20951,20952,20953,20954,20955,20956,20957,20958,20959,20960,20961,20962,20963,20964,20965,20966,20967,20968,20969,20970,20971,20972,20973,20974,20975,20976,20977,20978,20979,20980,20981,20982,20983,20984,20985,20986,20987,20988,20989,20990,20991,20992,20993,20994,20995,20996,20997,20998,20999,21000,21001,21002,21003,21004,21005,21006,21007,21008,21009,21010,21011,21012,21013,21014,21015,21016,21017,21018,21019,21020,21021,21022,21023,21024,21025,21026,21027,21028,21029,21030,21031,21032,21033,21034,21035,21036,21037,21038,21039,21040,21041,21042,21043,21044,21045,21046,21047,21048,21049,21050,21051,21052,21053,21054,21055,21056,21057,21058,21059,21060,21061,21062,21063,21064,21065,21066,21067,21068,21069,21070,21071,21072,21073,21074,21075,21076,21077,21078,21079,21080,21081,21082,21083,21084,21085,21086,21087,21088,21089,21090,21091,21092,21093,21094,21095,21096,21097,21098,21099,21100,21101,21102,21103,21104,21105,21106,21107,21108,21109,21110,21111,21112,21113,21114,21115,21116,21117,21118,21119,21120,21121,21122,21123,21124,21125,21126,21127,21128,21129,21130,21131,21132,21133,21134,21135,21136,21137,21138,21139,21140,21141,21142,21143,21144,21145,21146,21147,21148,21149,21150,21151,21152,21153,21154,21155,21156,21157,21158,21159,21160,21161,21162,21163,21164,21165,21166,21167,21168,21169,21170,21171,21172,21173,21174,21175,21176,21177,21178,21179,21180,21181,21182,21183,21184,21185,21186,21187,21188,21189,21190,21191,21192,21193,21194,21195,21196,21197,21198,21199,21200,21201,21202,21203,21204,21205,21206,21207,21208,21209,21210,21211,21212,21213,21214,21215,21216,21217,21218,21219,21220,21221,21222,21223,21224,21225,21226,21227,21228,21229,21230,21231,21232,21233,21234,21235,21236,21237,21238,21239,21240,21241,21242,21243,21244,21245,21246,21247,21248,21249,21250,21251,21252,21253,21254,21255,21256,21257,21258,21259,21260,21261,21262,21263,21264,21265,21266,21267,21268,21269,21270,21271,21272,21273,21274,21275,21276,21277,21278,21279,21280,21281,21282,21283,21284,21285,21286,21287,21288,21289,21290,21291,21292,21293,21294,21295,21296,21297,21298,21299,21300,21301,21302,21303,21304,21305,21306,21307,21308,21309,21310,21311,21312,21313,21314,21315,21316,21317,21318,21319,21320,21321,21322,21323,21324,21325,21326,21327,21328,21329,21330,21331,21332,21333,21334,21335,21336,21337,21338,21339,21340,21341,21342,21343,21344,21345,21346,21347,21348,21349,21350,21351,21352,21353,21354,21355,21356,21357,21358,21359,21360,21361,21362,21363,21364,21365,21366,21367,21368,21369,21370,21371,21372,21373,21374,21375,21376,21377,21378,21379,21380,21381,21382,21383,21384,21385,21386,21387,21388,21389,21390,21391,21392,21393,21394,21395,21396,21397,21398,21399,21400,21401,21402,21403,21404,21405,21406,21407,21408,21409,21410,21411,21412,21413,21414,21415,21416,21417,21418,21419,21420,21421,21422,21423,21424,21425,21426,21427,21428,21429,21430,21431,21432,21433,21434,21435,21436,21437,21438,21439,21440,21441,21442,21443,21444,21445,21446,21447,21448,21449,21450,21451,21452,21453,21454,21455,21456,21457,21458,21459,21460,21461,21462,21463,21464,21465,21466,21467,21468,21469,21470,21471,21472,21473,21474,21475,21476,21477,21478,21479,21480,21481,21482,21483,21484,21485,21486,21487,21488,21489,21490,21491,21492,21493,21494,21495,21496,21497,21498,21499,21500,21501,21502,21503,21504,21505,21506,21507,21508,21509,21510,21511,21512,21513,21514,21515,21516,21517,21518,21519,21520,21521,21522,21523,21524,21525,21526,21527,21528,21529,21530,21531,21532,21533,21534,21535,21536,21537,21538,21539,21540,21541,21542,21543,21544,21545,21546,21547,21548,21549,21550,21551,21552,21553,21554,21555,21556,21557,21558,21559,21560,21561,21562,21563,21564,21565,21566,21567,21568,21569,21570,21571,21572,21573,21574,21575,21576,21577,21578,21579,21580,21581,21582,21583,21584,21585,21586,21587,21588,21589,21590,21591,21592,21593,21594,21595,21596,21597,21598,21599,21600,21601,21602,21603,21604,21605,21606,21607,21608,21609,21610,21611,21612,21613,21614,21615,21616,21617,21618,21619,21620,21621,21622,21623,21624,21625,21626,21627,21628,21629,21630,21631,21632,21633,21634,21635,21636,21637,21638,21639,21640,21641,21642,21643,21644,21645,21646,21647,21648,21649,21650,21651,21652,21653,21654,21655,21656,21657,21658,21659,21660,21661,21662,21663,21664,21665,21666,21667,21668,21669,21670,21671,21672,21673,21674,21675,21676,21677,21678,21679,21680,21681,21682,21683,21684,21685,21686,21687,21688,21689,21690,21691,21692,21693,21694,21695,21696,21697,21698,21699,21700,21701,21702,21703,21704,21705,21706,21707,21708,21709,21710,21711,21712,21713,21714,21715,21716,21717,21718,21719,21720,21721,21722,21723,21724,21725,21726,21727,21728,21729,21730,21731,21732,21733,21734,21735,21736,21737,21738,21739,21740,21741,21742,21743,21744,21745,21746,21747,21748,21749,21750,21751,21752,21753,21754,21755,21756,21757,21758,21759,21760,21761,21762,21763,21764,21765,21766,21767,21768,21769,21770,21771,21772,21773,21774,21775,21776,21777,21778,21779,21780,21781,21782,21783,21784,21785,21786,21787,21788,21789,21790,21791,21792,21793,21794,21795,21796,21797,21798,21799,21800,21801,21802,21803,21804,21805,21806,21807,21808,21809,21810,21811,21812,21813,21814,21815,21816,21817,21818,21819,21820,21821,21822,21823,21824,21825,21826,21827,21828,21829,21830,21831,21832,21833,21834,21835,21836,21837,21838,21839,21840,21841,21842,21843,21844,21845,21846,21847,21848,21849,21850,21851,21852,21853,21854,21855,21856,21857,21858,21859,21860,21861,21862,21863,21864,21865,21866,21867,21868,21869,21870,21871,21872,21873,21874,21875,21876,21877,21878,21879,21880,21881,21882,21883,21884,21885,21886,21887,21888,21889,21890,21891,21892,21893,21894,21895,21896,21897,21898,21899,21900,21901,21902,21903,21904,21905,21906,21907,21908,21909,21910,21911,21912,21913,21914,21915,21916,21917,21918,21919,21920,21921,21922,21923,21924,21925,21926,21927,21928,21929,21930,21931,21932,21933,21934,21935,21936,21937,21938,21939,21940,21941,21942,21943,21944,21945,21946,21947,21948,21949,21950,21951,21952,21953,21954,21955,21956,21957,21958,21959,21960,21961,21962,21963,21964,21965,21966,21967,21968,21969,21970,21971,21972,21973,21974,21975,21976,21977,21978,21979,21980,21981,21982,21983,21984,21985,21986,21987,21988,21989,21990,21991,21992,21993,21994,21995,21996,21997,21998,21999,22000,22001,22002,22003,22004,22005,22006,22007,22008,22009,22010,22011,22012,22013,22014,22015,22016,22017,22018,22019,22020,22021,22022,22023,22024,22025,22026,22027,22028,22029,22030,22031,22032,22033,22034,22035,22036,22037,22038,22039,22040,22041,22042,22043,22044,22045,22046,22047,22048,22049,22050,22051,22052,22053,22054,22055,22056,22057,22058,22059,22060,22061,22062,22063,22064,22065,22066,22067,22068,22069,22070,22071,22072,22073,22074,22075,22076,22077,22078,22079,22080,22081,22082,22083,22084,22085,22086,22087,22088,22089,22090,22091,22092,22093,22094,22095,22096,22097,22098,22099,22100,22101,22102,22103,22104,22105,22106,22107,22108,22109,22110,22111,22112,22113,22114,22115,22116,22117,22118,22119,22120,22121,22122,22123,22124,22125,22126,22127,22128,22129,22130,22131,22132,22133,22134,22135,22136,22137,22138,22139,22140,22141,22142,22143,22144,22145,22146,22147,22148,22149,22150,22151,22152,22153,22154,22155,22156,22157,22158,22159,22160,22161,22162,22163,22164,22165,22166,22167,22168,22169,22170,22171,22172,22173,22174,22175,22176,22177,22178,22179,22180,22181,22182,22183,22184,22185,22186,22187,22188,22189,22190,22191,22192,22193,22194,22195,22196,22197,22198,22199,22200,22201,22202,22203,22204,22205,22206,22207,22208,22209,22210,22211,22212,22213,22214,22215,22216,22217,22218,22219,22220,22221,22222,22223,22224,22225,22226,22227,22228,22229,22230,22231,22232,22233,22234,22235,22236,22237,22238,22239,22240,22241,22242,22243,22244,22245,22246,22247,22248,22249,22250,22251,22252,22253,22254,22255,22256,22257,22258,22259,22260,22261,22262,22263,22264,22265,22266,22267,22268,22269,22270,22271,22272,22273,22274,22275,22276,22277,22278,22279,22280,22281,22282,22283,22284,22285,22286,22287,22288,22289,22290,22291,22292,22293,22294,22295,22296,22297,22298,22299,22300,22301,22302,22303,22304,22305,22306,22307,22308,22309,22310,22311,22312,22313,22314,22315,22316,22317,22318,22319,22320,22321,22322,22323,22324,22325,22326,22327,22328,22329,22330,22331,22332,22333,22334,22335,22336,22337,22338,22339,22340,22341,22342,22343,22344,22345,22346,22347,22348,22349,22350,22351,22352,22353,22354,22355,22356,22357,22358,22359,22360,22361,22362,22363,22364,22365,22366,22367,22368,22369,22370,22371,22372,22373,22374,22375,22376,22377,22378,22379,22380,22381,22382,22383,22384,22385,22386,22387,22388,22389,22390,22391,22392,22393,22394,22395,22396,22397,22398,22399,22400,22401,22402,22403,22404,22405,22406,22407,22408,22409,22410,22411,22412,22413,22414,22415,22416,22417,22418,22419,22420,22421,22422,22423,22424,22425,22426,22427,22428,22429,22430,22431,22432,22433,22434,22435,22436,22437,22438,22439,22440,22441,22442,22443,22444,22445,22446,22447,22448,22449,22450,22451,22452,22453,22454,22455,22456,22457,22458,22459,22460,22461,22462,22463,22464,22465,22466,22467,22468,22469,22470,22471,22472,22473,22474,22475,22476,22477,22478,22479,22480,22481,22482,22483,22484,22485,22486,22487,22488,22489,22490,22491,22492,22493,22494,22495,22496,22497,22498,22499,22500,22501,22502,22503,22504,22505,22506,22507,22508,22509,22510,22511,22512,22513,22514,22515,22516,22517,22518,22519,22520,22521,22522,22523,22524,22525,22526,22527,22528,22529,22530,22531,22532,22533,22534,22535,22536,22537,22538,22539,22540,22541,22542,22543,22544,22545,22546,22547,22548,22549,22550,22551,22552,22553,22554,22555,22556,22557,22558,22559,22560,22561,22562,22563,22564,22565,22566,22567,22568,22569,22570,22571,22572,22573,22574,22575,22576,22577,22578,22579,22580,22581,22582,22583,22584,22585,22586,22587,22588,22589,22590,22591,22592,22593,22594,22595,22596,22597,22598,22599,22600,22601,22602,22603,22604,22605,22606,22607,22608,22609,22610,22611,22612,22613,22614,22615,22616,22617,22618,22619,22620,22621,22622,22623,22624,22625,22626,22627,22628,22629,22630,22631,22632,22633,22634,22635,22636,22637,22638,22639,22640,22641,22642,22643,22644,22645,22646,22647,22648,22649,22650,22651,22652,22653,22654,22655,22656,22657,22658,22659,22660,22661,22662,22663,22664,22665,22666,22667,22668,22669,22670,22671,22672,22673,22674,22675,22676,22677,22678,22679,22680,22681,22682,22683,22684,22685,22686,22687,22688,22689,22690,22691,22692,22693,22694,22695,22696,22697,22698,22699,22700,22701,22702,22703,22704,22705,22706,22707,22708,22709,22710,22711,22712,22713,22714,22715,22716,22717,22718,22719,22720,22721,22722,22723,22724,22725,22726,22727,22728,22729,22730,22731,22732,22733,22734,22735,22736,22737,22738,22739,22740,22741,22742,22743,22744,22745,22746,22747,22748,22749,22750,22751,22752,22753,22754,22755,22756,22757,22758,22759,22760,22761,22762,22763,22764,22765,22766,22767,22768,22769,22770,22771,22772,22773,22774,22775,22776,22777,22778,22779,22780,22781,22782,22783,22784,22785,22786,22787,22788,22789,22790,22791,22792,22793,22794,22795,22796,22797,22798,22799,22800,22801,22802,22803,22804,22805,22806,22807,22808,22809,22810,22811,22812,22813,22814,22815,22816,22817,22818,22819,22820,22821,22822,22823,22824,22825,22826,22827,22828,22829,22830,22831,22832,22833,22834,22835,22836,22837,22838,22839,22840,22841,22842,22843,22844,22845,22846,22847,22848,22849,22850,22851,22852,22853,22854,22855,22856,22857,22858,22859,22860,22861,22862,22863,22864,22865,22866,22867,22868,22869,22870,22871,22872,22873,22874,22875,22876,22877,22878,22879,22880,22881,22882,22883,22884,22885,22886,22887,22888,22889,22890,22891,22892,22893,22894,22895,22896,22897,22898,22899,22900,22901,22902,22903,22904,22905,22906,22907,22908,22909,22910,22911,22912,22913,22914,22915,22916,22917,22918,22919,22920,22921,22922,22923,22924,22925,22926,22927,22928,22929,22930,22931,22932,22933,22934,22935,22936,22937,22938,22939,22940,22941,22942,22943,22944,22945,22946,22947,22948,22949,22950,22951,22952,22953,22954,22955,22956,22957,22958,22959,22960,22961,22962,22963,22964,22965,22966,22967,22968,22969,22970,22971,22972,22973,22974,22975,22976,22977,22978,22979,22980,22981,22982,22983,22984,22985,22986,22987,22988,22989,22990,22991,22992,22993,22994,22995,22996,22997,22998,22999,23000,23001,23002,23003,23004,23005,23006,23007,23008,23009,23010,23011,23012,23013,23014,23015,23016,23017,23018,23019,23020,23021,23022,23023,23024,23025,23026,23027,23028,23029,23030,23031,23032,23033,23034,23035,23036,23037,23038,23039,23040,23041,23042,23043,23044,23045,23046,23047,23048,23049,23050,23051,23052,23053,23054,23055,23056,23057,23058,23059,23060,23061,23062,23063,23064,23065,23066,23067,23068,23069,23070,23071,23072,23073,23074,23075,23076,23077,23078,23079,23080,23081,23082,23083,23084,23085,23086,23087,23088,23089,23090,23091,23092,23093,23094,23095,23096,23097,23098,23099,23100,23101,23102,23103,23104,23105,23106,23107,23108,23109,23110,23111,23112,23113,23114,23115,23116,23117,23118,23119,23120,23121,23122,23123,23124,23125,23126,23127,23128,23129,23130,23131,23132,23133,23134,23135,23136,23137,23138,23139,23140,23141,23142,23143,23144,23145,23146,23147,23148,23149,23150,23151,23152,23153,23154,23155,23156,23157,23158,23159,23160,23161,23162,23163,23164,23165,23166,23167,23168,23169,23170,23171,23172,23173,23174,23175,23176,23177,23178,23179,23180,23181,23182,23183,23184,23185,23186,23187,23188,23189,23190,23191,23192,23193,23194,23195,23196,23197,23198,23199,23200,23201,23202,23203,23204,23205,23206,23207,23208,23209,23210,23211,23212,23213,23214,23215,23216,23217,23218,23219,23220,23221,23222,23223,23224,23225,23226,23227,23228,23229,23230,23231,23232,23233,23234,23235,23236,23237,23238,23239,23240,23241,23242,23243,23244,23245,23246,23247,23248,23249,23250,23251,23252,23253,23254,23255,23256,23257,23258,23259,23260,23261,23262,23263,23264,23265,23266,23267,23268,23269,23270,23271,23272,23273,23274,23275,23276,23277,23278,23279,23280,23281,23282,23283,23284,23285,23286,23287,23288,23289,23290,23291,23292,23293,23294,23295,23296,23297,23298,23299,23300,23301,23302,23303,23304,23305,23306,23307,23308,23309,23310,23311,23312,23313,23314,23315,23316,23317,23318,23319,23320,23321,23322,23323,23324,23325,23326,23327,23328,23329,23330,23331,23332,23333,23334,23335,23336,23337,23338,23339,23340,23341,23342,23343,23344,23345,23346,23347,23348,23349,23350,23351,23352,23353,23354,23355,23356,23357,23358,23359,23360,23361,23362,23363,23364,23365,23366,23367,23368,23369,23370,23371,23372,23373,23374,23375,23376,23377,23378,23379,23380,23381,23382,23383,23384,23385,23386,23387,23388,23389,23390,23391,23392,23393,23394,23395,23396,23397,23398,23399,23400,23401,23402,23403,23404,23405,23406,23407,23408,23409,23410,23411,23412,23413,23414,23415,23416,23417,23418,23419,23420,23421,23422,23423,23424,23425,23426,23427,23428,23429,23430,23431,23432,23433,23434,23435,23436,23437,23438,23439,23440,23441,23442,23443,23444,23445,23446,23447,23448,23449,23450,23451,23452,23453,23454,23455,23456,23457,23458,23459,23460,23461,23462,23463,23464,23465,23466,23467,23468,23469,23470,23471,23472,23473,23474,23475,23476,23477,23478,23479,23480,23481,23482,23483,23484,23485,23486,23487,23488,23489,23490,23491,23492,23493,23494,23495,23496,23497,23498,23499,23500,23501,23502,23503,23504,23505,23506,23507,23508,23509,23510,23511,23512,23513,23514,23515,23516,23517,23518,23519,23520,23521,23522,23523,23524,23525,23526,23527,23528,23529,23530,23531,23532,23533,23534,23535,23536,23537,23538,23539,23540,23541,23542,23543,23544,23545,23546,23547,23548,23549,23550,23551,23552,23553,23554,23555,23556,23557,23558,23559,23560,23561,23562,23563,23564,23565,23566,23567,23568,23569,23570,23571,23572,23573,23574,23575,23576,23577,23578,23579,23580,23581,23582,23583,23584,23585,23586,23587,23588,23589,23590,23591,23592,23593,23594,23595,23596,23597,23598,23599,23600,23601,23602,23603,23604,23605,23606,23607,23608,23609,23610,23611,23612,23613,23614,23615,23616,23617,23618,23619,23620,23621,23622,23623,23624,23625,23626,23627,23628,23629,23630,23631,23632,23633,23634,23635,23636,23637,23638,23639,23640,23641,23642,23643,23644,23645,23646,23647,23648,23649,23650,23651,23652,23653,23654,23655,23656,23657,23658,23659,23660,23661,23662,23663,23664,23665,23666,23667,23668,23669,23670,23671,23672,23673,23674,23675,23676,23677,23678,23679,23680,23681,23682,23683,23684,23685,23686,23687,23688,23689,23690,23691,23692,23693,23694,23695,23696,23697,23698,23699,23700,23701,23702,23703,23704,23705,23706,23707,23708,23709,23710,23711,23712,23713,23714,23715,23716,23717,23718,23719,23720,23721,23722,23723,23724,23725,23726,23727,23728,23729,23730,23731,23732,23733,23734,23735,23736,23737,23738,23739,23740,23741,23742,23743,23744,23745,23746,23747,23748,23749,23750,23751,23752,23753,23754,23755,23756,23757,23758,23759,23760,23761,23762,23763,23764,23765,23766,23767,23768,23769,23770,23771,23772,23773,23774,23775,23776,23777,23778,23779,23780,23781,23782,23783,23784,23785,23786,23787,23788,23789,23790,23791,23792,23793,23794,23795,23796,23797,23798,23799,23800,23801,23802,23803,23804,23805,23806,23807,23808,23809,23810,23811,23812,23813,23814,23815,23816,23817,23818,23819,23820,23821,23822,23823,23824,23825,23826,23827,23828,23829,23830,23831,23832,23833,23834,23835,23836,23837,23838,23839,23840,23841,23842,23843,23844,23845,23846,23847,23848,23849,23850,23851,23852,23853,23854,23855,23856,23857,23858,23859,23860,23861,23862,23863,23864,23865,23866,23867,23868,23869,23870,23871,23872,23873,23874,23875,23876,23877,23878,23879,23880,23881,23882,23883,23884,23885,23886,23887,23888,23889,23890,23891,23892,23893,23894,23895,23896,23897,23898,23899,23900,23901,23902,23903,23904,23905,23906,23907,23908,23909,23910,23911,23912,23913,23914,23915,23916,23917,23918,23919,23920,23921,23922,23923,23924,23925,23926,23927,23928,23929,23930,23931,23932,23933,23934,23935,23936,23937,23938,23939,23940,23941,23942,23943,23944,23945,23946,23947,23948,23949,23950,23951,23952,23953,23954,23955,23956,23957,23958,23959,23960,23961,23962,23963,23964,23965,23966,23967,23968,23969,23970,23971,23972,23973,23974,23975,23976,23977,23978,23979,23980,23981,23982,23983,23984,23985,23986,23987,23988,23989,23990,23991,23992,23993,23994,23995,23996,23997,23998,23999,24000,24001,24002,24003,24004,24005,24006,24007,24008,24009,24010,24011,24012,24013,24014,24015,24016,24017,24018,24019,24020,24021,24022,24023,24024,24025,24026,24027,24028,24029,24030,24031,24032,24033,24034,24035,24036,24037,24038,24039,24040,24041,24042,24043,24044,24045,24046,24047,24048,24049,24050,24051,24052,24053,24054,24055,24056,24057,24058,24059,24060,24061,24062,24063,24064,24065,24066,24067,24068,24069,24070,24071,24072,24073,24074,24075,24076,24077,24078,24079,24080,24081,24082,24083,24084,24085,24086,24087,24088,24089,24090,24091,24092,24093,24094,24095,24096,24097,24098,24099,24100,24101,24102,24103,24104,24105,24106,24107,24108,24109,24110,24111,24112,24113,24114,24115,24116,24117,24118,24119,24120,24121,24122,24123,24124,24125,24126,24127,24128,24129,24130,24131,24132,24133,24134,24135,24136,24137,24138,24139,24140,24141,24142,24143,24144,24145,24146,24147,24148,24149,24150,24151,24152,24153,24154,24155,24156,24157,24158,24159,24160,24161,24162,24163,24164,24165,24166,24167,24168,24169,24170,24171,24172,24173,24174,24175,24176,24177,24178,24179,24180,24181,24182,24183,24184,24185,24186,24187,24188,24189,24190,24191,24192,24193,24194,24195,24196,24197,24198,24199,24200,24201,24202,24203,24204,24205,24206,24207,24208,24209,24210,24211,24212,24213,24214,24215,24216,24217,24218,24219,24220,24221,24222,24223,24224,24225,24226,24227,24228,24229,24230,24231,24232,24233,24234,24235,24236,24237,24238,24239,24240,24241,24242,24243,24244,24245,24246,24247,24248,24249,24250,24251,24252,24253,24254,24255,24256,24257,24258,24259,24260,24261,24262,24263,24264,24265,24266,24267,24268,24269,24270,24271,24272,24273,24274,24275,24276,24277,24278,24279,24280,24281,24282,24283,24284,24285,24286,24287,24288,24289,24290,24291,24292,24293,24294,24295,24296,24297,24298,24299,24300,24301,24302,24303,24304,24305,24306,24307,24308,24309,24310,24311,24312,24313,24314,24315,24316,24317,24318,24319,24320,24321,24322,24323,24324,24325,24326,24327,24328,24329,24330,24331,24332,24333,24334,24335,24336,24337,24338,24339,24340,24341,24342,24343,24344,24345,24346,24347,24348,24349,24350,24351,24352,24353,24354,24355,24356,24357,24358,24359,24360,24361,24362,24363,24364,24365,24366,24367,24368,24369,24370,24371,24372,24373,24374,24375,24376,24377,24378,24379,24380,24381,24382,24383,24384,24385,24386,24387,24388,24389,24390,24391,24392,24393,24394,24395,24396,24397,24398,24399,24400,24401,24402,24403,24404,24405,24406,24407,24408,24409,24410,24411,24412,24413,24414,24415,24416,24417,24418,24419,24420,24421,24422,24423,24424,24425,24426,24427,24428,24429,24430,24431,24432,24433,24434,24435,24436,24437,24438,24439,24440,24441,24442,24443,24444,24445,24446,24447,24448,24449,24450,24451,24452,24453,24454,24455,24456,24457,24458,24459,24460,24461,24462,24463,24464,24465,24466,24467,24468,24469,24470,24471,24472,24473,24474,24475,24476,24477,24478,24479,24480,24481,24482,24483,24484,24485,24486,24487,24488,24489,24490,24491,24492,24493,24494,24495,24496,24497,24498,24499,24500,24501,24502,24503,24504,24505,24506,24507,24508,24509,24510,24511,24512,24513,24514,24515,24516,24517,24518,24519,24520,24521,24522,24523,24524,24525,24526,24527,24528,24529,24530,24531,24532,24533,24534,24535,24536,24537,24538,24539,24540,24541,24542,24543,24544,24545,24546,24547,24548,24549,24550,24551,24552,24553,24554,24555,24556,24557,24558,24559,24560,24561,24562,24563,24564,24565,24566,24567,24568,24569,24570,24571,24572,24573,24574,24575,24576,24577,24578,24579,24580,24581,24582,24583,24584,24585,24586,24587,24588,24589,24590,24591,24592,24593,24594,24595,24596,24597,24598,24599,24600,24601,24602,24603,24604,24605,24606,24607,24608,24609,24610,24611,24612,24613,24614,24615,24616,24617,24618,24619,24620,24621,24622,24623,24624,24625,24626,24627,24628,24629,24630,24631,24632,24633,24634,24635,24636,24637,24638,24639,24640,24641,24642,24643,24644,24645,24646,24647,24648,24649,24650,24651,24652,24653,24654,24655,24656,24657,24658,24659,24660,24661,24662,24663,24664,24665,24666,24667,24668,24669,24670,24671,24672,24673,24674,24675,24676,24677,24678,24679,24680,24681,24682,24683,24684,24685,24686,24687,24688,24689,24690,24691,24692,24693,24694,24695,24696,24697,24698,24699,24700,24701,24702,24703,24704,24705,24706,24707,24708,24709,24710,24711,24712,24713,24714,24715,24716,24717,24718,24719,24720,24721,24722,24723,24724,24725,24726,24727,24728,24729,24730,24731,24732,24733,24734,24735,24736,24737,24738,24739,24740,24741,24742,24743,24744,24745,24746,24747,24748,24749,24750,24751,24752,24753,24754,24755,24756,24757,24758,24759,24760,24761,24762,24763,24764,24765,24766,24767,24768,24769,24770,24771,24772,24773,24774,24775,24776,24777,24778,24779,24780,24781,24782,24783,24784,24785,24786,24787,24788,24789,24790,24791,24792,24793,24794,24795,24796,24797,24798,24799,24800,24801,24802,24803,24804,24805,24806,24807,24808,24809,24810,24811,24812,24813,24814,24815,24816,24817,24818,24819,24820,24821,24822,24823,24824,24825,24826,24827,24828,24829,24830,24831,24832,24833,24834,24835,24836,24837,24838,24839,24840,24841,24842,24843,24844,24845,24846,24847,24848,24849,24850,24851,24852,24853,24854,24855,24856,24857,24858,24859,24860,24861,24862,24863,24864,24865,24866,24867,24868,24869,24870,24871,24872,24873,24874,24875,24876,24877,24878,24879,24880,24881,24882,24883,24884,24885,24886,24887,24888,24889,24890,24891,24892,24893,24894,24895,24896,24897,24898,24899,24900,24901,24902,24903,24904,24905,24906,24907,24908,24909,24910,24911,24912,24913,24914,24915,24916,24917,24918,24919,24920,24921,24922,24923,24924,24925,24926,24927,24928,24929,24930,24931,24932,24933,24934,24935,24936,24937,24938,24939,24940,24941,24942,24943,24944,24945,24946,24947,24948,24949,24950,24951,24952,24953,24954,24955,24956,24957,24958,24959,24960,24961,24962,24963,24964,24965,24966,24967,24968,24969,24970,24971,24972,24973,24974,24975,24976,24977,24978,24979,24980,24981,24982,24983,24984,24985,24986,24987,24988,24989,24990,24991,24992,24993,24994,24995,24996,24997,24998,24999,25000,25001,25002,25003,25004,25005,25006,25007,25008,25009,25010,25011,25012,25013,25014,25015,25016,25017,25018,25019,25020,25021,25022,25023,25024,25025,25026,25027,25028,25029,25030,25031,25032,25033,25034,25035,25036,25037,25038,25039,25040,25041,25042,25043,25044,25045,25046,25047,25048,25049,25050,25051,25052,25053,25054,25055,25056,25057,25058,25059,25060,25061,25062,25063,25064,25065,25066,25067,25068,25069,25070,25071,25072,25073,25074,25075,25076,25077,25078,25079,25080,25081,25082,25083,25084,25085,25086,25087,25088,25089,25090,25091,25092,25093,25094,25095,25096,25097,25098,25099,25100,25101,25102,25103,25104,25105,25106,25107,25108,25109,25110,25111,25112,25113,25114,25115,25116,25117,25118,25119,25120,25121,25122,25123,25124,25125,25126,25127,25128,25129,25130,25131,25132,25133,25134,25135,25136,25137,25138,25139,25140,25141,25142,25143,25144,25145,25146,25147,25148,25149,25150,25151,25152,25153,25154,25155,25156,25157,25158,25159,25160,25161,25162,25163,25164,25165,25166,25167,25168,25169,25170,25171,25172,25173,25174,25175,25176,25177,25178,25179,25180,25181,25182,25183,25184,25185,25186,25187,25188,25189,25190,25191,25192,25193,25194,25195,25196,25197,25198,25199,25200,25201,25202,25203,25204,25205,25206,25207,25208,25209,25210,25211,25212,25213,25214,25215,25216,25217,25218,25219,25220,25221,25222,25223,25224,25225,25226,25227,25228,25229,25230,25231,25232,25233,25234,25235,25236,25237,25238,25239,25240,25241,25242,25243,25244,25245,25246,25247,25248,25249,25250,25251,25252,25253,25254,25255,25256,25257,25258,25259,25260,25261,25262,25263,25264,25265,25266,25267,25268,25269,25270,25271,25272,25273,25274,25275,25276,25277,25278,25279,25280,25281,25282,25283,25284,25285,25286,25287,25288,25289,25290,25291,25292,25293,25294,25295,25296,25297,25298,25299,25300,25301,25302,25303,25304,25305,25306,25307,25308,25309,25310,25311,25312,25313,25314,25315,25316,25317,25318,25319,25320,25321,25322,25323,25324,25325,25326,25327,25328,25329,25330,25331,25332,25333,25334,25335,25336,25337,25338,25339,25340,25341,25342,25343,25344,25345,25346,25347,25348,25349,25350,25351,25352,25353,25354,25355,25356,25357,25358,25359,25360,25361,25362,25363,25364,25365,25366,25367,25368,25369,25370,25371,25372,25373,25374,25375,25376,25377,25378,25379,25380,25381,25382,25383,25384,25385,25386,25387,25388,25389,25390,25391,25392,25393,25394,25395,25396,25397,25398,25399,25400,25401,25402,25403,25404,25405,25406,25407,25408,25409,25410,25411,25412,25413,25414,25415,25416,25417,25418,25419,25420,25421,25422,25423,25424,25425,25426,25427,25428,25429,25430,25431,25432,25433,25434,25435,25436,25437,25438,25439,25440,25441,25442,25443,25444,25445,25446,25447,25448,25449,25450,25451,25452,25453,25454,25455,25456,25457,25458,25459,25460,25461,25462,25463,25464,25465,25466,25467,25468,25469,25470,25471,25472,25473,25474,25475,25476,25477,25478,25479,25480,25481,25482,25483,25484,25485,25486,25487,25488,25489,25490,25491,25492,25493,25494,25495,25496,25497,25498,25499,25500,25501,25502,25503,25504,25505,25506,25507,25508,25509,25510,25511,25512,25513,25514,25515,25516,25517,25518,25519,25520,25521,25522,25523,25524,25525,25526,25527,25528,25529,25530,25531,25532,25533,25534,25535,25536,25537,25538,25539,25540,25541,25542,25543,25544,25545,25546,25547,25548,25549,25550,25551,25552,25553,25554,25555,25556,25557,25558,25559,25560,25561,25562,25563,25564,25565,25566,25567,25568,25569,25570,25571,25572,25573,25574,25575,25576,25577,25578,25579,25580,25581,25582,25583,25584,25585,25586,25587,25588,25589,25590,25591,25592,25593,25594,25595,25596,25597,25598,25599,25600,25601,25602,25603,25604,25605,25606,25607,25608,25609,25610,25611,25612,25613,25614,25615,25616,25617,25618,25619,25620,25621,25622,25623,25624,25625,25626,25627,25628,25629,25630,25631,25632,25633,25634,25635,25636,25637,25638,25639,25640,25641,25642,25643,25644,25645,25646,25647,25648,25649,25650,25651,25652,25653,25654,25655,25656,25657,25658,25659,25660,25661,25662,25663,25664,25665,25666,25667,25668,25669,25670,25671,25672,25673,25674,25675,25676,25677,25678,25679,25680,25681,25682,25683,25684,25685,25686,25687,25688,25689,25690,25691,25692,25693,25694,25695,25696,25697,25698,25699,25700,25701,25702,25703,25704,25705,25706,25707,25708,25709,25710,25711,25712,25713,25714,25715,25716,25717,25718,25719,25720,25721,25722,25723,25724,25725,25726,25727,25728,25729,25730,25731,25732,25733,25734,25735,25736,25737,25738,25739,25740,25741,25742,25743,25744,25745,25746,25747,25748,25749,25750,25751,25752,25753,25754,25755,25756,25757,25758,25759,25760,25761,25762,25763,25764,25765,25766,25767,25768,25769,25770,25771,25772,25773,25774,25775,25776,25777,25778,25779,25780,25781,25782,25783,25784,25785,25786,25787,25788,25789,25790,25791,25792,25793,25794,25795,25796,25797,25798,25799,25800,25801,25802,25803,25804,25805,25806,25807,25808,25809,25810,25811,25812,25813,25814,25815,25816,25817,25818,25819,25820,25821,25822,25823,25824,25825,25826,25827,25828,25829,25830,25831,25832,25833,25834,25835,25836,25837,25838,25839,25840,25841,25842,25843,25844,25845,25846,25847,25848,25849,25850,25851,25852,25853,25854,25855,25856,25857,25858,25859,25860,25861,25862,25863,25864,25865,25866,25867,25868,25869,25870,25871,25872,25873,25874,25875,25876,25877,25878,25879,25880,25881,25882,25883,25884,25885,25886,25887,25888,25889,25890,25891,25892,25893,25894,25895,25896,25897,25898,25899,25900,25901,25902,25903,25904,25905,25906,25907,25908,25909,25910,25911,25912,25913,25914,25915,25916,25917,25918,25919,25920,25921,25922,25923,25924,25925,25926,25927,25928,25929,25930,25931,25932,25933,25934,25935,25936,25937,25938,25939,25940,25941,25942,25943,25944,25945,25946,25947,25948,25949,25950,25951,25952,25953,25954,25955,25956,25957,25958,25959,25960,25961,25962,25963,25964,25965,25966,25967,25968,25969,25970,25971,25972,25973,25974,25975,25976,25977,25978,25979,25980,25981,25982,25983,25984,25985,25986,25987,25988,25989,25990,25991,25992,25993,25994,25995,25996,25997,25998,25999,26000,26001,26002,26003,26004,26005,26006,26007,26008,26009,26010,26011,26012,26013,26014,26015,26016,26017,26018,26019,26020,26021,26022,26023,26024,26025,26026,26027,26028,26029,26030,26031,26032,26033,26034,26035,26036,26037,26038,26039,26040,26041,26042,26043,26044,26045,26046,26047,26048,26049,26050,26051,26052,26053,26054,26055,26056,26057,26058,26059,26060,26061,26062,26063,26064,26065,26066,26067,26068,26069,26070,26071,26072,26073,26074,26075,26076,26077,26078,26079,26080,26081,26082,26083,26084,26085,26086,26087,26088,26089,26090,26091,26092,26093,26094,26095,26096,26097,26098,26099,26100,26101,26102,26103,26104,26105,26106,26107,26108,26109,26110,26111,26112,26113,26114,26115,26116,26117,26118,26119,26120,26121,26122,26123,26124,26125,26126,26127,26128,26129,26130,26131,26132,26133,26134,26135,26136,26137,26138,26139,26140,26141,26142,26143,26144,26145,26146,26147,26148,26149,26150,26151,26152,26153,26154,26155,26156,26157,26158,26159,26160,26161,26162,26163,26164,26165,26166,26167,26168,26169,26170,26171,26172,26173,26174,26175,26176,26177,26178,26179,26180,26181,26182,26183,26184,26185,26186,26187,26188,26189,26190,26191,26192,26193,26194,26195,26196,26197,26198,26199,26200,26201,26202,26203,26204,26205,26206,26207,26208,26209,26210,26211,26212,26213,26214,26215,26216,26217,26218,26219,26220,26221,26222,26223,26224,26225,26226,26227,26228,26229,26230,26231,26232,26233,26234,26235,26236,26237,26238,26239,26240,26241,26242,26243,26244,26245,26246,26247,26248,26249,26250,26251,26252,26253,26254,26255,26256,26257,26258,26259,26260,26261,26262,26263,26264,26265,26266,26267,26268,26269,26270,26271,26272,26273,26274,26275,26276,26277,26278,26279,26280,26281,26282,26283,26284,26285,26286,26287,26288,26289,26290,26291,26292,26293,26294,26295,26296,26297,26298,26299,26300,26301,26302,26303,26304,26305,26306,26307,26308,26309,26310,26311,26312,26313,26314,26315,26316,26317,26318,26319,26320,26321,26322,26323,26324,26325,26326,26327,26328,26329,26330,26331,26332,26333,26334,26335,26336,26337,26338,26339,26340,26341,26342,26343,26344,26345,26346,26347,26348,26349,26350,26351,26352,26353,26354,26355,26356,26357,26358,26359,26360,26361,26362,26363,26364,26365,26366,26367,26368,26369,26370,26371,26372,26373,26374,26375,26376,26377,26378,26379,26380,26381,26382,26383,26384,26385,26386,26387,26388,26389,26390,26391,26392,26393,26394,26395,26396,26397,26398,26399,26400,26401,26402,26403,26404,26405,26406,26407,26408,26409,26410,26411,26412,26413,26414,26415,26416,26417,26418,26419,26420,26421,26422,26423,26424,26425,26426,26427,26428,26429,26430,26431,26432,26433,26434,26435,26436,26437,26438,26439,26440,26441,26442,26443,26444,26445,26446,26447,26448,26449,26450,26451,26452,26453,26454,26455,26456,26457,26458,26459,26460,26461,26462,26463,26464,26465,26466,26467,26468,26469,26470,26471,26472,26473,26474,26475,26476,26477,26478,26479,26480,26481,26482,26483,26484,26485,26486,26487,26488,26489,26490,26491,26492,26493,26494,26495,26496,26497,26498,26499,26500,26501,26502,26503,26504,26505,26506,26507,26508,26509,26510,26511,26512,26513,26514,26515,26516,26517,26518,26519,26520,26521,26522,26523,26524,26525,26526,26527,26528,26529,26530,26531,26532,26533,26534,26535,26536,26537,26538,26539,26540,26541,26542,26543,26544,26545,26546,26547,26548,26549,26550,26551,26552,26553,26554,26555,26556,26557,26558,26559,26560,26561,26562,26563,26564,26565,26566,26567,26568,26569,26570,26571,26572,26573,26574,26575,26576,26577,26578,26579,26580,26581,26582,26583,26584,26585,26586,26587,26588,26589,26590,26591,26592,26593,26594,26595,26596,26597,26598,26599,26600,26601,26602,26603,26604,26605,26606,26607,26608,26609,26610,26611,26612,26613,26614,26615,26616,26617,26618,26619,26620,26621,26622,26623,26624,26625,26626,26627,26628,26629,26630,26631,26632,26633,26634,26635,26636,26637,26638,26639,26640,26641,26642,26643,26644,26645,26646,26647,26648,26649,26650,26651,26652,26653,26654,26655,26656,26657,26658,26659,26660,26661,26662,26663,26664,26665,26666,26667,26668,26669,26670,26671,26672,26673,26674,26675,26676,26677,26678,26679,26680,26681,26682,26683,26684,26685,26686,26687,26688,26689,26690,26691,26692,26693,26694,26695,26696,26697,26698,26699,26700,26701,26702,26703,26704,26705,26706,26707,26708,26709,26710,26711,26712,26713,26714,26715,26716,26717,26718,26719,26720,26721,26722,26723,26724,26725,26726,26727,26728,26729,26730,26731,26732,26733,26734,26735,26736,26737,26738,26739,26740,26741,26742,26743,26744,26745,26746,26747,26748,26749,26750,26751,26752,26753,26754,26755,26756,26757,26758,26759,26760,26761,26762,26763,26764,26765,26766,26767,26768,26769,26770,26771,26772,26773,26774,26775,26776,26777,26778,26779,26780,26781,26782,26783,26784,26785,26786,26787,26788,26789,26790,26791,26792,26793,26794,26795,26796,26797,26798,26799,26800,26801,26802,26803,26804,26805,26806,26807,26808,26809,26810,26811,26812,26813,26814,26815,26816,26817,26818,26819,26820,26821,26822,26823,26824,26825,26826,26827,26828,26829,26830,26831,26832,26833,26834,26835,26836,26837,26838,26839,26840,26841,26842,26843,26844,26845,26846,26847,26848,26849,26850,26851,26852,26853,26854,26855,26856,26857,26858,26859,26860,26861,26862,26863,26864,26865,26866,26867,26868,26869,26870,26871,26872,26873,26874,26875,26876,26877,26878,26879,26880,26881,26882,26883,26884,26885,26886,26887,26888,26889,26890,26891,26892,26893,26894,26895,26896,26897,26898,26899,26900,26901,26902,26903,26904,26905,26906,26907,26908,26909,26910,26911,26912,26913,26914,26915,26916,26917,26918,26919,26920,26921,26922,26923,26924,26925,26926,26927,26928,26929,26930,26931,26932,26933,26934,26935,26936,26937,26938,26939,26940,26941,26942,26943,26944,26945,26946,26947,26948,26949,26950,26951,26952,26953,26954,26955,26956,26957,26958,26959,26960,26961,26962,26963,26964,26965,26966,26967,26968,26969,26970,26971,26972,26973,26974,26975,26976,26977,26978,26979,26980,26981,26982,26983,26984,26985,26986,26987,26988,26989,26990,26991,26992,26993,26994,26995,26996,26997,26998,26999,27000,27001,27002,27003,27004,27005,27006,27007,27008,27009,27010,27011,27012,27013,27014,27015,27016,27017,27018,27019,27020,27021,27022,27023,27024,27025,27026,27027,27028,27029,27030,27031,27032,27033,27034,27035,27036,27037,27038,27039,27040,27041,27042,27043,27044,27045,27046,27047,27048,27049,27050,27051,27052,27053,27054,27055,27056,27057,27058,27059,27060,27061,27062,27063,27064,27065,27066,27067,27068,27069,27070,27071,27072,27073,27074,27075,27076,27077,27078,27079,27080,27081,27082,27083,27084,27085,27086,27087,27088,27089,27090,27091,27092,27093,27094,27095,27096,27097,27098,27099,27100,27101,27102,27103,27104,27105,27106,27107,27108,27109,27110,27111,27112,27113,27114,27115,27116,27117,27118,27119,27120,27121,27122,27123,27124,27125,27126,27127,27128,27129,27130,27131,27132,27133,27134,27135,27136,27137,27138,27139,27140,27141,27142,27143,27144,27145,27146,27147,27148,27149,27150,27151,27152,27153,27154,27155,27156,27157,27158,27159,27160,27161,27162,27163,27164,27165,27166,27167,27168,27169,27170,27171,27172,27173,27174,27175,27176,27177,27178,27179,27180,27181,27182,27183,27184,27185,27186,27187,27188,27189,27190,27191,27192,27193,27194,27195,27196,27197,27198,27199,27200,27201,27202,27203,27204,27205,27206,27207,27208,27209,27210,27211,27212,27213,27214,27215,27216,27217,27218,27219,27220,27221,27222,27223,27224,27225,27226,27227,27228,27229,27230,27231,27232,27233,27234,27235,27236,27237,27238,27239,27240,27241,27242,27243,27244,27245,27246,27247,27248,27249,27250,27251,27252,27253,27254,27255,27256,27257,27258,27259,27260,27261,27262,27263,27264,27265,27266,27267,27268,27269,27270,27271,27272,27273,27274,27275,27276,27277,27278,27279,27280,27281,27282,27283,27284,27285,27286,27287,27288,27289,27290,27291,27292,27293,27294,27295,27296,27297,27298,27299,27300,27301,27302,27303,27304,27305,27306,27307,27308,27309,27310,27311,27312,27313,27314,27315,27316,27317,27318,27319,27320,27321,27322,27323,27324,27325,27326,27327,27328,27329,27330,27331,27332,27333,27334,27335,27336,27337,27338,27339,27340,27341,27342,27343,27344,27345,27346,27347,27348,27349,27350,27351,27352,27353,27354,27355,27356,27357,27358,27359,27360,27361,27362,27363,27364,27365,27366,27367,27368,27369,27370,27371,27372,27373,27374,27375,27376,27377,27378,27379,27380,27381,27382,27383,27384,27385,27386,27387,27388,27389,27390,27391,27392,27393,27394,27395,27396,27397,27398,27399,27400,27401,27402,27403,27404,27405,27406,27407,27408,27409,27410,27411,27412,27413,27414,27415,27416,27417,27418,27419,27420,27421,27422,27423,27424,27425,27426,27427,27428,27429,27430,27431,27432,27433,27434,27435,27436,27437,27438,27439,27440,27441,27442,27443,27444,27445,27446,27447,27448,27449,27450,27451,27452,27453,27454,27455,27456,27457,27458,27459,27460,27461,27462,27463,27464,27465,27466,27467,27468,27469,27470,27471,27472,27473,27474,27475,27476,27477,27478,27479,27480,27481,27482,27483,27484,27485,27486,27487,27488,27489,27490,27491,27492,27493,27494,27495,27496,27497,27498,27499,27500,27501,27502,27503,27504,27505,27506,27507,27508,27509,27510,27511,27512,27513,27514,27515,27516,27517,27518,27519,27520,27521,27522,27523,27524,27525,27526,27527,27528,27529,27530,27531,27532,27533,27534,27535,27536,27537,27538,27539,27540,27541,27542,27543,27544,27545,27546,27547,27548,27549,27550,27551,27552,27553,27554,27555,27556,27557,27558,27559,27560,27561,27562,27563,27564,27565,27566,27567,27568,27569,27570,27571,27572,27573,27574,27575,27576,27577,27578,27579,27580,27581,27582,27583,27584,27585,27586,27587,27588,27589,27590,27591,27592,27593,27594,27595,27596,27597,27598,27599,27600,27601,27602,27603,27604,27605,27606,27607,27608,27609,27610,27611,27612,27613,27614,27615,27616,27617,27618,27619,27620,27621,27622,27623,27624,27625,27626,27627,27628,27629,27630,27631,27632,27633,27634,27635,27636,27637,27638,27639,27640,27641,27642,27643,27644,27645,27646,27647,27648,27649,27650,27651,27652,27653,27654,27655,27656,27657,27658,27659,27660,27661,27662,27663,27664,27665,27666,27667,27668,27669,27670,27671,27672,27673,27674,27675,27676,27677,27678,27679,27680,27681,27682,27683,27684,27685,27686,27687,27688,27689,27690,27691,27692,27693,27694,27695,27696,27697,27698,27699,27700,27701,27702,27703,27704,27705,27706,27707,27708,27709,27710,27711,27712,27713,27714,27715,27716,27717,27718,27719,27720,27721,27722,27723,27724,27725,27726,27727,27728,27729,27730,27731,27732,27733,27734,27735,27736,27737,27738,27739,27740,27741,27742,27743,27744,27745,27746,27747,27748,27749,27750,27751,27752,27753,27754,27755,27756,27757,27758,27759,27760,27761,27762,27763,27764,27765,27766,27767,27768,27769,27770,27771,27772,27773,27774,27775,27776,27777,27778,27779,27780,27781,27782,27783,27784,27785,27786,27787,27788,27789,27790,27791,27792,27793,27794,27795,27796,27797,27798,27799,27800,27801,27802,27803,27804,27805,27806,27807,27808,27809,27810,27811,27812,27813,27814,27815,27816,27817,27818,27819,27820,27821,27822,27823,27824,27825,27826,27827,27828,27829,27830,27831,27832,27833,27834,27835,27836,27837,27838,27839,27840,27841,27842,27843,27844,27845,27846,27847,27848,27849,27850,27851,27852,27853,27854,27855,27856,27857,27858,27859,27860,27861,27862,27863,27864,27865,27866,27867,27868,27869,27870,27871,27872,27873,27874,27875,27876,27877,27878,27879,27880,27881,27882,27883,27884,27885,27886,27887,27888,27889,27890,27891,27892,27893,27894,27895,27896,27897,27898,27899,27900,27901,27902,27903,27904,27905,27906,27907,27908,27909,27910,27911,27912,27913,27914,27915,27916,27917,27918,27919,27920,27921,27922,27923,27924,27925,27926,27927,27928,27929,27930,27931,27932,27933,27934,27935,27936,27937,27938,27939,27940,27941,27942,27943,27944,27945,27946,27947,27948,27949,27950,27951,27952,27953,27954,27955,27956,27957,27958,27959,27960,27961,27962,27963,27964,27965,27966,27967,27968,27969,27970,27971,27972,27973,27974,27975,27976,27977,27978,27979,27980,27981,27982,27983,27984,27985,27986,27987,27988,27989,27990,27991,27992,27993,27994,27995,27996,27997,27998,27999,28000,28001,28002,28003,28004,28005,28006,28007,28008,28009,28010,28011,28012,28013,28014,28015,28016,28017,28018,28019,28020,28021,28022,28023,28024,28025,28026,28027,28028,28029,28030,28031,28032,28033,28034,28035,28036,28037,28038,28039,28040,28041,28042,28043,28044,28045,28046,28047,28048,28049,28050,28051,28052,28053,28054,28055,28056,28057,28058,28059,28060,28061,28062,28063,28064,28065,28066,28067,28068,28069,28070,28071,28072,28073,28074,28075,28076,28077,28078,28079,28080,28081,28082,28083,28084,28085,28086,28087,28088,28089,28090,28091,28092,28093,28094,28095,28096,28097,28098,28099,28100,28101,28102,28103,28104,28105,28106,28107,28108,28109,28110,28111,28112,28113,28114,28115,28116,28117,28118,28119,28120,28121,28122,28123,28124,28125,28126,28127,28128,28129,28130,28131,28132,28133,28134,28135,28136,28137,28138,28139,28140,28141,28142,28143,28144,28145,28146,28147,28148,28149,28150,28151,28152,28153,28154,28155,28156,28157,28158,28159,28160,28161,28162,28163,28164,28165,28166,28167,28168,28169,28170,28171,28172,28173,28174,28175,28176,28177,28178,28179,28180,28181,28182,28183,28184,28185,28186,28187,28188,28189,28190,28191,28192,28193,28194,28195,28196,28197,28198,28199,28200,28201,28202,28203,28204,28205,28206,28207,28208,28209,28210,28211,28212,28213,28214,28215,28216,28217,28218,28219,28220,28221,28222,28223,28224,28225,28226,28227,28228,28229,28230,28231,28232,28233,28234,28235,28236,28237,28238,28239,28240,28241,28242,28243,28244,28245,28246,28247,28248,28249,28250,28251,28252,28253,28254,28255,28256,28257,28258,28259,28260,28261,28262,28263,28264,28265,28266,28267,28268,28269,28270,28271,28272,28273,28274,28275,28276,28277,28278,28279,28280,28281,28282,28283,28284,28285,28286,28287,28288,28289,28290,28291,28292,28293,28294,28295,28296,28297,28298,28299,28300,28301,28302,28303,28304,28305,28306,28307,28308,28309,28310,28311,28312,28313,28314,28315,28316,28317,28318,28319,28320,28321,28322,28323,28324,28325,28326,28327,28328,28329,28330,28331,28332,28333,28334,28335,28336,28337,28338,28339,28340,28341,28342,28343,28344,28345,28346,28347,28348,28349,28350,28351,28352,28353,28354,28355,28356,28357,28358,28359,28360,28361,28362,28363,28364,28365,28366,28367,28368,28369,28370,28371,28372,28373,28374,28375,28376,28377,28378,28379,28380,28381,28382,28383,28384,28385,28386,28387,28388,28389,28390,28391,28392,28393,28394,28395,28396,28397,28398,28399,28400,28401,28402,28403,28404,28405,28406,28407,28408,28409,28410,28411,28412,28413,28414,28415,28416,28417,28418,28419,28420,28421,28422,28423,28424,28425,28426,28427,28428,28429,28430,28431,28432,28433,28434,28435,28436,28437,28438,28439,28440,28441,28442,28443,28444,28445,28446,28447,28448,28449,28450,28451,28452,28453,28454,28455,28456,28457,28458,28459,28460,28461,28462,28463,28464,28465,28466,28467,28468,28469,28470,28471,28472,28473,28474,28475,28476,28477,28478,28479,28480,28481,28482,28483,28484,28485,28486,28487,28488,28489,28490,28491,28492,28493,28494,28495,28496,28497,28498,28499,28500,28501,28502,28503,28504,28505,28506,28507,28508,28509,28510,28511,28512,28513,28514,28515,28516,28517,28518,28519,28520,28521,28522,28523,28524,28525,28526,28527,28528,28529,28530,28531,28532,28533,28534,28535,28536,28537,28538,28539,28540,28541,28542,28543,28544,28545,28546,28547,28548,28549,28550,28551,28552,28553,28554,28555,28556,28557,28558,28559,28560,28561,28562,28563,28564,28565,28566,28567,28568,28569,28570,28571,28572,28573,28574,28575,28576,28577,28578,28579,28580,28581,28582,28583,28584,28585,28586,28587,28588,28589,28590,28591,28592,28593,28594,28595,28596,28597,28598,28599,28600,28601,28602,28603,28604,28605,28606,28607,28608,28609,28610,28611,28612,28613,28614,28615,28616,28617,28618,28619,28620,28621,28622,28623,28624,28625,28626,28627,28628,28629,28630,28631,28632,28633,28634,28635,28636,28637,28638,28639,28640,28641,28642,28643,28644,28645,28646,28647,28648,28649,28650,28651,28652,28653,28654,28655,28656,28657,28658,28659,28660,28661,28662,28663,28664,28665,28666,28667,28668,28669,28670,28671,28672,28673,28674,28675,28676,28677,28678,28679,28680,28681,28682,28683,28684,28685,28686,28687,28688,28689,28690,28691,28692,28693,28694,28695,28696,28697,28698,28699,28700,28701,28702,28703,28704,28705,28706,28707,28708,28709,28710,28711,28712,28713,28714,28715,28716,28717,28718,28719,28720,28721,28722,28723,28724,28725,28726,28727,28728,28729,28730,28731,28732,28733,28734,28735,28736,28737,28738,28739,28740,28741,28742,28743,28744,28745,28746,28747,28748,28749,28750,28751,28752,28753,28754,28755,28756,28757,28758,28759,28760,28761,28762,28763,28764,28765,28766,28767,28768,28769,28770,28771,28772,28773,28774,28775,28776,28777,28778,28779,28780,28781,28782,28783,28784,28785,28786,28787,28788,28789,28790,28791,28792,28793,28794,28795,28796,28797,28798,28799,28800,28801,28802,28803,28804,28805,28806,28807,28808,28809,28810,28811,28812,28813,28814,28815,28816,28817,28818,28819,28820,28821,28822,28823,28824,28825,28826,28827,28828,28829,28830,28831,28832,28833,28834,28835,28836,28837,28838,28839,28840,28841,28842,28843,28844,28845,28846,28847,28848,28849,28850,28851,28852,28853,28854,28855,28856,28857,28858,28859,28860,28861,28862,28863,28864,28865,28866,28867,28868,28869,28870,28871,28872,28873,28874,28875,28876,28877,28878,28879,28880,28881,28882,28883,28884,28885,28886,28887,28888,28889,28890,28891,28892,28893,28894,28895,28896,28897,28898,28899,28900,28901,28902,28903,28904,28905,28906,28907,28908,28909,28910,28911,28912,28913,28914,28915,28916,28917,28918,28919,28920,28921,28922,28923,28924,28925,28926,28927,28928,28929,28930,28931,28932,28933,28934,28935,28936,28937,28938,28939,28940,28941,28942,28943,28944,28945,28946,28947,28948,28949,28950,28951,28952,28953,28954,28955,28956,28957,28958,28959,28960,28961,28962,28963,28964,28965,28966,28967,28968,28969,28970,28971,28972,28973,28974,28975,28976,28977,28978,28979,28980,28981,28982,28983,28984,28985,28986,28987,28988,28989,28990,28991,28992,28993,28994,28995,28996,28997,28998,28999,29000,29001,29002,29003,29004,29005,29006,29007,29008,29009,29010,29011,29012,29013,29014,29015,29016,29017,29018,29019,29020,29021,29022,29023,29024,29025,29026,29027,29028,29029,29030,29031,29032,29033,29034,29035,29036,29037,29038,29039,29040,29041,29042,29043,29044,29045,29046,29047,29048,29049,29050,29051,29052,29053,29054,29055,29056,29057,29058,29059,29060,29061,29062,29063,29064,29065,29066,29067,29068,29069,29070,29071,29072,29073,29074,29075,29076,29077,29078,29079,29080,29081,29082,29083,29084,29085,29086,29087,29088,29089,29090,29091,29092,29093,29094,29095,29096,29097,29098,29099,29100,29101,29102,29103,29104,29105,29106,29107,29108,29109,29110,29111,29112,29113,29114,29115,29116,29117,29118,29119,29120,29121,29122,29123,29124,29125,29126,29127,29128,29129,29130,29131,29132,29133,29134,29135,29136,29137,29138,29139,29140,29141,29142,29143,29144,29145,29146,29147,29148,29149,29150,29151,29152,29153,29154,29155,29156,29157,29158,29159,29160,29161,29162,29163,29164,29165,29166,29167,29168,29169,29170,29171,29172,29173,29174,29175,29176,29177,29178,29179,29180,29181,29182,29183,29184,29185,29186,29187,29188,29189,29190,29191,29192,29193,29194,29195,29196,29197,29198,29199,29200,29201,29202,29203,29204,29205,29206,29207,29208,29209,29210,29211,29212,29213,29214,29215,29216,29217,29218,29219,29220,29221,29222,29223,29224,29225,29226,29227,29228,29229,29230,29231,29232,29233,29234,29235,29236,29237,29238,29239,29240,29241,29242,29243,29244,29245,29246,29247,29248,29249,29250,29251,29252,29253,29254,29255,29256,29257,29258,29259,29260,29261,29262,29263,29264,29265,29266,29267,29268,29269,29270,29271,29272,29273,29274,29275,29276,29277,29278,29279,29280,29281,29282,29283,29284,29285,29286,29287,29288,29289,29290,29291,29292,29293,29294,29295,29296,29297,29298,29299,29300,29301,29302,29303,29304,29305,29306,29307,29308,29309,29310,29311,29312,29313,29314,29315,29316,29317,29318,29319,29320,29321,29322,29323,29324,29325,29326,29327,29328,29329,29330,29331,29332,29333,29334,29335,29336,29337,29338,29339,29340,29341,29342,29343,29344,29345,29346,29347,29348,29349,29350,29351,29352,29353,29354,29355,29356,29357,29358,29359,29360,29361,29362,29363,29364,29365,29366,29367,29368,29369,29370,29371,29372,29373,29374,29375,29376,29377,29378,29379,29380,29381,29382,29383,29384,29385,29386,29387,29388,29389,29390,29391,29392,29393,29394,29395,29396,29397,29398,29399,29400,29401,29402,29403,29404,29405,29406,29407,29408,29409,29410,29411,29412,29413,29414,29415,29416,29417,29418,29419,29420,29421,29422,29423,29424,29425,29426,29427,29428,29429,29430,29431,29432,29433,29434,29435,29436,29437,29438,29439,29440,29441,29442,29443,29444,29445,29446,29447,29448,29449,29450,29451,29452,29453,29454,29455,29456,29457,29458,29459,29460,29461,29462,29463,29464,29465,29466,29467,29468,29469,29470,29471,29472,29473,29474,29475,29476,29477,29478,29479,29480,29481,29482,29483,29484,29485,29486,29487,29488,29489,29490,29491,29492,29493,29494,29495,29496,29497,29498,29499,29500,29501,29502,29503,29504,29505,29506,29507,29508,29509,29510,29511,29512,29513,29514,29515,29516,29517,29518,29519,29520,29521,29522,29523,29524,29525,29526,29527,29528,29529,29530,29531,29532,29533,29534,29535,29536,29537,29538,29539,29540,29541,29542,29543,29544,29545,29546,29547,29548,29549,29550,29551,29552,29553,29554,29555,29556,29557,29558,29559,29560,29561,29562,29563,29564,29565,29566,29567,29568,29569,29570,29571,29572,29573,29574,29575,29576,29577,29578,29579,29580,29581,29582,29583,29584,29585,29586,29587,29588,29589,29590,29591,29592,29593,29594,29595,29596,29597,29598,29599,29600,29601,29602,29603,29604,29605,29606,29607,29608,29609,29610,29611,29612,29613,29614,29615,29616,29617,29618,29619,29620,29621,29622,29623,29624,29625,29626,29627,29628,29629,29630,29631,29632,29633,29634,29635,29636,29637,29638,29639,29640,29641,29642,29643,29644,29645,29646,29647,29648,29649,29650,29651,29652,29653,29654,29655,29656,29657,29658,29659,29660,29661,29662,29663,29664,29665,29666,29667,29668,29669,29670,29671,29672,29673,29674,29675,29676,29677,29678,29679,29680,29681,29682,29683,29684,29685,29686,29687,29688,29689,29690,29691,29692,29693,29694,29695,29696,29697,29698,29699,29700,29701,29702,29703,29704,29705,29706,29707,29708,29709,29710,29711,29712,29713,29714,29715,29716,29717,29718,29719,29720,29721,29722,29723,29724,29725,29726,29727,29728,29729,29730,29731,29732,29733,29734,29735,29736,29737,29738,29739,29740,29741,29742,29743,29744,29745,29746,29747,29748,29749,29750,29751,29752,29753,29754,29755,29756,29757,29758,29759,29760,29761,29762,29763,29764,29765,29766,29767,29768,29769,29770,29771,29772,29773,29774,29775,29776,29777,29778,29779,29780,29781,29782,29783,29784,29785,29786,29787,29788,29789,29790,29791,29792,29793,29794,29795,29796,29797,29798,29799,29800,29801,29802,29803,29804,29805,29806,29807,29808,29809,29810,29811,29812,29813,29814,29815,29816,29817,29818,29819,29820,29821,29822,29823,29824,29825,29826,29827,29828,29829,29830,29831,29832,29833,29834,29835,29836,29837,29838,29839,29840,29841,29842,29843,29844,29845,29846,29847,29848,29849,29850,29851,29852,29853,29854,29855,29856,29857,29858,29859,29860,29861,29862,29863,29864,29865,29866,29867,29868,29869,29870,29871,29872,29873,29874,29875,29876,29877,29878,29879,29880,29881,29882,29883,29884,29885,29886,29887,29888,29889,29890,29891,29892,29893,29894,29895,29896,29897,29898,29899,29900,29901,29902,29903,29904,29905,29906,29907,29908,29909,29910,29911,29912,29913,29914,29915,29916,29917,29918,29919,29920,29921,29922,29923,29924,29925,29926,29927,29928,29929,29930,29931,29932,29933,29934,29935,29936,29937,29938,29939,29940,29941,29942,29943,29944,29945,29946,29947,29948,29949,29950,29951,29952,29953,29954,29955,29956,29957,29958,29959,29960,29961,29962,29963,29964,29965,29966,29967,29968,29969,29970,29971,29972,29973,29974,29975,29976,29977,29978,29979,29980,29981,29982,29983,29984,29985,29986,29987,29988,29989,29990,29991,29992,29993,29994,29995,29996,29997,29998,29999,30000,30001,30002,30003,30004,30005,30006,30007,30008,30009,30010,30011,30012,30013,30014,30015,30016,30017,30018,30019,30020,30021,30022,30023,30024,30025,30026,30027,30028,30029,30030,30031,30032,30033,30034,30035,30036,30037,30038,30039,30040,30041,30042,30043,30044,30045,30046,30047,30048,30049,30050,30051,30052,30053,30054,30055,30056,30057,30058,30059,30060,30061,30062,30063,30064,30065,30066,30067,30068,30069,30070,30071,30072,30073,30074,30075,30076,30077,30078,30079,30080,30081,30082,30083,30084,30085,30086,30087,30088,30089,30090,30091,30092,30093,30094,30095,30096,30097,30098,30099,30100,30101,30102,30103,30104,30105,30106,30107,30108,30109,30110,30111,30112,30113,30114,30115,30116,30117,30118,30119,30120,30121,30122,30123,30124,30125,30126,30127,30128,30129,30130,30131,30132,30133,30134,30135,30136,30137,30138,30139,30140,30141,30142,30143,30144,30145,30146,30147,30148,30149,30150,30151,30152,30153,30154,30155,30156,30157,30158,30159,30160,30161,30162,30163,30164,30165,30166,30167,30168,30169,30170,30171,30172,30173,30174,30175,30176,30177,30178,30179,30180,30181,30182,30183,30184,30185,30186,30187,30188,30189,30190,30191,30192,30193,30194,30195,30196,30197,30198,30199,30200,30201,30202,30203,30204,30205,30206,30207,30208,30209,30210,30211,30212,30213,30214,30215,30216,30217,30218,30219,30220,30221,30222,30223,30224,30225,30226,30227,30228,30229,30230,30231,30232,30233,30234,30235,30236,30237,30238,30239,30240,30241,30242,30243,30244,30245,30246,30247,30248,30249,30250,30251,30252,30253,30254,30255,30256,30257,30258,30259,30260,30261,30262,30263,30264,30265,30266,30267,30268,30269,30270,30271,30272,30273,30274,30275,30276,30277,30278,30279,30280,30281,30282,30283,30284,30285,30286,30287,30288,30289,30290,30291,30292,30293,30294,30295,30296,30297,30298,30299,30300,30301,30302,30303,30304,30305,30306,30307,30308,30309,30310,30311,30312,30313,30314,30315,30316,30317,30318,30319,30320,30321,30322,30323,30324,30325,30326,30327,30328,30329,30330,30331,30332,30333,30334,30335,30336,30337,30338,30339,30340,30341,30342,30343,30344,30345,30346,30347,30348,30349,30350,30351,30352,30353,30354,30355,30356,30357,30358,30359,30360,30361,30362,30363,30364,30365,30366,30367,30368,30369,30370,30371,30372,30373,30374,30375,30376,30377,30378,30379,30380,30381,30382,30383,30384,30385,30386,30387,30388,30389,30390,30391,30392,30393,30394,30395,30396,30397,30398,30399,30400,30401,30402,30403,30404,30405,30406,30407,30408,30409,30410,30411,30412,30413,30414,30415,30416,30417,30418,30419,30420,30421,30422,30423,30424,30425,30426,30427,30428,30429,30430,30431,30432,30433,30434,30435,30436,30437,30438,30439,30440,30441,30442,30443,30444,30445,30446,30447,30448,30449,30450,30451,30452,30453,30454,30455,30456,30457,30458,30459,30460,30461,30462,30463,30464,30465,30466,30467,30468,30469,30470,30471,30472,30473,30474,30475,30476,30477,30478,30479,30480,30481,30482,30483,30484,30485,30486,30487,30488,30489,30490,30491,30492,30493,30494,30495,30496,30497,30498,30499,30500,30501,30502,30503,30504,30505,30506,30507,30508,30509,30510,30511,30512,30513,30514,30515,30516,30517,30518,30519,30520,30521,30522,30523,30524,30525,30526,30527,30528,30529,30530,30531,30532,30533,30534,30535,30536,30537,30538,30539,30540,30541,30542,30543,30544,30545,30546,30547,30548,30549,30550,30551,30552,30553,30554,30555,30556,30557,30558,30559,30560,30561,30562,30563,30564,30565,30566,30567,30568,30569,30570,30571,30572,30573,30574,30575,30576,30577,30578,30579,30580,30581,30582,30583,30584,30585,30586,30587,30588,30589,30590,30591,30592,30593,30594,30595,30596,30597,30598,30599,30600,30601,30602,30603,30604,30605,30606,30607,30608,30609,30610,30611,30612,30613,30614,30615,30616,30617,30618,30619,30620,30621,30622,30623,30624,30625,30626,30627,30628,30629,30630,30631,30632,30633,30634,30635,30636,30637,30638,30639,30640,30641,30642,30643,30644,30645,30646,30647,30648,30649,30650,30651,30652,30653,30654,30655,30656,30657,30658,30659,30660,30661,30662,30663,30664,30665,30666,30667,30668,30669,30670,30671,30672,30673,30674,30675,30676,30677,30678,30679,30680,30681,30682,30683,30684,30685,30686,30687,30688,30689,30690,30691,30692,30693,30694,30695,30696,30697,30698,30699,30700,30701,30702,30703,30704,30705,30706,30707,30708,30709,30710,30711,30712,30713,30714,30715,30716,30717,30718,30719,30720,30721,30722,30723,30724,30725,30726,30727,30728,30729,30730,30731,30732,30733,30734,30735,30736,30737,30738,30739,30740,30741,30742,30743,30744,30745,30746,30747,30748,30749,30750,30751,30752,30753,30754,30755,30756,30757,30758,30759,30760,30761,30762,30763,30764,30765,30766,30767,30768,30769,30770,30771,30772,30773,30774,30775,30776,30777,30778,30779,30780,30781,30782,30783,30784,30785,30786,30787,30788,30789,30790,30791,30792,30793,30794,30795,30796,30797,30798,30799,30800,30801,30802,30803,30804,30805,30806,30807,30808,30809,30810,30811,30812,30813,30814,30815,30816,30817,30818,30819,30820,30821,30822,30823,30824,30825,30826,30827,30828,30829,30830,30831,30832,30833,30834,30835,30836,30837,30838,30839,30840,30841,30842,30843,30844,30845,30846,30847,30848,30849,30850,30851,30852,30853,30854,30855,30856,30857,30858,30859,30860,30861,30862,30863,30864,30865,30866,30867,30868,30869,30870,30871,30872,30873,30874,30875,30876,30877,30878,30879,30880,30881,30882,30883,30884,30885,30886,30887,30888,30889,30890,30891,30892,30893,30894,30895,30896,30897,30898,30899,30900,30901,30902,30903,30904,30905,30906,30907,30908,30909,30910,30911,30912,30913,30914,30915,30916,30917,30918,30919,30920,30921,30922,30923,30924,30925,30926,30927,30928,30929,30930,30931,30932,30933,30934,30935,30936,30937,30938,30939,30940,30941,30942,30943,30944,30945,30946,30947,30948,30949,30950,30951,30952,30953,30954,30955,30956,30957,30958,30959,30960,30961,30962,30963,30964,30965,30966,30967,30968,30969,30970,30971,30972,30973,30974,30975,30976,30977,30978,30979,30980,30981,30982,30983,30984,30985,30986,30987,30988,30989,30990,30991,30992,30993,30994,30995,30996,30997,30998,30999,31000,31001,31002,31003,31004,31005,31006,31007,31008,31009,31010,31011,31012,31013,31014,31015,31016,31017,31018,31019,31020,31021,31022,31023,31024,31025,31026,31027,31028,31029,31030,31031,31032,31033,31034,31035,31036,31037,31038,31039,31040,31041,31042,31043,31044,31045,31046,31047,31048,31049,31050,31051,31052,31053,31054,31055,31056,31057,31058,31059,31060,31061,31062,31063,31064,31065,31066,31067,31068,31069,31070,31071,31072,31073,31074,31075,31076,31077,31078,31079,31080,31081,31082,31083,31084,31085,31086,31087,31088,31089,31090,31091,31092,31093,31094,31095,31096,31097,31098,31099,31100,31101,31102,31103,31104,31105,31106,31107,31108,31109,31110,31111,31112,31113,31114,31115,31116,31117,31118,31119,31120,31121,31122,31123,31124,31125,31126,31127,31128,31129,31130,31131,31132,31133,31134,31135,31136,31137,31138,31139,31140,31141,31142,31143,31144,31145,31146,31147,31148,31149,31150,31151,31152,31153,31154,31155,31156,31157,31158,31159,31160,31161,31162,31163,31164,31165,31166,31167,31168,31169,31170,31171,31172,31173,31174,31175,31176,31177,31178,31179,31180,31181,31182,31183,31184,31185,31186,31187,31188,31189,31190,31191,31192,31193,31194,31195,31196,31197,31198,31199,31200,31201,31202,31203,31204,31205,31206,31207,31208,31209,31210,31211,31212,31213,31214,31215,31216,31217,31218,31219,31220,31221,31222,31223,31224,31225,31226,31227,31228,31229,31230,31231,31232,31233,31234,31235,31236,31237,31238,31239,31240,31241,31242,31243,31244,31245,31246,31247,31248,31249,31250,31251,31252,31253,31254,31255,31256,31257,31258,31259,31260,31261,31262,31263,31264,31265,31266,31267,31268,31269,31270,31271,31272,31273,31274,31275,31276,31277,31278,31279,31280,31281,31282,31283,31284,31285,31286,31287,31288,31289,31290,31291,31292,31293,31294,31295,31296,31297,31298,31299,31300,31301,31302,31303,31304,31305,31306,31307,31308,31309,31310,31311,31312,31313,31314,31315,31316,31317,31318,31319,31320,31321,31322,31323,31324,31325,31326,31327,31328,31329,31330,31331,31332,31333,31334,31335,31336,31337,31338,31339,31340,31341,31342,31343,31344,31345,31346,31347,31348,31349,31350,31351,31352,31353,31354,31355,31356,31357,31358,31359,31360,31361,31362,31363,31364,31365,31366,31367,31368,31369,31370,31371,31372,31373,31374,31375,31376,31377,31378,31379,31380,31381,31382,31383,31384,31385,31386,31387,31388,31389,31390,31391,31392,31393,31394,31395,31396,31397,31398,31399,31400,31401,31402,31403,31404,31405,31406,31407,31408,31409,31410,31411,31412,31413,31414,31415,31416,31417,31418,31419,31420,31421,31422,31423,31424,31425,31426,31427,31428,31429,31430,31431,31432,31433,31434,31435,31436,31437,31438,31439,31440,31441,31442,31443,31444,31445,31446,31447,31448,31449,31450,31451,31452,31453,31454,31455,31456,31457,31458,31459,31460,31461,31462,31463,31464,31465,31466,31467,31468,31469,31470,31471,31472,31473,31474,31475,31476,31477,31478,31479,31480,31481,31482,31483,31484,31485,31486,31487,31488,31489,31490,31491,31492,31493,31494,31495,31496,31497,31498,31499,31500,31501,31502,31503,31504,31505,31506,31507,31508,31509,31510,31511,31512,31513,31514,31515,31516,31517,31518,31519,31520,31521,31522,31523,31524,31525,31526,31527,31528,31529,31530,31531,31532,31533,31534,31535,31536,31537,31538,31539,31540,31541,31542,31543,31544,31545,31546,31547,31548,31549,31550,31551,31552,31553,31554,31555,31556,31557,31558,31559,31560,31561,31562,31563,31564,31565,31566,31567,31568,31569,31570,31571,31572,31573,31574,31575,31576,31577,31578,31579,31580,31581,31582,31583,31584,31585,31586,31587,31588,31589,31590,31591,31592,31593,31594,31595,31596,31597,31598,31599,31600,31601,31602,31603,31604,31605,31606,31607,31608,31609,31610,31611,31612,31613,31614,31615,31616,31617,31618,31619,31620,31621,31622,31623,31624,31625,31626,31627,31628,31629,31630,31631,31632,31633,31634,31635,31636,31637,31638,31639,31640,31641,31642,31643,31644,31645,31646,31647,31648,31649,31650,31651,31652,31653,31654,31655,31656,31657,31658,31659,31660,31661,31662,31663,31664,31665,31666,31667,31668,31669,31670,31671,31672,31673,31674,31675,31676,31677,31678,31679,31680,31681,31682,31683,31684,31685,31686,31687,31688,31689,31690,31691,31692,31693,31694,31695,31696,31697,31698,31699,31700,31701,31702,31703,31704,31705,31706,31707,31708,31709,31710,31711,31712,31713,31714,31715,31716,31717,31718,31719,31720,31721,31722,31723,31724,31725,31726,31727,31728,31729,31730,31731,31732,31733,31734,31735,31736,31737,31738,31739,31740,31741,31742,31743,31744,31745,31746,31747,31748,31749,31750,31751,31752,31753,31754,31755,31756,31757,31758,31759,31760,31761,31762,31763,31764,31765,31766,31767,31768,31769,31770,31771,31772,31773,31774,31775,31776,31777,31778,31779,31780,31781,31782,31783,31784,31785,31786,31787,31788,31789,31790,31791,31792,31793,31794,31795,31796,31797,31798,31799,31800,31801,31802,31803,31804,31805,31806,31807,31808,31809,31810,31811,31812,31813,31814,31815,31816,31817,31818,31819,31820,31821,31822,31823,31824,31825,31826,31827,31828,31829,31830,31831,31832,31833,31834,31835,31836,31837,31838,31839,31840,31841,31842,31843,31844,31845,31846,31847,31848,31849,31850,31851,31852,31853,31854,31855,31856,31857,31858,31859,31860,31861,31862,31863,31864,31865,31866,31867,31868,31869,31870,31871,31872,31873,31874,31875,31876,31877,31878,31879,31880,31881,31882,31883,31884,31885,31886,31887,31888,31889,31890,31891,31892,31893,31894,31895,31896,31897,31898,31899,31900,31901,31902,31903,31904,31905,31906,31907,31908,31909,31910,31911,31912,31913,31914,31915,31916,31917,31918,31919,31920,31921,31922,31923,31924,31925,31926,31927,31928,31929,31930,31931,31932,31933,31934,31935,31936,31937,31938,31939,31940,31941,31942,31943,31944,31945,31946,31947,31948,31949,31950,31951,31952,31953,31954,31955,31956,31957,31958,31959,31960,31961,31962,31963,31964,31965,31966,31967,31968,31969,31970,31971,31972,31973,31974,31975,31976,31977,31978,31979,31980,31981,31982,31983,31984,31985,31986,31987,31988,31989,31990,31991,31992,31993,31994,31995,31996,31997,31998,31999,32000,32001,32002,32003,32004,32005,32006,32007,32008,32009,32010,32011,32012,32013,32014,32015,32016,32017,32018,32019,32020,32021,32022,32023,32024,32025,32026,32027,32028,32029,32030,32031,32032,32033,32034,32035,32036,32037,32038,32039,32040,32041,32042,32043,32044,32045,32046,32047,32048,32049,32050,32051,32052,32053,32054,32055,32056,32057,32058,32059,32060,32061,32062,32063,32064,32065,32066,32067,32068,32069,32070,32071,32072,32073,32074,32075,32076,32077,32078,32079,32080,32081,32082,32083,32084,32085,32086,32087,32088,32089,32090,32091,32092,32093,32094,32095,32096,32097,32098,32099,32100,32101,32102,32103,32104,32105,32106,32107,32108,32109,32110,32111,32112,32113,32114,32115,32116,32117,32118,32119,32120,32121,32122,32123,32124,32125,32126,32127,32128,32129,32130,32131,32132,32133,32134,32135,32136,32137,32138,32139,32140,32141,32142,32143,32144,32145,32146,32147,32148,32149,32150,32151,32152,32153,32154,32155,32156,32157,32158,32159,32160,32161,32162,32163,32164,32165,32166,32167,32168,32169,32170,32171,32172,32173,32174,32175,32176,32177,32178,32179,32180,32181,32182,32183,32184,32185,32186,32187,32188,32189,32190,32191,32192,32193,32194,32195,32196,32197,32198,32199,32200,32201,32202,32203,32204,32205,32206,32207,32208,32209,32210,32211,32212,32213,32214,32215,32216,32217,32218,32219,32220,32221,32222,32223,32224,32225,32226,32227,32228,32229,32230,32231,32232,32233,32234,32235,32236,32237,32238,32239,32240,32241,32242,32243,32244,32245,32246,32247,32248,32249,32250,32251,32252,32253,32254,32255,32256,32257,32258,32259,32260,32261,32262,32263,32264,32265,32266,32267,32268,32269,32270,32271,32272,32273,32274,32275,32276,32277,32278,32279,32280,32281,32282,32283,32284,32285,32286,32287,32288,32289,32290,32291,32292,32293,32294,32295,32296,32297,32298,32299,32300,32301,32302,32303,32304,32305,32306,32307,32308,32309,32310,32311,32312,32313,32314,32315,32316,32317,32318,32319,32320,32321,32322,32323,32324,32325,32326,32327,32328,32329,32330,32331,32332,32333,32334,32335,32336,32337,32338,32339,32340,32341,32342,32343,32344,32345,32346,32347,32348,32349,32350,32351,32352,32353,32354,32355,32356,32357,32358,32359,32360,32361,32362,32363,32364,32365,32366,32367,32368,32369,32370,32371,32372,32373,32374,32375,32376,32377,32378,32379,32380,32381,32382,32383,32384,32385,32386,32387,32388,32389,32390,32391,32392,32393,32394,32395,32396,32397,32398,32399,32400,32401,32402,32403,32404,32405,32406,32407,32408,32409,32410,32411,32412,32413,32414,32415,32416,32417,32418,32419,32420,32421,32422,32423,32424,32425,32426,32427,32428,32429,32430,32431,32432,32433,32434,32435,32436,32437,32438,32439,32440,32441,32442,32443,32444,32445,32446,32447,32448,32449,32450,32451,32452,32453,32454,32455,32456,32457,32458,32459,32460,32461,32462,32463,32464,32465,32466,32467,32468,32469,32470,32471,32472,32473,32474,32475,32476,32477,32478,32479,32480,32481,32482,32483,32484,32485,32486,32487,32488,32489,32490,32491,32492,32493,32494,32495,32496,32497,32498,32499,32500,32501,32502,32503,32504,32505,32506,32507,32508,32509,32510,32511,32512,32513,32514,32515,32516,32517,32518,32519,32520,32521,32522,32523,32524,32525,32526,32527,32528,32529,32530,32531,32532,32533,32534,32535,32536,32537,32538,32539,32540,32541,32542,32543,32544,32545,32546,32547,32548,32549,32550,32551,32552,32553,32554,32555,32556,32557,32558,32559,32560,32561,32562,32563,32564,32565,32566,32567,32568,32569,32570,32571,32572,32573,32574,32575,32576,32577,32578,32579,32580,32581,32582,32583,32584,32585,32586,32587,32588,32589,32590,32591,32592,32593,32594,32595,32596,32597,32598,32599,32600,32601,32602,32603,32604,32605,32606,32607,32608,32609,32610,32611,32612,32613,32614,32615,32616,32617,32618,32619,32620,32621,32622,32623,32624,32625,32626,32627,32628,32629,32630,32631,32632,32633,32634,32635,32636,32637,32638,32639,32640,32641,32642,32643,32644,32645,32646,32647,32648,32649,32650,32651,32652,32653,32654,32655,32656,32657,32658,32659,32660,32661,32662,32663,32664,32665,32666,32667,32668,32669,32670,32671,32672,32673,32674,32675,32676,32677,32678,32679,32680,32681,32682,32683,32684,32685,32686,32687,32688,32689,32690,32691,32692,32693,32694,32695,32696,32697,32698,32699,32700,32701,32702,32703,32704,32705,32706,32707,32708,32709,32710,32711,32712,32713,32714,32715,32716,32717,32718,32719,32720,32721,32722,32723,32724,32725,32726,32727,32728,32729,32730,32731,32732,32733,32734,32735,32736,32737,32738,32739,32740,32741,32742,32743,32744,32745,32746,32747,32748,32749,32750,32751,32752,32753,32754,32755,32756,32757,32758,32759,32760,32761,32762,32763,32764,32765,32766,32767,32768,32769,32770,32771,32772,32773,32774,32775,32776,32777,32778,32779,32780,32781,32782,32783,32784,32785,32786,32787,32788,32789,32790,32791,32792,32793,32794,32795,32796,32797,32798,32799,32800,32801,32802,32803,32804,32805,32806,32807,32808,32809,32810,32811,32812,32813,32814,32815,32816,32817,32818,32819,32820,32821,32822,32823,32824,32825,32826,32827,32828,32829,32830,32831,32832,32833,32834,32835,32836,32837,32838,32839,32840,32841,32842,32843,32844,32845,32846,32847,32848,32849,32850,32851,32852,32853,32854,32855,32856,32857,32858,32859,32860,32861,32862,32863,32864,32865,32866,32867,32868,32869,32870,32871,32872,32873,32874,32875,32876,32877,32878,32879,32880,32881,32882,32883,32884,32885,32886,32887,32888,32889,32890,32891,32892,32893,32894,32895,32896,32897,32898,32899,32900,32901,32902,32903,32904,32905,32906,32907,32908,32909,32910,32911,32912,32913,32914,32915,32916,32917,32918,32919,32920,32921,32922,32923,32924,32925,32926,32927,32928,32929,32930,32931,32932,32933,32934,32935,32936,32937,32938,32939,32940,32941,32942,32943,32944,32945,32946,32947,32948,32949,32950,32951,32952,32953,32954,32955,32956,32957,32958,32959,32960,32961,32962,32963,32964,32965,32966,32967,32968,32969,32970,32971,32972,32973,32974,32975,32976,32977,32978,32979,32980,32981,32982,32983,32984,32985,32986,32987,32988,32989,32990,32991,32992,32993,32994,32995,32996,32997,32998,32999,33000,33001,33002,33003,33004,33005,33006,33007,33008,33009,33010,33011,33012,33013,33014,33015,33016,33017,33018,33019,33020,33021,33022,33023,33024,33025,33026,33027,33028,33029,33030,33031,33032,33033,33034,33035,33036,33037,33038,33039,33040,33041,33042,33043,33044,33045,33046,33047,33048,33049,33050,33051,33052,33053,33054,33055,33056,33057,33058,33059,33060,33061,33062,33063,33064,33065,33066,33067,33068,33069,33070,33071,33072,33073,33074,33075,33076,33077,33078,33079,33080,33081,33082,33083,33084,33085,33086,33087,33088,33089,33090,33091,33092,33093,33094,33095,33096,33097,33098,33099,33100,33101,33102,33103,33104,33105,33106,33107,33108,33109,33110,33111,33112,33113,33114,33115,33116,33117,33118,33119,33120,33121,33122,33123,33124,33125,33126,33127,33128,33129,33130,33131,33132,33133,33134,33135,33136,33137,33138,33139,33140,33141,33142,33143,33144,33145,33146,33147,33148,33149,33150,33151,33152,33153,33154,33155,33156,33157,33158,33159,33160,33161,33162,33163,33164,33165,33166,33167,33168,33169,33170,33171,33172,33173,33174,33175,33176,33177,33178,33179,33180,33181,33182,33183,33184,33185,33186,33187,33188,33189,33190,33191,33192,33193,33194,33195,33196,33197,33198,33199,33200,33201,33202,33203,33204,33205,33206,33207,33208,33209,33210,33211,33212,33213,33214,33215,33216,33217,33218,33219,33220,33221,33222,33223,33224,33225,33226,33227,33228,33229,33230,33231,33232,33233,33234,33235,33236,33237,33238,33239,33240,33241,33242,33243,33244,33245,33246,33247,33248,33249,33250,33251,33252,33253,33254,33255,33256,33257,33258,33259,33260,33261,33262,33263,33264,33265,33266,33267,33268,33269,33270,33271,33272,33273,33274,33275,33276,33277,33278,33279,33280,33281,33282,33283,33284,33285,33286,33287,33288,33289,33290,33291,33292,33293,33294,33295,33296,33297,33298,33299,33300,33301,33302,33303,33304,33305,33306,33307,33308,33309,33310,33311,33312,33313,33314,33315,33316,33317,33318,33319,33320,33321,33322,33323,33324,33325,33326,33327,33328,33329,33330,33331,33332,33333,33334,33335,33336,33337,33338,33339,33340,33341,33342,33343,33344,33345,33346,33347,33348,33349,33350,33351,33352,33353,33354,33355,33356,33357,33358,33359,33360,33361,33362,33363,33364,33365,33366,33367,33368,33369,33370,33371,33372,33373,33374,33375,33376,33377,33378,33379,33380,33381,33382,33383,33384,33385,33386,33387,33388,33389,33390,33391,33392,33393,33394,33395,33396,33397,33398,33399,33400,33401,33402,33403,33404,33405,33406,33407,33408,33409,33410,33411,33412,33413,33414,33415,33416,33417,33418,33419,33420,33421,33422,33423,33424,33425,33426,33427,33428,33429,33430,33431,33432,33433,33434,33435,33436,33437,33438,33439,33440,33441,33442,33443,33444,33445,33446,33447,33448,33449,33450,33451,33452,33453,33454,33455,33456,33457,33458,33459,33460,33461,33462,33463,33464,33465,33466,33467,33468,33469,33470,33471,33472,33473,33474,33475,33476,33477,33478,33479,33480,33481,33482,33483,33484,33485,33486,33487,33488,33489,33490,33491,33492,33493,33494,33495,33496,33497,33498,33499,33500,33501,33502,33503,33504,33505,33506,33507,33508,33509,33510,33511,33512,33513,33514,33515,33516,33517,33518,33519,33520,33521,33522,33523,33524,33525,33526,33527,33528,33529,33530,33531,33532,33533,33534,33535,33536,33537,33538,33539,33540,33541,33542,33543,33544,33545,33546,33547,33548,33549,33550,33551,33552,33553,33554,33555,33556,33557,33558,33559,33560,33561,33562,33563,33564,33565,33566,33567,33568,33569,33570,33571,33572,33573,33574,33575,33576,33577,33578,33579,33580,33581,33582,33583,33584,33585,33586,33587,33588,33589,33590,33591,33592,33593,33594,33595,33596,33597,33598,33599,33600,33601,33602,33603,33604,33605,33606,33607,33608,33609,33610,33611,33612,33613,33614,33615,33616,33617,33618,33619,33620,33621,33622,33623,33624,33625,33626,33627,33628,33629,33630,33631,33632,33633,33634,33635,33636,33637,33638,33639,33640,33641,33642,33643,33644,33645,33646,33647,33648,33649,33650,33651,33652,33653,33654,33655,33656,33657,33658,33659,33660,33661,33662,33663,33664,33665,33666,33667,33668,33669,33670,33671,33672,33673,33674,33675,33676,33677,33678,33679,33680,33681,33682,33683,33684,33685,33686,33687,33688,33689,33690,33691,33692,33693,33694,33695,33696,33697,33698,33699,33700,33701,33702,33703,33704,33705,33706,33707,33708,33709,33710,33711,33712,33713,33714,33715,33716,33717,33718,33719,33720,33721,33722,33723,33724,33725,33726,33727,33728,33729,33730,33731,33732,33733,33734,33735,33736,33737,33738,33739,33740,33741,33742,33743,33744,33745,33746,33747,33748,33749,33750,33751,33752,33753,33754,33755,33756,33757,33758,33759,33760,33761,33762,33763,33764,33765,33766,33767,33768,33769,33770,33771,33772,33773,33774,33775,33776,33777,33778,33779,33780,33781,33782,33783,33784,33785,33786,33787,33788,33789,33790,33791,33792,33793,33794,33795,33796,33797,33798,33799,33800,33801,33802,33803,33804,33805,33806,33807,33808,33809,33810,33811,33812,33813,33814,33815,33816,33817,33818,33819,33820,33821,33822,33823,33824,33825,33826,33827,33828,33829,33830,33831,33832,33833,33834,33835,33836,33837,33838,33839,33840,33841,33842,33843,33844,33845,33846,33847,33848,33849,33850,33851,33852,33853,33854,33855,33856,33857,33858,33859,33860,33861,33862,33863,33864,33865,33866,33867,33868,33869,33870,33871,33872,33873,33874,33875,33876,33877,33878,33879,33880,33881,33882,33883,33884,33885,33886,33887,33888,33889,33890,33891,33892,33893,33894,33895,33896,33897,33898,33899,33900,33901,33902,33903,33904,33905,33906,33907,33908,33909,33910,33911,33912,33913,33914,33915,33916,33917,33918,33919,33920,33921,33922,33923,33924,33925,33926,33927,33928,33929,33930,33931,33932,33933,33934,33935,33936,33937,33938,33939,33940,33941,33942,33943,33944,33945,33946,33947,33948,33949,33950,33951,33952,33953,33954,33955,33956,33957,33958,33959,33960,33961,33962,33963,33964,33965,33966,33967,33968,33969,33970,33971,33972,33973,33974,33975,33976,33977,33978,33979,33980,33981,33982,33983,33984,33985,33986,33987,33988,33989,33990,33991,33992,33993,33994,33995,33996,33997,33998,33999,34000,34001,34002,34003,34004,34005,34006,34007,34008,34009,34010,34011,34012,34013,34014,34015,34016,34017,34018,34019,34020,34021,34022,34023,34024,34025,34026,34027,34028,34029,34030,34031,34032,34033,34034,34035,34036,34037,34038,34039,34040,34041,34042,34043,34044,34045,34046,34047,34048,34049,34050,34051,34052,34053,34054,34055,34056,34057,34058,34059,34060,34061,34062,34063,34064,34065,34066,34067,34068,34069,34070,34071,34072,34073,34074,34075,34076,34077,34078,34079,34080,34081,34082,34083,34084,34085,34086,34087,34088,34089,34090,34091,34092,34093,34094,34095,34096,34097,34098,34099,34100,34101,34102,34103,34104,34105,34106,34107,34108,34109,34110,34111,34112,34113,34114,34115,34116,34117,34118,34119,34120,34121,34122,34123,34124,34125,34126,34127,34128,34129,34130,34131,34132,34133,34134,34135,34136,34137,34138,34139,34140,34141,34142,34143,34144,34145,34146,34147,34148,34149,34150,34151,34152,34153,34154,34155,34156,34157,34158,34159,34160,34161,34162,34163,34164,34165,34166,34167,34168,34169,34170,34171,34172,34173,34174,34175,34176,34177,34178,34179,34180,34181,34182,34183,34184,34185,34186,34187,34188,34189,34190,34191,34192,34193,34194,34195,34196,34197,34198,34199,34200,34201,34202,34203,34204,34205,34206,34207,34208,34209,34210,34211,34212,34213,34214,34215,34216,34217,34218,34219,34220,34221,34222,34223,34224,34225,34226,34227,34228,34229,34230,34231,34232,34233,34234,34235,34236,34237,34238,34239,34240,34241,34242,34243,34244,34245,34246,34247,34248,34249,34250,34251,34252,34253,34254,34255,34256,34257,34258,34259,34260,34261,34262,34263,34264,34265,34266,34267,34268,34269,34270,34271,34272,34273,34274,34275,34276,34277,34278,34279,34280,34281,34282,34283,34284,34285,34286,34287,34288,34289,34290,34291,34292,34293,34294,34295,34296,34297,34298,34299,34300,34301,34302,34303,34304,34305,34306,34307,34308,34309,34310,34311,34312,34313,34314,34315,34316,34317,34318,34319,34320,34321,34322,34323,34324,34325,34326,34327,34328,34329,34330,34331,34332,34333,34334,34335,34336,34337,34338,34339,34340,34341,34342,34343,34344,34345,34346,34347,34348,34349,34350,34351,34352,34353,34354,34355,34356,34357,34358,34359,34360,34361,34362,34363,34364,34365,34366,34367,34368,34369,34370,34371,34372,34373,34374,34375,34376,34377,34378,34379,34380,34381,34382,34383,34384,34385,34386,34387,34388,34389,34390,34391,34392,34393,34394,34395,34396,34397,34398,34399,34400,34401,34402,34403,34404,34405,34406,34407,34408,34409,34410,34411,34412,34413,34414,34415,34416,34417,34418,34419,34420,34421,34422,34423,34424,34425,34426,34427,34428,34429,34430,34431,34432,34433,34434,34435,34436,34437,34438,34439,34440,34441,34442,34443,34444,34445,34446,34447,34448,34449,34450,34451,34452,34453,34454,34455,34456,34457,34458,34459,34460,34461,34462,34463,34464,34465,34466,34467,34468,34469,34470,34471,34472,34473,34474,34475,34476,34477,34478,34479,34480,34481,34482,34483,34484,34485,34486,34487,34488,34489,34490,34491,34492,34493,34494,34495,34496,34497,34498,34499,34500,34501,34502,34503,34504,34505,34506,34507,34508,34509,34510,34511,34512,34513,34514,34515,34516,34517,34518,34519,34520,34521,34522,34523,34524,34525,34526,34527,34528,34529,34530,34531,34532,34533,34534,34535,34536,34537,34538,34539,34540,34541,34542,34543,34544,34545,34546,34547,34548,34549,34550,34551,34552,34553,34554,34555,34556,34557,34558,34559,34560,34561,34562,34563,34564,34565,34566,34567,34568,34569,34570,34571,34572,34573,34574,34575,34576,34577,34578,34579,34580,34581,34582,34583,34584,34585,34586,34587,34588,34589,34590,34591,34592,34593,34594,34595,34596,34597,34598,34599,34600,34601,34602,34603,34604,34605,34606,34607,34608,34609,34610,34611,34612,34613,34614,34615,34616,34617,34618,34619,34620,34621,34622,34623,34624,34625,34626,34627,34628,34629,34630,34631,34632,34633,34634,34635,34636,34637,34638,34639,34640,34641,34642,34643,34644,34645,34646,34647,34648,34649,34650,34651,34652,34653,34654,34655,34656,34657,34658,34659,34660,34661,34662,34663,34664,34665,34666,34667,34668,34669,34670,34671,34672,34673,34674,34675,34676,34677,34678,34679,34680,34681,34682,34683,34684,34685,34686,34687,34688,34689,34690,34691,34692,34693,34694,34695,34696,34697,34698,34699,34700,34701,34702,34703,34704,34705,34706,34707,34708,34709,34710,34711,34712,34713,34714,34715,34716,34717,34718,34719,34720,34721,34722,34723,34724,34725,34726,34727,34728,34729,34730,34731,34732,34733,34734,34735,34736,34737,34738,34739,34740,34741,34742,34743,34744,34745,34746,34747,34748,34749,34750,34751,34752,34753,34754,34755,34756,34757,34758,34759,34760,34761,34762,34763,34764,34765,34766,34767,34768,34769,34770,34771,34772,34773,34774,34775,34776,34777,34778,34779,34780,34781,34782,34783,34784,34785,34786,34787,34788,34789,34790,34791,34792,34793,34794,34795,34796,34797,34798,34799,34800,34801,34802,34803,34804,34805,34806,34807,34808,34809,34810,34811,34812,34813,34814,34815,34816,34817,34818,34819,34820,34821,34822,34823,34824,34825,34826,34827,34828,34829,34830,34831,34832,34833,34834,34835,34836,34837,34838,34839,34840,34841,34842,34843,34844,34845,34846,34847,34848,34849,34850,34851,34852,34853,34854,34855,34856,34857,34858,34859,34860,34861,34862,34863,34864,34865,34866,34867,34868,34869,34870,34871,34872,34873,34874,34875,34876,34877,34878,34879,34880,34881,34882,34883,34884,34885,34886,34887,34888,34889,34890,34891,34892,34893,34894,34895,34896,34897,34898,34899,34900,34901,34902,34903,34904,34905,34906,34907,34908,34909,34910,34911,34912,34913,34914,34915,34916,34917,34918,34919,34920,34921,34922,34923,34924,34925,34926,34927,34928,34929,34930,34931,34932,34933,34934,34935,34936,34937,34938,34939,34940,34941,34942,34943,34944,34945,34946,34947,34948,34949,34950,34951,34952,34953,34954,34955,34956,34957,34958,34959,34960,34961,34962,34963,34964,34965,34966,34967,34968,34969,34970,34971,34972,34973,34974,34975,34976,34977,34978,34979,34980,34981,34982,34983,34984,34985,34986,34987,34988,34989,34990,34991,34992,34993,34994,34995,34996,34997,34998,34999,35000,35001,35002,35003,35004,35005,35006,35007,35008,35009,35010,35011,35012,35013,35014,35015,35016,35017,35018,35019,35020,35021,35022,35023,35024,35025,35026,35027,35028,35029,35030,35031,35032,35033,35034,35035,35036,35037,35038,35039,35040,35041,35042,35043,35044,35045,35046,35047,35048,35049,35050,35051,35052,35053,35054,35055,35056,35057,35058,35059,35060,35061,35062,35063,35064,35065,35066,35067,35068,35069,35070,35071,35072,35073,35074,35075,35076,35077,35078,35079,35080,35081,35082,35083,35084,35085,35086,35087,35088,35089,35090,35091,35092,35093,35094,35095,35096,35097,35098,35099,35100,35101,35102,35103,35104,35105,35106,35107,35108,35109,35110,35111,35112,35113,35114,35115,35116,35117,35118,35119,35120,35121,35122,35123,35124,35125,35126,35127,35128,35129,35130,35131,35132,35133,35134,35135,35136,35137,35138,35139,35140,35141,35142,35143,35144,35145,35146,35147,35148,35149,35150,35151,35152,35153,35154,35155,35156,35157,35158,35159,35160,35161,35162,35163,35164,35165,35166,35167,35168,35169,35170,35171,35172,35173,35174,35175,35176,35177,35178,35179,35180,35181,35182,35183,35184,35185,35186,35187,35188,35189,35190,35191,35192,35193,35194,35195,35196,35197,35198,35199,35200,35201,35202,35203,35204,35205,35206,35207,35208,35209,35210,35211,35212,35213,35214,35215,35216,35217,35218,35219,35220,35221,35222,35223,35224,35225,35226,35227,35228,35229,35230,35231,35232,35233,35234,35235,35236,35237,35238,35239,35240,35241,35242,35243,35244,35245,35246,35247,35248,35249,35250,35251,35252,35253,35254,35255,35256,35257,35258,35259,35260,35261,35262,35263,35264,35265,35266,35267,35268,35269,35270,35271,35272,35273,35274,35275,35276,35277,35278,35279,35280,35281,35282,35283,35284,35285,35286,35287,35288,35289,35290,35291,35292,35293,35294,35295,35296,35297,35298,35299,35300,35301,35302,35303,35304,35305,35306,35307,35308,35309,35310,35311,35312,35313,35314,35315,35316,35317,35318,35319,35320,35321,35322,35323,35324,35325,35326,35327,35328,35329,35330,35331,35332,35333,35334,35335,35336,35337,35338,35339,35340,35341,35342,35343,35344,35345,35346,35347,35348,35349,35350,35351,35352,35353,35354,35355,35356,35357,35358,35359,35360,35361,35362,35363,35364,35365,35366,35367,35368,35369,35370,35371,35372,35373,35374,35375,35376,35377,35378,35379,35380,35381,35382,35383,35384,35385,35386,35387,35388,35389,35390,35391,35392,35393,35394,35395,35396,35397,35398,35399,35400,35401,35402,35403,35404,35405,35406,35407,35408,35409,35410,35411,35412,35413,35414,35415,35416,35417,35418,35419,35420,35421,35422,35423,35424,35425,35426,35427,35428,35429,35430,35431,35432,35433,35434,35435,35436,35437,35438,35439,35440,35441,35442,35443,35444,35445,35446,35447,35448,35449,35450,35451,35452,35453,35454,35455,35456,35457,35458,35459,35460,35461,35462,35463,35464,35465,35466,35467,35468,35469,35470,35471,35472,35473,35474,35475,35476,35477,35478,35479,35480,35481,35482,35483,35484,35485,35486,35487,35488,35489,35490,35491,35492,35493,35494,35495,35496,35497,35498,35499,35500,35501,35502,35503,35504,35505,35506,35507,35508,35509,35510,35511,35512,35513,35514,35515,35516,35517,35518,35519,35520,35521,35522,35523,35524,35525,35526,35527,35528,35529,35530,35531,35532,35533,35534,35535,35536,35537,35538,35539,35540,35541,35542,35543,35544,35545,35546,35547,35548,35549,35550,35551,35552,35553,35554,35555,35556,35557,35558,35559,35560,35561,35562,35563,35564,35565,35566,35567,35568,35569,35570,35571,35572,35573,35574,35575,35576,35577,35578,35579,35580,35581,35582,35583,35584,35585,35586,35587,35588,35589,35590,35591,35592,35593,35594,35595,35596,35597,35598,35599,35600,35601,35602,35603,35604,35605,35606,35607,35608,35609,35610,35611,35612,35613,35614,35615,35616,35617,35618,35619,35620,35621,35622,35623,35624,35625,35626,35627,35628,35629,35630,35631,35632,35633,35634,35635,35636,35637,35638,35639,35640,35641,35642,35643,35644,35645,35646,35647,35648,35649,35650,35651,35652,35653,35654,35655,35656,35657,35658,35659,35660,35661,35662,35663,35664,35665,35666,35667,35668,35669,35670,35671,35672,35673,35674,35675,35676,35677,35678,35679,35680,35681,35682,35683,35684,35685,35686,35687,35688,35689,35690,35691,35692,35693,35694,35695,35696,35697,35698,35699,35700,35701,35702,35703,35704,35705,35706,35707,35708,35709,35710,35711,35712,35713,35714,35715,35716,35717,35718,35719,35720,35721,35722,35723,35724,35725,35726,35727,35728,35729,35730,35731,35732,35733,35734,35735,35736,35737,35738,35739,35740,35741,35742,35743,35744,35745,35746,35747,35748,35749,35750,35751,35752,35753,35754,35755,35756,35757,35758,35759,35760,35761,35762,35763,35764,35765,35766,35767,35768,35769,35770,35771,35772,35773,35774,35775,35776,35777,35778,35779,35780,35781,35782,35783,35784,35785,35786,35787,35788,35789,35790,35791,35792,35793,35794,35795,35796,35797,35798,35799,35800,35801,35802,35803,35804,35805,35806,35807,35808,35809,35810,35811,35812,35813,35814,35815,35816,35817,35818,35819,35820,35821,35822,35823,35824,35825,35826,35827,35828,35829,35830,35831,35832,35833,35834,35835,35836,35837,35838,35839,35840,35841,35842,35843,35844,35845,35846,35847,35848,35849,35850,35851,35852,35853,35854,35855,35856,35857,35858,35859,35860,35861,35862,35863,35864,35865,35866,35867,35868,35869,35870,35871,35872,35873,35874,35875,35876,35877,35878,35879,35880,35881,35882,35883,35884,35885,35886,35887,35888,35889,35890,35891,35892,35893,35894,35895,35896,35897,35898,35899,35900,35901,35902,35903,35904,35905,35906,35907,35908,35909,35910,35911,35912,35913,35914,35915,35916,35917,35918,35919,35920,35921,35922,35923,35924,35925,35926,35927,35928,35929,35930,35931,35932,35933,35934,35935,35936,35937,35938,35939,35940,35941,35942,35943,35944,35945,35946,35947,35948,35949,35950,35951,35952,35953,35954,35955,35956,35957,35958,35959,35960,35961,35962,35963,35964,35965,35966,35967,35968,35969,35970,35971,35972,35973,35974,35975,35976,35977,35978,35979,35980,35981,35982,35983,35984,35985,35986,35987,35988,35989,35990,35991,35992,35993,35994,35995,35996,35997,35998,35999,36000,36001,36002,36003,36004,36005,36006,36007,36008,36009,36010,36011,36012,36013,36014,36015,36016,36017,36018,36019,36020,36021,36022,36023,36024,36025,36026,36027,36028,36029,36030,36031,36032,36033,36034,36035,36036,36037,36038,36039,36040,36041,36042,36043,36044,36045,36046,36047,36048,36049,36050,36051,36052,36053,36054,36055,36056,36057,36058,36059,36060,36061,36062,36063,36064,36065,36066,36067,36068,36069,36070,36071,36072,36073,36074,36075,36076,36077,36078,36079,36080,36081,36082,36083,36084,36085,36086,36087,36088,36089,36090,36091,36092,36093,36094,36095,36096,36097,36098,36099,36100,36101,36102,36103,36104,36105,36106,36107,36108,36109,36110,36111,36112,36113,36114,36115,36116,36117,36118,36119,36120,36121,36122,36123,36124,36125,36126,36127,36128,36129,36130,36131,36132,36133,36134,36135,36136,36137,36138,36139,36140,36141,36142,36143,36144,36145,36146,36147,36148,36149,36150,36151,36152,36153,36154,36155,36156,36157,36158,36159,36160,36161,36162,36163,36164,36165,36166,36167,36168,36169,36170,36171,36172,36173,36174,36175,36176,36177,36178,36179,36180,36181,36182,36183,36184,36185,36186,36187,36188,36189,36190,36191,36192,36193,36194,36195,36196,36197,36198,36199,36200,36201,36202,36203,36204,36205,36206,36207,36208,36209,36210,36211,36212,36213,36214,36215,36216,36217,36218,36219,36220,36221,36222,36223,36224,36225,36226,36227,36228,36229,36230,36231,36232,36233,36234,36235,36236,36237,36238,36239,36240,36241,36242,36243,36244,36245,36246,36247,36248,36249,36250,36251,36252,36253,36254,36255,36256,36257,36258,36259,36260,36261,36262,36263,36264,36265,36266,36267,36268,36269,36270,36271,36272,36273,36274,36275,36276,36277,36278,36279,36280,36281,36282,36283,36284,36285,36286,36287,36288,36289,36290,36291,36292,36293,36294,36295,36296,36297,36298,36299,36300,36301,36302,36303,36304,36305,36306,36307,36308,36309,36310,36311,36312,36313,36314,36315,36316,36317,36318,36319,36320,36321,36322,36323,36324,36325,36326,36327,36328,36329,36330,36331,36332,36333,36334,36335,36336,36337,36338,36339,36340,36341,36342,36343,36344,36345,36346,36347,36348,36349,36350,36351,36352,36353,36354,36355,36356,36357,36358,36359,36360,36361,36362,36363,36364,36365,36366,36367,36368,36369,36370,36371,36372,36373,36374,36375,36376,36377,36378,36379,36380,36381,36382,36383,36384,36385,36386,36387,36388,36389,36390,36391,36392,36393,36394,36395,36396,36397,36398,36399,36400,36401,36402,36403,36404,36405,36406,36407,36408,36409,36410,36411,36412,36413,36414,36415,36416,36417,36418,36419,36420,36421,36422,36423,36424,36425,36426,36427,36428,36429,36430,36431,36432,36433,36434,36435,36436,36437,36438,36439,36440,36441,36442,36443,36444,36445,36446,36447,36448,36449,36450,36451,36452,36453,36454,36455,36456,36457,36458,36459,36460,36461,36462,36463,36464,36465,36466,36467,36468,36469,36470,36471,36472,36473,36474,36475,36476,36477,36478,36479,36480,36481,36482,36483,36484,36485,36486,36487,36488,36489,36490,36491,36492,36493,36494,36495,36496,36497,36498,36499,36500,36501,36502,36503,36504,36505,36506,36507,36508,36509,36510,36511,36512,36513,36514,36515,36516,36517,36518,36519,36520,36521,36522,36523,36524,36525,36526,36527,36528,36529,36530,36531,36532,36533,36534,36535,36536,36537,36538,36539,36540,36541,36542,36543,36544,36545,36546,36547,36548,36549,36550,36551,36552,36553,36554,36555,36556,36557,36558,36559,36560,36561,36562,36563,36564,36565,36566,36567,36568,36569,36570,36571,36572,36573,36574,36575,36576,36577,36578,36579,36580,36581,36582,36583,36584,36585,36586,36587,36588,36589,36590,36591,36592,36593,36594,36595,36596,36597,36598,36599,36600,36601,36602,36603,36604,36605,36606,36607,36608,36609,36610,36611,36612,36613,36614,36615,36616,36617,36618,36619,36620,36621,36622,36623,36624,36625,36626,36627,36628,36629,36630,36631,36632,36633,36634,36635,36636,36637,36638,36639,36640,36641,36642,36643,36644,36645,36646,36647,36648,36649,36650,36651,36652,36653,36654,36655,36656,36657,36658,36659,36660,36661,36662,36663,36664,36665,36666,36667,36668,36669,36670,36671,36672,36673,36674,36675,36676,36677,36678,36679,36680,36681,36682,36683,36684,36685,36686,36687,36688,36689,36690,36691,36692,36693,36694,36695,36696,36697,36698,36699,36700,36701,36702,36703,36704,36705,36706,36707,36708,36709,36710,36711,36712,36713,36714,36715,36716,36717,36718,36719,36720,36721,36722,36723,36724,36725,36726,36727,36728,36729,36730,36731,36732,36733,36734,36735,36736,36737,36738,36739,36740,36741,36742,36743,36744,36745,36746,36747,36748,36749,36750,36751,36752,36753,36754,36755,36756,36757,36758,36759,36760,36761,36762,36763,36764,36765,36766,36767,36768,36769,36770,36771,36772,36773,36774,36775,36776,36777,36778,36779,36780,36781,36782,36783,36784,36785,36786,36787,36788,36789,36790,36791,36792,36793,36794,36795,36796,36797,36798,36799,36800,36801,36802,36803,36804,36805,36806,36807,36808,36809,36810,36811,36812,36813,36814,36815,36816,36817,36818,36819,36820,36821,36822,36823,36824,36825,36826,36827,36828,36829,36830,36831,36832,36833,36834,36835,36836,36837,36838,36839,36840,36841,36842,36843,36844,36845,36846,36847,36848,36849,36850,36851,36852,36853,36854,36855,36856,36857,36858,36859,36860,36861,36862,36863,36864,36865,36866,36867,36868,36869,36870,36871,36872,36873,36874,36875,36876,36877,36878,36879,36880,36881,36882,36883,36884,36885,36886,36887,36888,36889,36890,36891,36892,36893,36894,36895,36896,36897,36898,36899,36900,36901,36902,36903,36904,36905,36906,36907,36908,36909,36910,36911,36912,36913,36914,36915,36916,36917,36918,36919,36920,36921,36922,36923,36924,36925,36926,36927,36928,36929,36930,36931,36932,36933,36934,36935,36936,36937,36938,36939,36940,36941,36942,36943,36944,36945,36946,36947,36948,36949,36950,36951,36952,36953,36954,36955,36956,36957,36958,36959,36960,36961,36962,36963,36964,36965,36966,36967,36968,36969,36970,36971,36972,36973,36974,36975,36976,36977,36978,36979,36980,36981,36982,36983,36984,36985,36986,36987,36988,36989,36990,36991,36992,36993,36994,36995,36996,36997,36998,36999,37000,37001,37002,37003,37004,37005,37006,37007,37008,37009,37010,37011,37012,37013,37014,37015,37016,37017,37018,37019,37020,37021,37022,37023,37024,37025,37026,37027,37028,37029,37030,37031,37032,37033,37034,37035,37036,37037,37038,37039,37040,37041,37042,37043,37044,37045,37046,37047,37048,37049,37050,37051,37052,37053,37054,37055,37056,37057,37058,37059,37060,37061,37062,37063,37064,37065,37066,37067,37068,37069,37070,37071,37072,37073,37074,37075,37076,37077,37078,37079,37080,37081,37082,37083,37084,37085,37086,37087,37088,37089,37090,37091,37092,37093,37094,37095,37096,37097,37098,37099,37100,37101,37102,37103,37104,37105,37106,37107,37108,37109,37110,37111,37112,37113,37114,37115,37116,37117,37118,37119,37120,37121,37122,37123,37124,37125,37126,37127,37128,37129,37130,37131,37132,37133,37134,37135,37136,37137,37138,37139,37140,37141,37142,37143,37144,37145,37146,37147,37148,37149,37150,37151,37152,37153,37154,37155,37156,37157,37158,37159,37160,37161,37162,37163,37164,37165,37166,37167,37168,37169,37170,37171,37172,37173,37174,37175,37176,37177,37178,37179,37180,37181,37182,37183,37184,37185,37186,37187,37188,37189,37190,37191,37192,37193,37194,37195,37196,37197,37198,37199,37200,37201,37202,37203,37204,37205,37206,37207,37208,37209,37210,37211,37212,37213,37214,37215,37216,37217,37218,37219,37220,37221,37222,37223,37224,37225,37226,37227,37228,37229,37230,37231,37232,37233,37234,37235,37236,37237,37238,37239,37240,37241,37242,37243,37244,37245,37246,37247,37248,37249,37250,37251,37252,37253,37254,37255,37256,37257,37258,37259,37260,37261,37262,37263,37264,37265,37266,37267,37268,37269,37270,37271,37272,37273,37274,37275,37276,37277,37278,37279,37280,37281,37282,37283,37284,37285,37286,37287,37288,37289,37290,37291,37292,37293,37294,37295,37296,37297,37298,37299,37300,37301,37302,37303,37304,37305,37306,37307,37308,37309,37310,37311,37312,37313,37314,37315,37316,37317,37318,37319,37320,37321,37322,37323,37324,37325,37326,37327,37328,37329,37330,37331,37332,37333,37334,37335,37336,37337,37338,37339,37340,37341,37342,37343,37344,37345,37346,37347,37348,37349,37350,37351,37352,37353,37354,37355,37356,37357,37358,37359,37360,37361,37362,37363,37364,37365,37366,37367,37368,37369,37370,37371,37372,37373,37374,37375,37376,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,37387,37388,37389,37390,37391,37392,37393,37394,37395,37396,37397,37398,37399,37400,37401,37402,37403,37404,37405,37406,37407,37408,37409,37410,37411,37412,37413,37414,37415,37416,37417,37418,37419,37420,37421,37422,37423,37424,37425,37426,37427,37428,37429,37430,37431,37432,37433,37434,37435,37436,37437,37438,37439,37440,37441,37442,37443,37444,37445,37446,37447,37448,37449,37450,37451,37452,37453,37454,37455,37456,37457,37458,37459,37460,37461,37462,37463,37464,37465,37466,37467,37468,37469,37470,37471,37472,37473,37474,37475,37476,37477,37478,37479,37480,37481,37482,37483,37484,37485,37486,37487,37488,37489,37490,37491,37492,37493,37494,37495,37496,37497,37498,37499,37500,37501,37502,37503,37504,37505,37506,37507,37508,37509,37510,37511,37512,37513,37514,37515,37516,37517,37518,37519,37520,37521,37522,37523,37524,37525,37526,37527,37528,37529,37530,37531,37532,37533,37534,37535,37536,37537,37538,37539,37540,37541,37542,37543,37544,37545,37546,37547,37548,37549,37550,37551,37552,37553,37554,37555,37556,37557,37558,37559,37560,37561,37562,37563,37564,37565,37566,37567,37568,37569,37570,37571,37572,37573,37574,37575,37576,37577,37578,37579,37580,37581,37582,37583,37584,37585,37586,37587,37588,37589,37590,37591,37592,37593,37594,37595,37596,37597,37598,37599,37600,37601,37602,37603,37604,37605,37606,37607,37608,37609,37610,37611,37612,37613,37614,37615,37616,37617,37618,37619,37620,37621,37622,37623,37624,37625,37626,37627,37628,37629,37630,37631,37632,37633,37634,37635,37636,37637,37638,37639,37640,37641,37642,37643,37644,37645,37646,37647,37648,37649,37650,37651,37652,37653,37654,37655,37656,37657,37658,37659,37660,37661,37662,37663,37664,37665,37666,37667,37668,37669,37670,37671,37672,37673,37674,37675,37676,37677,37678,37679,37680,37681,37682,37683,37684,37685,37686,37687,37688,37689,37690,37691,37692,37693,37694,37695,37696,37697,37698,37699,37700,37701,37702,37703,37704,37705,37706,37707,37708,37709,37710,37711,37712,37713,37714,37715,37716,37717,37718,37719,37720,37721,37722,37723,37724,37725,37726,37727,37728,37729,37730,37731,37732,37733,37734,37735,37736,37737,37738,37739,37740,37741,37742,37743,37744,37745,37746,37747,37748,37749,37750,37751,37752,37753,37754,37755,37756,37757,37758,37759,37760,37761,37762,37763,37764,37765,37766,37767,37768,37769,37770,37771,37772,37773,37774,37775,37776,37777,37778,37779,37780,37781,37782,37783,37784,37785,37786,37787,37788,37789,37790,37791,37792,37793,37794,37795,37796,37797,37798,37799,37800,37801,37802,37803,37804,37805,37806,37807,37808,37809,37810,37811,37812,37813,37814,37815,37816,37817,37818,37819,37820,37821,37822,37823,37824,37825,37826,37827,37828,37829,37830,37831,37832,37833,37834,37835,37836,37837,37838,37839,37840,37841,37842,37843,37844,37845,37846,37847,37848,37849,37850,37851,37852,37853,37854,37855,37856,37857,37858,37859,37860,37861,37862,37863,37864,37865,37866,37867,37868,37869,37870,37871,37872,37873,37874,37875,37876,37877,37878,37879,37880,37881,37882,37883,37884,37885,37886,37887,37888,37889,37890,37891,37892,37893,37894,37895,37896,37897,37898,37899,37900,37901,37902,37903,37904,37905,37906,37907,37908,37909,37910,37911,37912,37913,37914,37915,37916,37917,37918,37919,37920,37921,37922,37923,37924,37925,37926,37927,37928,37929,37930,37931,37932,37933,37934,37935,37936,37937,37938,37939,37940,37941,37942,37943,37944,37945,37946,37947,37948,37949,37950,37951,37952,37953,37954,37955,37956,37957,37958,37959,37960,37961,37962,37963,37964,37965,37966,37967,37968,37969,37970,37971,37972,37973,37974,37975,37976,37977,37978,37979,37980,37981,37982,37983,37984,37985,37986,37987,37988,37989,37990,37991,37992,37993,37994,37995,37996,37997,37998,37999,38000,38001,38002,38003,38004,38005,38006,38007,38008,38009,38010,38011,38012,38013,38014,38015,38016,38017,38018,38019,38020,38021,38022,38023,38024,38025,38026,38027,38028,38029,38030,38031,38032,38033,38034,38035,38036,38037,38038,38039,38040,38041,38042,38043,38044,38045,38046,38047,38048,38049,38050,38051,38052,38053,38054,38055,38056,38057,38058,38059,38060,38061,38062,38063,38064,38065,38066,38067,38068,38069,38070,38071,38072,38073,38074,38075,38076,38077,38078,38079,38080,38081,38082,38083,38084,38085,38086,38087,38088,38089,38090,38091,38092,38093,38094,38095,38096,38097,38098,38099,38100,38101,38102,38103,38104,38105,38106,38107,38108,38109,38110,38111,38112,38113,38114,38115,38116,38117,38118,38119,38120,38121,38122,38123,38124,38125,38126,38127,38128,38129,38130,38131,38132,38133,38134,38135,38136,38137,38138,38139,38140,38141,38142,38143,38144,38145,38146,38147,38148,38149,38150,38151,38152,38153,38154,38155,38156,38157,38158,38159,38160,38161,38162,38163,38164,38165,38166,38167,38168,38169,38170,38171,38172,38173,38174,38175,38176,38177,38178,38179,38180,38181,38182,38183,38184,38185,38186,38187,38188,38189,38190,38191,38192,38193,38194,38195,38196,38197,38198,38199,38200,38201,38202,38203,38204,38205,38206,38207,38208,38209,38210,38211,38212,38213,38214,38215,38216,38217,38218,38219,38220,38221,38222,38223,38224,38225,38226,38227,38228,38229,38230,38231,38232,38233,38234,38235,38236,38237,38238,38239,38240,38241,38242,38243,38244,38245,38246,38247,38248,38249,38250,38251,38252,38253,38254,38255,38256,38257,38258,38259,38260,38261,38262,38263,38264,38265,38266,38267,38268,38269,38270,38271,38272,38273,38274,38275,38276,38277,38278,38279,38280,38281,38282,38283,38284,38285,38286,38287,38288,38289,38290,38291,38292,38293,38294,38295,38296,38297,38298,38299,38300,38301,38302,38303,38304,38305,38306,38307,38308,38309,38310,38311,38312,38313,38314,38315,38316,38317,38318,38319,38320,38321,38322,38323,38324,38325,38326,38327,38328,38329,38330,38331,38332,38333,38334,38335,38336,38337,38338,38339,38340,38341,38342,38343,38344,38345,38346,38347,38348,38349,38350,38351,38352,38353,38354,38355,38356,38357,38358,38359,38360,38361,38362,38363,38364,38365,38366,38367,38368,38369,38370,38371,38372,38373,38374,38375,38376,38377,38378,38379,38380,38381,38382,38383,38384,38385,38386,38387,38388,38389,38390,38391,38392,38393,38394,38395,38396,38397,38398,38399,38400,38401,38402,38403,38404,38405,38406,38407,38408,38409,38410,38411,38412,38413,38414,38415,38416,38417,38418,38419,38420,38421,38422,38423,38424,38425,38426,38427,38428,38429,38430,38431,38432,38433,38434,38435,38436,38437,38438,38439,38440,38441,38442,38443,38444,38445,38446,38447,38448,38449,38450,38451,38452,38453,38454,38455,38456,38457,38458,38459,38460,38461,38462,38463,38464,38465,38466,38467,38468,38469,38470,38471,38472,38473,38474,38475,38476,38477,38478,38479,38480,38481,38482,38483,38484,38485,38486,38487,38488,38489,38490,38491,38492,38493,38494,38495,38496,38497,38498,38499,38500,38501,38502,38503,38504,38505,38506,38507,38508,38509,38510,38511,38512,38513,38514,38515,38516,38517,38518,38519,38520,38521,38522,38523,38524,38525,38526,38527,38528,38529,38530,38531,38532,38533,38534,38535,38536,38537,38538,38539,38540,38541,38542,38543,38544,38545,38546,38547,38548,38549,38550,38551,38552,38553,38554,38555,38556,38557,38558,38559,38560,38561,38562,38563,38564,38565,38566,38567,38568,38569,38570,38571,38572,38573,38574,38575,38576,38577,38578,38579,38580,38581,38582,38583,38584,38585,38586,38587,38588,38589,38590,38591,38592,38593,38594,38595,38596,38597,38598,38599,38600,38601,38602,38603,38604,38605,38606,38607,38608,38609,38610,38611,38612,38613,38614,38615,38616,38617,38618,38619,38620,38621,38622,38623,38624,38625,38626,38627,38628,38629,38630,38631,38632,38633,38634,38635,38636,38637,38638,38639,38640,38641,38642,38643,38644,38645,38646,38647,38648,38649,38650,38651,38652,38653,38654,38655,38656,38657,38658,38659,38660,38661,38662,38663,38664,38665,38666,38667,38668,38669,38670,38671,38672,38673,38674,38675,38676,38677,38678,38679,38680,38681,38682,38683,38684,38685,38686,38687,38688,38689,38690,38691,38692,38693,38694,38695,38696,38697,38698,38699,38700,38701,38702,38703,38704,38705,38706,38707,38708,38709,38710,38711,38712,38713,38714,38715,38716,38717,38718,38719,38720,38721,38722,38723,38724,38725,38726,38727,38728,38729,38730,38731,38732,38733,38734,38735,38736,38737,38738,38739,38740,38741,38742,38743,38744,38745,38746,38747,38748,38749,38750,38751,38752,38753,38754,38755,38756,38757,38758,38759,38760,38761,38762,38763,38764,38765,38766,38767,38768,38769,38770,38771,38772,38773,38774,38775,38776,38777,38778,38779,38780,38781,38782,38783,38784,38785,38786,38787,38788,38789,38790,38791,38792,38793,38794,38795,38796,38797,38798,38799,38800,38801,38802,38803,38804,38805,38806,38807,38808,38809,38810,38811,38812,38813,38814,38815,38816,38817,38818,38819,38820,38821,38822,38823,38824,38825,38826,38827,38828,38829,38830,38831,38832,38833,38834,38835,38836,38837,38838,38839,38840,38841,38842,38843,38844,38845,38846,38847,38848,38849,38850,38851,38852,38853,38854,38855,38856,38857,38858,38859,38860,38861,38862,38863,38864,38865,38866,38867,38868,38869,38870,38871,38872,38873,38874,38875,38876,38877,38878,38879,38880,38881,38882,38883,38884,38885,38886,38887,38888,38889,38890,38891,38892,38893,38894,38895,38896,38897,38898,38899,38900,38901,38902,38903,38904,38905,38906,38907,38908,38909,38910,38911,38912,38913,38914,38915,38916,38917,38918,38919,38920,38921,38922,38923,38924,38925,38926,38927,38928,38929,38930,38931,38932,38933,38934,38935,38936,38937,38938,38939,38940,38941,38942,38943,38944,38945,38946,38947,38948,38949,38950,38951,38952,38953,38954,38955,38956,38957,38958,38959,38960,38961,38962,38963,38964,38965,38966,38967,38968,38969,38970,38971,38972,38973,38974,38975,38976,38977,38978,38979,38980,38981,38982,38983,38984,38985,38986,38987,38988,38989,38990,38991,38992,38993,38994,38995,38996,38997,38998,38999,39000,39001,39002,39003,39004,39005,39006,39007,39008,39009,39010,39011,39012,39013,39014,39015,39016,39017,39018,39019,39020,39021,39022,39023,39024,39025,39026,39027,39028,39029,39030,39031,39032,39033,39034,39035,39036,39037,39038,39039,39040,39041,39042,39043,39044,39045,39046,39047,39048,39049,39050,39051,39052,39053,39054,39055,39056,39057,39058,39059,39060,39061,39062,39063,39064,39065,39066,39067,39068,39069,39070,39071,39072,39073,39074,39075,39076,39077,39078,39079,39080,39081,39082,39083,39084,39085,39086,39087,39088,39089,39090,39091,39092,39093,39094,39095,39096,39097,39098,39099,39100,39101,39102,39103,39104,39105,39106,39107,39108,39109,39110,39111,39112,39113,39114,39115,39116,39117,39118,39119,39120,39121,39122,39123,39124,39125,39126,39127,39128,39129,39130,39131,39132,39133,39134,39135,39136,39137,39138,39139,39140,39141,39142,39143,39144,39145,39146,39147,39148,39149,39150,39151,39152,39153,39154,39155,39156,39157,39158,39159,39160,39161,39162,39163,39164,39165,39166,39167,39168,39169,39170,39171,39172,39173,39174,39175,39176,39177,39178,39179,39180,39181,39182,39183,39184,39185,39186,39187,39188,39189,39190,39191,39192,39193,39194,39195,39196,39197,39198,39199,39200,39201,39202,39203,39204,39205,39206,39207,39208,39209,39210,39211,39212,39213,39214,39215,39216,39217,39218,39219,39220,39221,39222,39223,39224,39225,39226,39227,39228,39229,39230,39231,39232,39233,39234,39235,39236,39237,39238,39239,39240,39241,39242,39243,39244,39245,39246,39247,39248,39249,39250,39251,39252,39253,39254,39255,39256,39257,39258,39259,39260,39261,39262,39263,39264,39265,39266,39267,39268,39269,39270,39271,39272,39273,39274,39275,39276,39277,39278,39279,39280,39281,39282,39283,39284,39285,39286,39287,39288,39289,39290,39291,39292,39293,39294,39295,39296,39297,39298,39299,39300,39301,39302,39303,39304,39305,39306,39307,39308,39309,39310,39311,39312,39313,39314,39315,39316,39317,39318,39319,39320,39321,39322,39323,39324,39325,39326,39327,39328,39329,39330,39331,39332,39333,39334,39335,39336,39337,39338,39339,39340,39341,39342,39343,39344,39345,39346,39347,39348,39349,39350,39351,39352,39353,39354,39355,39356,39357,39358,39359,39360,39361,39362,39363,39364,39365,39366,39367,39368,39369,39370,39371,39372,39373,39374,39375,39376,39377,39378,39379,39380,39381,39382,39383,39384,39385,39386,39387,39388,39389,39390,39391,39392,39393,39394,39395,39396,39397,39398,39399,39400,39401,39402,39403,39404,39405,39406,39407,39408,39409,39410,39411,39412,39413,39414,39415,39416,39417,39418,39419,39420,39421,39422,39423,39424,39425,39426,39427,39428,39429,39430,39431,39432,39433,39434,39435,39436,39437,39438,39439,39440,39441,39442,39443,39444,39445,39446,39447,39448,39449,39450,39451,39452,39453,39454,39455,39456,39457,39458,39459,39460,39461,39462,39463,39464,39465,39466,39467,39468,39469,39470,39471,39472,39473,39474,39475,39476,39477,39478,39479,39480,39481,39482,39483,39484,39485,39486,39487,39488,39489,39490,39491,39492,39493,39494,39495,39496,39497,39498,39499,39500,39501,39502,39503,39504,39505,39506,39507,39508,39509,39510,39511,39512,39513,39514,39515,39516,39517,39518,39519,39520,39521,39522,39523,39524,39525,39526,39527,39528,39529,39530,39531,39532,39533,39534,39535,39536,39537,39538,39539,39540,39541,39542,39543,39544,39545,39546,39547,39548,39549,39550,39551,39552,39553,39554,39555,39556,39557,39558,39559,39560,39561,39562,39563,39564,39565,39566,39567,39568,39569,39570,39571,39572,39573,39574,39575,39576,39577,39578,39579,39580,39581,39582,39583,39584,39585,39586,39587,39588,39589,39590,39591,39592,39593,39594,39595,39596,39597,39598,39599,39600,39601,39602,39603,39604,39605,39606,39607,39608,39609,39610,39611,39612,39613,39614,39615,39616,39617,39618,39619,39620,39621,39622,39623,39624,39625,39626,39627,39628,39629,39630,39631,39632,39633,39634,39635,39636,39637,39638,39639,39640,39641,39642,39643,39644,39645,39646,39647,39648,39649,39650,39651,39652,39653,39654,39655,39656,39657,39658,39659,39660,39661,39662,39663,39664,39665,39666,39667,39668,39669,39670,39671,39672,39673,39674,39675,39676,39677,39678,39679,39680,39681,39682,39683,39684,39685,39686,39687,39688,39689,39690,39691,39692,39693,39694,39695,39696,39697,39698,39699,39700,39701,39702,39703,39704,39705,39706,39707,39708,39709,39710,39711,39712,39713,39714,39715,39716,39717,39718,39719,39720,39721,39722,39723,39724,39725,39726,39727,39728,39729,39730,39731,39732,39733,39734,39735,39736,39737,39738,39739,39740,39741,39742,39743,39744,39745,39746,39747,39748,39749,39750,39751,39752,39753,39754,39755,39756,39757,39758,39759,39760,39761,39762,39763,39764,39765,39766,39767,39768,39769,39770,39771,39772,39773,39774,39775,39776,39777,39778,39779,39780,39781,39782,39783,39784,39785,39786,39787,39788,39789,39790,39791,39792,39793,39794,39795,39796,39797,39798,39799,39800,39801,39802,39803,39804,39805,39806,39807,39808,39809,39810,39811,39812,39813,39814,39815,39816,39817,39818,39819,39820,39821,39822,39823,39824,39825,39826,39827,39828,39829,39830,39831,39832,39833,39834,39835,39836,39837,39838,39839,39840,39841,39842,39843,39844,39845,39846,39847,39848,39849,39850,39851,39852,39853,39854,39855,39856,39857,39858,39859,39860,39861,39862,39863,39864,39865,39866,39867,39868,39869,39870,39871,39872,39873,39874,39875,39876,39877,39878,39879,39880,39881,39882,39883,39884,39885,39886,39887,39888,39889,39890,39891,39892,39893,39894,39895,39896,39897,39898,39899,39900,39901,39902,39903,39904,39905,39906,39907,39908,39909,39910,39911,39912,39913,39914,39915,39916,39917,39918,39919,39920,39921,39922,39923,39924,39925,39926,39927,39928,39929,39930,39931,39932,39933,39934,39935,39936,39937,39938,39939,39940,39941,39942,39943,39944,39945,39946,39947,39948,39949,39950,39951,39952,39953,39954,39955,39956,39957,39958,39959,39960,39961,39962,39963,39964,39965,39966,39967,39968,39969,39970,39971,39972,39973,39974,39975,39976,39977,39978,39979,39980,39981,39982,39983,39984,39985,39986,39987,39988,39989,39990,39991,39992,39993,39994,39995,39996,39997,39998,39999,40000,40001,40002,40003,40004,40005,40006,40007,40008,40009,40010,40011,40012,40013,40014,40015,40016,40017,40018,40019,40020,40021,40022,40023,40024,40025,40026,40027,40028,40029,40030,40031,40032,40033,40034,40035,40036,40037,40038,40039,40040,40041,40042,40043,40044,40045,40046,40047,40048,40049,40050,40051,40052,40053,40054,40055,40056,40057,40058,40059,40060,40061,40062,40063,40064,40065,40066,40067,40068,40069,40070,40071,40072,40073,40074,40075,40076,40077,40078,40079,40080,40081,40082,40083,40084,40085,40086,40087,40088,40089,40090,40091,40092,40093,40094,40095,40096,40097,40098,40099,40100,40101,40102,40103,40104,40105,40106,40107,40108,40109,40110,40111,40112,40113,40114,40115,40116,40117,40118,40119,40120,40121,40122,40123,40124,40125,40126,40127,40128,40129,40130,40131,40132,40133,40134,40135,40136,40137,40138,40139,40140,40141,40142,40143,40144,40145,40146,40147,40148,40149,40150,40151,40152,40153,40154,40155,40156,40157,40158,40159,40160,40161,40162,40163,40164,40165,40166,40167,40168,40169,40170,40171,40172,40173,40174,40175,40176,40177,40178,40179,40180,40181,40182,40183,40184,40185,40186,40187,40188,40189,40190,40191,40192,40193,40194,40195,40196,40197,40198,40199,40200,40201,40202,40203,40204,40205,40206,40207,40208,40209,40210,40211,40212,40213,40214,40215,40216,40217,40218,40219,40220,40221,40222,40223,40224,40225,40226,40227,40228,40229,40230,40231,40232,40233,40234,40235,40236,40237,40238,40239,40240,40241,40242,40243,40244,40245,40246,40247,40248,40249,40250,40251,40252,40253,40254,40255,40256,40257,40258,40259,40260,40261,40262,40263,40264,40265,40266,40267,40268,40269,40270,40271,40272,40273,40274,40275,40276,40277,40278,40279,40280,40281,40282,40283,40284,40285,40286,40287,40288,40289,40290,40291,40292,40293,40294,40295,40296,40297,40298,40299,40300,40301,40302,40303,40304,40305,40306,40307,40308,40309,40310,40311,40312,40313,40314,40315,40316,40317,40318,40319,40320,40321,40322,40323,40324,40325,40326,40327,40328,40329,40330,40331,40332,40333,40334,40335,40336,40337,40338,40339,40340,40341,40342,40343,40344,40345,40346,40347,40348,40349,40350,40351,40352,40353,40354,40355,40356,40357,40358,40359,40360,40361,40362,40363,40364,40365,40366,40367,40368,40369,40370,40371,40372,40373,40374,40375,40376,40377,40378,40379,40380,40381,40382,40383,40384,40385,40386,40387,40388,40389,40390,40391,40392,40393,40394,40395,40396,40397,40398,40399,40400,40401,40402,40403,40404,40405,40406,40407,40408,40409,40410,40411,40412,40413,40414,40415,40416,40417,40418,40419,40420,40421,40422,40423,40424,40425,40426,40427,40428,40429,40430,40431,40432,40433,40434,40435,40436,40437,40438,40439,40440,40441,40442,40443,40444,40445,40446,40447,40448,40449,40450,40451,40452,40453,40454,40455,40456,40457,40458,40459,40460,40461,40462,40463,40464,40465,40466,40467,40468,40469,40470,40471,40472,40473,40474,40475,40476,40477,40478,40479,40480,40481,40482,40483,40484,40485,40486,40487,40488,40489,40490,40491,40492,40493,40494,40495,40496,40497,40498,40499,40500,40501,40502,40503,40504,40505,40506,40507,40508,40509,40510,40511,40512,40513,40514,40515,40516,40517,40518,40519,40520,40521,40522,40523,40524,40525,40526,40527,40528,40529,40530,40531,40532,40533,40534,40535,40536,40537,40538,40539,40540,40541,40542,40543,40544,40545,40546,40547,40548,40549,40550,40551,40552,40553,40554,40555,40556,40557,40558,40559,40560,40561,40562,40563,40564,40565,40566,40567,40568,40569,40570,40571,40572,40573,40574,40575,40576,40577,40578,40579,40580,40581,40582,40583,40584,40585,40586,40587,40588,40589,40590,40591,40592,40593,40594,40595,40596,40597,40598,40599,40600,40601,40602,40603,40604,40605,40606,40607,40608,40609,40610,40611,40612,40613,40614,40615,40616,40617,40618,40619,40620,40621,40622,40623,40624,40625,40626,40627,40628,40629,40630,40631,40632,40633,40634,40635,40636,40637,40638,40639,40640,40641,40642,40643,40644,40645,40646,40647,40648,40649,40650,40651,40652,40653,40654,40655,40656,40657,40658,40659,40660,40661,40662,40663,40664,40665,40666,40667,40668,40669,40670,40671,40672,40673,40674,40675,40676,40677,40678,40679,40680,40681,40682,40683,40684,40685,40686,40687,40688,40689,40690,40691,40692,40693,40694,40695,40696,40697,40698,40699,40700,40701,40702,40703,40704,40705,40706,40707,40708,40709,40710,40711,40712,40713,40714,40715,40716,40717,40718,40719,40720,40721,40722,40723,40724,40725,40726,40727,40728,40729,40730,40731,40732,40733,40734,40735,40736,40737,40738,40739,40740,40741,40742,40743,40744,40745,40746,40747,40748,40749,40750,40751,40752,40753,40754,40755,40756,40757,40758,40759,40760,40761,40762,40763,40764,40765,40766,40767,40768,40769,40770,40771,40772,40773,40774,40775,40776,40777,40778,40779,40780,40781,40782,40783,40784,40785,40786,40787,40788,40789,40790,40791,40792,40793,40794,40795,40796,40797,40798,40799,40800,40801,40802,40803,40804,40805,40806,40807,40808,40809,40810,40811,40812,40813,40814,40815,40816,40817,40818,40819,40820,40821,40822,40823,40824,40825,40826,40827,40828,40829,40830,40831,40832,40833,40834,40835,40836,40837,40838,40839,40840,40841,40842,40843,40844,40845,40846,40847,40848,40849,40850,40851,40852,40853,40854,40855,40856,40857,40858,40859,40860,40861,40862,40863,40864,40865,40866,40867,40868,40869,40870,40871,40872,40873,40874,40875,40876,40877,40878,40879,40880,40881,40882,40883,40884,40885,40886,40887,40888,40889,40890,40891,40892,40893,40894,40895,40896,40897,40898,40899,40900,40901,40902,40903,40904,40905,40906,40907,40908,40960,40961,40962,40963,40964,40965,40966,40967,40968,40969,40970,40971,40972,40973,40974,40975,40976,40977,40978,40979,40980,40981,40982,40983,40984,40985,40986,40987,40988,40989,40990,40991,40992,40993,40994,40995,40996,40997,40998,40999,41000,41001,41002,41003,41004,41005,41006,41007,41008,41009,41010,41011,41012,41013,41014,41015,41016,41017,41018,41019,41020,41021,41022,41023,41024,41025,41026,41027,41028,41029,41030,41031,41032,41033,41034,41035,41036,41037,41038,41039,41040,41041,41042,41043,41044,41045,41046,41047,41048,41049,41050,41051,41052,41053,41054,41055,41056,41057,41058,41059,41060,41061,41062,41063,41064,41065,41066,41067,41068,41069,41070,41071,41072,41073,41074,41075,41076,41077,41078,41079,41080,41081,41082,41083,41084,41085,41086,41087,41088,41089,41090,41091,41092,41093,41094,41095,41096,41097,41098,41099,41100,41101,41102,41103,41104,41105,41106,41107,41108,41109,41110,41111,41112,41113,41114,41115,41116,41117,41118,41119,41120,41121,41122,41123,41124,41125,41126,41127,41128,41129,41130,41131,41132,41133,41134,41135,41136,41137,41138,41139,41140,41141,41142,41143,41144,41145,41146,41147,41148,41149,41150,41151,41152,41153,41154,41155,41156,41157,41158,41159,41160,41161,41162,41163,41164,41165,41166,41167,41168,41169,41170,41171,41172,41173,41174,41175,41176,41177,41178,41179,41180,41181,41182,41183,41184,41185,41186,41187,41188,41189,41190,41191,41192,41193,41194,41195,41196,41197,41198,41199,41200,41201,41202,41203,41204,41205,41206,41207,41208,41209,41210,41211,41212,41213,41214,41215,41216,41217,41218,41219,41220,41221,41222,41223,41224,41225,41226,41227,41228,41229,41230,41231,41232,41233,41234,41235,41236,41237,41238,41239,41240,41241,41242,41243,41244,41245,41246,41247,41248,41249,41250,41251,41252,41253,41254,41255,41256,41257,41258,41259,41260,41261,41262,41263,41264,41265,41266,41267,41268,41269,41270,41271,41272,41273,41274,41275,41276,41277,41278,41279,41280,41281,41282,41283,41284,41285,41286,41287,41288,41289,41290,41291,41292,41293,41294,41295,41296,41297,41298,41299,41300,41301,41302,41303,41304,41305,41306,41307,41308,41309,41310,41311,41312,41313,41314,41315,41316,41317,41318,41319,41320,41321,41322,41323,41324,41325,41326,41327,41328,41329,41330,41331,41332,41333,41334,41335,41336,41337,41338,41339,41340,41341,41342,41343,41344,41345,41346,41347,41348,41349,41350,41351,41352,41353,41354,41355,41356,41357,41358,41359,41360,41361,41362,41363,41364,41365,41366,41367,41368,41369,41370,41371,41372,41373,41374,41375,41376,41377,41378,41379,41380,41381,41382,41383,41384,41385,41386,41387,41388,41389,41390,41391,41392,41393,41394,41395,41396,41397,41398,41399,41400,41401,41402,41403,41404,41405,41406,41407,41408,41409,41410,41411,41412,41413,41414,41415,41416,41417,41418,41419,41420,41421,41422,41423,41424,41425,41426,41427,41428,41429,41430,41431,41432,41433,41434,41435,41436,41437,41438,41439,41440,41441,41442,41443,41444,41445,41446,41447,41448,41449,41450,41451,41452,41453,41454,41455,41456,41457,41458,41459,41460,41461,41462,41463,41464,41465,41466,41467,41468,41469,41470,41471,41472,41473,41474,41475,41476,41477,41478,41479,41480,41481,41482,41483,41484,41485,41486,41487,41488,41489,41490,41491,41492,41493,41494,41495,41496,41497,41498,41499,41500,41501,41502,41503,41504,41505,41506,41507,41508,41509,41510,41511,41512,41513,41514,41515,41516,41517,41518,41519,41520,41521,41522,41523,41524,41525,41526,41527,41528,41529,41530,41531,41532,41533,41534,41535,41536,41537,41538,41539,41540,41541,41542,41543,41544,41545,41546,41547,41548,41549,41550,41551,41552,41553,41554,41555,41556,41557,41558,41559,41560,41561,41562,41563,41564,41565,41566,41567,41568,41569,41570,41571,41572,41573,41574,41575,41576,41577,41578,41579,41580,41581,41582,41583,41584,41585,41586,41587,41588,41589,41590,41591,41592,41593,41594,41595,41596,41597,41598,41599,41600,41601,41602,41603,41604,41605,41606,41607,41608,41609,41610,41611,41612,41613,41614,41615,41616,41617,41618,41619,41620,41621,41622,41623,41624,41625,41626,41627,41628,41629,41630,41631,41632,41633,41634,41635,41636,41637,41638,41639,41640,41641,41642,41643,41644,41645,41646,41647,41648,41649,41650,41651,41652,41653,41654,41655,41656,41657,41658,41659,41660,41661,41662,41663,41664,41665,41666,41667,41668,41669,41670,41671,41672,41673,41674,41675,41676,41677,41678,41679,41680,41681,41682,41683,41684,41685,41686,41687,41688,41689,41690,41691,41692,41693,41694,41695,41696,41697,41698,41699,41700,41701,41702,41703,41704,41705,41706,41707,41708,41709,41710,41711,41712,41713,41714,41715,41716,41717,41718,41719,41720,41721,41722,41723,41724,41725,41726,41727,41728,41729,41730,41731,41732,41733,41734,41735,41736,41737,41738,41739,41740,41741,41742,41743,41744,41745,41746,41747,41748,41749,41750,41751,41752,41753,41754,41755,41756,41757,41758,41759,41760,41761,41762,41763,41764,41765,41766,41767,41768,41769,41770,41771,41772,41773,41774,41775,41776,41777,41778,41779,41780,41781,41782,41783,41784,41785,41786,41787,41788,41789,41790,41791,41792,41793,41794,41795,41796,41797,41798,41799,41800,41801,41802,41803,41804,41805,41806,41807,41808,41809,41810,41811,41812,41813,41814,41815,41816,41817,41818,41819,41820,41821,41822,41823,41824,41825,41826,41827,41828,41829,41830,41831,41832,41833,41834,41835,41836,41837,41838,41839,41840,41841,41842,41843,41844,41845,41846,41847,41848,41849,41850,41851,41852,41853,41854,41855,41856,41857,41858,41859,41860,41861,41862,41863,41864,41865,41866,41867,41868,41869,41870,41871,41872,41873,41874,41875,41876,41877,41878,41879,41880,41881,41882,41883,41884,41885,41886,41887,41888,41889,41890,41891,41892,41893,41894,41895,41896,41897,41898,41899,41900,41901,41902,41903,41904,41905,41906,41907,41908,41909,41910,41911,41912,41913,41914,41915,41916,41917,41918,41919,41920,41921,41922,41923,41924,41925,41926,41927,41928,41929,41930,41931,41932,41933,41934,41935,41936,41937,41938,41939,41940,41941,41942,41943,41944,41945,41946,41947,41948,41949,41950,41951,41952,41953,41954,41955,41956,41957,41958,41959,41960,41961,41962,41963,41964,41965,41966,41967,41968,41969,41970,41971,41972,41973,41974,41975,41976,41977,41978,41979,41980,41981,41982,41983,41984,41985,41986,41987,41988,41989,41990,41991,41992,41993,41994,41995,41996,41997,41998,41999,42000,42001,42002,42003,42004,42005,42006,42007,42008,42009,42010,42011,42012,42013,42014,42015,42016,42017,42018,42019,42020,42021,42022,42023,42024,42025,42026,42027,42028,42029,42030,42031,42032,42033,42034,42035,42036,42037,42038,42039,42040,42041,42042,42043,42044,42045,42046,42047,42048,42049,42050,42051,42052,42053,42054,42055,42056,42057,42058,42059,42060,42061,42062,42063,42064,42065,42066,42067,42068,42069,42070,42071,42072,42073,42074,42075,42076,42077,42078,42079,42080,42081,42082,42083,42084,42085,42086,42087,42088,42089,42090,42091,42092,42093,42094,42095,42096,42097,42098,42099,42100,42101,42102,42103,42104,42105,42106,42107,42108,42109,42110,42111,42112,42113,42114,42115,42116,42117,42118,42119,42120,42121,42122,42123,42124,42192,42193,42194,42195,42196,42197,42198,42199,42200,42201,42202,42203,42204,42205,42206,42207,42208,42209,42210,42211,42212,42213,42214,42215,42216,42217,42218,42219,42220,42221,42222,42223,42224,42225,42226,42227,42228,42229,42230,42231,42232,42233,42234,42235,42236,42237,42240,42241,42242,42243,42244,42245,42246,42247,42248,42249,42250,42251,42252,42253,42254,42255,42256,42257,42258,42259,42260,42261,42262,42263,42264,42265,42266,42267,42268,42269,42270,42271,42272,42273,42274,42275,42276,42277,42278,42279,42280,42281,42282,42283,42284,42285,42286,42287,42288,42289,42290,42291,42292,42293,42294,42295,42296,42297,42298,42299,42300,42301,42302,42303,42304,42305,42306,42307,42308,42309,42310,42311,42312,42313,42314,42315,42316,42317,42318,42319,42320,42321,42322,42323,42324,42325,42326,42327,42328,42329,42330,42331,42332,42333,42334,42335,42336,42337,42338,42339,42340,42341,42342,42343,42344,42345,42346,42347,42348,42349,42350,42351,42352,42353,42354,42355,42356,42357,42358,42359,42360,42361,42362,42363,42364,42365,42366,42367,42368,42369,42370,42371,42372,42373,42374,42375,42376,42377,42378,42379,42380,42381,42382,42383,42384,42385,42386,42387,42388,42389,42390,42391,42392,42393,42394,42395,42396,42397,42398,42399,42400,42401,42402,42403,42404,42405,42406,42407,42408,42409,42410,42411,42412,42413,42414,42415,42416,42417,42418,42419,42420,42421,42422,42423,42424,42425,42426,42427,42428,42429,42430,42431,42432,42433,42434,42435,42436,42437,42438,42439,42440,42441,42442,42443,42444,42445,42446,42447,42448,42449,42450,42451,42452,42453,42454,42455,42456,42457,42458,42459,42460,42461,42462,42463,42464,42465,42466,42467,42468,42469,42470,42471,42472,42473,42474,42475,42476,42477,42478,42479,42480,42481,42482,42483,42484,42485,42486,42487,42488,42489,42490,42491,42492,42493,42494,42495,42496,42497,42498,42499,42500,42501,42502,42503,42504,42505,42506,42507,42508,42512,42513,42514,42515,42516,42517,42518,42519,42520,42521,42522,42523,42524,42525,42526,42527,42538,42539,42560,42561,42562,42563,42564,42565,42566,42567,42568,42569,42570,42571,42572,42573,42574,42575,42576,42577,42578,42579,42580,42581,42582,42583,42584,42585,42586,42587,42588,42589,42590,42591,42592,42593,42594,42595,42596,42597,42598,42599,42600,42601,42602,42603,42604,42605,42606,42623,42624,42625,42626,42627,42628,42629,42630,42631,42632,42633,42634,42635,42636,42637,42638,42639,42640,42641,42642,42643,42644,42645,42646,42647,42656,42657,42658,42659,42660,42661,42662,42663,42664,42665,42666,42667,42668,42669,42670,42671,42672,42673,42674,42675,42676,42677,42678,42679,42680,42681,42682,42683,42684,42685,42686,42687,42688,42689,42690,42691,42692,42693,42694,42695,42696,42697,42698,42699,42700,42701,42702,42703,42704,42705,42706,42707,42708,42709,42710,42711,42712,42713,42714,42715,42716,42717,42718,42719,42720,42721,42722,42723,42724,42725,42726,42727,42728,42729,42730,42731,42732,42733,42734,42735,42775,42776,42777,42778,42779,42780,42781,42782,42783,42786,42787,42788,42789,42790,42791,42792,42793,42794,42795,42796,42797,42798,42799,42800,42801,42802,42803,42804,42805,42806,42807,42808,42809,42810,42811,42812,42813,42814,42815,42816,42817,42818,42819,42820,42821,42822,42823,42824,42825,42826,42827,42828,42829,42830,42831,42832,42833,42834,42835,42836,42837,42838,42839,42840,42841,42842,42843,42844,42845,42846,42847,42848,42849,42850,42851,42852,42853,42854,42855,42856,42857,42858,42859,42860,42861,42862,42863,42864,42865,42866,42867,42868,42869,42870,42871,42872,42873,42874,42875,42876,42877,42878,42879,42880,42881,42882,42883,42884,42885,42886,42887,42888,42891,42892,42893,42894,42896,42897,42898,42899,42912,42913,42914,42915,42916,42917,42918,42919,42920,42921,42922,43000,43001,43002,43003,43004,43005,43006,43007,43008,43009,43011,43012,43013,43015,43016,43017,43018,43020,43021,43022,43023,43024,43025,43026,43027,43028,43029,43030,43031,43032,43033,43034,43035,43036,43037,43038,43039,43040,43041,43042,43072,43073,43074,43075,43076,43077,43078,43079,43080,43081,43082,43083,43084,43085,43086,43087,43088,43089,43090,43091,43092,43093,43094,43095,43096,43097,43098,43099,43100,43101,43102,43103,43104,43105,43106,43107,43108,43109,43110,43111,43112,43113,43114,43115,43116,43117,43118,43119,43120,43121,43122,43123,43138,43139,43140,43141,43142,43143,43144,43145,43146,43147,43148,43149,43150,43151,43152,43153,43154,43155,43156,43157,43158,43159,43160,43161,43162,43163,43164,43165,43166,43167,43168,43169,43170,43171,43172,43173,43174,43175,43176,43177,43178,43179,43180,43181,43182,43183,43184,43185,43186,43187,43250,43251,43252,43253,43254,43255,43259,43274,43275,43276,43277,43278,43279,43280,43281,43282,43283,43284,43285,43286,43287,43288,43289,43290,43291,43292,43293,43294,43295,43296,43297,43298,43299,43300,43301,43312,43313,43314,43315,43316,43317,43318,43319,43320,43321,43322,43323,43324,43325,43326,43327,43328,43329,43330,43331,43332,43333,43334,43360,43361,43362,43363,43364,43365,43366,43367,43368,43369,43370,43371,43372,43373,43374,43375,43376,43377,43378,43379,43380,43381,43382,43383,43384,43385,43386,43387,43388,43396,43397,43398,43399,43400,43401,43402,43403,43404,43405,43406,43407,43408,43409,43410,43411,43412,43413,43414,43415,43416,43417,43418,43419,43420,43421,43422,43423,43424,43425,43426,43427,43428,43429,43430,43431,43432,43433,43434,43435,43436,43437,43438,43439,43440,43441,43442,43471,43520,43521,43522,43523,43524,43525,43526,43527,43528,43529,43530,43531,43532,43533,43534,43535,43536,43537,43538,43539,43540,43541,43542,43543,43544,43545,43546,43547,43548,43549,43550,43551,43552,43553,43554,43555,43556,43557,43558,43559,43560,43584,43585,43586,43588,43589,43590,43591,43592,43593,43594,43595,43616,43617,43618,43619,43620,43621,43622,43623,43624,43625,43626,43627,43628,43629,43630,43631,43632,43633,43634,43635,43636,43637,43638,43642,43648,43649,43650,43651,43652,43653,43654,43655,43656,43657,43658,43659,43660,43661,43662,43663,43664,43665,43666,43667,43668,43669,43670,43671,43672,43673,43674,43675,43676,43677,43678,43679,43680,43681,43682,43683,43684,43685,43686,43687,43688,43689,43690,43691,43692,43693,43694,43695,43697,43701,43702,43705,43706,43707,43708,43709,43712,43714,43739,43740,43741,43744,43745,43746,43747,43748,43749,43750,43751,43752,43753,43754,43762,43763,43764,43777,43778,43779,43780,43781,43782,43785,43786,43787,43788,43789,43790,43793,43794,43795,43796,43797,43798,43808,43809,43810,43811,43812,43813,43814,43816,43817,43818,43819,43820,43821,43822,43968,43969,43970,43971,43972,43973,43974,43975,43976,43977,43978,43979,43980,43981,43982,43983,43984,43985,43986,43987,43988,43989,43990,43991,43992,43993,43994,43995,43996,43997,43998,43999,44000,44001,44002,44032,44033,44034,44035,44036,44037,44038,44039,44040,44041,44042,44043,44044,44045,44046,44047,44048,44049,44050,44051,44052,44053,44054,44055,44056,44057,44058,44059,44060,44061,44062,44063,44064,44065,44066,44067,44068,44069,44070,44071,44072,44073,44074,44075,44076,44077,44078,44079,44080,44081,44082,44083,44084,44085,44086,44087,44088,44089,44090,44091,44092,44093,44094,44095,44096,44097,44098,44099,44100,44101,44102,44103,44104,44105,44106,44107,44108,44109,44110,44111,44112,44113,44114,44115,44116,44117,44118,44119,44120,44121,44122,44123,44124,44125,44126,44127,44128,44129,44130,44131,44132,44133,44134,44135,44136,44137,44138,44139,44140,44141,44142,44143,44144,44145,44146,44147,44148,44149,44150,44151,44152,44153,44154,44155,44156,44157,44158,44159,44160,44161,44162,44163,44164,44165,44166,44167,44168,44169,44170,44171,44172,44173,44174,44175,44176,44177,44178,44179,44180,44181,44182,44183,44184,44185,44186,44187,44188,44189,44190,44191,44192,44193,44194,44195,44196,44197,44198,44199,44200,44201,44202,44203,44204,44205,44206,44207,44208,44209,44210,44211,44212,44213,44214,44215,44216,44217,44218,44219,44220,44221,44222,44223,44224,44225,44226,44227,44228,44229,44230,44231,44232,44233,44234,44235,44236,44237,44238,44239,44240,44241,44242,44243,44244,44245,44246,44247,44248,44249,44250,44251,44252,44253,44254,44255,44256,44257,44258,44259,44260,44261,44262,44263,44264,44265,44266,44267,44268,44269,44270,44271,44272,44273,44274,44275,44276,44277,44278,44279,44280,44281,44282,44283,44284,44285,44286,44287,44288,44289,44290,44291,44292,44293,44294,44295,44296,44297,44298,44299,44300,44301,44302,44303,44304,44305,44306,44307,44308,44309,44310,44311,44312,44313,44314,44315,44316,44317,44318,44319,44320,44321,44322,44323,44324,44325,44326,44327,44328,44329,44330,44331,44332,44333,44334,44335,44336,44337,44338,44339,44340,44341,44342,44343,44344,44345,44346,44347,44348,44349,44350,44351,44352,44353,44354,44355,44356,44357,44358,44359,44360,44361,44362,44363,44364,44365,44366,44367,44368,44369,44370,44371,44372,44373,44374,44375,44376,44377,44378,44379,44380,44381,44382,44383,44384,44385,44386,44387,44388,44389,44390,44391,44392,44393,44394,44395,44396,44397,44398,44399,44400,44401,44402,44403,44404,44405,44406,44407,44408,44409,44410,44411,44412,44413,44414,44415,44416,44417,44418,44419,44420,44421,44422,44423,44424,44425,44426,44427,44428,44429,44430,44431,44432,44433,44434,44435,44436,44437,44438,44439,44440,44441,44442,44443,44444,44445,44446,44447,44448,44449,44450,44451,44452,44453,44454,44455,44456,44457,44458,44459,44460,44461,44462,44463,44464,44465,44466,44467,44468,44469,44470,44471,44472,44473,44474,44475,44476,44477,44478,44479,44480,44481,44482,44483,44484,44485,44486,44487,44488,44489,44490,44491,44492,44493,44494,44495,44496,44497,44498,44499,44500,44501,44502,44503,44504,44505,44506,44507,44508,44509,44510,44511,44512,44513,44514,44515,44516,44517,44518,44519,44520,44521,44522,44523,44524,44525,44526,44527,44528,44529,44530,44531,44532,44533,44534,44535,44536,44537,44538,44539,44540,44541,44542,44543,44544,44545,44546,44547,44548,44549,44550,44551,44552,44553,44554,44555,44556,44557,44558,44559,44560,44561,44562,44563,44564,44565,44566,44567,44568,44569,44570,44571,44572,44573,44574,44575,44576,44577,44578,44579,44580,44581,44582,44583,44584,44585,44586,44587,44588,44589,44590,44591,44592,44593,44594,44595,44596,44597,44598,44599,44600,44601,44602,44603,44604,44605,44606,44607,44608,44609,44610,44611,44612,44613,44614,44615,44616,44617,44618,44619,44620,44621,44622,44623,44624,44625,44626,44627,44628,44629,44630,44631,44632,44633,44634,44635,44636,44637,44638,44639,44640,44641,44642,44643,44644,44645,44646,44647,44648,44649,44650,44651,44652,44653,44654,44655,44656,44657,44658,44659,44660,44661,44662,44663,44664,44665,44666,44667,44668,44669,44670,44671,44672,44673,44674,44675,44676,44677,44678,44679,44680,44681,44682,44683,44684,44685,44686,44687,44688,44689,44690,44691,44692,44693,44694,44695,44696,44697,44698,44699,44700,44701,44702,44703,44704,44705,44706,44707,44708,44709,44710,44711,44712,44713,44714,44715,44716,44717,44718,44719,44720,44721,44722,44723,44724,44725,44726,44727,44728,44729,44730,44731,44732,44733,44734,44735,44736,44737,44738,44739,44740,44741,44742,44743,44744,44745,44746,44747,44748,44749,44750,44751,44752,44753,44754,44755,44756,44757,44758,44759,44760,44761,44762,44763,44764,44765,44766,44767,44768,44769,44770,44771,44772,44773,44774,44775,44776,44777,44778,44779,44780,44781,44782,44783,44784,44785,44786,44787,44788,44789,44790,44791,44792,44793,44794,44795,44796,44797,44798,44799,44800,44801,44802,44803,44804,44805,44806,44807,44808,44809,44810,44811,44812,44813,44814,44815,44816,44817,44818,44819,44820,44821,44822,44823,44824,44825,44826,44827,44828,44829,44830,44831,44832,44833,44834,44835,44836,44837,44838,44839,44840,44841,44842,44843,44844,44845,44846,44847,44848,44849,44850,44851,44852,44853,44854,44855,44856,44857,44858,44859,44860,44861,44862,44863,44864,44865,44866,44867,44868,44869,44870,44871,44872,44873,44874,44875,44876,44877,44878,44879,44880,44881,44882,44883,44884,44885,44886,44887,44888,44889,44890,44891,44892,44893,44894,44895,44896,44897,44898,44899,44900,44901,44902,44903,44904,44905,44906,44907,44908,44909,44910,44911,44912,44913,44914,44915,44916,44917,44918,44919,44920,44921,44922,44923,44924,44925,44926,44927,44928,44929,44930,44931,44932,44933,44934,44935,44936,44937,44938,44939,44940,44941,44942,44943,44944,44945,44946,44947,44948,44949,44950,44951,44952,44953,44954,44955,44956,44957,44958,44959,44960,44961,44962,44963,44964,44965,44966,44967,44968,44969,44970,44971,44972,44973,44974,44975,44976,44977,44978,44979,44980,44981,44982,44983,44984,44985,44986,44987,44988,44989,44990,44991,44992,44993,44994,44995,44996,44997,44998,44999,45000,45001,45002,45003,45004,45005,45006,45007,45008,45009,45010,45011,45012,45013,45014,45015,45016,45017,45018,45019,45020,45021,45022,45023,45024,45025,45026,45027,45028,45029,45030,45031,45032,45033,45034,45035,45036,45037,45038,45039,45040,45041,45042,45043,45044,45045,45046,45047,45048,45049,45050,45051,45052,45053,45054,45055,45056,45057,45058,45059,45060,45061,45062,45063,45064,45065,45066,45067,45068,45069,45070,45071,45072,45073,45074,45075,45076,45077,45078,45079,45080,45081,45082,45083,45084,45085,45086,45087,45088,45089,45090,45091,45092,45093,45094,45095,45096,45097,45098,45099,45100,45101,45102,45103,45104,45105,45106,45107,45108,45109,45110,45111,45112,45113,45114,45115,45116,45117,45118,45119,45120,45121,45122,45123,45124,45125,45126,45127,45128,45129,45130,45131,45132,45133,45134,45135,45136,45137,45138,45139,45140,45141,45142,45143,45144,45145,45146,45147,45148,45149,45150,45151,45152,45153,45154,45155,45156,45157,45158,45159,45160,45161,45162,45163,45164,45165,45166,45167,45168,45169,45170,45171,45172,45173,45174,45175,45176,45177,45178,45179,45180,45181,45182,45183,45184,45185,45186,45187,45188,45189,45190,45191,45192,45193,45194,45195,45196,45197,45198,45199,45200,45201,45202,45203,45204,45205,45206,45207,45208,45209,45210,45211,45212,45213,45214,45215,45216,45217,45218,45219,45220,45221,45222,45223,45224,45225,45226,45227,45228,45229,45230,45231,45232,45233,45234,45235,45236,45237,45238,45239,45240,45241,45242,45243,45244,45245,45246,45247,45248,45249,45250,45251,45252,45253,45254,45255,45256,45257,45258,45259,45260,45261,45262,45263,45264,45265,45266,45267,45268,45269,45270,45271,45272,45273,45274,45275,45276,45277,45278,45279,45280,45281,45282,45283,45284,45285,45286,45287,45288,45289,45290,45291,45292,45293,45294,45295,45296,45297,45298,45299,45300,45301,45302,45303,45304,45305,45306,45307,45308,45309,45310,45311,45312,45313,45314,45315,45316,45317,45318,45319,45320,45321,45322,45323,45324,45325,45326,45327,45328,45329,45330,45331,45332,45333,45334,45335,45336,45337,45338,45339,45340,45341,45342,45343,45344,45345,45346,45347,45348,45349,45350,45351,45352,45353,45354,45355,45356,45357,45358,45359,45360,45361,45362,45363,45364,45365,45366,45367,45368,45369,45370,45371,45372,45373,45374,45375,45376,45377,45378,45379,45380,45381,45382,45383,45384,45385,45386,45387,45388,45389,45390,45391,45392,45393,45394,45395,45396,45397,45398,45399,45400,45401,45402,45403,45404,45405,45406,45407,45408,45409,45410,45411,45412,45413,45414,45415,45416,45417,45418,45419,45420,45421,45422,45423,45424,45425,45426,45427,45428,45429,45430,45431,45432,45433,45434,45435,45436,45437,45438,45439,45440,45441,45442,45443,45444,45445,45446,45447,45448,45449,45450,45451,45452,45453,45454,45455,45456,45457,45458,45459,45460,45461,45462,45463,45464,45465,45466,45467,45468,45469,45470,45471,45472,45473,45474,45475,45476,45477,45478,45479,45480,45481,45482,45483,45484,45485,45486,45487,45488,45489,45490,45491,45492,45493,45494,45495,45496,45497,45498,45499,45500,45501,45502,45503,45504,45505,45506,45507,45508,45509,45510,45511,45512,45513,45514,45515,45516,45517,45518,45519,45520,45521,45522,45523,45524,45525,45526,45527,45528,45529,45530,45531,45532,45533,45534,45535,45536,45537,45538,45539,45540,45541,45542,45543,45544,45545,45546,45547,45548,45549,45550,45551,45552,45553,45554,45555,45556,45557,45558,45559,45560,45561,45562,45563,45564,45565,45566,45567,45568,45569,45570,45571,45572,45573,45574,45575,45576,45577,45578,45579,45580,45581,45582,45583,45584,45585,45586,45587,45588,45589,45590,45591,45592,45593,45594,45595,45596,45597,45598,45599,45600,45601,45602,45603,45604,45605,45606,45607,45608,45609,45610,45611,45612,45613,45614,45615,45616,45617,45618,45619,45620,45621,45622,45623,45624,45625,45626,45627,45628,45629,45630,45631,45632,45633,45634,45635,45636,45637,45638,45639,45640,45641,45642,45643,45644,45645,45646,45647,45648,45649,45650,45651,45652,45653,45654,45655,45656,45657,45658,45659,45660,45661,45662,45663,45664,45665,45666,45667,45668,45669,45670,45671,45672,45673,45674,45675,45676,45677,45678,45679,45680,45681,45682,45683,45684,45685,45686,45687,45688,45689,45690,45691,45692,45693,45694,45695,45696,45697,45698,45699,45700,45701,45702,45703,45704,45705,45706,45707,45708,45709,45710,45711,45712,45713,45714,45715,45716,45717,45718,45719,45720,45721,45722,45723,45724,45725,45726,45727,45728,45729,45730,45731,45732,45733,45734,45735,45736,45737,45738,45739,45740,45741,45742,45743,45744,45745,45746,45747,45748,45749,45750,45751,45752,45753,45754,45755,45756,45757,45758,45759,45760,45761,45762,45763,45764,45765,45766,45767,45768,45769,45770,45771,45772,45773,45774,45775,45776,45777,45778,45779,45780,45781,45782,45783,45784,45785,45786,45787,45788,45789,45790,45791,45792,45793,45794,45795,45796,45797,45798,45799,45800,45801,45802,45803,45804,45805,45806,45807,45808,45809,45810,45811,45812,45813,45814,45815,45816,45817,45818,45819,45820,45821,45822,45823,45824,45825,45826,45827,45828,45829,45830,45831,45832,45833,45834,45835,45836,45837,45838,45839,45840,45841,45842,45843,45844,45845,45846,45847,45848,45849,45850,45851,45852,45853,45854,45855,45856,45857,45858,45859,45860,45861,45862,45863,45864,45865,45866,45867,45868,45869,45870,45871,45872,45873,45874,45875,45876,45877,45878,45879,45880,45881,45882,45883,45884,45885,45886,45887,45888,45889,45890,45891,45892,45893,45894,45895,45896,45897,45898,45899,45900,45901,45902,45903,45904,45905,45906,45907,45908,45909,45910,45911,45912,45913,45914,45915,45916,45917,45918,45919,45920,45921,45922,45923,45924,45925,45926,45927,45928,45929,45930,45931,45932,45933,45934,45935,45936,45937,45938,45939,45940,45941,45942,45943,45944,45945,45946,45947,45948,45949,45950,45951,45952,45953,45954,45955,45956,45957,45958,45959,45960,45961,45962,45963,45964,45965,45966,45967,45968,45969,45970,45971,45972,45973,45974,45975,45976,45977,45978,45979,45980,45981,45982,45983,45984,45985,45986,45987,45988,45989,45990,45991,45992,45993,45994,45995,45996,45997,45998,45999,46000,46001,46002,46003,46004,46005,46006,46007,46008,46009,46010,46011,46012,46013,46014,46015,46016,46017,46018,46019,46020,46021,46022,46023,46024,46025,46026,46027,46028,46029,46030,46031,46032,46033,46034,46035,46036,46037,46038,46039,46040,46041,46042,46043,46044,46045,46046,46047,46048,46049,46050,46051,46052,46053,46054,46055,46056,46057,46058,46059,46060,46061,46062,46063,46064,46065,46066,46067,46068,46069,46070,46071,46072,46073,46074,46075,46076,46077,46078,46079,46080,46081,46082,46083,46084,46085,46086,46087,46088,46089,46090,46091,46092,46093,46094,46095,46096,46097,46098,46099,46100,46101,46102,46103,46104,46105,46106,46107,46108,46109,46110,46111,46112,46113,46114,46115,46116,46117,46118,46119,46120,46121,46122,46123,46124,46125,46126,46127,46128,46129,46130,46131,46132,46133,46134,46135,46136,46137,46138,46139,46140,46141,46142,46143,46144,46145,46146,46147,46148,46149,46150,46151,46152,46153,46154,46155,46156,46157,46158,46159,46160,46161,46162,46163,46164,46165,46166,46167,46168,46169,46170,46171,46172,46173,46174,46175,46176,46177,46178,46179,46180,46181,46182,46183,46184,46185,46186,46187,46188,46189,46190,46191,46192,46193,46194,46195,46196,46197,46198,46199,46200,46201,46202,46203,46204,46205,46206,46207,46208,46209,46210,46211,46212,46213,46214,46215,46216,46217,46218,46219,46220,46221,46222,46223,46224,46225,46226,46227,46228,46229,46230,46231,46232,46233,46234,46235,46236,46237,46238,46239,46240,46241,46242,46243,46244,46245,46246,46247,46248,46249,46250,46251,46252,46253,46254,46255,46256,46257,46258,46259,46260,46261,46262,46263,46264,46265,46266,46267,46268,46269,46270,46271,46272,46273,46274,46275,46276,46277,46278,46279,46280,46281,46282,46283,46284,46285,46286,46287,46288,46289,46290,46291,46292,46293,46294,46295,46296,46297,46298,46299,46300,46301,46302,46303,46304,46305,46306,46307,46308,46309,46310,46311,46312,46313,46314,46315,46316,46317,46318,46319,46320,46321,46322,46323,46324,46325,46326,46327,46328,46329,46330,46331,46332,46333,46334,46335,46336,46337,46338,46339,46340,46341,46342,46343,46344,46345,46346,46347,46348,46349,46350,46351,46352,46353,46354,46355,46356,46357,46358,46359,46360,46361,46362,46363,46364,46365,46366,46367,46368,46369,46370,46371,46372,46373,46374,46375,46376,46377,46378,46379,46380,46381,46382,46383,46384,46385,46386,46387,46388,46389,46390,46391,46392,46393,46394,46395,46396,46397,46398,46399,46400,46401,46402,46403,46404,46405,46406,46407,46408,46409,46410,46411,46412,46413,46414,46415,46416,46417,46418,46419,46420,46421,46422,46423,46424,46425,46426,46427,46428,46429,46430,46431,46432,46433,46434,46435,46436,46437,46438,46439,46440,46441,46442,46443,46444,46445,46446,46447,46448,46449,46450,46451,46452,46453,46454,46455,46456,46457,46458,46459,46460,46461,46462,46463,46464,46465,46466,46467,46468,46469,46470,46471,46472,46473,46474,46475,46476,46477,46478,46479,46480,46481,46482,46483,46484,46485,46486,46487,46488,46489,46490,46491,46492,46493,46494,46495,46496,46497,46498,46499,46500,46501,46502,46503,46504,46505,46506,46507,46508,46509,46510,46511,46512,46513,46514,46515,46516,46517,46518,46519,46520,46521,46522,46523,46524,46525,46526,46527,46528,46529,46530,46531,46532,46533,46534,46535,46536,46537,46538,46539,46540,46541,46542,46543,46544,46545,46546,46547,46548,46549,46550,46551,46552,46553,46554,46555,46556,46557,46558,46559,46560,46561,46562,46563,46564,46565,46566,46567,46568,46569,46570,46571,46572,46573,46574,46575,46576,46577,46578,46579,46580,46581,46582,46583,46584,46585,46586,46587,46588,46589,46590,46591,46592,46593,46594,46595,46596,46597,46598,46599,46600,46601,46602,46603,46604,46605,46606,46607,46608,46609,46610,46611,46612,46613,46614,46615,46616,46617,46618,46619,46620,46621,46622,46623,46624,46625,46626,46627,46628,46629,46630,46631,46632,46633,46634,46635,46636,46637,46638,46639,46640,46641,46642,46643,46644,46645,46646,46647,46648,46649,46650,46651,46652,46653,46654,46655,46656,46657,46658,46659,46660,46661,46662,46663,46664,46665,46666,46667,46668,46669,46670,46671,46672,46673,46674,46675,46676,46677,46678,46679,46680,46681,46682,46683,46684,46685,46686,46687,46688,46689,46690,46691,46692,46693,46694,46695,46696,46697,46698,46699,46700,46701,46702,46703,46704,46705,46706,46707,46708,46709,46710,46711,46712,46713,46714,46715,46716,46717,46718,46719,46720,46721,46722,46723,46724,46725,46726,46727,46728,46729,46730,46731,46732,46733,46734,46735,46736,46737,46738,46739,46740,46741,46742,46743,46744,46745,46746,46747,46748,46749,46750,46751,46752,46753,46754,46755,46756,46757,46758,46759,46760,46761,46762,46763,46764,46765,46766,46767,46768,46769,46770,46771,46772,46773,46774,46775,46776,46777,46778,46779,46780,46781,46782,46783,46784,46785,46786,46787,46788,46789,46790,46791,46792,46793,46794,46795,46796,46797,46798,46799,46800,46801,46802,46803,46804,46805,46806,46807,46808,46809,46810,46811,46812,46813,46814,46815,46816,46817,46818,46819,46820,46821,46822,46823,46824,46825,46826,46827,46828,46829,46830,46831,46832,46833,46834,46835,46836,46837,46838,46839,46840,46841,46842,46843,46844,46845,46846,46847,46848,46849,46850,46851,46852,46853,46854,46855,46856,46857,46858,46859,46860,46861,46862,46863,46864,46865,46866,46867,46868,46869,46870,46871,46872,46873,46874,46875,46876,46877,46878,46879,46880,46881,46882,46883,46884,46885,46886,46887,46888,46889,46890,46891,46892,46893,46894,46895,46896,46897,46898,46899,46900,46901,46902,46903,46904,46905,46906,46907,46908,46909,46910,46911,46912,46913,46914,46915,46916,46917,46918,46919,46920,46921,46922,46923,46924,46925,46926,46927,46928,46929,46930,46931,46932,46933,46934,46935,46936,46937,46938,46939,46940,46941,46942,46943,46944,46945,46946,46947,46948,46949,46950,46951,46952,46953,46954,46955,46956,46957,46958,46959,46960,46961,46962,46963,46964,46965,46966,46967,46968,46969,46970,46971,46972,46973,46974,46975,46976,46977,46978,46979,46980,46981,46982,46983,46984,46985,46986,46987,46988,46989,46990,46991,46992,46993,46994,46995,46996,46997,46998,46999,47000,47001,47002,47003,47004,47005,47006,47007,47008,47009,47010,47011,47012,47013,47014,47015,47016,47017,47018,47019,47020,47021,47022,47023,47024,47025,47026,47027,47028,47029,47030,47031,47032,47033,47034,47035,47036,47037,47038,47039,47040,47041,47042,47043,47044,47045,47046,47047,47048,47049,47050,47051,47052,47053,47054,47055,47056,47057,47058,47059,47060,47061,47062,47063,47064,47065,47066,47067,47068,47069,47070,47071,47072,47073,47074,47075,47076,47077,47078,47079,47080,47081,47082,47083,47084,47085,47086,47087,47088,47089,47090,47091,47092,47093,47094,47095,47096,47097,47098,47099,47100,47101,47102,47103,47104,47105,47106,47107,47108,47109,47110,47111,47112,47113,47114,47115,47116,47117,47118,47119,47120,47121,47122,47123,47124,47125,47126,47127,47128,47129,47130,47131,47132,47133,47134,47135,47136,47137,47138,47139,47140,47141,47142,47143,47144,47145,47146,47147,47148,47149,47150,47151,47152,47153,47154,47155,47156,47157,47158,47159,47160,47161,47162,47163,47164,47165,47166,47167,47168,47169,47170,47171,47172,47173,47174,47175,47176,47177,47178,47179,47180,47181,47182,47183,47184,47185,47186,47187,47188,47189,47190,47191,47192,47193,47194,47195,47196,47197,47198,47199,47200,47201,47202,47203,47204,47205,47206,47207,47208,47209,47210,47211,47212,47213,47214,47215,47216,47217,47218,47219,47220,47221,47222,47223,47224,47225,47226,47227,47228,47229,47230,47231,47232,47233,47234,47235,47236,47237,47238,47239,47240,47241,47242,47243,47244,47245,47246,47247,47248,47249,47250,47251,47252,47253,47254,47255,47256,47257,47258,47259,47260,47261,47262,47263,47264,47265,47266,47267,47268,47269,47270,47271,47272,47273,47274,47275,47276,47277,47278,47279,47280,47281,47282,47283,47284,47285,47286,47287,47288,47289,47290,47291,47292,47293,47294,47295,47296,47297,47298,47299,47300,47301,47302,47303,47304,47305,47306,47307,47308,47309,47310,47311,47312,47313,47314,47315,47316,47317,47318,47319,47320,47321,47322,47323,47324,47325,47326,47327,47328,47329,47330,47331,47332,47333,47334,47335,47336,47337,47338,47339,47340,47341,47342,47343,47344,47345,47346,47347,47348,47349,47350,47351,47352,47353,47354,47355,47356,47357,47358,47359,47360,47361,47362,47363,47364,47365,47366,47367,47368,47369,47370,47371,47372,47373,47374,47375,47376,47377,47378,47379,47380,47381,47382,47383,47384,47385,47386,47387,47388,47389,47390,47391,47392,47393,47394,47395,47396,47397,47398,47399,47400,47401,47402,47403,47404,47405,47406,47407,47408,47409,47410,47411,47412,47413,47414,47415,47416,47417,47418,47419,47420,47421,47422,47423,47424,47425,47426,47427,47428,47429,47430,47431,47432,47433,47434,47435,47436,47437,47438,47439,47440,47441,47442,47443,47444,47445,47446,47447,47448,47449,47450,47451,47452,47453,47454,47455,47456,47457,47458,47459,47460,47461,47462,47463,47464,47465,47466,47467,47468,47469,47470,47471,47472,47473,47474,47475,47476,47477,47478,47479,47480,47481,47482,47483,47484,47485,47486,47487,47488,47489,47490,47491,47492,47493,47494,47495,47496,47497,47498,47499,47500,47501,47502,47503,47504,47505,47506,47507,47508,47509,47510,47511,47512,47513,47514,47515,47516,47517,47518,47519,47520,47521,47522,47523,47524,47525,47526,47527,47528,47529,47530,47531,47532,47533,47534,47535,47536,47537,47538,47539,47540,47541,47542,47543,47544,47545,47546,47547,47548,47549,47550,47551,47552,47553,47554,47555,47556,47557,47558,47559,47560,47561,47562,47563,47564,47565,47566,47567,47568,47569,47570,47571,47572,47573,47574,47575,47576,47577,47578,47579,47580,47581,47582,47583,47584,47585,47586,47587,47588,47589,47590,47591,47592,47593,47594,47595,47596,47597,47598,47599,47600,47601,47602,47603,47604,47605,47606,47607,47608,47609,47610,47611,47612,47613,47614,47615,47616,47617,47618,47619,47620,47621,47622,47623,47624,47625,47626,47627,47628,47629,47630,47631,47632,47633,47634,47635,47636,47637,47638,47639,47640,47641,47642,47643,47644,47645,47646,47647,47648,47649,47650,47651,47652,47653,47654,47655,47656,47657,47658,47659,47660,47661,47662,47663,47664,47665,47666,47667,47668,47669,47670,47671,47672,47673,47674,47675,47676,47677,47678,47679,47680,47681,47682,47683,47684,47685,47686,47687,47688,47689,47690,47691,47692,47693,47694,47695,47696,47697,47698,47699,47700,47701,47702,47703,47704,47705,47706,47707,47708,47709,47710,47711,47712,47713,47714,47715,47716,47717,47718,47719,47720,47721,47722,47723,47724,47725,47726,47727,47728,47729,47730,47731,47732,47733,47734,47735,47736,47737,47738,47739,47740,47741,47742,47743,47744,47745,47746,47747,47748,47749,47750,47751,47752,47753,47754,47755,47756,47757,47758,47759,47760,47761,47762,47763,47764,47765,47766,47767,47768,47769,47770,47771,47772,47773,47774,47775,47776,47777,47778,47779,47780,47781,47782,47783,47784,47785,47786,47787,47788,47789,47790,47791,47792,47793,47794,47795,47796,47797,47798,47799,47800,47801,47802,47803,47804,47805,47806,47807,47808,47809,47810,47811,47812,47813,47814,47815,47816,47817,47818,47819,47820,47821,47822,47823,47824,47825,47826,47827,47828,47829,47830,47831,47832,47833,47834,47835,47836,47837,47838,47839,47840,47841,47842,47843,47844,47845,47846,47847,47848,47849,47850,47851,47852,47853,47854,47855,47856,47857,47858,47859,47860,47861,47862,47863,47864,47865,47866,47867,47868,47869,47870,47871,47872,47873,47874,47875,47876,47877,47878,47879,47880,47881,47882,47883,47884,47885,47886,47887,47888,47889,47890,47891,47892,47893,47894,47895,47896,47897,47898,47899,47900,47901,47902,47903,47904,47905,47906,47907,47908,47909,47910,47911,47912,47913,47914,47915,47916,47917,47918,47919,47920,47921,47922,47923,47924,47925,47926,47927,47928,47929,47930,47931,47932,47933,47934,47935,47936,47937,47938,47939,47940,47941,47942,47943,47944,47945,47946,47947,47948,47949,47950,47951,47952,47953,47954,47955,47956,47957,47958,47959,47960,47961,47962,47963,47964,47965,47966,47967,47968,47969,47970,47971,47972,47973,47974,47975,47976,47977,47978,47979,47980,47981,47982,47983,47984,47985,47986,47987,47988,47989,47990,47991,47992,47993,47994,47995,47996,47997,47998,47999,48000,48001,48002,48003,48004,48005,48006,48007,48008,48009,48010,48011,48012,48013,48014,48015,48016,48017,48018,48019,48020,48021,48022,48023,48024,48025,48026,48027,48028,48029,48030,48031,48032,48033,48034,48035,48036,48037,48038,48039,48040,48041,48042,48043,48044,48045,48046,48047,48048,48049,48050,48051,48052,48053,48054,48055,48056,48057,48058,48059,48060,48061,48062,48063,48064,48065,48066,48067,48068,48069,48070,48071,48072,48073,48074,48075,48076,48077,48078,48079,48080,48081,48082,48083,48084,48085,48086,48087,48088,48089,48090,48091,48092,48093,48094,48095,48096,48097,48098,48099,48100,48101,48102,48103,48104,48105,48106,48107,48108,48109,48110,48111,48112,48113,48114,48115,48116,48117,48118,48119,48120,48121,48122,48123,48124,48125,48126,48127,48128,48129,48130,48131,48132,48133,48134,48135,48136,48137,48138,48139,48140,48141,48142,48143,48144,48145,48146,48147,48148,48149,48150,48151,48152,48153,48154,48155,48156,48157,48158,48159,48160,48161,48162,48163,48164,48165,48166,48167,48168,48169,48170,48171,48172,48173,48174,48175,48176,48177,48178,48179,48180,48181,48182,48183,48184,48185,48186,48187,48188,48189,48190,48191,48192,48193,48194,48195,48196,48197,48198,48199,48200,48201,48202,48203,48204,48205,48206,48207,48208,48209,48210,48211,48212,48213,48214,48215,48216,48217,48218,48219,48220,48221,48222,48223,48224,48225,48226,48227,48228,48229,48230,48231,48232,48233,48234,48235,48236,48237,48238,48239,48240,48241,48242,48243,48244,48245,48246,48247,48248,48249,48250,48251,48252,48253,48254,48255,48256,48257,48258,48259,48260,48261,48262,48263,48264,48265,48266,48267,48268,48269,48270,48271,48272,48273,48274,48275,48276,48277,48278,48279,48280,48281,48282,48283,48284,48285,48286,48287,48288,48289,48290,48291,48292,48293,48294,48295,48296,48297,48298,48299,48300,48301,48302,48303,48304,48305,48306,48307,48308,48309,48310,48311,48312,48313,48314,48315,48316,48317,48318,48319,48320,48321,48322,48323,48324,48325,48326,48327,48328,48329,48330,48331,48332,48333,48334,48335,48336,48337,48338,48339,48340,48341,48342,48343,48344,48345,48346,48347,48348,48349,48350,48351,48352,48353,48354,48355,48356,48357,48358,48359,48360,48361,48362,48363,48364,48365,48366,48367,48368,48369,48370,48371,48372,48373,48374,48375,48376,48377,48378,48379,48380,48381,48382,48383,48384,48385,48386,48387,48388,48389,48390,48391,48392,48393,48394,48395,48396,48397,48398,48399,48400,48401,48402,48403,48404,48405,48406,48407,48408,48409,48410,48411,48412,48413,48414,48415,48416,48417,48418,48419,48420,48421,48422,48423,48424,48425,48426,48427,48428,48429,48430,48431,48432,48433,48434,48435,48436,48437,48438,48439,48440,48441,48442,48443,48444,48445,48446,48447,48448,48449,48450,48451,48452,48453,48454,48455,48456,48457,48458,48459,48460,48461,48462,48463,48464,48465,48466,48467,48468,48469,48470,48471,48472,48473,48474,48475,48476,48477,48478,48479,48480,48481,48482,48483,48484,48485,48486,48487,48488,48489,48490,48491,48492,48493,48494,48495,48496,48497,48498,48499,48500,48501,48502,48503,48504,48505,48506,48507,48508,48509,48510,48511,48512,48513,48514,48515,48516,48517,48518,48519,48520,48521,48522,48523,48524,48525,48526,48527,48528,48529,48530,48531,48532,48533,48534,48535,48536,48537,48538,48539,48540,48541,48542,48543,48544,48545,48546,48547,48548,48549,48550,48551,48552,48553,48554,48555,48556,48557,48558,48559,48560,48561,48562,48563,48564,48565,48566,48567,48568,48569,48570,48571,48572,48573,48574,48575,48576,48577,48578,48579,48580,48581,48582,48583,48584,48585,48586,48587,48588,48589,48590,48591,48592,48593,48594,48595,48596,48597,48598,48599,48600,48601,48602,48603,48604,48605,48606,48607,48608,48609,48610,48611,48612,48613,48614,48615,48616,48617,48618,48619,48620,48621,48622,48623,48624,48625,48626,48627,48628,48629,48630,48631,48632,48633,48634,48635,48636,48637,48638,48639,48640,48641,48642,48643,48644,48645,48646,48647,48648,48649,48650,48651,48652,48653,48654,48655,48656,48657,48658,48659,48660,48661,48662,48663,48664,48665,48666,48667,48668,48669,48670,48671,48672,48673,48674,48675,48676,48677,48678,48679,48680,48681,48682,48683,48684,48685,48686,48687,48688,48689,48690,48691,48692,48693,48694,48695,48696,48697,48698,48699,48700,48701,48702,48703,48704,48705,48706,48707,48708,48709,48710,48711,48712,48713,48714,48715,48716,48717,48718,48719,48720,48721,48722,48723,48724,48725,48726,48727,48728,48729,48730,48731,48732,48733,48734,48735,48736,48737,48738,48739,48740,48741,48742,48743,48744,48745,48746,48747,48748,48749,48750,48751,48752,48753,48754,48755,48756,48757,48758,48759,48760,48761,48762,48763,48764,48765,48766,48767,48768,48769,48770,48771,48772,48773,48774,48775,48776,48777,48778,48779,48780,48781,48782,48783,48784,48785,48786,48787,48788,48789,48790,48791,48792,48793,48794,48795,48796,48797,48798,48799,48800,48801,48802,48803,48804,48805,48806,48807,48808,48809,48810,48811,48812,48813,48814,48815,48816,48817,48818,48819,48820,48821,48822,48823,48824,48825,48826,48827,48828,48829,48830,48831,48832,48833,48834,48835,48836,48837,48838,48839,48840,48841,48842,48843,48844,48845,48846,48847,48848,48849,48850,48851,48852,48853,48854,48855,48856,48857,48858,48859,48860,48861,48862,48863,48864,48865,48866,48867,48868,48869,48870,48871,48872,48873,48874,48875,48876,48877,48878,48879,48880,48881,48882,48883,48884,48885,48886,48887,48888,48889,48890,48891,48892,48893,48894,48895,48896,48897,48898,48899,48900,48901,48902,48903,48904,48905,48906,48907,48908,48909,48910,48911,48912,48913,48914,48915,48916,48917,48918,48919,48920,48921,48922,48923,48924,48925,48926,48927,48928,48929,48930,48931,48932,48933,48934,48935,48936,48937,48938,48939,48940,48941,48942,48943,48944,48945,48946,48947,48948,48949,48950,48951,48952,48953,48954,48955,48956,48957,48958,48959,48960,48961,48962,48963,48964,48965,48966,48967,48968,48969,48970,48971,48972,48973,48974,48975,48976,48977,48978,48979,48980,48981,48982,48983,48984,48985,48986,48987,48988,48989,48990,48991,48992,48993,48994,48995,48996,48997,48998,48999,49000,49001,49002,49003,49004,49005,49006,49007,49008,49009,49010,49011,49012,49013,49014,49015,49016,49017,49018,49019,49020,49021,49022,49023,49024,49025,49026,49027,49028,49029,49030,49031,49032,49033,49034,49035,49036,49037,49038,49039,49040,49041,49042,49043,49044,49045,49046,49047,49048,49049,49050,49051,49052,49053,49054,49055,49056,49057,49058,49059,49060,49061,49062,49063,49064,49065,49066,49067,49068,49069,49070,49071,49072,49073,49074,49075,49076,49077,49078,49079,49080,49081,49082,49083,49084,49085,49086,49087,49088,49089,49090,49091,49092,49093,49094,49095,49096,49097,49098,49099,49100,49101,49102,49103,49104,49105,49106,49107,49108,49109,49110,49111,49112,49113,49114,49115,49116,49117,49118,49119,49120,49121,49122,49123,49124,49125,49126,49127,49128,49129,49130,49131,49132,49133,49134,49135,49136,49137,49138,49139,49140,49141,49142,49143,49144,49145,49146,49147,49148,49149,49150,49151,49152,49153,49154,49155,49156,49157,49158,49159,49160,49161,49162,49163,49164,49165,49166,49167,49168,49169,49170,49171,49172,49173,49174,49175,49176,49177,49178,49179,49180,49181,49182,49183,49184,49185,49186,49187,49188,49189,49190,49191,49192,49193,49194,49195,49196,49197,49198,49199,49200,49201,49202,49203,49204,49205,49206,49207,49208,49209,49210,49211,49212,49213,49214,49215,49216,49217,49218,49219,49220,49221,49222,49223,49224,49225,49226,49227,49228,49229,49230,49231,49232,49233,49234,49235,49236,49237,49238,49239,49240,49241,49242,49243,49244,49245,49246,49247,49248,49249,49250,49251,49252,49253,49254,49255,49256,49257,49258,49259,49260,49261,49262,49263,49264,49265,49266,49267,49268,49269,49270,49271,49272,49273,49274,49275,49276,49277,49278,49279,49280,49281,49282,49283,49284,49285,49286,49287,49288,49289,49290,49291,49292,49293,49294,49295,49296,49297,49298,49299,49300,49301,49302,49303,49304,49305,49306,49307,49308,49309,49310,49311,49312,49313,49314,49315,49316,49317,49318,49319,49320,49321,49322,49323,49324,49325,49326,49327,49328,49329,49330,49331,49332,49333,49334,49335,49336,49337,49338,49339,49340,49341,49342,49343,49344,49345,49346,49347,49348,49349,49350,49351,49352,49353,49354,49355,49356,49357,49358,49359,49360,49361,49362,49363,49364,49365,49366,49367,49368,49369,49370,49371,49372,49373,49374,49375,49376,49377,49378,49379,49380,49381,49382,49383,49384,49385,49386,49387,49388,49389,49390,49391,49392,49393,49394,49395,49396,49397,49398,49399,49400,49401,49402,49403,49404,49405,49406,49407,49408,49409,49410,49411,49412,49413,49414,49415,49416,49417,49418,49419,49420,49421,49422,49423,49424,49425,49426,49427,49428,49429,49430,49431,49432,49433,49434,49435,49436,49437,49438,49439,49440,49441,49442,49443,49444,49445,49446,49447,49448,49449,49450,49451,49452,49453,49454,49455,49456,49457,49458,49459,49460,49461,49462,49463,49464,49465,49466,49467,49468,49469,49470,49471,49472,49473,49474,49475,49476,49477,49478,49479,49480,49481,49482,49483,49484,49485,49486,49487,49488,49489,49490,49491,49492,49493,49494,49495,49496,49497,49498,49499,49500,49501,49502,49503,49504,49505,49506,49507,49508,49509,49510,49511,49512,49513,49514,49515,49516,49517,49518,49519,49520,49521,49522,49523,49524,49525,49526,49527,49528,49529,49530,49531,49532,49533,49534,49535,49536,49537,49538,49539,49540,49541,49542,49543,49544,49545,49546,49547,49548,49549,49550,49551,49552,49553,49554,49555,49556,49557,49558,49559,49560,49561,49562,49563,49564,49565,49566,49567,49568,49569,49570,49571,49572,49573,49574,49575,49576,49577,49578,49579,49580,49581,49582,49583,49584,49585,49586,49587,49588,49589,49590,49591,49592,49593,49594,49595,49596,49597,49598,49599,49600,49601,49602,49603,49604,49605,49606,49607,49608,49609,49610,49611,49612,49613,49614,49615,49616,49617,49618,49619,49620,49621,49622,49623,49624,49625,49626,49627,49628,49629,49630,49631,49632,49633,49634,49635,49636,49637,49638,49639,49640,49641,49642,49643,49644,49645,49646,49647,49648,49649,49650,49651,49652,49653,49654,49655,49656,49657,49658,49659,49660,49661,49662,49663,49664,49665,49666,49667,49668,49669,49670,49671,49672,49673,49674,49675,49676,49677,49678,49679,49680,49681,49682,49683,49684,49685,49686,49687,49688,49689,49690,49691,49692,49693,49694,49695,49696,49697,49698,49699,49700,49701,49702,49703,49704,49705,49706,49707,49708,49709,49710,49711,49712,49713,49714,49715,49716,49717,49718,49719,49720,49721,49722,49723,49724,49725,49726,49727,49728,49729,49730,49731,49732,49733,49734,49735,49736,49737,49738,49739,49740,49741,49742,49743,49744,49745,49746,49747,49748,49749,49750,49751,49752,49753,49754,49755,49756,49757,49758,49759,49760,49761,49762,49763,49764,49765,49766,49767,49768,49769,49770,49771,49772,49773,49774,49775,49776,49777,49778,49779,49780,49781,49782,49783,49784,49785,49786,49787,49788,49789,49790,49791,49792,49793,49794,49795,49796,49797,49798,49799,49800,49801,49802,49803,49804,49805,49806,49807,49808,49809,49810,49811,49812,49813,49814,49815,49816,49817,49818,49819,49820,49821,49822,49823,49824,49825,49826,49827,49828,49829,49830,49831,49832,49833,49834,49835,49836,49837,49838,49839,49840,49841,49842,49843,49844,49845,49846,49847,49848,49849,49850,49851,49852,49853,49854,49855,49856,49857,49858,49859,49860,49861,49862,49863,49864,49865,49866,49867,49868,49869,49870,49871,49872,49873,49874,49875,49876,49877,49878,49879,49880,49881,49882,49883,49884,49885,49886,49887,49888,49889,49890,49891,49892,49893,49894,49895,49896,49897,49898,49899,49900,49901,49902,49903,49904,49905,49906,49907,49908,49909,49910,49911,49912,49913,49914,49915,49916,49917,49918,49919,49920,49921,49922,49923,49924,49925,49926,49927,49928,49929,49930,49931,49932,49933,49934,49935,49936,49937,49938,49939,49940,49941,49942,49943,49944,49945,49946,49947,49948,49949,49950,49951,49952,49953,49954,49955,49956,49957,49958,49959,49960,49961,49962,49963,49964,49965,49966,49967,49968,49969,49970,49971,49972,49973,49974,49975,49976,49977,49978,49979,49980,49981,49982,49983,49984,49985,49986,49987,49988,49989,49990,49991,49992,49993,49994,49995,49996,49997,49998,49999,50000,50001,50002,50003,50004,50005,50006,50007,50008,50009,50010,50011,50012,50013,50014,50015,50016,50017,50018,50019,50020,50021,50022,50023,50024,50025,50026,50027,50028,50029,50030,50031,50032,50033,50034,50035,50036,50037,50038,50039,50040,50041,50042,50043,50044,50045,50046,50047,50048,50049,50050,50051,50052,50053,50054,50055,50056,50057,50058,50059,50060,50061,50062,50063,50064,50065,50066,50067,50068,50069,50070,50071,50072,50073,50074,50075,50076,50077,50078,50079,50080,50081,50082,50083,50084,50085,50086,50087,50088,50089,50090,50091,50092,50093,50094,50095,50096,50097,50098,50099,50100,50101,50102,50103,50104,50105,50106,50107,50108,50109,50110,50111,50112,50113,50114,50115,50116,50117,50118,50119,50120,50121,50122,50123,50124,50125,50126,50127,50128,50129,50130,50131,50132,50133,50134,50135,50136,50137,50138,50139,50140,50141,50142,50143,50144,50145,50146,50147,50148,50149,50150,50151,50152,50153,50154,50155,50156,50157,50158,50159,50160,50161,50162,50163,50164,50165,50166,50167,50168,50169,50170,50171,50172,50173,50174,50175,50176,50177,50178,50179,50180,50181,50182,50183,50184,50185,50186,50187,50188,50189,50190,50191,50192,50193,50194,50195,50196,50197,50198,50199,50200,50201,50202,50203,50204,50205,50206,50207,50208,50209,50210,50211,50212,50213,50214,50215,50216,50217,50218,50219,50220,50221,50222,50223,50224,50225,50226,50227,50228,50229,50230,50231,50232,50233,50234,50235,50236,50237,50238,50239,50240,50241,50242,50243,50244,50245,50246,50247,50248,50249,50250,50251,50252,50253,50254,50255,50256,50257,50258,50259,50260,50261,50262,50263,50264,50265,50266,50267,50268,50269,50270,50271,50272,50273,50274,50275,50276,50277,50278,50279,50280,50281,50282,50283,50284,50285,50286,50287,50288,50289,50290,50291,50292,50293,50294,50295,50296,50297,50298,50299,50300,50301,50302,50303,50304,50305,50306,50307,50308,50309,50310,50311,50312,50313,50314,50315,50316,50317,50318,50319,50320,50321,50322,50323,50324,50325,50326,50327,50328,50329,50330,50331,50332,50333,50334,50335,50336,50337,50338,50339,50340,50341,50342,50343,50344,50345,50346,50347,50348,50349,50350,50351,50352,50353,50354,50355,50356,50357,50358,50359,50360,50361,50362,50363,50364,50365,50366,50367,50368,50369,50370,50371,50372,50373,50374,50375,50376,50377,50378,50379,50380,50381,50382,50383,50384,50385,50386,50387,50388,50389,50390,50391,50392,50393,50394,50395,50396,50397,50398,50399,50400,50401,50402,50403,50404,50405,50406,50407,50408,50409,50410,50411,50412,50413,50414,50415,50416,50417,50418,50419,50420,50421,50422,50423,50424,50425,50426,50427,50428,50429,50430,50431,50432,50433,50434,50435,50436,50437,50438,50439,50440,50441,50442,50443,50444,50445,50446,50447,50448,50449,50450,50451,50452,50453,50454,50455,50456,50457,50458,50459,50460,50461,50462,50463,50464,50465,50466,50467,50468,50469,50470,50471,50472,50473,50474,50475,50476,50477,50478,50479,50480,50481,50482,50483,50484,50485,50486,50487,50488,50489,50490,50491,50492,50493,50494,50495,50496,50497,50498,50499,50500,50501,50502,50503,50504,50505,50506,50507,50508,50509,50510,50511,50512,50513,50514,50515,50516,50517,50518,50519,50520,50521,50522,50523,50524,50525,50526,50527,50528,50529,50530,50531,50532,50533,50534,50535,50536,50537,50538,50539,50540,50541,50542,50543,50544,50545,50546,50547,50548,50549,50550,50551,50552,50553,50554,50555,50556,50557,50558,50559,50560,50561,50562,50563,50564,50565,50566,50567,50568,50569,50570,50571,50572,50573,50574,50575,50576,50577,50578,50579,50580,50581,50582,50583,50584,50585,50586,50587,50588,50589,50590,50591,50592,50593,50594,50595,50596,50597,50598,50599,50600,50601,50602,50603,50604,50605,50606,50607,50608,50609,50610,50611,50612,50613,50614,50615,50616,50617,50618,50619,50620,50621,50622,50623,50624,50625,50626,50627,50628,50629,50630,50631,50632,50633,50634,50635,50636,50637,50638,50639,50640,50641,50642,50643,50644,50645,50646,50647,50648,50649,50650,50651,50652,50653,50654,50655,50656,50657,50658,50659,50660,50661,50662,50663,50664,50665,50666,50667,50668,50669,50670,50671,50672,50673,50674,50675,50676,50677,50678,50679,50680,50681,50682,50683,50684,50685,50686,50687,50688,50689,50690,50691,50692,50693,50694,50695,50696,50697,50698,50699,50700,50701,50702,50703,50704,50705,50706,50707,50708,50709,50710,50711,50712,50713,50714,50715,50716,50717,50718,50719,50720,50721,50722,50723,50724,50725,50726,50727,50728,50729,50730,50731,50732,50733,50734,50735,50736,50737,50738,50739,50740,50741,50742,50743,50744,50745,50746,50747,50748,50749,50750,50751,50752,50753,50754,50755,50756,50757,50758,50759,50760,50761,50762,50763,50764,50765,50766,50767,50768,50769,50770,50771,50772,50773,50774,50775,50776,50777,50778,50779,50780,50781,50782,50783,50784,50785,50786,50787,50788,50789,50790,50791,50792,50793,50794,50795,50796,50797,50798,50799,50800,50801,50802,50803,50804,50805,50806,50807,50808,50809,50810,50811,50812,50813,50814,50815,50816,50817,50818,50819,50820,50821,50822,50823,50824,50825,50826,50827,50828,50829,50830,50831,50832,50833,50834,50835,50836,50837,50838,50839,50840,50841,50842,50843,50844,50845,50846,50847,50848,50849,50850,50851,50852,50853,50854,50855,50856,50857,50858,50859,50860,50861,50862,50863,50864,50865,50866,50867,50868,50869,50870,50871,50872,50873,50874,50875,50876,50877,50878,50879,50880,50881,50882,50883,50884,50885,50886,50887,50888,50889,50890,50891,50892,50893,50894,50895,50896,50897,50898,50899,50900,50901,50902,50903,50904,50905,50906,50907,50908,50909,50910,50911,50912,50913,50914,50915,50916,50917,50918,50919,50920,50921,50922,50923,50924,50925,50926,50927,50928,50929,50930,50931,50932,50933,50934,50935,50936,50937,50938,50939,50940,50941,50942,50943,50944,50945,50946,50947,50948,50949,50950,50951,50952,50953,50954,50955,50956,50957,50958,50959,50960,50961,50962,50963,50964,50965,50966,50967,50968,50969,50970,50971,50972,50973,50974,50975,50976,50977,50978,50979,50980,50981,50982,50983,50984,50985,50986,50987,50988,50989,50990,50991,50992,50993,50994,50995,50996,50997,50998,50999,51000,51001,51002,51003,51004,51005,51006,51007,51008,51009,51010,51011,51012,51013,51014,51015,51016,51017,51018,51019,51020,51021,51022,51023,51024,51025,51026,51027,51028,51029,51030,51031,51032,51033,51034,51035,51036,51037,51038,51039,51040,51041,51042,51043,51044,51045,51046,51047,51048,51049,51050,51051,51052,51053,51054,51055,51056,51057,51058,51059,51060,51061,51062,51063,51064,51065,51066,51067,51068,51069,51070,51071,51072,51073,51074,51075,51076,51077,51078,51079,51080,51081,51082,51083,51084,51085,51086,51087,51088,51089,51090,51091,51092,51093,51094,51095,51096,51097,51098,51099,51100,51101,51102,51103,51104,51105,51106,51107,51108,51109,51110,51111,51112,51113,51114,51115,51116,51117,51118,51119,51120,51121,51122,51123,51124,51125,51126,51127,51128,51129,51130,51131,51132,51133,51134,51135,51136,51137,51138,51139,51140,51141,51142,51143,51144,51145,51146,51147,51148,51149,51150,51151,51152,51153,51154,51155,51156,51157,51158,51159,51160,51161,51162,51163,51164,51165,51166,51167,51168,51169,51170,51171,51172,51173,51174,51175,51176,51177,51178,51179,51180,51181,51182,51183,51184,51185,51186,51187,51188,51189,51190,51191,51192,51193,51194,51195,51196,51197,51198,51199,51200,51201,51202,51203,51204,51205,51206,51207,51208,51209,51210,51211,51212,51213,51214,51215,51216,51217,51218,51219,51220,51221,51222,51223,51224,51225,51226,51227,51228,51229,51230,51231,51232,51233,51234,51235,51236,51237,51238,51239,51240,51241,51242,51243,51244,51245,51246,51247,51248,51249,51250,51251,51252,51253,51254,51255,51256,51257,51258,51259,51260,51261,51262,51263,51264,51265,51266,51267,51268,51269,51270,51271,51272,51273,51274,51275,51276,51277,51278,51279,51280,51281,51282,51283,51284,51285,51286,51287,51288,51289,51290,51291,51292,51293,51294,51295,51296,51297,51298,51299,51300,51301,51302,51303,51304,51305,51306,51307,51308,51309,51310,51311,51312,51313,51314,51315,51316,51317,51318,51319,51320,51321,51322,51323,51324,51325,51326,51327,51328,51329,51330,51331,51332,51333,51334,51335,51336,51337,51338,51339,51340,51341,51342,51343,51344,51345,51346,51347,51348,51349,51350,51351,51352,51353,51354,51355,51356,51357,51358,51359,51360,51361,51362,51363,51364,51365,51366,51367,51368,51369,51370,51371,51372,51373,51374,51375,51376,51377,51378,51379,51380,51381,51382,51383,51384,51385,51386,51387,51388,51389,51390,51391,51392,51393,51394,51395,51396,51397,51398,51399,51400,51401,51402,51403,51404,51405,51406,51407,51408,51409,51410,51411,51412,51413,51414,51415,51416,51417,51418,51419,51420,51421,51422,51423,51424,51425,51426,51427,51428,51429,51430,51431,51432,51433,51434,51435,51436,51437,51438,51439,51440,51441,51442,51443,51444,51445,51446,51447,51448,51449,51450,51451,51452,51453,51454,51455,51456,51457,51458,51459,51460,51461,51462,51463,51464,51465,51466,51467,51468,51469,51470,51471,51472,51473,51474,51475,51476,51477,51478,51479,51480,51481,51482,51483,51484,51485,51486,51487,51488,51489,51490,51491,51492,51493,51494,51495,51496,51497,51498,51499,51500,51501,51502,51503,51504,51505,51506,51507,51508,51509,51510,51511,51512,51513,51514,51515,51516,51517,51518,51519,51520,51521,51522,51523,51524,51525,51526,51527,51528,51529,51530,51531,51532,51533,51534,51535,51536,51537,51538,51539,51540,51541,51542,51543,51544,51545,51546,51547,51548,51549,51550,51551,51552,51553,51554,51555,51556,51557,51558,51559,51560,51561,51562,51563,51564,51565,51566,51567,51568,51569,51570,51571,51572,51573,51574,51575,51576,51577,51578,51579,51580,51581,51582,51583,51584,51585,51586,51587,51588,51589,51590,51591,51592,51593,51594,51595,51596,51597,51598,51599,51600,51601,51602,51603,51604,51605,51606,51607,51608,51609,51610,51611,51612,51613,51614,51615,51616,51617,51618,51619,51620,51621,51622,51623,51624,51625,51626,51627,51628,51629,51630,51631,51632,51633,51634,51635,51636,51637,51638,51639,51640,51641,51642,51643,51644,51645,51646,51647,51648,51649,51650,51651,51652,51653,51654,51655,51656,51657,51658,51659,51660,51661,51662,51663,51664,51665,51666,51667,51668,51669,51670,51671,51672,51673,51674,51675,51676,51677,51678,51679,51680,51681,51682,51683,51684,51685,51686,51687,51688,51689,51690,51691,51692,51693,51694,51695,51696,51697,51698,51699,51700,51701,51702,51703,51704,51705,51706,51707,51708,51709,51710,51711,51712,51713,51714,51715,51716,51717,51718,51719,51720,51721,51722,51723,51724,51725,51726,51727,51728,51729,51730,51731,51732,51733,51734,51735,51736,51737,51738,51739,51740,51741,51742,51743,51744,51745,51746,51747,51748,51749,51750,51751,51752,51753,51754,51755,51756,51757,51758,51759,51760,51761,51762,51763,51764,51765,51766,51767,51768,51769,51770,51771,51772,51773,51774,51775,51776,51777,51778,51779,51780,51781,51782,51783,51784,51785,51786,51787,51788,51789,51790,51791,51792,51793,51794,51795,51796,51797,51798,51799,51800,51801,51802,51803,51804,51805,51806,51807,51808,51809,51810,51811,51812,51813,51814,51815,51816,51817,51818,51819,51820,51821,51822,51823,51824,51825,51826,51827,51828,51829,51830,51831,51832,51833,51834,51835,51836,51837,51838,51839,51840,51841,51842,51843,51844,51845,51846,51847,51848,51849,51850,51851,51852,51853,51854,51855,51856,51857,51858,51859,51860,51861,51862,51863,51864,51865,51866,51867,51868,51869,51870,51871,51872,51873,51874,51875,51876,51877,51878,51879,51880,51881,51882,51883,51884,51885,51886,51887,51888,51889,51890,51891,51892,51893,51894,51895,51896,51897,51898,51899,51900,51901,51902,51903,51904,51905,51906,51907,51908,51909,51910,51911,51912,51913,51914,51915,51916,51917,51918,51919,51920,51921,51922,51923,51924,51925,51926,51927,51928,51929,51930,51931,51932,51933,51934,51935,51936,51937,51938,51939,51940,51941,51942,51943,51944,51945,51946,51947,51948,51949,51950,51951,51952,51953,51954,51955,51956,51957,51958,51959,51960,51961,51962,51963,51964,51965,51966,51967,51968,51969,51970,51971,51972,51973,51974,51975,51976,51977,51978,51979,51980,51981,51982,51983,51984,51985,51986,51987,51988,51989,51990,51991,51992,51993,51994,51995,51996,51997,51998,51999,52000,52001,52002,52003,52004,52005,52006,52007,52008,52009,52010,52011,52012,52013,52014,52015,52016,52017,52018,52019,52020,52021,52022,52023,52024,52025,52026,52027,52028,52029,52030,52031,52032,52033,52034,52035,52036,52037,52038,52039,52040,52041,52042,52043,52044,52045,52046,52047,52048,52049,52050,52051,52052,52053,52054,52055,52056,52057,52058,52059,52060,52061,52062,52063,52064,52065,52066,52067,52068,52069,52070,52071,52072,52073,52074,52075,52076,52077,52078,52079,52080,52081,52082,52083,52084,52085,52086,52087,52088,52089,52090,52091,52092,52093,52094,52095,52096,52097,52098,52099,52100,52101,52102,52103,52104,52105,52106,52107,52108,52109,52110,52111,52112,52113,52114,52115,52116,52117,52118,52119,52120,52121,52122,52123,52124,52125,52126,52127,52128,52129,52130,52131,52132,52133,52134,52135,52136,52137,52138,52139,52140,52141,52142,52143,52144,52145,52146,52147,52148,52149,52150,52151,52152,52153,52154,52155,52156,52157,52158,52159,52160,52161,52162,52163,52164,52165,52166,52167,52168,52169,52170,52171,52172,52173,52174,52175,52176,52177,52178,52179,52180,52181,52182,52183,52184,52185,52186,52187,52188,52189,52190,52191,52192,52193,52194,52195,52196,52197,52198,52199,52200,52201,52202,52203,52204,52205,52206,52207,52208,52209,52210,52211,52212,52213,52214,52215,52216,52217,52218,52219,52220,52221,52222,52223,52224,52225,52226,52227,52228,52229,52230,52231,52232,52233,52234,52235,52236,52237,52238,52239,52240,52241,52242,52243,52244,52245,52246,52247,52248,52249,52250,52251,52252,52253,52254,52255,52256,52257,52258,52259,52260,52261,52262,52263,52264,52265,52266,52267,52268,52269,52270,52271,52272,52273,52274,52275,52276,52277,52278,52279,52280,52281,52282,52283,52284,52285,52286,52287,52288,52289,52290,52291,52292,52293,52294,52295,52296,52297,52298,52299,52300,52301,52302,52303,52304,52305,52306,52307,52308,52309,52310,52311,52312,52313,52314,52315,52316,52317,52318,52319,52320,52321,52322,52323,52324,52325,52326,52327,52328,52329,52330,52331,52332,52333,52334,52335,52336,52337,52338,52339,52340,52341,52342,52343,52344,52345,52346,52347,52348,52349,52350,52351,52352,52353,52354,52355,52356,52357,52358,52359,52360,52361,52362,52363,52364,52365,52366,52367,52368,52369,52370,52371,52372,52373,52374,52375,52376,52377,52378,52379,52380,52381,52382,52383,52384,52385,52386,52387,52388,52389,52390,52391,52392,52393,52394,52395,52396,52397,52398,52399,52400,52401,52402,52403,52404,52405,52406,52407,52408,52409,52410,52411,52412,52413,52414,52415,52416,52417,52418,52419,52420,52421,52422,52423,52424,52425,52426,52427,52428,52429,52430,52431,52432,52433,52434,52435,52436,52437,52438,52439,52440,52441,52442,52443,52444,52445,52446,52447,52448,52449,52450,52451,52452,52453,52454,52455,52456,52457,52458,52459,52460,52461,52462,52463,52464,52465,52466,52467,52468,52469,52470,52471,52472,52473,52474,52475,52476,52477,52478,52479,52480,52481,52482,52483,52484,52485,52486,52487,52488,52489,52490,52491,52492,52493,52494,52495,52496,52497,52498,52499,52500,52501,52502,52503,52504,52505,52506,52507,52508,52509,52510,52511,52512,52513,52514,52515,52516,52517,52518,52519,52520,52521,52522,52523,52524,52525,52526,52527,52528,52529,52530,52531,52532,52533,52534,52535,52536,52537,52538,52539,52540,52541,52542,52543,52544,52545,52546,52547,52548,52549,52550,52551,52552,52553,52554,52555,52556,52557,52558,52559,52560,52561,52562,52563,52564,52565,52566,52567,52568,52569,52570,52571,52572,52573,52574,52575,52576,52577,52578,52579,52580,52581,52582,52583,52584,52585,52586,52587,52588,52589,52590,52591,52592,52593,52594,52595,52596,52597,52598,52599,52600,52601,52602,52603,52604,52605,52606,52607,52608,52609,52610,52611,52612,52613,52614,52615,52616,52617,52618,52619,52620,52621,52622,52623,52624,52625,52626,52627,52628,52629,52630,52631,52632,52633,52634,52635,52636,52637,52638,52639,52640,52641,52642,52643,52644,52645,52646,52647,52648,52649,52650,52651,52652,52653,52654,52655,52656,52657,52658,52659,52660,52661,52662,52663,52664,52665,52666,52667,52668,52669,52670,52671,52672,52673,52674,52675,52676,52677,52678,52679,52680,52681,52682,52683,52684,52685,52686,52687,52688,52689,52690,52691,52692,52693,52694,52695,52696,52697,52698,52699,52700,52701,52702,52703,52704,52705,52706,52707,52708,52709,52710,52711,52712,52713,52714,52715,52716,52717,52718,52719,52720,52721,52722,52723,52724,52725,52726,52727,52728,52729,52730,52731,52732,52733,52734,52735,52736,52737,52738,52739,52740,52741,52742,52743,52744,52745,52746,52747,52748,52749,52750,52751,52752,52753,52754,52755,52756,52757,52758,52759,52760,52761,52762,52763,52764,52765,52766,52767,52768,52769,52770,52771,52772,52773,52774,52775,52776,52777,52778,52779,52780,52781,52782,52783,52784,52785,52786,52787,52788,52789,52790,52791,52792,52793,52794,52795,52796,52797,52798,52799,52800,52801,52802,52803,52804,52805,52806,52807,52808,52809,52810,52811,52812,52813,52814,52815,52816,52817,52818,52819,52820,52821,52822,52823,52824,52825,52826,52827,52828,52829,52830,52831,52832,52833,52834,52835,52836,52837,52838,52839,52840,52841,52842,52843,52844,52845,52846,52847,52848,52849,52850,52851,52852,52853,52854,52855,52856,52857,52858,52859,52860,52861,52862,52863,52864,52865,52866,52867,52868,52869,52870,52871,52872,52873,52874,52875,52876,52877,52878,52879,52880,52881,52882,52883,52884,52885,52886,52887,52888,52889,52890,52891,52892,52893,52894,52895,52896,52897,52898,52899,52900,52901,52902,52903,52904,52905,52906,52907,52908,52909,52910,52911,52912,52913,52914,52915,52916,52917,52918,52919,52920,52921,52922,52923,52924,52925,52926,52927,52928,52929,52930,52931,52932,52933,52934,52935,52936,52937,52938,52939,52940,52941,52942,52943,52944,52945,52946,52947,52948,52949,52950,52951,52952,52953,52954,52955,52956,52957,52958,52959,52960,52961,52962,52963,52964,52965,52966,52967,52968,52969,52970,52971,52972,52973,52974,52975,52976,52977,52978,52979,52980,52981,52982,52983,52984,52985,52986,52987,52988,52989,52990,52991,52992,52993,52994,52995,52996,52997,52998,52999,53000,53001,53002,53003,53004,53005,53006,53007,53008,53009,53010,53011,53012,53013,53014,53015,53016,53017,53018,53019,53020,53021,53022,53023,53024,53025,53026,53027,53028,53029,53030,53031,53032,53033,53034,53035,53036,53037,53038,53039,53040,53041,53042,53043,53044,53045,53046,53047,53048,53049,53050,53051,53052,53053,53054,53055,53056,53057,53058,53059,53060,53061,53062,53063,53064,53065,53066,53067,53068,53069,53070,53071,53072,53073,53074,53075,53076,53077,53078,53079,53080,53081,53082,53083,53084,53085,53086,53087,53088,53089,53090,53091,53092,53093,53094,53095,53096,53097,53098,53099,53100,53101,53102,53103,53104,53105,53106,53107,53108,53109,53110,53111,53112,53113,53114,53115,53116,53117,53118,53119,53120,53121,53122,53123,53124,53125,53126,53127,53128,53129,53130,53131,53132,53133,53134,53135,53136,53137,53138,53139,53140,53141,53142,53143,53144,53145,53146,53147,53148,53149,53150,53151,53152,53153,53154,53155,53156,53157,53158,53159,53160,53161,53162,53163,53164,53165,53166,53167,53168,53169,53170,53171,53172,53173,53174,53175,53176,53177,53178,53179,53180,53181,53182,53183,53184,53185,53186,53187,53188,53189,53190,53191,53192,53193,53194,53195,53196,53197,53198,53199,53200,53201,53202,53203,53204,53205,53206,53207,53208,53209,53210,53211,53212,53213,53214,53215,53216,53217,53218,53219,53220,53221,53222,53223,53224,53225,53226,53227,53228,53229,53230,53231,53232,53233,53234,53235,53236,53237,53238,53239,53240,53241,53242,53243,53244,53245,53246,53247,53248,53249,53250,53251,53252,53253,53254,53255,53256,53257,53258,53259,53260,53261,53262,53263,53264,53265,53266,53267,53268,53269,53270,53271,53272,53273,53274,53275,53276,53277,53278,53279,53280,53281,53282,53283,53284,53285,53286,53287,53288,53289,53290,53291,53292,53293,53294,53295,53296,53297,53298,53299,53300,53301,53302,53303,53304,53305,53306,53307,53308,53309,53310,53311,53312,53313,53314,53315,53316,53317,53318,53319,53320,53321,53322,53323,53324,53325,53326,53327,53328,53329,53330,53331,53332,53333,53334,53335,53336,53337,53338,53339,53340,53341,53342,53343,53344,53345,53346,53347,53348,53349,53350,53351,53352,53353,53354,53355,53356,53357,53358,53359,53360,53361,53362,53363,53364,53365,53366,53367,53368,53369,53370,53371,53372,53373,53374,53375,53376,53377,53378,53379,53380,53381,53382,53383,53384,53385,53386,53387,53388,53389,53390,53391,53392,53393,53394,53395,53396,53397,53398,53399,53400,53401,53402,53403,53404,53405,53406,53407,53408,53409,53410,53411,53412,53413,53414,53415,53416,53417,53418,53419,53420,53421,53422,53423,53424,53425,53426,53427,53428,53429,53430,53431,53432,53433,53434,53435,53436,53437,53438,53439,53440,53441,53442,53443,53444,53445,53446,53447,53448,53449,53450,53451,53452,53453,53454,53455,53456,53457,53458,53459,53460,53461,53462,53463,53464,53465,53466,53467,53468,53469,53470,53471,53472,53473,53474,53475,53476,53477,53478,53479,53480,53481,53482,53483,53484,53485,53486,53487,53488,53489,53490,53491,53492,53493,53494,53495,53496,53497,53498,53499,53500,53501,53502,53503,53504,53505,53506,53507,53508,53509,53510,53511,53512,53513,53514,53515,53516,53517,53518,53519,53520,53521,53522,53523,53524,53525,53526,53527,53528,53529,53530,53531,53532,53533,53534,53535,53536,53537,53538,53539,53540,53541,53542,53543,53544,53545,53546,53547,53548,53549,53550,53551,53552,53553,53554,53555,53556,53557,53558,53559,53560,53561,53562,53563,53564,53565,53566,53567,53568,53569,53570,53571,53572,53573,53574,53575,53576,53577,53578,53579,53580,53581,53582,53583,53584,53585,53586,53587,53588,53589,53590,53591,53592,53593,53594,53595,53596,53597,53598,53599,53600,53601,53602,53603,53604,53605,53606,53607,53608,53609,53610,53611,53612,53613,53614,53615,53616,53617,53618,53619,53620,53621,53622,53623,53624,53625,53626,53627,53628,53629,53630,53631,53632,53633,53634,53635,53636,53637,53638,53639,53640,53641,53642,53643,53644,53645,53646,53647,53648,53649,53650,53651,53652,53653,53654,53655,53656,53657,53658,53659,53660,53661,53662,53663,53664,53665,53666,53667,53668,53669,53670,53671,53672,53673,53674,53675,53676,53677,53678,53679,53680,53681,53682,53683,53684,53685,53686,53687,53688,53689,53690,53691,53692,53693,53694,53695,53696,53697,53698,53699,53700,53701,53702,53703,53704,53705,53706,53707,53708,53709,53710,53711,53712,53713,53714,53715,53716,53717,53718,53719,53720,53721,53722,53723,53724,53725,53726,53727,53728,53729,53730,53731,53732,53733,53734,53735,53736,53737,53738,53739,53740,53741,53742,53743,53744,53745,53746,53747,53748,53749,53750,53751,53752,53753,53754,53755,53756,53757,53758,53759,53760,53761,53762,53763,53764,53765,53766,53767,53768,53769,53770,53771,53772,53773,53774,53775,53776,53777,53778,53779,53780,53781,53782,53783,53784,53785,53786,53787,53788,53789,53790,53791,53792,53793,53794,53795,53796,53797,53798,53799,53800,53801,53802,53803,53804,53805,53806,53807,53808,53809,53810,53811,53812,53813,53814,53815,53816,53817,53818,53819,53820,53821,53822,53823,53824,53825,53826,53827,53828,53829,53830,53831,53832,53833,53834,53835,53836,53837,53838,53839,53840,53841,53842,53843,53844,53845,53846,53847,53848,53849,53850,53851,53852,53853,53854,53855,53856,53857,53858,53859,53860,53861,53862,53863,53864,53865,53866,53867,53868,53869,53870,53871,53872,53873,53874,53875,53876,53877,53878,53879,53880,53881,53882,53883,53884,53885,53886,53887,53888,53889,53890,53891,53892,53893,53894,53895,53896,53897,53898,53899,53900,53901,53902,53903,53904,53905,53906,53907,53908,53909,53910,53911,53912,53913,53914,53915,53916,53917,53918,53919,53920,53921,53922,53923,53924,53925,53926,53927,53928,53929,53930,53931,53932,53933,53934,53935,53936,53937,53938,53939,53940,53941,53942,53943,53944,53945,53946,53947,53948,53949,53950,53951,53952,53953,53954,53955,53956,53957,53958,53959,53960,53961,53962,53963,53964,53965,53966,53967,53968,53969,53970,53971,53972,53973,53974,53975,53976,53977,53978,53979,53980,53981,53982,53983,53984,53985,53986,53987,53988,53989,53990,53991,53992,53993,53994,53995,53996,53997,53998,53999,54000,54001,54002,54003,54004,54005,54006,54007,54008,54009,54010,54011,54012,54013,54014,54015,54016,54017,54018,54019,54020,54021,54022,54023,54024,54025,54026,54027,54028,54029,54030,54031,54032,54033,54034,54035,54036,54037,54038,54039,54040,54041,54042,54043,54044,54045,54046,54047,54048,54049,54050,54051,54052,54053,54054,54055,54056,54057,54058,54059,54060,54061,54062,54063,54064,54065,54066,54067,54068,54069,54070,54071,54072,54073,54074,54075,54076,54077,54078,54079,54080,54081,54082,54083,54084,54085,54086,54087,54088,54089,54090,54091,54092,54093,54094,54095,54096,54097,54098,54099,54100,54101,54102,54103,54104,54105,54106,54107,54108,54109,54110,54111,54112,54113,54114,54115,54116,54117,54118,54119,54120,54121,54122,54123,54124,54125,54126,54127,54128,54129,54130,54131,54132,54133,54134,54135,54136,54137,54138,54139,54140,54141,54142,54143,54144,54145,54146,54147,54148,54149,54150,54151,54152,54153,54154,54155,54156,54157,54158,54159,54160,54161,54162,54163,54164,54165,54166,54167,54168,54169,54170,54171,54172,54173,54174,54175,54176,54177,54178,54179,54180,54181,54182,54183,54184,54185,54186,54187,54188,54189,54190,54191,54192,54193,54194,54195,54196,54197,54198,54199,54200,54201,54202,54203,54204,54205,54206,54207,54208,54209,54210,54211,54212,54213,54214,54215,54216,54217,54218,54219,54220,54221,54222,54223,54224,54225,54226,54227,54228,54229,54230,54231,54232,54233,54234,54235,54236,54237,54238,54239,54240,54241,54242,54243,54244,54245,54246,54247,54248,54249,54250,54251,54252,54253,54254,54255,54256,54257,54258,54259,54260,54261,54262,54263,54264,54265,54266,54267,54268,54269,54270,54271,54272,54273,54274,54275,54276,54277,54278,54279,54280,54281,54282,54283,54284,54285,54286,54287,54288,54289,54290,54291,54292,54293,54294,54295,54296,54297,54298,54299,54300,54301,54302,54303,54304,54305,54306,54307,54308,54309,54310,54311,54312,54313,54314,54315,54316,54317,54318,54319,54320,54321,54322,54323,54324,54325,54326,54327,54328,54329,54330,54331,54332,54333,54334,54335,54336,54337,54338,54339,54340,54341,54342,54343,54344,54345,54346,54347,54348,54349,54350,54351,54352,54353,54354,54355,54356,54357,54358,54359,54360,54361,54362,54363,54364,54365,54366,54367,54368,54369,54370,54371,54372,54373,54374,54375,54376,54377,54378,54379,54380,54381,54382,54383,54384,54385,54386,54387,54388,54389,54390,54391,54392,54393,54394,54395,54396,54397,54398,54399,54400,54401,54402,54403,54404,54405,54406,54407,54408,54409,54410,54411,54412,54413,54414,54415,54416,54417,54418,54419,54420,54421,54422,54423,54424,54425,54426,54427,54428,54429,54430,54431,54432,54433,54434,54435,54436,54437,54438,54439,54440,54441,54442,54443,54444,54445,54446,54447,54448,54449,54450,54451,54452,54453,54454,54455,54456,54457,54458,54459,54460,54461,54462,54463,54464,54465,54466,54467,54468,54469,54470,54471,54472,54473,54474,54475,54476,54477,54478,54479,54480,54481,54482,54483,54484,54485,54486,54487,54488,54489,54490,54491,54492,54493,54494,54495,54496,54497,54498,54499,54500,54501,54502,54503,54504,54505,54506,54507,54508,54509,54510,54511,54512,54513,54514,54515,54516,54517,54518,54519,54520,54521,54522,54523,54524,54525,54526,54527,54528,54529,54530,54531,54532,54533,54534,54535,54536,54537,54538,54539,54540,54541,54542,54543,54544,54545,54546,54547,54548,54549,54550,54551,54552,54553,54554,54555,54556,54557,54558,54559,54560,54561,54562,54563,54564,54565,54566,54567,54568,54569,54570,54571,54572,54573,54574,54575,54576,54577,54578,54579,54580,54581,54582,54583,54584,54585,54586,54587,54588,54589,54590,54591,54592,54593,54594,54595,54596,54597,54598,54599,54600,54601,54602,54603,54604,54605,54606,54607,54608,54609,54610,54611,54612,54613,54614,54615,54616,54617,54618,54619,54620,54621,54622,54623,54624,54625,54626,54627,54628,54629,54630,54631,54632,54633,54634,54635,54636,54637,54638,54639,54640,54641,54642,54643,54644,54645,54646,54647,54648,54649,54650,54651,54652,54653,54654,54655,54656,54657,54658,54659,54660,54661,54662,54663,54664,54665,54666,54667,54668,54669,54670,54671,54672,54673,54674,54675,54676,54677,54678,54679,54680,54681,54682,54683,54684,54685,54686,54687,54688,54689,54690,54691,54692,54693,54694,54695,54696,54697,54698,54699,54700,54701,54702,54703,54704,54705,54706,54707,54708,54709,54710,54711,54712,54713,54714,54715,54716,54717,54718,54719,54720,54721,54722,54723,54724,54725,54726,54727,54728,54729,54730,54731,54732,54733,54734,54735,54736,54737,54738,54739,54740,54741,54742,54743,54744,54745,54746,54747,54748,54749,54750,54751,54752,54753,54754,54755,54756,54757,54758,54759,54760,54761,54762,54763,54764,54765,54766,54767,54768,54769,54770,54771,54772,54773,54774,54775,54776,54777,54778,54779,54780,54781,54782,54783,54784,54785,54786,54787,54788,54789,54790,54791,54792,54793,54794,54795,54796,54797,54798,54799,54800,54801,54802,54803,54804,54805,54806,54807,54808,54809,54810,54811,54812,54813,54814,54815,54816,54817,54818,54819,54820,54821,54822,54823,54824,54825,54826,54827,54828,54829,54830,54831,54832,54833,54834,54835,54836,54837,54838,54839,54840,54841,54842,54843,54844,54845,54846,54847,54848,54849,54850,54851,54852,54853,54854,54855,54856,54857,54858,54859,54860,54861,54862,54863,54864,54865,54866,54867,54868,54869,54870,54871,54872,54873,54874,54875,54876,54877,54878,54879,54880,54881,54882,54883,54884,54885,54886,54887,54888,54889,54890,54891,54892,54893,54894,54895,54896,54897,54898,54899,54900,54901,54902,54903,54904,54905,54906,54907,54908,54909,54910,54911,54912,54913,54914,54915,54916,54917,54918,54919,54920,54921,54922,54923,54924,54925,54926,54927,54928,54929,54930,54931,54932,54933,54934,54935,54936,54937,54938,54939,54940,54941,54942,54943,54944,54945,54946,54947,54948,54949,54950,54951,54952,54953,54954,54955,54956,54957,54958,54959,54960,54961,54962,54963,54964,54965,54966,54967,54968,54969,54970,54971,54972,54973,54974,54975,54976,54977,54978,54979,54980,54981,54982,54983,54984,54985,54986,54987,54988,54989,54990,54991,54992,54993,54994,54995,54996,54997,54998,54999,55000,55001,55002,55003,55004,55005,55006,55007,55008,55009,55010,55011,55012,55013,55014,55015,55016,55017,55018,55019,55020,55021,55022,55023,55024,55025,55026,55027,55028,55029,55030,55031,55032,55033,55034,55035,55036,55037,55038,55039,55040,55041,55042,55043,55044,55045,55046,55047,55048,55049,55050,55051,55052,55053,55054,55055,55056,55057,55058,55059,55060,55061,55062,55063,55064,55065,55066,55067,55068,55069,55070,55071,55072,55073,55074,55075,55076,55077,55078,55079,55080,55081,55082,55083,55084,55085,55086,55087,55088,55089,55090,55091,55092,55093,55094,55095,55096,55097,55098,55099,55100,55101,55102,55103,55104,55105,55106,55107,55108,55109,55110,55111,55112,55113,55114,55115,55116,55117,55118,55119,55120,55121,55122,55123,55124,55125,55126,55127,55128,55129,55130,55131,55132,55133,55134,55135,55136,55137,55138,55139,55140,55141,55142,55143,55144,55145,55146,55147,55148,55149,55150,55151,55152,55153,55154,55155,55156,55157,55158,55159,55160,55161,55162,55163,55164,55165,55166,55167,55168,55169,55170,55171,55172,55173,55174,55175,55176,55177,55178,55179,55180,55181,55182,55183,55184,55185,55186,55187,55188,55189,55190,55191,55192,55193,55194,55195,55196,55197,55198,55199,55200,55201,55202,55203,55216,55217,55218,55219,55220,55221,55222,55223,55224,55225,55226,55227,55228,55229,55230,55231,55232,55233,55234,55235,55236,55237,55238,55243,55244,55245,55246,55247,55248,55249,55250,55251,55252,55253,55254,55255,55256,55257,55258,55259,55260,55261,55262,55263,55264,55265,55266,55267,55268,55269,55270,55271,55272,55273,55274,55275,55276,55277,55278,55279,55280,55281,55282,55283,55284,55285,55286,55287,55288,55289,55290,55291,63744,63745,63746,63747,63748,63749,63750,63751,63752,63753,63754,63755,63756,63757,63758,63759,63760,63761,63762,63763,63764,63765,63766,63767,63768,63769,63770,63771,63772,63773,63774,63775,63776,63777,63778,63779,63780,63781,63782,63783,63784,63785,63786,63787,63788,63789,63790,63791,63792,63793,63794,63795,63796,63797,63798,63799,63800,63801,63802,63803,63804,63805,63806,63807,63808,63809,63810,63811,63812,63813,63814,63815,63816,63817,63818,63819,63820,63821,63822,63823,63824,63825,63826,63827,63828,63829,63830,63831,63832,63833,63834,63835,63836,63837,63838,63839,63840,63841,63842,63843,63844,63845,63846,63847,63848,63849,63850,63851,63852,63853,63854,63855,63856,63857,63858,63859,63860,63861,63862,63863,63864,63865,63866,63867,63868,63869,63870,63871,63872,63873,63874,63875,63876,63877,63878,63879,63880,63881,63882,63883,63884,63885,63886,63887,63888,63889,63890,63891,63892,63893,63894,63895,63896,63897,63898,63899,63900,63901,63902,63903,63904,63905,63906,63907,63908,63909,63910,63911,63912,63913,63914,63915,63916,63917,63918,63919,63920,63921,63922,63923,63924,63925,63926,63927,63928,63929,63930,63931,63932,63933,63934,63935,63936,63937,63938,63939,63940,63941,63942,63943,63944,63945,63946,63947,63948,63949,63950,63951,63952,63953,63954,63955,63956,63957,63958,63959,63960,63961,63962,63963,63964,63965,63966,63967,63968,63969,63970,63971,63972,63973,63974,63975,63976,63977,63978,63979,63980,63981,63982,63983,63984,63985,63986,63987,63988,63989,63990,63991,63992,63993,63994,63995,63996,63997,63998,63999,64000,64001,64002,64003,64004,64005,64006,64007,64008,64009,64010,64011,64012,64013,64014,64015,64016,64017,64018,64019,64020,64021,64022,64023,64024,64025,64026,64027,64028,64029,64030,64031,64032,64033,64034,64035,64036,64037,64038,64039,64040,64041,64042,64043,64044,64045,64046,64047,64048,64049,64050,64051,64052,64053,64054,64055,64056,64057,64058,64059,64060,64061,64062,64063,64064,64065,64066,64067,64068,64069,64070,64071,64072,64073,64074,64075,64076,64077,64078,64079,64080,64081,64082,64083,64084,64085,64086,64087,64088,64089,64090,64091,64092,64093,64094,64095,64096,64097,64098,64099,64100,64101,64102,64103,64104,64105,64106,64107,64108,64109,64112,64113,64114,64115,64116,64117,64118,64119,64120,64121,64122,64123,64124,64125,64126,64127,64128,64129,64130,64131,64132,64133,64134,64135,64136,64137,64138,64139,64140,64141,64142,64143,64144,64145,64146,64147,64148,64149,64150,64151,64152,64153,64154,64155,64156,64157,64158,64159,64160,64161,64162,64163,64164,64165,64166,64167,64168,64169,64170,64171,64172,64173,64174,64175,64176,64177,64178,64179,64180,64181,64182,64183,64184,64185,64186,64187,64188,64189,64190,64191,64192,64193,64194,64195,64196,64197,64198,64199,64200,64201,64202,64203,64204,64205,64206,64207,64208,64209,64210,64211,64212,64213,64214,64215,64216,64217,64256,64257,64258,64259,64260,64261,64262,64275,64276,64277,64278,64279,64285,64287,64288,64289,64290,64291,64292,64293,64294,64295,64296,64298,64299,64300,64301,64302,64303,64304,64305,64306,64307,64308,64309,64310,64312,64313,64314,64315,64316,64318,64320,64321,64323,64324,64326,64327,64328,64329,64330,64331,64332,64333,64334,64335,64336,64337,64338,64339,64340,64341,64342,64343,64344,64345,64346,64347,64348,64349,64350,64351,64352,64353,64354,64355,64356,64357,64358,64359,64360,64361,64362,64363,64364,64365,64366,64367,64368,64369,64370,64371,64372,64373,64374,64375,64376,64377,64378,64379,64380,64381,64382,64383,64384,64385,64386,64387,64388,64389,64390,64391,64392,64393,64394,64395,64396,64397,64398,64399,64400,64401,64402,64403,64404,64405,64406,64407,64408,64409,64410,64411,64412,64413,64414,64415,64416,64417,64418,64419,64420,64421,64422,64423,64424,64425,64426,64427,64428,64429,64430,64431,64432,64433,64467,64468,64469,64470,64471,64472,64473,64474,64475,64476,64477,64478,64479,64480,64481,64482,64483,64484,64485,64486,64487,64488,64489,64490,64491,64492,64493,64494,64495,64496,64497,64498,64499,64500,64501,64502,64503,64504,64505,64506,64507,64508,64509,64510,64511,64512,64513,64514,64515,64516,64517,64518,64519,64520,64521,64522,64523,64524,64525,64526,64527,64528,64529,64530,64531,64532,64533,64534,64535,64536,64537,64538,64539,64540,64541,64542,64543,64544,64545,64546,64547,64548,64549,64550,64551,64552,64553,64554,64555,64556,64557,64558,64559,64560,64561,64562,64563,64564,64565,64566,64567,64568,64569,64570,64571,64572,64573,64574,64575,64576,64577,64578,64579,64580,64581,64582,64583,64584,64585,64586,64587,64588,64589,64590,64591,64592,64593,64594,64595,64596,64597,64598,64599,64600,64601,64602,64603,64604,64605,64606,64607,64608,64609,64610,64611,64612,64613,64614,64615,64616,64617,64618,64619,64620,64621,64622,64623,64624,64625,64626,64627,64628,64629,64630,64631,64632,64633,64634,64635,64636,64637,64638,64639,64640,64641,64642,64643,64644,64645,64646,64647,64648,64649,64650,64651,64652,64653,64654,64655,64656,64657,64658,64659,64660,64661,64662,64663,64664,64665,64666,64667,64668,64669,64670,64671,64672,64673,64674,64675,64676,64677,64678,64679,64680,64681,64682,64683,64684,64685,64686,64687,64688,64689,64690,64691,64692,64693,64694,64695,64696,64697,64698,64699,64700,64701,64702,64703,64704,64705,64706,64707,64708,64709,64710,64711,64712,64713,64714,64715,64716,64717,64718,64719,64720,64721,64722,64723,64724,64725,64726,64727,64728,64729,64730,64731,64732,64733,64734,64735,64736,64737,64738,64739,64740,64741,64742,64743,64744,64745,64746,64747,64748,64749,64750,64751,64752,64753,64754,64755,64756,64757,64758,64759,64760,64761,64762,64763,64764,64765,64766,64767,64768,64769,64770,64771,64772,64773,64774,64775,64776,64777,64778,64779,64780,64781,64782,64783,64784,64785,64786,64787,64788,64789,64790,64791,64792,64793,64794,64795,64796,64797,64798,64799,64800,64801,64802,64803,64804,64805,64806,64807,64808,64809,64810,64811,64812,64813,64814,64815,64816,64817,64818,64819,64820,64821,64822,64823,64824,64825,64826,64827,64828,64829,64848,64849,64850,64851,64852,64853,64854,64855,64856,64857,64858,64859,64860,64861,64862,64863,64864,64865,64866,64867,64868,64869,64870,64871,64872,64873,64874,64875,64876,64877,64878,64879,64880,64881,64882,64883,64884,64885,64886,64887,64888,64889,64890,64891,64892,64893,64894,64895,64896,64897,64898,64899,64900,64901,64902,64903,64904,64905,64906,64907,64908,64909,64910,64911,64914,64915,64916,64917,64918,64919,64920,64921,64922,64923,64924,64925,64926,64927,64928,64929,64930,64931,64932,64933,64934,64935,64936,64937,64938,64939,64940,64941,64942,64943,64944,64945,64946,64947,64948,64949,64950,64951,64952,64953,64954,64955,64956,64957,64958,64959,64960,64961,64962,64963,64964,64965,64966,64967,65008,65009,65010,65011,65012,65013,65014,65015,65016,65017,65018,65019,65136,65137,65138,65139,65140,65142,65143,65144,65145,65146,65147,65148,65149,65150,65151,65152,65153,65154,65155,65156,65157,65158,65159,65160,65161,65162,65163,65164,65165,65166,65167,65168,65169,65170,65171,65172,65173,65174,65175,65176,65177,65178,65179,65180,65181,65182,65183,65184,65185,65186,65187,65188,65189,65190,65191,65192,65193,65194,65195,65196,65197,65198,65199,65200,65201,65202,65203,65204,65205,65206,65207,65208,65209,65210,65211,65212,65213,65214,65215,65216,65217,65218,65219,65220,65221,65222,65223,65224,65225,65226,65227,65228,65229,65230,65231,65232,65233,65234,65235,65236,65237,65238,65239,65240,65241,65242,65243,65244,65245,65246,65247,65248,65249,65250,65251,65252,65253,65254,65255,65256,65257,65258,65259,65260,65261,65262,65263,65264,65265,65266,65267,65268,65269,65270,65271,65272,65273,65274,65275,65276,65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,65345,65346,65347,65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,65382,65383,65384,65385,65386,65387,65388,65389,65390,65391,65392,65393,65394,65395,65396,65397,65398,65399,65400,65401,65402,65403,65404,65405,65406,65407,65408,65409,65410,65411,65412,65413,65414,65415,65416,65417,65418,65419,65420,65421,65422,65423,65424,65425,65426,65427,65428,65429,65430,65431,65432,65433,65434,65435,65436,65437,65438,65439,65440,65441,65442,65443,65444,65445,65446,65447,65448,65449,65450,65451,65452,65453,65454,65455,65456,65457,65458,65459,65460,65461,65462,65463,65464,65465,65466,65467,65468,65469,65470,65474,65475,65476,65477,65478,65479,65482,65483,65484,65485,65486,65487,65490,65491,65492,65493,65494,65495,65498,65499,65500'; +var arr = str.split(',').map(function(code) { + return parseInt(code, 10); +}); +module.exports = arr; \ No newline at end of file diff --git a/node_modules/jshint/dist/jshint-rhino.js b/node_modules/jshint/dist/jshint-rhino.js new file mode 100644 index 0000000..2efde3d --- /dev/null +++ b/node_modules/jshint/dist/jshint-rhino.js @@ -0,0 +1,24429 @@ +#!/usr/bin/env rhino +var window = {}; +/*! 2.9.4 */ +var JSHINT; +if (typeof window === 'undefined') window = {}; +(function () { +var require; +require=(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= 65 && i <= 90 || // A-Z + i === 95 || // _ + i >= 97 && i <= 122; // a-z +} + +var identifierPartTable = []; + +for (var i = 0; i < 128; i++) { + identifierPartTable[i] = + identifierStartTable[i] || // $, _, A-Z, a-z + i >= 48 && i <= 57; // 0-9 +} + +module.exports = { + asciiIdentifierStartTable: identifierStartTable, + asciiIdentifierPartTable: identifierPartTable +}; + +},{}],2:[function(require,module,exports){ +var str = '768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,1155,1156,1157,1158,1159,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1471,1473,1474,1476,1477,1479,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1611,1612,1613,1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1648,1750,1751,1752,1753,1754,1755,1756,1759,1760,1761,1762,1763,1764,1767,1768,1770,1771,1772,1773,1776,1777,1778,1779,1780,1781,1782,1783,1784,1785,1809,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,2027,2028,2029,2030,2031,2032,2033,2034,2035,2070,2071,2072,2073,2075,2076,2077,2078,2079,2080,2081,2082,2083,2085,2086,2087,2089,2090,2091,2092,2093,2137,2138,2139,2276,2277,2278,2279,2280,2281,2282,2283,2284,2285,2286,2287,2288,2289,2290,2291,2292,2293,2294,2295,2296,2297,2298,2299,2300,2301,2302,2304,2305,2306,2307,2362,2363,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2385,2386,2387,2388,2389,2390,2391,2402,2403,2406,2407,2408,2409,2410,2411,2412,2413,2414,2415,2433,2434,2435,2492,2494,2495,2496,2497,2498,2499,2500,2503,2504,2507,2508,2509,2519,2530,2531,2534,2535,2536,2537,2538,2539,2540,2541,2542,2543,2561,2562,2563,2620,2622,2623,2624,2625,2626,2631,2632,2635,2636,2637,2641,2662,2663,2664,2665,2666,2667,2668,2669,2670,2671,2672,2673,2677,2689,2690,2691,2748,2750,2751,2752,2753,2754,2755,2756,2757,2759,2760,2761,2763,2764,2765,2786,2787,2790,2791,2792,2793,2794,2795,2796,2797,2798,2799,2817,2818,2819,2876,2878,2879,2880,2881,2882,2883,2884,2887,2888,2891,2892,2893,2902,2903,2914,2915,2918,2919,2920,2921,2922,2923,2924,2925,2926,2927,2946,3006,3007,3008,3009,3010,3014,3015,3016,3018,3019,3020,3021,3031,3046,3047,3048,3049,3050,3051,3052,3053,3054,3055,3073,3074,3075,3134,3135,3136,3137,3138,3139,3140,3142,3143,3144,3146,3147,3148,3149,3157,3158,3170,3171,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3202,3203,3260,3262,3263,3264,3265,3266,3267,3268,3270,3271,3272,3274,3275,3276,3277,3285,3286,3298,3299,3302,3303,3304,3305,3306,3307,3308,3309,3310,3311,3330,3331,3390,3391,3392,3393,3394,3395,3396,3398,3399,3400,3402,3403,3404,3405,3415,3426,3427,3430,3431,3432,3433,3434,3435,3436,3437,3438,3439,3458,3459,3530,3535,3536,3537,3538,3539,3540,3542,3544,3545,3546,3547,3548,3549,3550,3551,3570,3571,3633,3636,3637,3638,3639,3640,3641,3642,3655,3656,3657,3658,3659,3660,3661,3662,3664,3665,3666,3667,3668,3669,3670,3671,3672,3673,3761,3764,3765,3766,3767,3768,3769,3771,3772,3784,3785,3786,3787,3788,3789,3792,3793,3794,3795,3796,3797,3798,3799,3800,3801,3864,3865,3872,3873,3874,3875,3876,3877,3878,3879,3880,3881,3893,3895,3897,3902,3903,3953,3954,3955,3956,3957,3958,3959,3960,3961,3962,3963,3964,3965,3966,3967,3968,3969,3970,3971,3972,3974,3975,3981,3982,3983,3984,3985,3986,3987,3988,3989,3990,3991,3993,3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005,4006,4007,4008,4009,4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027,4028,4038,4139,4140,4141,4142,4143,4144,4145,4146,4147,4148,4149,4150,4151,4152,4153,4154,4155,4156,4157,4158,4160,4161,4162,4163,4164,4165,4166,4167,4168,4169,4182,4183,4184,4185,4190,4191,4192,4194,4195,4196,4199,4200,4201,4202,4203,4204,4205,4209,4210,4211,4212,4226,4227,4228,4229,4230,4231,4232,4233,4234,4235,4236,4237,4239,4240,4241,4242,4243,4244,4245,4246,4247,4248,4249,4250,4251,4252,4253,4957,4958,4959,5906,5907,5908,5938,5939,5940,5970,5971,6002,6003,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,6099,6109,6112,6113,6114,6115,6116,6117,6118,6119,6120,6121,6155,6156,6157,6160,6161,6162,6163,6164,6165,6166,6167,6168,6169,6313,6432,6433,6434,6435,6436,6437,6438,6439,6440,6441,6442,6443,6448,6449,6450,6451,6452,6453,6454,6455,6456,6457,6458,6459,6470,6471,6472,6473,6474,6475,6476,6477,6478,6479,6576,6577,6578,6579,6580,6581,6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6600,6601,6608,6609,6610,6611,6612,6613,6614,6615,6616,6617,6679,6680,6681,6682,6683,6741,6742,6743,6744,6745,6746,6747,6748,6749,6750,6752,6753,6754,6755,6756,6757,6758,6759,6760,6761,6762,6763,6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,6774,6775,6776,6777,6778,6779,6780,6783,6784,6785,6786,6787,6788,6789,6790,6791,6792,6793,6800,6801,6802,6803,6804,6805,6806,6807,6808,6809,6912,6913,6914,6915,6916,6964,6965,6966,6967,6968,6969,6970,6971,6972,6973,6974,6975,6976,6977,6978,6979,6980,6992,6993,6994,6995,6996,6997,6998,6999,7000,7001,7019,7020,7021,7022,7023,7024,7025,7026,7027,7040,7041,7042,7073,7074,7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7088,7089,7090,7091,7092,7093,7094,7095,7096,7097,7142,7143,7144,7145,7146,7147,7148,7149,7150,7151,7152,7153,7154,7155,7204,7205,7206,7207,7208,7209,7210,7211,7212,7213,7214,7215,7216,7217,7218,7219,7220,7221,7222,7223,7232,7233,7234,7235,7236,7237,7238,7239,7240,7241,7248,7249,7250,7251,7252,7253,7254,7255,7256,7257,7376,7377,7378,7380,7381,7382,7383,7384,7385,7386,7387,7388,7389,7390,7391,7392,7393,7394,7395,7396,7397,7398,7399,7400,7405,7410,7411,7412,7616,7617,7618,7619,7620,7621,7622,7623,7624,7625,7626,7627,7628,7629,7630,7631,7632,7633,7634,7635,7636,7637,7638,7639,7640,7641,7642,7643,7644,7645,7646,7647,7648,7649,7650,7651,7652,7653,7654,7676,7677,7678,7679,8204,8205,8255,8256,8276,8400,8401,8402,8403,8404,8405,8406,8407,8408,8409,8410,8411,8412,8417,8421,8422,8423,8424,8425,8426,8427,8428,8429,8430,8431,8432,11503,11504,11505,11647,11744,11745,11746,11747,11748,11749,11750,11751,11752,11753,11754,11755,11756,11757,11758,11759,11760,11761,11762,11763,11764,11765,11766,11767,11768,11769,11770,11771,11772,11773,11774,11775,12330,12331,12332,12333,12334,12335,12441,12442,42528,42529,42530,42531,42532,42533,42534,42535,42536,42537,42607,42612,42613,42614,42615,42616,42617,42618,42619,42620,42621,42655,42736,42737,43010,43014,43019,43043,43044,43045,43046,43047,43136,43137,43188,43189,43190,43191,43192,43193,43194,43195,43196,43197,43198,43199,43200,43201,43202,43203,43204,43216,43217,43218,43219,43220,43221,43222,43223,43224,43225,43232,43233,43234,43235,43236,43237,43238,43239,43240,43241,43242,43243,43244,43245,43246,43247,43248,43249,43264,43265,43266,43267,43268,43269,43270,43271,43272,43273,43302,43303,43304,43305,43306,43307,43308,43309,43335,43336,43337,43338,43339,43340,43341,43342,43343,43344,43345,43346,43347,43392,43393,43394,43395,43443,43444,43445,43446,43447,43448,43449,43450,43451,43452,43453,43454,43455,43456,43472,43473,43474,43475,43476,43477,43478,43479,43480,43481,43561,43562,43563,43564,43565,43566,43567,43568,43569,43570,43571,43572,43573,43574,43587,43596,43597,43600,43601,43602,43603,43604,43605,43606,43607,43608,43609,43643,43696,43698,43699,43700,43703,43704,43710,43711,43713,43755,43756,43757,43758,43759,43765,43766,44003,44004,44005,44006,44007,44008,44009,44010,44012,44013,44016,44017,44018,44019,44020,44021,44022,44023,44024,44025,64286,65024,65025,65026,65027,65028,65029,65030,65031,65032,65033,65034,65035,65036,65037,65038,65039,65056,65057,65058,65059,65060,65061,65062,65075,65076,65101,65102,65103,65296,65297,65298,65299,65300,65301,65302,65303,65304,65305,65343'; +var arr = str.split(',').map(function(code) { + return parseInt(code, 10); +}); +module.exports = arr; +},{}],3:[function(require,module,exports){ +var str = '170,181,186,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,710,711,712,713,714,715,716,717,718,719,720,721,736,737,738,739,740,748,750,880,881,882,883,884,886,887,890,891,892,893,902,904,905,906,908,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1369,1377,1378,1379,1380,1381,1382,1383,1384,1385,1386,1387,1388,1389,1390,1391,1392,1393,1394,1395,1396,1397,1398,1399,1400,1401,1402,1403,1404,1405,1406,1407,1408,1409,1410,1411,1412,1413,1414,1415,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1520,1521,1522,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1646,1647,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660,1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1749,1765,1766,1774,1775,1786,1787,1788,1791,1808,1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,1839,1869,1870,1871,1872,1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883,1884,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,1896,1897,1898,1899,1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1969,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022,2023,2024,2025,2026,2036,2037,2042,2048,2049,2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,2060,2061,2062,2063,2064,2065,2066,2067,2068,2069,2074,2084,2088,2112,2113,2114,2115,2116,2117,2118,2119,2120,2121,2122,2123,2124,2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2208,2210,2211,2212,2213,2214,2215,2216,2217,2218,2219,2220,2308,2309,2310,2311,2312,2313,2314,2315,2316,2317,2318,2319,2320,2321,2322,2323,2324,2325,2326,2327,2328,2329,2330,2331,2332,2333,2334,2335,2336,2337,2338,2339,2340,2341,2342,2343,2344,2345,2346,2347,2348,2349,2350,2351,2352,2353,2354,2355,2356,2357,2358,2359,2360,2361,2365,2384,2392,2393,2394,2395,2396,2397,2398,2399,2400,2401,2417,2418,2419,2420,2421,2422,2423,2425,2426,2427,2428,2429,2430,2431,2437,2438,2439,2440,2441,2442,2443,2444,2447,2448,2451,2452,2453,2454,2455,2456,2457,2458,2459,2460,2461,2462,2463,2464,2465,2466,2467,2468,2469,2470,2471,2472,2474,2475,2476,2477,2478,2479,2480,2482,2486,2487,2488,2489,2493,2510,2524,2525,2527,2528,2529,2544,2545,2565,2566,2567,2568,2569,2570,2575,2576,2579,2580,2581,2582,2583,2584,2585,2586,2587,2588,2589,2590,2591,2592,2593,2594,2595,2596,2597,2598,2599,2600,2602,2603,2604,2605,2606,2607,2608,2610,2611,2613,2614,2616,2617,2649,2650,2651,2652,2654,2674,2675,2676,2693,2694,2695,2696,2697,2698,2699,2700,2701,2703,2704,2705,2707,2708,2709,2710,2711,2712,2713,2714,2715,2716,2717,2718,2719,2720,2721,2722,2723,2724,2725,2726,2727,2728,2730,2731,2732,2733,2734,2735,2736,2738,2739,2741,2742,2743,2744,2745,2749,2768,2784,2785,2821,2822,2823,2824,2825,2826,2827,2828,2831,2832,2835,2836,2837,2838,2839,2840,2841,2842,2843,2844,2845,2846,2847,2848,2849,2850,2851,2852,2853,2854,2855,2856,2858,2859,2860,2861,2862,2863,2864,2866,2867,2869,2870,2871,2872,2873,2877,2908,2909,2911,2912,2913,2929,2947,2949,2950,2951,2952,2953,2954,2958,2959,2960,2962,2963,2964,2965,2969,2970,2972,2974,2975,2979,2980,2984,2985,2986,2990,2991,2992,2993,2994,2995,2996,2997,2998,2999,3000,3001,3024,3077,3078,3079,3080,3081,3082,3083,3084,3086,3087,3088,3090,3091,3092,3093,3094,3095,3096,3097,3098,3099,3100,3101,3102,3103,3104,3105,3106,3107,3108,3109,3110,3111,3112,3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3125,3126,3127,3128,3129,3133,3160,3161,3168,3169,3205,3206,3207,3208,3209,3210,3211,3212,3214,3215,3216,3218,3219,3220,3221,3222,3223,3224,3225,3226,3227,3228,3229,3230,3231,3232,3233,3234,3235,3236,3237,3238,3239,3240,3242,3243,3244,3245,3246,3247,3248,3249,3250,3251,3253,3254,3255,3256,3257,3261,3294,3296,3297,3313,3314,3333,3334,3335,3336,3337,3338,3339,3340,3342,3343,3344,3346,3347,3348,3349,3350,3351,3352,3353,3354,3355,3356,3357,3358,3359,3360,3361,3362,3363,3364,3365,3366,3367,3368,3369,3370,3371,3372,3373,3374,3375,3376,3377,3378,3379,3380,3381,3382,3383,3384,3385,3386,3389,3406,3424,3425,3450,3451,3452,3453,3454,3455,3461,3462,3463,3464,3465,3466,3467,3468,3469,3470,3471,3472,3473,3474,3475,3476,3477,3478,3482,3483,3484,3485,3486,3487,3488,3489,3490,3491,3492,3493,3494,3495,3496,3497,3498,3499,3500,3501,3502,3503,3504,3505,3507,3508,3509,3510,3511,3512,3513,3514,3515,3517,3520,3521,3522,3523,3524,3525,3526,3585,3586,3587,3588,3589,3590,3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607,3608,3609,3610,3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,3621,3622,3623,3624,3625,3626,3627,3628,3629,3630,3631,3632,3634,3635,3648,3649,3650,3651,3652,3653,3654,3713,3714,3716,3719,3720,3722,3725,3732,3733,3734,3735,3737,3738,3739,3740,3741,3742,3743,3745,3746,3747,3749,3751,3754,3755,3757,3758,3759,3760,3762,3763,3773,3776,3777,3778,3779,3780,3782,3804,3805,3806,3807,3840,3904,3905,3906,3907,3908,3909,3910,3911,3913,3914,3915,3916,3917,3918,3919,3920,3921,3922,3923,3924,3925,3926,3927,3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,3939,3940,3941,3942,3943,3944,3945,3946,3947,3948,3976,3977,3978,3979,3980,4096,4097,4098,4099,4100,4101,4102,4103,4104,4105,4106,4107,4108,4109,4110,4111,4112,4113,4114,4115,4116,4117,4118,4119,4120,4121,4122,4123,4124,4125,4126,4127,4128,4129,4130,4131,4132,4133,4134,4135,4136,4137,4138,4159,4176,4177,4178,4179,4180,4181,4186,4187,4188,4189,4193,4197,4198,4206,4207,4208,4213,4214,4215,4216,4217,4218,4219,4220,4221,4222,4223,4224,4225,4238,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265,4266,4267,4268,4269,4270,4271,4272,4273,4274,4275,4276,4277,4278,4279,4280,4281,4282,4283,4284,4285,4286,4287,4288,4289,4290,4291,4292,4293,4295,4301,4304,4305,4306,4307,4308,4309,4310,4311,4312,4313,4314,4315,4316,4317,4318,4319,4320,4321,4322,4323,4324,4325,4326,4327,4328,4329,4330,4331,4332,4333,4334,4335,4336,4337,4338,4339,4340,4341,4342,4343,4344,4345,4346,4348,4349,4350,4351,4352,4353,4354,4355,4356,4357,4358,4359,4360,4361,4362,4363,4364,4365,4366,4367,4368,4369,4370,4371,4372,4373,4374,4375,4376,4377,4378,4379,4380,4381,4382,4383,4384,4385,4386,4387,4388,4389,4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403,4404,4405,4406,4407,4408,4409,4410,4411,4412,4413,4414,4415,4416,4417,4418,4419,4420,4421,4422,4423,4424,4425,4426,4427,4428,4429,4430,4431,4432,4433,4434,4435,4436,4437,4438,4439,4440,4441,4442,4443,4444,4445,4446,4447,4448,4449,4450,4451,4452,4453,4454,4455,4456,4457,4458,4459,4460,4461,4462,4463,4464,4465,4466,4467,4468,4469,4470,4471,4472,4473,4474,4475,4476,4477,4478,4479,4480,4481,4482,4483,4484,4485,4486,4487,4488,4489,4490,4491,4492,4493,4494,4495,4496,4497,4498,4499,4500,4501,4502,4503,4504,4505,4506,4507,4508,4509,4510,4511,4512,4513,4514,4515,4516,4517,4518,4519,4520,4521,4522,4523,4524,4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,4536,4537,4538,4539,4540,4541,4542,4543,4544,4545,4546,4547,4548,4549,4550,4551,4552,4553,4554,4555,4556,4557,4558,4559,4560,4561,4562,4563,4564,4565,4566,4567,4568,4569,4570,4571,4572,4573,4574,4575,4576,4577,4578,4579,4580,4581,4582,4583,4584,4585,4586,4587,4588,4589,4590,4591,4592,4593,4594,4595,4596,4597,4598,4599,4600,4601,4602,4603,4604,4605,4606,4607,4608,4609,4610,4611,4612,4613,4614,4615,4616,4617,4618,4619,4620,4621,4622,4623,4624,4625,4626,4627,4628,4629,4630,4631,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642,4643,4644,4645,4646,4647,4648,4649,4650,4651,4652,4653,4654,4655,4656,4657,4658,4659,4660,4661,4662,4663,4664,4665,4666,4667,4668,4669,4670,4671,4672,4673,4674,4675,4676,4677,4678,4679,4680,4682,4683,4684,4685,4688,4689,4690,4691,4692,4693,4694,4696,4698,4699,4700,4701,4704,4705,4706,4707,4708,4709,4710,4711,4712,4713,4714,4715,4716,4717,4718,4719,4720,4721,4722,4723,4724,4725,4726,4727,4728,4729,4730,4731,4732,4733,4734,4735,4736,4737,4738,4739,4740,4741,4742,4743,4744,4746,4747,4748,4749,4752,4753,4754,4755,4756,4757,4758,4759,4760,4761,4762,4763,4764,4765,4766,4767,4768,4769,4770,4771,4772,4773,4774,4775,4776,4777,4778,4779,4780,4781,4782,4783,4784,4786,4787,4788,4789,4792,4793,4794,4795,4796,4797,4798,4800,4802,4803,4804,4805,4808,4809,4810,4811,4812,4813,4814,4815,4816,4817,4818,4819,4820,4821,4822,4824,4825,4826,4827,4828,4829,4830,4831,4832,4833,4834,4835,4836,4837,4838,4839,4840,4841,4842,4843,4844,4845,4846,4847,4848,4849,4850,4851,4852,4853,4854,4855,4856,4857,4858,4859,4860,4861,4862,4863,4864,4865,4866,4867,4868,4869,4870,4871,4872,4873,4874,4875,4876,4877,4878,4879,4880,4882,4883,4884,4885,4888,4889,4890,4891,4892,4893,4894,4895,4896,4897,4898,4899,4900,4901,4902,4903,4904,4905,4906,4907,4908,4909,4910,4911,4912,4913,4914,4915,4916,4917,4918,4919,4920,4921,4922,4923,4924,4925,4926,4927,4928,4929,4930,4931,4932,4933,4934,4935,4936,4937,4938,4939,4940,4941,4942,4943,4944,4945,4946,4947,4948,4949,4950,4951,4952,4953,4954,4992,4993,4994,4995,4996,4997,4998,4999,5000,5001,5002,5003,5004,5005,5006,5007,5024,5025,5026,5027,5028,5029,5030,5031,5032,5033,5034,5035,5036,5037,5038,5039,5040,5041,5042,5043,5044,5045,5046,5047,5048,5049,5050,5051,5052,5053,5054,5055,5056,5057,5058,5059,5060,5061,5062,5063,5064,5065,5066,5067,5068,5069,5070,5071,5072,5073,5074,5075,5076,5077,5078,5079,5080,5081,5082,5083,5084,5085,5086,5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102,5103,5104,5105,5106,5107,5108,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133,5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149,5150,5151,5152,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164,5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,5176,5177,5178,5179,5180,5181,5182,5183,5184,5185,5186,5187,5188,5189,5190,5191,5192,5193,5194,5195,5196,5197,5198,5199,5200,5201,5202,5203,5204,5205,5206,5207,5208,5209,5210,5211,5212,5213,5214,5215,5216,5217,5218,5219,5220,5221,5222,5223,5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,5237,5238,5239,5240,5241,5242,5243,5244,5245,5246,5247,5248,5249,5250,5251,5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267,5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283,5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331,5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347,5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363,5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379,5380,5381,5382,5383,5384,5385,5386,5387,5388,5389,5390,5391,5392,5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408,5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440,5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456,5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472,5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488,5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504,5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520,5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536,5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552,5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568,5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584,5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600,5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616,5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632,5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648,5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664,5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680,5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696,5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712,5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728,5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5743,5744,5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776,5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5792,5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808,5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856,5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5870,5871,5872,5888,5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5902,5903,5904,5905,5920,5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936,5937,5952,5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968,5969,5984,5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5998,5999,6000,6016,6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032,6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6103,6108,6176,6177,6178,6179,6180,6181,6182,6183,6184,6185,6186,6187,6188,6189,6190,6191,6192,6193,6194,6195,6196,6197,6198,6199,6200,6201,6202,6203,6204,6205,6206,6207,6208,6209,6210,6211,6212,6213,6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6229,6230,6231,6232,6233,6234,6235,6236,6237,6238,6239,6240,6241,6242,6243,6244,6245,6246,6247,6248,6249,6250,6251,6252,6253,6254,6255,6256,6257,6258,6259,6260,6261,6262,6263,6272,6273,6274,6275,6276,6277,6278,6279,6280,6281,6282,6283,6284,6285,6286,6287,6288,6289,6290,6291,6292,6293,6294,6295,6296,6297,6298,6299,6300,6301,6302,6303,6304,6305,6306,6307,6308,6309,6310,6311,6312,6314,6320,6321,6322,6323,6324,6325,6326,6327,6328,6329,6330,6331,6332,6333,6334,6335,6336,6337,6338,6339,6340,6341,6342,6343,6344,6345,6346,6347,6348,6349,6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362,6363,6364,6365,6366,6367,6368,6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379,6380,6381,6382,6383,6384,6385,6386,6387,6388,6389,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411,6412,6413,6414,6415,6416,6417,6418,6419,6420,6421,6422,6423,6424,6425,6426,6427,6428,6480,6481,6482,6483,6484,6485,6486,6487,6488,6489,6490,6491,6492,6493,6494,6495,6496,6497,6498,6499,6500,6501,6502,6503,6504,6505,6506,6507,6508,6509,6512,6513,6514,6515,6516,6528,6529,6530,6531,6532,6533,6534,6535,6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548,6549,6550,6551,6552,6553,6554,6555,6556,6557,6558,6559,6560,6561,6562,6563,6564,6565,6566,6567,6568,6569,6570,6571,6593,6594,6595,6596,6597,6598,6599,6656,6657,6658,6659,6660,6661,6662,6663,6664,6665,6666,6667,6668,6669,6670,6671,6672,6673,6674,6675,6676,6677,6678,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,6698,6699,6700,6701,6702,6703,6704,6705,6706,6707,6708,6709,6710,6711,6712,6713,6714,6715,6716,6717,6718,6719,6720,6721,6722,6723,6724,6725,6726,6727,6728,6729,6730,6731,6732,6733,6734,6735,6736,6737,6738,6739,6740,6823,6917,6918,6919,6920,6921,6922,6923,6924,6925,6926,6927,6928,6929,6930,6931,6932,6933,6934,6935,6936,6937,6938,6939,6940,6941,6942,6943,6944,6945,6946,6947,6948,6949,6950,6951,6952,6953,6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6981,6982,6983,6984,6985,6986,6987,7043,7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058,7059,7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,7071,7072,7086,7087,7098,7099,7100,7101,7102,7103,7104,7105,7106,7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,7119,7120,7121,7122,7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,7134,7135,7136,7137,7138,7139,7140,7141,7168,7169,7170,7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183,7184,7185,7186,7187,7188,7189,7190,7191,7192,7193,7194,7195,7196,7197,7198,7199,7200,7201,7202,7203,7245,7246,7247,7258,7259,7260,7261,7262,7263,7264,7265,7266,7267,7268,7269,7270,7271,7272,7273,7274,7275,7276,7277,7278,7279,7280,7281,7282,7283,7284,7285,7286,7287,7288,7289,7290,7291,7292,7293,7401,7402,7403,7404,7406,7407,7408,7409,7413,7414,7424,7425,7426,7427,7428,7429,7430,7431,7432,7433,7434,7435,7436,7437,7438,7439,7440,7441,7442,7443,7444,7445,7446,7447,7448,7449,7450,7451,7452,7453,7454,7455,7456,7457,7458,7459,7460,7461,7462,7463,7464,7465,7466,7467,7468,7469,7470,7471,7472,7473,7474,7475,7476,7477,7478,7479,7480,7481,7482,7483,7484,7485,7486,7487,7488,7489,7490,7491,7492,7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,7503,7504,7505,7506,7507,7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519,7520,7521,7522,7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535,7536,7537,7538,7539,7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,7550,7551,7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,7566,7567,7568,7569,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,7580,7581,7582,7583,7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,7595,7596,7597,7598,7599,7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,7610,7611,7612,7613,7614,7615,7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690,7691,7692,7693,7694,7695,7696,7697,7698,7699,7700,7701,7702,7703,7704,7705,7706,7707,7708,7709,7710,7711,7712,7713,7714,7715,7716,7717,7718,7719,7720,7721,7722,7723,7724,7725,7726,7727,7728,7729,7730,7731,7732,7733,7734,7735,7736,7737,7738,7739,7740,7741,7742,7743,7744,7745,7746,7747,7748,7749,7750,7751,7752,7753,7754,7755,7756,7757,7758,7759,7760,7761,7762,7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,7777,7778,7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791,7792,7793,7794,7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,7806,7807,7808,7809,7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,7824,7825,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839,7840,7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855,7856,7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871,7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887,7888,7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903,7904,7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919,7920,7921,7922,7923,7924,7925,7926,7927,7928,7929,7930,7931,7932,7933,7934,7935,7936,7937,7938,7939,7940,7941,7942,7943,7944,7945,7946,7947,7948,7949,7950,7951,7952,7953,7954,7955,7956,7957,7960,7961,7962,7963,7964,7965,7968,7969,7970,7971,7972,7973,7974,7975,7976,7977,7978,7979,7980,7981,7982,7983,7984,7985,7986,7987,7988,7989,7990,7991,7992,7993,7994,7995,7996,7997,7998,7999,8000,8001,8002,8003,8004,8005,8008,8009,8010,8011,8012,8013,8016,8017,8018,8019,8020,8021,8022,8023,8025,8027,8029,8031,8032,8033,8034,8035,8036,8037,8038,8039,8040,8041,8042,8043,8044,8045,8046,8047,8048,8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111,8112,8113,8114,8115,8116,8118,8119,8120,8121,8122,8123,8124,8126,8130,8131,8132,8134,8135,8136,8137,8138,8139,8140,8144,8145,8146,8147,8150,8151,8152,8153,8154,8155,8160,8161,8162,8163,8164,8165,8166,8167,8168,8169,8170,8171,8172,8178,8179,8180,8182,8183,8184,8185,8186,8187,8188,8305,8319,8336,8337,8338,8339,8340,8341,8342,8343,8344,8345,8346,8347,8348,8450,8455,8458,8459,8460,8461,8462,8463,8464,8465,8466,8467,8469,8473,8474,8475,8476,8477,8484,8486,8488,8490,8491,8492,8493,8495,8496,8497,8498,8499,8500,8501,8502,8503,8504,8505,8508,8509,8510,8511,8517,8518,8519,8520,8521,8526,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,8555,8556,8557,8558,8559,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,8570,8571,8572,8573,8574,8575,8576,8577,8578,8579,8580,8581,8582,8583,8584,11264,11265,11266,11267,11268,11269,11270,11271,11272,11273,11274,11275,11276,11277,11278,11279,11280,11281,11282,11283,11284,11285,11286,11287,11288,11289,11290,11291,11292,11293,11294,11295,11296,11297,11298,11299,11300,11301,11302,11303,11304,11305,11306,11307,11308,11309,11310,11312,11313,11314,11315,11316,11317,11318,11319,11320,11321,11322,11323,11324,11325,11326,11327,11328,11329,11330,11331,11332,11333,11334,11335,11336,11337,11338,11339,11340,11341,11342,11343,11344,11345,11346,11347,11348,11349,11350,11351,11352,11353,11354,11355,11356,11357,11358,11360,11361,11362,11363,11364,11365,11366,11367,11368,11369,11370,11371,11372,11373,11374,11375,11376,11377,11378,11379,11380,11381,11382,11383,11384,11385,11386,11387,11388,11389,11390,11391,11392,11393,11394,11395,11396,11397,11398,11399,11400,11401,11402,11403,11404,11405,11406,11407,11408,11409,11410,11411,11412,11413,11414,11415,11416,11417,11418,11419,11420,11421,11422,11423,11424,11425,11426,11427,11428,11429,11430,11431,11432,11433,11434,11435,11436,11437,11438,11439,11440,11441,11442,11443,11444,11445,11446,11447,11448,11449,11450,11451,11452,11453,11454,11455,11456,11457,11458,11459,11460,11461,11462,11463,11464,11465,11466,11467,11468,11469,11470,11471,11472,11473,11474,11475,11476,11477,11478,11479,11480,11481,11482,11483,11484,11485,11486,11487,11488,11489,11490,11491,11492,11499,11500,11501,11502,11506,11507,11520,11521,11522,11523,11524,11525,11526,11527,11528,11529,11530,11531,11532,11533,11534,11535,11536,11537,11538,11539,11540,11541,11542,11543,11544,11545,11546,11547,11548,11549,11550,11551,11552,11553,11554,11555,11556,11557,11559,11565,11568,11569,11570,11571,11572,11573,11574,11575,11576,11577,11578,11579,11580,11581,11582,11583,11584,11585,11586,11587,11588,11589,11590,11591,11592,11593,11594,11595,11596,11597,11598,11599,11600,11601,11602,11603,11604,11605,11606,11607,11608,11609,11610,11611,11612,11613,11614,11615,11616,11617,11618,11619,11620,11621,11622,11623,11631,11648,11649,11650,11651,11652,11653,11654,11655,11656,11657,11658,11659,11660,11661,11662,11663,11664,11665,11666,11667,11668,11669,11670,11680,11681,11682,11683,11684,11685,11686,11688,11689,11690,11691,11692,11693,11694,11696,11697,11698,11699,11700,11701,11702,11704,11705,11706,11707,11708,11709,11710,11712,11713,11714,11715,11716,11717,11718,11720,11721,11722,11723,11724,11725,11726,11728,11729,11730,11731,11732,11733,11734,11736,11737,11738,11739,11740,11741,11742,11823,12293,12294,12295,12321,12322,12323,12324,12325,12326,12327,12328,12329,12337,12338,12339,12340,12341,12344,12345,12346,12347,12348,12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,12435,12436,12437,12438,12445,12446,12447,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,12535,12536,12537,12538,12540,12541,12542,12543,12549,12550,12551,12552,12553,12554,12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,12570,12571,12572,12573,12574,12575,12576,12577,12578,12579,12580,12581,12582,12583,12584,12585,12586,12587,12588,12589,12593,12594,12595,12596,12597,12598,12599,12600,12601,12602,12603,12604,12605,12606,12607,12608,12609,12610,12611,12612,12613,12614,12615,12616,12617,12618,12619,12620,12621,12622,12623,12624,12625,12626,12627,12628,12629,12630,12631,12632,12633,12634,12635,12636,12637,12638,12639,12640,12641,12642,12643,12644,12645,12646,12647,12648,12649,12650,12651,12652,12653,12654,12655,12656,12657,12658,12659,12660,12661,12662,12663,12664,12665,12666,12667,12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679,12680,12681,12682,12683,12684,12685,12686,12704,12705,12706,12707,12708,12709,12710,12711,12712,12713,12714,12715,12716,12717,12718,12719,12720,12721,12722,12723,12724,12725,12726,12727,12728,12729,12730,12784,12785,12786,12787,12788,12789,12790,12791,12792,12793,12794,12795,12796,12797,12798,12799,13312,13313,13314,13315,13316,13317,13318,13319,13320,13321,13322,13323,13324,13325,13326,13327,13328,13329,13330,13331,13332,13333,13334,13335,13336,13337,13338,13339,13340,13341,13342,13343,13344,13345,13346,13347,13348,13349,13350,13351,13352,13353,13354,13355,13356,13357,13358,13359,13360,13361,13362,13363,13364,13365,13366,13367,13368,13369,13370,13371,13372,13373,13374,13375,13376,13377,13378,13379,13380,13381,13382,13383,13384,13385,13386,13387,13388,13389,13390,13391,13392,13393,13394,13395,13396,13397,13398,13399,13400,13401,13402,13403,13404,13405,13406,13407,13408,13409,13410,13411,13412,13413,13414,13415,13416,13417,13418,13419,13420,13421,13422,13423,13424,13425,13426,13427,13428,13429,13430,13431,13432,13433,13434,13435,13436,13437,13438,13439,13440,13441,13442,13443,13444,13445,13446,13447,13448,13449,13450,13451,13452,13453,13454,13455,13456,13457,13458,13459,13460,13461,13462,13463,13464,13465,13466,13467,13468,13469,13470,13471,13472,13473,13474,13475,13476,13477,13478,13479,13480,13481,13482,13483,13484,13485,13486,13487,13488,13489,13490,13491,13492,13493,13494,13495,13496,13497,13498,13499,13500,13501,13502,13503,13504,13505,13506,13507,13508,13509,13510,13511,13512,13513,13514,13515,13516,13517,13518,13519,13520,13521,13522,13523,13524,13525,13526,13527,13528,13529,13530,13531,13532,13533,13534,13535,13536,13537,13538,13539,13540,13541,13542,13543,13544,13545,13546,13547,13548,13549,13550,13551,13552,13553,13554,13555,13556,13557,13558,13559,13560,13561,13562,13563,13564,13565,13566,13567,13568,13569,13570,13571,13572,13573,13574,13575,13576,13577,13578,13579,13580,13581,13582,13583,13584,13585,13586,13587,13588,13589,13590,13591,13592,13593,13594,13595,13596,13597,13598,13599,13600,13601,13602,13603,13604,13605,13606,13607,13608,13609,13610,13611,13612,13613,13614,13615,13616,13617,13618,13619,13620,13621,13622,13623,13624,13625,13626,13627,13628,13629,13630,13631,13632,13633,13634,13635,13636,13637,13638,13639,13640,13641,13642,13643,13644,13645,13646,13647,13648,13649,13650,13651,13652,13653,13654,13655,13656,13657,13658,13659,13660,13661,13662,13663,13664,13665,13666,13667,13668,13669,13670,13671,13672,13673,13674,13675,13676,13677,13678,13679,13680,13681,13682,13683,13684,13685,13686,13687,13688,13689,13690,13691,13692,13693,13694,13695,13696,13697,13698,13699,13700,13701,13702,13703,13704,13705,13706,13707,13708,13709,13710,13711,13712,13713,13714,13715,13716,13717,13718,13719,13720,13721,13722,13723,13724,13725,13726,13727,13728,13729,13730,13731,13732,13733,13734,13735,13736,13737,13738,13739,13740,13741,13742,13743,13744,13745,13746,13747,13748,13749,13750,13751,13752,13753,13754,13755,13756,13757,13758,13759,13760,13761,13762,13763,13764,13765,13766,13767,13768,13769,13770,13771,13772,13773,13774,13775,13776,13777,13778,13779,13780,13781,13782,13783,13784,13785,13786,13787,13788,13789,13790,13791,13792,13793,13794,13795,13796,13797,13798,13799,13800,13801,13802,13803,13804,13805,13806,13807,13808,13809,13810,13811,13812,13813,13814,13815,13816,13817,13818,13819,13820,13821,13822,13823,13824,13825,13826,13827,13828,13829,13830,13831,13832,13833,13834,13835,13836,13837,13838,13839,13840,13841,13842,13843,13844,13845,13846,13847,13848,13849,13850,13851,13852,13853,13854,13855,13856,13857,13858,13859,13860,13861,13862,13863,13864,13865,13866,13867,13868,13869,13870,13871,13872,13873,13874,13875,13876,13877,13878,13879,13880,13881,13882,13883,13884,13885,13886,13887,13888,13889,13890,13891,13892,13893,13894,13895,13896,13897,13898,13899,13900,13901,13902,13903,13904,13905,13906,13907,13908,13909,13910,13911,13912,13913,13914,13915,13916,13917,13918,13919,13920,13921,13922,13923,13924,13925,13926,13927,13928,13929,13930,13931,13932,13933,13934,13935,13936,13937,13938,13939,13940,13941,13942,13943,13944,13945,13946,13947,13948,13949,13950,13951,13952,13953,13954,13955,13956,13957,13958,13959,13960,13961,13962,13963,13964,13965,13966,13967,13968,13969,13970,13971,13972,13973,13974,13975,13976,13977,13978,13979,13980,13981,13982,13983,13984,13985,13986,13987,13988,13989,13990,13991,13992,13993,13994,13995,13996,13997,13998,13999,14000,14001,14002,14003,14004,14005,14006,14007,14008,14009,14010,14011,14012,14013,14014,14015,14016,14017,14018,14019,14020,14021,14022,14023,14024,14025,14026,14027,14028,14029,14030,14031,14032,14033,14034,14035,14036,14037,14038,14039,14040,14041,14042,14043,14044,14045,14046,14047,14048,14049,14050,14051,14052,14053,14054,14055,14056,14057,14058,14059,14060,14061,14062,14063,14064,14065,14066,14067,14068,14069,14070,14071,14072,14073,14074,14075,14076,14077,14078,14079,14080,14081,14082,14083,14084,14085,14086,14087,14088,14089,14090,14091,14092,14093,14094,14095,14096,14097,14098,14099,14100,14101,14102,14103,14104,14105,14106,14107,14108,14109,14110,14111,14112,14113,14114,14115,14116,14117,14118,14119,14120,14121,14122,14123,14124,14125,14126,14127,14128,14129,14130,14131,14132,14133,14134,14135,14136,14137,14138,14139,14140,14141,14142,14143,14144,14145,14146,14147,14148,14149,14150,14151,14152,14153,14154,14155,14156,14157,14158,14159,14160,14161,14162,14163,14164,14165,14166,14167,14168,14169,14170,14171,14172,14173,14174,14175,14176,14177,14178,14179,14180,14181,14182,14183,14184,14185,14186,14187,14188,14189,14190,14191,14192,14193,14194,14195,14196,14197,14198,14199,14200,14201,14202,14203,14204,14205,14206,14207,14208,14209,14210,14211,14212,14213,14214,14215,14216,14217,14218,14219,14220,14221,14222,14223,14224,14225,14226,14227,14228,14229,14230,14231,14232,14233,14234,14235,14236,14237,14238,14239,14240,14241,14242,14243,14244,14245,14246,14247,14248,14249,14250,14251,14252,14253,14254,14255,14256,14257,14258,14259,14260,14261,14262,14263,14264,14265,14266,14267,14268,14269,14270,14271,14272,14273,14274,14275,14276,14277,14278,14279,14280,14281,14282,14283,14284,14285,14286,14287,14288,14289,14290,14291,14292,14293,14294,14295,14296,14297,14298,14299,14300,14301,14302,14303,14304,14305,14306,14307,14308,14309,14310,14311,14312,14313,14314,14315,14316,14317,14318,14319,14320,14321,14322,14323,14324,14325,14326,14327,14328,14329,14330,14331,14332,14333,14334,14335,14336,14337,14338,14339,14340,14341,14342,14343,14344,14345,14346,14347,14348,14349,14350,14351,14352,14353,14354,14355,14356,14357,14358,14359,14360,14361,14362,14363,14364,14365,14366,14367,14368,14369,14370,14371,14372,14373,14374,14375,14376,14377,14378,14379,14380,14381,14382,14383,14384,14385,14386,14387,14388,14389,14390,14391,14392,14393,14394,14395,14396,14397,14398,14399,14400,14401,14402,14403,14404,14405,14406,14407,14408,14409,14410,14411,14412,14413,14414,14415,14416,14417,14418,14419,14420,14421,14422,14423,14424,14425,14426,14427,14428,14429,14430,14431,14432,14433,14434,14435,14436,14437,14438,14439,14440,14441,14442,14443,14444,14445,14446,14447,14448,14449,14450,14451,14452,14453,14454,14455,14456,14457,14458,14459,14460,14461,14462,14463,14464,14465,14466,14467,14468,14469,14470,14471,14472,14473,14474,14475,14476,14477,14478,14479,14480,14481,14482,14483,14484,14485,14486,14487,14488,14489,14490,14491,14492,14493,14494,14495,14496,14497,14498,14499,14500,14501,14502,14503,14504,14505,14506,14507,14508,14509,14510,14511,14512,14513,14514,14515,14516,14517,14518,14519,14520,14521,14522,14523,14524,14525,14526,14527,14528,14529,14530,14531,14532,14533,14534,14535,14536,14537,14538,14539,14540,14541,14542,14543,14544,14545,14546,14547,14548,14549,14550,14551,14552,14553,14554,14555,14556,14557,14558,14559,14560,14561,14562,14563,14564,14565,14566,14567,14568,14569,14570,14571,14572,14573,14574,14575,14576,14577,14578,14579,14580,14581,14582,14583,14584,14585,14586,14587,14588,14589,14590,14591,14592,14593,14594,14595,14596,14597,14598,14599,14600,14601,14602,14603,14604,14605,14606,14607,14608,14609,14610,14611,14612,14613,14614,14615,14616,14617,14618,14619,14620,14621,14622,14623,14624,14625,14626,14627,14628,14629,14630,14631,14632,14633,14634,14635,14636,14637,14638,14639,14640,14641,14642,14643,14644,14645,14646,14647,14648,14649,14650,14651,14652,14653,14654,14655,14656,14657,14658,14659,14660,14661,14662,14663,14664,14665,14666,14667,14668,14669,14670,14671,14672,14673,14674,14675,14676,14677,14678,14679,14680,14681,14682,14683,14684,14685,14686,14687,14688,14689,14690,14691,14692,14693,14694,14695,14696,14697,14698,14699,14700,14701,14702,14703,14704,14705,14706,14707,14708,14709,14710,14711,14712,14713,14714,14715,14716,14717,14718,14719,14720,14721,14722,14723,14724,14725,14726,14727,14728,14729,14730,14731,14732,14733,14734,14735,14736,14737,14738,14739,14740,14741,14742,14743,14744,14745,14746,14747,14748,14749,14750,14751,14752,14753,14754,14755,14756,14757,14758,14759,14760,14761,14762,14763,14764,14765,14766,14767,14768,14769,14770,14771,14772,14773,14774,14775,14776,14777,14778,14779,14780,14781,14782,14783,14784,14785,14786,14787,14788,14789,14790,14791,14792,14793,14794,14795,14796,14797,14798,14799,14800,14801,14802,14803,14804,14805,14806,14807,14808,14809,14810,14811,14812,14813,14814,14815,14816,14817,14818,14819,14820,14821,14822,14823,14824,14825,14826,14827,14828,14829,14830,14831,14832,14833,14834,14835,14836,14837,14838,14839,14840,14841,14842,14843,14844,14845,14846,14847,14848,14849,14850,14851,14852,14853,14854,14855,14856,14857,14858,14859,14860,14861,14862,14863,14864,14865,14866,14867,14868,14869,14870,14871,14872,14873,14874,14875,14876,14877,14878,14879,14880,14881,14882,14883,14884,14885,14886,14887,14888,14889,14890,14891,14892,14893,14894,14895,14896,14897,14898,14899,14900,14901,14902,14903,14904,14905,14906,14907,14908,14909,14910,14911,14912,14913,14914,14915,14916,14917,14918,14919,14920,14921,14922,14923,14924,14925,14926,14927,14928,14929,14930,14931,14932,14933,14934,14935,14936,14937,14938,14939,14940,14941,14942,14943,14944,14945,14946,14947,14948,14949,14950,14951,14952,14953,14954,14955,14956,14957,14958,14959,14960,14961,14962,14963,14964,14965,14966,14967,14968,14969,14970,14971,14972,14973,14974,14975,14976,14977,14978,14979,14980,14981,14982,14983,14984,14985,14986,14987,14988,14989,14990,14991,14992,14993,14994,14995,14996,14997,14998,14999,15000,15001,15002,15003,15004,15005,15006,15007,15008,15009,15010,15011,15012,15013,15014,15015,15016,15017,15018,15019,15020,15021,15022,15023,15024,15025,15026,15027,15028,15029,15030,15031,15032,15033,15034,15035,15036,15037,15038,15039,15040,15041,15042,15043,15044,15045,15046,15047,15048,15049,15050,15051,15052,15053,15054,15055,15056,15057,15058,15059,15060,15061,15062,15063,15064,15065,15066,15067,15068,15069,15070,15071,15072,15073,15074,15075,15076,15077,15078,15079,15080,15081,15082,15083,15084,15085,15086,15087,15088,15089,15090,15091,15092,15093,15094,15095,15096,15097,15098,15099,15100,15101,15102,15103,15104,15105,15106,15107,15108,15109,15110,15111,15112,15113,15114,15115,15116,15117,15118,15119,15120,15121,15122,15123,15124,15125,15126,15127,15128,15129,15130,15131,15132,15133,15134,15135,15136,15137,15138,15139,15140,15141,15142,15143,15144,15145,15146,15147,15148,15149,15150,15151,15152,15153,15154,15155,15156,15157,15158,15159,15160,15161,15162,15163,15164,15165,15166,15167,15168,15169,15170,15171,15172,15173,15174,15175,15176,15177,15178,15179,15180,15181,15182,15183,15184,15185,15186,15187,15188,15189,15190,15191,15192,15193,15194,15195,15196,15197,15198,15199,15200,15201,15202,15203,15204,15205,15206,15207,15208,15209,15210,15211,15212,15213,15214,15215,15216,15217,15218,15219,15220,15221,15222,15223,15224,15225,15226,15227,15228,15229,15230,15231,15232,15233,15234,15235,15236,15237,15238,15239,15240,15241,15242,15243,15244,15245,15246,15247,15248,15249,15250,15251,15252,15253,15254,15255,15256,15257,15258,15259,15260,15261,15262,15263,15264,15265,15266,15267,15268,15269,15270,15271,15272,15273,15274,15275,15276,15277,15278,15279,15280,15281,15282,15283,15284,15285,15286,15287,15288,15289,15290,15291,15292,15293,15294,15295,15296,15297,15298,15299,15300,15301,15302,15303,15304,15305,15306,15307,15308,15309,15310,15311,15312,15313,15314,15315,15316,15317,15318,15319,15320,15321,15322,15323,15324,15325,15326,15327,15328,15329,15330,15331,15332,15333,15334,15335,15336,15337,15338,15339,15340,15341,15342,15343,15344,15345,15346,15347,15348,15349,15350,15351,15352,15353,15354,15355,15356,15357,15358,15359,15360,15361,15362,15363,15364,15365,15366,15367,15368,15369,15370,15371,15372,15373,15374,15375,15376,15377,15378,15379,15380,15381,15382,15383,15384,15385,15386,15387,15388,15389,15390,15391,15392,15393,15394,15395,15396,15397,15398,15399,15400,15401,15402,15403,15404,15405,15406,15407,15408,15409,15410,15411,15412,15413,15414,15415,15416,15417,15418,15419,15420,15421,15422,15423,15424,15425,15426,15427,15428,15429,15430,15431,15432,15433,15434,15435,15436,15437,15438,15439,15440,15441,15442,15443,15444,15445,15446,15447,15448,15449,15450,15451,15452,15453,15454,15455,15456,15457,15458,15459,15460,15461,15462,15463,15464,15465,15466,15467,15468,15469,15470,15471,15472,15473,15474,15475,15476,15477,15478,15479,15480,15481,15482,15483,15484,15485,15486,15487,15488,15489,15490,15491,15492,15493,15494,15495,15496,15497,15498,15499,15500,15501,15502,15503,15504,15505,15506,15507,15508,15509,15510,15511,15512,15513,15514,15515,15516,15517,15518,15519,15520,15521,15522,15523,15524,15525,15526,15527,15528,15529,15530,15531,15532,15533,15534,15535,15536,15537,15538,15539,15540,15541,15542,15543,15544,15545,15546,15547,15548,15549,15550,15551,15552,15553,15554,15555,15556,15557,15558,15559,15560,15561,15562,15563,15564,15565,15566,15567,15568,15569,15570,15571,15572,15573,15574,15575,15576,15577,15578,15579,15580,15581,15582,15583,15584,15585,15586,15587,15588,15589,15590,15591,15592,15593,15594,15595,15596,15597,15598,15599,15600,15601,15602,15603,15604,15605,15606,15607,15608,15609,15610,15611,15612,15613,15614,15615,15616,15617,15618,15619,15620,15621,15622,15623,15624,15625,15626,15627,15628,15629,15630,15631,15632,15633,15634,15635,15636,15637,15638,15639,15640,15641,15642,15643,15644,15645,15646,15647,15648,15649,15650,15651,15652,15653,15654,15655,15656,15657,15658,15659,15660,15661,15662,15663,15664,15665,15666,15667,15668,15669,15670,15671,15672,15673,15674,15675,15676,15677,15678,15679,15680,15681,15682,15683,15684,15685,15686,15687,15688,15689,15690,15691,15692,15693,15694,15695,15696,15697,15698,15699,15700,15701,15702,15703,15704,15705,15706,15707,15708,15709,15710,15711,15712,15713,15714,15715,15716,15717,15718,15719,15720,15721,15722,15723,15724,15725,15726,15727,15728,15729,15730,15731,15732,15733,15734,15735,15736,15737,15738,15739,15740,15741,15742,15743,15744,15745,15746,15747,15748,15749,15750,15751,15752,15753,15754,15755,15756,15757,15758,15759,15760,15761,15762,15763,15764,15765,15766,15767,15768,15769,15770,15771,15772,15773,15774,15775,15776,15777,15778,15779,15780,15781,15782,15783,15784,15785,15786,15787,15788,15789,15790,15791,15792,15793,15794,15795,15796,15797,15798,15799,15800,15801,15802,15803,15804,15805,15806,15807,15808,15809,15810,15811,15812,15813,15814,15815,15816,15817,15818,15819,15820,15821,15822,15823,15824,15825,15826,15827,15828,15829,15830,15831,15832,15833,15834,15835,15836,15837,15838,15839,15840,15841,15842,15843,15844,15845,15846,15847,15848,15849,15850,15851,15852,15853,15854,15855,15856,15857,15858,15859,15860,15861,15862,15863,15864,15865,15866,15867,15868,15869,15870,15871,15872,15873,15874,15875,15876,15877,15878,15879,15880,15881,15882,15883,15884,15885,15886,15887,15888,15889,15890,15891,15892,15893,15894,15895,15896,15897,15898,15899,15900,15901,15902,15903,15904,15905,15906,15907,15908,15909,15910,15911,15912,15913,15914,15915,15916,15917,15918,15919,15920,15921,15922,15923,15924,15925,15926,15927,15928,15929,15930,15931,15932,15933,15934,15935,15936,15937,15938,15939,15940,15941,15942,15943,15944,15945,15946,15947,15948,15949,15950,15951,15952,15953,15954,15955,15956,15957,15958,15959,15960,15961,15962,15963,15964,15965,15966,15967,15968,15969,15970,15971,15972,15973,15974,15975,15976,15977,15978,15979,15980,15981,15982,15983,15984,15985,15986,15987,15988,15989,15990,15991,15992,15993,15994,15995,15996,15997,15998,15999,16000,16001,16002,16003,16004,16005,16006,16007,16008,16009,16010,16011,16012,16013,16014,16015,16016,16017,16018,16019,16020,16021,16022,16023,16024,16025,16026,16027,16028,16029,16030,16031,16032,16033,16034,16035,16036,16037,16038,16039,16040,16041,16042,16043,16044,16045,16046,16047,16048,16049,16050,16051,16052,16053,16054,16055,16056,16057,16058,16059,16060,16061,16062,16063,16064,16065,16066,16067,16068,16069,16070,16071,16072,16073,16074,16075,16076,16077,16078,16079,16080,16081,16082,16083,16084,16085,16086,16087,16088,16089,16090,16091,16092,16093,16094,16095,16096,16097,16098,16099,16100,16101,16102,16103,16104,16105,16106,16107,16108,16109,16110,16111,16112,16113,16114,16115,16116,16117,16118,16119,16120,16121,16122,16123,16124,16125,16126,16127,16128,16129,16130,16131,16132,16133,16134,16135,16136,16137,16138,16139,16140,16141,16142,16143,16144,16145,16146,16147,16148,16149,16150,16151,16152,16153,16154,16155,16156,16157,16158,16159,16160,16161,16162,16163,16164,16165,16166,16167,16168,16169,16170,16171,16172,16173,16174,16175,16176,16177,16178,16179,16180,16181,16182,16183,16184,16185,16186,16187,16188,16189,16190,16191,16192,16193,16194,16195,16196,16197,16198,16199,16200,16201,16202,16203,16204,16205,16206,16207,16208,16209,16210,16211,16212,16213,16214,16215,16216,16217,16218,16219,16220,16221,16222,16223,16224,16225,16226,16227,16228,16229,16230,16231,16232,16233,16234,16235,16236,16237,16238,16239,16240,16241,16242,16243,16244,16245,16246,16247,16248,16249,16250,16251,16252,16253,16254,16255,16256,16257,16258,16259,16260,16261,16262,16263,16264,16265,16266,16267,16268,16269,16270,16271,16272,16273,16274,16275,16276,16277,16278,16279,16280,16281,16282,16283,16284,16285,16286,16287,16288,16289,16290,16291,16292,16293,16294,16295,16296,16297,16298,16299,16300,16301,16302,16303,16304,16305,16306,16307,16308,16309,16310,16311,16312,16313,16314,16315,16316,16317,16318,16319,16320,16321,16322,16323,16324,16325,16326,16327,16328,16329,16330,16331,16332,16333,16334,16335,16336,16337,16338,16339,16340,16341,16342,16343,16344,16345,16346,16347,16348,16349,16350,16351,16352,16353,16354,16355,16356,16357,16358,16359,16360,16361,16362,16363,16364,16365,16366,16367,16368,16369,16370,16371,16372,16373,16374,16375,16376,16377,16378,16379,16380,16381,16382,16383,16384,16385,16386,16387,16388,16389,16390,16391,16392,16393,16394,16395,16396,16397,16398,16399,16400,16401,16402,16403,16404,16405,16406,16407,16408,16409,16410,16411,16412,16413,16414,16415,16416,16417,16418,16419,16420,16421,16422,16423,16424,16425,16426,16427,16428,16429,16430,16431,16432,16433,16434,16435,16436,16437,16438,16439,16440,16441,16442,16443,16444,16445,16446,16447,16448,16449,16450,16451,16452,16453,16454,16455,16456,16457,16458,16459,16460,16461,16462,16463,16464,16465,16466,16467,16468,16469,16470,16471,16472,16473,16474,16475,16476,16477,16478,16479,16480,16481,16482,16483,16484,16485,16486,16487,16488,16489,16490,16491,16492,16493,16494,16495,16496,16497,16498,16499,16500,16501,16502,16503,16504,16505,16506,16507,16508,16509,16510,16511,16512,16513,16514,16515,16516,16517,16518,16519,16520,16521,16522,16523,16524,16525,16526,16527,16528,16529,16530,16531,16532,16533,16534,16535,16536,16537,16538,16539,16540,16541,16542,16543,16544,16545,16546,16547,16548,16549,16550,16551,16552,16553,16554,16555,16556,16557,16558,16559,16560,16561,16562,16563,16564,16565,16566,16567,16568,16569,16570,16571,16572,16573,16574,16575,16576,16577,16578,16579,16580,16581,16582,16583,16584,16585,16586,16587,16588,16589,16590,16591,16592,16593,16594,16595,16596,16597,16598,16599,16600,16601,16602,16603,16604,16605,16606,16607,16608,16609,16610,16611,16612,16613,16614,16615,16616,16617,16618,16619,16620,16621,16622,16623,16624,16625,16626,16627,16628,16629,16630,16631,16632,16633,16634,16635,16636,16637,16638,16639,16640,16641,16642,16643,16644,16645,16646,16647,16648,16649,16650,16651,16652,16653,16654,16655,16656,16657,16658,16659,16660,16661,16662,16663,16664,16665,16666,16667,16668,16669,16670,16671,16672,16673,16674,16675,16676,16677,16678,16679,16680,16681,16682,16683,16684,16685,16686,16687,16688,16689,16690,16691,16692,16693,16694,16695,16696,16697,16698,16699,16700,16701,16702,16703,16704,16705,16706,16707,16708,16709,16710,16711,16712,16713,16714,16715,16716,16717,16718,16719,16720,16721,16722,16723,16724,16725,16726,16727,16728,16729,16730,16731,16732,16733,16734,16735,16736,16737,16738,16739,16740,16741,16742,16743,16744,16745,16746,16747,16748,16749,16750,16751,16752,16753,16754,16755,16756,16757,16758,16759,16760,16761,16762,16763,16764,16765,16766,16767,16768,16769,16770,16771,16772,16773,16774,16775,16776,16777,16778,16779,16780,16781,16782,16783,16784,16785,16786,16787,16788,16789,16790,16791,16792,16793,16794,16795,16796,16797,16798,16799,16800,16801,16802,16803,16804,16805,16806,16807,16808,16809,16810,16811,16812,16813,16814,16815,16816,16817,16818,16819,16820,16821,16822,16823,16824,16825,16826,16827,16828,16829,16830,16831,16832,16833,16834,16835,16836,16837,16838,16839,16840,16841,16842,16843,16844,16845,16846,16847,16848,16849,16850,16851,16852,16853,16854,16855,16856,16857,16858,16859,16860,16861,16862,16863,16864,16865,16866,16867,16868,16869,16870,16871,16872,16873,16874,16875,16876,16877,16878,16879,16880,16881,16882,16883,16884,16885,16886,16887,16888,16889,16890,16891,16892,16893,16894,16895,16896,16897,16898,16899,16900,16901,16902,16903,16904,16905,16906,16907,16908,16909,16910,16911,16912,16913,16914,16915,16916,16917,16918,16919,16920,16921,16922,16923,16924,16925,16926,16927,16928,16929,16930,16931,16932,16933,16934,16935,16936,16937,16938,16939,16940,16941,16942,16943,16944,16945,16946,16947,16948,16949,16950,16951,16952,16953,16954,16955,16956,16957,16958,16959,16960,16961,16962,16963,16964,16965,16966,16967,16968,16969,16970,16971,16972,16973,16974,16975,16976,16977,16978,16979,16980,16981,16982,16983,16984,16985,16986,16987,16988,16989,16990,16991,16992,16993,16994,16995,16996,16997,16998,16999,17000,17001,17002,17003,17004,17005,17006,17007,17008,17009,17010,17011,17012,17013,17014,17015,17016,17017,17018,17019,17020,17021,17022,17023,17024,17025,17026,17027,17028,17029,17030,17031,17032,17033,17034,17035,17036,17037,17038,17039,17040,17041,17042,17043,17044,17045,17046,17047,17048,17049,17050,17051,17052,17053,17054,17055,17056,17057,17058,17059,17060,17061,17062,17063,17064,17065,17066,17067,17068,17069,17070,17071,17072,17073,17074,17075,17076,17077,17078,17079,17080,17081,17082,17083,17084,17085,17086,17087,17088,17089,17090,17091,17092,17093,17094,17095,17096,17097,17098,17099,17100,17101,17102,17103,17104,17105,17106,17107,17108,17109,17110,17111,17112,17113,17114,17115,17116,17117,17118,17119,17120,17121,17122,17123,17124,17125,17126,17127,17128,17129,17130,17131,17132,17133,17134,17135,17136,17137,17138,17139,17140,17141,17142,17143,17144,17145,17146,17147,17148,17149,17150,17151,17152,17153,17154,17155,17156,17157,17158,17159,17160,17161,17162,17163,17164,17165,17166,17167,17168,17169,17170,17171,17172,17173,17174,17175,17176,17177,17178,17179,17180,17181,17182,17183,17184,17185,17186,17187,17188,17189,17190,17191,17192,17193,17194,17195,17196,17197,17198,17199,17200,17201,17202,17203,17204,17205,17206,17207,17208,17209,17210,17211,17212,17213,17214,17215,17216,17217,17218,17219,17220,17221,17222,17223,17224,17225,17226,17227,17228,17229,17230,17231,17232,17233,17234,17235,17236,17237,17238,17239,17240,17241,17242,17243,17244,17245,17246,17247,17248,17249,17250,17251,17252,17253,17254,17255,17256,17257,17258,17259,17260,17261,17262,17263,17264,17265,17266,17267,17268,17269,17270,17271,17272,17273,17274,17275,17276,17277,17278,17279,17280,17281,17282,17283,17284,17285,17286,17287,17288,17289,17290,17291,17292,17293,17294,17295,17296,17297,17298,17299,17300,17301,17302,17303,17304,17305,17306,17307,17308,17309,17310,17311,17312,17313,17314,17315,17316,17317,17318,17319,17320,17321,17322,17323,17324,17325,17326,17327,17328,17329,17330,17331,17332,17333,17334,17335,17336,17337,17338,17339,17340,17341,17342,17343,17344,17345,17346,17347,17348,17349,17350,17351,17352,17353,17354,17355,17356,17357,17358,17359,17360,17361,17362,17363,17364,17365,17366,17367,17368,17369,17370,17371,17372,17373,17374,17375,17376,17377,17378,17379,17380,17381,17382,17383,17384,17385,17386,17387,17388,17389,17390,17391,17392,17393,17394,17395,17396,17397,17398,17399,17400,17401,17402,17403,17404,17405,17406,17407,17408,17409,17410,17411,17412,17413,17414,17415,17416,17417,17418,17419,17420,17421,17422,17423,17424,17425,17426,17427,17428,17429,17430,17431,17432,17433,17434,17435,17436,17437,17438,17439,17440,17441,17442,17443,17444,17445,17446,17447,17448,17449,17450,17451,17452,17453,17454,17455,17456,17457,17458,17459,17460,17461,17462,17463,17464,17465,17466,17467,17468,17469,17470,17471,17472,17473,17474,17475,17476,17477,17478,17479,17480,17481,17482,17483,17484,17485,17486,17487,17488,17489,17490,17491,17492,17493,17494,17495,17496,17497,17498,17499,17500,17501,17502,17503,17504,17505,17506,17507,17508,17509,17510,17511,17512,17513,17514,17515,17516,17517,17518,17519,17520,17521,17522,17523,17524,17525,17526,17527,17528,17529,17530,17531,17532,17533,17534,17535,17536,17537,17538,17539,17540,17541,17542,17543,17544,17545,17546,17547,17548,17549,17550,17551,17552,17553,17554,17555,17556,17557,17558,17559,17560,17561,17562,17563,17564,17565,17566,17567,17568,17569,17570,17571,17572,17573,17574,17575,17576,17577,17578,17579,17580,17581,17582,17583,17584,17585,17586,17587,17588,17589,17590,17591,17592,17593,17594,17595,17596,17597,17598,17599,17600,17601,17602,17603,17604,17605,17606,17607,17608,17609,17610,17611,17612,17613,17614,17615,17616,17617,17618,17619,17620,17621,17622,17623,17624,17625,17626,17627,17628,17629,17630,17631,17632,17633,17634,17635,17636,17637,17638,17639,17640,17641,17642,17643,17644,17645,17646,17647,17648,17649,17650,17651,17652,17653,17654,17655,17656,17657,17658,17659,17660,17661,17662,17663,17664,17665,17666,17667,17668,17669,17670,17671,17672,17673,17674,17675,17676,17677,17678,17679,17680,17681,17682,17683,17684,17685,17686,17687,17688,17689,17690,17691,17692,17693,17694,17695,17696,17697,17698,17699,17700,17701,17702,17703,17704,17705,17706,17707,17708,17709,17710,17711,17712,17713,17714,17715,17716,17717,17718,17719,17720,17721,17722,17723,17724,17725,17726,17727,17728,17729,17730,17731,17732,17733,17734,17735,17736,17737,17738,17739,17740,17741,17742,17743,17744,17745,17746,17747,17748,17749,17750,17751,17752,17753,17754,17755,17756,17757,17758,17759,17760,17761,17762,17763,17764,17765,17766,17767,17768,17769,17770,17771,17772,17773,17774,17775,17776,17777,17778,17779,17780,17781,17782,17783,17784,17785,17786,17787,17788,17789,17790,17791,17792,17793,17794,17795,17796,17797,17798,17799,17800,17801,17802,17803,17804,17805,17806,17807,17808,17809,17810,17811,17812,17813,17814,17815,17816,17817,17818,17819,17820,17821,17822,17823,17824,17825,17826,17827,17828,17829,17830,17831,17832,17833,17834,17835,17836,17837,17838,17839,17840,17841,17842,17843,17844,17845,17846,17847,17848,17849,17850,17851,17852,17853,17854,17855,17856,17857,17858,17859,17860,17861,17862,17863,17864,17865,17866,17867,17868,17869,17870,17871,17872,17873,17874,17875,17876,17877,17878,17879,17880,17881,17882,17883,17884,17885,17886,17887,17888,17889,17890,17891,17892,17893,17894,17895,17896,17897,17898,17899,17900,17901,17902,17903,17904,17905,17906,17907,17908,17909,17910,17911,17912,17913,17914,17915,17916,17917,17918,17919,17920,17921,17922,17923,17924,17925,17926,17927,17928,17929,17930,17931,17932,17933,17934,17935,17936,17937,17938,17939,17940,17941,17942,17943,17944,17945,17946,17947,17948,17949,17950,17951,17952,17953,17954,17955,17956,17957,17958,17959,17960,17961,17962,17963,17964,17965,17966,17967,17968,17969,17970,17971,17972,17973,17974,17975,17976,17977,17978,17979,17980,17981,17982,17983,17984,17985,17986,17987,17988,17989,17990,17991,17992,17993,17994,17995,17996,17997,17998,17999,18000,18001,18002,18003,18004,18005,18006,18007,18008,18009,18010,18011,18012,18013,18014,18015,18016,18017,18018,18019,18020,18021,18022,18023,18024,18025,18026,18027,18028,18029,18030,18031,18032,18033,18034,18035,18036,18037,18038,18039,18040,18041,18042,18043,18044,18045,18046,18047,18048,18049,18050,18051,18052,18053,18054,18055,18056,18057,18058,18059,18060,18061,18062,18063,18064,18065,18066,18067,18068,18069,18070,18071,18072,18073,18074,18075,18076,18077,18078,18079,18080,18081,18082,18083,18084,18085,18086,18087,18088,18089,18090,18091,18092,18093,18094,18095,18096,18097,18098,18099,18100,18101,18102,18103,18104,18105,18106,18107,18108,18109,18110,18111,18112,18113,18114,18115,18116,18117,18118,18119,18120,18121,18122,18123,18124,18125,18126,18127,18128,18129,18130,18131,18132,18133,18134,18135,18136,18137,18138,18139,18140,18141,18142,18143,18144,18145,18146,18147,18148,18149,18150,18151,18152,18153,18154,18155,18156,18157,18158,18159,18160,18161,18162,18163,18164,18165,18166,18167,18168,18169,18170,18171,18172,18173,18174,18175,18176,18177,18178,18179,18180,18181,18182,18183,18184,18185,18186,18187,18188,18189,18190,18191,18192,18193,18194,18195,18196,18197,18198,18199,18200,18201,18202,18203,18204,18205,18206,18207,18208,18209,18210,18211,18212,18213,18214,18215,18216,18217,18218,18219,18220,18221,18222,18223,18224,18225,18226,18227,18228,18229,18230,18231,18232,18233,18234,18235,18236,18237,18238,18239,18240,18241,18242,18243,18244,18245,18246,18247,18248,18249,18250,18251,18252,18253,18254,18255,18256,18257,18258,18259,18260,18261,18262,18263,18264,18265,18266,18267,18268,18269,18270,18271,18272,18273,18274,18275,18276,18277,18278,18279,18280,18281,18282,18283,18284,18285,18286,18287,18288,18289,18290,18291,18292,18293,18294,18295,18296,18297,18298,18299,18300,18301,18302,18303,18304,18305,18306,18307,18308,18309,18310,18311,18312,18313,18314,18315,18316,18317,18318,18319,18320,18321,18322,18323,18324,18325,18326,18327,18328,18329,18330,18331,18332,18333,18334,18335,18336,18337,18338,18339,18340,18341,18342,18343,18344,18345,18346,18347,18348,18349,18350,18351,18352,18353,18354,18355,18356,18357,18358,18359,18360,18361,18362,18363,18364,18365,18366,18367,18368,18369,18370,18371,18372,18373,18374,18375,18376,18377,18378,18379,18380,18381,18382,18383,18384,18385,18386,18387,18388,18389,18390,18391,18392,18393,18394,18395,18396,18397,18398,18399,18400,18401,18402,18403,18404,18405,18406,18407,18408,18409,18410,18411,18412,18413,18414,18415,18416,18417,18418,18419,18420,18421,18422,18423,18424,18425,18426,18427,18428,18429,18430,18431,18432,18433,18434,18435,18436,18437,18438,18439,18440,18441,18442,18443,18444,18445,18446,18447,18448,18449,18450,18451,18452,18453,18454,18455,18456,18457,18458,18459,18460,18461,18462,18463,18464,18465,18466,18467,18468,18469,18470,18471,18472,18473,18474,18475,18476,18477,18478,18479,18480,18481,18482,18483,18484,18485,18486,18487,18488,18489,18490,18491,18492,18493,18494,18495,18496,18497,18498,18499,18500,18501,18502,18503,18504,18505,18506,18507,18508,18509,18510,18511,18512,18513,18514,18515,18516,18517,18518,18519,18520,18521,18522,18523,18524,18525,18526,18527,18528,18529,18530,18531,18532,18533,18534,18535,18536,18537,18538,18539,18540,18541,18542,18543,18544,18545,18546,18547,18548,18549,18550,18551,18552,18553,18554,18555,18556,18557,18558,18559,18560,18561,18562,18563,18564,18565,18566,18567,18568,18569,18570,18571,18572,18573,18574,18575,18576,18577,18578,18579,18580,18581,18582,18583,18584,18585,18586,18587,18588,18589,18590,18591,18592,18593,18594,18595,18596,18597,18598,18599,18600,18601,18602,18603,18604,18605,18606,18607,18608,18609,18610,18611,18612,18613,18614,18615,18616,18617,18618,18619,18620,18621,18622,18623,18624,18625,18626,18627,18628,18629,18630,18631,18632,18633,18634,18635,18636,18637,18638,18639,18640,18641,18642,18643,18644,18645,18646,18647,18648,18649,18650,18651,18652,18653,18654,18655,18656,18657,18658,18659,18660,18661,18662,18663,18664,18665,18666,18667,18668,18669,18670,18671,18672,18673,18674,18675,18676,18677,18678,18679,18680,18681,18682,18683,18684,18685,18686,18687,18688,18689,18690,18691,18692,18693,18694,18695,18696,18697,18698,18699,18700,18701,18702,18703,18704,18705,18706,18707,18708,18709,18710,18711,18712,18713,18714,18715,18716,18717,18718,18719,18720,18721,18722,18723,18724,18725,18726,18727,18728,18729,18730,18731,18732,18733,18734,18735,18736,18737,18738,18739,18740,18741,18742,18743,18744,18745,18746,18747,18748,18749,18750,18751,18752,18753,18754,18755,18756,18757,18758,18759,18760,18761,18762,18763,18764,18765,18766,18767,18768,18769,18770,18771,18772,18773,18774,18775,18776,18777,18778,18779,18780,18781,18782,18783,18784,18785,18786,18787,18788,18789,18790,18791,18792,18793,18794,18795,18796,18797,18798,18799,18800,18801,18802,18803,18804,18805,18806,18807,18808,18809,18810,18811,18812,18813,18814,18815,18816,18817,18818,18819,18820,18821,18822,18823,18824,18825,18826,18827,18828,18829,18830,18831,18832,18833,18834,18835,18836,18837,18838,18839,18840,18841,18842,18843,18844,18845,18846,18847,18848,18849,18850,18851,18852,18853,18854,18855,18856,18857,18858,18859,18860,18861,18862,18863,18864,18865,18866,18867,18868,18869,18870,18871,18872,18873,18874,18875,18876,18877,18878,18879,18880,18881,18882,18883,18884,18885,18886,18887,18888,18889,18890,18891,18892,18893,18894,18895,18896,18897,18898,18899,18900,18901,18902,18903,18904,18905,18906,18907,18908,18909,18910,18911,18912,18913,18914,18915,18916,18917,18918,18919,18920,18921,18922,18923,18924,18925,18926,18927,18928,18929,18930,18931,18932,18933,18934,18935,18936,18937,18938,18939,18940,18941,18942,18943,18944,18945,18946,18947,18948,18949,18950,18951,18952,18953,18954,18955,18956,18957,18958,18959,18960,18961,18962,18963,18964,18965,18966,18967,18968,18969,18970,18971,18972,18973,18974,18975,18976,18977,18978,18979,18980,18981,18982,18983,18984,18985,18986,18987,18988,18989,18990,18991,18992,18993,18994,18995,18996,18997,18998,18999,19000,19001,19002,19003,19004,19005,19006,19007,19008,19009,19010,19011,19012,19013,19014,19015,19016,19017,19018,19019,19020,19021,19022,19023,19024,19025,19026,19027,19028,19029,19030,19031,19032,19033,19034,19035,19036,19037,19038,19039,19040,19041,19042,19043,19044,19045,19046,19047,19048,19049,19050,19051,19052,19053,19054,19055,19056,19057,19058,19059,19060,19061,19062,19063,19064,19065,19066,19067,19068,19069,19070,19071,19072,19073,19074,19075,19076,19077,19078,19079,19080,19081,19082,19083,19084,19085,19086,19087,19088,19089,19090,19091,19092,19093,19094,19095,19096,19097,19098,19099,19100,19101,19102,19103,19104,19105,19106,19107,19108,19109,19110,19111,19112,19113,19114,19115,19116,19117,19118,19119,19120,19121,19122,19123,19124,19125,19126,19127,19128,19129,19130,19131,19132,19133,19134,19135,19136,19137,19138,19139,19140,19141,19142,19143,19144,19145,19146,19147,19148,19149,19150,19151,19152,19153,19154,19155,19156,19157,19158,19159,19160,19161,19162,19163,19164,19165,19166,19167,19168,19169,19170,19171,19172,19173,19174,19175,19176,19177,19178,19179,19180,19181,19182,19183,19184,19185,19186,19187,19188,19189,19190,19191,19192,19193,19194,19195,19196,19197,19198,19199,19200,19201,19202,19203,19204,19205,19206,19207,19208,19209,19210,19211,19212,19213,19214,19215,19216,19217,19218,19219,19220,19221,19222,19223,19224,19225,19226,19227,19228,19229,19230,19231,19232,19233,19234,19235,19236,19237,19238,19239,19240,19241,19242,19243,19244,19245,19246,19247,19248,19249,19250,19251,19252,19253,19254,19255,19256,19257,19258,19259,19260,19261,19262,19263,19264,19265,19266,19267,19268,19269,19270,19271,19272,19273,19274,19275,19276,19277,19278,19279,19280,19281,19282,19283,19284,19285,19286,19287,19288,19289,19290,19291,19292,19293,19294,19295,19296,19297,19298,19299,19300,19301,19302,19303,19304,19305,19306,19307,19308,19309,19310,19311,19312,19313,19314,19315,19316,19317,19318,19319,19320,19321,19322,19323,19324,19325,19326,19327,19328,19329,19330,19331,19332,19333,19334,19335,19336,19337,19338,19339,19340,19341,19342,19343,19344,19345,19346,19347,19348,19349,19350,19351,19352,19353,19354,19355,19356,19357,19358,19359,19360,19361,19362,19363,19364,19365,19366,19367,19368,19369,19370,19371,19372,19373,19374,19375,19376,19377,19378,19379,19380,19381,19382,19383,19384,19385,19386,19387,19388,19389,19390,19391,19392,19393,19394,19395,19396,19397,19398,19399,19400,19401,19402,19403,19404,19405,19406,19407,19408,19409,19410,19411,19412,19413,19414,19415,19416,19417,19418,19419,19420,19421,19422,19423,19424,19425,19426,19427,19428,19429,19430,19431,19432,19433,19434,19435,19436,19437,19438,19439,19440,19441,19442,19443,19444,19445,19446,19447,19448,19449,19450,19451,19452,19453,19454,19455,19456,19457,19458,19459,19460,19461,19462,19463,19464,19465,19466,19467,19468,19469,19470,19471,19472,19473,19474,19475,19476,19477,19478,19479,19480,19481,19482,19483,19484,19485,19486,19487,19488,19489,19490,19491,19492,19493,19494,19495,19496,19497,19498,19499,19500,19501,19502,19503,19504,19505,19506,19507,19508,19509,19510,19511,19512,19513,19514,19515,19516,19517,19518,19519,19520,19521,19522,19523,19524,19525,19526,19527,19528,19529,19530,19531,19532,19533,19534,19535,19536,19537,19538,19539,19540,19541,19542,19543,19544,19545,19546,19547,19548,19549,19550,19551,19552,19553,19554,19555,19556,19557,19558,19559,19560,19561,19562,19563,19564,19565,19566,19567,19568,19569,19570,19571,19572,19573,19574,19575,19576,19577,19578,19579,19580,19581,19582,19583,19584,19585,19586,19587,19588,19589,19590,19591,19592,19593,19594,19595,19596,19597,19598,19599,19600,19601,19602,19603,19604,19605,19606,19607,19608,19609,19610,19611,19612,19613,19614,19615,19616,19617,19618,19619,19620,19621,19622,19623,19624,19625,19626,19627,19628,19629,19630,19631,19632,19633,19634,19635,19636,19637,19638,19639,19640,19641,19642,19643,19644,19645,19646,19647,19648,19649,19650,19651,19652,19653,19654,19655,19656,19657,19658,19659,19660,19661,19662,19663,19664,19665,19666,19667,19668,19669,19670,19671,19672,19673,19674,19675,19676,19677,19678,19679,19680,19681,19682,19683,19684,19685,19686,19687,19688,19689,19690,19691,19692,19693,19694,19695,19696,19697,19698,19699,19700,19701,19702,19703,19704,19705,19706,19707,19708,19709,19710,19711,19712,19713,19714,19715,19716,19717,19718,19719,19720,19721,19722,19723,19724,19725,19726,19727,19728,19729,19730,19731,19732,19733,19734,19735,19736,19737,19738,19739,19740,19741,19742,19743,19744,19745,19746,19747,19748,19749,19750,19751,19752,19753,19754,19755,19756,19757,19758,19759,19760,19761,19762,19763,19764,19765,19766,19767,19768,19769,19770,19771,19772,19773,19774,19775,19776,19777,19778,19779,19780,19781,19782,19783,19784,19785,19786,19787,19788,19789,19790,19791,19792,19793,19794,19795,19796,19797,19798,19799,19800,19801,19802,19803,19804,19805,19806,19807,19808,19809,19810,19811,19812,19813,19814,19815,19816,19817,19818,19819,19820,19821,19822,19823,19824,19825,19826,19827,19828,19829,19830,19831,19832,19833,19834,19835,19836,19837,19838,19839,19840,19841,19842,19843,19844,19845,19846,19847,19848,19849,19850,19851,19852,19853,19854,19855,19856,19857,19858,19859,19860,19861,19862,19863,19864,19865,19866,19867,19868,19869,19870,19871,19872,19873,19874,19875,19876,19877,19878,19879,19880,19881,19882,19883,19884,19885,19886,19887,19888,19889,19890,19891,19892,19893,19968,19969,19970,19971,19972,19973,19974,19975,19976,19977,19978,19979,19980,19981,19982,19983,19984,19985,19986,19987,19988,19989,19990,19991,19992,19993,19994,19995,19996,19997,19998,19999,20000,20001,20002,20003,20004,20005,20006,20007,20008,20009,20010,20011,20012,20013,20014,20015,20016,20017,20018,20019,20020,20021,20022,20023,20024,20025,20026,20027,20028,20029,20030,20031,20032,20033,20034,20035,20036,20037,20038,20039,20040,20041,20042,20043,20044,20045,20046,20047,20048,20049,20050,20051,20052,20053,20054,20055,20056,20057,20058,20059,20060,20061,20062,20063,20064,20065,20066,20067,20068,20069,20070,20071,20072,20073,20074,20075,20076,20077,20078,20079,20080,20081,20082,20083,20084,20085,20086,20087,20088,20089,20090,20091,20092,20093,20094,20095,20096,20097,20098,20099,20100,20101,20102,20103,20104,20105,20106,20107,20108,20109,20110,20111,20112,20113,20114,20115,20116,20117,20118,20119,20120,20121,20122,20123,20124,20125,20126,20127,20128,20129,20130,20131,20132,20133,20134,20135,20136,20137,20138,20139,20140,20141,20142,20143,20144,20145,20146,20147,20148,20149,20150,20151,20152,20153,20154,20155,20156,20157,20158,20159,20160,20161,20162,20163,20164,20165,20166,20167,20168,20169,20170,20171,20172,20173,20174,20175,20176,20177,20178,20179,20180,20181,20182,20183,20184,20185,20186,20187,20188,20189,20190,20191,20192,20193,20194,20195,20196,20197,20198,20199,20200,20201,20202,20203,20204,20205,20206,20207,20208,20209,20210,20211,20212,20213,20214,20215,20216,20217,20218,20219,20220,20221,20222,20223,20224,20225,20226,20227,20228,20229,20230,20231,20232,20233,20234,20235,20236,20237,20238,20239,20240,20241,20242,20243,20244,20245,20246,20247,20248,20249,20250,20251,20252,20253,20254,20255,20256,20257,20258,20259,20260,20261,20262,20263,20264,20265,20266,20267,20268,20269,20270,20271,20272,20273,20274,20275,20276,20277,20278,20279,20280,20281,20282,20283,20284,20285,20286,20287,20288,20289,20290,20291,20292,20293,20294,20295,20296,20297,20298,20299,20300,20301,20302,20303,20304,20305,20306,20307,20308,20309,20310,20311,20312,20313,20314,20315,20316,20317,20318,20319,20320,20321,20322,20323,20324,20325,20326,20327,20328,20329,20330,20331,20332,20333,20334,20335,20336,20337,20338,20339,20340,20341,20342,20343,20344,20345,20346,20347,20348,20349,20350,20351,20352,20353,20354,20355,20356,20357,20358,20359,20360,20361,20362,20363,20364,20365,20366,20367,20368,20369,20370,20371,20372,20373,20374,20375,20376,20377,20378,20379,20380,20381,20382,20383,20384,20385,20386,20387,20388,20389,20390,20391,20392,20393,20394,20395,20396,20397,20398,20399,20400,20401,20402,20403,20404,20405,20406,20407,20408,20409,20410,20411,20412,20413,20414,20415,20416,20417,20418,20419,20420,20421,20422,20423,20424,20425,20426,20427,20428,20429,20430,20431,20432,20433,20434,20435,20436,20437,20438,20439,20440,20441,20442,20443,20444,20445,20446,20447,20448,20449,20450,20451,20452,20453,20454,20455,20456,20457,20458,20459,20460,20461,20462,20463,20464,20465,20466,20467,20468,20469,20470,20471,20472,20473,20474,20475,20476,20477,20478,20479,20480,20481,20482,20483,20484,20485,20486,20487,20488,20489,20490,20491,20492,20493,20494,20495,20496,20497,20498,20499,20500,20501,20502,20503,20504,20505,20506,20507,20508,20509,20510,20511,20512,20513,20514,20515,20516,20517,20518,20519,20520,20521,20522,20523,20524,20525,20526,20527,20528,20529,20530,20531,20532,20533,20534,20535,20536,20537,20538,20539,20540,20541,20542,20543,20544,20545,20546,20547,20548,20549,20550,20551,20552,20553,20554,20555,20556,20557,20558,20559,20560,20561,20562,20563,20564,20565,20566,20567,20568,20569,20570,20571,20572,20573,20574,20575,20576,20577,20578,20579,20580,20581,20582,20583,20584,20585,20586,20587,20588,20589,20590,20591,20592,20593,20594,20595,20596,20597,20598,20599,20600,20601,20602,20603,20604,20605,20606,20607,20608,20609,20610,20611,20612,20613,20614,20615,20616,20617,20618,20619,20620,20621,20622,20623,20624,20625,20626,20627,20628,20629,20630,20631,20632,20633,20634,20635,20636,20637,20638,20639,20640,20641,20642,20643,20644,20645,20646,20647,20648,20649,20650,20651,20652,20653,20654,20655,20656,20657,20658,20659,20660,20661,20662,20663,20664,20665,20666,20667,20668,20669,20670,20671,20672,20673,20674,20675,20676,20677,20678,20679,20680,20681,20682,20683,20684,20685,20686,20687,20688,20689,20690,20691,20692,20693,20694,20695,20696,20697,20698,20699,20700,20701,20702,20703,20704,20705,20706,20707,20708,20709,20710,20711,20712,20713,20714,20715,20716,20717,20718,20719,20720,20721,20722,20723,20724,20725,20726,20727,20728,20729,20730,20731,20732,20733,20734,20735,20736,20737,20738,20739,20740,20741,20742,20743,20744,20745,20746,20747,20748,20749,20750,20751,20752,20753,20754,20755,20756,20757,20758,20759,20760,20761,20762,20763,20764,20765,20766,20767,20768,20769,20770,20771,20772,20773,20774,20775,20776,20777,20778,20779,20780,20781,20782,20783,20784,20785,20786,20787,20788,20789,20790,20791,20792,20793,20794,20795,20796,20797,20798,20799,20800,20801,20802,20803,20804,20805,20806,20807,20808,20809,20810,20811,20812,20813,20814,20815,20816,20817,20818,20819,20820,20821,20822,20823,20824,20825,20826,20827,20828,20829,20830,20831,20832,20833,20834,20835,20836,20837,20838,20839,20840,20841,20842,20843,20844,20845,20846,20847,20848,20849,20850,20851,20852,20853,20854,20855,20856,20857,20858,20859,20860,20861,20862,20863,20864,20865,20866,20867,20868,20869,20870,20871,20872,20873,20874,20875,20876,20877,20878,20879,20880,20881,20882,20883,20884,20885,20886,20887,20888,20889,20890,20891,20892,20893,20894,20895,20896,20897,20898,20899,20900,20901,20902,20903,20904,20905,20906,20907,20908,20909,20910,20911,20912,20913,20914,20915,20916,20917,20918,20919,20920,20921,20922,20923,20924,20925,20926,20927,20928,20929,20930,20931,20932,20933,20934,20935,20936,20937,20938,20939,20940,20941,20942,20943,20944,20945,20946,20947,20948,20949,20950,20951,20952,20953,20954,20955,20956,20957,20958,20959,20960,20961,20962,20963,20964,20965,20966,20967,20968,20969,20970,20971,20972,20973,20974,20975,20976,20977,20978,20979,20980,20981,20982,20983,20984,20985,20986,20987,20988,20989,20990,20991,20992,20993,20994,20995,20996,20997,20998,20999,21000,21001,21002,21003,21004,21005,21006,21007,21008,21009,21010,21011,21012,21013,21014,21015,21016,21017,21018,21019,21020,21021,21022,21023,21024,21025,21026,21027,21028,21029,21030,21031,21032,21033,21034,21035,21036,21037,21038,21039,21040,21041,21042,21043,21044,21045,21046,21047,21048,21049,21050,21051,21052,21053,21054,21055,21056,21057,21058,21059,21060,21061,21062,21063,21064,21065,21066,21067,21068,21069,21070,21071,21072,21073,21074,21075,21076,21077,21078,21079,21080,21081,21082,21083,21084,21085,21086,21087,21088,21089,21090,21091,21092,21093,21094,21095,21096,21097,21098,21099,21100,21101,21102,21103,21104,21105,21106,21107,21108,21109,21110,21111,21112,21113,21114,21115,21116,21117,21118,21119,21120,21121,21122,21123,21124,21125,21126,21127,21128,21129,21130,21131,21132,21133,21134,21135,21136,21137,21138,21139,21140,21141,21142,21143,21144,21145,21146,21147,21148,21149,21150,21151,21152,21153,21154,21155,21156,21157,21158,21159,21160,21161,21162,21163,21164,21165,21166,21167,21168,21169,21170,21171,21172,21173,21174,21175,21176,21177,21178,21179,21180,21181,21182,21183,21184,21185,21186,21187,21188,21189,21190,21191,21192,21193,21194,21195,21196,21197,21198,21199,21200,21201,21202,21203,21204,21205,21206,21207,21208,21209,21210,21211,21212,21213,21214,21215,21216,21217,21218,21219,21220,21221,21222,21223,21224,21225,21226,21227,21228,21229,21230,21231,21232,21233,21234,21235,21236,21237,21238,21239,21240,21241,21242,21243,21244,21245,21246,21247,21248,21249,21250,21251,21252,21253,21254,21255,21256,21257,21258,21259,21260,21261,21262,21263,21264,21265,21266,21267,21268,21269,21270,21271,21272,21273,21274,21275,21276,21277,21278,21279,21280,21281,21282,21283,21284,21285,21286,21287,21288,21289,21290,21291,21292,21293,21294,21295,21296,21297,21298,21299,21300,21301,21302,21303,21304,21305,21306,21307,21308,21309,21310,21311,21312,21313,21314,21315,21316,21317,21318,21319,21320,21321,21322,21323,21324,21325,21326,21327,21328,21329,21330,21331,21332,21333,21334,21335,21336,21337,21338,21339,21340,21341,21342,21343,21344,21345,21346,21347,21348,21349,21350,21351,21352,21353,21354,21355,21356,21357,21358,21359,21360,21361,21362,21363,21364,21365,21366,21367,21368,21369,21370,21371,21372,21373,21374,21375,21376,21377,21378,21379,21380,21381,21382,21383,21384,21385,21386,21387,21388,21389,21390,21391,21392,21393,21394,21395,21396,21397,21398,21399,21400,21401,21402,21403,21404,21405,21406,21407,21408,21409,21410,21411,21412,21413,21414,21415,21416,21417,21418,21419,21420,21421,21422,21423,21424,21425,21426,21427,21428,21429,21430,21431,21432,21433,21434,21435,21436,21437,21438,21439,21440,21441,21442,21443,21444,21445,21446,21447,21448,21449,21450,21451,21452,21453,21454,21455,21456,21457,21458,21459,21460,21461,21462,21463,21464,21465,21466,21467,21468,21469,21470,21471,21472,21473,21474,21475,21476,21477,21478,21479,21480,21481,21482,21483,21484,21485,21486,21487,21488,21489,21490,21491,21492,21493,21494,21495,21496,21497,21498,21499,21500,21501,21502,21503,21504,21505,21506,21507,21508,21509,21510,21511,21512,21513,21514,21515,21516,21517,21518,21519,21520,21521,21522,21523,21524,21525,21526,21527,21528,21529,21530,21531,21532,21533,21534,21535,21536,21537,21538,21539,21540,21541,21542,21543,21544,21545,21546,21547,21548,21549,21550,21551,21552,21553,21554,21555,21556,21557,21558,21559,21560,21561,21562,21563,21564,21565,21566,21567,21568,21569,21570,21571,21572,21573,21574,21575,21576,21577,21578,21579,21580,21581,21582,21583,21584,21585,21586,21587,21588,21589,21590,21591,21592,21593,21594,21595,21596,21597,21598,21599,21600,21601,21602,21603,21604,21605,21606,21607,21608,21609,21610,21611,21612,21613,21614,21615,21616,21617,21618,21619,21620,21621,21622,21623,21624,21625,21626,21627,21628,21629,21630,21631,21632,21633,21634,21635,21636,21637,21638,21639,21640,21641,21642,21643,21644,21645,21646,21647,21648,21649,21650,21651,21652,21653,21654,21655,21656,21657,21658,21659,21660,21661,21662,21663,21664,21665,21666,21667,21668,21669,21670,21671,21672,21673,21674,21675,21676,21677,21678,21679,21680,21681,21682,21683,21684,21685,21686,21687,21688,21689,21690,21691,21692,21693,21694,21695,21696,21697,21698,21699,21700,21701,21702,21703,21704,21705,21706,21707,21708,21709,21710,21711,21712,21713,21714,21715,21716,21717,21718,21719,21720,21721,21722,21723,21724,21725,21726,21727,21728,21729,21730,21731,21732,21733,21734,21735,21736,21737,21738,21739,21740,21741,21742,21743,21744,21745,21746,21747,21748,21749,21750,21751,21752,21753,21754,21755,21756,21757,21758,21759,21760,21761,21762,21763,21764,21765,21766,21767,21768,21769,21770,21771,21772,21773,21774,21775,21776,21777,21778,21779,21780,21781,21782,21783,21784,21785,21786,21787,21788,21789,21790,21791,21792,21793,21794,21795,21796,21797,21798,21799,21800,21801,21802,21803,21804,21805,21806,21807,21808,21809,21810,21811,21812,21813,21814,21815,21816,21817,21818,21819,21820,21821,21822,21823,21824,21825,21826,21827,21828,21829,21830,21831,21832,21833,21834,21835,21836,21837,21838,21839,21840,21841,21842,21843,21844,21845,21846,21847,21848,21849,21850,21851,21852,21853,21854,21855,21856,21857,21858,21859,21860,21861,21862,21863,21864,21865,21866,21867,21868,21869,21870,21871,21872,21873,21874,21875,21876,21877,21878,21879,21880,21881,21882,21883,21884,21885,21886,21887,21888,21889,21890,21891,21892,21893,21894,21895,21896,21897,21898,21899,21900,21901,21902,21903,21904,21905,21906,21907,21908,21909,21910,21911,21912,21913,21914,21915,21916,21917,21918,21919,21920,21921,21922,21923,21924,21925,21926,21927,21928,21929,21930,21931,21932,21933,21934,21935,21936,21937,21938,21939,21940,21941,21942,21943,21944,21945,21946,21947,21948,21949,21950,21951,21952,21953,21954,21955,21956,21957,21958,21959,21960,21961,21962,21963,21964,21965,21966,21967,21968,21969,21970,21971,21972,21973,21974,21975,21976,21977,21978,21979,21980,21981,21982,21983,21984,21985,21986,21987,21988,21989,21990,21991,21992,21993,21994,21995,21996,21997,21998,21999,22000,22001,22002,22003,22004,22005,22006,22007,22008,22009,22010,22011,22012,22013,22014,22015,22016,22017,22018,22019,22020,22021,22022,22023,22024,22025,22026,22027,22028,22029,22030,22031,22032,22033,22034,22035,22036,22037,22038,22039,22040,22041,22042,22043,22044,22045,22046,22047,22048,22049,22050,22051,22052,22053,22054,22055,22056,22057,22058,22059,22060,22061,22062,22063,22064,22065,22066,22067,22068,22069,22070,22071,22072,22073,22074,22075,22076,22077,22078,22079,22080,22081,22082,22083,22084,22085,22086,22087,22088,22089,22090,22091,22092,22093,22094,22095,22096,22097,22098,22099,22100,22101,22102,22103,22104,22105,22106,22107,22108,22109,22110,22111,22112,22113,22114,22115,22116,22117,22118,22119,22120,22121,22122,22123,22124,22125,22126,22127,22128,22129,22130,22131,22132,22133,22134,22135,22136,22137,22138,22139,22140,22141,22142,22143,22144,22145,22146,22147,22148,22149,22150,22151,22152,22153,22154,22155,22156,22157,22158,22159,22160,22161,22162,22163,22164,22165,22166,22167,22168,22169,22170,22171,22172,22173,22174,22175,22176,22177,22178,22179,22180,22181,22182,22183,22184,22185,22186,22187,22188,22189,22190,22191,22192,22193,22194,22195,22196,22197,22198,22199,22200,22201,22202,22203,22204,22205,22206,22207,22208,22209,22210,22211,22212,22213,22214,22215,22216,22217,22218,22219,22220,22221,22222,22223,22224,22225,22226,22227,22228,22229,22230,22231,22232,22233,22234,22235,22236,22237,22238,22239,22240,22241,22242,22243,22244,22245,22246,22247,22248,22249,22250,22251,22252,22253,22254,22255,22256,22257,22258,22259,22260,22261,22262,22263,22264,22265,22266,22267,22268,22269,22270,22271,22272,22273,22274,22275,22276,22277,22278,22279,22280,22281,22282,22283,22284,22285,22286,22287,22288,22289,22290,22291,22292,22293,22294,22295,22296,22297,22298,22299,22300,22301,22302,22303,22304,22305,22306,22307,22308,22309,22310,22311,22312,22313,22314,22315,22316,22317,22318,22319,22320,22321,22322,22323,22324,22325,22326,22327,22328,22329,22330,22331,22332,22333,22334,22335,22336,22337,22338,22339,22340,22341,22342,22343,22344,22345,22346,22347,22348,22349,22350,22351,22352,22353,22354,22355,22356,22357,22358,22359,22360,22361,22362,22363,22364,22365,22366,22367,22368,22369,22370,22371,22372,22373,22374,22375,22376,22377,22378,22379,22380,22381,22382,22383,22384,22385,22386,22387,22388,22389,22390,22391,22392,22393,22394,22395,22396,22397,22398,22399,22400,22401,22402,22403,22404,22405,22406,22407,22408,22409,22410,22411,22412,22413,22414,22415,22416,22417,22418,22419,22420,22421,22422,22423,22424,22425,22426,22427,22428,22429,22430,22431,22432,22433,22434,22435,22436,22437,22438,22439,22440,22441,22442,22443,22444,22445,22446,22447,22448,22449,22450,22451,22452,22453,22454,22455,22456,22457,22458,22459,22460,22461,22462,22463,22464,22465,22466,22467,22468,22469,22470,22471,22472,22473,22474,22475,22476,22477,22478,22479,22480,22481,22482,22483,22484,22485,22486,22487,22488,22489,22490,22491,22492,22493,22494,22495,22496,22497,22498,22499,22500,22501,22502,22503,22504,22505,22506,22507,22508,22509,22510,22511,22512,22513,22514,22515,22516,22517,22518,22519,22520,22521,22522,22523,22524,22525,22526,22527,22528,22529,22530,22531,22532,22533,22534,22535,22536,22537,22538,22539,22540,22541,22542,22543,22544,22545,22546,22547,22548,22549,22550,22551,22552,22553,22554,22555,22556,22557,22558,22559,22560,22561,22562,22563,22564,22565,22566,22567,22568,22569,22570,22571,22572,22573,22574,22575,22576,22577,22578,22579,22580,22581,22582,22583,22584,22585,22586,22587,22588,22589,22590,22591,22592,22593,22594,22595,22596,22597,22598,22599,22600,22601,22602,22603,22604,22605,22606,22607,22608,22609,22610,22611,22612,22613,22614,22615,22616,22617,22618,22619,22620,22621,22622,22623,22624,22625,22626,22627,22628,22629,22630,22631,22632,22633,22634,22635,22636,22637,22638,22639,22640,22641,22642,22643,22644,22645,22646,22647,22648,22649,22650,22651,22652,22653,22654,22655,22656,22657,22658,22659,22660,22661,22662,22663,22664,22665,22666,22667,22668,22669,22670,22671,22672,22673,22674,22675,22676,22677,22678,22679,22680,22681,22682,22683,22684,22685,22686,22687,22688,22689,22690,22691,22692,22693,22694,22695,22696,22697,22698,22699,22700,22701,22702,22703,22704,22705,22706,22707,22708,22709,22710,22711,22712,22713,22714,22715,22716,22717,22718,22719,22720,22721,22722,22723,22724,22725,22726,22727,22728,22729,22730,22731,22732,22733,22734,22735,22736,22737,22738,22739,22740,22741,22742,22743,22744,22745,22746,22747,22748,22749,22750,22751,22752,22753,22754,22755,22756,22757,22758,22759,22760,22761,22762,22763,22764,22765,22766,22767,22768,22769,22770,22771,22772,22773,22774,22775,22776,22777,22778,22779,22780,22781,22782,22783,22784,22785,22786,22787,22788,22789,22790,22791,22792,22793,22794,22795,22796,22797,22798,22799,22800,22801,22802,22803,22804,22805,22806,22807,22808,22809,22810,22811,22812,22813,22814,22815,22816,22817,22818,22819,22820,22821,22822,22823,22824,22825,22826,22827,22828,22829,22830,22831,22832,22833,22834,22835,22836,22837,22838,22839,22840,22841,22842,22843,22844,22845,22846,22847,22848,22849,22850,22851,22852,22853,22854,22855,22856,22857,22858,22859,22860,22861,22862,22863,22864,22865,22866,22867,22868,22869,22870,22871,22872,22873,22874,22875,22876,22877,22878,22879,22880,22881,22882,22883,22884,22885,22886,22887,22888,22889,22890,22891,22892,22893,22894,22895,22896,22897,22898,22899,22900,22901,22902,22903,22904,22905,22906,22907,22908,22909,22910,22911,22912,22913,22914,22915,22916,22917,22918,22919,22920,22921,22922,22923,22924,22925,22926,22927,22928,22929,22930,22931,22932,22933,22934,22935,22936,22937,22938,22939,22940,22941,22942,22943,22944,22945,22946,22947,22948,22949,22950,22951,22952,22953,22954,22955,22956,22957,22958,22959,22960,22961,22962,22963,22964,22965,22966,22967,22968,22969,22970,22971,22972,22973,22974,22975,22976,22977,22978,22979,22980,22981,22982,22983,22984,22985,22986,22987,22988,22989,22990,22991,22992,22993,22994,22995,22996,22997,22998,22999,23000,23001,23002,23003,23004,23005,23006,23007,23008,23009,23010,23011,23012,23013,23014,23015,23016,23017,23018,23019,23020,23021,23022,23023,23024,23025,23026,23027,23028,23029,23030,23031,23032,23033,23034,23035,23036,23037,23038,23039,23040,23041,23042,23043,23044,23045,23046,23047,23048,23049,23050,23051,23052,23053,23054,23055,23056,23057,23058,23059,23060,23061,23062,23063,23064,23065,23066,23067,23068,23069,23070,23071,23072,23073,23074,23075,23076,23077,23078,23079,23080,23081,23082,23083,23084,23085,23086,23087,23088,23089,23090,23091,23092,23093,23094,23095,23096,23097,23098,23099,23100,23101,23102,23103,23104,23105,23106,23107,23108,23109,23110,23111,23112,23113,23114,23115,23116,23117,23118,23119,23120,23121,23122,23123,23124,23125,23126,23127,23128,23129,23130,23131,23132,23133,23134,23135,23136,23137,23138,23139,23140,23141,23142,23143,23144,23145,23146,23147,23148,23149,23150,23151,23152,23153,23154,23155,23156,23157,23158,23159,23160,23161,23162,23163,23164,23165,23166,23167,23168,23169,23170,23171,23172,23173,23174,23175,23176,23177,23178,23179,23180,23181,23182,23183,23184,23185,23186,23187,23188,23189,23190,23191,23192,23193,23194,23195,23196,23197,23198,23199,23200,23201,23202,23203,23204,23205,23206,23207,23208,23209,23210,23211,23212,23213,23214,23215,23216,23217,23218,23219,23220,23221,23222,23223,23224,23225,23226,23227,23228,23229,23230,23231,23232,23233,23234,23235,23236,23237,23238,23239,23240,23241,23242,23243,23244,23245,23246,23247,23248,23249,23250,23251,23252,23253,23254,23255,23256,23257,23258,23259,23260,23261,23262,23263,23264,23265,23266,23267,23268,23269,23270,23271,23272,23273,23274,23275,23276,23277,23278,23279,23280,23281,23282,23283,23284,23285,23286,23287,23288,23289,23290,23291,23292,23293,23294,23295,23296,23297,23298,23299,23300,23301,23302,23303,23304,23305,23306,23307,23308,23309,23310,23311,23312,23313,23314,23315,23316,23317,23318,23319,23320,23321,23322,23323,23324,23325,23326,23327,23328,23329,23330,23331,23332,23333,23334,23335,23336,23337,23338,23339,23340,23341,23342,23343,23344,23345,23346,23347,23348,23349,23350,23351,23352,23353,23354,23355,23356,23357,23358,23359,23360,23361,23362,23363,23364,23365,23366,23367,23368,23369,23370,23371,23372,23373,23374,23375,23376,23377,23378,23379,23380,23381,23382,23383,23384,23385,23386,23387,23388,23389,23390,23391,23392,23393,23394,23395,23396,23397,23398,23399,23400,23401,23402,23403,23404,23405,23406,23407,23408,23409,23410,23411,23412,23413,23414,23415,23416,23417,23418,23419,23420,23421,23422,23423,23424,23425,23426,23427,23428,23429,23430,23431,23432,23433,23434,23435,23436,23437,23438,23439,23440,23441,23442,23443,23444,23445,23446,23447,23448,23449,23450,23451,23452,23453,23454,23455,23456,23457,23458,23459,23460,23461,23462,23463,23464,23465,23466,23467,23468,23469,23470,23471,23472,23473,23474,23475,23476,23477,23478,23479,23480,23481,23482,23483,23484,23485,23486,23487,23488,23489,23490,23491,23492,23493,23494,23495,23496,23497,23498,23499,23500,23501,23502,23503,23504,23505,23506,23507,23508,23509,23510,23511,23512,23513,23514,23515,23516,23517,23518,23519,23520,23521,23522,23523,23524,23525,23526,23527,23528,23529,23530,23531,23532,23533,23534,23535,23536,23537,23538,23539,23540,23541,23542,23543,23544,23545,23546,23547,23548,23549,23550,23551,23552,23553,23554,23555,23556,23557,23558,23559,23560,23561,23562,23563,23564,23565,23566,23567,23568,23569,23570,23571,23572,23573,23574,23575,23576,23577,23578,23579,23580,23581,23582,23583,23584,23585,23586,23587,23588,23589,23590,23591,23592,23593,23594,23595,23596,23597,23598,23599,23600,23601,23602,23603,23604,23605,23606,23607,23608,23609,23610,23611,23612,23613,23614,23615,23616,23617,23618,23619,23620,23621,23622,23623,23624,23625,23626,23627,23628,23629,23630,23631,23632,23633,23634,23635,23636,23637,23638,23639,23640,23641,23642,23643,23644,23645,23646,23647,23648,23649,23650,23651,23652,23653,23654,23655,23656,23657,23658,23659,23660,23661,23662,23663,23664,23665,23666,23667,23668,23669,23670,23671,23672,23673,23674,23675,23676,23677,23678,23679,23680,23681,23682,23683,23684,23685,23686,23687,23688,23689,23690,23691,23692,23693,23694,23695,23696,23697,23698,23699,23700,23701,23702,23703,23704,23705,23706,23707,23708,23709,23710,23711,23712,23713,23714,23715,23716,23717,23718,23719,23720,23721,23722,23723,23724,23725,23726,23727,23728,23729,23730,23731,23732,23733,23734,23735,23736,23737,23738,23739,23740,23741,23742,23743,23744,23745,23746,23747,23748,23749,23750,23751,23752,23753,23754,23755,23756,23757,23758,23759,23760,23761,23762,23763,23764,23765,23766,23767,23768,23769,23770,23771,23772,23773,23774,23775,23776,23777,23778,23779,23780,23781,23782,23783,23784,23785,23786,23787,23788,23789,23790,23791,23792,23793,23794,23795,23796,23797,23798,23799,23800,23801,23802,23803,23804,23805,23806,23807,23808,23809,23810,23811,23812,23813,23814,23815,23816,23817,23818,23819,23820,23821,23822,23823,23824,23825,23826,23827,23828,23829,23830,23831,23832,23833,23834,23835,23836,23837,23838,23839,23840,23841,23842,23843,23844,23845,23846,23847,23848,23849,23850,23851,23852,23853,23854,23855,23856,23857,23858,23859,23860,23861,23862,23863,23864,23865,23866,23867,23868,23869,23870,23871,23872,23873,23874,23875,23876,23877,23878,23879,23880,23881,23882,23883,23884,23885,23886,23887,23888,23889,23890,23891,23892,23893,23894,23895,23896,23897,23898,23899,23900,23901,23902,23903,23904,23905,23906,23907,23908,23909,23910,23911,23912,23913,23914,23915,23916,23917,23918,23919,23920,23921,23922,23923,23924,23925,23926,23927,23928,23929,23930,23931,23932,23933,23934,23935,23936,23937,23938,23939,23940,23941,23942,23943,23944,23945,23946,23947,23948,23949,23950,23951,23952,23953,23954,23955,23956,23957,23958,23959,23960,23961,23962,23963,23964,23965,23966,23967,23968,23969,23970,23971,23972,23973,23974,23975,23976,23977,23978,23979,23980,23981,23982,23983,23984,23985,23986,23987,23988,23989,23990,23991,23992,23993,23994,23995,23996,23997,23998,23999,24000,24001,24002,24003,24004,24005,24006,24007,24008,24009,24010,24011,24012,24013,24014,24015,24016,24017,24018,24019,24020,24021,24022,24023,24024,24025,24026,24027,24028,24029,24030,24031,24032,24033,24034,24035,24036,24037,24038,24039,24040,24041,24042,24043,24044,24045,24046,24047,24048,24049,24050,24051,24052,24053,24054,24055,24056,24057,24058,24059,24060,24061,24062,24063,24064,24065,24066,24067,24068,24069,24070,24071,24072,24073,24074,24075,24076,24077,24078,24079,24080,24081,24082,24083,24084,24085,24086,24087,24088,24089,24090,24091,24092,24093,24094,24095,24096,24097,24098,24099,24100,24101,24102,24103,24104,24105,24106,24107,24108,24109,24110,24111,24112,24113,24114,24115,24116,24117,24118,24119,24120,24121,24122,24123,24124,24125,24126,24127,24128,24129,24130,24131,24132,24133,24134,24135,24136,24137,24138,24139,24140,24141,24142,24143,24144,24145,24146,24147,24148,24149,24150,24151,24152,24153,24154,24155,24156,24157,24158,24159,24160,24161,24162,24163,24164,24165,24166,24167,24168,24169,24170,24171,24172,24173,24174,24175,24176,24177,24178,24179,24180,24181,24182,24183,24184,24185,24186,24187,24188,24189,24190,24191,24192,24193,24194,24195,24196,24197,24198,24199,24200,24201,24202,24203,24204,24205,24206,24207,24208,24209,24210,24211,24212,24213,24214,24215,24216,24217,24218,24219,24220,24221,24222,24223,24224,24225,24226,24227,24228,24229,24230,24231,24232,24233,24234,24235,24236,24237,24238,24239,24240,24241,24242,24243,24244,24245,24246,24247,24248,24249,24250,24251,24252,24253,24254,24255,24256,24257,24258,24259,24260,24261,24262,24263,24264,24265,24266,24267,24268,24269,24270,24271,24272,24273,24274,24275,24276,24277,24278,24279,24280,24281,24282,24283,24284,24285,24286,24287,24288,24289,24290,24291,24292,24293,24294,24295,24296,24297,24298,24299,24300,24301,24302,24303,24304,24305,24306,24307,24308,24309,24310,24311,24312,24313,24314,24315,24316,24317,24318,24319,24320,24321,24322,24323,24324,24325,24326,24327,24328,24329,24330,24331,24332,24333,24334,24335,24336,24337,24338,24339,24340,24341,24342,24343,24344,24345,24346,24347,24348,24349,24350,24351,24352,24353,24354,24355,24356,24357,24358,24359,24360,24361,24362,24363,24364,24365,24366,24367,24368,24369,24370,24371,24372,24373,24374,24375,24376,24377,24378,24379,24380,24381,24382,24383,24384,24385,24386,24387,24388,24389,24390,24391,24392,24393,24394,24395,24396,24397,24398,24399,24400,24401,24402,24403,24404,24405,24406,24407,24408,24409,24410,24411,24412,24413,24414,24415,24416,24417,24418,24419,24420,24421,24422,24423,24424,24425,24426,24427,24428,24429,24430,24431,24432,24433,24434,24435,24436,24437,24438,24439,24440,24441,24442,24443,24444,24445,24446,24447,24448,24449,24450,24451,24452,24453,24454,24455,24456,24457,24458,24459,24460,24461,24462,24463,24464,24465,24466,24467,24468,24469,24470,24471,24472,24473,24474,24475,24476,24477,24478,24479,24480,24481,24482,24483,24484,24485,24486,24487,24488,24489,24490,24491,24492,24493,24494,24495,24496,24497,24498,24499,24500,24501,24502,24503,24504,24505,24506,24507,24508,24509,24510,24511,24512,24513,24514,24515,24516,24517,24518,24519,24520,24521,24522,24523,24524,24525,24526,24527,24528,24529,24530,24531,24532,24533,24534,24535,24536,24537,24538,24539,24540,24541,24542,24543,24544,24545,24546,24547,24548,24549,24550,24551,24552,24553,24554,24555,24556,24557,24558,24559,24560,24561,24562,24563,24564,24565,24566,24567,24568,24569,24570,24571,24572,24573,24574,24575,24576,24577,24578,24579,24580,24581,24582,24583,24584,24585,24586,24587,24588,24589,24590,24591,24592,24593,24594,24595,24596,24597,24598,24599,24600,24601,24602,24603,24604,24605,24606,24607,24608,24609,24610,24611,24612,24613,24614,24615,24616,24617,24618,24619,24620,24621,24622,24623,24624,24625,24626,24627,24628,24629,24630,24631,24632,24633,24634,24635,24636,24637,24638,24639,24640,24641,24642,24643,24644,24645,24646,24647,24648,24649,24650,24651,24652,24653,24654,24655,24656,24657,24658,24659,24660,24661,24662,24663,24664,24665,24666,24667,24668,24669,24670,24671,24672,24673,24674,24675,24676,24677,24678,24679,24680,24681,24682,24683,24684,24685,24686,24687,24688,24689,24690,24691,24692,24693,24694,24695,24696,24697,24698,24699,24700,24701,24702,24703,24704,24705,24706,24707,24708,24709,24710,24711,24712,24713,24714,24715,24716,24717,24718,24719,24720,24721,24722,24723,24724,24725,24726,24727,24728,24729,24730,24731,24732,24733,24734,24735,24736,24737,24738,24739,24740,24741,24742,24743,24744,24745,24746,24747,24748,24749,24750,24751,24752,24753,24754,24755,24756,24757,24758,24759,24760,24761,24762,24763,24764,24765,24766,24767,24768,24769,24770,24771,24772,24773,24774,24775,24776,24777,24778,24779,24780,24781,24782,24783,24784,24785,24786,24787,24788,24789,24790,24791,24792,24793,24794,24795,24796,24797,24798,24799,24800,24801,24802,24803,24804,24805,24806,24807,24808,24809,24810,24811,24812,24813,24814,24815,24816,24817,24818,24819,24820,24821,24822,24823,24824,24825,24826,24827,24828,24829,24830,24831,24832,24833,24834,24835,24836,24837,24838,24839,24840,24841,24842,24843,24844,24845,24846,24847,24848,24849,24850,24851,24852,24853,24854,24855,24856,24857,24858,24859,24860,24861,24862,24863,24864,24865,24866,24867,24868,24869,24870,24871,24872,24873,24874,24875,24876,24877,24878,24879,24880,24881,24882,24883,24884,24885,24886,24887,24888,24889,24890,24891,24892,24893,24894,24895,24896,24897,24898,24899,24900,24901,24902,24903,24904,24905,24906,24907,24908,24909,24910,24911,24912,24913,24914,24915,24916,24917,24918,24919,24920,24921,24922,24923,24924,24925,24926,24927,24928,24929,24930,24931,24932,24933,24934,24935,24936,24937,24938,24939,24940,24941,24942,24943,24944,24945,24946,24947,24948,24949,24950,24951,24952,24953,24954,24955,24956,24957,24958,24959,24960,24961,24962,24963,24964,24965,24966,24967,24968,24969,24970,24971,24972,24973,24974,24975,24976,24977,24978,24979,24980,24981,24982,24983,24984,24985,24986,24987,24988,24989,24990,24991,24992,24993,24994,24995,24996,24997,24998,24999,25000,25001,25002,25003,25004,25005,25006,25007,25008,25009,25010,25011,25012,25013,25014,25015,25016,25017,25018,25019,25020,25021,25022,25023,25024,25025,25026,25027,25028,25029,25030,25031,25032,25033,25034,25035,25036,25037,25038,25039,25040,25041,25042,25043,25044,25045,25046,25047,25048,25049,25050,25051,25052,25053,25054,25055,25056,25057,25058,25059,25060,25061,25062,25063,25064,25065,25066,25067,25068,25069,25070,25071,25072,25073,25074,25075,25076,25077,25078,25079,25080,25081,25082,25083,25084,25085,25086,25087,25088,25089,25090,25091,25092,25093,25094,25095,25096,25097,25098,25099,25100,25101,25102,25103,25104,25105,25106,25107,25108,25109,25110,25111,25112,25113,25114,25115,25116,25117,25118,25119,25120,25121,25122,25123,25124,25125,25126,25127,25128,25129,25130,25131,25132,25133,25134,25135,25136,25137,25138,25139,25140,25141,25142,25143,25144,25145,25146,25147,25148,25149,25150,25151,25152,25153,25154,25155,25156,25157,25158,25159,25160,25161,25162,25163,25164,25165,25166,25167,25168,25169,25170,25171,25172,25173,25174,25175,25176,25177,25178,25179,25180,25181,25182,25183,25184,25185,25186,25187,25188,25189,25190,25191,25192,25193,25194,25195,25196,25197,25198,25199,25200,25201,25202,25203,25204,25205,25206,25207,25208,25209,25210,25211,25212,25213,25214,25215,25216,25217,25218,25219,25220,25221,25222,25223,25224,25225,25226,25227,25228,25229,25230,25231,25232,25233,25234,25235,25236,25237,25238,25239,25240,25241,25242,25243,25244,25245,25246,25247,25248,25249,25250,25251,25252,25253,25254,25255,25256,25257,25258,25259,25260,25261,25262,25263,25264,25265,25266,25267,25268,25269,25270,25271,25272,25273,25274,25275,25276,25277,25278,25279,25280,25281,25282,25283,25284,25285,25286,25287,25288,25289,25290,25291,25292,25293,25294,25295,25296,25297,25298,25299,25300,25301,25302,25303,25304,25305,25306,25307,25308,25309,25310,25311,25312,25313,25314,25315,25316,25317,25318,25319,25320,25321,25322,25323,25324,25325,25326,25327,25328,25329,25330,25331,25332,25333,25334,25335,25336,25337,25338,25339,25340,25341,25342,25343,25344,25345,25346,25347,25348,25349,25350,25351,25352,25353,25354,25355,25356,25357,25358,25359,25360,25361,25362,25363,25364,25365,25366,25367,25368,25369,25370,25371,25372,25373,25374,25375,25376,25377,25378,25379,25380,25381,25382,25383,25384,25385,25386,25387,25388,25389,25390,25391,25392,25393,25394,25395,25396,25397,25398,25399,25400,25401,25402,25403,25404,25405,25406,25407,25408,25409,25410,25411,25412,25413,25414,25415,25416,25417,25418,25419,25420,25421,25422,25423,25424,25425,25426,25427,25428,25429,25430,25431,25432,25433,25434,25435,25436,25437,25438,25439,25440,25441,25442,25443,25444,25445,25446,25447,25448,25449,25450,25451,25452,25453,25454,25455,25456,25457,25458,25459,25460,25461,25462,25463,25464,25465,25466,25467,25468,25469,25470,25471,25472,25473,25474,25475,25476,25477,25478,25479,25480,25481,25482,25483,25484,25485,25486,25487,25488,25489,25490,25491,25492,25493,25494,25495,25496,25497,25498,25499,25500,25501,25502,25503,25504,25505,25506,25507,25508,25509,25510,25511,25512,25513,25514,25515,25516,25517,25518,25519,25520,25521,25522,25523,25524,25525,25526,25527,25528,25529,25530,25531,25532,25533,25534,25535,25536,25537,25538,25539,25540,25541,25542,25543,25544,25545,25546,25547,25548,25549,25550,25551,25552,25553,25554,25555,25556,25557,25558,25559,25560,25561,25562,25563,25564,25565,25566,25567,25568,25569,25570,25571,25572,25573,25574,25575,25576,25577,25578,25579,25580,25581,25582,25583,25584,25585,25586,25587,25588,25589,25590,25591,25592,25593,25594,25595,25596,25597,25598,25599,25600,25601,25602,25603,25604,25605,25606,25607,25608,25609,25610,25611,25612,25613,25614,25615,25616,25617,25618,25619,25620,25621,25622,25623,25624,25625,25626,25627,25628,25629,25630,25631,25632,25633,25634,25635,25636,25637,25638,25639,25640,25641,25642,25643,25644,25645,25646,25647,25648,25649,25650,25651,25652,25653,25654,25655,25656,25657,25658,25659,25660,25661,25662,25663,25664,25665,25666,25667,25668,25669,25670,25671,25672,25673,25674,25675,25676,25677,25678,25679,25680,25681,25682,25683,25684,25685,25686,25687,25688,25689,25690,25691,25692,25693,25694,25695,25696,25697,25698,25699,25700,25701,25702,25703,25704,25705,25706,25707,25708,25709,25710,25711,25712,25713,25714,25715,25716,25717,25718,25719,25720,25721,25722,25723,25724,25725,25726,25727,25728,25729,25730,25731,25732,25733,25734,25735,25736,25737,25738,25739,25740,25741,25742,25743,25744,25745,25746,25747,25748,25749,25750,25751,25752,25753,25754,25755,25756,25757,25758,25759,25760,25761,25762,25763,25764,25765,25766,25767,25768,25769,25770,25771,25772,25773,25774,25775,25776,25777,25778,25779,25780,25781,25782,25783,25784,25785,25786,25787,25788,25789,25790,25791,25792,25793,25794,25795,25796,25797,25798,25799,25800,25801,25802,25803,25804,25805,25806,25807,25808,25809,25810,25811,25812,25813,25814,25815,25816,25817,25818,25819,25820,25821,25822,25823,25824,25825,25826,25827,25828,25829,25830,25831,25832,25833,25834,25835,25836,25837,25838,25839,25840,25841,25842,25843,25844,25845,25846,25847,25848,25849,25850,25851,25852,25853,25854,25855,25856,25857,25858,25859,25860,25861,25862,25863,25864,25865,25866,25867,25868,25869,25870,25871,25872,25873,25874,25875,25876,25877,25878,25879,25880,25881,25882,25883,25884,25885,25886,25887,25888,25889,25890,25891,25892,25893,25894,25895,25896,25897,25898,25899,25900,25901,25902,25903,25904,25905,25906,25907,25908,25909,25910,25911,25912,25913,25914,25915,25916,25917,25918,25919,25920,25921,25922,25923,25924,25925,25926,25927,25928,25929,25930,25931,25932,25933,25934,25935,25936,25937,25938,25939,25940,25941,25942,25943,25944,25945,25946,25947,25948,25949,25950,25951,25952,25953,25954,25955,25956,25957,25958,25959,25960,25961,25962,25963,25964,25965,25966,25967,25968,25969,25970,25971,25972,25973,25974,25975,25976,25977,25978,25979,25980,25981,25982,25983,25984,25985,25986,25987,25988,25989,25990,25991,25992,25993,25994,25995,25996,25997,25998,25999,26000,26001,26002,26003,26004,26005,26006,26007,26008,26009,26010,26011,26012,26013,26014,26015,26016,26017,26018,26019,26020,26021,26022,26023,26024,26025,26026,26027,26028,26029,26030,26031,26032,26033,26034,26035,26036,26037,26038,26039,26040,26041,26042,26043,26044,26045,26046,26047,26048,26049,26050,26051,26052,26053,26054,26055,26056,26057,26058,26059,26060,26061,26062,26063,26064,26065,26066,26067,26068,26069,26070,26071,26072,26073,26074,26075,26076,26077,26078,26079,26080,26081,26082,26083,26084,26085,26086,26087,26088,26089,26090,26091,26092,26093,26094,26095,26096,26097,26098,26099,26100,26101,26102,26103,26104,26105,26106,26107,26108,26109,26110,26111,26112,26113,26114,26115,26116,26117,26118,26119,26120,26121,26122,26123,26124,26125,26126,26127,26128,26129,26130,26131,26132,26133,26134,26135,26136,26137,26138,26139,26140,26141,26142,26143,26144,26145,26146,26147,26148,26149,26150,26151,26152,26153,26154,26155,26156,26157,26158,26159,26160,26161,26162,26163,26164,26165,26166,26167,26168,26169,26170,26171,26172,26173,26174,26175,26176,26177,26178,26179,26180,26181,26182,26183,26184,26185,26186,26187,26188,26189,26190,26191,26192,26193,26194,26195,26196,26197,26198,26199,26200,26201,26202,26203,26204,26205,26206,26207,26208,26209,26210,26211,26212,26213,26214,26215,26216,26217,26218,26219,26220,26221,26222,26223,26224,26225,26226,26227,26228,26229,26230,26231,26232,26233,26234,26235,26236,26237,26238,26239,26240,26241,26242,26243,26244,26245,26246,26247,26248,26249,26250,26251,26252,26253,26254,26255,26256,26257,26258,26259,26260,26261,26262,26263,26264,26265,26266,26267,26268,26269,26270,26271,26272,26273,26274,26275,26276,26277,26278,26279,26280,26281,26282,26283,26284,26285,26286,26287,26288,26289,26290,26291,26292,26293,26294,26295,26296,26297,26298,26299,26300,26301,26302,26303,26304,26305,26306,26307,26308,26309,26310,26311,26312,26313,26314,26315,26316,26317,26318,26319,26320,26321,26322,26323,26324,26325,26326,26327,26328,26329,26330,26331,26332,26333,26334,26335,26336,26337,26338,26339,26340,26341,26342,26343,26344,26345,26346,26347,26348,26349,26350,26351,26352,26353,26354,26355,26356,26357,26358,26359,26360,26361,26362,26363,26364,26365,26366,26367,26368,26369,26370,26371,26372,26373,26374,26375,26376,26377,26378,26379,26380,26381,26382,26383,26384,26385,26386,26387,26388,26389,26390,26391,26392,26393,26394,26395,26396,26397,26398,26399,26400,26401,26402,26403,26404,26405,26406,26407,26408,26409,26410,26411,26412,26413,26414,26415,26416,26417,26418,26419,26420,26421,26422,26423,26424,26425,26426,26427,26428,26429,26430,26431,26432,26433,26434,26435,26436,26437,26438,26439,26440,26441,26442,26443,26444,26445,26446,26447,26448,26449,26450,26451,26452,26453,26454,26455,26456,26457,26458,26459,26460,26461,26462,26463,26464,26465,26466,26467,26468,26469,26470,26471,26472,26473,26474,26475,26476,26477,26478,26479,26480,26481,26482,26483,26484,26485,26486,26487,26488,26489,26490,26491,26492,26493,26494,26495,26496,26497,26498,26499,26500,26501,26502,26503,26504,26505,26506,26507,26508,26509,26510,26511,26512,26513,26514,26515,26516,26517,26518,26519,26520,26521,26522,26523,26524,26525,26526,26527,26528,26529,26530,26531,26532,26533,26534,26535,26536,26537,26538,26539,26540,26541,26542,26543,26544,26545,26546,26547,26548,26549,26550,26551,26552,26553,26554,26555,26556,26557,26558,26559,26560,26561,26562,26563,26564,26565,26566,26567,26568,26569,26570,26571,26572,26573,26574,26575,26576,26577,26578,26579,26580,26581,26582,26583,26584,26585,26586,26587,26588,26589,26590,26591,26592,26593,26594,26595,26596,26597,26598,26599,26600,26601,26602,26603,26604,26605,26606,26607,26608,26609,26610,26611,26612,26613,26614,26615,26616,26617,26618,26619,26620,26621,26622,26623,26624,26625,26626,26627,26628,26629,26630,26631,26632,26633,26634,26635,26636,26637,26638,26639,26640,26641,26642,26643,26644,26645,26646,26647,26648,26649,26650,26651,26652,26653,26654,26655,26656,26657,26658,26659,26660,26661,26662,26663,26664,26665,26666,26667,26668,26669,26670,26671,26672,26673,26674,26675,26676,26677,26678,26679,26680,26681,26682,26683,26684,26685,26686,26687,26688,26689,26690,26691,26692,26693,26694,26695,26696,26697,26698,26699,26700,26701,26702,26703,26704,26705,26706,26707,26708,26709,26710,26711,26712,26713,26714,26715,26716,26717,26718,26719,26720,26721,26722,26723,26724,26725,26726,26727,26728,26729,26730,26731,26732,26733,26734,26735,26736,26737,26738,26739,26740,26741,26742,26743,26744,26745,26746,26747,26748,26749,26750,26751,26752,26753,26754,26755,26756,26757,26758,26759,26760,26761,26762,26763,26764,26765,26766,26767,26768,26769,26770,26771,26772,26773,26774,26775,26776,26777,26778,26779,26780,26781,26782,26783,26784,26785,26786,26787,26788,26789,26790,26791,26792,26793,26794,26795,26796,26797,26798,26799,26800,26801,26802,26803,26804,26805,26806,26807,26808,26809,26810,26811,26812,26813,26814,26815,26816,26817,26818,26819,26820,26821,26822,26823,26824,26825,26826,26827,26828,26829,26830,26831,26832,26833,26834,26835,26836,26837,26838,26839,26840,26841,26842,26843,26844,26845,26846,26847,26848,26849,26850,26851,26852,26853,26854,26855,26856,26857,26858,26859,26860,26861,26862,26863,26864,26865,26866,26867,26868,26869,26870,26871,26872,26873,26874,26875,26876,26877,26878,26879,26880,26881,26882,26883,26884,26885,26886,26887,26888,26889,26890,26891,26892,26893,26894,26895,26896,26897,26898,26899,26900,26901,26902,26903,26904,26905,26906,26907,26908,26909,26910,26911,26912,26913,26914,26915,26916,26917,26918,26919,26920,26921,26922,26923,26924,26925,26926,26927,26928,26929,26930,26931,26932,26933,26934,26935,26936,26937,26938,26939,26940,26941,26942,26943,26944,26945,26946,26947,26948,26949,26950,26951,26952,26953,26954,26955,26956,26957,26958,26959,26960,26961,26962,26963,26964,26965,26966,26967,26968,26969,26970,26971,26972,26973,26974,26975,26976,26977,26978,26979,26980,26981,26982,26983,26984,26985,26986,26987,26988,26989,26990,26991,26992,26993,26994,26995,26996,26997,26998,26999,27000,27001,27002,27003,27004,27005,27006,27007,27008,27009,27010,27011,27012,27013,27014,27015,27016,27017,27018,27019,27020,27021,27022,27023,27024,27025,27026,27027,27028,27029,27030,27031,27032,27033,27034,27035,27036,27037,27038,27039,27040,27041,27042,27043,27044,27045,27046,27047,27048,27049,27050,27051,27052,27053,27054,27055,27056,27057,27058,27059,27060,27061,27062,27063,27064,27065,27066,27067,27068,27069,27070,27071,27072,27073,27074,27075,27076,27077,27078,27079,27080,27081,27082,27083,27084,27085,27086,27087,27088,27089,27090,27091,27092,27093,27094,27095,27096,27097,27098,27099,27100,27101,27102,27103,27104,27105,27106,27107,27108,27109,27110,27111,27112,27113,27114,27115,27116,27117,27118,27119,27120,27121,27122,27123,27124,27125,27126,27127,27128,27129,27130,27131,27132,27133,27134,27135,27136,27137,27138,27139,27140,27141,27142,27143,27144,27145,27146,27147,27148,27149,27150,27151,27152,27153,27154,27155,27156,27157,27158,27159,27160,27161,27162,27163,27164,27165,27166,27167,27168,27169,27170,27171,27172,27173,27174,27175,27176,27177,27178,27179,27180,27181,27182,27183,27184,27185,27186,27187,27188,27189,27190,27191,27192,27193,27194,27195,27196,27197,27198,27199,27200,27201,27202,27203,27204,27205,27206,27207,27208,27209,27210,27211,27212,27213,27214,27215,27216,27217,27218,27219,27220,27221,27222,27223,27224,27225,27226,27227,27228,27229,27230,27231,27232,27233,27234,27235,27236,27237,27238,27239,27240,27241,27242,27243,27244,27245,27246,27247,27248,27249,27250,27251,27252,27253,27254,27255,27256,27257,27258,27259,27260,27261,27262,27263,27264,27265,27266,27267,27268,27269,27270,27271,27272,27273,27274,27275,27276,27277,27278,27279,27280,27281,27282,27283,27284,27285,27286,27287,27288,27289,27290,27291,27292,27293,27294,27295,27296,27297,27298,27299,27300,27301,27302,27303,27304,27305,27306,27307,27308,27309,27310,27311,27312,27313,27314,27315,27316,27317,27318,27319,27320,27321,27322,27323,27324,27325,27326,27327,27328,27329,27330,27331,27332,27333,27334,27335,27336,27337,27338,27339,27340,27341,27342,27343,27344,27345,27346,27347,27348,27349,27350,27351,27352,27353,27354,27355,27356,27357,27358,27359,27360,27361,27362,27363,27364,27365,27366,27367,27368,27369,27370,27371,27372,27373,27374,27375,27376,27377,27378,27379,27380,27381,27382,27383,27384,27385,27386,27387,27388,27389,27390,27391,27392,27393,27394,27395,27396,27397,27398,27399,27400,27401,27402,27403,27404,27405,27406,27407,27408,27409,27410,27411,27412,27413,27414,27415,27416,27417,27418,27419,27420,27421,27422,27423,27424,27425,27426,27427,27428,27429,27430,27431,27432,27433,27434,27435,27436,27437,27438,27439,27440,27441,27442,27443,27444,27445,27446,27447,27448,27449,27450,27451,27452,27453,27454,27455,27456,27457,27458,27459,27460,27461,27462,27463,27464,27465,27466,27467,27468,27469,27470,27471,27472,27473,27474,27475,27476,27477,27478,27479,27480,27481,27482,27483,27484,27485,27486,27487,27488,27489,27490,27491,27492,27493,27494,27495,27496,27497,27498,27499,27500,27501,27502,27503,27504,27505,27506,27507,27508,27509,27510,27511,27512,27513,27514,27515,27516,27517,27518,27519,27520,27521,27522,27523,27524,27525,27526,27527,27528,27529,27530,27531,27532,27533,27534,27535,27536,27537,27538,27539,27540,27541,27542,27543,27544,27545,27546,27547,27548,27549,27550,27551,27552,27553,27554,27555,27556,27557,27558,27559,27560,27561,27562,27563,27564,27565,27566,27567,27568,27569,27570,27571,27572,27573,27574,27575,27576,27577,27578,27579,27580,27581,27582,27583,27584,27585,27586,27587,27588,27589,27590,27591,27592,27593,27594,27595,27596,27597,27598,27599,27600,27601,27602,27603,27604,27605,27606,27607,27608,27609,27610,27611,27612,27613,27614,27615,27616,27617,27618,27619,27620,27621,27622,27623,27624,27625,27626,27627,27628,27629,27630,27631,27632,27633,27634,27635,27636,27637,27638,27639,27640,27641,27642,27643,27644,27645,27646,27647,27648,27649,27650,27651,27652,27653,27654,27655,27656,27657,27658,27659,27660,27661,27662,27663,27664,27665,27666,27667,27668,27669,27670,27671,27672,27673,27674,27675,27676,27677,27678,27679,27680,27681,27682,27683,27684,27685,27686,27687,27688,27689,27690,27691,27692,27693,27694,27695,27696,27697,27698,27699,27700,27701,27702,27703,27704,27705,27706,27707,27708,27709,27710,27711,27712,27713,27714,27715,27716,27717,27718,27719,27720,27721,27722,27723,27724,27725,27726,27727,27728,27729,27730,27731,27732,27733,27734,27735,27736,27737,27738,27739,27740,27741,27742,27743,27744,27745,27746,27747,27748,27749,27750,27751,27752,27753,27754,27755,27756,27757,27758,27759,27760,27761,27762,27763,27764,27765,27766,27767,27768,27769,27770,27771,27772,27773,27774,27775,27776,27777,27778,27779,27780,27781,27782,27783,27784,27785,27786,27787,27788,27789,27790,27791,27792,27793,27794,27795,27796,27797,27798,27799,27800,27801,27802,27803,27804,27805,27806,27807,27808,27809,27810,27811,27812,27813,27814,27815,27816,27817,27818,27819,27820,27821,27822,27823,27824,27825,27826,27827,27828,27829,27830,27831,27832,27833,27834,27835,27836,27837,27838,27839,27840,27841,27842,27843,27844,27845,27846,27847,27848,27849,27850,27851,27852,27853,27854,27855,27856,27857,27858,27859,27860,27861,27862,27863,27864,27865,27866,27867,27868,27869,27870,27871,27872,27873,27874,27875,27876,27877,27878,27879,27880,27881,27882,27883,27884,27885,27886,27887,27888,27889,27890,27891,27892,27893,27894,27895,27896,27897,27898,27899,27900,27901,27902,27903,27904,27905,27906,27907,27908,27909,27910,27911,27912,27913,27914,27915,27916,27917,27918,27919,27920,27921,27922,27923,27924,27925,27926,27927,27928,27929,27930,27931,27932,27933,27934,27935,27936,27937,27938,27939,27940,27941,27942,27943,27944,27945,27946,27947,27948,27949,27950,27951,27952,27953,27954,27955,27956,27957,27958,27959,27960,27961,27962,27963,27964,27965,27966,27967,27968,27969,27970,27971,27972,27973,27974,27975,27976,27977,27978,27979,27980,27981,27982,27983,27984,27985,27986,27987,27988,27989,27990,27991,27992,27993,27994,27995,27996,27997,27998,27999,28000,28001,28002,28003,28004,28005,28006,28007,28008,28009,28010,28011,28012,28013,28014,28015,28016,28017,28018,28019,28020,28021,28022,28023,28024,28025,28026,28027,28028,28029,28030,28031,28032,28033,28034,28035,28036,28037,28038,28039,28040,28041,28042,28043,28044,28045,28046,28047,28048,28049,28050,28051,28052,28053,28054,28055,28056,28057,28058,28059,28060,28061,28062,28063,28064,28065,28066,28067,28068,28069,28070,28071,28072,28073,28074,28075,28076,28077,28078,28079,28080,28081,28082,28083,28084,28085,28086,28087,28088,28089,28090,28091,28092,28093,28094,28095,28096,28097,28098,28099,28100,28101,28102,28103,28104,28105,28106,28107,28108,28109,28110,28111,28112,28113,28114,28115,28116,28117,28118,28119,28120,28121,28122,28123,28124,28125,28126,28127,28128,28129,28130,28131,28132,28133,28134,28135,28136,28137,28138,28139,28140,28141,28142,28143,28144,28145,28146,28147,28148,28149,28150,28151,28152,28153,28154,28155,28156,28157,28158,28159,28160,28161,28162,28163,28164,28165,28166,28167,28168,28169,28170,28171,28172,28173,28174,28175,28176,28177,28178,28179,28180,28181,28182,28183,28184,28185,28186,28187,28188,28189,28190,28191,28192,28193,28194,28195,28196,28197,28198,28199,28200,28201,28202,28203,28204,28205,28206,28207,28208,28209,28210,28211,28212,28213,28214,28215,28216,28217,28218,28219,28220,28221,28222,28223,28224,28225,28226,28227,28228,28229,28230,28231,28232,28233,28234,28235,28236,28237,28238,28239,28240,28241,28242,28243,28244,28245,28246,28247,28248,28249,28250,28251,28252,28253,28254,28255,28256,28257,28258,28259,28260,28261,28262,28263,28264,28265,28266,28267,28268,28269,28270,28271,28272,28273,28274,28275,28276,28277,28278,28279,28280,28281,28282,28283,28284,28285,28286,28287,28288,28289,28290,28291,28292,28293,28294,28295,28296,28297,28298,28299,28300,28301,28302,28303,28304,28305,28306,28307,28308,28309,28310,28311,28312,28313,28314,28315,28316,28317,28318,28319,28320,28321,28322,28323,28324,28325,28326,28327,28328,28329,28330,28331,28332,28333,28334,28335,28336,28337,28338,28339,28340,28341,28342,28343,28344,28345,28346,28347,28348,28349,28350,28351,28352,28353,28354,28355,28356,28357,28358,28359,28360,28361,28362,28363,28364,28365,28366,28367,28368,28369,28370,28371,28372,28373,28374,28375,28376,28377,28378,28379,28380,28381,28382,28383,28384,28385,28386,28387,28388,28389,28390,28391,28392,28393,28394,28395,28396,28397,28398,28399,28400,28401,28402,28403,28404,28405,28406,28407,28408,28409,28410,28411,28412,28413,28414,28415,28416,28417,28418,28419,28420,28421,28422,28423,28424,28425,28426,28427,28428,28429,28430,28431,28432,28433,28434,28435,28436,28437,28438,28439,28440,28441,28442,28443,28444,28445,28446,28447,28448,28449,28450,28451,28452,28453,28454,28455,28456,28457,28458,28459,28460,28461,28462,28463,28464,28465,28466,28467,28468,28469,28470,28471,28472,28473,28474,28475,28476,28477,28478,28479,28480,28481,28482,28483,28484,28485,28486,28487,28488,28489,28490,28491,28492,28493,28494,28495,28496,28497,28498,28499,28500,28501,28502,28503,28504,28505,28506,28507,28508,28509,28510,28511,28512,28513,28514,28515,28516,28517,28518,28519,28520,28521,28522,28523,28524,28525,28526,28527,28528,28529,28530,28531,28532,28533,28534,28535,28536,28537,28538,28539,28540,28541,28542,28543,28544,28545,28546,28547,28548,28549,28550,28551,28552,28553,28554,28555,28556,28557,28558,28559,28560,28561,28562,28563,28564,28565,28566,28567,28568,28569,28570,28571,28572,28573,28574,28575,28576,28577,28578,28579,28580,28581,28582,28583,28584,28585,28586,28587,28588,28589,28590,28591,28592,28593,28594,28595,28596,28597,28598,28599,28600,28601,28602,28603,28604,28605,28606,28607,28608,28609,28610,28611,28612,28613,28614,28615,28616,28617,28618,28619,28620,28621,28622,28623,28624,28625,28626,28627,28628,28629,28630,28631,28632,28633,28634,28635,28636,28637,28638,28639,28640,28641,28642,28643,28644,28645,28646,28647,28648,28649,28650,28651,28652,28653,28654,28655,28656,28657,28658,28659,28660,28661,28662,28663,28664,28665,28666,28667,28668,28669,28670,28671,28672,28673,28674,28675,28676,28677,28678,28679,28680,28681,28682,28683,28684,28685,28686,28687,28688,28689,28690,28691,28692,28693,28694,28695,28696,28697,28698,28699,28700,28701,28702,28703,28704,28705,28706,28707,28708,28709,28710,28711,28712,28713,28714,28715,28716,28717,28718,28719,28720,28721,28722,28723,28724,28725,28726,28727,28728,28729,28730,28731,28732,28733,28734,28735,28736,28737,28738,28739,28740,28741,28742,28743,28744,28745,28746,28747,28748,28749,28750,28751,28752,28753,28754,28755,28756,28757,28758,28759,28760,28761,28762,28763,28764,28765,28766,28767,28768,28769,28770,28771,28772,28773,28774,28775,28776,28777,28778,28779,28780,28781,28782,28783,28784,28785,28786,28787,28788,28789,28790,28791,28792,28793,28794,28795,28796,28797,28798,28799,28800,28801,28802,28803,28804,28805,28806,28807,28808,28809,28810,28811,28812,28813,28814,28815,28816,28817,28818,28819,28820,28821,28822,28823,28824,28825,28826,28827,28828,28829,28830,28831,28832,28833,28834,28835,28836,28837,28838,28839,28840,28841,28842,28843,28844,28845,28846,28847,28848,28849,28850,28851,28852,28853,28854,28855,28856,28857,28858,28859,28860,28861,28862,28863,28864,28865,28866,28867,28868,28869,28870,28871,28872,28873,28874,28875,28876,28877,28878,28879,28880,28881,28882,28883,28884,28885,28886,28887,28888,28889,28890,28891,28892,28893,28894,28895,28896,28897,28898,28899,28900,28901,28902,28903,28904,28905,28906,28907,28908,28909,28910,28911,28912,28913,28914,28915,28916,28917,28918,28919,28920,28921,28922,28923,28924,28925,28926,28927,28928,28929,28930,28931,28932,28933,28934,28935,28936,28937,28938,28939,28940,28941,28942,28943,28944,28945,28946,28947,28948,28949,28950,28951,28952,28953,28954,28955,28956,28957,28958,28959,28960,28961,28962,28963,28964,28965,28966,28967,28968,28969,28970,28971,28972,28973,28974,28975,28976,28977,28978,28979,28980,28981,28982,28983,28984,28985,28986,28987,28988,28989,28990,28991,28992,28993,28994,28995,28996,28997,28998,28999,29000,29001,29002,29003,29004,29005,29006,29007,29008,29009,29010,29011,29012,29013,29014,29015,29016,29017,29018,29019,29020,29021,29022,29023,29024,29025,29026,29027,29028,29029,29030,29031,29032,29033,29034,29035,29036,29037,29038,29039,29040,29041,29042,29043,29044,29045,29046,29047,29048,29049,29050,29051,29052,29053,29054,29055,29056,29057,29058,29059,29060,29061,29062,29063,29064,29065,29066,29067,29068,29069,29070,29071,29072,29073,29074,29075,29076,29077,29078,29079,29080,29081,29082,29083,29084,29085,29086,29087,29088,29089,29090,29091,29092,29093,29094,29095,29096,29097,29098,29099,29100,29101,29102,29103,29104,29105,29106,29107,29108,29109,29110,29111,29112,29113,29114,29115,29116,29117,29118,29119,29120,29121,29122,29123,29124,29125,29126,29127,29128,29129,29130,29131,29132,29133,29134,29135,29136,29137,29138,29139,29140,29141,29142,29143,29144,29145,29146,29147,29148,29149,29150,29151,29152,29153,29154,29155,29156,29157,29158,29159,29160,29161,29162,29163,29164,29165,29166,29167,29168,29169,29170,29171,29172,29173,29174,29175,29176,29177,29178,29179,29180,29181,29182,29183,29184,29185,29186,29187,29188,29189,29190,29191,29192,29193,29194,29195,29196,29197,29198,29199,29200,29201,29202,29203,29204,29205,29206,29207,29208,29209,29210,29211,29212,29213,29214,29215,29216,29217,29218,29219,29220,29221,29222,29223,29224,29225,29226,29227,29228,29229,29230,29231,29232,29233,29234,29235,29236,29237,29238,29239,29240,29241,29242,29243,29244,29245,29246,29247,29248,29249,29250,29251,29252,29253,29254,29255,29256,29257,29258,29259,29260,29261,29262,29263,29264,29265,29266,29267,29268,29269,29270,29271,29272,29273,29274,29275,29276,29277,29278,29279,29280,29281,29282,29283,29284,29285,29286,29287,29288,29289,29290,29291,29292,29293,29294,29295,29296,29297,29298,29299,29300,29301,29302,29303,29304,29305,29306,29307,29308,29309,29310,29311,29312,29313,29314,29315,29316,29317,29318,29319,29320,29321,29322,29323,29324,29325,29326,29327,29328,29329,29330,29331,29332,29333,29334,29335,29336,29337,29338,29339,29340,29341,29342,29343,29344,29345,29346,29347,29348,29349,29350,29351,29352,29353,29354,29355,29356,29357,29358,29359,29360,29361,29362,29363,29364,29365,29366,29367,29368,29369,29370,29371,29372,29373,29374,29375,29376,29377,29378,29379,29380,29381,29382,29383,29384,29385,29386,29387,29388,29389,29390,29391,29392,29393,29394,29395,29396,29397,29398,29399,29400,29401,29402,29403,29404,29405,29406,29407,29408,29409,29410,29411,29412,29413,29414,29415,29416,29417,29418,29419,29420,29421,29422,29423,29424,29425,29426,29427,29428,29429,29430,29431,29432,29433,29434,29435,29436,29437,29438,29439,29440,29441,29442,29443,29444,29445,29446,29447,29448,29449,29450,29451,29452,29453,29454,29455,29456,29457,29458,29459,29460,29461,29462,29463,29464,29465,29466,29467,29468,29469,29470,29471,29472,29473,29474,29475,29476,29477,29478,29479,29480,29481,29482,29483,29484,29485,29486,29487,29488,29489,29490,29491,29492,29493,29494,29495,29496,29497,29498,29499,29500,29501,29502,29503,29504,29505,29506,29507,29508,29509,29510,29511,29512,29513,29514,29515,29516,29517,29518,29519,29520,29521,29522,29523,29524,29525,29526,29527,29528,29529,29530,29531,29532,29533,29534,29535,29536,29537,29538,29539,29540,29541,29542,29543,29544,29545,29546,29547,29548,29549,29550,29551,29552,29553,29554,29555,29556,29557,29558,29559,29560,29561,29562,29563,29564,29565,29566,29567,29568,29569,29570,29571,29572,29573,29574,29575,29576,29577,29578,29579,29580,29581,29582,29583,29584,29585,29586,29587,29588,29589,29590,29591,29592,29593,29594,29595,29596,29597,29598,29599,29600,29601,29602,29603,29604,29605,29606,29607,29608,29609,29610,29611,29612,29613,29614,29615,29616,29617,29618,29619,29620,29621,29622,29623,29624,29625,29626,29627,29628,29629,29630,29631,29632,29633,29634,29635,29636,29637,29638,29639,29640,29641,29642,29643,29644,29645,29646,29647,29648,29649,29650,29651,29652,29653,29654,29655,29656,29657,29658,29659,29660,29661,29662,29663,29664,29665,29666,29667,29668,29669,29670,29671,29672,29673,29674,29675,29676,29677,29678,29679,29680,29681,29682,29683,29684,29685,29686,29687,29688,29689,29690,29691,29692,29693,29694,29695,29696,29697,29698,29699,29700,29701,29702,29703,29704,29705,29706,29707,29708,29709,29710,29711,29712,29713,29714,29715,29716,29717,29718,29719,29720,29721,29722,29723,29724,29725,29726,29727,29728,29729,29730,29731,29732,29733,29734,29735,29736,29737,29738,29739,29740,29741,29742,29743,29744,29745,29746,29747,29748,29749,29750,29751,29752,29753,29754,29755,29756,29757,29758,29759,29760,29761,29762,29763,29764,29765,29766,29767,29768,29769,29770,29771,29772,29773,29774,29775,29776,29777,29778,29779,29780,29781,29782,29783,29784,29785,29786,29787,29788,29789,29790,29791,29792,29793,29794,29795,29796,29797,29798,29799,29800,29801,29802,29803,29804,29805,29806,29807,29808,29809,29810,29811,29812,29813,29814,29815,29816,29817,29818,29819,29820,29821,29822,29823,29824,29825,29826,29827,29828,29829,29830,29831,29832,29833,29834,29835,29836,29837,29838,29839,29840,29841,29842,29843,29844,29845,29846,29847,29848,29849,29850,29851,29852,29853,29854,29855,29856,29857,29858,29859,29860,29861,29862,29863,29864,29865,29866,29867,29868,29869,29870,29871,29872,29873,29874,29875,29876,29877,29878,29879,29880,29881,29882,29883,29884,29885,29886,29887,29888,29889,29890,29891,29892,29893,29894,29895,29896,29897,29898,29899,29900,29901,29902,29903,29904,29905,29906,29907,29908,29909,29910,29911,29912,29913,29914,29915,29916,29917,29918,29919,29920,29921,29922,29923,29924,29925,29926,29927,29928,29929,29930,29931,29932,29933,29934,29935,29936,29937,29938,29939,29940,29941,29942,29943,29944,29945,29946,29947,29948,29949,29950,29951,29952,29953,29954,29955,29956,29957,29958,29959,29960,29961,29962,29963,29964,29965,29966,29967,29968,29969,29970,29971,29972,29973,29974,29975,29976,29977,29978,29979,29980,29981,29982,29983,29984,29985,29986,29987,29988,29989,29990,29991,29992,29993,29994,29995,29996,29997,29998,29999,30000,30001,30002,30003,30004,30005,30006,30007,30008,30009,30010,30011,30012,30013,30014,30015,30016,30017,30018,30019,30020,30021,30022,30023,30024,30025,30026,30027,30028,30029,30030,30031,30032,30033,30034,30035,30036,30037,30038,30039,30040,30041,30042,30043,30044,30045,30046,30047,30048,30049,30050,30051,30052,30053,30054,30055,30056,30057,30058,30059,30060,30061,30062,30063,30064,30065,30066,30067,30068,30069,30070,30071,30072,30073,30074,30075,30076,30077,30078,30079,30080,30081,30082,30083,30084,30085,30086,30087,30088,30089,30090,30091,30092,30093,30094,30095,30096,30097,30098,30099,30100,30101,30102,30103,30104,30105,30106,30107,30108,30109,30110,30111,30112,30113,30114,30115,30116,30117,30118,30119,30120,30121,30122,30123,30124,30125,30126,30127,30128,30129,30130,30131,30132,30133,30134,30135,30136,30137,30138,30139,30140,30141,30142,30143,30144,30145,30146,30147,30148,30149,30150,30151,30152,30153,30154,30155,30156,30157,30158,30159,30160,30161,30162,30163,30164,30165,30166,30167,30168,30169,30170,30171,30172,30173,30174,30175,30176,30177,30178,30179,30180,30181,30182,30183,30184,30185,30186,30187,30188,30189,30190,30191,30192,30193,30194,30195,30196,30197,30198,30199,30200,30201,30202,30203,30204,30205,30206,30207,30208,30209,30210,30211,30212,30213,30214,30215,30216,30217,30218,30219,30220,30221,30222,30223,30224,30225,30226,30227,30228,30229,30230,30231,30232,30233,30234,30235,30236,30237,30238,30239,30240,30241,30242,30243,30244,30245,30246,30247,30248,30249,30250,30251,30252,30253,30254,30255,30256,30257,30258,30259,30260,30261,30262,30263,30264,30265,30266,30267,30268,30269,30270,30271,30272,30273,30274,30275,30276,30277,30278,30279,30280,30281,30282,30283,30284,30285,30286,30287,30288,30289,30290,30291,30292,30293,30294,30295,30296,30297,30298,30299,30300,30301,30302,30303,30304,30305,30306,30307,30308,30309,30310,30311,30312,30313,30314,30315,30316,30317,30318,30319,30320,30321,30322,30323,30324,30325,30326,30327,30328,30329,30330,30331,30332,30333,30334,30335,30336,30337,30338,30339,30340,30341,30342,30343,30344,30345,30346,30347,30348,30349,30350,30351,30352,30353,30354,30355,30356,30357,30358,30359,30360,30361,30362,30363,30364,30365,30366,30367,30368,30369,30370,30371,30372,30373,30374,30375,30376,30377,30378,30379,30380,30381,30382,30383,30384,30385,30386,30387,30388,30389,30390,30391,30392,30393,30394,30395,30396,30397,30398,30399,30400,30401,30402,30403,30404,30405,30406,30407,30408,30409,30410,30411,30412,30413,30414,30415,30416,30417,30418,30419,30420,30421,30422,30423,30424,30425,30426,30427,30428,30429,30430,30431,30432,30433,30434,30435,30436,30437,30438,30439,30440,30441,30442,30443,30444,30445,30446,30447,30448,30449,30450,30451,30452,30453,30454,30455,30456,30457,30458,30459,30460,30461,30462,30463,30464,30465,30466,30467,30468,30469,30470,30471,30472,30473,30474,30475,30476,30477,30478,30479,30480,30481,30482,30483,30484,30485,30486,30487,30488,30489,30490,30491,30492,30493,30494,30495,30496,30497,30498,30499,30500,30501,30502,30503,30504,30505,30506,30507,30508,30509,30510,30511,30512,30513,30514,30515,30516,30517,30518,30519,30520,30521,30522,30523,30524,30525,30526,30527,30528,30529,30530,30531,30532,30533,30534,30535,30536,30537,30538,30539,30540,30541,30542,30543,30544,30545,30546,30547,30548,30549,30550,30551,30552,30553,30554,30555,30556,30557,30558,30559,30560,30561,30562,30563,30564,30565,30566,30567,30568,30569,30570,30571,30572,30573,30574,30575,30576,30577,30578,30579,30580,30581,30582,30583,30584,30585,30586,30587,30588,30589,30590,30591,30592,30593,30594,30595,30596,30597,30598,30599,30600,30601,30602,30603,30604,30605,30606,30607,30608,30609,30610,30611,30612,30613,30614,30615,30616,30617,30618,30619,30620,30621,30622,30623,30624,30625,30626,30627,30628,30629,30630,30631,30632,30633,30634,30635,30636,30637,30638,30639,30640,30641,30642,30643,30644,30645,30646,30647,30648,30649,30650,30651,30652,30653,30654,30655,30656,30657,30658,30659,30660,30661,30662,30663,30664,30665,30666,30667,30668,30669,30670,30671,30672,30673,30674,30675,30676,30677,30678,30679,30680,30681,30682,30683,30684,30685,30686,30687,30688,30689,30690,30691,30692,30693,30694,30695,30696,30697,30698,30699,30700,30701,30702,30703,30704,30705,30706,30707,30708,30709,30710,30711,30712,30713,30714,30715,30716,30717,30718,30719,30720,30721,30722,30723,30724,30725,30726,30727,30728,30729,30730,30731,30732,30733,30734,30735,30736,30737,30738,30739,30740,30741,30742,30743,30744,30745,30746,30747,30748,30749,30750,30751,30752,30753,30754,30755,30756,30757,30758,30759,30760,30761,30762,30763,30764,30765,30766,30767,30768,30769,30770,30771,30772,30773,30774,30775,30776,30777,30778,30779,30780,30781,30782,30783,30784,30785,30786,30787,30788,30789,30790,30791,30792,30793,30794,30795,30796,30797,30798,30799,30800,30801,30802,30803,30804,30805,30806,30807,30808,30809,30810,30811,30812,30813,30814,30815,30816,30817,30818,30819,30820,30821,30822,30823,30824,30825,30826,30827,30828,30829,30830,30831,30832,30833,30834,30835,30836,30837,30838,30839,30840,30841,30842,30843,30844,30845,30846,30847,30848,30849,30850,30851,30852,30853,30854,30855,30856,30857,30858,30859,30860,30861,30862,30863,30864,30865,30866,30867,30868,30869,30870,30871,30872,30873,30874,30875,30876,30877,30878,30879,30880,30881,30882,30883,30884,30885,30886,30887,30888,30889,30890,30891,30892,30893,30894,30895,30896,30897,30898,30899,30900,30901,30902,30903,30904,30905,30906,30907,30908,30909,30910,30911,30912,30913,30914,30915,30916,30917,30918,30919,30920,30921,30922,30923,30924,30925,30926,30927,30928,30929,30930,30931,30932,30933,30934,30935,30936,30937,30938,30939,30940,30941,30942,30943,30944,30945,30946,30947,30948,30949,30950,30951,30952,30953,30954,30955,30956,30957,30958,30959,30960,30961,30962,30963,30964,30965,30966,30967,30968,30969,30970,30971,30972,30973,30974,30975,30976,30977,30978,30979,30980,30981,30982,30983,30984,30985,30986,30987,30988,30989,30990,30991,30992,30993,30994,30995,30996,30997,30998,30999,31000,31001,31002,31003,31004,31005,31006,31007,31008,31009,31010,31011,31012,31013,31014,31015,31016,31017,31018,31019,31020,31021,31022,31023,31024,31025,31026,31027,31028,31029,31030,31031,31032,31033,31034,31035,31036,31037,31038,31039,31040,31041,31042,31043,31044,31045,31046,31047,31048,31049,31050,31051,31052,31053,31054,31055,31056,31057,31058,31059,31060,31061,31062,31063,31064,31065,31066,31067,31068,31069,31070,31071,31072,31073,31074,31075,31076,31077,31078,31079,31080,31081,31082,31083,31084,31085,31086,31087,31088,31089,31090,31091,31092,31093,31094,31095,31096,31097,31098,31099,31100,31101,31102,31103,31104,31105,31106,31107,31108,31109,31110,31111,31112,31113,31114,31115,31116,31117,31118,31119,31120,31121,31122,31123,31124,31125,31126,31127,31128,31129,31130,31131,31132,31133,31134,31135,31136,31137,31138,31139,31140,31141,31142,31143,31144,31145,31146,31147,31148,31149,31150,31151,31152,31153,31154,31155,31156,31157,31158,31159,31160,31161,31162,31163,31164,31165,31166,31167,31168,31169,31170,31171,31172,31173,31174,31175,31176,31177,31178,31179,31180,31181,31182,31183,31184,31185,31186,31187,31188,31189,31190,31191,31192,31193,31194,31195,31196,31197,31198,31199,31200,31201,31202,31203,31204,31205,31206,31207,31208,31209,31210,31211,31212,31213,31214,31215,31216,31217,31218,31219,31220,31221,31222,31223,31224,31225,31226,31227,31228,31229,31230,31231,31232,31233,31234,31235,31236,31237,31238,31239,31240,31241,31242,31243,31244,31245,31246,31247,31248,31249,31250,31251,31252,31253,31254,31255,31256,31257,31258,31259,31260,31261,31262,31263,31264,31265,31266,31267,31268,31269,31270,31271,31272,31273,31274,31275,31276,31277,31278,31279,31280,31281,31282,31283,31284,31285,31286,31287,31288,31289,31290,31291,31292,31293,31294,31295,31296,31297,31298,31299,31300,31301,31302,31303,31304,31305,31306,31307,31308,31309,31310,31311,31312,31313,31314,31315,31316,31317,31318,31319,31320,31321,31322,31323,31324,31325,31326,31327,31328,31329,31330,31331,31332,31333,31334,31335,31336,31337,31338,31339,31340,31341,31342,31343,31344,31345,31346,31347,31348,31349,31350,31351,31352,31353,31354,31355,31356,31357,31358,31359,31360,31361,31362,31363,31364,31365,31366,31367,31368,31369,31370,31371,31372,31373,31374,31375,31376,31377,31378,31379,31380,31381,31382,31383,31384,31385,31386,31387,31388,31389,31390,31391,31392,31393,31394,31395,31396,31397,31398,31399,31400,31401,31402,31403,31404,31405,31406,31407,31408,31409,31410,31411,31412,31413,31414,31415,31416,31417,31418,31419,31420,31421,31422,31423,31424,31425,31426,31427,31428,31429,31430,31431,31432,31433,31434,31435,31436,31437,31438,31439,31440,31441,31442,31443,31444,31445,31446,31447,31448,31449,31450,31451,31452,31453,31454,31455,31456,31457,31458,31459,31460,31461,31462,31463,31464,31465,31466,31467,31468,31469,31470,31471,31472,31473,31474,31475,31476,31477,31478,31479,31480,31481,31482,31483,31484,31485,31486,31487,31488,31489,31490,31491,31492,31493,31494,31495,31496,31497,31498,31499,31500,31501,31502,31503,31504,31505,31506,31507,31508,31509,31510,31511,31512,31513,31514,31515,31516,31517,31518,31519,31520,31521,31522,31523,31524,31525,31526,31527,31528,31529,31530,31531,31532,31533,31534,31535,31536,31537,31538,31539,31540,31541,31542,31543,31544,31545,31546,31547,31548,31549,31550,31551,31552,31553,31554,31555,31556,31557,31558,31559,31560,31561,31562,31563,31564,31565,31566,31567,31568,31569,31570,31571,31572,31573,31574,31575,31576,31577,31578,31579,31580,31581,31582,31583,31584,31585,31586,31587,31588,31589,31590,31591,31592,31593,31594,31595,31596,31597,31598,31599,31600,31601,31602,31603,31604,31605,31606,31607,31608,31609,31610,31611,31612,31613,31614,31615,31616,31617,31618,31619,31620,31621,31622,31623,31624,31625,31626,31627,31628,31629,31630,31631,31632,31633,31634,31635,31636,31637,31638,31639,31640,31641,31642,31643,31644,31645,31646,31647,31648,31649,31650,31651,31652,31653,31654,31655,31656,31657,31658,31659,31660,31661,31662,31663,31664,31665,31666,31667,31668,31669,31670,31671,31672,31673,31674,31675,31676,31677,31678,31679,31680,31681,31682,31683,31684,31685,31686,31687,31688,31689,31690,31691,31692,31693,31694,31695,31696,31697,31698,31699,31700,31701,31702,31703,31704,31705,31706,31707,31708,31709,31710,31711,31712,31713,31714,31715,31716,31717,31718,31719,31720,31721,31722,31723,31724,31725,31726,31727,31728,31729,31730,31731,31732,31733,31734,31735,31736,31737,31738,31739,31740,31741,31742,31743,31744,31745,31746,31747,31748,31749,31750,31751,31752,31753,31754,31755,31756,31757,31758,31759,31760,31761,31762,31763,31764,31765,31766,31767,31768,31769,31770,31771,31772,31773,31774,31775,31776,31777,31778,31779,31780,31781,31782,31783,31784,31785,31786,31787,31788,31789,31790,31791,31792,31793,31794,31795,31796,31797,31798,31799,31800,31801,31802,31803,31804,31805,31806,31807,31808,31809,31810,31811,31812,31813,31814,31815,31816,31817,31818,31819,31820,31821,31822,31823,31824,31825,31826,31827,31828,31829,31830,31831,31832,31833,31834,31835,31836,31837,31838,31839,31840,31841,31842,31843,31844,31845,31846,31847,31848,31849,31850,31851,31852,31853,31854,31855,31856,31857,31858,31859,31860,31861,31862,31863,31864,31865,31866,31867,31868,31869,31870,31871,31872,31873,31874,31875,31876,31877,31878,31879,31880,31881,31882,31883,31884,31885,31886,31887,31888,31889,31890,31891,31892,31893,31894,31895,31896,31897,31898,31899,31900,31901,31902,31903,31904,31905,31906,31907,31908,31909,31910,31911,31912,31913,31914,31915,31916,31917,31918,31919,31920,31921,31922,31923,31924,31925,31926,31927,31928,31929,31930,31931,31932,31933,31934,31935,31936,31937,31938,31939,31940,31941,31942,31943,31944,31945,31946,31947,31948,31949,31950,31951,31952,31953,31954,31955,31956,31957,31958,31959,31960,31961,31962,31963,31964,31965,31966,31967,31968,31969,31970,31971,31972,31973,31974,31975,31976,31977,31978,31979,31980,31981,31982,31983,31984,31985,31986,31987,31988,31989,31990,31991,31992,31993,31994,31995,31996,31997,31998,31999,32000,32001,32002,32003,32004,32005,32006,32007,32008,32009,32010,32011,32012,32013,32014,32015,32016,32017,32018,32019,32020,32021,32022,32023,32024,32025,32026,32027,32028,32029,32030,32031,32032,32033,32034,32035,32036,32037,32038,32039,32040,32041,32042,32043,32044,32045,32046,32047,32048,32049,32050,32051,32052,32053,32054,32055,32056,32057,32058,32059,32060,32061,32062,32063,32064,32065,32066,32067,32068,32069,32070,32071,32072,32073,32074,32075,32076,32077,32078,32079,32080,32081,32082,32083,32084,32085,32086,32087,32088,32089,32090,32091,32092,32093,32094,32095,32096,32097,32098,32099,32100,32101,32102,32103,32104,32105,32106,32107,32108,32109,32110,32111,32112,32113,32114,32115,32116,32117,32118,32119,32120,32121,32122,32123,32124,32125,32126,32127,32128,32129,32130,32131,32132,32133,32134,32135,32136,32137,32138,32139,32140,32141,32142,32143,32144,32145,32146,32147,32148,32149,32150,32151,32152,32153,32154,32155,32156,32157,32158,32159,32160,32161,32162,32163,32164,32165,32166,32167,32168,32169,32170,32171,32172,32173,32174,32175,32176,32177,32178,32179,32180,32181,32182,32183,32184,32185,32186,32187,32188,32189,32190,32191,32192,32193,32194,32195,32196,32197,32198,32199,32200,32201,32202,32203,32204,32205,32206,32207,32208,32209,32210,32211,32212,32213,32214,32215,32216,32217,32218,32219,32220,32221,32222,32223,32224,32225,32226,32227,32228,32229,32230,32231,32232,32233,32234,32235,32236,32237,32238,32239,32240,32241,32242,32243,32244,32245,32246,32247,32248,32249,32250,32251,32252,32253,32254,32255,32256,32257,32258,32259,32260,32261,32262,32263,32264,32265,32266,32267,32268,32269,32270,32271,32272,32273,32274,32275,32276,32277,32278,32279,32280,32281,32282,32283,32284,32285,32286,32287,32288,32289,32290,32291,32292,32293,32294,32295,32296,32297,32298,32299,32300,32301,32302,32303,32304,32305,32306,32307,32308,32309,32310,32311,32312,32313,32314,32315,32316,32317,32318,32319,32320,32321,32322,32323,32324,32325,32326,32327,32328,32329,32330,32331,32332,32333,32334,32335,32336,32337,32338,32339,32340,32341,32342,32343,32344,32345,32346,32347,32348,32349,32350,32351,32352,32353,32354,32355,32356,32357,32358,32359,32360,32361,32362,32363,32364,32365,32366,32367,32368,32369,32370,32371,32372,32373,32374,32375,32376,32377,32378,32379,32380,32381,32382,32383,32384,32385,32386,32387,32388,32389,32390,32391,32392,32393,32394,32395,32396,32397,32398,32399,32400,32401,32402,32403,32404,32405,32406,32407,32408,32409,32410,32411,32412,32413,32414,32415,32416,32417,32418,32419,32420,32421,32422,32423,32424,32425,32426,32427,32428,32429,32430,32431,32432,32433,32434,32435,32436,32437,32438,32439,32440,32441,32442,32443,32444,32445,32446,32447,32448,32449,32450,32451,32452,32453,32454,32455,32456,32457,32458,32459,32460,32461,32462,32463,32464,32465,32466,32467,32468,32469,32470,32471,32472,32473,32474,32475,32476,32477,32478,32479,32480,32481,32482,32483,32484,32485,32486,32487,32488,32489,32490,32491,32492,32493,32494,32495,32496,32497,32498,32499,32500,32501,32502,32503,32504,32505,32506,32507,32508,32509,32510,32511,32512,32513,32514,32515,32516,32517,32518,32519,32520,32521,32522,32523,32524,32525,32526,32527,32528,32529,32530,32531,32532,32533,32534,32535,32536,32537,32538,32539,32540,32541,32542,32543,32544,32545,32546,32547,32548,32549,32550,32551,32552,32553,32554,32555,32556,32557,32558,32559,32560,32561,32562,32563,32564,32565,32566,32567,32568,32569,32570,32571,32572,32573,32574,32575,32576,32577,32578,32579,32580,32581,32582,32583,32584,32585,32586,32587,32588,32589,32590,32591,32592,32593,32594,32595,32596,32597,32598,32599,32600,32601,32602,32603,32604,32605,32606,32607,32608,32609,32610,32611,32612,32613,32614,32615,32616,32617,32618,32619,32620,32621,32622,32623,32624,32625,32626,32627,32628,32629,32630,32631,32632,32633,32634,32635,32636,32637,32638,32639,32640,32641,32642,32643,32644,32645,32646,32647,32648,32649,32650,32651,32652,32653,32654,32655,32656,32657,32658,32659,32660,32661,32662,32663,32664,32665,32666,32667,32668,32669,32670,32671,32672,32673,32674,32675,32676,32677,32678,32679,32680,32681,32682,32683,32684,32685,32686,32687,32688,32689,32690,32691,32692,32693,32694,32695,32696,32697,32698,32699,32700,32701,32702,32703,32704,32705,32706,32707,32708,32709,32710,32711,32712,32713,32714,32715,32716,32717,32718,32719,32720,32721,32722,32723,32724,32725,32726,32727,32728,32729,32730,32731,32732,32733,32734,32735,32736,32737,32738,32739,32740,32741,32742,32743,32744,32745,32746,32747,32748,32749,32750,32751,32752,32753,32754,32755,32756,32757,32758,32759,32760,32761,32762,32763,32764,32765,32766,32767,32768,32769,32770,32771,32772,32773,32774,32775,32776,32777,32778,32779,32780,32781,32782,32783,32784,32785,32786,32787,32788,32789,32790,32791,32792,32793,32794,32795,32796,32797,32798,32799,32800,32801,32802,32803,32804,32805,32806,32807,32808,32809,32810,32811,32812,32813,32814,32815,32816,32817,32818,32819,32820,32821,32822,32823,32824,32825,32826,32827,32828,32829,32830,32831,32832,32833,32834,32835,32836,32837,32838,32839,32840,32841,32842,32843,32844,32845,32846,32847,32848,32849,32850,32851,32852,32853,32854,32855,32856,32857,32858,32859,32860,32861,32862,32863,32864,32865,32866,32867,32868,32869,32870,32871,32872,32873,32874,32875,32876,32877,32878,32879,32880,32881,32882,32883,32884,32885,32886,32887,32888,32889,32890,32891,32892,32893,32894,32895,32896,32897,32898,32899,32900,32901,32902,32903,32904,32905,32906,32907,32908,32909,32910,32911,32912,32913,32914,32915,32916,32917,32918,32919,32920,32921,32922,32923,32924,32925,32926,32927,32928,32929,32930,32931,32932,32933,32934,32935,32936,32937,32938,32939,32940,32941,32942,32943,32944,32945,32946,32947,32948,32949,32950,32951,32952,32953,32954,32955,32956,32957,32958,32959,32960,32961,32962,32963,32964,32965,32966,32967,32968,32969,32970,32971,32972,32973,32974,32975,32976,32977,32978,32979,32980,32981,32982,32983,32984,32985,32986,32987,32988,32989,32990,32991,32992,32993,32994,32995,32996,32997,32998,32999,33000,33001,33002,33003,33004,33005,33006,33007,33008,33009,33010,33011,33012,33013,33014,33015,33016,33017,33018,33019,33020,33021,33022,33023,33024,33025,33026,33027,33028,33029,33030,33031,33032,33033,33034,33035,33036,33037,33038,33039,33040,33041,33042,33043,33044,33045,33046,33047,33048,33049,33050,33051,33052,33053,33054,33055,33056,33057,33058,33059,33060,33061,33062,33063,33064,33065,33066,33067,33068,33069,33070,33071,33072,33073,33074,33075,33076,33077,33078,33079,33080,33081,33082,33083,33084,33085,33086,33087,33088,33089,33090,33091,33092,33093,33094,33095,33096,33097,33098,33099,33100,33101,33102,33103,33104,33105,33106,33107,33108,33109,33110,33111,33112,33113,33114,33115,33116,33117,33118,33119,33120,33121,33122,33123,33124,33125,33126,33127,33128,33129,33130,33131,33132,33133,33134,33135,33136,33137,33138,33139,33140,33141,33142,33143,33144,33145,33146,33147,33148,33149,33150,33151,33152,33153,33154,33155,33156,33157,33158,33159,33160,33161,33162,33163,33164,33165,33166,33167,33168,33169,33170,33171,33172,33173,33174,33175,33176,33177,33178,33179,33180,33181,33182,33183,33184,33185,33186,33187,33188,33189,33190,33191,33192,33193,33194,33195,33196,33197,33198,33199,33200,33201,33202,33203,33204,33205,33206,33207,33208,33209,33210,33211,33212,33213,33214,33215,33216,33217,33218,33219,33220,33221,33222,33223,33224,33225,33226,33227,33228,33229,33230,33231,33232,33233,33234,33235,33236,33237,33238,33239,33240,33241,33242,33243,33244,33245,33246,33247,33248,33249,33250,33251,33252,33253,33254,33255,33256,33257,33258,33259,33260,33261,33262,33263,33264,33265,33266,33267,33268,33269,33270,33271,33272,33273,33274,33275,33276,33277,33278,33279,33280,33281,33282,33283,33284,33285,33286,33287,33288,33289,33290,33291,33292,33293,33294,33295,33296,33297,33298,33299,33300,33301,33302,33303,33304,33305,33306,33307,33308,33309,33310,33311,33312,33313,33314,33315,33316,33317,33318,33319,33320,33321,33322,33323,33324,33325,33326,33327,33328,33329,33330,33331,33332,33333,33334,33335,33336,33337,33338,33339,33340,33341,33342,33343,33344,33345,33346,33347,33348,33349,33350,33351,33352,33353,33354,33355,33356,33357,33358,33359,33360,33361,33362,33363,33364,33365,33366,33367,33368,33369,33370,33371,33372,33373,33374,33375,33376,33377,33378,33379,33380,33381,33382,33383,33384,33385,33386,33387,33388,33389,33390,33391,33392,33393,33394,33395,33396,33397,33398,33399,33400,33401,33402,33403,33404,33405,33406,33407,33408,33409,33410,33411,33412,33413,33414,33415,33416,33417,33418,33419,33420,33421,33422,33423,33424,33425,33426,33427,33428,33429,33430,33431,33432,33433,33434,33435,33436,33437,33438,33439,33440,33441,33442,33443,33444,33445,33446,33447,33448,33449,33450,33451,33452,33453,33454,33455,33456,33457,33458,33459,33460,33461,33462,33463,33464,33465,33466,33467,33468,33469,33470,33471,33472,33473,33474,33475,33476,33477,33478,33479,33480,33481,33482,33483,33484,33485,33486,33487,33488,33489,33490,33491,33492,33493,33494,33495,33496,33497,33498,33499,33500,33501,33502,33503,33504,33505,33506,33507,33508,33509,33510,33511,33512,33513,33514,33515,33516,33517,33518,33519,33520,33521,33522,33523,33524,33525,33526,33527,33528,33529,33530,33531,33532,33533,33534,33535,33536,33537,33538,33539,33540,33541,33542,33543,33544,33545,33546,33547,33548,33549,33550,33551,33552,33553,33554,33555,33556,33557,33558,33559,33560,33561,33562,33563,33564,33565,33566,33567,33568,33569,33570,33571,33572,33573,33574,33575,33576,33577,33578,33579,33580,33581,33582,33583,33584,33585,33586,33587,33588,33589,33590,33591,33592,33593,33594,33595,33596,33597,33598,33599,33600,33601,33602,33603,33604,33605,33606,33607,33608,33609,33610,33611,33612,33613,33614,33615,33616,33617,33618,33619,33620,33621,33622,33623,33624,33625,33626,33627,33628,33629,33630,33631,33632,33633,33634,33635,33636,33637,33638,33639,33640,33641,33642,33643,33644,33645,33646,33647,33648,33649,33650,33651,33652,33653,33654,33655,33656,33657,33658,33659,33660,33661,33662,33663,33664,33665,33666,33667,33668,33669,33670,33671,33672,33673,33674,33675,33676,33677,33678,33679,33680,33681,33682,33683,33684,33685,33686,33687,33688,33689,33690,33691,33692,33693,33694,33695,33696,33697,33698,33699,33700,33701,33702,33703,33704,33705,33706,33707,33708,33709,33710,33711,33712,33713,33714,33715,33716,33717,33718,33719,33720,33721,33722,33723,33724,33725,33726,33727,33728,33729,33730,33731,33732,33733,33734,33735,33736,33737,33738,33739,33740,33741,33742,33743,33744,33745,33746,33747,33748,33749,33750,33751,33752,33753,33754,33755,33756,33757,33758,33759,33760,33761,33762,33763,33764,33765,33766,33767,33768,33769,33770,33771,33772,33773,33774,33775,33776,33777,33778,33779,33780,33781,33782,33783,33784,33785,33786,33787,33788,33789,33790,33791,33792,33793,33794,33795,33796,33797,33798,33799,33800,33801,33802,33803,33804,33805,33806,33807,33808,33809,33810,33811,33812,33813,33814,33815,33816,33817,33818,33819,33820,33821,33822,33823,33824,33825,33826,33827,33828,33829,33830,33831,33832,33833,33834,33835,33836,33837,33838,33839,33840,33841,33842,33843,33844,33845,33846,33847,33848,33849,33850,33851,33852,33853,33854,33855,33856,33857,33858,33859,33860,33861,33862,33863,33864,33865,33866,33867,33868,33869,33870,33871,33872,33873,33874,33875,33876,33877,33878,33879,33880,33881,33882,33883,33884,33885,33886,33887,33888,33889,33890,33891,33892,33893,33894,33895,33896,33897,33898,33899,33900,33901,33902,33903,33904,33905,33906,33907,33908,33909,33910,33911,33912,33913,33914,33915,33916,33917,33918,33919,33920,33921,33922,33923,33924,33925,33926,33927,33928,33929,33930,33931,33932,33933,33934,33935,33936,33937,33938,33939,33940,33941,33942,33943,33944,33945,33946,33947,33948,33949,33950,33951,33952,33953,33954,33955,33956,33957,33958,33959,33960,33961,33962,33963,33964,33965,33966,33967,33968,33969,33970,33971,33972,33973,33974,33975,33976,33977,33978,33979,33980,33981,33982,33983,33984,33985,33986,33987,33988,33989,33990,33991,33992,33993,33994,33995,33996,33997,33998,33999,34000,34001,34002,34003,34004,34005,34006,34007,34008,34009,34010,34011,34012,34013,34014,34015,34016,34017,34018,34019,34020,34021,34022,34023,34024,34025,34026,34027,34028,34029,34030,34031,34032,34033,34034,34035,34036,34037,34038,34039,34040,34041,34042,34043,34044,34045,34046,34047,34048,34049,34050,34051,34052,34053,34054,34055,34056,34057,34058,34059,34060,34061,34062,34063,34064,34065,34066,34067,34068,34069,34070,34071,34072,34073,34074,34075,34076,34077,34078,34079,34080,34081,34082,34083,34084,34085,34086,34087,34088,34089,34090,34091,34092,34093,34094,34095,34096,34097,34098,34099,34100,34101,34102,34103,34104,34105,34106,34107,34108,34109,34110,34111,34112,34113,34114,34115,34116,34117,34118,34119,34120,34121,34122,34123,34124,34125,34126,34127,34128,34129,34130,34131,34132,34133,34134,34135,34136,34137,34138,34139,34140,34141,34142,34143,34144,34145,34146,34147,34148,34149,34150,34151,34152,34153,34154,34155,34156,34157,34158,34159,34160,34161,34162,34163,34164,34165,34166,34167,34168,34169,34170,34171,34172,34173,34174,34175,34176,34177,34178,34179,34180,34181,34182,34183,34184,34185,34186,34187,34188,34189,34190,34191,34192,34193,34194,34195,34196,34197,34198,34199,34200,34201,34202,34203,34204,34205,34206,34207,34208,34209,34210,34211,34212,34213,34214,34215,34216,34217,34218,34219,34220,34221,34222,34223,34224,34225,34226,34227,34228,34229,34230,34231,34232,34233,34234,34235,34236,34237,34238,34239,34240,34241,34242,34243,34244,34245,34246,34247,34248,34249,34250,34251,34252,34253,34254,34255,34256,34257,34258,34259,34260,34261,34262,34263,34264,34265,34266,34267,34268,34269,34270,34271,34272,34273,34274,34275,34276,34277,34278,34279,34280,34281,34282,34283,34284,34285,34286,34287,34288,34289,34290,34291,34292,34293,34294,34295,34296,34297,34298,34299,34300,34301,34302,34303,34304,34305,34306,34307,34308,34309,34310,34311,34312,34313,34314,34315,34316,34317,34318,34319,34320,34321,34322,34323,34324,34325,34326,34327,34328,34329,34330,34331,34332,34333,34334,34335,34336,34337,34338,34339,34340,34341,34342,34343,34344,34345,34346,34347,34348,34349,34350,34351,34352,34353,34354,34355,34356,34357,34358,34359,34360,34361,34362,34363,34364,34365,34366,34367,34368,34369,34370,34371,34372,34373,34374,34375,34376,34377,34378,34379,34380,34381,34382,34383,34384,34385,34386,34387,34388,34389,34390,34391,34392,34393,34394,34395,34396,34397,34398,34399,34400,34401,34402,34403,34404,34405,34406,34407,34408,34409,34410,34411,34412,34413,34414,34415,34416,34417,34418,34419,34420,34421,34422,34423,34424,34425,34426,34427,34428,34429,34430,34431,34432,34433,34434,34435,34436,34437,34438,34439,34440,34441,34442,34443,34444,34445,34446,34447,34448,34449,34450,34451,34452,34453,34454,34455,34456,34457,34458,34459,34460,34461,34462,34463,34464,34465,34466,34467,34468,34469,34470,34471,34472,34473,34474,34475,34476,34477,34478,34479,34480,34481,34482,34483,34484,34485,34486,34487,34488,34489,34490,34491,34492,34493,34494,34495,34496,34497,34498,34499,34500,34501,34502,34503,34504,34505,34506,34507,34508,34509,34510,34511,34512,34513,34514,34515,34516,34517,34518,34519,34520,34521,34522,34523,34524,34525,34526,34527,34528,34529,34530,34531,34532,34533,34534,34535,34536,34537,34538,34539,34540,34541,34542,34543,34544,34545,34546,34547,34548,34549,34550,34551,34552,34553,34554,34555,34556,34557,34558,34559,34560,34561,34562,34563,34564,34565,34566,34567,34568,34569,34570,34571,34572,34573,34574,34575,34576,34577,34578,34579,34580,34581,34582,34583,34584,34585,34586,34587,34588,34589,34590,34591,34592,34593,34594,34595,34596,34597,34598,34599,34600,34601,34602,34603,34604,34605,34606,34607,34608,34609,34610,34611,34612,34613,34614,34615,34616,34617,34618,34619,34620,34621,34622,34623,34624,34625,34626,34627,34628,34629,34630,34631,34632,34633,34634,34635,34636,34637,34638,34639,34640,34641,34642,34643,34644,34645,34646,34647,34648,34649,34650,34651,34652,34653,34654,34655,34656,34657,34658,34659,34660,34661,34662,34663,34664,34665,34666,34667,34668,34669,34670,34671,34672,34673,34674,34675,34676,34677,34678,34679,34680,34681,34682,34683,34684,34685,34686,34687,34688,34689,34690,34691,34692,34693,34694,34695,34696,34697,34698,34699,34700,34701,34702,34703,34704,34705,34706,34707,34708,34709,34710,34711,34712,34713,34714,34715,34716,34717,34718,34719,34720,34721,34722,34723,34724,34725,34726,34727,34728,34729,34730,34731,34732,34733,34734,34735,34736,34737,34738,34739,34740,34741,34742,34743,34744,34745,34746,34747,34748,34749,34750,34751,34752,34753,34754,34755,34756,34757,34758,34759,34760,34761,34762,34763,34764,34765,34766,34767,34768,34769,34770,34771,34772,34773,34774,34775,34776,34777,34778,34779,34780,34781,34782,34783,34784,34785,34786,34787,34788,34789,34790,34791,34792,34793,34794,34795,34796,34797,34798,34799,34800,34801,34802,34803,34804,34805,34806,34807,34808,34809,34810,34811,34812,34813,34814,34815,34816,34817,34818,34819,34820,34821,34822,34823,34824,34825,34826,34827,34828,34829,34830,34831,34832,34833,34834,34835,34836,34837,34838,34839,34840,34841,34842,34843,34844,34845,34846,34847,34848,34849,34850,34851,34852,34853,34854,34855,34856,34857,34858,34859,34860,34861,34862,34863,34864,34865,34866,34867,34868,34869,34870,34871,34872,34873,34874,34875,34876,34877,34878,34879,34880,34881,34882,34883,34884,34885,34886,34887,34888,34889,34890,34891,34892,34893,34894,34895,34896,34897,34898,34899,34900,34901,34902,34903,34904,34905,34906,34907,34908,34909,34910,34911,34912,34913,34914,34915,34916,34917,34918,34919,34920,34921,34922,34923,34924,34925,34926,34927,34928,34929,34930,34931,34932,34933,34934,34935,34936,34937,34938,34939,34940,34941,34942,34943,34944,34945,34946,34947,34948,34949,34950,34951,34952,34953,34954,34955,34956,34957,34958,34959,34960,34961,34962,34963,34964,34965,34966,34967,34968,34969,34970,34971,34972,34973,34974,34975,34976,34977,34978,34979,34980,34981,34982,34983,34984,34985,34986,34987,34988,34989,34990,34991,34992,34993,34994,34995,34996,34997,34998,34999,35000,35001,35002,35003,35004,35005,35006,35007,35008,35009,35010,35011,35012,35013,35014,35015,35016,35017,35018,35019,35020,35021,35022,35023,35024,35025,35026,35027,35028,35029,35030,35031,35032,35033,35034,35035,35036,35037,35038,35039,35040,35041,35042,35043,35044,35045,35046,35047,35048,35049,35050,35051,35052,35053,35054,35055,35056,35057,35058,35059,35060,35061,35062,35063,35064,35065,35066,35067,35068,35069,35070,35071,35072,35073,35074,35075,35076,35077,35078,35079,35080,35081,35082,35083,35084,35085,35086,35087,35088,35089,35090,35091,35092,35093,35094,35095,35096,35097,35098,35099,35100,35101,35102,35103,35104,35105,35106,35107,35108,35109,35110,35111,35112,35113,35114,35115,35116,35117,35118,35119,35120,35121,35122,35123,35124,35125,35126,35127,35128,35129,35130,35131,35132,35133,35134,35135,35136,35137,35138,35139,35140,35141,35142,35143,35144,35145,35146,35147,35148,35149,35150,35151,35152,35153,35154,35155,35156,35157,35158,35159,35160,35161,35162,35163,35164,35165,35166,35167,35168,35169,35170,35171,35172,35173,35174,35175,35176,35177,35178,35179,35180,35181,35182,35183,35184,35185,35186,35187,35188,35189,35190,35191,35192,35193,35194,35195,35196,35197,35198,35199,35200,35201,35202,35203,35204,35205,35206,35207,35208,35209,35210,35211,35212,35213,35214,35215,35216,35217,35218,35219,35220,35221,35222,35223,35224,35225,35226,35227,35228,35229,35230,35231,35232,35233,35234,35235,35236,35237,35238,35239,35240,35241,35242,35243,35244,35245,35246,35247,35248,35249,35250,35251,35252,35253,35254,35255,35256,35257,35258,35259,35260,35261,35262,35263,35264,35265,35266,35267,35268,35269,35270,35271,35272,35273,35274,35275,35276,35277,35278,35279,35280,35281,35282,35283,35284,35285,35286,35287,35288,35289,35290,35291,35292,35293,35294,35295,35296,35297,35298,35299,35300,35301,35302,35303,35304,35305,35306,35307,35308,35309,35310,35311,35312,35313,35314,35315,35316,35317,35318,35319,35320,35321,35322,35323,35324,35325,35326,35327,35328,35329,35330,35331,35332,35333,35334,35335,35336,35337,35338,35339,35340,35341,35342,35343,35344,35345,35346,35347,35348,35349,35350,35351,35352,35353,35354,35355,35356,35357,35358,35359,35360,35361,35362,35363,35364,35365,35366,35367,35368,35369,35370,35371,35372,35373,35374,35375,35376,35377,35378,35379,35380,35381,35382,35383,35384,35385,35386,35387,35388,35389,35390,35391,35392,35393,35394,35395,35396,35397,35398,35399,35400,35401,35402,35403,35404,35405,35406,35407,35408,35409,35410,35411,35412,35413,35414,35415,35416,35417,35418,35419,35420,35421,35422,35423,35424,35425,35426,35427,35428,35429,35430,35431,35432,35433,35434,35435,35436,35437,35438,35439,35440,35441,35442,35443,35444,35445,35446,35447,35448,35449,35450,35451,35452,35453,35454,35455,35456,35457,35458,35459,35460,35461,35462,35463,35464,35465,35466,35467,35468,35469,35470,35471,35472,35473,35474,35475,35476,35477,35478,35479,35480,35481,35482,35483,35484,35485,35486,35487,35488,35489,35490,35491,35492,35493,35494,35495,35496,35497,35498,35499,35500,35501,35502,35503,35504,35505,35506,35507,35508,35509,35510,35511,35512,35513,35514,35515,35516,35517,35518,35519,35520,35521,35522,35523,35524,35525,35526,35527,35528,35529,35530,35531,35532,35533,35534,35535,35536,35537,35538,35539,35540,35541,35542,35543,35544,35545,35546,35547,35548,35549,35550,35551,35552,35553,35554,35555,35556,35557,35558,35559,35560,35561,35562,35563,35564,35565,35566,35567,35568,35569,35570,35571,35572,35573,35574,35575,35576,35577,35578,35579,35580,35581,35582,35583,35584,35585,35586,35587,35588,35589,35590,35591,35592,35593,35594,35595,35596,35597,35598,35599,35600,35601,35602,35603,35604,35605,35606,35607,35608,35609,35610,35611,35612,35613,35614,35615,35616,35617,35618,35619,35620,35621,35622,35623,35624,35625,35626,35627,35628,35629,35630,35631,35632,35633,35634,35635,35636,35637,35638,35639,35640,35641,35642,35643,35644,35645,35646,35647,35648,35649,35650,35651,35652,35653,35654,35655,35656,35657,35658,35659,35660,35661,35662,35663,35664,35665,35666,35667,35668,35669,35670,35671,35672,35673,35674,35675,35676,35677,35678,35679,35680,35681,35682,35683,35684,35685,35686,35687,35688,35689,35690,35691,35692,35693,35694,35695,35696,35697,35698,35699,35700,35701,35702,35703,35704,35705,35706,35707,35708,35709,35710,35711,35712,35713,35714,35715,35716,35717,35718,35719,35720,35721,35722,35723,35724,35725,35726,35727,35728,35729,35730,35731,35732,35733,35734,35735,35736,35737,35738,35739,35740,35741,35742,35743,35744,35745,35746,35747,35748,35749,35750,35751,35752,35753,35754,35755,35756,35757,35758,35759,35760,35761,35762,35763,35764,35765,35766,35767,35768,35769,35770,35771,35772,35773,35774,35775,35776,35777,35778,35779,35780,35781,35782,35783,35784,35785,35786,35787,35788,35789,35790,35791,35792,35793,35794,35795,35796,35797,35798,35799,35800,35801,35802,35803,35804,35805,35806,35807,35808,35809,35810,35811,35812,35813,35814,35815,35816,35817,35818,35819,35820,35821,35822,35823,35824,35825,35826,35827,35828,35829,35830,35831,35832,35833,35834,35835,35836,35837,35838,35839,35840,35841,35842,35843,35844,35845,35846,35847,35848,35849,35850,35851,35852,35853,35854,35855,35856,35857,35858,35859,35860,35861,35862,35863,35864,35865,35866,35867,35868,35869,35870,35871,35872,35873,35874,35875,35876,35877,35878,35879,35880,35881,35882,35883,35884,35885,35886,35887,35888,35889,35890,35891,35892,35893,35894,35895,35896,35897,35898,35899,35900,35901,35902,35903,35904,35905,35906,35907,35908,35909,35910,35911,35912,35913,35914,35915,35916,35917,35918,35919,35920,35921,35922,35923,35924,35925,35926,35927,35928,35929,35930,35931,35932,35933,35934,35935,35936,35937,35938,35939,35940,35941,35942,35943,35944,35945,35946,35947,35948,35949,35950,35951,35952,35953,35954,35955,35956,35957,35958,35959,35960,35961,35962,35963,35964,35965,35966,35967,35968,35969,35970,35971,35972,35973,35974,35975,35976,35977,35978,35979,35980,35981,35982,35983,35984,35985,35986,35987,35988,35989,35990,35991,35992,35993,35994,35995,35996,35997,35998,35999,36000,36001,36002,36003,36004,36005,36006,36007,36008,36009,36010,36011,36012,36013,36014,36015,36016,36017,36018,36019,36020,36021,36022,36023,36024,36025,36026,36027,36028,36029,36030,36031,36032,36033,36034,36035,36036,36037,36038,36039,36040,36041,36042,36043,36044,36045,36046,36047,36048,36049,36050,36051,36052,36053,36054,36055,36056,36057,36058,36059,36060,36061,36062,36063,36064,36065,36066,36067,36068,36069,36070,36071,36072,36073,36074,36075,36076,36077,36078,36079,36080,36081,36082,36083,36084,36085,36086,36087,36088,36089,36090,36091,36092,36093,36094,36095,36096,36097,36098,36099,36100,36101,36102,36103,36104,36105,36106,36107,36108,36109,36110,36111,36112,36113,36114,36115,36116,36117,36118,36119,36120,36121,36122,36123,36124,36125,36126,36127,36128,36129,36130,36131,36132,36133,36134,36135,36136,36137,36138,36139,36140,36141,36142,36143,36144,36145,36146,36147,36148,36149,36150,36151,36152,36153,36154,36155,36156,36157,36158,36159,36160,36161,36162,36163,36164,36165,36166,36167,36168,36169,36170,36171,36172,36173,36174,36175,36176,36177,36178,36179,36180,36181,36182,36183,36184,36185,36186,36187,36188,36189,36190,36191,36192,36193,36194,36195,36196,36197,36198,36199,36200,36201,36202,36203,36204,36205,36206,36207,36208,36209,36210,36211,36212,36213,36214,36215,36216,36217,36218,36219,36220,36221,36222,36223,36224,36225,36226,36227,36228,36229,36230,36231,36232,36233,36234,36235,36236,36237,36238,36239,36240,36241,36242,36243,36244,36245,36246,36247,36248,36249,36250,36251,36252,36253,36254,36255,36256,36257,36258,36259,36260,36261,36262,36263,36264,36265,36266,36267,36268,36269,36270,36271,36272,36273,36274,36275,36276,36277,36278,36279,36280,36281,36282,36283,36284,36285,36286,36287,36288,36289,36290,36291,36292,36293,36294,36295,36296,36297,36298,36299,36300,36301,36302,36303,36304,36305,36306,36307,36308,36309,36310,36311,36312,36313,36314,36315,36316,36317,36318,36319,36320,36321,36322,36323,36324,36325,36326,36327,36328,36329,36330,36331,36332,36333,36334,36335,36336,36337,36338,36339,36340,36341,36342,36343,36344,36345,36346,36347,36348,36349,36350,36351,36352,36353,36354,36355,36356,36357,36358,36359,36360,36361,36362,36363,36364,36365,36366,36367,36368,36369,36370,36371,36372,36373,36374,36375,36376,36377,36378,36379,36380,36381,36382,36383,36384,36385,36386,36387,36388,36389,36390,36391,36392,36393,36394,36395,36396,36397,36398,36399,36400,36401,36402,36403,36404,36405,36406,36407,36408,36409,36410,36411,36412,36413,36414,36415,36416,36417,36418,36419,36420,36421,36422,36423,36424,36425,36426,36427,36428,36429,36430,36431,36432,36433,36434,36435,36436,36437,36438,36439,36440,36441,36442,36443,36444,36445,36446,36447,36448,36449,36450,36451,36452,36453,36454,36455,36456,36457,36458,36459,36460,36461,36462,36463,36464,36465,36466,36467,36468,36469,36470,36471,36472,36473,36474,36475,36476,36477,36478,36479,36480,36481,36482,36483,36484,36485,36486,36487,36488,36489,36490,36491,36492,36493,36494,36495,36496,36497,36498,36499,36500,36501,36502,36503,36504,36505,36506,36507,36508,36509,36510,36511,36512,36513,36514,36515,36516,36517,36518,36519,36520,36521,36522,36523,36524,36525,36526,36527,36528,36529,36530,36531,36532,36533,36534,36535,36536,36537,36538,36539,36540,36541,36542,36543,36544,36545,36546,36547,36548,36549,36550,36551,36552,36553,36554,36555,36556,36557,36558,36559,36560,36561,36562,36563,36564,36565,36566,36567,36568,36569,36570,36571,36572,36573,36574,36575,36576,36577,36578,36579,36580,36581,36582,36583,36584,36585,36586,36587,36588,36589,36590,36591,36592,36593,36594,36595,36596,36597,36598,36599,36600,36601,36602,36603,36604,36605,36606,36607,36608,36609,36610,36611,36612,36613,36614,36615,36616,36617,36618,36619,36620,36621,36622,36623,36624,36625,36626,36627,36628,36629,36630,36631,36632,36633,36634,36635,36636,36637,36638,36639,36640,36641,36642,36643,36644,36645,36646,36647,36648,36649,36650,36651,36652,36653,36654,36655,36656,36657,36658,36659,36660,36661,36662,36663,36664,36665,36666,36667,36668,36669,36670,36671,36672,36673,36674,36675,36676,36677,36678,36679,36680,36681,36682,36683,36684,36685,36686,36687,36688,36689,36690,36691,36692,36693,36694,36695,36696,36697,36698,36699,36700,36701,36702,36703,36704,36705,36706,36707,36708,36709,36710,36711,36712,36713,36714,36715,36716,36717,36718,36719,36720,36721,36722,36723,36724,36725,36726,36727,36728,36729,36730,36731,36732,36733,36734,36735,36736,36737,36738,36739,36740,36741,36742,36743,36744,36745,36746,36747,36748,36749,36750,36751,36752,36753,36754,36755,36756,36757,36758,36759,36760,36761,36762,36763,36764,36765,36766,36767,36768,36769,36770,36771,36772,36773,36774,36775,36776,36777,36778,36779,36780,36781,36782,36783,36784,36785,36786,36787,36788,36789,36790,36791,36792,36793,36794,36795,36796,36797,36798,36799,36800,36801,36802,36803,36804,36805,36806,36807,36808,36809,36810,36811,36812,36813,36814,36815,36816,36817,36818,36819,36820,36821,36822,36823,36824,36825,36826,36827,36828,36829,36830,36831,36832,36833,36834,36835,36836,36837,36838,36839,36840,36841,36842,36843,36844,36845,36846,36847,36848,36849,36850,36851,36852,36853,36854,36855,36856,36857,36858,36859,36860,36861,36862,36863,36864,36865,36866,36867,36868,36869,36870,36871,36872,36873,36874,36875,36876,36877,36878,36879,36880,36881,36882,36883,36884,36885,36886,36887,36888,36889,36890,36891,36892,36893,36894,36895,36896,36897,36898,36899,36900,36901,36902,36903,36904,36905,36906,36907,36908,36909,36910,36911,36912,36913,36914,36915,36916,36917,36918,36919,36920,36921,36922,36923,36924,36925,36926,36927,36928,36929,36930,36931,36932,36933,36934,36935,36936,36937,36938,36939,36940,36941,36942,36943,36944,36945,36946,36947,36948,36949,36950,36951,36952,36953,36954,36955,36956,36957,36958,36959,36960,36961,36962,36963,36964,36965,36966,36967,36968,36969,36970,36971,36972,36973,36974,36975,36976,36977,36978,36979,36980,36981,36982,36983,36984,36985,36986,36987,36988,36989,36990,36991,36992,36993,36994,36995,36996,36997,36998,36999,37000,37001,37002,37003,37004,37005,37006,37007,37008,37009,37010,37011,37012,37013,37014,37015,37016,37017,37018,37019,37020,37021,37022,37023,37024,37025,37026,37027,37028,37029,37030,37031,37032,37033,37034,37035,37036,37037,37038,37039,37040,37041,37042,37043,37044,37045,37046,37047,37048,37049,37050,37051,37052,37053,37054,37055,37056,37057,37058,37059,37060,37061,37062,37063,37064,37065,37066,37067,37068,37069,37070,37071,37072,37073,37074,37075,37076,37077,37078,37079,37080,37081,37082,37083,37084,37085,37086,37087,37088,37089,37090,37091,37092,37093,37094,37095,37096,37097,37098,37099,37100,37101,37102,37103,37104,37105,37106,37107,37108,37109,37110,37111,37112,37113,37114,37115,37116,37117,37118,37119,37120,37121,37122,37123,37124,37125,37126,37127,37128,37129,37130,37131,37132,37133,37134,37135,37136,37137,37138,37139,37140,37141,37142,37143,37144,37145,37146,37147,37148,37149,37150,37151,37152,37153,37154,37155,37156,37157,37158,37159,37160,37161,37162,37163,37164,37165,37166,37167,37168,37169,37170,37171,37172,37173,37174,37175,37176,37177,37178,37179,37180,37181,37182,37183,37184,37185,37186,37187,37188,37189,37190,37191,37192,37193,37194,37195,37196,37197,37198,37199,37200,37201,37202,37203,37204,37205,37206,37207,37208,37209,37210,37211,37212,37213,37214,37215,37216,37217,37218,37219,37220,37221,37222,37223,37224,37225,37226,37227,37228,37229,37230,37231,37232,37233,37234,37235,37236,37237,37238,37239,37240,37241,37242,37243,37244,37245,37246,37247,37248,37249,37250,37251,37252,37253,37254,37255,37256,37257,37258,37259,37260,37261,37262,37263,37264,37265,37266,37267,37268,37269,37270,37271,37272,37273,37274,37275,37276,37277,37278,37279,37280,37281,37282,37283,37284,37285,37286,37287,37288,37289,37290,37291,37292,37293,37294,37295,37296,37297,37298,37299,37300,37301,37302,37303,37304,37305,37306,37307,37308,37309,37310,37311,37312,37313,37314,37315,37316,37317,37318,37319,37320,37321,37322,37323,37324,37325,37326,37327,37328,37329,37330,37331,37332,37333,37334,37335,37336,37337,37338,37339,37340,37341,37342,37343,37344,37345,37346,37347,37348,37349,37350,37351,37352,37353,37354,37355,37356,37357,37358,37359,37360,37361,37362,37363,37364,37365,37366,37367,37368,37369,37370,37371,37372,37373,37374,37375,37376,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,37387,37388,37389,37390,37391,37392,37393,37394,37395,37396,37397,37398,37399,37400,37401,37402,37403,37404,37405,37406,37407,37408,37409,37410,37411,37412,37413,37414,37415,37416,37417,37418,37419,37420,37421,37422,37423,37424,37425,37426,37427,37428,37429,37430,37431,37432,37433,37434,37435,37436,37437,37438,37439,37440,37441,37442,37443,37444,37445,37446,37447,37448,37449,37450,37451,37452,37453,37454,37455,37456,37457,37458,37459,37460,37461,37462,37463,37464,37465,37466,37467,37468,37469,37470,37471,37472,37473,37474,37475,37476,37477,37478,37479,37480,37481,37482,37483,37484,37485,37486,37487,37488,37489,37490,37491,37492,37493,37494,37495,37496,37497,37498,37499,37500,37501,37502,37503,37504,37505,37506,37507,37508,37509,37510,37511,37512,37513,37514,37515,37516,37517,37518,37519,37520,37521,37522,37523,37524,37525,37526,37527,37528,37529,37530,37531,37532,37533,37534,37535,37536,37537,37538,37539,37540,37541,37542,37543,37544,37545,37546,37547,37548,37549,37550,37551,37552,37553,37554,37555,37556,37557,37558,37559,37560,37561,37562,37563,37564,37565,37566,37567,37568,37569,37570,37571,37572,37573,37574,37575,37576,37577,37578,37579,37580,37581,37582,37583,37584,37585,37586,37587,37588,37589,37590,37591,37592,37593,37594,37595,37596,37597,37598,37599,37600,37601,37602,37603,37604,37605,37606,37607,37608,37609,37610,37611,37612,37613,37614,37615,37616,37617,37618,37619,37620,37621,37622,37623,37624,37625,37626,37627,37628,37629,37630,37631,37632,37633,37634,37635,37636,37637,37638,37639,37640,37641,37642,37643,37644,37645,37646,37647,37648,37649,37650,37651,37652,37653,37654,37655,37656,37657,37658,37659,37660,37661,37662,37663,37664,37665,37666,37667,37668,37669,37670,37671,37672,37673,37674,37675,37676,37677,37678,37679,37680,37681,37682,37683,37684,37685,37686,37687,37688,37689,37690,37691,37692,37693,37694,37695,37696,37697,37698,37699,37700,37701,37702,37703,37704,37705,37706,37707,37708,37709,37710,37711,37712,37713,37714,37715,37716,37717,37718,37719,37720,37721,37722,37723,37724,37725,37726,37727,37728,37729,37730,37731,37732,37733,37734,37735,37736,37737,37738,37739,37740,37741,37742,37743,37744,37745,37746,37747,37748,37749,37750,37751,37752,37753,37754,37755,37756,37757,37758,37759,37760,37761,37762,37763,37764,37765,37766,37767,37768,37769,37770,37771,37772,37773,37774,37775,37776,37777,37778,37779,37780,37781,37782,37783,37784,37785,37786,37787,37788,37789,37790,37791,37792,37793,37794,37795,37796,37797,37798,37799,37800,37801,37802,37803,37804,37805,37806,37807,37808,37809,37810,37811,37812,37813,37814,37815,37816,37817,37818,37819,37820,37821,37822,37823,37824,37825,37826,37827,37828,37829,37830,37831,37832,37833,37834,37835,37836,37837,37838,37839,37840,37841,37842,37843,37844,37845,37846,37847,37848,37849,37850,37851,37852,37853,37854,37855,37856,37857,37858,37859,37860,37861,37862,37863,37864,37865,37866,37867,37868,37869,37870,37871,37872,37873,37874,37875,37876,37877,37878,37879,37880,37881,37882,37883,37884,37885,37886,37887,37888,37889,37890,37891,37892,37893,37894,37895,37896,37897,37898,37899,37900,37901,37902,37903,37904,37905,37906,37907,37908,37909,37910,37911,37912,37913,37914,37915,37916,37917,37918,37919,37920,37921,37922,37923,37924,37925,37926,37927,37928,37929,37930,37931,37932,37933,37934,37935,37936,37937,37938,37939,37940,37941,37942,37943,37944,37945,37946,37947,37948,37949,37950,37951,37952,37953,37954,37955,37956,37957,37958,37959,37960,37961,37962,37963,37964,37965,37966,37967,37968,37969,37970,37971,37972,37973,37974,37975,37976,37977,37978,37979,37980,37981,37982,37983,37984,37985,37986,37987,37988,37989,37990,37991,37992,37993,37994,37995,37996,37997,37998,37999,38000,38001,38002,38003,38004,38005,38006,38007,38008,38009,38010,38011,38012,38013,38014,38015,38016,38017,38018,38019,38020,38021,38022,38023,38024,38025,38026,38027,38028,38029,38030,38031,38032,38033,38034,38035,38036,38037,38038,38039,38040,38041,38042,38043,38044,38045,38046,38047,38048,38049,38050,38051,38052,38053,38054,38055,38056,38057,38058,38059,38060,38061,38062,38063,38064,38065,38066,38067,38068,38069,38070,38071,38072,38073,38074,38075,38076,38077,38078,38079,38080,38081,38082,38083,38084,38085,38086,38087,38088,38089,38090,38091,38092,38093,38094,38095,38096,38097,38098,38099,38100,38101,38102,38103,38104,38105,38106,38107,38108,38109,38110,38111,38112,38113,38114,38115,38116,38117,38118,38119,38120,38121,38122,38123,38124,38125,38126,38127,38128,38129,38130,38131,38132,38133,38134,38135,38136,38137,38138,38139,38140,38141,38142,38143,38144,38145,38146,38147,38148,38149,38150,38151,38152,38153,38154,38155,38156,38157,38158,38159,38160,38161,38162,38163,38164,38165,38166,38167,38168,38169,38170,38171,38172,38173,38174,38175,38176,38177,38178,38179,38180,38181,38182,38183,38184,38185,38186,38187,38188,38189,38190,38191,38192,38193,38194,38195,38196,38197,38198,38199,38200,38201,38202,38203,38204,38205,38206,38207,38208,38209,38210,38211,38212,38213,38214,38215,38216,38217,38218,38219,38220,38221,38222,38223,38224,38225,38226,38227,38228,38229,38230,38231,38232,38233,38234,38235,38236,38237,38238,38239,38240,38241,38242,38243,38244,38245,38246,38247,38248,38249,38250,38251,38252,38253,38254,38255,38256,38257,38258,38259,38260,38261,38262,38263,38264,38265,38266,38267,38268,38269,38270,38271,38272,38273,38274,38275,38276,38277,38278,38279,38280,38281,38282,38283,38284,38285,38286,38287,38288,38289,38290,38291,38292,38293,38294,38295,38296,38297,38298,38299,38300,38301,38302,38303,38304,38305,38306,38307,38308,38309,38310,38311,38312,38313,38314,38315,38316,38317,38318,38319,38320,38321,38322,38323,38324,38325,38326,38327,38328,38329,38330,38331,38332,38333,38334,38335,38336,38337,38338,38339,38340,38341,38342,38343,38344,38345,38346,38347,38348,38349,38350,38351,38352,38353,38354,38355,38356,38357,38358,38359,38360,38361,38362,38363,38364,38365,38366,38367,38368,38369,38370,38371,38372,38373,38374,38375,38376,38377,38378,38379,38380,38381,38382,38383,38384,38385,38386,38387,38388,38389,38390,38391,38392,38393,38394,38395,38396,38397,38398,38399,38400,38401,38402,38403,38404,38405,38406,38407,38408,38409,38410,38411,38412,38413,38414,38415,38416,38417,38418,38419,38420,38421,38422,38423,38424,38425,38426,38427,38428,38429,38430,38431,38432,38433,38434,38435,38436,38437,38438,38439,38440,38441,38442,38443,38444,38445,38446,38447,38448,38449,38450,38451,38452,38453,38454,38455,38456,38457,38458,38459,38460,38461,38462,38463,38464,38465,38466,38467,38468,38469,38470,38471,38472,38473,38474,38475,38476,38477,38478,38479,38480,38481,38482,38483,38484,38485,38486,38487,38488,38489,38490,38491,38492,38493,38494,38495,38496,38497,38498,38499,38500,38501,38502,38503,38504,38505,38506,38507,38508,38509,38510,38511,38512,38513,38514,38515,38516,38517,38518,38519,38520,38521,38522,38523,38524,38525,38526,38527,38528,38529,38530,38531,38532,38533,38534,38535,38536,38537,38538,38539,38540,38541,38542,38543,38544,38545,38546,38547,38548,38549,38550,38551,38552,38553,38554,38555,38556,38557,38558,38559,38560,38561,38562,38563,38564,38565,38566,38567,38568,38569,38570,38571,38572,38573,38574,38575,38576,38577,38578,38579,38580,38581,38582,38583,38584,38585,38586,38587,38588,38589,38590,38591,38592,38593,38594,38595,38596,38597,38598,38599,38600,38601,38602,38603,38604,38605,38606,38607,38608,38609,38610,38611,38612,38613,38614,38615,38616,38617,38618,38619,38620,38621,38622,38623,38624,38625,38626,38627,38628,38629,38630,38631,38632,38633,38634,38635,38636,38637,38638,38639,38640,38641,38642,38643,38644,38645,38646,38647,38648,38649,38650,38651,38652,38653,38654,38655,38656,38657,38658,38659,38660,38661,38662,38663,38664,38665,38666,38667,38668,38669,38670,38671,38672,38673,38674,38675,38676,38677,38678,38679,38680,38681,38682,38683,38684,38685,38686,38687,38688,38689,38690,38691,38692,38693,38694,38695,38696,38697,38698,38699,38700,38701,38702,38703,38704,38705,38706,38707,38708,38709,38710,38711,38712,38713,38714,38715,38716,38717,38718,38719,38720,38721,38722,38723,38724,38725,38726,38727,38728,38729,38730,38731,38732,38733,38734,38735,38736,38737,38738,38739,38740,38741,38742,38743,38744,38745,38746,38747,38748,38749,38750,38751,38752,38753,38754,38755,38756,38757,38758,38759,38760,38761,38762,38763,38764,38765,38766,38767,38768,38769,38770,38771,38772,38773,38774,38775,38776,38777,38778,38779,38780,38781,38782,38783,38784,38785,38786,38787,38788,38789,38790,38791,38792,38793,38794,38795,38796,38797,38798,38799,38800,38801,38802,38803,38804,38805,38806,38807,38808,38809,38810,38811,38812,38813,38814,38815,38816,38817,38818,38819,38820,38821,38822,38823,38824,38825,38826,38827,38828,38829,38830,38831,38832,38833,38834,38835,38836,38837,38838,38839,38840,38841,38842,38843,38844,38845,38846,38847,38848,38849,38850,38851,38852,38853,38854,38855,38856,38857,38858,38859,38860,38861,38862,38863,38864,38865,38866,38867,38868,38869,38870,38871,38872,38873,38874,38875,38876,38877,38878,38879,38880,38881,38882,38883,38884,38885,38886,38887,38888,38889,38890,38891,38892,38893,38894,38895,38896,38897,38898,38899,38900,38901,38902,38903,38904,38905,38906,38907,38908,38909,38910,38911,38912,38913,38914,38915,38916,38917,38918,38919,38920,38921,38922,38923,38924,38925,38926,38927,38928,38929,38930,38931,38932,38933,38934,38935,38936,38937,38938,38939,38940,38941,38942,38943,38944,38945,38946,38947,38948,38949,38950,38951,38952,38953,38954,38955,38956,38957,38958,38959,38960,38961,38962,38963,38964,38965,38966,38967,38968,38969,38970,38971,38972,38973,38974,38975,38976,38977,38978,38979,38980,38981,38982,38983,38984,38985,38986,38987,38988,38989,38990,38991,38992,38993,38994,38995,38996,38997,38998,38999,39000,39001,39002,39003,39004,39005,39006,39007,39008,39009,39010,39011,39012,39013,39014,39015,39016,39017,39018,39019,39020,39021,39022,39023,39024,39025,39026,39027,39028,39029,39030,39031,39032,39033,39034,39035,39036,39037,39038,39039,39040,39041,39042,39043,39044,39045,39046,39047,39048,39049,39050,39051,39052,39053,39054,39055,39056,39057,39058,39059,39060,39061,39062,39063,39064,39065,39066,39067,39068,39069,39070,39071,39072,39073,39074,39075,39076,39077,39078,39079,39080,39081,39082,39083,39084,39085,39086,39087,39088,39089,39090,39091,39092,39093,39094,39095,39096,39097,39098,39099,39100,39101,39102,39103,39104,39105,39106,39107,39108,39109,39110,39111,39112,39113,39114,39115,39116,39117,39118,39119,39120,39121,39122,39123,39124,39125,39126,39127,39128,39129,39130,39131,39132,39133,39134,39135,39136,39137,39138,39139,39140,39141,39142,39143,39144,39145,39146,39147,39148,39149,39150,39151,39152,39153,39154,39155,39156,39157,39158,39159,39160,39161,39162,39163,39164,39165,39166,39167,39168,39169,39170,39171,39172,39173,39174,39175,39176,39177,39178,39179,39180,39181,39182,39183,39184,39185,39186,39187,39188,39189,39190,39191,39192,39193,39194,39195,39196,39197,39198,39199,39200,39201,39202,39203,39204,39205,39206,39207,39208,39209,39210,39211,39212,39213,39214,39215,39216,39217,39218,39219,39220,39221,39222,39223,39224,39225,39226,39227,39228,39229,39230,39231,39232,39233,39234,39235,39236,39237,39238,39239,39240,39241,39242,39243,39244,39245,39246,39247,39248,39249,39250,39251,39252,39253,39254,39255,39256,39257,39258,39259,39260,39261,39262,39263,39264,39265,39266,39267,39268,39269,39270,39271,39272,39273,39274,39275,39276,39277,39278,39279,39280,39281,39282,39283,39284,39285,39286,39287,39288,39289,39290,39291,39292,39293,39294,39295,39296,39297,39298,39299,39300,39301,39302,39303,39304,39305,39306,39307,39308,39309,39310,39311,39312,39313,39314,39315,39316,39317,39318,39319,39320,39321,39322,39323,39324,39325,39326,39327,39328,39329,39330,39331,39332,39333,39334,39335,39336,39337,39338,39339,39340,39341,39342,39343,39344,39345,39346,39347,39348,39349,39350,39351,39352,39353,39354,39355,39356,39357,39358,39359,39360,39361,39362,39363,39364,39365,39366,39367,39368,39369,39370,39371,39372,39373,39374,39375,39376,39377,39378,39379,39380,39381,39382,39383,39384,39385,39386,39387,39388,39389,39390,39391,39392,39393,39394,39395,39396,39397,39398,39399,39400,39401,39402,39403,39404,39405,39406,39407,39408,39409,39410,39411,39412,39413,39414,39415,39416,39417,39418,39419,39420,39421,39422,39423,39424,39425,39426,39427,39428,39429,39430,39431,39432,39433,39434,39435,39436,39437,39438,39439,39440,39441,39442,39443,39444,39445,39446,39447,39448,39449,39450,39451,39452,39453,39454,39455,39456,39457,39458,39459,39460,39461,39462,39463,39464,39465,39466,39467,39468,39469,39470,39471,39472,39473,39474,39475,39476,39477,39478,39479,39480,39481,39482,39483,39484,39485,39486,39487,39488,39489,39490,39491,39492,39493,39494,39495,39496,39497,39498,39499,39500,39501,39502,39503,39504,39505,39506,39507,39508,39509,39510,39511,39512,39513,39514,39515,39516,39517,39518,39519,39520,39521,39522,39523,39524,39525,39526,39527,39528,39529,39530,39531,39532,39533,39534,39535,39536,39537,39538,39539,39540,39541,39542,39543,39544,39545,39546,39547,39548,39549,39550,39551,39552,39553,39554,39555,39556,39557,39558,39559,39560,39561,39562,39563,39564,39565,39566,39567,39568,39569,39570,39571,39572,39573,39574,39575,39576,39577,39578,39579,39580,39581,39582,39583,39584,39585,39586,39587,39588,39589,39590,39591,39592,39593,39594,39595,39596,39597,39598,39599,39600,39601,39602,39603,39604,39605,39606,39607,39608,39609,39610,39611,39612,39613,39614,39615,39616,39617,39618,39619,39620,39621,39622,39623,39624,39625,39626,39627,39628,39629,39630,39631,39632,39633,39634,39635,39636,39637,39638,39639,39640,39641,39642,39643,39644,39645,39646,39647,39648,39649,39650,39651,39652,39653,39654,39655,39656,39657,39658,39659,39660,39661,39662,39663,39664,39665,39666,39667,39668,39669,39670,39671,39672,39673,39674,39675,39676,39677,39678,39679,39680,39681,39682,39683,39684,39685,39686,39687,39688,39689,39690,39691,39692,39693,39694,39695,39696,39697,39698,39699,39700,39701,39702,39703,39704,39705,39706,39707,39708,39709,39710,39711,39712,39713,39714,39715,39716,39717,39718,39719,39720,39721,39722,39723,39724,39725,39726,39727,39728,39729,39730,39731,39732,39733,39734,39735,39736,39737,39738,39739,39740,39741,39742,39743,39744,39745,39746,39747,39748,39749,39750,39751,39752,39753,39754,39755,39756,39757,39758,39759,39760,39761,39762,39763,39764,39765,39766,39767,39768,39769,39770,39771,39772,39773,39774,39775,39776,39777,39778,39779,39780,39781,39782,39783,39784,39785,39786,39787,39788,39789,39790,39791,39792,39793,39794,39795,39796,39797,39798,39799,39800,39801,39802,39803,39804,39805,39806,39807,39808,39809,39810,39811,39812,39813,39814,39815,39816,39817,39818,39819,39820,39821,39822,39823,39824,39825,39826,39827,39828,39829,39830,39831,39832,39833,39834,39835,39836,39837,39838,39839,39840,39841,39842,39843,39844,39845,39846,39847,39848,39849,39850,39851,39852,39853,39854,39855,39856,39857,39858,39859,39860,39861,39862,39863,39864,39865,39866,39867,39868,39869,39870,39871,39872,39873,39874,39875,39876,39877,39878,39879,39880,39881,39882,39883,39884,39885,39886,39887,39888,39889,39890,39891,39892,39893,39894,39895,39896,39897,39898,39899,39900,39901,39902,39903,39904,39905,39906,39907,39908,39909,39910,39911,39912,39913,39914,39915,39916,39917,39918,39919,39920,39921,39922,39923,39924,39925,39926,39927,39928,39929,39930,39931,39932,39933,39934,39935,39936,39937,39938,39939,39940,39941,39942,39943,39944,39945,39946,39947,39948,39949,39950,39951,39952,39953,39954,39955,39956,39957,39958,39959,39960,39961,39962,39963,39964,39965,39966,39967,39968,39969,39970,39971,39972,39973,39974,39975,39976,39977,39978,39979,39980,39981,39982,39983,39984,39985,39986,39987,39988,39989,39990,39991,39992,39993,39994,39995,39996,39997,39998,39999,40000,40001,40002,40003,40004,40005,40006,40007,40008,40009,40010,40011,40012,40013,40014,40015,40016,40017,40018,40019,40020,40021,40022,40023,40024,40025,40026,40027,40028,40029,40030,40031,40032,40033,40034,40035,40036,40037,40038,40039,40040,40041,40042,40043,40044,40045,40046,40047,40048,40049,40050,40051,40052,40053,40054,40055,40056,40057,40058,40059,40060,40061,40062,40063,40064,40065,40066,40067,40068,40069,40070,40071,40072,40073,40074,40075,40076,40077,40078,40079,40080,40081,40082,40083,40084,40085,40086,40087,40088,40089,40090,40091,40092,40093,40094,40095,40096,40097,40098,40099,40100,40101,40102,40103,40104,40105,40106,40107,40108,40109,40110,40111,40112,40113,40114,40115,40116,40117,40118,40119,40120,40121,40122,40123,40124,40125,40126,40127,40128,40129,40130,40131,40132,40133,40134,40135,40136,40137,40138,40139,40140,40141,40142,40143,40144,40145,40146,40147,40148,40149,40150,40151,40152,40153,40154,40155,40156,40157,40158,40159,40160,40161,40162,40163,40164,40165,40166,40167,40168,40169,40170,40171,40172,40173,40174,40175,40176,40177,40178,40179,40180,40181,40182,40183,40184,40185,40186,40187,40188,40189,40190,40191,40192,40193,40194,40195,40196,40197,40198,40199,40200,40201,40202,40203,40204,40205,40206,40207,40208,40209,40210,40211,40212,40213,40214,40215,40216,40217,40218,40219,40220,40221,40222,40223,40224,40225,40226,40227,40228,40229,40230,40231,40232,40233,40234,40235,40236,40237,40238,40239,40240,40241,40242,40243,40244,40245,40246,40247,40248,40249,40250,40251,40252,40253,40254,40255,40256,40257,40258,40259,40260,40261,40262,40263,40264,40265,40266,40267,40268,40269,40270,40271,40272,40273,40274,40275,40276,40277,40278,40279,40280,40281,40282,40283,40284,40285,40286,40287,40288,40289,40290,40291,40292,40293,40294,40295,40296,40297,40298,40299,40300,40301,40302,40303,40304,40305,40306,40307,40308,40309,40310,40311,40312,40313,40314,40315,40316,40317,40318,40319,40320,40321,40322,40323,40324,40325,40326,40327,40328,40329,40330,40331,40332,40333,40334,40335,40336,40337,40338,40339,40340,40341,40342,40343,40344,40345,40346,40347,40348,40349,40350,40351,40352,40353,40354,40355,40356,40357,40358,40359,40360,40361,40362,40363,40364,40365,40366,40367,40368,40369,40370,40371,40372,40373,40374,40375,40376,40377,40378,40379,40380,40381,40382,40383,40384,40385,40386,40387,40388,40389,40390,40391,40392,40393,40394,40395,40396,40397,40398,40399,40400,40401,40402,40403,40404,40405,40406,40407,40408,40409,40410,40411,40412,40413,40414,40415,40416,40417,40418,40419,40420,40421,40422,40423,40424,40425,40426,40427,40428,40429,40430,40431,40432,40433,40434,40435,40436,40437,40438,40439,40440,40441,40442,40443,40444,40445,40446,40447,40448,40449,40450,40451,40452,40453,40454,40455,40456,40457,40458,40459,40460,40461,40462,40463,40464,40465,40466,40467,40468,40469,40470,40471,40472,40473,40474,40475,40476,40477,40478,40479,40480,40481,40482,40483,40484,40485,40486,40487,40488,40489,40490,40491,40492,40493,40494,40495,40496,40497,40498,40499,40500,40501,40502,40503,40504,40505,40506,40507,40508,40509,40510,40511,40512,40513,40514,40515,40516,40517,40518,40519,40520,40521,40522,40523,40524,40525,40526,40527,40528,40529,40530,40531,40532,40533,40534,40535,40536,40537,40538,40539,40540,40541,40542,40543,40544,40545,40546,40547,40548,40549,40550,40551,40552,40553,40554,40555,40556,40557,40558,40559,40560,40561,40562,40563,40564,40565,40566,40567,40568,40569,40570,40571,40572,40573,40574,40575,40576,40577,40578,40579,40580,40581,40582,40583,40584,40585,40586,40587,40588,40589,40590,40591,40592,40593,40594,40595,40596,40597,40598,40599,40600,40601,40602,40603,40604,40605,40606,40607,40608,40609,40610,40611,40612,40613,40614,40615,40616,40617,40618,40619,40620,40621,40622,40623,40624,40625,40626,40627,40628,40629,40630,40631,40632,40633,40634,40635,40636,40637,40638,40639,40640,40641,40642,40643,40644,40645,40646,40647,40648,40649,40650,40651,40652,40653,40654,40655,40656,40657,40658,40659,40660,40661,40662,40663,40664,40665,40666,40667,40668,40669,40670,40671,40672,40673,40674,40675,40676,40677,40678,40679,40680,40681,40682,40683,40684,40685,40686,40687,40688,40689,40690,40691,40692,40693,40694,40695,40696,40697,40698,40699,40700,40701,40702,40703,40704,40705,40706,40707,40708,40709,40710,40711,40712,40713,40714,40715,40716,40717,40718,40719,40720,40721,40722,40723,40724,40725,40726,40727,40728,40729,40730,40731,40732,40733,40734,40735,40736,40737,40738,40739,40740,40741,40742,40743,40744,40745,40746,40747,40748,40749,40750,40751,40752,40753,40754,40755,40756,40757,40758,40759,40760,40761,40762,40763,40764,40765,40766,40767,40768,40769,40770,40771,40772,40773,40774,40775,40776,40777,40778,40779,40780,40781,40782,40783,40784,40785,40786,40787,40788,40789,40790,40791,40792,40793,40794,40795,40796,40797,40798,40799,40800,40801,40802,40803,40804,40805,40806,40807,40808,40809,40810,40811,40812,40813,40814,40815,40816,40817,40818,40819,40820,40821,40822,40823,40824,40825,40826,40827,40828,40829,40830,40831,40832,40833,40834,40835,40836,40837,40838,40839,40840,40841,40842,40843,40844,40845,40846,40847,40848,40849,40850,40851,40852,40853,40854,40855,40856,40857,40858,40859,40860,40861,40862,40863,40864,40865,40866,40867,40868,40869,40870,40871,40872,40873,40874,40875,40876,40877,40878,40879,40880,40881,40882,40883,40884,40885,40886,40887,40888,40889,40890,40891,40892,40893,40894,40895,40896,40897,40898,40899,40900,40901,40902,40903,40904,40905,40906,40907,40908,40960,40961,40962,40963,40964,40965,40966,40967,40968,40969,40970,40971,40972,40973,40974,40975,40976,40977,40978,40979,40980,40981,40982,40983,40984,40985,40986,40987,40988,40989,40990,40991,40992,40993,40994,40995,40996,40997,40998,40999,41000,41001,41002,41003,41004,41005,41006,41007,41008,41009,41010,41011,41012,41013,41014,41015,41016,41017,41018,41019,41020,41021,41022,41023,41024,41025,41026,41027,41028,41029,41030,41031,41032,41033,41034,41035,41036,41037,41038,41039,41040,41041,41042,41043,41044,41045,41046,41047,41048,41049,41050,41051,41052,41053,41054,41055,41056,41057,41058,41059,41060,41061,41062,41063,41064,41065,41066,41067,41068,41069,41070,41071,41072,41073,41074,41075,41076,41077,41078,41079,41080,41081,41082,41083,41084,41085,41086,41087,41088,41089,41090,41091,41092,41093,41094,41095,41096,41097,41098,41099,41100,41101,41102,41103,41104,41105,41106,41107,41108,41109,41110,41111,41112,41113,41114,41115,41116,41117,41118,41119,41120,41121,41122,41123,41124,41125,41126,41127,41128,41129,41130,41131,41132,41133,41134,41135,41136,41137,41138,41139,41140,41141,41142,41143,41144,41145,41146,41147,41148,41149,41150,41151,41152,41153,41154,41155,41156,41157,41158,41159,41160,41161,41162,41163,41164,41165,41166,41167,41168,41169,41170,41171,41172,41173,41174,41175,41176,41177,41178,41179,41180,41181,41182,41183,41184,41185,41186,41187,41188,41189,41190,41191,41192,41193,41194,41195,41196,41197,41198,41199,41200,41201,41202,41203,41204,41205,41206,41207,41208,41209,41210,41211,41212,41213,41214,41215,41216,41217,41218,41219,41220,41221,41222,41223,41224,41225,41226,41227,41228,41229,41230,41231,41232,41233,41234,41235,41236,41237,41238,41239,41240,41241,41242,41243,41244,41245,41246,41247,41248,41249,41250,41251,41252,41253,41254,41255,41256,41257,41258,41259,41260,41261,41262,41263,41264,41265,41266,41267,41268,41269,41270,41271,41272,41273,41274,41275,41276,41277,41278,41279,41280,41281,41282,41283,41284,41285,41286,41287,41288,41289,41290,41291,41292,41293,41294,41295,41296,41297,41298,41299,41300,41301,41302,41303,41304,41305,41306,41307,41308,41309,41310,41311,41312,41313,41314,41315,41316,41317,41318,41319,41320,41321,41322,41323,41324,41325,41326,41327,41328,41329,41330,41331,41332,41333,41334,41335,41336,41337,41338,41339,41340,41341,41342,41343,41344,41345,41346,41347,41348,41349,41350,41351,41352,41353,41354,41355,41356,41357,41358,41359,41360,41361,41362,41363,41364,41365,41366,41367,41368,41369,41370,41371,41372,41373,41374,41375,41376,41377,41378,41379,41380,41381,41382,41383,41384,41385,41386,41387,41388,41389,41390,41391,41392,41393,41394,41395,41396,41397,41398,41399,41400,41401,41402,41403,41404,41405,41406,41407,41408,41409,41410,41411,41412,41413,41414,41415,41416,41417,41418,41419,41420,41421,41422,41423,41424,41425,41426,41427,41428,41429,41430,41431,41432,41433,41434,41435,41436,41437,41438,41439,41440,41441,41442,41443,41444,41445,41446,41447,41448,41449,41450,41451,41452,41453,41454,41455,41456,41457,41458,41459,41460,41461,41462,41463,41464,41465,41466,41467,41468,41469,41470,41471,41472,41473,41474,41475,41476,41477,41478,41479,41480,41481,41482,41483,41484,41485,41486,41487,41488,41489,41490,41491,41492,41493,41494,41495,41496,41497,41498,41499,41500,41501,41502,41503,41504,41505,41506,41507,41508,41509,41510,41511,41512,41513,41514,41515,41516,41517,41518,41519,41520,41521,41522,41523,41524,41525,41526,41527,41528,41529,41530,41531,41532,41533,41534,41535,41536,41537,41538,41539,41540,41541,41542,41543,41544,41545,41546,41547,41548,41549,41550,41551,41552,41553,41554,41555,41556,41557,41558,41559,41560,41561,41562,41563,41564,41565,41566,41567,41568,41569,41570,41571,41572,41573,41574,41575,41576,41577,41578,41579,41580,41581,41582,41583,41584,41585,41586,41587,41588,41589,41590,41591,41592,41593,41594,41595,41596,41597,41598,41599,41600,41601,41602,41603,41604,41605,41606,41607,41608,41609,41610,41611,41612,41613,41614,41615,41616,41617,41618,41619,41620,41621,41622,41623,41624,41625,41626,41627,41628,41629,41630,41631,41632,41633,41634,41635,41636,41637,41638,41639,41640,41641,41642,41643,41644,41645,41646,41647,41648,41649,41650,41651,41652,41653,41654,41655,41656,41657,41658,41659,41660,41661,41662,41663,41664,41665,41666,41667,41668,41669,41670,41671,41672,41673,41674,41675,41676,41677,41678,41679,41680,41681,41682,41683,41684,41685,41686,41687,41688,41689,41690,41691,41692,41693,41694,41695,41696,41697,41698,41699,41700,41701,41702,41703,41704,41705,41706,41707,41708,41709,41710,41711,41712,41713,41714,41715,41716,41717,41718,41719,41720,41721,41722,41723,41724,41725,41726,41727,41728,41729,41730,41731,41732,41733,41734,41735,41736,41737,41738,41739,41740,41741,41742,41743,41744,41745,41746,41747,41748,41749,41750,41751,41752,41753,41754,41755,41756,41757,41758,41759,41760,41761,41762,41763,41764,41765,41766,41767,41768,41769,41770,41771,41772,41773,41774,41775,41776,41777,41778,41779,41780,41781,41782,41783,41784,41785,41786,41787,41788,41789,41790,41791,41792,41793,41794,41795,41796,41797,41798,41799,41800,41801,41802,41803,41804,41805,41806,41807,41808,41809,41810,41811,41812,41813,41814,41815,41816,41817,41818,41819,41820,41821,41822,41823,41824,41825,41826,41827,41828,41829,41830,41831,41832,41833,41834,41835,41836,41837,41838,41839,41840,41841,41842,41843,41844,41845,41846,41847,41848,41849,41850,41851,41852,41853,41854,41855,41856,41857,41858,41859,41860,41861,41862,41863,41864,41865,41866,41867,41868,41869,41870,41871,41872,41873,41874,41875,41876,41877,41878,41879,41880,41881,41882,41883,41884,41885,41886,41887,41888,41889,41890,41891,41892,41893,41894,41895,41896,41897,41898,41899,41900,41901,41902,41903,41904,41905,41906,41907,41908,41909,41910,41911,41912,41913,41914,41915,41916,41917,41918,41919,41920,41921,41922,41923,41924,41925,41926,41927,41928,41929,41930,41931,41932,41933,41934,41935,41936,41937,41938,41939,41940,41941,41942,41943,41944,41945,41946,41947,41948,41949,41950,41951,41952,41953,41954,41955,41956,41957,41958,41959,41960,41961,41962,41963,41964,41965,41966,41967,41968,41969,41970,41971,41972,41973,41974,41975,41976,41977,41978,41979,41980,41981,41982,41983,41984,41985,41986,41987,41988,41989,41990,41991,41992,41993,41994,41995,41996,41997,41998,41999,42000,42001,42002,42003,42004,42005,42006,42007,42008,42009,42010,42011,42012,42013,42014,42015,42016,42017,42018,42019,42020,42021,42022,42023,42024,42025,42026,42027,42028,42029,42030,42031,42032,42033,42034,42035,42036,42037,42038,42039,42040,42041,42042,42043,42044,42045,42046,42047,42048,42049,42050,42051,42052,42053,42054,42055,42056,42057,42058,42059,42060,42061,42062,42063,42064,42065,42066,42067,42068,42069,42070,42071,42072,42073,42074,42075,42076,42077,42078,42079,42080,42081,42082,42083,42084,42085,42086,42087,42088,42089,42090,42091,42092,42093,42094,42095,42096,42097,42098,42099,42100,42101,42102,42103,42104,42105,42106,42107,42108,42109,42110,42111,42112,42113,42114,42115,42116,42117,42118,42119,42120,42121,42122,42123,42124,42192,42193,42194,42195,42196,42197,42198,42199,42200,42201,42202,42203,42204,42205,42206,42207,42208,42209,42210,42211,42212,42213,42214,42215,42216,42217,42218,42219,42220,42221,42222,42223,42224,42225,42226,42227,42228,42229,42230,42231,42232,42233,42234,42235,42236,42237,42240,42241,42242,42243,42244,42245,42246,42247,42248,42249,42250,42251,42252,42253,42254,42255,42256,42257,42258,42259,42260,42261,42262,42263,42264,42265,42266,42267,42268,42269,42270,42271,42272,42273,42274,42275,42276,42277,42278,42279,42280,42281,42282,42283,42284,42285,42286,42287,42288,42289,42290,42291,42292,42293,42294,42295,42296,42297,42298,42299,42300,42301,42302,42303,42304,42305,42306,42307,42308,42309,42310,42311,42312,42313,42314,42315,42316,42317,42318,42319,42320,42321,42322,42323,42324,42325,42326,42327,42328,42329,42330,42331,42332,42333,42334,42335,42336,42337,42338,42339,42340,42341,42342,42343,42344,42345,42346,42347,42348,42349,42350,42351,42352,42353,42354,42355,42356,42357,42358,42359,42360,42361,42362,42363,42364,42365,42366,42367,42368,42369,42370,42371,42372,42373,42374,42375,42376,42377,42378,42379,42380,42381,42382,42383,42384,42385,42386,42387,42388,42389,42390,42391,42392,42393,42394,42395,42396,42397,42398,42399,42400,42401,42402,42403,42404,42405,42406,42407,42408,42409,42410,42411,42412,42413,42414,42415,42416,42417,42418,42419,42420,42421,42422,42423,42424,42425,42426,42427,42428,42429,42430,42431,42432,42433,42434,42435,42436,42437,42438,42439,42440,42441,42442,42443,42444,42445,42446,42447,42448,42449,42450,42451,42452,42453,42454,42455,42456,42457,42458,42459,42460,42461,42462,42463,42464,42465,42466,42467,42468,42469,42470,42471,42472,42473,42474,42475,42476,42477,42478,42479,42480,42481,42482,42483,42484,42485,42486,42487,42488,42489,42490,42491,42492,42493,42494,42495,42496,42497,42498,42499,42500,42501,42502,42503,42504,42505,42506,42507,42508,42512,42513,42514,42515,42516,42517,42518,42519,42520,42521,42522,42523,42524,42525,42526,42527,42538,42539,42560,42561,42562,42563,42564,42565,42566,42567,42568,42569,42570,42571,42572,42573,42574,42575,42576,42577,42578,42579,42580,42581,42582,42583,42584,42585,42586,42587,42588,42589,42590,42591,42592,42593,42594,42595,42596,42597,42598,42599,42600,42601,42602,42603,42604,42605,42606,42623,42624,42625,42626,42627,42628,42629,42630,42631,42632,42633,42634,42635,42636,42637,42638,42639,42640,42641,42642,42643,42644,42645,42646,42647,42656,42657,42658,42659,42660,42661,42662,42663,42664,42665,42666,42667,42668,42669,42670,42671,42672,42673,42674,42675,42676,42677,42678,42679,42680,42681,42682,42683,42684,42685,42686,42687,42688,42689,42690,42691,42692,42693,42694,42695,42696,42697,42698,42699,42700,42701,42702,42703,42704,42705,42706,42707,42708,42709,42710,42711,42712,42713,42714,42715,42716,42717,42718,42719,42720,42721,42722,42723,42724,42725,42726,42727,42728,42729,42730,42731,42732,42733,42734,42735,42775,42776,42777,42778,42779,42780,42781,42782,42783,42786,42787,42788,42789,42790,42791,42792,42793,42794,42795,42796,42797,42798,42799,42800,42801,42802,42803,42804,42805,42806,42807,42808,42809,42810,42811,42812,42813,42814,42815,42816,42817,42818,42819,42820,42821,42822,42823,42824,42825,42826,42827,42828,42829,42830,42831,42832,42833,42834,42835,42836,42837,42838,42839,42840,42841,42842,42843,42844,42845,42846,42847,42848,42849,42850,42851,42852,42853,42854,42855,42856,42857,42858,42859,42860,42861,42862,42863,42864,42865,42866,42867,42868,42869,42870,42871,42872,42873,42874,42875,42876,42877,42878,42879,42880,42881,42882,42883,42884,42885,42886,42887,42888,42891,42892,42893,42894,42896,42897,42898,42899,42912,42913,42914,42915,42916,42917,42918,42919,42920,42921,42922,43000,43001,43002,43003,43004,43005,43006,43007,43008,43009,43011,43012,43013,43015,43016,43017,43018,43020,43021,43022,43023,43024,43025,43026,43027,43028,43029,43030,43031,43032,43033,43034,43035,43036,43037,43038,43039,43040,43041,43042,43072,43073,43074,43075,43076,43077,43078,43079,43080,43081,43082,43083,43084,43085,43086,43087,43088,43089,43090,43091,43092,43093,43094,43095,43096,43097,43098,43099,43100,43101,43102,43103,43104,43105,43106,43107,43108,43109,43110,43111,43112,43113,43114,43115,43116,43117,43118,43119,43120,43121,43122,43123,43138,43139,43140,43141,43142,43143,43144,43145,43146,43147,43148,43149,43150,43151,43152,43153,43154,43155,43156,43157,43158,43159,43160,43161,43162,43163,43164,43165,43166,43167,43168,43169,43170,43171,43172,43173,43174,43175,43176,43177,43178,43179,43180,43181,43182,43183,43184,43185,43186,43187,43250,43251,43252,43253,43254,43255,43259,43274,43275,43276,43277,43278,43279,43280,43281,43282,43283,43284,43285,43286,43287,43288,43289,43290,43291,43292,43293,43294,43295,43296,43297,43298,43299,43300,43301,43312,43313,43314,43315,43316,43317,43318,43319,43320,43321,43322,43323,43324,43325,43326,43327,43328,43329,43330,43331,43332,43333,43334,43360,43361,43362,43363,43364,43365,43366,43367,43368,43369,43370,43371,43372,43373,43374,43375,43376,43377,43378,43379,43380,43381,43382,43383,43384,43385,43386,43387,43388,43396,43397,43398,43399,43400,43401,43402,43403,43404,43405,43406,43407,43408,43409,43410,43411,43412,43413,43414,43415,43416,43417,43418,43419,43420,43421,43422,43423,43424,43425,43426,43427,43428,43429,43430,43431,43432,43433,43434,43435,43436,43437,43438,43439,43440,43441,43442,43471,43520,43521,43522,43523,43524,43525,43526,43527,43528,43529,43530,43531,43532,43533,43534,43535,43536,43537,43538,43539,43540,43541,43542,43543,43544,43545,43546,43547,43548,43549,43550,43551,43552,43553,43554,43555,43556,43557,43558,43559,43560,43584,43585,43586,43588,43589,43590,43591,43592,43593,43594,43595,43616,43617,43618,43619,43620,43621,43622,43623,43624,43625,43626,43627,43628,43629,43630,43631,43632,43633,43634,43635,43636,43637,43638,43642,43648,43649,43650,43651,43652,43653,43654,43655,43656,43657,43658,43659,43660,43661,43662,43663,43664,43665,43666,43667,43668,43669,43670,43671,43672,43673,43674,43675,43676,43677,43678,43679,43680,43681,43682,43683,43684,43685,43686,43687,43688,43689,43690,43691,43692,43693,43694,43695,43697,43701,43702,43705,43706,43707,43708,43709,43712,43714,43739,43740,43741,43744,43745,43746,43747,43748,43749,43750,43751,43752,43753,43754,43762,43763,43764,43777,43778,43779,43780,43781,43782,43785,43786,43787,43788,43789,43790,43793,43794,43795,43796,43797,43798,43808,43809,43810,43811,43812,43813,43814,43816,43817,43818,43819,43820,43821,43822,43968,43969,43970,43971,43972,43973,43974,43975,43976,43977,43978,43979,43980,43981,43982,43983,43984,43985,43986,43987,43988,43989,43990,43991,43992,43993,43994,43995,43996,43997,43998,43999,44000,44001,44002,44032,44033,44034,44035,44036,44037,44038,44039,44040,44041,44042,44043,44044,44045,44046,44047,44048,44049,44050,44051,44052,44053,44054,44055,44056,44057,44058,44059,44060,44061,44062,44063,44064,44065,44066,44067,44068,44069,44070,44071,44072,44073,44074,44075,44076,44077,44078,44079,44080,44081,44082,44083,44084,44085,44086,44087,44088,44089,44090,44091,44092,44093,44094,44095,44096,44097,44098,44099,44100,44101,44102,44103,44104,44105,44106,44107,44108,44109,44110,44111,44112,44113,44114,44115,44116,44117,44118,44119,44120,44121,44122,44123,44124,44125,44126,44127,44128,44129,44130,44131,44132,44133,44134,44135,44136,44137,44138,44139,44140,44141,44142,44143,44144,44145,44146,44147,44148,44149,44150,44151,44152,44153,44154,44155,44156,44157,44158,44159,44160,44161,44162,44163,44164,44165,44166,44167,44168,44169,44170,44171,44172,44173,44174,44175,44176,44177,44178,44179,44180,44181,44182,44183,44184,44185,44186,44187,44188,44189,44190,44191,44192,44193,44194,44195,44196,44197,44198,44199,44200,44201,44202,44203,44204,44205,44206,44207,44208,44209,44210,44211,44212,44213,44214,44215,44216,44217,44218,44219,44220,44221,44222,44223,44224,44225,44226,44227,44228,44229,44230,44231,44232,44233,44234,44235,44236,44237,44238,44239,44240,44241,44242,44243,44244,44245,44246,44247,44248,44249,44250,44251,44252,44253,44254,44255,44256,44257,44258,44259,44260,44261,44262,44263,44264,44265,44266,44267,44268,44269,44270,44271,44272,44273,44274,44275,44276,44277,44278,44279,44280,44281,44282,44283,44284,44285,44286,44287,44288,44289,44290,44291,44292,44293,44294,44295,44296,44297,44298,44299,44300,44301,44302,44303,44304,44305,44306,44307,44308,44309,44310,44311,44312,44313,44314,44315,44316,44317,44318,44319,44320,44321,44322,44323,44324,44325,44326,44327,44328,44329,44330,44331,44332,44333,44334,44335,44336,44337,44338,44339,44340,44341,44342,44343,44344,44345,44346,44347,44348,44349,44350,44351,44352,44353,44354,44355,44356,44357,44358,44359,44360,44361,44362,44363,44364,44365,44366,44367,44368,44369,44370,44371,44372,44373,44374,44375,44376,44377,44378,44379,44380,44381,44382,44383,44384,44385,44386,44387,44388,44389,44390,44391,44392,44393,44394,44395,44396,44397,44398,44399,44400,44401,44402,44403,44404,44405,44406,44407,44408,44409,44410,44411,44412,44413,44414,44415,44416,44417,44418,44419,44420,44421,44422,44423,44424,44425,44426,44427,44428,44429,44430,44431,44432,44433,44434,44435,44436,44437,44438,44439,44440,44441,44442,44443,44444,44445,44446,44447,44448,44449,44450,44451,44452,44453,44454,44455,44456,44457,44458,44459,44460,44461,44462,44463,44464,44465,44466,44467,44468,44469,44470,44471,44472,44473,44474,44475,44476,44477,44478,44479,44480,44481,44482,44483,44484,44485,44486,44487,44488,44489,44490,44491,44492,44493,44494,44495,44496,44497,44498,44499,44500,44501,44502,44503,44504,44505,44506,44507,44508,44509,44510,44511,44512,44513,44514,44515,44516,44517,44518,44519,44520,44521,44522,44523,44524,44525,44526,44527,44528,44529,44530,44531,44532,44533,44534,44535,44536,44537,44538,44539,44540,44541,44542,44543,44544,44545,44546,44547,44548,44549,44550,44551,44552,44553,44554,44555,44556,44557,44558,44559,44560,44561,44562,44563,44564,44565,44566,44567,44568,44569,44570,44571,44572,44573,44574,44575,44576,44577,44578,44579,44580,44581,44582,44583,44584,44585,44586,44587,44588,44589,44590,44591,44592,44593,44594,44595,44596,44597,44598,44599,44600,44601,44602,44603,44604,44605,44606,44607,44608,44609,44610,44611,44612,44613,44614,44615,44616,44617,44618,44619,44620,44621,44622,44623,44624,44625,44626,44627,44628,44629,44630,44631,44632,44633,44634,44635,44636,44637,44638,44639,44640,44641,44642,44643,44644,44645,44646,44647,44648,44649,44650,44651,44652,44653,44654,44655,44656,44657,44658,44659,44660,44661,44662,44663,44664,44665,44666,44667,44668,44669,44670,44671,44672,44673,44674,44675,44676,44677,44678,44679,44680,44681,44682,44683,44684,44685,44686,44687,44688,44689,44690,44691,44692,44693,44694,44695,44696,44697,44698,44699,44700,44701,44702,44703,44704,44705,44706,44707,44708,44709,44710,44711,44712,44713,44714,44715,44716,44717,44718,44719,44720,44721,44722,44723,44724,44725,44726,44727,44728,44729,44730,44731,44732,44733,44734,44735,44736,44737,44738,44739,44740,44741,44742,44743,44744,44745,44746,44747,44748,44749,44750,44751,44752,44753,44754,44755,44756,44757,44758,44759,44760,44761,44762,44763,44764,44765,44766,44767,44768,44769,44770,44771,44772,44773,44774,44775,44776,44777,44778,44779,44780,44781,44782,44783,44784,44785,44786,44787,44788,44789,44790,44791,44792,44793,44794,44795,44796,44797,44798,44799,44800,44801,44802,44803,44804,44805,44806,44807,44808,44809,44810,44811,44812,44813,44814,44815,44816,44817,44818,44819,44820,44821,44822,44823,44824,44825,44826,44827,44828,44829,44830,44831,44832,44833,44834,44835,44836,44837,44838,44839,44840,44841,44842,44843,44844,44845,44846,44847,44848,44849,44850,44851,44852,44853,44854,44855,44856,44857,44858,44859,44860,44861,44862,44863,44864,44865,44866,44867,44868,44869,44870,44871,44872,44873,44874,44875,44876,44877,44878,44879,44880,44881,44882,44883,44884,44885,44886,44887,44888,44889,44890,44891,44892,44893,44894,44895,44896,44897,44898,44899,44900,44901,44902,44903,44904,44905,44906,44907,44908,44909,44910,44911,44912,44913,44914,44915,44916,44917,44918,44919,44920,44921,44922,44923,44924,44925,44926,44927,44928,44929,44930,44931,44932,44933,44934,44935,44936,44937,44938,44939,44940,44941,44942,44943,44944,44945,44946,44947,44948,44949,44950,44951,44952,44953,44954,44955,44956,44957,44958,44959,44960,44961,44962,44963,44964,44965,44966,44967,44968,44969,44970,44971,44972,44973,44974,44975,44976,44977,44978,44979,44980,44981,44982,44983,44984,44985,44986,44987,44988,44989,44990,44991,44992,44993,44994,44995,44996,44997,44998,44999,45000,45001,45002,45003,45004,45005,45006,45007,45008,45009,45010,45011,45012,45013,45014,45015,45016,45017,45018,45019,45020,45021,45022,45023,45024,45025,45026,45027,45028,45029,45030,45031,45032,45033,45034,45035,45036,45037,45038,45039,45040,45041,45042,45043,45044,45045,45046,45047,45048,45049,45050,45051,45052,45053,45054,45055,45056,45057,45058,45059,45060,45061,45062,45063,45064,45065,45066,45067,45068,45069,45070,45071,45072,45073,45074,45075,45076,45077,45078,45079,45080,45081,45082,45083,45084,45085,45086,45087,45088,45089,45090,45091,45092,45093,45094,45095,45096,45097,45098,45099,45100,45101,45102,45103,45104,45105,45106,45107,45108,45109,45110,45111,45112,45113,45114,45115,45116,45117,45118,45119,45120,45121,45122,45123,45124,45125,45126,45127,45128,45129,45130,45131,45132,45133,45134,45135,45136,45137,45138,45139,45140,45141,45142,45143,45144,45145,45146,45147,45148,45149,45150,45151,45152,45153,45154,45155,45156,45157,45158,45159,45160,45161,45162,45163,45164,45165,45166,45167,45168,45169,45170,45171,45172,45173,45174,45175,45176,45177,45178,45179,45180,45181,45182,45183,45184,45185,45186,45187,45188,45189,45190,45191,45192,45193,45194,45195,45196,45197,45198,45199,45200,45201,45202,45203,45204,45205,45206,45207,45208,45209,45210,45211,45212,45213,45214,45215,45216,45217,45218,45219,45220,45221,45222,45223,45224,45225,45226,45227,45228,45229,45230,45231,45232,45233,45234,45235,45236,45237,45238,45239,45240,45241,45242,45243,45244,45245,45246,45247,45248,45249,45250,45251,45252,45253,45254,45255,45256,45257,45258,45259,45260,45261,45262,45263,45264,45265,45266,45267,45268,45269,45270,45271,45272,45273,45274,45275,45276,45277,45278,45279,45280,45281,45282,45283,45284,45285,45286,45287,45288,45289,45290,45291,45292,45293,45294,45295,45296,45297,45298,45299,45300,45301,45302,45303,45304,45305,45306,45307,45308,45309,45310,45311,45312,45313,45314,45315,45316,45317,45318,45319,45320,45321,45322,45323,45324,45325,45326,45327,45328,45329,45330,45331,45332,45333,45334,45335,45336,45337,45338,45339,45340,45341,45342,45343,45344,45345,45346,45347,45348,45349,45350,45351,45352,45353,45354,45355,45356,45357,45358,45359,45360,45361,45362,45363,45364,45365,45366,45367,45368,45369,45370,45371,45372,45373,45374,45375,45376,45377,45378,45379,45380,45381,45382,45383,45384,45385,45386,45387,45388,45389,45390,45391,45392,45393,45394,45395,45396,45397,45398,45399,45400,45401,45402,45403,45404,45405,45406,45407,45408,45409,45410,45411,45412,45413,45414,45415,45416,45417,45418,45419,45420,45421,45422,45423,45424,45425,45426,45427,45428,45429,45430,45431,45432,45433,45434,45435,45436,45437,45438,45439,45440,45441,45442,45443,45444,45445,45446,45447,45448,45449,45450,45451,45452,45453,45454,45455,45456,45457,45458,45459,45460,45461,45462,45463,45464,45465,45466,45467,45468,45469,45470,45471,45472,45473,45474,45475,45476,45477,45478,45479,45480,45481,45482,45483,45484,45485,45486,45487,45488,45489,45490,45491,45492,45493,45494,45495,45496,45497,45498,45499,45500,45501,45502,45503,45504,45505,45506,45507,45508,45509,45510,45511,45512,45513,45514,45515,45516,45517,45518,45519,45520,45521,45522,45523,45524,45525,45526,45527,45528,45529,45530,45531,45532,45533,45534,45535,45536,45537,45538,45539,45540,45541,45542,45543,45544,45545,45546,45547,45548,45549,45550,45551,45552,45553,45554,45555,45556,45557,45558,45559,45560,45561,45562,45563,45564,45565,45566,45567,45568,45569,45570,45571,45572,45573,45574,45575,45576,45577,45578,45579,45580,45581,45582,45583,45584,45585,45586,45587,45588,45589,45590,45591,45592,45593,45594,45595,45596,45597,45598,45599,45600,45601,45602,45603,45604,45605,45606,45607,45608,45609,45610,45611,45612,45613,45614,45615,45616,45617,45618,45619,45620,45621,45622,45623,45624,45625,45626,45627,45628,45629,45630,45631,45632,45633,45634,45635,45636,45637,45638,45639,45640,45641,45642,45643,45644,45645,45646,45647,45648,45649,45650,45651,45652,45653,45654,45655,45656,45657,45658,45659,45660,45661,45662,45663,45664,45665,45666,45667,45668,45669,45670,45671,45672,45673,45674,45675,45676,45677,45678,45679,45680,45681,45682,45683,45684,45685,45686,45687,45688,45689,45690,45691,45692,45693,45694,45695,45696,45697,45698,45699,45700,45701,45702,45703,45704,45705,45706,45707,45708,45709,45710,45711,45712,45713,45714,45715,45716,45717,45718,45719,45720,45721,45722,45723,45724,45725,45726,45727,45728,45729,45730,45731,45732,45733,45734,45735,45736,45737,45738,45739,45740,45741,45742,45743,45744,45745,45746,45747,45748,45749,45750,45751,45752,45753,45754,45755,45756,45757,45758,45759,45760,45761,45762,45763,45764,45765,45766,45767,45768,45769,45770,45771,45772,45773,45774,45775,45776,45777,45778,45779,45780,45781,45782,45783,45784,45785,45786,45787,45788,45789,45790,45791,45792,45793,45794,45795,45796,45797,45798,45799,45800,45801,45802,45803,45804,45805,45806,45807,45808,45809,45810,45811,45812,45813,45814,45815,45816,45817,45818,45819,45820,45821,45822,45823,45824,45825,45826,45827,45828,45829,45830,45831,45832,45833,45834,45835,45836,45837,45838,45839,45840,45841,45842,45843,45844,45845,45846,45847,45848,45849,45850,45851,45852,45853,45854,45855,45856,45857,45858,45859,45860,45861,45862,45863,45864,45865,45866,45867,45868,45869,45870,45871,45872,45873,45874,45875,45876,45877,45878,45879,45880,45881,45882,45883,45884,45885,45886,45887,45888,45889,45890,45891,45892,45893,45894,45895,45896,45897,45898,45899,45900,45901,45902,45903,45904,45905,45906,45907,45908,45909,45910,45911,45912,45913,45914,45915,45916,45917,45918,45919,45920,45921,45922,45923,45924,45925,45926,45927,45928,45929,45930,45931,45932,45933,45934,45935,45936,45937,45938,45939,45940,45941,45942,45943,45944,45945,45946,45947,45948,45949,45950,45951,45952,45953,45954,45955,45956,45957,45958,45959,45960,45961,45962,45963,45964,45965,45966,45967,45968,45969,45970,45971,45972,45973,45974,45975,45976,45977,45978,45979,45980,45981,45982,45983,45984,45985,45986,45987,45988,45989,45990,45991,45992,45993,45994,45995,45996,45997,45998,45999,46000,46001,46002,46003,46004,46005,46006,46007,46008,46009,46010,46011,46012,46013,46014,46015,46016,46017,46018,46019,46020,46021,46022,46023,46024,46025,46026,46027,46028,46029,46030,46031,46032,46033,46034,46035,46036,46037,46038,46039,46040,46041,46042,46043,46044,46045,46046,46047,46048,46049,46050,46051,46052,46053,46054,46055,46056,46057,46058,46059,46060,46061,46062,46063,46064,46065,46066,46067,46068,46069,46070,46071,46072,46073,46074,46075,46076,46077,46078,46079,46080,46081,46082,46083,46084,46085,46086,46087,46088,46089,46090,46091,46092,46093,46094,46095,46096,46097,46098,46099,46100,46101,46102,46103,46104,46105,46106,46107,46108,46109,46110,46111,46112,46113,46114,46115,46116,46117,46118,46119,46120,46121,46122,46123,46124,46125,46126,46127,46128,46129,46130,46131,46132,46133,46134,46135,46136,46137,46138,46139,46140,46141,46142,46143,46144,46145,46146,46147,46148,46149,46150,46151,46152,46153,46154,46155,46156,46157,46158,46159,46160,46161,46162,46163,46164,46165,46166,46167,46168,46169,46170,46171,46172,46173,46174,46175,46176,46177,46178,46179,46180,46181,46182,46183,46184,46185,46186,46187,46188,46189,46190,46191,46192,46193,46194,46195,46196,46197,46198,46199,46200,46201,46202,46203,46204,46205,46206,46207,46208,46209,46210,46211,46212,46213,46214,46215,46216,46217,46218,46219,46220,46221,46222,46223,46224,46225,46226,46227,46228,46229,46230,46231,46232,46233,46234,46235,46236,46237,46238,46239,46240,46241,46242,46243,46244,46245,46246,46247,46248,46249,46250,46251,46252,46253,46254,46255,46256,46257,46258,46259,46260,46261,46262,46263,46264,46265,46266,46267,46268,46269,46270,46271,46272,46273,46274,46275,46276,46277,46278,46279,46280,46281,46282,46283,46284,46285,46286,46287,46288,46289,46290,46291,46292,46293,46294,46295,46296,46297,46298,46299,46300,46301,46302,46303,46304,46305,46306,46307,46308,46309,46310,46311,46312,46313,46314,46315,46316,46317,46318,46319,46320,46321,46322,46323,46324,46325,46326,46327,46328,46329,46330,46331,46332,46333,46334,46335,46336,46337,46338,46339,46340,46341,46342,46343,46344,46345,46346,46347,46348,46349,46350,46351,46352,46353,46354,46355,46356,46357,46358,46359,46360,46361,46362,46363,46364,46365,46366,46367,46368,46369,46370,46371,46372,46373,46374,46375,46376,46377,46378,46379,46380,46381,46382,46383,46384,46385,46386,46387,46388,46389,46390,46391,46392,46393,46394,46395,46396,46397,46398,46399,46400,46401,46402,46403,46404,46405,46406,46407,46408,46409,46410,46411,46412,46413,46414,46415,46416,46417,46418,46419,46420,46421,46422,46423,46424,46425,46426,46427,46428,46429,46430,46431,46432,46433,46434,46435,46436,46437,46438,46439,46440,46441,46442,46443,46444,46445,46446,46447,46448,46449,46450,46451,46452,46453,46454,46455,46456,46457,46458,46459,46460,46461,46462,46463,46464,46465,46466,46467,46468,46469,46470,46471,46472,46473,46474,46475,46476,46477,46478,46479,46480,46481,46482,46483,46484,46485,46486,46487,46488,46489,46490,46491,46492,46493,46494,46495,46496,46497,46498,46499,46500,46501,46502,46503,46504,46505,46506,46507,46508,46509,46510,46511,46512,46513,46514,46515,46516,46517,46518,46519,46520,46521,46522,46523,46524,46525,46526,46527,46528,46529,46530,46531,46532,46533,46534,46535,46536,46537,46538,46539,46540,46541,46542,46543,46544,46545,46546,46547,46548,46549,46550,46551,46552,46553,46554,46555,46556,46557,46558,46559,46560,46561,46562,46563,46564,46565,46566,46567,46568,46569,46570,46571,46572,46573,46574,46575,46576,46577,46578,46579,46580,46581,46582,46583,46584,46585,46586,46587,46588,46589,46590,46591,46592,46593,46594,46595,46596,46597,46598,46599,46600,46601,46602,46603,46604,46605,46606,46607,46608,46609,46610,46611,46612,46613,46614,46615,46616,46617,46618,46619,46620,46621,46622,46623,46624,46625,46626,46627,46628,46629,46630,46631,46632,46633,46634,46635,46636,46637,46638,46639,46640,46641,46642,46643,46644,46645,46646,46647,46648,46649,46650,46651,46652,46653,46654,46655,46656,46657,46658,46659,46660,46661,46662,46663,46664,46665,46666,46667,46668,46669,46670,46671,46672,46673,46674,46675,46676,46677,46678,46679,46680,46681,46682,46683,46684,46685,46686,46687,46688,46689,46690,46691,46692,46693,46694,46695,46696,46697,46698,46699,46700,46701,46702,46703,46704,46705,46706,46707,46708,46709,46710,46711,46712,46713,46714,46715,46716,46717,46718,46719,46720,46721,46722,46723,46724,46725,46726,46727,46728,46729,46730,46731,46732,46733,46734,46735,46736,46737,46738,46739,46740,46741,46742,46743,46744,46745,46746,46747,46748,46749,46750,46751,46752,46753,46754,46755,46756,46757,46758,46759,46760,46761,46762,46763,46764,46765,46766,46767,46768,46769,46770,46771,46772,46773,46774,46775,46776,46777,46778,46779,46780,46781,46782,46783,46784,46785,46786,46787,46788,46789,46790,46791,46792,46793,46794,46795,46796,46797,46798,46799,46800,46801,46802,46803,46804,46805,46806,46807,46808,46809,46810,46811,46812,46813,46814,46815,46816,46817,46818,46819,46820,46821,46822,46823,46824,46825,46826,46827,46828,46829,46830,46831,46832,46833,46834,46835,46836,46837,46838,46839,46840,46841,46842,46843,46844,46845,46846,46847,46848,46849,46850,46851,46852,46853,46854,46855,46856,46857,46858,46859,46860,46861,46862,46863,46864,46865,46866,46867,46868,46869,46870,46871,46872,46873,46874,46875,46876,46877,46878,46879,46880,46881,46882,46883,46884,46885,46886,46887,46888,46889,46890,46891,46892,46893,46894,46895,46896,46897,46898,46899,46900,46901,46902,46903,46904,46905,46906,46907,46908,46909,46910,46911,46912,46913,46914,46915,46916,46917,46918,46919,46920,46921,46922,46923,46924,46925,46926,46927,46928,46929,46930,46931,46932,46933,46934,46935,46936,46937,46938,46939,46940,46941,46942,46943,46944,46945,46946,46947,46948,46949,46950,46951,46952,46953,46954,46955,46956,46957,46958,46959,46960,46961,46962,46963,46964,46965,46966,46967,46968,46969,46970,46971,46972,46973,46974,46975,46976,46977,46978,46979,46980,46981,46982,46983,46984,46985,46986,46987,46988,46989,46990,46991,46992,46993,46994,46995,46996,46997,46998,46999,47000,47001,47002,47003,47004,47005,47006,47007,47008,47009,47010,47011,47012,47013,47014,47015,47016,47017,47018,47019,47020,47021,47022,47023,47024,47025,47026,47027,47028,47029,47030,47031,47032,47033,47034,47035,47036,47037,47038,47039,47040,47041,47042,47043,47044,47045,47046,47047,47048,47049,47050,47051,47052,47053,47054,47055,47056,47057,47058,47059,47060,47061,47062,47063,47064,47065,47066,47067,47068,47069,47070,47071,47072,47073,47074,47075,47076,47077,47078,47079,47080,47081,47082,47083,47084,47085,47086,47087,47088,47089,47090,47091,47092,47093,47094,47095,47096,47097,47098,47099,47100,47101,47102,47103,47104,47105,47106,47107,47108,47109,47110,47111,47112,47113,47114,47115,47116,47117,47118,47119,47120,47121,47122,47123,47124,47125,47126,47127,47128,47129,47130,47131,47132,47133,47134,47135,47136,47137,47138,47139,47140,47141,47142,47143,47144,47145,47146,47147,47148,47149,47150,47151,47152,47153,47154,47155,47156,47157,47158,47159,47160,47161,47162,47163,47164,47165,47166,47167,47168,47169,47170,47171,47172,47173,47174,47175,47176,47177,47178,47179,47180,47181,47182,47183,47184,47185,47186,47187,47188,47189,47190,47191,47192,47193,47194,47195,47196,47197,47198,47199,47200,47201,47202,47203,47204,47205,47206,47207,47208,47209,47210,47211,47212,47213,47214,47215,47216,47217,47218,47219,47220,47221,47222,47223,47224,47225,47226,47227,47228,47229,47230,47231,47232,47233,47234,47235,47236,47237,47238,47239,47240,47241,47242,47243,47244,47245,47246,47247,47248,47249,47250,47251,47252,47253,47254,47255,47256,47257,47258,47259,47260,47261,47262,47263,47264,47265,47266,47267,47268,47269,47270,47271,47272,47273,47274,47275,47276,47277,47278,47279,47280,47281,47282,47283,47284,47285,47286,47287,47288,47289,47290,47291,47292,47293,47294,47295,47296,47297,47298,47299,47300,47301,47302,47303,47304,47305,47306,47307,47308,47309,47310,47311,47312,47313,47314,47315,47316,47317,47318,47319,47320,47321,47322,47323,47324,47325,47326,47327,47328,47329,47330,47331,47332,47333,47334,47335,47336,47337,47338,47339,47340,47341,47342,47343,47344,47345,47346,47347,47348,47349,47350,47351,47352,47353,47354,47355,47356,47357,47358,47359,47360,47361,47362,47363,47364,47365,47366,47367,47368,47369,47370,47371,47372,47373,47374,47375,47376,47377,47378,47379,47380,47381,47382,47383,47384,47385,47386,47387,47388,47389,47390,47391,47392,47393,47394,47395,47396,47397,47398,47399,47400,47401,47402,47403,47404,47405,47406,47407,47408,47409,47410,47411,47412,47413,47414,47415,47416,47417,47418,47419,47420,47421,47422,47423,47424,47425,47426,47427,47428,47429,47430,47431,47432,47433,47434,47435,47436,47437,47438,47439,47440,47441,47442,47443,47444,47445,47446,47447,47448,47449,47450,47451,47452,47453,47454,47455,47456,47457,47458,47459,47460,47461,47462,47463,47464,47465,47466,47467,47468,47469,47470,47471,47472,47473,47474,47475,47476,47477,47478,47479,47480,47481,47482,47483,47484,47485,47486,47487,47488,47489,47490,47491,47492,47493,47494,47495,47496,47497,47498,47499,47500,47501,47502,47503,47504,47505,47506,47507,47508,47509,47510,47511,47512,47513,47514,47515,47516,47517,47518,47519,47520,47521,47522,47523,47524,47525,47526,47527,47528,47529,47530,47531,47532,47533,47534,47535,47536,47537,47538,47539,47540,47541,47542,47543,47544,47545,47546,47547,47548,47549,47550,47551,47552,47553,47554,47555,47556,47557,47558,47559,47560,47561,47562,47563,47564,47565,47566,47567,47568,47569,47570,47571,47572,47573,47574,47575,47576,47577,47578,47579,47580,47581,47582,47583,47584,47585,47586,47587,47588,47589,47590,47591,47592,47593,47594,47595,47596,47597,47598,47599,47600,47601,47602,47603,47604,47605,47606,47607,47608,47609,47610,47611,47612,47613,47614,47615,47616,47617,47618,47619,47620,47621,47622,47623,47624,47625,47626,47627,47628,47629,47630,47631,47632,47633,47634,47635,47636,47637,47638,47639,47640,47641,47642,47643,47644,47645,47646,47647,47648,47649,47650,47651,47652,47653,47654,47655,47656,47657,47658,47659,47660,47661,47662,47663,47664,47665,47666,47667,47668,47669,47670,47671,47672,47673,47674,47675,47676,47677,47678,47679,47680,47681,47682,47683,47684,47685,47686,47687,47688,47689,47690,47691,47692,47693,47694,47695,47696,47697,47698,47699,47700,47701,47702,47703,47704,47705,47706,47707,47708,47709,47710,47711,47712,47713,47714,47715,47716,47717,47718,47719,47720,47721,47722,47723,47724,47725,47726,47727,47728,47729,47730,47731,47732,47733,47734,47735,47736,47737,47738,47739,47740,47741,47742,47743,47744,47745,47746,47747,47748,47749,47750,47751,47752,47753,47754,47755,47756,47757,47758,47759,47760,47761,47762,47763,47764,47765,47766,47767,47768,47769,47770,47771,47772,47773,47774,47775,47776,47777,47778,47779,47780,47781,47782,47783,47784,47785,47786,47787,47788,47789,47790,47791,47792,47793,47794,47795,47796,47797,47798,47799,47800,47801,47802,47803,47804,47805,47806,47807,47808,47809,47810,47811,47812,47813,47814,47815,47816,47817,47818,47819,47820,47821,47822,47823,47824,47825,47826,47827,47828,47829,47830,47831,47832,47833,47834,47835,47836,47837,47838,47839,47840,47841,47842,47843,47844,47845,47846,47847,47848,47849,47850,47851,47852,47853,47854,47855,47856,47857,47858,47859,47860,47861,47862,47863,47864,47865,47866,47867,47868,47869,47870,47871,47872,47873,47874,47875,47876,47877,47878,47879,47880,47881,47882,47883,47884,47885,47886,47887,47888,47889,47890,47891,47892,47893,47894,47895,47896,47897,47898,47899,47900,47901,47902,47903,47904,47905,47906,47907,47908,47909,47910,47911,47912,47913,47914,47915,47916,47917,47918,47919,47920,47921,47922,47923,47924,47925,47926,47927,47928,47929,47930,47931,47932,47933,47934,47935,47936,47937,47938,47939,47940,47941,47942,47943,47944,47945,47946,47947,47948,47949,47950,47951,47952,47953,47954,47955,47956,47957,47958,47959,47960,47961,47962,47963,47964,47965,47966,47967,47968,47969,47970,47971,47972,47973,47974,47975,47976,47977,47978,47979,47980,47981,47982,47983,47984,47985,47986,47987,47988,47989,47990,47991,47992,47993,47994,47995,47996,47997,47998,47999,48000,48001,48002,48003,48004,48005,48006,48007,48008,48009,48010,48011,48012,48013,48014,48015,48016,48017,48018,48019,48020,48021,48022,48023,48024,48025,48026,48027,48028,48029,48030,48031,48032,48033,48034,48035,48036,48037,48038,48039,48040,48041,48042,48043,48044,48045,48046,48047,48048,48049,48050,48051,48052,48053,48054,48055,48056,48057,48058,48059,48060,48061,48062,48063,48064,48065,48066,48067,48068,48069,48070,48071,48072,48073,48074,48075,48076,48077,48078,48079,48080,48081,48082,48083,48084,48085,48086,48087,48088,48089,48090,48091,48092,48093,48094,48095,48096,48097,48098,48099,48100,48101,48102,48103,48104,48105,48106,48107,48108,48109,48110,48111,48112,48113,48114,48115,48116,48117,48118,48119,48120,48121,48122,48123,48124,48125,48126,48127,48128,48129,48130,48131,48132,48133,48134,48135,48136,48137,48138,48139,48140,48141,48142,48143,48144,48145,48146,48147,48148,48149,48150,48151,48152,48153,48154,48155,48156,48157,48158,48159,48160,48161,48162,48163,48164,48165,48166,48167,48168,48169,48170,48171,48172,48173,48174,48175,48176,48177,48178,48179,48180,48181,48182,48183,48184,48185,48186,48187,48188,48189,48190,48191,48192,48193,48194,48195,48196,48197,48198,48199,48200,48201,48202,48203,48204,48205,48206,48207,48208,48209,48210,48211,48212,48213,48214,48215,48216,48217,48218,48219,48220,48221,48222,48223,48224,48225,48226,48227,48228,48229,48230,48231,48232,48233,48234,48235,48236,48237,48238,48239,48240,48241,48242,48243,48244,48245,48246,48247,48248,48249,48250,48251,48252,48253,48254,48255,48256,48257,48258,48259,48260,48261,48262,48263,48264,48265,48266,48267,48268,48269,48270,48271,48272,48273,48274,48275,48276,48277,48278,48279,48280,48281,48282,48283,48284,48285,48286,48287,48288,48289,48290,48291,48292,48293,48294,48295,48296,48297,48298,48299,48300,48301,48302,48303,48304,48305,48306,48307,48308,48309,48310,48311,48312,48313,48314,48315,48316,48317,48318,48319,48320,48321,48322,48323,48324,48325,48326,48327,48328,48329,48330,48331,48332,48333,48334,48335,48336,48337,48338,48339,48340,48341,48342,48343,48344,48345,48346,48347,48348,48349,48350,48351,48352,48353,48354,48355,48356,48357,48358,48359,48360,48361,48362,48363,48364,48365,48366,48367,48368,48369,48370,48371,48372,48373,48374,48375,48376,48377,48378,48379,48380,48381,48382,48383,48384,48385,48386,48387,48388,48389,48390,48391,48392,48393,48394,48395,48396,48397,48398,48399,48400,48401,48402,48403,48404,48405,48406,48407,48408,48409,48410,48411,48412,48413,48414,48415,48416,48417,48418,48419,48420,48421,48422,48423,48424,48425,48426,48427,48428,48429,48430,48431,48432,48433,48434,48435,48436,48437,48438,48439,48440,48441,48442,48443,48444,48445,48446,48447,48448,48449,48450,48451,48452,48453,48454,48455,48456,48457,48458,48459,48460,48461,48462,48463,48464,48465,48466,48467,48468,48469,48470,48471,48472,48473,48474,48475,48476,48477,48478,48479,48480,48481,48482,48483,48484,48485,48486,48487,48488,48489,48490,48491,48492,48493,48494,48495,48496,48497,48498,48499,48500,48501,48502,48503,48504,48505,48506,48507,48508,48509,48510,48511,48512,48513,48514,48515,48516,48517,48518,48519,48520,48521,48522,48523,48524,48525,48526,48527,48528,48529,48530,48531,48532,48533,48534,48535,48536,48537,48538,48539,48540,48541,48542,48543,48544,48545,48546,48547,48548,48549,48550,48551,48552,48553,48554,48555,48556,48557,48558,48559,48560,48561,48562,48563,48564,48565,48566,48567,48568,48569,48570,48571,48572,48573,48574,48575,48576,48577,48578,48579,48580,48581,48582,48583,48584,48585,48586,48587,48588,48589,48590,48591,48592,48593,48594,48595,48596,48597,48598,48599,48600,48601,48602,48603,48604,48605,48606,48607,48608,48609,48610,48611,48612,48613,48614,48615,48616,48617,48618,48619,48620,48621,48622,48623,48624,48625,48626,48627,48628,48629,48630,48631,48632,48633,48634,48635,48636,48637,48638,48639,48640,48641,48642,48643,48644,48645,48646,48647,48648,48649,48650,48651,48652,48653,48654,48655,48656,48657,48658,48659,48660,48661,48662,48663,48664,48665,48666,48667,48668,48669,48670,48671,48672,48673,48674,48675,48676,48677,48678,48679,48680,48681,48682,48683,48684,48685,48686,48687,48688,48689,48690,48691,48692,48693,48694,48695,48696,48697,48698,48699,48700,48701,48702,48703,48704,48705,48706,48707,48708,48709,48710,48711,48712,48713,48714,48715,48716,48717,48718,48719,48720,48721,48722,48723,48724,48725,48726,48727,48728,48729,48730,48731,48732,48733,48734,48735,48736,48737,48738,48739,48740,48741,48742,48743,48744,48745,48746,48747,48748,48749,48750,48751,48752,48753,48754,48755,48756,48757,48758,48759,48760,48761,48762,48763,48764,48765,48766,48767,48768,48769,48770,48771,48772,48773,48774,48775,48776,48777,48778,48779,48780,48781,48782,48783,48784,48785,48786,48787,48788,48789,48790,48791,48792,48793,48794,48795,48796,48797,48798,48799,48800,48801,48802,48803,48804,48805,48806,48807,48808,48809,48810,48811,48812,48813,48814,48815,48816,48817,48818,48819,48820,48821,48822,48823,48824,48825,48826,48827,48828,48829,48830,48831,48832,48833,48834,48835,48836,48837,48838,48839,48840,48841,48842,48843,48844,48845,48846,48847,48848,48849,48850,48851,48852,48853,48854,48855,48856,48857,48858,48859,48860,48861,48862,48863,48864,48865,48866,48867,48868,48869,48870,48871,48872,48873,48874,48875,48876,48877,48878,48879,48880,48881,48882,48883,48884,48885,48886,48887,48888,48889,48890,48891,48892,48893,48894,48895,48896,48897,48898,48899,48900,48901,48902,48903,48904,48905,48906,48907,48908,48909,48910,48911,48912,48913,48914,48915,48916,48917,48918,48919,48920,48921,48922,48923,48924,48925,48926,48927,48928,48929,48930,48931,48932,48933,48934,48935,48936,48937,48938,48939,48940,48941,48942,48943,48944,48945,48946,48947,48948,48949,48950,48951,48952,48953,48954,48955,48956,48957,48958,48959,48960,48961,48962,48963,48964,48965,48966,48967,48968,48969,48970,48971,48972,48973,48974,48975,48976,48977,48978,48979,48980,48981,48982,48983,48984,48985,48986,48987,48988,48989,48990,48991,48992,48993,48994,48995,48996,48997,48998,48999,49000,49001,49002,49003,49004,49005,49006,49007,49008,49009,49010,49011,49012,49013,49014,49015,49016,49017,49018,49019,49020,49021,49022,49023,49024,49025,49026,49027,49028,49029,49030,49031,49032,49033,49034,49035,49036,49037,49038,49039,49040,49041,49042,49043,49044,49045,49046,49047,49048,49049,49050,49051,49052,49053,49054,49055,49056,49057,49058,49059,49060,49061,49062,49063,49064,49065,49066,49067,49068,49069,49070,49071,49072,49073,49074,49075,49076,49077,49078,49079,49080,49081,49082,49083,49084,49085,49086,49087,49088,49089,49090,49091,49092,49093,49094,49095,49096,49097,49098,49099,49100,49101,49102,49103,49104,49105,49106,49107,49108,49109,49110,49111,49112,49113,49114,49115,49116,49117,49118,49119,49120,49121,49122,49123,49124,49125,49126,49127,49128,49129,49130,49131,49132,49133,49134,49135,49136,49137,49138,49139,49140,49141,49142,49143,49144,49145,49146,49147,49148,49149,49150,49151,49152,49153,49154,49155,49156,49157,49158,49159,49160,49161,49162,49163,49164,49165,49166,49167,49168,49169,49170,49171,49172,49173,49174,49175,49176,49177,49178,49179,49180,49181,49182,49183,49184,49185,49186,49187,49188,49189,49190,49191,49192,49193,49194,49195,49196,49197,49198,49199,49200,49201,49202,49203,49204,49205,49206,49207,49208,49209,49210,49211,49212,49213,49214,49215,49216,49217,49218,49219,49220,49221,49222,49223,49224,49225,49226,49227,49228,49229,49230,49231,49232,49233,49234,49235,49236,49237,49238,49239,49240,49241,49242,49243,49244,49245,49246,49247,49248,49249,49250,49251,49252,49253,49254,49255,49256,49257,49258,49259,49260,49261,49262,49263,49264,49265,49266,49267,49268,49269,49270,49271,49272,49273,49274,49275,49276,49277,49278,49279,49280,49281,49282,49283,49284,49285,49286,49287,49288,49289,49290,49291,49292,49293,49294,49295,49296,49297,49298,49299,49300,49301,49302,49303,49304,49305,49306,49307,49308,49309,49310,49311,49312,49313,49314,49315,49316,49317,49318,49319,49320,49321,49322,49323,49324,49325,49326,49327,49328,49329,49330,49331,49332,49333,49334,49335,49336,49337,49338,49339,49340,49341,49342,49343,49344,49345,49346,49347,49348,49349,49350,49351,49352,49353,49354,49355,49356,49357,49358,49359,49360,49361,49362,49363,49364,49365,49366,49367,49368,49369,49370,49371,49372,49373,49374,49375,49376,49377,49378,49379,49380,49381,49382,49383,49384,49385,49386,49387,49388,49389,49390,49391,49392,49393,49394,49395,49396,49397,49398,49399,49400,49401,49402,49403,49404,49405,49406,49407,49408,49409,49410,49411,49412,49413,49414,49415,49416,49417,49418,49419,49420,49421,49422,49423,49424,49425,49426,49427,49428,49429,49430,49431,49432,49433,49434,49435,49436,49437,49438,49439,49440,49441,49442,49443,49444,49445,49446,49447,49448,49449,49450,49451,49452,49453,49454,49455,49456,49457,49458,49459,49460,49461,49462,49463,49464,49465,49466,49467,49468,49469,49470,49471,49472,49473,49474,49475,49476,49477,49478,49479,49480,49481,49482,49483,49484,49485,49486,49487,49488,49489,49490,49491,49492,49493,49494,49495,49496,49497,49498,49499,49500,49501,49502,49503,49504,49505,49506,49507,49508,49509,49510,49511,49512,49513,49514,49515,49516,49517,49518,49519,49520,49521,49522,49523,49524,49525,49526,49527,49528,49529,49530,49531,49532,49533,49534,49535,49536,49537,49538,49539,49540,49541,49542,49543,49544,49545,49546,49547,49548,49549,49550,49551,49552,49553,49554,49555,49556,49557,49558,49559,49560,49561,49562,49563,49564,49565,49566,49567,49568,49569,49570,49571,49572,49573,49574,49575,49576,49577,49578,49579,49580,49581,49582,49583,49584,49585,49586,49587,49588,49589,49590,49591,49592,49593,49594,49595,49596,49597,49598,49599,49600,49601,49602,49603,49604,49605,49606,49607,49608,49609,49610,49611,49612,49613,49614,49615,49616,49617,49618,49619,49620,49621,49622,49623,49624,49625,49626,49627,49628,49629,49630,49631,49632,49633,49634,49635,49636,49637,49638,49639,49640,49641,49642,49643,49644,49645,49646,49647,49648,49649,49650,49651,49652,49653,49654,49655,49656,49657,49658,49659,49660,49661,49662,49663,49664,49665,49666,49667,49668,49669,49670,49671,49672,49673,49674,49675,49676,49677,49678,49679,49680,49681,49682,49683,49684,49685,49686,49687,49688,49689,49690,49691,49692,49693,49694,49695,49696,49697,49698,49699,49700,49701,49702,49703,49704,49705,49706,49707,49708,49709,49710,49711,49712,49713,49714,49715,49716,49717,49718,49719,49720,49721,49722,49723,49724,49725,49726,49727,49728,49729,49730,49731,49732,49733,49734,49735,49736,49737,49738,49739,49740,49741,49742,49743,49744,49745,49746,49747,49748,49749,49750,49751,49752,49753,49754,49755,49756,49757,49758,49759,49760,49761,49762,49763,49764,49765,49766,49767,49768,49769,49770,49771,49772,49773,49774,49775,49776,49777,49778,49779,49780,49781,49782,49783,49784,49785,49786,49787,49788,49789,49790,49791,49792,49793,49794,49795,49796,49797,49798,49799,49800,49801,49802,49803,49804,49805,49806,49807,49808,49809,49810,49811,49812,49813,49814,49815,49816,49817,49818,49819,49820,49821,49822,49823,49824,49825,49826,49827,49828,49829,49830,49831,49832,49833,49834,49835,49836,49837,49838,49839,49840,49841,49842,49843,49844,49845,49846,49847,49848,49849,49850,49851,49852,49853,49854,49855,49856,49857,49858,49859,49860,49861,49862,49863,49864,49865,49866,49867,49868,49869,49870,49871,49872,49873,49874,49875,49876,49877,49878,49879,49880,49881,49882,49883,49884,49885,49886,49887,49888,49889,49890,49891,49892,49893,49894,49895,49896,49897,49898,49899,49900,49901,49902,49903,49904,49905,49906,49907,49908,49909,49910,49911,49912,49913,49914,49915,49916,49917,49918,49919,49920,49921,49922,49923,49924,49925,49926,49927,49928,49929,49930,49931,49932,49933,49934,49935,49936,49937,49938,49939,49940,49941,49942,49943,49944,49945,49946,49947,49948,49949,49950,49951,49952,49953,49954,49955,49956,49957,49958,49959,49960,49961,49962,49963,49964,49965,49966,49967,49968,49969,49970,49971,49972,49973,49974,49975,49976,49977,49978,49979,49980,49981,49982,49983,49984,49985,49986,49987,49988,49989,49990,49991,49992,49993,49994,49995,49996,49997,49998,49999,50000,50001,50002,50003,50004,50005,50006,50007,50008,50009,50010,50011,50012,50013,50014,50015,50016,50017,50018,50019,50020,50021,50022,50023,50024,50025,50026,50027,50028,50029,50030,50031,50032,50033,50034,50035,50036,50037,50038,50039,50040,50041,50042,50043,50044,50045,50046,50047,50048,50049,50050,50051,50052,50053,50054,50055,50056,50057,50058,50059,50060,50061,50062,50063,50064,50065,50066,50067,50068,50069,50070,50071,50072,50073,50074,50075,50076,50077,50078,50079,50080,50081,50082,50083,50084,50085,50086,50087,50088,50089,50090,50091,50092,50093,50094,50095,50096,50097,50098,50099,50100,50101,50102,50103,50104,50105,50106,50107,50108,50109,50110,50111,50112,50113,50114,50115,50116,50117,50118,50119,50120,50121,50122,50123,50124,50125,50126,50127,50128,50129,50130,50131,50132,50133,50134,50135,50136,50137,50138,50139,50140,50141,50142,50143,50144,50145,50146,50147,50148,50149,50150,50151,50152,50153,50154,50155,50156,50157,50158,50159,50160,50161,50162,50163,50164,50165,50166,50167,50168,50169,50170,50171,50172,50173,50174,50175,50176,50177,50178,50179,50180,50181,50182,50183,50184,50185,50186,50187,50188,50189,50190,50191,50192,50193,50194,50195,50196,50197,50198,50199,50200,50201,50202,50203,50204,50205,50206,50207,50208,50209,50210,50211,50212,50213,50214,50215,50216,50217,50218,50219,50220,50221,50222,50223,50224,50225,50226,50227,50228,50229,50230,50231,50232,50233,50234,50235,50236,50237,50238,50239,50240,50241,50242,50243,50244,50245,50246,50247,50248,50249,50250,50251,50252,50253,50254,50255,50256,50257,50258,50259,50260,50261,50262,50263,50264,50265,50266,50267,50268,50269,50270,50271,50272,50273,50274,50275,50276,50277,50278,50279,50280,50281,50282,50283,50284,50285,50286,50287,50288,50289,50290,50291,50292,50293,50294,50295,50296,50297,50298,50299,50300,50301,50302,50303,50304,50305,50306,50307,50308,50309,50310,50311,50312,50313,50314,50315,50316,50317,50318,50319,50320,50321,50322,50323,50324,50325,50326,50327,50328,50329,50330,50331,50332,50333,50334,50335,50336,50337,50338,50339,50340,50341,50342,50343,50344,50345,50346,50347,50348,50349,50350,50351,50352,50353,50354,50355,50356,50357,50358,50359,50360,50361,50362,50363,50364,50365,50366,50367,50368,50369,50370,50371,50372,50373,50374,50375,50376,50377,50378,50379,50380,50381,50382,50383,50384,50385,50386,50387,50388,50389,50390,50391,50392,50393,50394,50395,50396,50397,50398,50399,50400,50401,50402,50403,50404,50405,50406,50407,50408,50409,50410,50411,50412,50413,50414,50415,50416,50417,50418,50419,50420,50421,50422,50423,50424,50425,50426,50427,50428,50429,50430,50431,50432,50433,50434,50435,50436,50437,50438,50439,50440,50441,50442,50443,50444,50445,50446,50447,50448,50449,50450,50451,50452,50453,50454,50455,50456,50457,50458,50459,50460,50461,50462,50463,50464,50465,50466,50467,50468,50469,50470,50471,50472,50473,50474,50475,50476,50477,50478,50479,50480,50481,50482,50483,50484,50485,50486,50487,50488,50489,50490,50491,50492,50493,50494,50495,50496,50497,50498,50499,50500,50501,50502,50503,50504,50505,50506,50507,50508,50509,50510,50511,50512,50513,50514,50515,50516,50517,50518,50519,50520,50521,50522,50523,50524,50525,50526,50527,50528,50529,50530,50531,50532,50533,50534,50535,50536,50537,50538,50539,50540,50541,50542,50543,50544,50545,50546,50547,50548,50549,50550,50551,50552,50553,50554,50555,50556,50557,50558,50559,50560,50561,50562,50563,50564,50565,50566,50567,50568,50569,50570,50571,50572,50573,50574,50575,50576,50577,50578,50579,50580,50581,50582,50583,50584,50585,50586,50587,50588,50589,50590,50591,50592,50593,50594,50595,50596,50597,50598,50599,50600,50601,50602,50603,50604,50605,50606,50607,50608,50609,50610,50611,50612,50613,50614,50615,50616,50617,50618,50619,50620,50621,50622,50623,50624,50625,50626,50627,50628,50629,50630,50631,50632,50633,50634,50635,50636,50637,50638,50639,50640,50641,50642,50643,50644,50645,50646,50647,50648,50649,50650,50651,50652,50653,50654,50655,50656,50657,50658,50659,50660,50661,50662,50663,50664,50665,50666,50667,50668,50669,50670,50671,50672,50673,50674,50675,50676,50677,50678,50679,50680,50681,50682,50683,50684,50685,50686,50687,50688,50689,50690,50691,50692,50693,50694,50695,50696,50697,50698,50699,50700,50701,50702,50703,50704,50705,50706,50707,50708,50709,50710,50711,50712,50713,50714,50715,50716,50717,50718,50719,50720,50721,50722,50723,50724,50725,50726,50727,50728,50729,50730,50731,50732,50733,50734,50735,50736,50737,50738,50739,50740,50741,50742,50743,50744,50745,50746,50747,50748,50749,50750,50751,50752,50753,50754,50755,50756,50757,50758,50759,50760,50761,50762,50763,50764,50765,50766,50767,50768,50769,50770,50771,50772,50773,50774,50775,50776,50777,50778,50779,50780,50781,50782,50783,50784,50785,50786,50787,50788,50789,50790,50791,50792,50793,50794,50795,50796,50797,50798,50799,50800,50801,50802,50803,50804,50805,50806,50807,50808,50809,50810,50811,50812,50813,50814,50815,50816,50817,50818,50819,50820,50821,50822,50823,50824,50825,50826,50827,50828,50829,50830,50831,50832,50833,50834,50835,50836,50837,50838,50839,50840,50841,50842,50843,50844,50845,50846,50847,50848,50849,50850,50851,50852,50853,50854,50855,50856,50857,50858,50859,50860,50861,50862,50863,50864,50865,50866,50867,50868,50869,50870,50871,50872,50873,50874,50875,50876,50877,50878,50879,50880,50881,50882,50883,50884,50885,50886,50887,50888,50889,50890,50891,50892,50893,50894,50895,50896,50897,50898,50899,50900,50901,50902,50903,50904,50905,50906,50907,50908,50909,50910,50911,50912,50913,50914,50915,50916,50917,50918,50919,50920,50921,50922,50923,50924,50925,50926,50927,50928,50929,50930,50931,50932,50933,50934,50935,50936,50937,50938,50939,50940,50941,50942,50943,50944,50945,50946,50947,50948,50949,50950,50951,50952,50953,50954,50955,50956,50957,50958,50959,50960,50961,50962,50963,50964,50965,50966,50967,50968,50969,50970,50971,50972,50973,50974,50975,50976,50977,50978,50979,50980,50981,50982,50983,50984,50985,50986,50987,50988,50989,50990,50991,50992,50993,50994,50995,50996,50997,50998,50999,51000,51001,51002,51003,51004,51005,51006,51007,51008,51009,51010,51011,51012,51013,51014,51015,51016,51017,51018,51019,51020,51021,51022,51023,51024,51025,51026,51027,51028,51029,51030,51031,51032,51033,51034,51035,51036,51037,51038,51039,51040,51041,51042,51043,51044,51045,51046,51047,51048,51049,51050,51051,51052,51053,51054,51055,51056,51057,51058,51059,51060,51061,51062,51063,51064,51065,51066,51067,51068,51069,51070,51071,51072,51073,51074,51075,51076,51077,51078,51079,51080,51081,51082,51083,51084,51085,51086,51087,51088,51089,51090,51091,51092,51093,51094,51095,51096,51097,51098,51099,51100,51101,51102,51103,51104,51105,51106,51107,51108,51109,51110,51111,51112,51113,51114,51115,51116,51117,51118,51119,51120,51121,51122,51123,51124,51125,51126,51127,51128,51129,51130,51131,51132,51133,51134,51135,51136,51137,51138,51139,51140,51141,51142,51143,51144,51145,51146,51147,51148,51149,51150,51151,51152,51153,51154,51155,51156,51157,51158,51159,51160,51161,51162,51163,51164,51165,51166,51167,51168,51169,51170,51171,51172,51173,51174,51175,51176,51177,51178,51179,51180,51181,51182,51183,51184,51185,51186,51187,51188,51189,51190,51191,51192,51193,51194,51195,51196,51197,51198,51199,51200,51201,51202,51203,51204,51205,51206,51207,51208,51209,51210,51211,51212,51213,51214,51215,51216,51217,51218,51219,51220,51221,51222,51223,51224,51225,51226,51227,51228,51229,51230,51231,51232,51233,51234,51235,51236,51237,51238,51239,51240,51241,51242,51243,51244,51245,51246,51247,51248,51249,51250,51251,51252,51253,51254,51255,51256,51257,51258,51259,51260,51261,51262,51263,51264,51265,51266,51267,51268,51269,51270,51271,51272,51273,51274,51275,51276,51277,51278,51279,51280,51281,51282,51283,51284,51285,51286,51287,51288,51289,51290,51291,51292,51293,51294,51295,51296,51297,51298,51299,51300,51301,51302,51303,51304,51305,51306,51307,51308,51309,51310,51311,51312,51313,51314,51315,51316,51317,51318,51319,51320,51321,51322,51323,51324,51325,51326,51327,51328,51329,51330,51331,51332,51333,51334,51335,51336,51337,51338,51339,51340,51341,51342,51343,51344,51345,51346,51347,51348,51349,51350,51351,51352,51353,51354,51355,51356,51357,51358,51359,51360,51361,51362,51363,51364,51365,51366,51367,51368,51369,51370,51371,51372,51373,51374,51375,51376,51377,51378,51379,51380,51381,51382,51383,51384,51385,51386,51387,51388,51389,51390,51391,51392,51393,51394,51395,51396,51397,51398,51399,51400,51401,51402,51403,51404,51405,51406,51407,51408,51409,51410,51411,51412,51413,51414,51415,51416,51417,51418,51419,51420,51421,51422,51423,51424,51425,51426,51427,51428,51429,51430,51431,51432,51433,51434,51435,51436,51437,51438,51439,51440,51441,51442,51443,51444,51445,51446,51447,51448,51449,51450,51451,51452,51453,51454,51455,51456,51457,51458,51459,51460,51461,51462,51463,51464,51465,51466,51467,51468,51469,51470,51471,51472,51473,51474,51475,51476,51477,51478,51479,51480,51481,51482,51483,51484,51485,51486,51487,51488,51489,51490,51491,51492,51493,51494,51495,51496,51497,51498,51499,51500,51501,51502,51503,51504,51505,51506,51507,51508,51509,51510,51511,51512,51513,51514,51515,51516,51517,51518,51519,51520,51521,51522,51523,51524,51525,51526,51527,51528,51529,51530,51531,51532,51533,51534,51535,51536,51537,51538,51539,51540,51541,51542,51543,51544,51545,51546,51547,51548,51549,51550,51551,51552,51553,51554,51555,51556,51557,51558,51559,51560,51561,51562,51563,51564,51565,51566,51567,51568,51569,51570,51571,51572,51573,51574,51575,51576,51577,51578,51579,51580,51581,51582,51583,51584,51585,51586,51587,51588,51589,51590,51591,51592,51593,51594,51595,51596,51597,51598,51599,51600,51601,51602,51603,51604,51605,51606,51607,51608,51609,51610,51611,51612,51613,51614,51615,51616,51617,51618,51619,51620,51621,51622,51623,51624,51625,51626,51627,51628,51629,51630,51631,51632,51633,51634,51635,51636,51637,51638,51639,51640,51641,51642,51643,51644,51645,51646,51647,51648,51649,51650,51651,51652,51653,51654,51655,51656,51657,51658,51659,51660,51661,51662,51663,51664,51665,51666,51667,51668,51669,51670,51671,51672,51673,51674,51675,51676,51677,51678,51679,51680,51681,51682,51683,51684,51685,51686,51687,51688,51689,51690,51691,51692,51693,51694,51695,51696,51697,51698,51699,51700,51701,51702,51703,51704,51705,51706,51707,51708,51709,51710,51711,51712,51713,51714,51715,51716,51717,51718,51719,51720,51721,51722,51723,51724,51725,51726,51727,51728,51729,51730,51731,51732,51733,51734,51735,51736,51737,51738,51739,51740,51741,51742,51743,51744,51745,51746,51747,51748,51749,51750,51751,51752,51753,51754,51755,51756,51757,51758,51759,51760,51761,51762,51763,51764,51765,51766,51767,51768,51769,51770,51771,51772,51773,51774,51775,51776,51777,51778,51779,51780,51781,51782,51783,51784,51785,51786,51787,51788,51789,51790,51791,51792,51793,51794,51795,51796,51797,51798,51799,51800,51801,51802,51803,51804,51805,51806,51807,51808,51809,51810,51811,51812,51813,51814,51815,51816,51817,51818,51819,51820,51821,51822,51823,51824,51825,51826,51827,51828,51829,51830,51831,51832,51833,51834,51835,51836,51837,51838,51839,51840,51841,51842,51843,51844,51845,51846,51847,51848,51849,51850,51851,51852,51853,51854,51855,51856,51857,51858,51859,51860,51861,51862,51863,51864,51865,51866,51867,51868,51869,51870,51871,51872,51873,51874,51875,51876,51877,51878,51879,51880,51881,51882,51883,51884,51885,51886,51887,51888,51889,51890,51891,51892,51893,51894,51895,51896,51897,51898,51899,51900,51901,51902,51903,51904,51905,51906,51907,51908,51909,51910,51911,51912,51913,51914,51915,51916,51917,51918,51919,51920,51921,51922,51923,51924,51925,51926,51927,51928,51929,51930,51931,51932,51933,51934,51935,51936,51937,51938,51939,51940,51941,51942,51943,51944,51945,51946,51947,51948,51949,51950,51951,51952,51953,51954,51955,51956,51957,51958,51959,51960,51961,51962,51963,51964,51965,51966,51967,51968,51969,51970,51971,51972,51973,51974,51975,51976,51977,51978,51979,51980,51981,51982,51983,51984,51985,51986,51987,51988,51989,51990,51991,51992,51993,51994,51995,51996,51997,51998,51999,52000,52001,52002,52003,52004,52005,52006,52007,52008,52009,52010,52011,52012,52013,52014,52015,52016,52017,52018,52019,52020,52021,52022,52023,52024,52025,52026,52027,52028,52029,52030,52031,52032,52033,52034,52035,52036,52037,52038,52039,52040,52041,52042,52043,52044,52045,52046,52047,52048,52049,52050,52051,52052,52053,52054,52055,52056,52057,52058,52059,52060,52061,52062,52063,52064,52065,52066,52067,52068,52069,52070,52071,52072,52073,52074,52075,52076,52077,52078,52079,52080,52081,52082,52083,52084,52085,52086,52087,52088,52089,52090,52091,52092,52093,52094,52095,52096,52097,52098,52099,52100,52101,52102,52103,52104,52105,52106,52107,52108,52109,52110,52111,52112,52113,52114,52115,52116,52117,52118,52119,52120,52121,52122,52123,52124,52125,52126,52127,52128,52129,52130,52131,52132,52133,52134,52135,52136,52137,52138,52139,52140,52141,52142,52143,52144,52145,52146,52147,52148,52149,52150,52151,52152,52153,52154,52155,52156,52157,52158,52159,52160,52161,52162,52163,52164,52165,52166,52167,52168,52169,52170,52171,52172,52173,52174,52175,52176,52177,52178,52179,52180,52181,52182,52183,52184,52185,52186,52187,52188,52189,52190,52191,52192,52193,52194,52195,52196,52197,52198,52199,52200,52201,52202,52203,52204,52205,52206,52207,52208,52209,52210,52211,52212,52213,52214,52215,52216,52217,52218,52219,52220,52221,52222,52223,52224,52225,52226,52227,52228,52229,52230,52231,52232,52233,52234,52235,52236,52237,52238,52239,52240,52241,52242,52243,52244,52245,52246,52247,52248,52249,52250,52251,52252,52253,52254,52255,52256,52257,52258,52259,52260,52261,52262,52263,52264,52265,52266,52267,52268,52269,52270,52271,52272,52273,52274,52275,52276,52277,52278,52279,52280,52281,52282,52283,52284,52285,52286,52287,52288,52289,52290,52291,52292,52293,52294,52295,52296,52297,52298,52299,52300,52301,52302,52303,52304,52305,52306,52307,52308,52309,52310,52311,52312,52313,52314,52315,52316,52317,52318,52319,52320,52321,52322,52323,52324,52325,52326,52327,52328,52329,52330,52331,52332,52333,52334,52335,52336,52337,52338,52339,52340,52341,52342,52343,52344,52345,52346,52347,52348,52349,52350,52351,52352,52353,52354,52355,52356,52357,52358,52359,52360,52361,52362,52363,52364,52365,52366,52367,52368,52369,52370,52371,52372,52373,52374,52375,52376,52377,52378,52379,52380,52381,52382,52383,52384,52385,52386,52387,52388,52389,52390,52391,52392,52393,52394,52395,52396,52397,52398,52399,52400,52401,52402,52403,52404,52405,52406,52407,52408,52409,52410,52411,52412,52413,52414,52415,52416,52417,52418,52419,52420,52421,52422,52423,52424,52425,52426,52427,52428,52429,52430,52431,52432,52433,52434,52435,52436,52437,52438,52439,52440,52441,52442,52443,52444,52445,52446,52447,52448,52449,52450,52451,52452,52453,52454,52455,52456,52457,52458,52459,52460,52461,52462,52463,52464,52465,52466,52467,52468,52469,52470,52471,52472,52473,52474,52475,52476,52477,52478,52479,52480,52481,52482,52483,52484,52485,52486,52487,52488,52489,52490,52491,52492,52493,52494,52495,52496,52497,52498,52499,52500,52501,52502,52503,52504,52505,52506,52507,52508,52509,52510,52511,52512,52513,52514,52515,52516,52517,52518,52519,52520,52521,52522,52523,52524,52525,52526,52527,52528,52529,52530,52531,52532,52533,52534,52535,52536,52537,52538,52539,52540,52541,52542,52543,52544,52545,52546,52547,52548,52549,52550,52551,52552,52553,52554,52555,52556,52557,52558,52559,52560,52561,52562,52563,52564,52565,52566,52567,52568,52569,52570,52571,52572,52573,52574,52575,52576,52577,52578,52579,52580,52581,52582,52583,52584,52585,52586,52587,52588,52589,52590,52591,52592,52593,52594,52595,52596,52597,52598,52599,52600,52601,52602,52603,52604,52605,52606,52607,52608,52609,52610,52611,52612,52613,52614,52615,52616,52617,52618,52619,52620,52621,52622,52623,52624,52625,52626,52627,52628,52629,52630,52631,52632,52633,52634,52635,52636,52637,52638,52639,52640,52641,52642,52643,52644,52645,52646,52647,52648,52649,52650,52651,52652,52653,52654,52655,52656,52657,52658,52659,52660,52661,52662,52663,52664,52665,52666,52667,52668,52669,52670,52671,52672,52673,52674,52675,52676,52677,52678,52679,52680,52681,52682,52683,52684,52685,52686,52687,52688,52689,52690,52691,52692,52693,52694,52695,52696,52697,52698,52699,52700,52701,52702,52703,52704,52705,52706,52707,52708,52709,52710,52711,52712,52713,52714,52715,52716,52717,52718,52719,52720,52721,52722,52723,52724,52725,52726,52727,52728,52729,52730,52731,52732,52733,52734,52735,52736,52737,52738,52739,52740,52741,52742,52743,52744,52745,52746,52747,52748,52749,52750,52751,52752,52753,52754,52755,52756,52757,52758,52759,52760,52761,52762,52763,52764,52765,52766,52767,52768,52769,52770,52771,52772,52773,52774,52775,52776,52777,52778,52779,52780,52781,52782,52783,52784,52785,52786,52787,52788,52789,52790,52791,52792,52793,52794,52795,52796,52797,52798,52799,52800,52801,52802,52803,52804,52805,52806,52807,52808,52809,52810,52811,52812,52813,52814,52815,52816,52817,52818,52819,52820,52821,52822,52823,52824,52825,52826,52827,52828,52829,52830,52831,52832,52833,52834,52835,52836,52837,52838,52839,52840,52841,52842,52843,52844,52845,52846,52847,52848,52849,52850,52851,52852,52853,52854,52855,52856,52857,52858,52859,52860,52861,52862,52863,52864,52865,52866,52867,52868,52869,52870,52871,52872,52873,52874,52875,52876,52877,52878,52879,52880,52881,52882,52883,52884,52885,52886,52887,52888,52889,52890,52891,52892,52893,52894,52895,52896,52897,52898,52899,52900,52901,52902,52903,52904,52905,52906,52907,52908,52909,52910,52911,52912,52913,52914,52915,52916,52917,52918,52919,52920,52921,52922,52923,52924,52925,52926,52927,52928,52929,52930,52931,52932,52933,52934,52935,52936,52937,52938,52939,52940,52941,52942,52943,52944,52945,52946,52947,52948,52949,52950,52951,52952,52953,52954,52955,52956,52957,52958,52959,52960,52961,52962,52963,52964,52965,52966,52967,52968,52969,52970,52971,52972,52973,52974,52975,52976,52977,52978,52979,52980,52981,52982,52983,52984,52985,52986,52987,52988,52989,52990,52991,52992,52993,52994,52995,52996,52997,52998,52999,53000,53001,53002,53003,53004,53005,53006,53007,53008,53009,53010,53011,53012,53013,53014,53015,53016,53017,53018,53019,53020,53021,53022,53023,53024,53025,53026,53027,53028,53029,53030,53031,53032,53033,53034,53035,53036,53037,53038,53039,53040,53041,53042,53043,53044,53045,53046,53047,53048,53049,53050,53051,53052,53053,53054,53055,53056,53057,53058,53059,53060,53061,53062,53063,53064,53065,53066,53067,53068,53069,53070,53071,53072,53073,53074,53075,53076,53077,53078,53079,53080,53081,53082,53083,53084,53085,53086,53087,53088,53089,53090,53091,53092,53093,53094,53095,53096,53097,53098,53099,53100,53101,53102,53103,53104,53105,53106,53107,53108,53109,53110,53111,53112,53113,53114,53115,53116,53117,53118,53119,53120,53121,53122,53123,53124,53125,53126,53127,53128,53129,53130,53131,53132,53133,53134,53135,53136,53137,53138,53139,53140,53141,53142,53143,53144,53145,53146,53147,53148,53149,53150,53151,53152,53153,53154,53155,53156,53157,53158,53159,53160,53161,53162,53163,53164,53165,53166,53167,53168,53169,53170,53171,53172,53173,53174,53175,53176,53177,53178,53179,53180,53181,53182,53183,53184,53185,53186,53187,53188,53189,53190,53191,53192,53193,53194,53195,53196,53197,53198,53199,53200,53201,53202,53203,53204,53205,53206,53207,53208,53209,53210,53211,53212,53213,53214,53215,53216,53217,53218,53219,53220,53221,53222,53223,53224,53225,53226,53227,53228,53229,53230,53231,53232,53233,53234,53235,53236,53237,53238,53239,53240,53241,53242,53243,53244,53245,53246,53247,53248,53249,53250,53251,53252,53253,53254,53255,53256,53257,53258,53259,53260,53261,53262,53263,53264,53265,53266,53267,53268,53269,53270,53271,53272,53273,53274,53275,53276,53277,53278,53279,53280,53281,53282,53283,53284,53285,53286,53287,53288,53289,53290,53291,53292,53293,53294,53295,53296,53297,53298,53299,53300,53301,53302,53303,53304,53305,53306,53307,53308,53309,53310,53311,53312,53313,53314,53315,53316,53317,53318,53319,53320,53321,53322,53323,53324,53325,53326,53327,53328,53329,53330,53331,53332,53333,53334,53335,53336,53337,53338,53339,53340,53341,53342,53343,53344,53345,53346,53347,53348,53349,53350,53351,53352,53353,53354,53355,53356,53357,53358,53359,53360,53361,53362,53363,53364,53365,53366,53367,53368,53369,53370,53371,53372,53373,53374,53375,53376,53377,53378,53379,53380,53381,53382,53383,53384,53385,53386,53387,53388,53389,53390,53391,53392,53393,53394,53395,53396,53397,53398,53399,53400,53401,53402,53403,53404,53405,53406,53407,53408,53409,53410,53411,53412,53413,53414,53415,53416,53417,53418,53419,53420,53421,53422,53423,53424,53425,53426,53427,53428,53429,53430,53431,53432,53433,53434,53435,53436,53437,53438,53439,53440,53441,53442,53443,53444,53445,53446,53447,53448,53449,53450,53451,53452,53453,53454,53455,53456,53457,53458,53459,53460,53461,53462,53463,53464,53465,53466,53467,53468,53469,53470,53471,53472,53473,53474,53475,53476,53477,53478,53479,53480,53481,53482,53483,53484,53485,53486,53487,53488,53489,53490,53491,53492,53493,53494,53495,53496,53497,53498,53499,53500,53501,53502,53503,53504,53505,53506,53507,53508,53509,53510,53511,53512,53513,53514,53515,53516,53517,53518,53519,53520,53521,53522,53523,53524,53525,53526,53527,53528,53529,53530,53531,53532,53533,53534,53535,53536,53537,53538,53539,53540,53541,53542,53543,53544,53545,53546,53547,53548,53549,53550,53551,53552,53553,53554,53555,53556,53557,53558,53559,53560,53561,53562,53563,53564,53565,53566,53567,53568,53569,53570,53571,53572,53573,53574,53575,53576,53577,53578,53579,53580,53581,53582,53583,53584,53585,53586,53587,53588,53589,53590,53591,53592,53593,53594,53595,53596,53597,53598,53599,53600,53601,53602,53603,53604,53605,53606,53607,53608,53609,53610,53611,53612,53613,53614,53615,53616,53617,53618,53619,53620,53621,53622,53623,53624,53625,53626,53627,53628,53629,53630,53631,53632,53633,53634,53635,53636,53637,53638,53639,53640,53641,53642,53643,53644,53645,53646,53647,53648,53649,53650,53651,53652,53653,53654,53655,53656,53657,53658,53659,53660,53661,53662,53663,53664,53665,53666,53667,53668,53669,53670,53671,53672,53673,53674,53675,53676,53677,53678,53679,53680,53681,53682,53683,53684,53685,53686,53687,53688,53689,53690,53691,53692,53693,53694,53695,53696,53697,53698,53699,53700,53701,53702,53703,53704,53705,53706,53707,53708,53709,53710,53711,53712,53713,53714,53715,53716,53717,53718,53719,53720,53721,53722,53723,53724,53725,53726,53727,53728,53729,53730,53731,53732,53733,53734,53735,53736,53737,53738,53739,53740,53741,53742,53743,53744,53745,53746,53747,53748,53749,53750,53751,53752,53753,53754,53755,53756,53757,53758,53759,53760,53761,53762,53763,53764,53765,53766,53767,53768,53769,53770,53771,53772,53773,53774,53775,53776,53777,53778,53779,53780,53781,53782,53783,53784,53785,53786,53787,53788,53789,53790,53791,53792,53793,53794,53795,53796,53797,53798,53799,53800,53801,53802,53803,53804,53805,53806,53807,53808,53809,53810,53811,53812,53813,53814,53815,53816,53817,53818,53819,53820,53821,53822,53823,53824,53825,53826,53827,53828,53829,53830,53831,53832,53833,53834,53835,53836,53837,53838,53839,53840,53841,53842,53843,53844,53845,53846,53847,53848,53849,53850,53851,53852,53853,53854,53855,53856,53857,53858,53859,53860,53861,53862,53863,53864,53865,53866,53867,53868,53869,53870,53871,53872,53873,53874,53875,53876,53877,53878,53879,53880,53881,53882,53883,53884,53885,53886,53887,53888,53889,53890,53891,53892,53893,53894,53895,53896,53897,53898,53899,53900,53901,53902,53903,53904,53905,53906,53907,53908,53909,53910,53911,53912,53913,53914,53915,53916,53917,53918,53919,53920,53921,53922,53923,53924,53925,53926,53927,53928,53929,53930,53931,53932,53933,53934,53935,53936,53937,53938,53939,53940,53941,53942,53943,53944,53945,53946,53947,53948,53949,53950,53951,53952,53953,53954,53955,53956,53957,53958,53959,53960,53961,53962,53963,53964,53965,53966,53967,53968,53969,53970,53971,53972,53973,53974,53975,53976,53977,53978,53979,53980,53981,53982,53983,53984,53985,53986,53987,53988,53989,53990,53991,53992,53993,53994,53995,53996,53997,53998,53999,54000,54001,54002,54003,54004,54005,54006,54007,54008,54009,54010,54011,54012,54013,54014,54015,54016,54017,54018,54019,54020,54021,54022,54023,54024,54025,54026,54027,54028,54029,54030,54031,54032,54033,54034,54035,54036,54037,54038,54039,54040,54041,54042,54043,54044,54045,54046,54047,54048,54049,54050,54051,54052,54053,54054,54055,54056,54057,54058,54059,54060,54061,54062,54063,54064,54065,54066,54067,54068,54069,54070,54071,54072,54073,54074,54075,54076,54077,54078,54079,54080,54081,54082,54083,54084,54085,54086,54087,54088,54089,54090,54091,54092,54093,54094,54095,54096,54097,54098,54099,54100,54101,54102,54103,54104,54105,54106,54107,54108,54109,54110,54111,54112,54113,54114,54115,54116,54117,54118,54119,54120,54121,54122,54123,54124,54125,54126,54127,54128,54129,54130,54131,54132,54133,54134,54135,54136,54137,54138,54139,54140,54141,54142,54143,54144,54145,54146,54147,54148,54149,54150,54151,54152,54153,54154,54155,54156,54157,54158,54159,54160,54161,54162,54163,54164,54165,54166,54167,54168,54169,54170,54171,54172,54173,54174,54175,54176,54177,54178,54179,54180,54181,54182,54183,54184,54185,54186,54187,54188,54189,54190,54191,54192,54193,54194,54195,54196,54197,54198,54199,54200,54201,54202,54203,54204,54205,54206,54207,54208,54209,54210,54211,54212,54213,54214,54215,54216,54217,54218,54219,54220,54221,54222,54223,54224,54225,54226,54227,54228,54229,54230,54231,54232,54233,54234,54235,54236,54237,54238,54239,54240,54241,54242,54243,54244,54245,54246,54247,54248,54249,54250,54251,54252,54253,54254,54255,54256,54257,54258,54259,54260,54261,54262,54263,54264,54265,54266,54267,54268,54269,54270,54271,54272,54273,54274,54275,54276,54277,54278,54279,54280,54281,54282,54283,54284,54285,54286,54287,54288,54289,54290,54291,54292,54293,54294,54295,54296,54297,54298,54299,54300,54301,54302,54303,54304,54305,54306,54307,54308,54309,54310,54311,54312,54313,54314,54315,54316,54317,54318,54319,54320,54321,54322,54323,54324,54325,54326,54327,54328,54329,54330,54331,54332,54333,54334,54335,54336,54337,54338,54339,54340,54341,54342,54343,54344,54345,54346,54347,54348,54349,54350,54351,54352,54353,54354,54355,54356,54357,54358,54359,54360,54361,54362,54363,54364,54365,54366,54367,54368,54369,54370,54371,54372,54373,54374,54375,54376,54377,54378,54379,54380,54381,54382,54383,54384,54385,54386,54387,54388,54389,54390,54391,54392,54393,54394,54395,54396,54397,54398,54399,54400,54401,54402,54403,54404,54405,54406,54407,54408,54409,54410,54411,54412,54413,54414,54415,54416,54417,54418,54419,54420,54421,54422,54423,54424,54425,54426,54427,54428,54429,54430,54431,54432,54433,54434,54435,54436,54437,54438,54439,54440,54441,54442,54443,54444,54445,54446,54447,54448,54449,54450,54451,54452,54453,54454,54455,54456,54457,54458,54459,54460,54461,54462,54463,54464,54465,54466,54467,54468,54469,54470,54471,54472,54473,54474,54475,54476,54477,54478,54479,54480,54481,54482,54483,54484,54485,54486,54487,54488,54489,54490,54491,54492,54493,54494,54495,54496,54497,54498,54499,54500,54501,54502,54503,54504,54505,54506,54507,54508,54509,54510,54511,54512,54513,54514,54515,54516,54517,54518,54519,54520,54521,54522,54523,54524,54525,54526,54527,54528,54529,54530,54531,54532,54533,54534,54535,54536,54537,54538,54539,54540,54541,54542,54543,54544,54545,54546,54547,54548,54549,54550,54551,54552,54553,54554,54555,54556,54557,54558,54559,54560,54561,54562,54563,54564,54565,54566,54567,54568,54569,54570,54571,54572,54573,54574,54575,54576,54577,54578,54579,54580,54581,54582,54583,54584,54585,54586,54587,54588,54589,54590,54591,54592,54593,54594,54595,54596,54597,54598,54599,54600,54601,54602,54603,54604,54605,54606,54607,54608,54609,54610,54611,54612,54613,54614,54615,54616,54617,54618,54619,54620,54621,54622,54623,54624,54625,54626,54627,54628,54629,54630,54631,54632,54633,54634,54635,54636,54637,54638,54639,54640,54641,54642,54643,54644,54645,54646,54647,54648,54649,54650,54651,54652,54653,54654,54655,54656,54657,54658,54659,54660,54661,54662,54663,54664,54665,54666,54667,54668,54669,54670,54671,54672,54673,54674,54675,54676,54677,54678,54679,54680,54681,54682,54683,54684,54685,54686,54687,54688,54689,54690,54691,54692,54693,54694,54695,54696,54697,54698,54699,54700,54701,54702,54703,54704,54705,54706,54707,54708,54709,54710,54711,54712,54713,54714,54715,54716,54717,54718,54719,54720,54721,54722,54723,54724,54725,54726,54727,54728,54729,54730,54731,54732,54733,54734,54735,54736,54737,54738,54739,54740,54741,54742,54743,54744,54745,54746,54747,54748,54749,54750,54751,54752,54753,54754,54755,54756,54757,54758,54759,54760,54761,54762,54763,54764,54765,54766,54767,54768,54769,54770,54771,54772,54773,54774,54775,54776,54777,54778,54779,54780,54781,54782,54783,54784,54785,54786,54787,54788,54789,54790,54791,54792,54793,54794,54795,54796,54797,54798,54799,54800,54801,54802,54803,54804,54805,54806,54807,54808,54809,54810,54811,54812,54813,54814,54815,54816,54817,54818,54819,54820,54821,54822,54823,54824,54825,54826,54827,54828,54829,54830,54831,54832,54833,54834,54835,54836,54837,54838,54839,54840,54841,54842,54843,54844,54845,54846,54847,54848,54849,54850,54851,54852,54853,54854,54855,54856,54857,54858,54859,54860,54861,54862,54863,54864,54865,54866,54867,54868,54869,54870,54871,54872,54873,54874,54875,54876,54877,54878,54879,54880,54881,54882,54883,54884,54885,54886,54887,54888,54889,54890,54891,54892,54893,54894,54895,54896,54897,54898,54899,54900,54901,54902,54903,54904,54905,54906,54907,54908,54909,54910,54911,54912,54913,54914,54915,54916,54917,54918,54919,54920,54921,54922,54923,54924,54925,54926,54927,54928,54929,54930,54931,54932,54933,54934,54935,54936,54937,54938,54939,54940,54941,54942,54943,54944,54945,54946,54947,54948,54949,54950,54951,54952,54953,54954,54955,54956,54957,54958,54959,54960,54961,54962,54963,54964,54965,54966,54967,54968,54969,54970,54971,54972,54973,54974,54975,54976,54977,54978,54979,54980,54981,54982,54983,54984,54985,54986,54987,54988,54989,54990,54991,54992,54993,54994,54995,54996,54997,54998,54999,55000,55001,55002,55003,55004,55005,55006,55007,55008,55009,55010,55011,55012,55013,55014,55015,55016,55017,55018,55019,55020,55021,55022,55023,55024,55025,55026,55027,55028,55029,55030,55031,55032,55033,55034,55035,55036,55037,55038,55039,55040,55041,55042,55043,55044,55045,55046,55047,55048,55049,55050,55051,55052,55053,55054,55055,55056,55057,55058,55059,55060,55061,55062,55063,55064,55065,55066,55067,55068,55069,55070,55071,55072,55073,55074,55075,55076,55077,55078,55079,55080,55081,55082,55083,55084,55085,55086,55087,55088,55089,55090,55091,55092,55093,55094,55095,55096,55097,55098,55099,55100,55101,55102,55103,55104,55105,55106,55107,55108,55109,55110,55111,55112,55113,55114,55115,55116,55117,55118,55119,55120,55121,55122,55123,55124,55125,55126,55127,55128,55129,55130,55131,55132,55133,55134,55135,55136,55137,55138,55139,55140,55141,55142,55143,55144,55145,55146,55147,55148,55149,55150,55151,55152,55153,55154,55155,55156,55157,55158,55159,55160,55161,55162,55163,55164,55165,55166,55167,55168,55169,55170,55171,55172,55173,55174,55175,55176,55177,55178,55179,55180,55181,55182,55183,55184,55185,55186,55187,55188,55189,55190,55191,55192,55193,55194,55195,55196,55197,55198,55199,55200,55201,55202,55203,55216,55217,55218,55219,55220,55221,55222,55223,55224,55225,55226,55227,55228,55229,55230,55231,55232,55233,55234,55235,55236,55237,55238,55243,55244,55245,55246,55247,55248,55249,55250,55251,55252,55253,55254,55255,55256,55257,55258,55259,55260,55261,55262,55263,55264,55265,55266,55267,55268,55269,55270,55271,55272,55273,55274,55275,55276,55277,55278,55279,55280,55281,55282,55283,55284,55285,55286,55287,55288,55289,55290,55291,63744,63745,63746,63747,63748,63749,63750,63751,63752,63753,63754,63755,63756,63757,63758,63759,63760,63761,63762,63763,63764,63765,63766,63767,63768,63769,63770,63771,63772,63773,63774,63775,63776,63777,63778,63779,63780,63781,63782,63783,63784,63785,63786,63787,63788,63789,63790,63791,63792,63793,63794,63795,63796,63797,63798,63799,63800,63801,63802,63803,63804,63805,63806,63807,63808,63809,63810,63811,63812,63813,63814,63815,63816,63817,63818,63819,63820,63821,63822,63823,63824,63825,63826,63827,63828,63829,63830,63831,63832,63833,63834,63835,63836,63837,63838,63839,63840,63841,63842,63843,63844,63845,63846,63847,63848,63849,63850,63851,63852,63853,63854,63855,63856,63857,63858,63859,63860,63861,63862,63863,63864,63865,63866,63867,63868,63869,63870,63871,63872,63873,63874,63875,63876,63877,63878,63879,63880,63881,63882,63883,63884,63885,63886,63887,63888,63889,63890,63891,63892,63893,63894,63895,63896,63897,63898,63899,63900,63901,63902,63903,63904,63905,63906,63907,63908,63909,63910,63911,63912,63913,63914,63915,63916,63917,63918,63919,63920,63921,63922,63923,63924,63925,63926,63927,63928,63929,63930,63931,63932,63933,63934,63935,63936,63937,63938,63939,63940,63941,63942,63943,63944,63945,63946,63947,63948,63949,63950,63951,63952,63953,63954,63955,63956,63957,63958,63959,63960,63961,63962,63963,63964,63965,63966,63967,63968,63969,63970,63971,63972,63973,63974,63975,63976,63977,63978,63979,63980,63981,63982,63983,63984,63985,63986,63987,63988,63989,63990,63991,63992,63993,63994,63995,63996,63997,63998,63999,64000,64001,64002,64003,64004,64005,64006,64007,64008,64009,64010,64011,64012,64013,64014,64015,64016,64017,64018,64019,64020,64021,64022,64023,64024,64025,64026,64027,64028,64029,64030,64031,64032,64033,64034,64035,64036,64037,64038,64039,64040,64041,64042,64043,64044,64045,64046,64047,64048,64049,64050,64051,64052,64053,64054,64055,64056,64057,64058,64059,64060,64061,64062,64063,64064,64065,64066,64067,64068,64069,64070,64071,64072,64073,64074,64075,64076,64077,64078,64079,64080,64081,64082,64083,64084,64085,64086,64087,64088,64089,64090,64091,64092,64093,64094,64095,64096,64097,64098,64099,64100,64101,64102,64103,64104,64105,64106,64107,64108,64109,64112,64113,64114,64115,64116,64117,64118,64119,64120,64121,64122,64123,64124,64125,64126,64127,64128,64129,64130,64131,64132,64133,64134,64135,64136,64137,64138,64139,64140,64141,64142,64143,64144,64145,64146,64147,64148,64149,64150,64151,64152,64153,64154,64155,64156,64157,64158,64159,64160,64161,64162,64163,64164,64165,64166,64167,64168,64169,64170,64171,64172,64173,64174,64175,64176,64177,64178,64179,64180,64181,64182,64183,64184,64185,64186,64187,64188,64189,64190,64191,64192,64193,64194,64195,64196,64197,64198,64199,64200,64201,64202,64203,64204,64205,64206,64207,64208,64209,64210,64211,64212,64213,64214,64215,64216,64217,64256,64257,64258,64259,64260,64261,64262,64275,64276,64277,64278,64279,64285,64287,64288,64289,64290,64291,64292,64293,64294,64295,64296,64298,64299,64300,64301,64302,64303,64304,64305,64306,64307,64308,64309,64310,64312,64313,64314,64315,64316,64318,64320,64321,64323,64324,64326,64327,64328,64329,64330,64331,64332,64333,64334,64335,64336,64337,64338,64339,64340,64341,64342,64343,64344,64345,64346,64347,64348,64349,64350,64351,64352,64353,64354,64355,64356,64357,64358,64359,64360,64361,64362,64363,64364,64365,64366,64367,64368,64369,64370,64371,64372,64373,64374,64375,64376,64377,64378,64379,64380,64381,64382,64383,64384,64385,64386,64387,64388,64389,64390,64391,64392,64393,64394,64395,64396,64397,64398,64399,64400,64401,64402,64403,64404,64405,64406,64407,64408,64409,64410,64411,64412,64413,64414,64415,64416,64417,64418,64419,64420,64421,64422,64423,64424,64425,64426,64427,64428,64429,64430,64431,64432,64433,64467,64468,64469,64470,64471,64472,64473,64474,64475,64476,64477,64478,64479,64480,64481,64482,64483,64484,64485,64486,64487,64488,64489,64490,64491,64492,64493,64494,64495,64496,64497,64498,64499,64500,64501,64502,64503,64504,64505,64506,64507,64508,64509,64510,64511,64512,64513,64514,64515,64516,64517,64518,64519,64520,64521,64522,64523,64524,64525,64526,64527,64528,64529,64530,64531,64532,64533,64534,64535,64536,64537,64538,64539,64540,64541,64542,64543,64544,64545,64546,64547,64548,64549,64550,64551,64552,64553,64554,64555,64556,64557,64558,64559,64560,64561,64562,64563,64564,64565,64566,64567,64568,64569,64570,64571,64572,64573,64574,64575,64576,64577,64578,64579,64580,64581,64582,64583,64584,64585,64586,64587,64588,64589,64590,64591,64592,64593,64594,64595,64596,64597,64598,64599,64600,64601,64602,64603,64604,64605,64606,64607,64608,64609,64610,64611,64612,64613,64614,64615,64616,64617,64618,64619,64620,64621,64622,64623,64624,64625,64626,64627,64628,64629,64630,64631,64632,64633,64634,64635,64636,64637,64638,64639,64640,64641,64642,64643,64644,64645,64646,64647,64648,64649,64650,64651,64652,64653,64654,64655,64656,64657,64658,64659,64660,64661,64662,64663,64664,64665,64666,64667,64668,64669,64670,64671,64672,64673,64674,64675,64676,64677,64678,64679,64680,64681,64682,64683,64684,64685,64686,64687,64688,64689,64690,64691,64692,64693,64694,64695,64696,64697,64698,64699,64700,64701,64702,64703,64704,64705,64706,64707,64708,64709,64710,64711,64712,64713,64714,64715,64716,64717,64718,64719,64720,64721,64722,64723,64724,64725,64726,64727,64728,64729,64730,64731,64732,64733,64734,64735,64736,64737,64738,64739,64740,64741,64742,64743,64744,64745,64746,64747,64748,64749,64750,64751,64752,64753,64754,64755,64756,64757,64758,64759,64760,64761,64762,64763,64764,64765,64766,64767,64768,64769,64770,64771,64772,64773,64774,64775,64776,64777,64778,64779,64780,64781,64782,64783,64784,64785,64786,64787,64788,64789,64790,64791,64792,64793,64794,64795,64796,64797,64798,64799,64800,64801,64802,64803,64804,64805,64806,64807,64808,64809,64810,64811,64812,64813,64814,64815,64816,64817,64818,64819,64820,64821,64822,64823,64824,64825,64826,64827,64828,64829,64848,64849,64850,64851,64852,64853,64854,64855,64856,64857,64858,64859,64860,64861,64862,64863,64864,64865,64866,64867,64868,64869,64870,64871,64872,64873,64874,64875,64876,64877,64878,64879,64880,64881,64882,64883,64884,64885,64886,64887,64888,64889,64890,64891,64892,64893,64894,64895,64896,64897,64898,64899,64900,64901,64902,64903,64904,64905,64906,64907,64908,64909,64910,64911,64914,64915,64916,64917,64918,64919,64920,64921,64922,64923,64924,64925,64926,64927,64928,64929,64930,64931,64932,64933,64934,64935,64936,64937,64938,64939,64940,64941,64942,64943,64944,64945,64946,64947,64948,64949,64950,64951,64952,64953,64954,64955,64956,64957,64958,64959,64960,64961,64962,64963,64964,64965,64966,64967,65008,65009,65010,65011,65012,65013,65014,65015,65016,65017,65018,65019,65136,65137,65138,65139,65140,65142,65143,65144,65145,65146,65147,65148,65149,65150,65151,65152,65153,65154,65155,65156,65157,65158,65159,65160,65161,65162,65163,65164,65165,65166,65167,65168,65169,65170,65171,65172,65173,65174,65175,65176,65177,65178,65179,65180,65181,65182,65183,65184,65185,65186,65187,65188,65189,65190,65191,65192,65193,65194,65195,65196,65197,65198,65199,65200,65201,65202,65203,65204,65205,65206,65207,65208,65209,65210,65211,65212,65213,65214,65215,65216,65217,65218,65219,65220,65221,65222,65223,65224,65225,65226,65227,65228,65229,65230,65231,65232,65233,65234,65235,65236,65237,65238,65239,65240,65241,65242,65243,65244,65245,65246,65247,65248,65249,65250,65251,65252,65253,65254,65255,65256,65257,65258,65259,65260,65261,65262,65263,65264,65265,65266,65267,65268,65269,65270,65271,65272,65273,65274,65275,65276,65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,65345,65346,65347,65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,65382,65383,65384,65385,65386,65387,65388,65389,65390,65391,65392,65393,65394,65395,65396,65397,65398,65399,65400,65401,65402,65403,65404,65405,65406,65407,65408,65409,65410,65411,65412,65413,65414,65415,65416,65417,65418,65419,65420,65421,65422,65423,65424,65425,65426,65427,65428,65429,65430,65431,65432,65433,65434,65435,65436,65437,65438,65439,65440,65441,65442,65443,65444,65445,65446,65447,65448,65449,65450,65451,65452,65453,65454,65455,65456,65457,65458,65459,65460,65461,65462,65463,65464,65465,65466,65467,65468,65469,65470,65474,65475,65476,65477,65478,65479,65482,65483,65484,65485,65486,65487,65490,65491,65492,65493,65494,65495,65498,65499,65500'; +var arr = str.split(',').map(function(code) { + return parseInt(code, 10); +}); +module.exports = arr; +},{}],4:[function(require,module,exports){ +// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 +// +// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! +// +// Originally from narwhal.js (http://narwhaljs.org) +// Copyright (c) 2009 Thomas Robinson <280north.com> +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the 'Software'), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// when used in node, this will actually load the util module we depend on +// versus loading the builtin util module as happens otherwise +// this is a bug in node module loading as far as I am concerned +var util = require('util/'); + +var pSlice = Array.prototype.slice; +var hasOwn = Object.prototype.hasOwnProperty; + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = module.exports = ok; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) + +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + if (options.message) { + this.message = options.message; + this.generatedMessage = false; + } else { + this.message = getMessage(this); + this.generatedMessage = true; + } + var stackStartFunction = options.stackStartFunction || fail; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, stackStartFunction); + } + else { + // non v8 browsers so we can have a stacktrace + var err = new Error(); + if (err.stack) { + var out = err.stack; + + // try to strip useless frames + var fn_name = stackStartFunction.name; + var idx = out.indexOf('\n' + fn_name); + if (idx >= 0) { + // once we have located the function frame + // we need to strip out everything before it (and its line) + var next_line = out.indexOf('\n', idx + 1); + out = out.substring(next_line + 1); + } + + this.stack = out; + } + } +}; + +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); + +function replacer(key, value) { + if (util.isUndefined(value)) { + return '' + value; + } + if (util.isNumber(value) && !isFinite(value)) { + return value.toString(); + } + if (util.isFunction(value) || util.isRegExp(value)) { + return value.toString(); + } + return value; +} + +function truncate(s, n) { + if (util.isString(s)) { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } +} + +function getMessage(self) { + return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + + self.operator + ' ' + + truncate(JSON.stringify(self.expected, replacer), 128); +} + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, !!guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +function ok(value, message) { + if (!value) fail(value, true, message, '==', assert.ok); +} +assert.ok = ok; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (util.isBuffer(actual) && util.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (util.isDate(actual) && util.isDate(expected)) { + return actual.getTime() === expected.getTime(); + + // 7.3 If the expected value is a RegExp object, the actual value is + // equivalent if it is also a RegExp object with the same source and + // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). + } else if (util.isRegExp(actual) && util.isRegExp(expected)) { + return actual.source === expected.source && + actual.global === expected.global && + actual.multiline === expected.multiline && + actual.lastIndex === expected.lastIndex && + actual.ignoreCase === expected.ignoreCase; + + // 7.4. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (!util.isObject(actual) && !util.isObject(expected)) { + return actual == expected; + + // 7.5 For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv(a, b) { + if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + // if one is a primitive, the other must be same + if (util.isPrimitive(a) || util.isPrimitive(b)) { + return a === b; + } + var aIsArgs = isArguments(a), + bIsArgs = isArguments(b); + if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) + return false; + if (aIsArgs) { + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + var ka = objectKeys(a), + kb = objectKeys(b), + key, i; + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key])) return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } +}; + +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } + + if (Object.prototype.toString.call(expected) == '[object RegExp]') { + return expected.test(actual); + } else if (actual instanceof expected) { + return true; + } else if (expected.call({}, actual) === true) { + return true; + } + + return false; +} + +function _throws(shouldThrow, block, expected, message) { + var actual; + + if (util.isString(expected)) { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); + + if (shouldThrow && !actual) { + fail(actual, expected, 'Missing expected exception' + message); + } + + if (!shouldThrow && expectedException(actual, expected)) { + fail(actual, expected, 'Got unwanted exception' + message); + } + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function(err) { if (err) {throw err;}}; + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + if (hasOwn.call(obj, key)) keys.push(key); + } + return keys; +}; + +},{"util/":9}],5:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } + throw TypeError('Uncaught, unspecified "error" event.'); + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + +},{}],6:[function(require,module,exports){ +// shim for using process in browser + +var process = module.exports = {}; +var queue = []; +var draining = false; + +function drainQueue() { + if (draining) { + return; + } + draining = true; + var currentQueue; + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + var i = -1; + while (++i < len) { + currentQueue[i](); + } + len = queue.length; + } + draining = false; +} +process.nextTick = function (fun) { + queue.push(fun); + if (!draining) { + setTimeout(drainQueue, 0); + } +}; + +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +// TODO(shtylman) +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],7:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} + +},{}],8:[function(require,module,exports){ +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; +} +},{}],9:[function(require,module,exports){ +(function (process,global){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; +}; + + +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +}; + + +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; + + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; + + +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} + + +function stylizeNoColor(str, styleType) { + return str; +} + + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = require('./support/isBuffer'); + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + + +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; + + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = require('inherits'); + +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; + +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./support/isBuffer":8,"_process":6,"inherits":7}],10:[function(require,module,exports){ +(function (global){ +/*global window, global*/ +var util = require("util") +var assert = require("assert") +var now = require("date-now") + +var slice = Array.prototype.slice +var console +var times = {} + +if (typeof global !== "undefined" && global.console) { + console = global.console +} else if (typeof window !== "undefined" && window.console) { + console = window.console +} else { + console = {} +} + +var functions = [ + [log, "log"], + [info, "info"], + [warn, "warn"], + [error, "error"], + [time, "time"], + [timeEnd, "timeEnd"], + [trace, "trace"], + [dir, "dir"], + [consoleAssert, "assert"] +] + +for (var i = 0; i < functions.length; i++) { + var tuple = functions[i] + var f = tuple[0] + var name = tuple[1] + + if (!console[name]) { + console[name] = f + } +} + +module.exports = console + +function log() {} + +function info() { + console.log.apply(console, arguments) +} + +function warn() { + console.log.apply(console, arguments) +} + +function error() { + console.warn.apply(console, arguments) +} + +function time(label) { + times[label] = now() +} + +function timeEnd(label) { + var time = times[label] + if (!time) { + throw new Error("No such label: " + label) + } + + var duration = now() - time + console.log(label + ": " + duration + "ms") +} + +function trace() { + var err = new Error() + err.name = "Trace" + err.message = util.format.apply(null, arguments) + console.error(err.stack) +} + +function dir(object) { + console.log(util.inspect(object) + "\n") +} + +function consoleAssert(expression) { + if (!expression) { + var arr = slice.call(arguments, 1) + assert.ok(false, util.format.apply(null, arr)) + } +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"assert":4,"date-now":11,"util":9}],11:[function(require,module,exports){ +module.exports = now + +function now() { + return new Date().getTime() +} + +},{}],12:[function(require,module,exports){ +(function (global){ +/** + * @license + * lodash 3.7.0 (Custom Build) + * Build: `lodash modern -d -o ./index.js` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; + + /** Used as the semantic version number. */ + var VERSION = '3.7.0'; + + /** Used to compose bitmasks for wrapper metadata. */ + var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_BOUND_FLAG = 4, + CURRY_FLAG = 8, + CURRY_RIGHT_FLAG = 16, + PARTIAL_FLAG = 32, + PARTIAL_RIGHT_FLAG = 64, + ARY_FLAG = 128, + REARG_FLAG = 256; + + /** Used as default options for `_.trunc`. */ + var DEFAULT_TRUNC_LENGTH = 30, + DEFAULT_TRUNC_OMISSION = '...'; + + /** Used to detect when a function becomes hot. */ + var HOT_COUNT = 150, + HOT_SPAN = 16; + + /** Used to indicate the type of lazy iteratees. */ + var LAZY_DROP_WHILE_FLAG = 0, + LAZY_FILTER_FLAG = 1, + LAZY_MAP_FLAG = 2; + + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used as the internal argument placeholder. */ + var PLACEHOLDER = '__lodash_placeholder__'; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to match empty string literals in compiled template source. */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** Used to match HTML entities and HTML characters. */ + var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g, + reUnescapedHtml = /[&<>"'`]/g, + reHasEscapedHtml = RegExp(reEscapedHtml.source), + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** Used to match template delimiters. */ + var reEscape = /<%-([\s\S]+?)%>/g, + reEvaluate = /<%([\s\S]+?)%>/g, + reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]+|(["'])(?:(?!\1)[^\n\\]|\\.)*?)\1\]/, + reIsPlainProp = /^\w*$/, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; + + /** + * Used to match `RegExp` [special characters](http://www.regular-expressions.info/characters.html#special). + * In addition to special characters the forward slash is escaped to allow for + * easier `eval` use and `Function` compilation. + */ + var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g, + reHasRegExpChars = RegExp(reRegExpChars.source); + + /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */ + var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** Used to match [ES template delimiters](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components). */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect hexadecimal string values. */ + var reHasHexPrefix = /^0[xX]/; + + /** Used to detect host constructors (Safari > 5). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ + var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; + + /** Used to ensure capturing order of template delimiters. */ + var reNoMatch = /($^)/; + + /** Used to match unescaped characters in compiled string literals. */ + var reUnescapedString = /['\n\r\u2028\u2029\\]/g; + + /** Used to match words to create compound words. */ + var reWords = (function() { + var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]', + lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+'; + + return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'); + }()); + + /** Used to detect and test for whitespace. */ + var whitespace = ( + // Basic whitespace characters. + ' \t\x0b\f\xa0\ufeff' + + + // Line terminators. + '\n\r\u2028\u2029' + + + // Unicode category "Zs" space separators. + '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' + ); + + /** Used to assign default `context` object properties. */ + var contextProps = [ + 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array', + 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number', + 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'document', + 'isFinite', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', + 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', + 'window' + ]; + + /** Used to make template sourceURLs easier to identify. */ + var templateCounter = -1; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = + typedArrayTags[dateTag] = typedArrayTags[errorTag] = + typedArrayTags[funcTag] = typedArrayTags[mapTag] = + typedArrayTags[numberTag] = typedArrayTags[objectTag] = + typedArrayTags[regexpTag] = typedArrayTags[setTag] = + typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = + cloneableTags[dateTag] = cloneableTags[float32Tag] = + cloneableTags[float64Tag] = cloneableTags[int8Tag] = + cloneableTags[int16Tag] = cloneableTags[int32Tag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[stringTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[mapTag] = cloneableTags[setTag] = + cloneableTags[weakMapTag] = false; + + /** Used as an internal `_.debounce` options object by `_.throttle`. */ + var debounceOptions = { + 'leading': false, + 'maxWait': 0, + 'trailing': false + }; + + /** Used to map latin-1 supplementary letters to basic latin letters. */ + var deburredLetters = { + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss' + }; + + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + + /** Used to map HTML entities to characters. */ + var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'", + '`': '`' + }; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; + + /** Used to escape characters for inclusion in compiled string literals. */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Detect free variable `exports`. */ + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global; + + /** Detect free variable `self`. */ + var freeSelf = objectTypes[typeof self] && self && self.Object && self; + + /** Detect free variable `window`. */ + var freeWindow = objectTypes[typeof window] && window && window.Object && window; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + + /** + * Used as a reference to the global object. + * + * The `this` value is used if it is the global object to avoid Greasemonkey's + * restricted `window` object, otherwise the `window` object is used. + */ + var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this; + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `compareAscending` which compares values and + * sorts them in ascending order without guaranteeing a stable sort. + * + * @private + * @param {*} value The value to compare to `other`. + * @param {*} other The value to compare to `value`. + * @returns {number} Returns the sort order indicator for `value`. + */ + function baseCompareAscending(value, other) { + if (value !== other) { + var valIsReflexive = value === value, + othIsReflexive = other === other; + + if (value > other || !valIsReflexive || (value === undefined && othIsReflexive)) { + return 1; + } + if (value < other || !othIsReflexive || (other === undefined && valIsReflexive)) { + return -1; + } + } + return 0; + } + + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to search. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.indexOf` without support for binary searches. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + if (value !== value) { + return indexOfNaN(array, fromIndex); + } + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.isFunction` without support for environments + * with incorrect `typeof` results. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + */ + function baseIsFunction(value) { + // Avoid a Chakra JIT bug in compatibility modes of IE 11. + // See https://github.com/jashkenas/underscore/issues/1621 for more details. + return typeof value == 'function' || false; + } + + /** + * Converts `value` to a string if it is not one. An empty string is returned + * for `null` or `undefined` values. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + if (typeof value == 'string') { + return value; + } + return value == null ? '' : (value + ''); + } + + /** + * Used by `_.max` and `_.min` as the default callback for string values. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the code unit of the first character of the string. + */ + function charAtCallback(string) { + return string.charCodeAt(0); + } + + /** + * Used by `_.trim` and `_.trimLeft` to get the index of the first character + * of `string` that is not found in `chars`. + * + * @private + * @param {string} string The string to inspect. + * @param {string} chars The characters to find. + * @returns {number} Returns the index of the first character not found in `chars`. + */ + function charsLeftIndex(string, chars) { + var index = -1, + length = string.length; + + while (++index < length && chars.indexOf(string.charAt(index)) > -1) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimRight` to get the index of the last character + * of `string` that is not found in `chars`. + * + * @private + * @param {string} string The string to inspect. + * @param {string} chars The characters to find. + * @returns {number} Returns the index of the last character not found in `chars`. + */ + function charsRightIndex(string, chars) { + var index = string.length; + + while (index-- && chars.indexOf(string.charAt(index)) > -1) {} + return index; + } + + /** + * Used by `_.sortBy` to compare transformed elements of a collection and stable + * sort them in ascending order. + * + * @private + * @param {Object} object The object to compare to `other`. + * @param {Object} other The object to compare to `object`. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareAscending(object, other) { + return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index); + } + + /** + * Used by `_.sortByOrder` to compare multiple properties of each element + * in a collection and stable sort them in the following order: + * + * If `orders` is unspecified, sort in ascending order for all properties. + * Otherwise, for each property, sort in ascending order if its corresponding value in + * orders is true, and descending order if false. + * + * @private + * @param {Object} object The object to compare to `other`. + * @param {Object} other The object to compare to `object`. + * @param {boolean[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = baseCompareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + return result * (orders[index] ? 1 : -1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://code.google.com/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; + } + + /** + * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ + function deburrLetter(letter) { + return deburredLetters[letter]; + } + + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(chr) { + return htmlEscapes[chr]; + } + + /** + * Used by `_.template` to escape characters for inclusion in compiled + * string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; + } + + /** + * Gets the index at which the first occurrence of `NaN` is found in `array`. + * + * @private + * @param {Array} array The array to search. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched `NaN`, else `-1`. + */ + function indexOfNaN(array, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 0 : -1); + + while ((fromRight ? index-- : ++index < length)) { + var other = array[index]; + if (other !== other) { + return index; + } + } + return -1; + } + + /** + * Checks if `value` is object-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a + * character code is whitespace. + * + * @private + * @param {number} charCode The character code to inspect. + * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`. + */ + function isSpace(charCode) { + return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 || + (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279))); + } + + /** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ + function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + if (array[index] === placeholder) { + array[index] = PLACEHOLDER; + result[++resIndex] = index; + } + } + return result; + } + + /** + * An implementation of `_.uniq` optimized for sorted arrays without support + * for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function sortedUniq(array, iteratee) { + var seen, + index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; + + if (!index || seen !== computed) { + seen = computed; + result[++resIndex] = value; + } + } + return result; + } + + /** + * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the first non-whitespace character. + */ + function trimmedLeftIndex(string) { + var index = -1, + length = string.length; + + while (++index < length && isSpace(string.charCodeAt(index))) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ + function trimmedRightIndex(string) { + var index = string.length; + + while (index-- && isSpace(string.charCodeAt(index))) {} + return index; + } + + /** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(chr) { + return htmlUnescapes[chr]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new pristine `lodash` function using the given `context` object. + * + * @static + * @memberOf _ + * @category Utility + * @param {Object} [context=root] The context object. + * @returns {Function} Returns a new `lodash` function. + * @example + * + * _.mixin({ 'foo': _.constant('foo') }); + * + * var lodash = _.runInContext(); + * lodash.mixin({ 'bar': lodash.constant('bar') }); + * + * _.isFunction(_.foo); + * // => true + * _.isFunction(_.bar); + * // => false + * + * lodash.isFunction(lodash.foo); + * // => false + * lodash.isFunction(lodash.bar); + * // => true + * + * // using `context` to mock `Date#getTime` use in `_.now` + * var mock = _.runInContext({ + * 'Date': function() { + * return { 'getTime': getTimeMock }; + * } + * }); + * + * // or creating a suped-up `defer` in Node.js + * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; + */ + function runInContext(context) { + // Avoid issues with some ES3 environments that attempt to use values, named + // after built-in constructors like `Object`, for the creation of literals. + // ES5 clears this up by stating that literals must use built-in constructors. + // See https://es5.github.io/#x11.1.5 for more details. + context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; + + /** Native constructor references. */ + var Array = context.Array, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Number = context.Number, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** Used for native method references. */ + var arrayProto = Array.prototype, + objectProto = Object.prototype, + stringProto = String.prototype; + + /** Used to detect DOM support. */ + var document = (document = context.window) && document.document; + + /** Used to resolve the decompiled source of functions. */ + var fnToString = Function.prototype.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to generate unique IDs. */ + var idCounter = 0; + + /** + * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) + * of values. + */ + var objToString = objectProto.toString; + + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = context._; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + escapeRegExp(objToString) + .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Native method references. */ + var ArrayBuffer = isNative(ArrayBuffer = context.ArrayBuffer) && ArrayBuffer, + bufferSlice = isNative(bufferSlice = ArrayBuffer && new ArrayBuffer(0).slice) && bufferSlice, + ceil = Math.ceil, + clearTimeout = context.clearTimeout, + floor = Math.floor, + getOwnPropertySymbols = isNative(getOwnPropertySymbols = Object.getOwnPropertySymbols) && getOwnPropertySymbols, + getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, + push = arrayProto.push, + preventExtensions = isNative(Object.preventExtensions = Object.preventExtensions) && preventExtensions, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + Set = isNative(Set = context.Set) && Set, + setTimeout = context.setTimeout, + splice = arrayProto.splice, + Uint8Array = isNative(Uint8Array = context.Uint8Array) && Uint8Array, + WeakMap = isNative(WeakMap = context.WeakMap) && WeakMap; + + /** Used to clone array buffers. */ + var Float64Array = (function() { + // Safari 5 errors when using an array buffer to initialize a typed array + // where the array buffer's `byteLength` is not a multiple of the typed + // array's `BYTES_PER_ELEMENT`. + try { + var func = isNative(func = context.Float64Array) && func, + result = new func(new ArrayBuffer(10), 0, 1) && func; + } catch(e) {} + return result; + }()); + + /** Used as `baseAssign`. */ + var nativeAssign = (function() { + // Avoid `Object.assign` in Firefox 34-37 which have an early implementation + // with a now defunct try/catch behavior. See https://bugzilla.mozilla.org/show_bug.cgi?id=1103344 + // for more details. + // + // Use `Object.preventExtensions` on a plain object instead of simply using + // `Object('x')` because Chrome and IE fail to throw an error when attempting + // to assign values to readonly indexes of strings in strict mode. + var object = { '1': 0 }, + func = preventExtensions && isNative(func = Object.assign) && func; + + try { func(preventExtensions(object), 'xo'); } catch(e) {} + return !object[1] && func; + }()); + + /* Native method references for those with the same name as other `lodash` methods. */ + var nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, + nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, + nativeIsFinite = context.isFinite, + nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, + nativeMax = Math.max, + nativeMin = Math.min, + nativeNow = isNative(nativeNow = Date.now) && nativeNow, + nativeNumIsFinite = isNative(nativeNumIsFinite = Number.isFinite) && nativeNumIsFinite, + nativeParseInt = context.parseInt, + nativeRandom = Math.random; + + /** Used as references for `-Infinity` and `Infinity`. */ + var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY, + POSITIVE_INFINITY = Number.POSITIVE_INFINITY; + + /** Used as references for the maximum length and index of an array. */ + var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + + /** Used as the size, in bytes, of each `Float64Array` element. */ + var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0; + + /** + * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) + * of an array-like value. + */ + var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; + + /** Used to store function metadata. */ + var metaMap = WeakMap && new WeakMap; + + /** Used to lookup unminified function names. */ + var realNames = {}; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps `value` to enable implicit chaining. + * Methods that operate on and return arrays, collections, and functions can + * be chained together. Methods that return a boolean or single value will + * automatically end the chain returning the unwrapped value. Explicit chaining + * may be enabled using `_.chain`. The execution of chained methods is lazy, + * that is, execution is deferred until `_#value` is implicitly or explicitly + * called. + * + * Lazy evaluation allows several methods to support shortcut fusion. Shortcut + * fusion is an optimization that merges iteratees to avoid creating intermediate + * arrays and reduce the number of iteratee executions. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, + * `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, + * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, + * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, + * and `where` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, + * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, + * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defer`, `delay`, + * `difference`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `fill`, + * `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, `forEach`, + * `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`, + * `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`, + * `keysIn`, `map`, `mapValues`, `matches`, `matchesProperty`, `memoize`, + * `merge`, `mixin`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, + * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, + * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `reverse`, + * `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, `sortByOrder`, `splice`, + * `spread`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, + * `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, `transform`, + * `union`, `uniq`, `unshift`, `unzip`, `values`, `valuesIn`, `where`, + * `without`, `wrap`, `xor`, `zip`, and `zipObject` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `deburr`, + * `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, + * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `has`, + * `identity`, `includes`, `indexOf`, `inRange`, `isArguments`, `isArray`, + * `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`, `isFinite` + * `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, + * `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, + * `join`, `kebabCase`, `last`, `lastIndexOf`, `max`, `min`, `noConflict`, + * `noop`, `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, + * `reduce`, `reduceRight`, `repeat`, `result`, `runInContext`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, `startsWith`, + * `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, `unescape`, + * `uniqueId`, `value`, and `words` + * + * The wrapper method `sample` will return a wrapped value when `n` is provided, + * otherwise an unwrapped value is returned. + * + * @name _ + * @constructor + * @category Chain + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(total, n) { + * return total + n; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(n) { + * return n * n; + * }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); + } + + /** + * The function whose prototype all chaining wrappers inherit from. + * + * @private + */ + function baseLodash() { + // No operation performed. + } + + /** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable chaining for all wrapper methods. + * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value. + */ + function LodashWrapper(value, chainAll, actions) { + this.__wrapped__ = value; + this.__actions__ = actions || []; + this.__chain__ = !!chainAll; + } + + /** + * An object environment feature flags. + * + * @static + * @memberOf _ + * @type Object + */ + var support = lodash.support = {}; + + (function(x) { + var Ctor = function() { this.x = x; }, + object = { '0': x, 'length': x }, + props = []; + + Ctor.prototype = { 'valueOf': x, 'y': x }; + for (var key in new Ctor) { props.push(key); } + + /** + * Detect if functions can be decompiled by `Function#toString` + * (all but Firefox OS certified apps, older Opera mobile browsers, and + * the PlayStation 3; forced `false` for Windows 8 apps). + * + * @memberOf _.support + * @type boolean + */ + support.funcDecomp = /\bthis\b/.test(function() { return this; }); + + /** + * Detect if `Function#name` is supported (all but IE). + * + * @memberOf _.support + * @type boolean + */ + support.funcNames = typeof Function.name == 'string'; + + /** + * Detect if the DOM is supported. + * + * @memberOf _.support + * @type boolean + */ + try { + support.dom = document.createDocumentFragment().nodeType === 11; + } catch(e) { + support.dom = false; + } + + /** + * Detect if `arguments` object indexes are non-enumerable. + * + * In Firefox < 4, IE < 9, PhantomJS, and Safari < 5.1 `arguments` object + * indexes are non-enumerable. Chrome < 25 and Node.js < 0.11.0 treat + * `arguments` object indexes as non-enumerable and fail `hasOwnProperty` + * checks for indexes that exceed the number of function parameters and + * whose associated argument values are `0`. + * + * @memberOf _.support + * @type boolean + */ + try { + support.nonEnumArgs = !propertyIsEnumerable.call(arguments, 1); + } catch(e) { + support.nonEnumArgs = true; + } + }(1, 0)); + + /** + * By default, the template delimiters used by lodash are like those in + * embedded Ruby (ERB). Change the following template settings to use + * alternative delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': reEscape, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': reEvaluate, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type Object + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type Function + */ + '_': lodash + } + }; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @param {*} value The value to wrap. + */ + function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = null; + this.__dir__ = 1; + this.__dropCount__ = 0; + this.__filtered__ = false; + this.__iteratees__ = null; + this.__takeCount__ = POSITIVE_INFINITY; + this.__views__ = null; + } + + /** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ + function lazyClone() { + var actions = this.__actions__, + iteratees = this.__iteratees__, + views = this.__views__, + result = new LazyWrapper(this.__wrapped__); + + result.__actions__ = actions ? arrayCopy(actions) : null; + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = iteratees ? arrayCopy(iteratees) : null; + result.__takeCount__ = this.__takeCount__; + result.__views__ = views ? arrayCopy(views) : null; + return result; + } + + /** + * Reverses the direction of lazy iteration. + * + * @private + * @name reverse + * @memberOf LazyWrapper + * @returns {Object} Returns the new reversed `LazyWrapper` object. + */ + function lazyReverse() { + if (this.__filtered__) { + var result = new LazyWrapper(this); + result.__dir__ = -1; + result.__filtered__ = true; + } else { + result = this.clone(); + result.__dir__ *= -1; + } + return result; + } + + /** + * Extracts the unwrapped value from its lazy wrapper. + * + * @private + * @name value + * @memberOf LazyWrapper + * @returns {*} Returns the unwrapped value. + */ + function lazyValue() { + var array = this.__wrapped__.value(); + if (!isArray(array)) { + return baseWrapperValue(array, this.__actions__); + } + var dir = this.__dir__, + isRight = dir < 0, + view = getView(0, array.length, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : (start - 1), + takeCount = nativeMin(length, this.__takeCount__), + iteratees = this.__iteratees__, + iterLength = iteratees ? iteratees.length : 0, + resIndex = 0, + result = []; + + outer: + while (length-- && resIndex < takeCount) { + index += dir; + + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type; + + if (type == LAZY_DROP_WHILE_FLAG) { + if (data.done && (isRight ? (index > data.index) : (index < data.index))) { + data.count = 0; + data.done = false; + } + data.index = index; + if (!data.done) { + var limit = data.limit; + if (!(data.done = limit > -1 ? (data.count++ >= limit) : !iteratee(value))) { + continue outer; + } + } + } else { + var computed = iteratee(value); + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } + } + } + } + result[resIndex++] = value; + } + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a cache object to store key/value pairs. + * + * @private + * @static + * @name Cache + * @memberOf _.memoize + */ + function MapCache() { + this.__data__ = {}; + } + + /** + * Removes `key` and its value from the cache. + * + * @private + * @name delete + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`. + */ + function mapDelete(key) { + return this.has(key) && delete this.__data__[key]; + } + + /** + * Gets the cached value for `key`. + * + * @private + * @name get + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to get. + * @returns {*} Returns the cached value. + */ + function mapGet(key) { + return key == '__proto__' ? undefined : this.__data__[key]; + } + + /** + * Checks if a cached value for `key` exists. + * + * @private + * @name has + * @memberOf _.memoize.Cache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapHas(key) { + return key != '__proto__' && hasOwnProperty.call(this.__data__, key); + } + + /** + * Sets `value` to `key` of the cache. + * + * @private + * @name set + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to cache. + * @param {*} value The value to cache. + * @returns {Object} Returns the cache object. + */ + function mapSet(key, value) { + if (key != '__proto__') { + this.__data__[key] = value; + } + return this; + } + + /*------------------------------------------------------------------------*/ + + /** + * + * Creates a cache object to store unique values. + * + * @private + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var length = values ? values.length : 0; + + this.data = { 'hash': nativeCreate(null), 'set': new Set }; + while (length--) { + this.push(values[length]); + } + } + + /** + * Checks if `value` is in `cache` mimicking the return signature of + * `_.indexOf` by returning `0` if the value is found, else `-1`. + * + * @private + * @param {Object} cache The cache to search. + * @param {*} value The value to search for. + * @returns {number} Returns `0` if `value` is found, else `-1`. + */ + function cacheIndexOf(cache, value) { + var data = cache.data, + result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value]; + + return result ? 0 : -1; + } + + /** + * Adds `value` to the cache. + * + * @private + * @name push + * @memberOf SetCache + * @param {*} value The value to cache. + */ + function cachePush(value) { + var data = this.data; + if (typeof value == 'string' || isObject(value)) { + data.set.add(value); + } else { + data.hash[value] = true; + } + } + + /*------------------------------------------------------------------------*/ + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function arrayCopy(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * A specialized version of `_.forEach` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.forEachRight` for arrays without support for + * callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEachRight(array, iteratee) { + var length = array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.every` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + */ + function arrayEvery(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; + } + + /** + * A specialized version of `_.filter` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * A specialized version of `_.map` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * A specialized version of `_.max` for arrays without support for iteratees. + * + * @private + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + */ + function arrayMax(array) { + var index = -1, + length = array.length, + result = NEGATIVE_INFINITY; + + while (++index < length) { + var value = array[index]; + if (value > result) { + result = value; + } + } + return result; + } + + /** + * A specialized version of `_.min` for arrays without support for iteratees. + * + * @private + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + */ + function arrayMin(array) { + var index = -1, + length = array.length, + result = POSITIVE_INFINITY; + + while (++index < length) { + var value = array[index]; + if (value < result) { + result = value; + } + } + return result; + } + + /** + * A specialized version of `_.reduce` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray] Specify using the first element of `array` + * as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initFromArray) { + var index = -1, + length = array.length; + + if (initFromArray && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * A specialized version of `_.reduceRight` for arrays without support for + * callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray] Specify using the last element of `array` + * as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduceRight(array, iteratee, accumulator, initFromArray) { + var length = array.length; + if (initFromArray && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; + } + + /** + * A specialized version of `_.some` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * A specialized version of `_.sum` for arrays without support for iteratees. + * + * @private + * @param {Array} array The array to iterate over. + * @returns {number} Returns the sum. + */ + function arraySum(array) { + var length = array.length, + result = 0; + + while (length--) { + result += +array[length] || 0; + } + return result; + } + + /** + * Used by `_.defaults` to customize its `_.assign` use. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @returns {*} Returns the value to assign to the destination object. + */ + function assignDefaults(objectValue, sourceValue) { + return objectValue === undefined ? sourceValue : objectValue; + } + + /** + * Used by `_.template` to customize its `_.assign` use. + * + * **Note:** This function is like `assignDefaults` except that it ignores + * inherited property values when checking if a property is `undefined`. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @param {string} key The key associated with the object and source values. + * @param {Object} object The destination object. + * @returns {*} Returns the value to assign to the destination object. + */ + function assignOwnDefaults(objectValue, sourceValue, key, object) { + return (objectValue === undefined || !hasOwnProperty.call(object, key)) + ? sourceValue + : objectValue; + } + + /** + * A specialized version of `_.assign` for customizing assigned values without + * support for argument juggling, multiple sources, and `this` binding `customizer` + * functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + */ + function assignWith(object, source, customizer) { + var props = keys(source); + push.apply(props, getSymbols(source)); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index], + value = object[key], + result = customizer(value, source[key], key, object, source); + + if ((result === result ? (result !== value) : (value === value)) || + (value === undefined && !(key in object))) { + object[key] = result; + } + } + return object; + } + + /** + * The base implementation of `_.assign` without support for argument juggling, + * multiple sources, and `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + var baseAssign = nativeAssign || function(object, source) { + return source == null + ? object + : baseCopy(source, getSymbols(source), baseCopy(source, keys(source), object)); + }; + + /** + * The base implementation of `_.at` without support for string collections + * and individual key arguments. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {number[]|string[]} props The property names or indexes of elements to pick. + * @returns {Array} Returns the new array of picked elements. + */ + function baseAt(collection, props) { + var index = -1, + length = collection.length, + isArr = isLength(length), + propsLength = props.length, + result = Array(propsLength); + + while(++index < propsLength) { + var key = props[index]; + if (isArr) { + result[index] = isIndex(key, length) ? collection[key] : undefined; + } else { + result[index] = collection[key]; + } + } + return result; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ + function baseCopy(source, props, object) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + object[key] = source[key]; + } + return object; + } + + /** + * The base implementation of `_.callback` which supports specifying the + * number of arguments to provide to `func`. + * + * @private + * @param {*} [func=_.identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ + function baseCallback(func, thisArg, argCount) { + var type = typeof func; + if (type == 'function') { + return thisArg === undefined + ? func + : bindCallback(func, thisArg, argCount); + } + if (func == null) { + return identity; + } + if (type == 'object') { + return baseMatches(func); + } + return thisArg === undefined + ? property(func) + : baseMatchesProperty(func, thisArg); + } + + /** + * The base implementation of `_.clone` without support for argument juggling + * and `this` binding `customizer` functions. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The object `value` belongs to. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates clones with source counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { + var result; + if (customizer) { + result = object ? customizer(value, key, object) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return arrayCopy(value, result); + } + } else { + var tag = objToString.call(value), + isFunc = tag == funcTag; + + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return baseAssign(result, value); + } + } else { + return cloneableTags[tag] + ? initCloneByTag(value, tag, isDeep) + : (object ? value : {}); + } + } + // Check for circular references and return corresponding clone. + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + // Add the source value to the stack of traversed objects and associate it with its clone. + stackA.push(value); + stackB.push(result); + + // Recursively populate clone (susceptible to call stack limits). + (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { + result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB); + }); + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function() { + function Object() {} + return function(prototype) { + if (isObject(prototype)) { + Object.prototype = prototype; + var result = new Object; + Object.prototype = null; + } + return result || context.Object(); + }; + }()); + + /** + * The base implementation of `_.delay` and `_.defer` which accepts an index + * of where to slice the arguments to provide to `func`. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Object} args The arguments provide to `func`. + * @returns {number} Returns the timer id. + */ + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * The base implementation of `_.difference` which accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @returns {Array} Returns the new array of filtered values. + */ + function baseDifference(array, values) { + var length = array ? array.length : 0, + result = []; + + if (!length) { + return result; + } + var index = -1, + indexOf = getIndexOf(), + isCommon = indexOf == baseIndexOf, + cache = (isCommon && values.length >= 200) ? createCache(values) : null, + valuesLength = values.length; + + if (cache) { + indexOf = cacheIndexOf; + isCommon = false; + values = cache; + } + outer: + while (++index < length) { + var value = array[index]; + + if (isCommon && value === value) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === value) { + continue outer; + } + } + result.push(value); + } + else if (indexOf(values, value, 0) < 0) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.forEach` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEach = createBaseEach(baseForOwn); + + /** + * The base implementation of `_.forEachRight` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEachRight = createBaseEach(baseForOwnRight, true); + + /** + * The base implementation of `_.every` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false` + */ + function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } + + /** + * The base implementation of `_.fill` without an iteratee call guard. + * + * @private + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + */ + function baseFill(array, value, start, end) { + var length = array.length; + + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : (end >>> 0); + start >>>= 0; + + while (start < length) { + array[start++] = value; + } + return array; + } + + /** + * The base implementation of `_.filter` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; + } + + /** + * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`, + * without support for callback shorthands and `this` binding, which iterates + * over `collection` using the provided `eachFunc`. + * + * @private + * @param {Array|Object|string} collection The collection to search. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @param {boolean} [retKey] Specify returning the key of the found element + * instead of the element itself. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFind(collection, predicate, eachFunc, retKey) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = retKey ? key : value; + return false; + } + }); + return result; + } + + /** + * The base implementation of `_.flatten` with added support for restricting + * flattening and specifying the start index. + * + * @private + * @param {Array} array The array to flatten. + * @param {boolean} isDeep Specify a deep flatten. + * @param {boolean} isStrict Restrict flattening to arrays and `arguments` objects. + * @returns {Array} Returns the new flattened array. + */ + function baseFlatten(array, isDeep, isStrict) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + + if (isObjectLike(value) && isLength(value.length) && (isArray(value) || isArguments(value))) { + if (isDeep) { + // Recursively flatten arrays (susceptible to call stack limits). + value = baseFlatten(value, isDeep, isStrict); + } + var valIndex = -1, + valLength = value.length; + + result.length += valLength; + while (++valIndex < valLength) { + result[++resIndex] = value[valIndex]; + } + } else if (!isStrict) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * The base implementation of `baseForIn` and `baseForOwn` which iterates + * over `object` properties returned by `keysFunc` invoking `iteratee` for + * each property. Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * This function is like `baseFor` except that it iterates over properties + * in the opposite order. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseForRight = createBaseFor(true); + + /** + * The base implementation of `_.forIn` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForIn(object, iteratee) { + return baseFor(object, iteratee, keysIn); + } + + /** + * The base implementation of `_.forOwn` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return baseFor(object, iteratee, keys); + } + + /** + * The base implementation of `_.forOwnRight` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwnRight(object, iteratee) { + return baseForRight(object, iteratee, keys); + } + + /** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from those provided. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the new array of filtered property names. + */ + function baseFunctions(object, props) { + var index = -1, + length = props.length, + resIndex = -1, + result = []; + + while (++index < length) { + var key = props[index]; + if (isFunction(object[key])) { + result[++resIndex] = key; + } + } + return result; + } + + /** + * The base implementation of `get` without support for string paths + * and default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path of the property to get. + * @param {string} [pathKey] The key representation of path. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path, pathKey) { + if (object == null) { + return; + } + if (pathKey !== undefined && pathKey in toObject(object)) { + path = [pathKey]; + } + var index = -1, + length = path.length; + + while (object != null && ++index < length) { + var result = object = object[path[index]]; + } + return result; + } + + /** + * The base implementation of `_.isEqual` without support for `this` binding + * `customizer` functions. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { + // Exit early for identical values. + if (value === other) { + // Treat `+0` vs. `-0` as not equal. + return value !== 0 || (1 / value == 1 / other); + } + var valType = typeof value, + othType = typeof other; + + // Exit early for unlike primitive values. + if ((valType != 'function' && valType != 'object' && othType != 'function' && othType != 'object') || + value == null || other == null) { + // Return `false` unless both values are `NaN`. + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); + } + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing objects. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `value` objects. + * @param {Array} [stackB=[]] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = arrayTag, + othTag = arrayTag; + + if (!objIsArr) { + objTag = objToString.call(object); + if (objTag == argsTag) { + objTag = objectTag; + } else if (objTag != objectTag) { + objIsArr = isTypedArray(object); + } + } + if (!othIsArr) { + othTag = objToString.call(other); + if (othTag == argsTag) { + othTag = objectTag; + } else if (othTag != objectTag) { + othIsArr = isTypedArray(other); + } + } + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && !(objIsArr || objIsObj)) { + return equalByTag(object, other, objTag); + } + if (!isLoose) { + var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (valWrapped || othWrapped) { + return equalFunc(valWrapped ? object.value() : object, othWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); + } + } + if (!isSameTag) { + return false; + } + // Assume cyclic values are equal. + // For more information on detecting circular references see https://es5.github.io/#JO. + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == object) { + return stackB[length] == other; + } + } + // Add `object` and `other` to the stack of traversed objects. + stackA.push(object); + stackB.push(other); + + var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); + + stackA.pop(); + stackB.pop(); + + return result; + } + + /** + * The base implementation of `_.isMatch` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The source property names to match. + * @param {Array} values The source values to match. + * @param {Array} strictCompareFlags Strict comparison flags for source values. + * @param {Function} [customizer] The function to customize comparing objects. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, props, values, strictCompareFlags, customizer) { + var index = -1, + length = props.length, + noCustomizer = !customizer; + + while (++index < length) { + if ((noCustomizer && strictCompareFlags[index]) + ? values[index] !== object[props[index]] + : !(props[index] in object) + ) { + return false; + } + } + index = -1; + while (++index < length) { + var key = props[index], + objValue = object[key], + srcValue = values[index]; + + if (noCustomizer && strictCompareFlags[index]) { + var result = objValue !== undefined || (key in object); + } else { + result = customizer ? customizer(objValue, srcValue, key) : undefined; + if (result === undefined) { + result = baseIsEqual(srcValue, objValue, customizer, true); + } + } + if (!result) { + return false; + } + } + return true; + } + + /** + * The base implementation of `_.map` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function baseMap(collection, iteratee) { + var index = -1, + length = getLength(collection), + result = isLength(length) ? Array(length) : []; + + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; + } + + /** + * The base implementation of `_.matches` which does not clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + */ + function baseMatches(source) { + var props = keys(source), + length = props.length; + + if (!length) { + return constant(true); + } + if (length == 1) { + var key = props[0], + value = source[key]; + + if (isStrictComparable(value)) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === value && (value !== undefined || (key in toObject(object))); + }; + } + } + var values = Array(length), + strictCompareFlags = Array(length); + + while (length--) { + value = source[props[length]]; + values[length] = value; + strictCompareFlags[length] = isStrictComparable(value); + } + return function(object) { + return object != null && baseIsMatch(toObject(object), props, values, strictCompareFlags); + }; + } + + /** + * The base implementation of `_.matchesProperty` which does not which does + * not clone `value`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} value The value to compare. + * @returns {Function} Returns the new function. + */ + function baseMatchesProperty(path, value) { + var isArr = isArray(path), + isCommon = isKey(path) && isStrictComparable(value), + pathKey = (path + ''); + + path = toPath(path); + return function(object) { + if (object == null) { + return false; + } + var key = pathKey; + object = toObject(object); + if ((isArr || !isCommon) && !(key in object)) { + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + if (object == null) { + return false; + } + key = last(path); + object = toObject(object); + } + return object[key] === value + ? (value !== undefined || (key in object)) + : baseIsEqual(value, object[key], null, true); + }; + } + + /** + * The base implementation of `_.merge` without support for argument juggling, + * multiple sources, and `this` binding `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} [customizer] The function to customize merging properties. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + * @returns {Object} Returns `object`. + */ + function baseMerge(object, source, customizer, stackA, stackB) { + if (!isObject(object)) { + return object; + } + var isSrcArr = isLength(source.length) && (isArray(source) || isTypedArray(source)); + if (!isSrcArr) { + var props = keys(source); + push.apply(props, getSymbols(source)); + } + arrayEach(props || source, function(srcValue, key) { + if (props) { + key = srcValue; + srcValue = source[key]; + } + if (isObjectLike(srcValue)) { + stackA || (stackA = []); + stackB || (stackB = []); + baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); + } + else { + var value = object[key], + result = customizer ? customizer(value, srcValue, key, object, source) : undefined, + isCommon = result === undefined; + + if (isCommon) { + result = srcValue; + } + if ((isSrcArr || result !== undefined) && + (isCommon || (result === result ? (result !== value) : (value === value)))) { + object[key] = result; + } + } + }); + return object; + } + + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize merging properties. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) { + var length = stackA.length, + srcValue = source[key]; + + while (length--) { + if (stackA[length] == srcValue) { + object[key] = stackB[length]; + return; + } + } + var value = object[key], + result = customizer ? customizer(value, srcValue, key, object, source) : undefined, + isCommon = result === undefined; + + if (isCommon) { + result = srcValue; + if (isLength(srcValue.length) && (isArray(srcValue) || isTypedArray(srcValue))) { + result = isArray(value) + ? value + : (getLength(value) ? arrayCopy(value) : []); + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + result = isArguments(value) + ? toPlainObject(value) + : (isPlainObject(value) ? value : {}); + } + else { + isCommon = false; + } + } + // Add the source value to the stack of traversed objects and associate + // it with its merged value. + stackA.push(srcValue); + stackB.push(result); + + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB); + } else if (result === result ? (result !== value) : (value === value)) { + object[key] = result; + } + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new function. + */ + function basePropertyDeep(path) { + var pathKey = (path + ''); + path = toPath(path); + return function(object) { + return baseGet(object, path, pathKey); + }; + } + + /** + * The base implementation of `_.pullAt` without support for individual + * index arguments and capturing the removed elements. + * + * @private + * @param {Array} array The array to modify. + * @param {number[]} indexes The indexes of elements to remove. + * @returns {Array} Returns `array`. + */ + function basePullAt(array, indexes) { + var length = indexes.length; + while (length--) { + var index = parseFloat(indexes[length]); + if (index != previous && isIndex(index)) { + var previous = index; + splice.call(array, index, 1); + } + } + return array; + } + + /** + * The base implementation of `_.random` without support for argument juggling + * and returning floating-point numbers. + * + * @private + * @param {number} min The minimum possible value. + * @param {number} max The maximum possible value. + * @returns {number} Returns the random number. + */ + function baseRandom(min, max) { + return min + floor(nativeRandom() * (max - min + 1)); + } + + /** + * The base implementation of `_.reduce` and `_.reduceRight` without support + * for callback shorthands and `this` binding, which iterates over `collection` + * using the provided `eachFunc`. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initFromCollection Specify using the first or last element + * of `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initFromCollection + ? (initFromCollection = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The base implementation of `setData` without support for hot loop detection. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var baseSetData = !metaMap ? identity : function(func, data) { + metaMap.set(func, data); + return func; + }; + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * The base implementation of `_.some` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } + + /** + * The base implementation of `_.sortBy` which uses `comparer` to define + * the sort order of `array` and replaces criteria objects with their + * corresponding values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ + function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; + } + + /** + * The base implementation of `_.sortByOrder` without param guards. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {boolean[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ + function baseSortByOrder(collection, iteratees, orders) { + var callback = getCallback(), + index = -1; + + iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); }); + + var result = baseMap(collection, function(value) { + var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); + } + + /** + * The base implementation of `_.sum` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function baseSum(collection, iteratee) { + var result = 0; + baseEach(collection, function(value, index, collection) { + result += +iteratee(value, index, collection) || 0; + }); + return result; + } + + /** + * The base implementation of `_.uniq` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function baseUniq(array, iteratee) { + var index = -1, + indexOf = getIndexOf(), + length = array.length, + isCommon = indexOf == baseIndexOf, + isLarge = isCommon && length >= 200, + seen = isLarge ? createCache() : null, + result = []; + + if (seen) { + indexOf = cacheIndexOf; + isCommon = false; + } else { + isLarge = false; + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; + + if (isCommon && value === value) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (indexOf(seen, computed, 0) < 0) { + if (iteratee || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + var index = -1, + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } + + /** + * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`, + * and `_.takeWhile` without support for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to query. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [isDrop] Specify dropping elements instead of taking them. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the slice of `array`. + */ + function baseWhile(array, predicate, isDrop, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {} + return isDrop + ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) + : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); + } + + /** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to peform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ + function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + var index = -1, + length = actions.length; + + while (++index < length) { + var args = [result], + action = actions[index]; + + push.apply(args, action.args); + result = action.func.apply(action.thisArg, args); + } + return result; + } + + /** + * Performs a binary search of `array` to determine the index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function binaryIndex(array, value, retHighest) { + var low = 0, + high = array ? array.length : low; + + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; + + if (retHighest ? (computed <= value) : (computed < value)) { + low = mid + 1; + } else { + high = mid; + } + } + return high; + } + return binaryIndexBy(array, value, identity, retHighest); + } + + /** + * This function is like `binaryIndex` except that it invokes `iteratee` for + * `value` and each element of `array` to compute their sort ranking. The + * iteratee is invoked with one argument; (value). + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} iteratee The function invoked per iteration. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function binaryIndexBy(array, value, iteratee, retHighest) { + value = iteratee(value); + + var low = 0, + high = array ? array.length : 0, + valIsNaN = value !== value, + valIsUndef = value === undefined; + + while (low < high) { + var mid = floor((low + high) / 2), + computed = iteratee(array[mid]), + isReflexive = computed === computed; + + if (valIsNaN) { + var setLow = isReflexive || retHighest; + } else if (valIsUndef) { + setLow = isReflexive && (retHighest || computed !== undefined); + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); + } + + /** + * A specialized version of `baseCallback` which only supports `this` binding + * and specifying the number of arguments to provide to `func`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ + function bindCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + if (thisArg === undefined) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + case 5: return function(value, other, key, object, source) { + return func.call(thisArg, value, other, key, object, source); + }; + } + return function() { + return func.apply(thisArg, arguments); + }; + } + + /** + * Creates a clone of the given array buffer. + * + * @private + * @param {ArrayBuffer} buffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function bufferClone(buffer) { + return bufferSlice.call(buffer, 0); + } + if (!bufferSlice) { + // PhantomJS has `ArrayBuffer` and `Uint8Array` but not `Float64Array`. + bufferClone = !(ArrayBuffer && Uint8Array) ? constant(null) : function(buffer) { + var byteLength = buffer.byteLength, + floatLength = Float64Array ? floor(byteLength / FLOAT64_BYTES_PER_ELEMENT) : 0, + offset = floatLength * FLOAT64_BYTES_PER_ELEMENT, + result = new ArrayBuffer(byteLength); + + if (floatLength) { + var view = new Float64Array(result, 0, floatLength); + view.set(new Float64Array(buffer, 0, floatLength)); + } + if (byteLength != offset) { + view = new Uint8Array(result, offset); + view.set(new Uint8Array(buffer, offset)); + } + return result; + }; + } + + /** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgs(args, partials, holders) { + var holdersLength = holders.length, + argsIndex = -1, + argsLength = nativeMax(args.length - holdersLength, 0), + leftIndex = -1, + leftLength = partials.length, + result = Array(argsLength + leftLength); + + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + while (argsLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; + } + + /** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgsRight(args, partials, holders) { + var holdersIndex = -1, + holdersLength = holders.length, + argsIndex = -1, + argsLength = nativeMax(args.length - holdersLength, 0), + rightIndex = -1, + rightLength = partials.length, + result = Array(argsLength + rightLength); + + while (++argsIndex < argsLength) { + result[argsIndex] = args[argsIndex]; + } + var pad = argsIndex; + while (++rightIndex < rightLength) { + result[pad + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + result[pad + holders[holdersIndex]] = args[argsIndex++]; + } + return result; + } + + /** + * Creates a function that aggregates a collection, creating an accumulator + * object composed from the results of running each element in the collection + * through an iteratee. + * + * **Note:** This function is used to create `_.countBy`, `_.groupBy`, `_.indexBy`, + * and `_.partition`. + * + * @private + * @param {Function} setter The function to set keys and values of the accumulator object. + * @param {Function} [initializer] The function to initialize the accumulator object. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter, initializer) { + return function(collection, iteratee, thisArg) { + var result = initializer ? initializer() : {}; + iteratee = getCallback(iteratee, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + setter(result, value, iteratee(value, index, collection), collection); + } + } else { + baseEach(collection, function(value, key, collection) { + setter(result, value, iteratee(value, key, collection), collection); + }); + } + return result; + }; + } + + /** + * Creates a function that assigns properties of source object(s) to a given + * destination object. + * + * **Note:** This function is used to create `_.assign`, `_.defaults`, and `_.merge`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return restParam(function(object, sources) { + var index = -1, + length = object == null ? 0 : sources.length, + customizer = length > 2 && sources[length - 2], + guard = length > 2 && sources[2], + thisArg = length > 1 && sources[length - 1]; + + if (typeof customizer == 'function') { + customizer = bindCallback(customizer, thisArg, 5); + length -= 2; + } else { + customizer = typeof thisArg == 'function' ? thisArg : null; + length -= (customizer ? 1 : 0); + } + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? null : customizer; + length = 1; + } + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, customizer); + } + } + return object; + }); + } + + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + return eachFunc(collection, iteratee); + } + var index = fromRight ? length : -1, + iterable = toObject(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } + + /** + * Creates a base function for `_.forIn` or `_.forInRight`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var iterable = toObject(object), + props = keysFunc(object), + length = props.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + var key = props[index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * Creates a function that wraps `func` and invokes it with the `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new bound function. + */ + function createBindWrapper(func, thisArg) { + var Ctor = createCtorWrapper(func); + + function wrapper() { + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(thisArg, arguments); + } + return wrapper; + } + + /** + * Creates a `Set` cache object to optimize linear searches of large arrays. + * + * @private + * @param {Array} [values] The values to cache. + * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`. + */ + var createCache = !(nativeCreate && Set) ? constant(null) : function(values) { + return new SetCache(values); + }; + + /** + * Creates a function that produces compound words out of the words in a + * given string. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ + function createCompounder(callback) { + return function(string) { + var index = -1, + array = words(deburr(string)), + length = array.length, + result = ''; + + while (++index < length) { + result = callback(result, array[index], index); + } + return result; + }; + } + + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ + function createCtorWrapper(Ctor) { + return function() { + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, arguments); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } + + /** + * Creates a `_.curry` or `_.curryRight` function. + * + * @private + * @param {boolean} flag The curry bit flag. + * @returns {Function} Returns the new curry function. + */ + function createCurry(flag) { + function curryFunc(func, arity, guard) { + if (guard && isIterateeCall(func, arity, guard)) { + arity = null; + } + var result = createWrapper(func, flag, null, null, null, null, null, arity); + result.placeholder = curryFunc.placeholder; + return result; + } + return curryFunc; + } + + /** + * Creates a `_.max` or `_.min` function. + * + * @private + * @param {Function} arrayFunc The function to get the extremum value from an array. + * @param {boolean} [isMin] Specify returning the minimum, instead of the maximum, + * extremum value. + * @returns {Function} Returns the new extremum function. + */ + function createExtremum(arrayFunc, isMin) { + return function(collection, iteratee, thisArg) { + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = null; + } + var func = getCallback(), + noIteratee = iteratee == null; + + if (!(func === baseCallback && noIteratee)) { + noIteratee = false; + iteratee = func(iteratee, thisArg, 3); + } + if (noIteratee) { + var isArr = isArray(collection); + if (!isArr && isString(collection)) { + iteratee = charAtCallback; + } else { + return arrayFunc(isArr ? collection : toIterable(collection)); + } + } + return extremumBy(collection, iteratee, isMin); + }; + } + + /** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new find function. + */ + function createFind(eachFunc, fromRight) { + return function(collection, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate, fromRight); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, eachFunc); + } + } + + /** + * Creates a `_.findIndex` or `_.findLastIndex` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new find function. + */ + function createFindIndex(fromRight) { + return function(array, predicate, thisArg) { + if (!(array && array.length)) { + return -1; + } + predicate = getCallback(predicate, thisArg, 3); + return baseFindIndex(array, predicate, fromRight); + }; + } + + /** + * Creates a `_.findKey` or `_.findLastKey` function. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new find function. + */ + function createFindKey(objectFunc) { + return function(object, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + return baseFind(object, predicate, objectFunc, true); + }; + } + + /** + * Creates a `_.flow` or `_.flowRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new flow function. + */ + function createFlow(fromRight) { + return function() { + var length = arguments.length; + if (!length) { + return function() { return arguments[0]; }; + } + var wrapper, + index = fromRight ? length : -1, + leftIndex = 0, + funcs = Array(length); + + while ((fromRight ? index-- : ++index < length)) { + var func = funcs[leftIndex++] = arguments[index]; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var funcName = wrapper ? '' : getFuncName(func); + wrapper = funcName == 'wrapper' ? new LodashWrapper([]) : wrapper; + } + index = wrapper ? -1 : length; + while (++index < length) { + func = funcs[index]; + funcName = getFuncName(func); + + var data = funcName == 'wrapper' ? getData(func) : null; + if (data && isLaziable(data[0])) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); + } + } + return function() { + var args = arguments; + if (wrapper && args.length == 1 && isArray(args[0])) { + return wrapper.plant(args[0]).value(); + } + var index = 0, + result = funcs[index].apply(this, args); + + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }; + } + + /** + * Creates a function for `_.forEach` or `_.forEachRight`. + * + * @private + * @param {Function} arrayFunc The function to iterate over an array. + * @param {Function} eachFunc The function to iterate over a collection. + * @returns {Function} Returns the new each function. + */ + function createForEach(arrayFunc, eachFunc) { + return function(collection, iteratee, thisArg) { + return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) + ? arrayFunc(collection, iteratee) + : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); + }; + } + + /** + * Creates a function for `_.forIn` or `_.forInRight`. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new each function. + */ + function createForIn(objectFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || thisArg !== undefined) { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee, keysIn); + }; + } + + /** + * Creates a function for `_.forOwn` or `_.forOwnRight`. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new each function. + */ + function createForOwn(objectFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || thisArg !== undefined) { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee); + }; + } + + /** + * Creates a function for `_.padLeft` or `_.padRight`. + * + * @private + * @param {boolean} [fromRight] Specify padding from the right. + * @returns {Function} Returns the new pad function. + */ + function createPadDir(fromRight) { + return function(string, length, chars) { + string = baseToString(string); + return string && ((fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string)); + }; + } + + /** + * Creates a `_.partial` or `_.partialRight` function. + * + * @private + * @param {boolean} flag The partial bit flag. + * @returns {Function} Returns the new partial function. + */ + function createPartial(flag) { + var partialFunc = restParam(function(func, partials) { + var holders = replaceHolders(partials, partialFunc.placeholder); + return createWrapper(func, flag, null, partials, holders); + }); + return partialFunc; + } + + /** + * Creates a function for `_.reduce` or `_.reduceRight`. + * + * @private + * @param {Function} arrayFunc The function to iterate over an array. + * @param {Function} eachFunc The function to iterate over a collection. + * @returns {Function} Returns the new each function. + */ + function createReduce(arrayFunc, eachFunc) { + return function(collection, iteratee, accumulator, thisArg) { + var initFromArray = arguments.length < 3; + return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) + ? arrayFunc(collection, iteratee, accumulator, initFromArray) + : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc); + }; + } + + /** + * Creates a function that wraps `func` and invokes it with optional `this` + * binding of, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [partialsRight] The arguments to append to those provided to the new function. + * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & ARY_FLAG, + isBind = bitmask & BIND_FLAG, + isBindKey = bitmask & BIND_KEY_FLAG, + isCurry = bitmask & CURRY_FLAG, + isCurryBound = bitmask & CURRY_BOUND_FLAG, + isCurryRight = bitmask & CURRY_RIGHT_FLAG; + + var Ctor = !isBindKey && createCtorWrapper(func), + key = func; + + function wrapper() { + // Avoid `arguments` object use disqualifying optimizations by + // converting it to an array before providing it to other functions. + var length = arguments.length, + index = length, + args = Array(length); + + while (index--) { + args[index] = arguments[index]; + } + if (partials) { + args = composeArgs(args, partials, holders); + } + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight); + } + if (isCurry || isCurryRight) { + var placeholder = wrapper.placeholder, + argsHolders = replaceHolders(args, placeholder); + + length -= argsHolders.length; + if (length < arity) { + var newArgPos = argPos ? arrayCopy(argPos) : null, + newArity = nativeMax(arity - length, 0), + newsHolders = isCurry ? argsHolders : null, + newHoldersRight = isCurry ? null : argsHolders, + newPartials = isCurry ? args : null, + newPartialsRight = isCurry ? null : args; + + bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); + + if (!isCurryBound) { + bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); + } + var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], + result = createHybridWrapper.apply(undefined, newData); + + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return result; + } + } + var thisBinding = isBind ? thisArg : this; + if (isBindKey) { + func = thisBinding[key]; + } + if (argPos) { + args = reorder(args, argPos); + } + if (isAry && ary < args.length) { + args.length = ary; + } + var fn = (this && this !== root && this instanceof wrapper) ? (Ctor || createCtorWrapper(func)) : func; + return fn.apply(thisBinding, args); + } + return wrapper; + } + + /** + * Creates the padding required for `string` based on the given `length`. + * The `chars` string is truncated if the number of characters exceeds `length`. + * + * @private + * @param {string} string The string to create padding for. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the pad for `string`. + */ + function createPadding(string, length, chars) { + var strLength = string.length; + length = +length; + + if (strLength >= length || !nativeIsFinite(length)) { + return ''; + } + var padLength = length - strLength; + chars = chars == null ? ' ' : (chars + ''); + return repeat(chars, ceil(padLength / chars.length)).slice(0, padLength); + } + + /** + * Creates a function that wraps `func` and invokes it with the optional `this` + * binding of `thisArg` and the `partials` prepended to those provided to + * the wrapper. + * + * @private + * @param {Function} func The function to partially apply arguments to. + * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to the new function. + * @returns {Function} Returns the new bound function. + */ + function createPartialWrapper(func, bitmask, thisArg, partials) { + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + // Avoid `arguments` object use disqualifying optimizations by + // converting it to an array before providing it `func`. + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(argsLength + leftLength); + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(isBind ? thisArg : this, args); + } + return wrapper; + } + + /** + * Creates a `_.sortedIndex` or `_.sortedLastIndex` function. + * + * @private + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {Function} Returns the new index function. + */ + function createSortedIndex(retHighest) { + return function(array, value, iteratee, thisArg) { + var func = getCallback(iteratee); + return (func === baseCallback && iteratee == null) + ? binaryIndex(array, value, retHighest) + : binaryIndexBy(array, value, func(iteratee, thisArg, 1), retHighest); + }; + } + + /** + * Creates a function that either curries or invokes `func` with optional + * `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of flags. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to be partially applied. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & BIND_KEY_FLAG; + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); + partials = holders = null; + } + length -= (holders ? holders.length : 0); + if (bitmask & PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; + + partials = holders = null; + } + var data = isBindKey ? null : getData(func), + newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; + + if (data) { + mergeData(newData, data); + bitmask = newData[1]; + arity = newData[9]; + } + newData[9] = arity == null + ? (isBindKey ? 0 : func.length) + : (nativeMax(arity - length, 0) || 0); + + if (bitmask == BIND_FLAG) { + var result = createBindWrapper(newData[0], newData[2]); + } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) { + result = createPartialWrapper.apply(undefined, newData); + } else { + result = createHybridWrapper.apply(undefined, newData); + } + var setter = data ? baseSetData : setData; + return setter(result, newData); + } + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing arrays. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { + var index = -1, + arrLength = array.length, + othLength = other.length, + result = true; + + if (arrLength != othLength && !(isLoose && othLength > arrLength)) { + return false; + } + // Deep compare the contents, ignoring non-numeric properties. + while (result && ++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + result = undefined; + if (customizer) { + result = isLoose + ? customizer(othValue, arrValue, index) + : customizer(arrValue, othValue, index); + } + if (result === undefined) { + // Recursively compare arrays (susceptible to call stack limits). + if (isLoose) { + var othIndex = othLength; + while (othIndex--) { + othValue = other[othIndex]; + result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); + if (result) { + break; + } + } + } else { + result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); + } + } + } + return !!result; + } + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} value The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag) { + switch (tag) { + case boolTag: + case dateTag: + // Coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. + return +object == +other; + + case errorTag: + return object.name == other.name && object.message == other.message; + + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) + ? other != +other + // But, treat `-0` vs. `+0` as not equal. + : (object == 0 ? ((1 / object) == (1 / other)) : object == +other); + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings primitives and string + // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. + return object == (other + ''); + } + return false; + } + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; + + if (objLength != othLength && !isLoose) { + return false; + } + var skipCtor = isLoose, + index = -1; + + while (++index < objLength) { + var key = objProps[index], + result = isLoose ? key in other : hasOwnProperty.call(other, key); + + if (result) { + var objValue = object[key], + othValue = other[key]; + + result = undefined; + if (customizer) { + result = isLoose + ? customizer(othValue, objValue, key) + : customizer(objValue, othValue, key); + } + if (result === undefined) { + // Recursively compare objects (susceptible to call stack limits). + result = (objValue && objValue === othValue) || equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB); + } + } + if (!result) { + return false; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (!skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + return false; + } + } + return true; + } + + /** + * Gets the extremum value of `collection` invoking `iteratee` for each value + * in `collection` to generate the criterion by which the value is ranked. + * The `iteratee` is invoked with three arguments: (value, index, collection). + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {boolean} [isMin] Specify returning the minimum, instead of the + * maximum, extremum value. + * @returns {*} Returns the extremum value. + */ + function extremumBy(collection, iteratee, isMin) { + var exValue = isMin ? POSITIVE_INFINITY : NEGATIVE_INFINITY, + computed = exValue, + result = computed; + + baseEach(collection, function(value, index, collection) { + var current = iteratee(value, index, collection); + if ((isMin ? (current < computed) : (current > computed)) || + (current === exValue && current === result)) { + computed = current; + result = value; + } + }); + return result; + } + + /** + * Gets the appropriate "callback" function. If the `_.callback` method is + * customized this function returns the custom method, otherwise it returns + * the `baseCallback` function. If arguments are provided the chosen function + * is invoked with them and its result is returned. + * + * @private + * @returns {Function} Returns the chosen function or its result. + */ + function getCallback(func, thisArg, argCount) { + var result = lodash.callback || callback; + result = result === callback ? baseCallback : result; + return argCount ? result(func, thisArg, argCount) : result; + } + + /** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ + var getData = !metaMap ? noop : function(func) { + return metaMap.get(func); + }; + + /** + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ + var getFuncName = (function() { + if (!support.funcNames) { + return constant(''); + } + if (constant.name == 'constant') { + return baseProperty('name'); + } + return function(func) { + var result = func.name, + array = realNames[result], + length = array ? array.length : 0; + + while (length--) { + var data = array[length], + otherFunc = data.func; + + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; + }; + }()); + + /** + * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * customized this function returns the custom method, otherwise it returns + * the `baseIndexOf` function. If arguments are provided the chosen function + * is invoked with them and its result is returned. + * + * @private + * @returns {Function|number} Returns the chosen function or its result. + */ + function getIndexOf(collection, target, fromIndex) { + var result = lodash.indexOf || indexOf; + result = result === indexOf ? baseIndexOf : result; + return collection ? result(collection, target, fromIndex) : result; + } + + /** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * in Safari on iOS 8.1 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ + var getLength = baseProperty('length'); + + /** + * Creates an array of the own symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = !getOwnPropertySymbols ? constant([]) : function(object) { + return getOwnPropertySymbols(toObject(object)); + }; + + /** + * Gets the view, applying any `transforms` to the `start` and `end` positions. + * + * @private + * @param {number} start The start of the view. + * @param {number} end The end of the view. + * @param {Array} [transforms] The transformations to apply to the view. + * @returns {Object} Returns an object containing the `start` and `end` + * positions of the view. + */ + function getView(start, end, transforms) { + var index = -1, + length = transforms ? transforms.length : 0; + + while (++index < length) { + var data = transforms[index], + size = data.size; + + switch (data.type) { + case 'drop': start += size; break; + case 'dropRight': end -= size; break; + case 'take': end = nativeMin(end, start + size); break; + case 'takeRight': start = nativeMax(start, end - size); break; + } + } + return { 'start': start, 'end': end }; + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add array properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + var Ctor = object.constructor; + if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { + Ctor = Object; + } + return new Ctor; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return bufferClone(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + var buffer = object.buffer; + return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + var result = new Ctor(object.source, reFlags.exec(object)); + result.lastIndex = object.lastIndex; + } + return result; + } + + /** + * Invokes the method at `path` on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ + function invokePath(object, path, args) { + if (object != null && !isKey(path, object)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + path = last(path); + } + var func = object == null ? object : object[path]; + return func == null ? undefined : func.apply(object, args); + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + value = +value; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; + } + + /** + * Checks if the provided arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number') { + var length = getLength(object), + prereq = isLength(length) && isIndex(index, length); + } else { + prereq = type == 'string' && index in object; + } + if (prereq) { + var other = object[index]; + return value === value ? (value === other) : (other !== other); + } + return false; + } + + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + var type = typeof value; + if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { + return true; + } + if (isArray(value)) { + return false; + } + var result = !reIsDeepProp.test(value); + return result || (object != null && value in toObject(object)); + } + + /** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. + */ + function isLaziable(func) { + var funcName = getFuncName(func); + return !!funcName && func === lodash[funcName] && funcName in LazyWrapper.prototype; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength). + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ + function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ + function isStrictComparable(value) { + return value === value && (value === 0 ? ((1 / value) > 0) : !isObject(value)); + } + + /** + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers required to invoke a function. + * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` + * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` + * augment function arguments, making the order in which they are executed important, + * preventing the merging of metadata. However, we make an exception for a safe + * common case where curried functions have `_.ary` and or `_.rearg` applied. + * + * @private + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. + */ + function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < ARY_FLAG; + + var isCombo = + (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || + (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) || + (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; + } + // Use source `thisArg` if available. + if (srcBitmask & BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; + } + // Compose partial arguments. + var value = source[3]; + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value); + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]); + } + // Compose partial right arguments. + value = source[5]; + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value); + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]); + } + // Use source `argPos` if available. + value = source[7]; + if (value) { + data[7] = arrayCopy(value); + } + // Use source `ary` if it's smaller. + if (srcBitmask & ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } + // Use source `arity` if one is not provided. + if (data[9] == null) { + data[9] = source[9]; + } + // Use source `func` and merge bitmasks. + data[0] = source[0]; + data[1] = newBitmask; + + return data; + } + + /** + * A specialized version of `_.pick` that picks `object` properties specified + * by `props`. + * + * @private + * @param {Object} object The source object. + * @param {string[]} props The property names to pick. + * @returns {Object} Returns the new object. + */ + function pickByArray(object, props) { + object = toObject(object); + + var index = -1, + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + return result; + } + + /** + * A specialized version of `_.pick` that picks `object` properties `predicate` + * returns truthy for. + * + * @private + * @param {Object} object The source object. + * @param {Function} predicate The function invoked per iteration. + * @returns {Object} Returns the new object. + */ + function pickByCallback(object, predicate) { + var result = {}; + baseForIn(object, function(value, key, object) { + if (predicate(value, key, object)) { + result[key] = value; + } + }); + return result; + } + + /** + * Reorder `array` according to the specified indexes where the element at + * the first index is assigned as the first element, the element at + * the second index is assigned as the second element, and so on. + * + * @private + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. + */ + function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = arrayCopy(array); + + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; + } + return array; + } + + /** + * Sets metadata for `func`. + * + * **Note:** If this function becomes hot, i.e. is invoked a lot in a short + * period of time, it will trip its breaker and transition to an identity function + * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) + * for more details. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var setData = (function() { + var count = 0, + lastCalled = 0; + + return function(key, value) { + var stamp = now(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return key; + } + } else { + count = 0; + } + return baseSetData(key, value); + }; + }()); + + /** + * A fallback implementation of `_.isPlainObject` which checks if `value` + * is an object created by the `Object` constructor or has a `[[Prototype]]` + * of `null`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + */ + function shimIsPlainObject(value) { + var Ctor, + support = lodash.support; + + // Exit early for non `Object` objects. + if (!(isObjectLike(value) && objToString.call(value) == objectTag) || + (!hasOwnProperty.call(value, 'constructor') && + (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { + return false; + } + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + var result; + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + baseForIn(value, function(subValue, key) { + result = key; + }); + return result === undefined || hasOwnProperty.call(value, result); + } + + /** + * A fallback implementation of `Object.keys` which creates an array of the + * own enumerable property names of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function shimKeys(object) { + var props = keysIn(object), + propsLength = props.length, + length = propsLength && object.length, + support = lodash.support; + + var allowIndexes = length && isLength(length) && + (isArray(object) || (support.nonEnumArgs && isArguments(object))); + + var index = -1, + result = []; + + while (++index < propsLength) { + var key = props[index]; + if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { + result.push(key); + } + } + return result; + } + + /** + * Converts `value` to an array-like object if it is not one. + * + * @private + * @param {*} value The value to process. + * @returns {Array|Object} Returns the array-like object. + */ + function toIterable(value) { + if (value == null) { + return []; + } + if (!isLength(getLength(value))) { + return values(value); + } + return isObject(value) ? value : Object(value); + } + + /** + * Converts `value` to an object if it is not one. + * + * @private + * @param {*} value The value to process. + * @returns {Object} Returns the object. + */ + function toObject(value) { + return isObject(value) ? value : Object(value); + } + + /** + * Converts `value` to property path array if it is not one. + * + * @private + * @param {*} value The value to process. + * @returns {Array} Returns the property path array. + */ + function toPath(value) { + if (isArray(value)) { + return value; + } + var result = []; + baseToString(value).replace(rePropName, function(match, number, quote, string) { + result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + } + + /** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ + function wrapperClone(wrapper) { + return wrapper instanceof LazyWrapper + ? wrapper.clone() + : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements split into groups the length of `size`. + * If `collection` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=1] The length of each chunk. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new array containing chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ + function chunk(array, size, guard) { + if (guard ? isIterateeCall(array, size, guard) : size == null) { + size = 1; + } else { + size = nativeMax(+size || 1, 1); + } + var index = 0, + length = array ? array.length : 0, + resIndex = -1, + result = Array(ceil(length / size)); + + while (index < length) { + result[++resIndex] = baseSlice(array, index, (index += size)); + } + return result; + } + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * Creates an array excluding all values of the provided arrays using + * `SameValueZero` for equality comparisons. + * + * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * comparisons are like strict equality comparisons, e.g. `===`, except that + * `NaN` matches `NaN`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.difference([1, 2, 3], [4, 2]); + * // => [1, 3] + */ + var difference = restParam(function(array, values) { + return (isArray(array) || isArguments(array)) + ? baseDifference(array, baseFlatten(values, false, true)) + : []; + }); + + /** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function drop(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements dropped from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRight([1, 2, 3]); + * // => [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function dropRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that match the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [1] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); + * // => ['barney'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function dropRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true) + : []; + } + + /** + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [3] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropWhile(users, 'active', false), 'user'); + * // => ['pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function dropWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true) + : []; + } + + /** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8], '*', 1, 2); + * // => [4, '*', 8] + */ + function fill(array, value, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } + return baseFill(array, value, start, end); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(chr) { + * return chr.user == 'barney'; + * }); + * // => 0 + * + * // using the `_.matches` callback shorthand + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // using the `_.matchesProperty` callback shorthand + * _.findIndex(users, 'active', false); + * // => 0 + * + * // using the `_.property` callback shorthand + * _.findIndex(users, 'active'); + * // => 2 + */ + var findIndex = createFindIndex(); + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(chr) { + * return chr.user == 'pebbles'; + * }); + * // => 2 + * + * // using the `_.matches` callback shorthand + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastIndex(users, 'active', false); + * // => 2 + * + * // using the `_.property` callback shorthand + * _.findLastIndex(users, 'active'); + * // => 0 + */ + var findLastIndex = createFindIndex(true); + + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @alias head + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([]); + * // => undefined + */ + function first(array) { + return array ? array[0] : undefined; + } + + /** + * Flattens a nested array. If `isDeep` is `true` the array is recursively + * flattened, otherwise it is only flattened a single level. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @param {boolean} [isDeep] Specify a deep flatten. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, 3, [4]]]); + * // => [1, 2, 3, [4]] + * + * // using `isDeep` + * _.flatten([1, [2, 3, [4]]], true); + * // => [1, 2, 3, 4] + */ + function flatten(array, isDeep, guard) { + var length = array ? array.length : 0; + if (guard && isIterateeCall(array, isDeep, guard)) { + isDeep = false; + } + return length ? baseFlatten(array, isDeep) : []; + } + + /** + * Recursively flattens a nested array. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to recursively flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, 3, [4]]]); + * // => [1, 2, 3, 4] + */ + function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, true) : []; + } + + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using `SameValueZero` for equality comparisons. If `fromIndex` is negative, + * it is used as the offset from the end of `array`. If `array` is sorted + * providing `true` for `fromIndex` performs a faster binary search. + * + * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * comparisons are like strict equality comparisons, e.g. `===`, except that + * `NaN` matches `NaN`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // using `fromIndex` + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + * + * // performing a binary search + * _.indexOf([1, 1, 2, 2], 2, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + if (typeof fromIndex == 'number') { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; + } else if (fromIndex) { + var index = binaryIndex(array, value), + other = array[index]; + + if (value === value ? (value === other) : (other !== other)) { + return index; + } + return -1; + } + return baseIndexOf(array, value, fromIndex || 0); + } + + /** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ + function initial(array) { + return dropRight(array, 1); + } + + /** + * Creates an array of unique values in all provided arrays using `SameValueZero` + * for equality comparisons. + * + * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * comparisons are like strict equality comparisons, e.g. `===`, except that + * `NaN` matches `NaN`. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of shared values. + * @example + * _.intersection([1, 2], [4, 2], [2, 1]); + * // => [2] + */ + function intersection() { + var args = [], + argsIndex = -1, + argsLength = arguments.length, + caches = [], + indexOf = getIndexOf(), + isCommon = indexOf == baseIndexOf, + result = []; + + while (++argsIndex < argsLength) { + var value = arguments[argsIndex]; + if (isArray(value) || isArguments(value)) { + args.push(value); + caches.push((isCommon && value.length >= 120) ? createCache(argsIndex && value) : null); + } + } + argsLength = args.length; + if (argsLength < 2) { + return result; + } + var array = args[0], + index = -1, + length = array ? array.length : 0, + seen = caches[0]; + + outer: + while (++index < length) { + value = array[index]; + if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) { + argsIndex = argsLength; + while (--argsIndex) { + var cache = caches[argsIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value, 0)) < 0) { + continue outer; + } + } + if (seen) { + seen.push(value); + } + result.push(value); + } + } + return result; + } + + /** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ + function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; + } + + /** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=array.length-1] The index to search from + * or `true` to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // using `fromIndex` + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + * + * // performing a binary search + * _.lastIndexOf([1, 1, 2, 2], 2, true); + * // => 3 + */ + function lastIndexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + var index = length; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1; + } else if (fromIndex) { + index = binaryIndex(array, value, true) - 1; + var other = array[index]; + if (value === value ? (value === other) : (other !== other)) { + return index; + } + return -1; + } + if (value !== value) { + return indexOfNaN(array, index, true); + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Removes all provided values from `array` using `SameValueZero` for equality + * comparisons. + * + * **Notes:** + * - Unlike `_.without`, this method mutates `array` + * - [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * comparisons are like strict equality comparisons, e.g. `===`, except + * that `NaN` matches `NaN` + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...*} [values] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ + function pull() { + var args = arguments, + array = args[0]; + + if (!(array && array.length)) { + return array; + } + var index = 0, + indexOf = getIndexOf(), + length = args.length; + + while (++index < length) { + var fromIndex = 0, + value = args[index]; + + while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { + splice.call(array, fromIndex, 1); + } + } + return array; + } + + /** + * Removes elements from `array` corresponding to the given indexes and returns + * an array of the removed elements. Indexes may be specified as an array of + * indexes or as individual arguments. + * + * **Note:** Unlike `_.at`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...(number|number[])} [indexes] The indexes of elements to remove, + * specified as individual indexes or arrays of indexes. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [5, 10, 15, 20]; + * var evens = _.pullAt(array, 1, 3); + * + * console.log(array); + * // => [5, 15] + * + * console.log(evens); + * // => [10, 20] + */ + var pullAt = restParam(function(array, indexes) { + array || (array = []); + indexes = baseFlatten(indexes); + + var result = baseAt(array, indexes); + basePullAt(array, indexes.sort(baseCompareAscending)); + return result; + }); + + /** + * Removes all elements from `array` that `predicate` returns truthy for + * and returns an array of the removed elements. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * **Note:** Unlike `_.filter`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4]; + * var evens = _.remove(array, function(n) { + * return n % 2 == 0; + * }); + * + * console.log(array); + * // => [1, 3] + * + * console.log(evens); + * // => [2, 4] + */ + function remove(array, predicate, thisArg) { + var result = []; + if (!(array && array.length)) { + return result; + } + var index = -1, + indexes = [], + length = array.length; + + predicate = getCallback(predicate, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result.push(value); + indexes.push(index); + } + } + basePullAt(array, indexes); + return result; + } + + /** + * Gets all but the first element of `array`. + * + * @static + * @memberOf _ + * @alias tail + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + */ + function rest(array) { + return drop(array, 1); + } + + /** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of `Array#slice` to support node + * lists in IE < 9 and to ensure dense arrays are returned. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function slice(array, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; + } + return baseSlice(array, start, end); + } + + /** + * Uses a binary search to determine the lowest index at which `value` should + * be inserted into `array` in order to maintain its sort order. If an iteratee + * function is provided it is invoked for `value` and each element of `array` + * to compute their sort ranking. The iteratee is bound to `thisArg` and + * invoked with one argument; (value). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + * + * _.sortedIndex([4, 4, 5, 5], 5); + * // => 2 + * + * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; + * + * // using an iteratee function + * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { + * return this.data[word]; + * }, dict); + * // => 1 + * + * // using the `_.property` callback shorthand + * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 1 + */ + var sortedIndex = createSortedIndex(); + + /** + * This method is like `_.sortedIndex` except that it returns the highest + * index at which `value` should be inserted into `array` in order to + * maintain its sort order. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedLastIndex([4, 4, 5, 5], 5); + * // => 4 + */ + var sortedLastIndex = createSortedIndex(true); + + /** + * Creates a slice of `array` with `n` elements taken from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.take([1, 2, 3]); + * // => [1] + * + * _.take([1, 2, 3], 2); + * // => [1, 2] + * + * _.take([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.take([1, 2, 3], 0); + * // => [] + */ + function take(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements taken from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRight([1, 2, 3]); + * // => [3] + * + * _.takeRight([1, 2, 3], 2); + * // => [2, 3] + * + * _.takeRight([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.takeRight([1, 2, 3], 0); + * // => [] + */ + function takeRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with elements taken from the end. Elements are + * taken until `predicate` returns falsey. The predicate is bound to `thisArg` + * and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [2, 3] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active'), 'user'); + * // => [] + */ + function takeRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true) + : []; + } + + /** + * Creates a slice of `array` with elements taken from the beginning. Elements + * are taken until `predicate` returns falsey. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [1, 2] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false}, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeWhile(users, 'active', false), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeWhile(users, 'active'), 'user'); + * // => [] + */ + function takeWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3)) + : []; + } + + /** + * Creates an array of unique values, in order, of the provided arrays using + * `SameValueZero` for equality comparisons. + * + * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * comparisons are like strict equality comparisons, e.g. `===`, except that + * `NaN` matches `NaN`. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([1, 2], [4, 2], [2, 1]); + * // => [1, 2, 4] + */ + var union = restParam(function(arrays) { + return baseUniq(baseFlatten(arrays, false, true)); + }); + + /** + * Creates a duplicate-free version of an array, using `SameValueZero` for + * equality comparisons, in which only the first occurence of each element + * is kept. Providing `true` for `isSorted` performs a faster search algorithm + * for sorted arrays. If an iteratee function is provided it is invoked for + * each element in the array to generate the criterion by which uniqueness + * is computed. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index, array). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * comparisons are like strict equality comparisons, e.g. `===`, except that + * `NaN` matches `NaN`. + * + * @static + * @memberOf _ + * @alias unique + * @category Array + * @param {Array} array The array to inspect. + * @param {boolean} [isSorted] Specify the array is sorted. + * @param {Function|Object|string} [iteratee] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new duplicate-value-free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + * + * // using `isSorted` + * _.uniq([1, 1, 2], true); + * // => [1, 2] + * + * // using an iteratee function + * _.uniq([1, 2.5, 1.5, 2], function(n) { + * return this.floor(n); + * }, Math); + * // => [1, 2.5] + * + * // using the `_.property` callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniq(array, isSorted, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (isSorted != null && typeof isSorted != 'boolean') { + thisArg = iteratee; + iteratee = isIterateeCall(array, isSorted, thisArg) ? null : isSorted; + isSorted = false; + } + var func = getCallback(); + if (!(func === baseCallback && iteratee == null)) { + iteratee = func(iteratee, thisArg, 3); + } + return (isSorted && getIndexOf() == baseIndexOf) + ? sortedUniq(array, iteratee) + : baseUniq(array, iteratee); + } + + /** + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-`_.zip` + * configuration. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + * + * _.unzip(zipped); + * // => [['fred', 'barney'], [30, 40], [true, false]] + */ + function unzip(array) { + var index = -1, + length = (array && array.length && arrayMax(arrayMap(array, getLength))) >>> 0, + result = Array(length); + + while (++index < length) { + result[index] = arrayMap(array, baseProperty(index)); + } + return result; + } + + /** + * Creates an array excluding all provided values using `SameValueZero` for + * equality comparisons. + * + * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * comparisons are like strict equality comparisons, e.g. `===`, except that + * `NaN` matches `NaN`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to filter. + * @param {...*} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.without([1, 2, 1, 3], 1, 2); + * // => [3] + */ + var without = restParam(function(array, values) { + return (isArray(array) || isArguments(array)) + ? baseDifference(array, values) + : []; + }); + + /** + * Creates an array that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) + * of the provided arrays. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of values. + * @example + * + * _.xor([1, 2], [4, 2]); + * // => [1, 4] + */ + function xor() { + var index = -1, + length = arguments.length; + + while (++index < length) { + var array = arguments[index]; + if (isArray(array) || isArguments(array)) { + var result = result + ? baseDifference(result, array).concat(baseDifference(array, result)) + : array; + } + } + return result ? baseUniq(result) : []; + } + + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second elements + * of the given arrays, and so on. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + var zip = restParam(unzip); + + /** + * The inverse of `_.pairs`; this method returns an object composed from arrays + * of property names and values. Provide either a single two dimensional array, + * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names + * and one of corresponding values. + * + * @static + * @memberOf _ + * @alias object + * @category Array + * @param {Array} props The property names. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject([['fred', 30], ['barney', 40]]); + * // => { 'fred': 30, 'barney': 40 } + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ + function zipObject(props, values) { + var index = -1, + length = props ? props.length : 0, + result = {}; + + if (length && !values && !isArray(props[0])) { + values = []; + } + while (++index < length) { + var key = props[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object that wraps `value` with explicit method + * chaining enabled. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _.chain(users) + * .sortBy('age') + * .map(function(chr) { + * return chr.user + ' is ' + chr.age; + * }) + * .first() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; + } + + /** + * This method invokes `interceptor` and returns `value`. The interceptor is + * bound to `thisArg` and invoked with one argument; (value). The purpose of + * this method is to "tap into" a method chain in order to perform operations + * on intermediate results within the chain. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ + function tap(value, interceptor, thisArg) { + interceptor.call(thisArg, value); + return value; + } + + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ + function thru(value, interceptor, thisArg) { + return interceptor.call(thisArg, value); + } + + /** + * Enables explicit method chaining on the wrapper object. + * + * @name chain + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // without explicit chaining + * _(users).first(); + * // => { 'user': 'barney', 'age': 36 } + * + * // with explicit chaining + * _(users).chain() + * .first() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ + function wrapperChain() { + return chain(this); + } + + /** + * Executes the chained sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapper = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapper = wrapper.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapper.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ + function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); + } + + /** + * Creates a clone of the chained sequence planting `value` as the wrapped value. + * + * @name plant + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapper = _(array).map(function(value) { + * return Math.pow(value, 2); + * }); + * + * var other = [3, 4]; + * var otherWrapper = wrapper.plant(other); + * + * otherWrapper.value(); + * // => [9, 16] + * + * wrapper.value(); + * // => [1, 4] + */ + function wrapperPlant(value) { + var result, + parent = this; + + while (parent instanceof baseLodash) { + var clone = wrapperClone(parent); + if (result) { + previous.__wrapped__ = clone; + } else { + result = clone; + } + var previous = clone; + parent = parent.__wrapped__; + } + previous.__wrapped__ = value; + return result; + } + + /** + * Reverses the wrapped array so the first element becomes the last, the + * second element becomes the second to last, and so on. + * + * **Note:** This method mutates the wrapped array. + * + * @name reverse + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new reversed `lodash` wrapper instance. + * @example + * + * var array = [1, 2, 3]; + * + * _(array).reverse().value() + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function wrapperReverse() { + var value = this.__wrapped__; + if (value instanceof LazyWrapper) { + if (this.__actions__.length) { + value = new LazyWrapper(this); + } + return new LodashWrapper(value.reverse(), this.__chain__); + } + return this.thru(function(value) { + return value.reverse(); + }); + } + + /** + * Produces the result of coercing the unwrapped value to a string. + * + * @name toString + * @memberOf _ + * @category Chain + * @returns {string} Returns the coerced string value. + * @example + * + * _([1, 2, 3]).toString(); + * // => '1,2,3' + */ + function wrapperToString() { + return (this.value() + ''); + } + + /** + * Executes the chained sequence to extract the unwrapped value. + * + * @name value + * @memberOf _ + * @alias run, toJSON, valueOf + * @category Chain + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements corresponding to the given keys, or indexes, + * of `collection`. Keys may be specified as individual arguments or as arrays + * of keys. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [props] The property names + * or indexes of elements to pick, specified individually or in arrays. + * @returns {Array} Returns the new array of picked elements. + * @example + * + * _.at(['a', 'b', 'c'], [0, 2]); + * // => ['a', 'c'] + * + * _.at(['barney', 'fred', 'pebbles'], 0, 2); + * // => ['barney', 'pebbles'] + */ + var at = restParam(function(collection, props) { + var length = collection ? getLength(collection) : 0; + if (isLength(length)) { + collection = toIterable(collection); + } + return baseAt(collection, baseFlatten(props)); + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the number of times the key was returned by `iteratee`. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return Math.floor(n); + * }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); + }); + + /** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * The predicate is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.every(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.every(users, 'active'); + * // => false + */ + function every(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = null; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = getCallback(predicate, thisArg, 3); + } + return func(collection, predicate); + } + + /** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.filter([4, 5, 6], function(n) { + * return n % 2 == 0; + * }); + * // => [4, 6] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.filter(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.filter(users, 'active'), 'user'); + * // => ['barney'] + */ + function filter(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getCallback(predicate, thisArg, 3); + return func(collection, predicate); + } + + /** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias detect + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.result(_.find(users, function(chr) { + * return chr.age < 40; + * }), 'user'); + * // => 'barney' + * + * // using the `_.matches` callback shorthand + * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); + * // => 'pebbles' + * + * // using the `_.matchesProperty` callback shorthand + * _.result(_.find(users, 'active', false), 'user'); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.result(_.find(users, 'active'), 'user'); + * // => 'barney' + */ + var find = createFind(baseEach); + + /** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 + */ + var findLast = createFind(baseEachRight, true); + + /** + * Performs a deep comparison between each element in `collection` and the + * source object, returning the first element that has equivalent property + * values. + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); + * // => 'barney' + * + * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); + * // => 'fred' + */ + function findWhere(collection, source) { + return find(collection, baseMatches(source)); + } + + /** + * Iterates over elements of `collection` invoking `iteratee` for each element. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). Iteratee functions may exit iteration early + * by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2]).forEach(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from left to right and returns the array + * + * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { + * console.log(n, key); + * }); + * // => logs each value-key pair and returns the object (iteration order is not guaranteed) + */ + var forEach = createForEach(arrayEach, baseEach); + + /** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2]).forEachRight(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from right to left and returns the array + */ + var forEachRight = createForEach(arrayEachRight, baseEachRight); + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return Math.floor(n); + * }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using the `_.property` callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + result[key] = [value]; + } + }); + + /** + * Checks if `value` is in `collection` using `SameValueZero` for equality + * comparisons. If `fromIndex` is negative, it is used as the offset from + * the end of `collection`. + * + * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * comparisons are like strict equality comparisons, e.g. `===`, except that + * `NaN` matches `NaN`. + * + * @static + * @memberOf _ + * @alias contains, include + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {*} target The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {boolean} Returns `true` if a matching element is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.includes('pebbles', 'eb'); + * // => true + */ + function includes(collection, target, fromIndex, guard) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + collection = values(collection); + length = collection.length; + } + if (!length) { + return false; + } + if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { + fromIndex = 0; + } else { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); + } + return (typeof collection == 'string' || !isArray(collection) && isString(collection)) + ? (fromIndex < length && collection.indexOf(target, fromIndex) > -1) + : (getIndexOf(collection, target, fromIndex) > -1); + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the last element responsible for generating the key. The + * iteratee function is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keyData = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keyData, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return String.fromCharCode(object.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return this.fromCharCode(object.code); + * }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Invokes the method at `path` on each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `methodName` is a function it is + * invoked for, and `this` bound to, each element in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|string} path The path of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + var invoke = restParam(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + isProp = isKey(path), + length = getLength(collection), + result = isLength(length) ? Array(length) : []; + + baseEach(collection, function(value) { + var func = isFunc ? path : (isProp && value != null && value[path]); + result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); + }); + return result; + }); + + /** + * Creates an array of values by running each element in `collection` through + * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * Many lodash methods are guarded to work as interatees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, `drop`, + * `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, `parseInt`, + * `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimLeft`, + * `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, `uniq`, and `words` + * + * @static + * @memberOf _ + * @alias collect + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new mapped array. + * @example + * + * function timesThree(n) { + * return n * 3; + * } + * + * _.map([1, 2], timesThree); + * // => [3, 6] + * + * _.map({ 'a': 1, 'b': 2 }, timesThree); + * // => [3, 6] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // using the `_.property` callback shorthand + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ + function map(collection, iteratee, thisArg) { + var func = isArray(collection) ? arrayMap : baseMap; + iteratee = getCallback(iteratee, thisArg, 3); + return func(collection, iteratee); + } + + /** + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, while the second of which + * contains elements `predicate` returns falsey for. The predicate is bound + * to `thisArg` and invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the array of grouped elements. + * @example + * + * _.partition([1, 2, 3], function(n) { + * return n % 2; + * }); + * // => [[1, 3], [2]] + * + * _.partition([1.2, 2.3, 3.4], function(n) { + * return this.floor(n) % 2; + * }, Math); + * // => [[1.2, 3.4], [2.3]] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * var mapper = function(array) { + * return _.pluck(array, 'user'); + * }; + * + * // using the `_.matches` callback shorthand + * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper); + * // => [['pebbles'], ['barney', 'fred']] + * + * // using the `_.matchesProperty` callback shorthand + * _.map(_.partition(users, 'active', false), mapper); + * // => [['barney', 'pebbles'], ['fred']] + * + * // using the `_.property` callback shorthand + * _.map(_.partition(users, 'active'), mapper); + * // => [['fred'], ['barney', 'pebbles']] + */ + var partition = createAggregator(function(result, value, key) { + result[key ? 0 : 1].push(value); + }, function() { return [[], []]; }); + + /** + * Gets the property value of `path` from all elements in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|string} path The path of the property to pluck. + * @returns {Array} Returns the property values. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * _.pluck(users, 'user'); + * // => ['barney', 'fred'] + * + * var userIndex = _.indexBy(users, 'user'); + * _.pluck(userIndex, 'age'); + * // => [36, 40] (iteration order is not guaranteed) + */ + function pluck(collection, path) { + return map(collection, property(path)); + } + + /** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` through `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not provided the first element of `collection` is used as the initial + * value. The `iteratee` is bound to `thisArg` and invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as interatees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `includes`, `merge`, `sortByAll`, and `sortByOrder` + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * _.reduce([1, 2], function(total, n) { + * return total + n; + * }); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { + * result[key] = n * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) + */ + var reduce = createReduce(arrayReduce, baseEach); + + /** + * This method is like `_.reduce` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * var array = [[0, 1], [2, 3], [4, 5]]; + * + * _.reduceRight(array, function(flattened, other) { + * return flattened.concat(other); + * }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + var reduceRight = createReduce(arrayReduceRight, baseEachRight); + + /** + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.reject([1, 2, 3, 4], function(n) { + * return n % 2 == 0; + * }); + * // => [1, 3] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.reject(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.reject(users, 'active'), 'user'); + * // => ['barney'] + */ + function reject(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getCallback(predicate, thisArg, 3); + return func(collection, function(value, index, collection) { + return !predicate(value, index, collection); + }); + } + + /** + * Gets a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {*} Returns the random sample(s). + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ + function sample(collection, n, guard) { + if (guard ? isIterateeCall(collection, n, guard) : n == null) { + collection = toIterable(collection); + var length = collection.length; + return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; + } + var result = shuffle(collection); + result.length = nativeMin(n < 0 ? 0 : (+n || 0), result.length); + return result; + } + + /** + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + * @example + * + * _.shuffle([1, 2, 3, 4]); + * // => [4, 1, 3, 2] + */ + function shuffle(collection) { + collection = toIterable(collection); + + var index = -1, + length = collection.length, + result = Array(length); + + while (++index < length) { + var rand = baseRandom(0, index); + if (index != rand) { + result[index] = result[rand]; + } + result[rand] = collection[index]; + } + return result; + } + + /** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the size of `collection`. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + var length = collection ? getLength(collection) : 0; + return isLength(length) ? length : keys(collection).length; + } + + /** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * The function returns as soon as it finds a passing value and does not iterate + * over the entire collection. The predicate is bound to `thisArg` and invoked + * with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.some(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.some(users, 'active'); + * // => true + */ + function some(collection, predicate, thisArg) { + var func = isArray(collection) ? arraySome : baseSome; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = null; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = getCallback(predicate, thisArg, 3); + } + return func(collection, predicate); + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through `iteratee`. This method performs + * a stable sort, that is, it preserves the original sort order of equal elements. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new sorted array. + * @example + * + * _.sortBy([1, 2, 3], function(n) { + * return Math.sin(n); + * }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(n) { + * return this.sin(n); + * }, Math); + * // => [3, 1, 2] + * + * var users = [ + * { 'user': 'fred' }, + * { 'user': 'pebbles' }, + * { 'user': 'barney' } + * ]; + * + * // using the `_.property` callback shorthand + * _.pluck(_.sortBy(users, 'user'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function sortBy(collection, iteratee, thisArg) { + if (collection == null) { + return []; + } + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = null; + } + var index = -1; + iteratee = getCallback(iteratee, thisArg, 3); + + var result = baseMap(collection, function(value, key, collection) { + return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value }; + }); + return baseSortBy(result, compareAscending); + } + + /** + * This method is like `_.sortBy` except that it can sort by multiple iteratees + * or property names. + * + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees + * The iteratees to sort by, specified as individual values or arrays of values. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.map(_.sortByAll(users, ['user', 'age']), _.values); + * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * + * _.map(_.sortByAll(users, 'user', function(chr) { + * return Math.floor(chr.age / 10); + * }), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + var sortByAll = restParam(function(collection, iteratees) { + if (collection == null) { + return []; + } + var guard = iteratees[2]; + if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) { + iteratees.length = 1; + } + return baseSortByOrder(collection, baseFlatten(iteratees), []); + }); + + /** + * This method is like `_.sortByAll` except that it allows specifying the + * sort orders of the iteratees to sort by. A truthy value in `orders` will + * sort the corresponding property name in ascending order while a falsey + * value will sort it in descending order. + * + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {boolean[]} orders The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 36 } + * ]; + * + * // sort by `user` in ascending order and by `age` in descending order + * _.map(_.sortByOrder(users, ['user', 'age'], [true, false]), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + function sortByOrder(collection, iteratees, orders, guard) { + if (collection == null) { + return []; + } + if (guard && isIterateeCall(iteratees, orders, guard)) { + orders = null; + } + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; + } + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; + } + return baseSortByOrder(collection, iteratees, orders); + } + + /** + * Performs a deep comparison between each element in `collection` and the + * source object, returning an array of all elements that have equivalent + * property values. + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] }, + * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); + * // => ['barney'] + * + * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); + * // => ['fred'] + */ + function where(collection, source) { + return filter(collection, baseMatches(source)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @category Date + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => logs the number of milliseconds it took for the deferred function to be invoked + */ + var now = nativeNow || function() { + return new Date().getTime(); + }; + + /*------------------------------------------------------------------------*/ + + /** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it is called `n` or more times. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'done saving!' after the two async saves have completed + */ + function after(n, func) { + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } + } + n = nativeIsFinite(n = +n) ? n : 0; + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that accepts up to `n` arguments ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] + */ + function ary(func, n, guard) { + if (guard && isIterateeCall(func, n, guard)) { + n = null; + } + n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); + return createWrapper(func, ARY_FLAG, null, null, null, null, n); + } + + /** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it is called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery('#add').on('click', _.before(5, addContactToList)); + * // => allows adding up to 4 contacts to the list + */ + function before(n, func) { + var result; + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } + } + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = null; + } + return result; + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and prepends any additional `_.bind` arguments to those provided to the + * bound function. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind` this method does not set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var greet = function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * }; + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // using placeholders + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ + var bind = restParam(function(func, thisArg, partials) { + var bitmask = BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bind.placeholder); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(func, bitmask, thisArg, partials, holders); + }); + + /** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all enumerable function + * properties, own and inherited, of `object` are bound. + * + * **Note:** This method does not set the "length" property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...(string|string[])} [methodNames] The object method names to bind, + * specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { + * console.log('clicked ' + this.label); + * } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs' when the element is clicked + */ + var bindAll = restParam(function(object, methodNames) { + methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object); + + var index = -1, + length = methodNames.length; + + while (++index < length) { + var key = methodNames[index]; + object[key] = createWrapper(object[key], BIND_FLAG, object); + } + return object; + }); + + /** + * Creates a function that invokes the method at `object[key]` and prepends + * any additional `_.bindKey` arguments to those provided to the bound function. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. + * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // using placeholders + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ + var bindKey = restParam(function(object, key, partials) { + var bitmask = BIND_FLAG | BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bindKey.placeholder); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(key, bitmask, object, partials, holders); + }); + + /** + * Creates a function that accepts one or more arguments of `func` that when + * called either invokes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` may be specified + * if `func.length` is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(1)(_, 3)(2); + * // => [1, 2, 3] + */ + var curry = createCurry(CURRY_FLAG); + + /** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(3)(1, _)(2); + * // => [1, 2, 3] + */ + var curryRight = createCurry(CURRY_RIGHT_FLAG); + + /** + * Creates a function that delays invoking `func` until after `wait` milliseconds + * have elapsed since the last time it was invoked. The created function comes + * with a `cancel` method to cancel delayed invocations. Provide an options + * object to indicate that `func` should be invoked on the leading and/or + * trailing edge of the `wait` timeout. Subsequent calls to the debounced + * function return the result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify invoking on the leading + * edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be + * delayed before it is invoked. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // invoke `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // ensure `batchLog` is invoked once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * jQuery(source).on('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * })); + * + * // cancel a debounced call + * var todoChanges = _.debounce(batchLog, 1000); + * Object.observe(models.todo, todoChanges); + * + * Object.observe(models, function(changes) { + * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { + * todoChanges.cancel(); + * } + * }, ['delete']); + * + * // ...at some point `models.todo` is changed + * models.todo.completed = true; + * + * // ...before 1 second has passed `models.todo` is deleted + * // which cancels the debounced `todoChanges` call + * delete models.todo; + */ + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = wait < 0 ? 0 : (+wait || 0); + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = options.leading; + maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); + trailing = 'trailing' in options ? options.trailing : trailing; + } + + function cancel() { + if (timeoutId) { + clearTimeout(timeoutId); + } + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + } + + function delayed() { + var remaining = wait - (now() - stamp); + if (remaining <= 0 || remaining > wait) { + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + var isCalled = trailingCall; + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + } else { + timeoutId = setTimeout(delayed, remaining); + } + } + + function maxDelayed() { + if (timeoutId) { + clearTimeout(timeoutId); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (trailing || (maxWait !== wait)) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + } + + function debounced() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0 || remaining > maxWait; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + return result; + } + debounced.cancel = cancel; + return debounced; + } + + /** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // logs 'deferred' after one or more milliseconds + */ + var defer = restParam(function(func, args) { + return baseDelay(func, 1, args); + }); + + /** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => logs 'later' after one second + */ + var delay = restParam(function(func, wait, args) { + return baseDelay(func, wait, args); + }); + + /** + * Creates a function that returns the result of invoking the provided + * functions with the `this` binding of the created function, where each + * successive invocation is supplied the return value of the previous. + * + * @static + * @memberOf _ + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flow(_.add, square); + * addSquare(1, 2); + * // => 9 + */ + var flow = createFlow(); + + /** + * This method is like `_.flow` except that it creates a function that + * invokes the provided functions from right to left. + * + * @static + * @memberOf _ + * @alias backflow, compose + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flowRight(square, _.add); + * addSquare(1, 2); + * // => 9 + */ + var flowRight = createFlow(true); + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is coerced to a string and used as the + * cache key. The `func` is invoked with the `this` binding of the memoized + * function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the [`Map`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-properties-of-the-map-prototype-object) + * method interface of `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var upperCase = _.memoize(function(string) { + * return string.toUpperCase(); + * }); + * + * upperCase('fred'); + * // => 'FRED' + * + * // modifying the result cache + * upperCase.cache.set('fred', 'BARNEY'); + * upperCase('fred'); + * // => 'BARNEY' + * + * // replacing `_.memoize.Cache` + * var object = { 'user': 'fred' }; + * var other = { 'user': 'barney' }; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'fred' } + * + * _.memoize.Cache = WeakMap; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'barney' } + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + cache = memoized.cache, + key = resolver ? resolver.apply(this, args) : args[0]; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + cache.set(key, result); + return result; + }; + memoized.cache = new memoize.Cache; + return memoized; + } + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + return !predicate.apply(this, arguments); + }; + } + + /** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first call. The `func` is invoked + * with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` invokes `createApplication` once + */ + function once(func) { + return before(2, func); + } + + /** + * Creates a function that invokes `func` with `partial` arguments prepended + * to those provided to the new function. This method is like `_.bind` except + * it does **not** alter the `this` binding. + * + * The `_.partial.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method does not set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var sayHelloTo = _.partial(greet, 'hello'); + * sayHelloTo('fred'); + * // => 'hello fred' + * + * // using placeholders + * var greetFred = _.partial(greet, _, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + */ + var partial = createPartial(PARTIAL_FLAG); + + /** + * This method is like `_.partial` except that partially applied arguments + * are appended to those provided to the new function. + * + * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method does not set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var greetFred = _.partialRight(greet, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + * + * // using placeholders + * var sayHelloTo = _.partialRight(greet, 'hello', _); + * sayHelloTo('fred'); + * // => 'hello fred' + */ + var partialRight = createPartial(PARTIAL_RIGHT_FLAG); + + /** + * Creates a function that invokes `func` with arguments arranged according + * to the specified indexes where the argument value at the first index is + * provided as the first argument, the argument value at the second index is + * provided as the second argument, and so on. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to rearrange arguments for. + * @param {...(number|number[])} indexes The arranged argument indexes, + * specified as individual indexes or arrays of indexes. + * @returns {Function} Returns the new function. + * @example + * + * var rearged = _.rearg(function(a, b, c) { + * return [a, b, c]; + * }, 2, 0, 1); + * + * rearged('b', 'c', 'a') + * // => ['a', 'b', 'c'] + * + * var map = _.rearg(_.map, [1, 0]); + * map(function(n) { + * return n * 3; + * }, [1, 2, 3]); + * // => [3, 6, 9] + */ + var rearg = restParam(function(func, indexes) { + return createWrapper(func, REARG_FLAG, null, null, null, baseFlatten(indexes)); + }); + + /** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as an array. + * + * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.restParam(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ + function restParam(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + rest = Array(length); + + while (++index < length) { + rest[index] = args[start + index]; + } + switch (start) { + case 0: return func.call(this, rest); + case 1: return func.call(this, args[0], rest); + case 2: return func.call(this, args[0], args[1], rest); + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = rest; + return func.apply(this, otherArgs); + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of the created + * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). + * + * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to spread arguments over. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.spread(function(who, what) { + * return who + ' says ' + what; + * }); + * + * say(['fred', 'hello']); + * // => 'fred says hello' + * + * // with a Promise + * var numbers = Promise.all([ + * Promise.resolve(40), + * Promise.resolve(36) + * ]); + * + * numbers.then(_.spread(function(x, y) { + * return x + y; + * })); + * // => a Promise of 76 + */ + function spread(func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function(array) { + return func.apply(this, array); + }; + } + + /** + * Creates a function that only invokes `func` at most once per every `wait` + * milliseconds. The created function comes with a `cancel` method to cancel + * delayed invocations. Provide an options object to indicate that `func` + * should be invoked on the leading and/or trailing edge of the `wait` timeout. + * Subsequent calls to the throttled function return the result of the last + * `func` call. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify invoking on the leading + * edge of the timeout. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // avoid excessively updating the position while scrolling + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + * + * // cancel a trailing throttled call + * jQuery(window).on('popstate', throttled.cancel); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + debounceOptions.leading = leading; + debounceOptions.maxWait = +wait; + debounceOptions.trailing = trailing; + return debounce(func, wait, debounceOptions); + } + + /** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Any additional arguments provided to the function are + * appended to those provided to the wrapper function. The wrapper is invoked + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

          ' + func(text) + '

          '; + * }); + * + * p('fred, barney, & pebbles'); + * // => '

          fred, barney, & pebbles

          ' + */ + function wrap(value, wrapper) { + wrapper = wrapper == null ? identity : wrapper; + return createWrapper(wrapper, PARTIAL_FLAG, null, [value], []); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned, + * otherwise they are assigned by reference. If `customizer` is provided it is + * invoked to produce the cloned values. If `customizer` returns `undefined` + * cloning is handled by the method instead. The `customizer` is bound to + * `thisArg` and invoked with two argument; (value [, index|key, object]). + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). + * The enumerable properties of `arguments` objects and objects created by + * constructors other than `Object` are cloned to plain `Object` objects. An + * empty object is returned for uncloneable values such as functions, DOM nodes, + * Maps, Sets, and WeakMaps. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {*} Returns the cloned value. + * @example + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * var shallow = _.clone(users); + * shallow[0] === users[0]; + * // => true + * + * var deep = _.clone(users, true); + * deep[0] === users[0]; + * // => false + * + * // using a customizer callback + * var el = _.clone(document.body, function(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * }); + * + * el === document.body + * // => false + * el.nodeName + * // => BODY + * el.childNodes.length; + * // => 0 + */ + function clone(value, isDeep, customizer, thisArg) { + if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) { + isDeep = false; + } + else if (typeof isDeep == 'function') { + thisArg = customizer; + customizer = isDeep; + isDeep = false; + } + customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 1); + return baseClone(value, isDeep, customizer); + } + + /** + * Creates a deep clone of `value`. If `customizer` is provided it is invoked + * to produce the cloned values. If `customizer` returns `undefined` cloning + * is handled by the method instead. The `customizer` is bound to `thisArg` + * and invoked with two argument; (value [, index|key, object]). + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). + * The enumerable properties of `arguments` objects and objects created by + * constructors other than `Object` are cloned to plain `Object` objects. An + * empty object is returned for uncloneable values such as functions, DOM nodes, + * Maps, Sets, and WeakMaps. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {*} Returns the deep cloned value. + * @example + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * var deep = _.cloneDeep(users); + * deep[0] === users[0]; + * // => false + * + * // using a customizer callback + * var el = _.cloneDeep(document.body, function(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * }); + * + * el === document.body + * // => false + * el.nodeName + * // => BODY + * el.childNodes.length; + * // => 20 + */ + function cloneDeep(value, customizer, thisArg) { + customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 1); + return baseClone(value, true, customizer); + } + + /** + * Checks if `value` is classified as an `arguments` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + var length = isObjectLike(value) ? value.length : undefined; + return isLength(length) && objToString.call(value) == argsTag; + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(function() { return arguments; }()); + * // => false + */ + var isArray = nativeIsArray || function(value) { + return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; + }; + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag); + } + + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ + function isDate(value) { + return isObjectLike(value) && objToString.call(value) == dateTag; + } + + /** + * Checks if `value` is a DOM element. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false + */ + function isElement(value) { + return !!value && value.nodeType === 1 && isObjectLike(value) && + (objToString.call(value).indexOf('Element') > -1); + } + // Fallback for environments without DOM support. + if (!support.dom) { + isElement = function(value) { + return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); + }; + } + + /** + * Checks if `value` is empty. A value is considered empty unless it is an + * `arguments` object, array, string, or jQuery-like collection with a length + * greater than `0` or an object with own enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ + function isEmpty(value) { + if (value == null) { + return true; + } + var length = getLength(value); + if (isLength(length) && (isArray(value) || isString(value) || isArguments(value) || + (isObjectLike(value) && isFunction(value.splice)))) { + return !length; + } + return !keys(value).length; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. If `customizer` is provided it is invoked to compare values. + * If `customizer` returns `undefined` comparisons are handled by the method + * instead. The `customizer` is bound to `thisArg` and invoked with three + * arguments: (value, other [, index|key]). + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. Functions and DOM nodes + * are **not** supported. Provide a customizer function to extend support + * for comparing other values. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize value comparisons. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * object == other; + * // => false + * + * _.isEqual(object, other); + * // => true + * + * // using a customizer callback + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqual(array, other, function(value, other) { + * if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) { + * return true; + * } + * }); + * // => true + */ + function isEqual(value, other, customizer, thisArg) { + customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 3); + if (!customizer && isStrictComparable(value) && isStrictComparable(other)) { + return value === other; + } + var result = customizer ? customizer(value, other) : undefined; + return result === undefined ? baseIsEqual(value, other, customizer) : !!result; + } + + /** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ + function isError(value) { + return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag; + } + + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on [`Number.isFinite`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(10); + * // => true + * + * _.isFinite('10'); + * // => false + * + * _.isFinite(true); + * // => false + * + * _.isFinite(Object(10)); + * // => false + * + * _.isFinite(Infinity); + * // => false + */ + var isFinite = nativeNumIsFinite || function(value) { + return typeof value == 'number' && nativeIsFinite(value); + }; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + var isFunction = !(baseIsFunction(/x/) || (Uint8Array && !baseIsFunction(Uint8Array))) ? baseIsFunction : function(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in older versions of Chrome and Safari which return 'function' for regexes + // and Safari 8 equivalents which return 'object' for typed array constructors. + return objToString.call(value) == funcTag; + }; + + /** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ + function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return type == 'function' || (!!value && type == 'object'); + } + + /** + * Performs a deep comparison between `object` and `source` to determine if + * `object` contains equivalent property values. If `customizer` is provided + * it is invoked to compare values. If `customizer` returns `undefined` + * comparisons are handled by the method instead. The `customizer` is bound + * to `thisArg` and invoked with three arguments: (value, other, index|key). + * + * **Note:** This method supports comparing properties of arrays, booleans, + * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions + * and DOM nodes are **not** supported. Provide a customizer function to extend + * support for comparing other values. + * + * @static + * @memberOf _ + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize value comparisons. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.isMatch(object, { 'age': 40 }); + * // => true + * + * _.isMatch(object, { 'age': 36 }); + * // => false + * + * // using a customizer callback + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatch(object, source, function(value, other) { + * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; + * }); + * // => true + */ + function isMatch(object, source, customizer, thisArg) { + var props = keys(source), + length = props.length; + + if (!length) { + return true; + } + if (object == null) { + return false; + } + customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 3); + object = toObject(object); + if (!customizer && length == 1) { + var key = props[0], + value = source[key]; + + if (isStrictComparable(value)) { + return value === object[key] && (value !== undefined || (key in object)); + } + } + var values = Array(length), + strictCompareFlags = Array(length); + + while (length--) { + value = values[length] = source[props[length]]; + strictCompareFlags[length] = isStrictComparable(value); + } + return baseIsMatch(object, props, values, strictCompareFlags, customizer); + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) + * which returns `true` for `undefined` and other non-numeric values. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some host objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is a native function. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ + function isNative(value) { + if (value == null) { + return false; + } + if (objToString.call(value) == funcTag) { + return reIsNative.test(fnToString.call(value)); + } + return isObjectLike(value) && reIsHostCtor.test(value); + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified + * as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isNumber(8.4); + * // => true + * + * _.isNumber(NaN); + * // => true + * + * _.isNumber('8.4'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag); + } + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * **Note:** This method assumes objects created by the `Object` constructor + * have no inherited enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { + if (!(value && objToString.call(value) == objectTag)) { + return false; + } + var valueOf = value.valueOf, + objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); + + return objProto + ? (value == objProto || getPrototypeOf(value) == objProto) + : shimIsPlainObject(value); + }; + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + function isRegExp(value) { + return (isObjectLike(value) && objToString.call(value) == regexpTag) || false; + } + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); + } + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + function isTypedArray(value) { + return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * Converts `value` to an array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * (function() { + * return _.toArray(arguments).slice(1); + * }(1, 2, 3)); + * // => [2, 3] + */ + function toArray(value) { + var length = value ? getLength(value) : 0; + if (!isLength(length)) { + return values(value); + } + if (!length) { + return []; + } + return arrayCopy(value); + } + + /** + * Converts `value` to a plain object flattening inherited enumerable + * properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return baseCopy(value, keysIn(value)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources overwrite property assignments of previous sources. + * If `customizer` is provided it is invoked to produce the assigned values. + * The `customizer` is bound to `thisArg` and invoked with five arguments: + * (objectValue, sourceValue, key, object, source). + * + * **Note:** This method mutates `object` and is based on + * [`Object.assign`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign). + * + * + * @static + * @memberOf _ + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. + * @example + * + * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); + * // => { 'user': 'fred', 'age': 40 } + * + * // using a customizer callback + * var defaults = _.partialRight(_.assign, function(value, other) { + * return _.isUndefined(value) ? other : value; + * }); + * + * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var assign = createAssigner(function(object, source, customizer) { + return customizer + ? assignWith(object, source, customizer) + : baseAssign(object, source); + }); + + /** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties, guard) { + var result = baseCreate(prototype); + if (guard && isIterateeCall(prototype, properties, guard)) { + properties = null; + } + return properties ? baseAssign(result, properties) : result; + } + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var defaults = restParam(function(args) { + var object = args[0]; + if (object == null) { + return object; + } + args.push(assignDefaults); + return assign.apply(undefined, args); + }); + + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(chr) { + * return chr.age < 40; + * }); + * // => 'barney' (iteration order is not guaranteed) + * + * // using the `_.matches` callback shorthand + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // using the `_.matchesProperty` callback shorthand + * _.findKey(users, 'active', false); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.findKey(users, 'active'); + * // => 'barney' + */ + var findKey = createFindKey(baseForOwn); + + /** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(chr) { + * return chr.age < 40; + * }); + * // => returns `pebbles` assuming `_.findKey` returns `barney` + * + * // using the `_.matches` callback shorthand + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastKey(users, 'active', false); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ + var findLastKey = createFindKey(baseForOwnRight); + + /** + * Iterates over own and inherited enumerable properties of an object invoking + * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed) + */ + var forIn = createForIn(baseFor); + + /** + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c' + */ + var forInRight = createForIn(baseForRight); + + /** + * Iterates over own enumerable properties of an object invoking `iteratee` + * for each property. The `iteratee` is bound to `thisArg` and invoked with + * three arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' and 'b' (iteration order is not guaranteed) + */ + var forOwn = createForOwn(baseForOwn); + + /** + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b' + */ + var forOwnRight = createForOwn(baseForOwnRight); + + /** + * Creates an array of function property names from all enumerable properties, + * own and inherited, of `object`. + * + * @static + * @memberOf _ + * @alias methods + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. + * @example + * + * _.functions(_); + * // => ['after', 'ary', 'assign', ...] + */ + function functions(object) { + return baseFunctions(object, keysIn(object)); + } + + /** + * Gets the property value of `path` on `object`. If the resolved value is + * `undefined` the `defaultValue` is used in its place. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, toPath(path), path + ''); + return result === undefined ? defaultValue : result; + } + + /** + * Checks if `path` is a direct property. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` is a direct property, else `false`. + * @example + * + * var object = { 'a': { 'b': { 'c': 3 } } }; + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b.c'); + * // => true + * + * _.has(object, ['a', 'b', 'c']); + * // => true + */ + function has(object, path) { + if (object == null) { + return false; + } + var result = hasOwnProperty.call(object, path); + if (!result && !isKey(path)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + path = last(path); + result = object != null && hasOwnProperty.call(object, path); + } + return result; + } + + /** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite property + * assignments of previous values unless `multiValue` is `true`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to invert. + * @param {boolean} [multiValue] Allow multiple values per key. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + * + * // with `multiValue` + * _.invert(object, true); + * // => { '1': ['a', 'c'], '2': ['b'] } + */ + function invert(object, multiValue, guard) { + if (guard && isIterateeCall(object, multiValue, guard)) { + multiValue = null; + } + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index], + value = object[key]; + + if (multiValue) { + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + } + else { + result[value] = key; + } + } + return result; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + var keys = !nativeKeys ? shimKeys : function(object) { + if (object) { + var Ctor = object.constructor, + length = object.length; + } + if ((typeof Ctor == 'function' && Ctor.prototype === object) || + (typeof object != 'function' && isLength(length))) { + return shimKeys(object); + } + return isObject(object) ? nativeKeys(object) : []; + }; + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + if (object == null) { + return []; + } + if (!isObject(object)) { + object = Object(object); + } + var length = object.length; + length = (length && isLength(length) && + (isArray(object) || (support.nonEnumArgs && isArguments(object))) && length) || 0; + + var Ctor = object.constructor, + index = -1, + isProto = typeof Ctor == 'function' && Ctor.prototype === object, + result = Array(length), + skipIndexes = length > 0; + + while (++index < length) { + result[index] = (index + ''); + } + for (var key in object) { + if (!(skipIndexes && isIndex(key, length)) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through `iteratee`. The + * iteratee function is bound to `thisArg` and invoked with three arguments: + * (value, key, object). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the new mapped object. + * @example + * + * _.mapValues({ 'a': 1, 'b': 2 }, function(n) { + * return n * 3; + * }); + * // => { 'a': 3, 'b': 6 } + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * // using the `_.property` callback shorthand + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ + function mapValues(object, iteratee, thisArg) { + var result = {}; + iteratee = getCallback(iteratee, thisArg, 3); + + baseForOwn(object, function(value, key, object) { + result[key] = iteratee(value, key, object); + }); + return result; + } + + /** + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * overwrite property assignments of previous sources. If `customizer` is + * provided it is invoked to produce the merged values of the destination and + * source properties. If `customizer` returns `undefined` merging is handled + * by the method instead. The `customizer` is bound to `thisArg` and invoked + * with five arguments: (objectValue, sourceValue, key, object, source). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. + * @example + * + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] + * }; + * + * var ages = { + * 'data': [{ 'age': 36 }, { 'age': 40 }] + * }; + * + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } + * + * // using a customizer callback + * var object = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var other = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(object, other, function(a, b) { + * if (_.isArray(a)) { + * return a.concat(b); + * } + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } + */ + var merge = createAssigner(baseMerge); + + /** + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable properties of `object` that are not omitted. + * Property names may be specified as individual arguments or as arrays of + * property names. If `predicate` is provided it is invoked for each property + * of `object` omitting the properties `predicate` returns truthy for. The + * predicate is bound to `thisArg` and invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {Function|...(string|string[])} [predicate] The function invoked per + * iteration or property names to omit, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.omit(object, 'age'); + * // => { 'user': 'fred' } + * + * _.omit(object, _.isNumber); + * // => { 'user': 'fred' } + */ + var omit = restParam(function(object, props) { + if (object == null) { + return {}; + } + if (typeof props[0] != 'function') { + var props = arrayMap(baseFlatten(props), String); + return pickByArray(object, baseDifference(keysIn(object), props)); + } + var predicate = bindCallback(props[0], props[1], 3); + return pickByCallback(object, function(value, key, object) { + return !predicate(value, key, object); + }); + }); + + /** + * Creates a two dimensional array of the key-value pairs for `object`, + * e.g. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the new array of key-value pairs. + * @example + * + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) + */ + function pairs(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; + } + + /** + * Creates an object composed of the picked `object` properties. Property + * names may be specified as individual arguments or as arrays of property + * names. If `predicate` is provided it is invoked for each property of `object` + * picking the properties `predicate` returns truthy for. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {Function|...(string|string[])} [predicate] The function invoked per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.pick(object, 'user'); + * // => { 'user': 'fred' } + * + * _.pick(object, _.isString); + * // => { 'user': 'fred' } + */ + var pick = restParam(function(object, props) { + if (object == null) { + return {}; + } + return typeof props[0] == 'function' + ? pickByCallback(object, bindCallback(props[0], props[1], 3)) + : pickByArray(object, baseFlatten(props)); + }); + + /** + * This method is like `_.get` except that if the resolved value is a function + * it is invoked with the `this` binding of its parent object and its result + * is returned. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a.b.c', 'default'); + * // => 'default' + * + * _.result(object, 'a.b.c', _.constant('default')); + * // => 'default' + */ + function result(object, path, defaultValue) { + var result = object == null ? undefined : object[path]; + if (result === undefined) { + if (object != null && !isKey(path, object)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + result = object == null ? undefined : object[last(path)]; + } + result = result === undefined ? defaultValue : result; + } + return isFunction(result) ? result.call(object) : result; + } + + /** + * Sets the property value of `path` on `object`. If a portion of `path` + * does not exist it is created. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to augment. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 + * + * _.set(object, 'x[0].y.z', 5); + * console.log(object.x[0].y.z); + * // => 5 + */ + function set(object, path, value) { + if (object == null) { + return object; + } + var pathKey = (path + ''); + path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path); + + var index = -1, + length = path.length, + endIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = path[index]; + if (isObject(nested)) { + if (index == endIndex) { + nested[key] = value; + } else if (nested[key] == null) { + nested[key] = isIndex(path[index + 1]) ? [] : {}; + } + } + nested = nested[key]; + } + return object; + } + + /** + * An alternative to `_.reduce`; this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own enumerable + * properties through `iteratee`, with each invocation potentially mutating + * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked + * with four arguments: (accumulator, value, key, object). Iteratee functions + * may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Array|Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * _.transform([2, 3, 4], function(result, n) { + * result.push(n *= n); + * return n % 2 == 0; + * }); + * // => [4, 9] + * + * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) { + * result[key] = n * 3; + * }); + * // => { 'a': 3, 'b': 6 } + */ + function transform(object, iteratee, accumulator, thisArg) { + var isArr = isArray(object) || isTypedArray(object); + iteratee = getCallback(iteratee, thisArg, 4); + + if (accumulator == null) { + if (isArr || isObject(object)) { + var Ctor = object.constructor; + if (isArr) { + accumulator = isArray(object) ? new Ctor : []; + } else { + accumulator = baseCreate(isFunction(Ctor) && Ctor.prototype); + } + } else { + accumulator = {}; + } + } + (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { + return iteratee(accumulator, value, index, object); + }); + return accumulator; + } + + /** + * Creates an array of the own enumerable property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return baseValues(object, keys(object)); + } + + /** + * Creates an array of the own and inherited enumerable property values + * of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.valuesIn(new Foo); + * // => [1, 2, 3] (iteration order is not guaranteed) + */ + function valuesIn(object) { + return baseValues(object, keysIn(object)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Checks if `n` is between `start` and up to but not including, `end`. If + * `end` is not specified it is set to `start` with `start` then set to `0`. + * + * @static + * @memberOf _ + * @category Number + * @param {number} n The number to check. + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `n` is in the range, else `false`. + * @example + * + * _.inRange(3, 2, 4); + * // => true + * + * _.inRange(4, 8); + * // => true + * + * _.inRange(4, 2); + * // => false + * + * _.inRange(2, 2); + * // => false + * + * _.inRange(1.2, 2); + * // => true + * + * _.inRange(5.2, 4); + * // => false + */ + function inRange(value, start, end) { + start = +start || 0; + if (typeof end === 'undefined') { + end = start; + start = 0; + } else { + end = +end || 0; + } + return value >= nativeMin(start, end) && value < nativeMax(start, end); + } + + /** + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is provided a number between `0` and the given number is returned. + * If `floating` is `true`, or either `min` or `max` are floats, a floating-point + * number is returned instead of an integer. + * + * @static + * @memberOf _ + * @category Number + * @param {number} [min=0] The minimum possible value. + * @param {number} [max=1] The maximum possible value. + * @param {boolean} [floating] Specify returning a floating-point number. + * @returns {number} Returns the random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(min, max, floating) { + if (floating && isIterateeCall(min, max, floating)) { + max = floating = null; + } + var noMin = min == null, + noMax = max == null; + + if (floating == null) { + if (noMax && typeof min == 'boolean') { + floating = min; + min = 1; + } + else if (typeof max == 'boolean') { + floating = max; + noMax = true; + } + } + if (noMin && noMax) { + max = 1; + noMax = false; + } + min = +min || 0; + if (noMax) { + max = min; + min = 0; + } else { + max = +max || 0; + } + if (floating || min % 1 || max % 1) { + var rand = nativeRandom(); + return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max); + } + return baseRandom(min, max); + } + + /*------------------------------------------------------------------------*/ + + /** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar'); + * // => 'fooBar' + * + * _.camelCase('__foo_bar__'); + * // => 'fooBar' + */ + var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word); + }); + + /** + * Capitalizes the first character of `string`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('fred'); + * // => 'Fred' + */ + function capitalize(string) { + string = baseToString(string); + return string && (string.charAt(0).toUpperCase() + string.slice(1)); + } + + /** + * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ + function deburr(string) { + string = baseToString(string); + return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, ''); + } + + /** + * Checks if `string` ends with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search from. + * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`. + * @example + * + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true + */ + function endsWith(string, target, position) { + string = baseToString(string); + target = (target + ''); + + var length = string.length; + position = position === undefined + ? length + : nativeMin(position < 0 ? 0 : (+position || 0), length); + + position -= target.length; + return position >= 0 && string.indexOf(target, position) == position; + } + + /** + * Converts the characters "&", "<", ">", '"', "'", and "\`", in `string` to + * their corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional characters + * use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't require escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. + * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * Backticks are escaped because in Internet Explorer < 9, they can break out + * of attribute values or HTML comments. See [#59](https://html5sec.org/#59), + * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and + * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) + * for more details. + * + * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) + * to reduce XSS vectors. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function escape(string) { + // Reset `lastIndex` because in IE < 9 `String#replace` does not. + string = baseToString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; + } + + /** + * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?", + * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https:\/\/lodash\.com\/\)' + */ + function escapeRegExp(string) { + string = baseToString(string); + return (string && reHasRegExpChars.test(string)) + ? string.replace(reRegExpChars, '\\$&') + : string; + } + + /** + * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__foo_bar__'); + * // => 'foo-bar' + */ + var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); + }); + + /** + * Pads `string` on the left and right sides if it is shorter than `length`. + * Padding characters are truncated if they can't be evenly divided by `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.pad('abc', 8); + * // => ' abc ' + * + * _.pad('abc', 8, '_-'); + * // => '_-abc_-_' + * + * _.pad('abc', 3); + * // => 'abc' + */ + function pad(string, length, chars) { + string = baseToString(string); + length = +length; + + var strLength = string.length; + if (strLength >= length || !nativeIsFinite(length)) { + return string; + } + var mid = (length - strLength) / 2, + leftLength = floor(mid), + rightLength = ceil(mid); + + chars = createPadding('', rightLength, chars); + return chars.slice(0, leftLength) + string + chars; + } + + /** + * Pads `string` on the left side if it is shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padLeft('abc', 6); + * // => ' abc' + * + * _.padLeft('abc', 6, '_-'); + * // => '_-_abc' + * + * _.padLeft('abc', 3); + * // => 'abc' + */ + var padLeft = createPadDir(); + + /** + * Pads `string` on the right side if it is shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padRight('abc', 6); + * // => 'abc ' + * + * _.padRight('abc', 6, '_-'); + * // => 'abc_-_' + * + * _.padRight('abc', 3); + * // => 'abc' + */ + var padRight = createPadDir(true); + + /** + * Converts `string` to an integer of the specified radix. If `radix` is + * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal, + * in which case a `radix` of `16` is used. + * + * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E) + * of `parseInt`. + * + * @static + * @memberOf _ + * @category String + * @param {string} string The string to convert. + * @param {number} [radix] The radix to interpret `value` by. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {number} Returns the converted integer. + * @example + * + * _.parseInt('08'); + * // => 8 + * + * _.map(['6', '08', '10'], _.parseInt); + * // => [6, 8, 10] + */ + function parseInt(string, radix, guard) { + if (guard && isIterateeCall(string, radix, guard)) { + radix = 0; + } + return nativeParseInt(string, radix); + } + // Fallback for environments with pre-ES5 implementations. + if (nativeParseInt(whitespace + '08') != 8) { + parseInt = function(string, radix, guard) { + // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`. + // Chrome fails to trim leading whitespace characters. + // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. + if (guard ? isIterateeCall(string, radix, guard) : radix == null) { + radix = 0; + } else if (radix) { + radix = +radix; + } + string = trim(string); + return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); + }; + } + + /** + * Repeats the given string `n` times. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to repeat. + * @param {number} [n=0] The number of times to repeat the string. + * @returns {string} Returns the repeated string. + * @example + * + * _.repeat('*', 3); + * // => '***' + * + * _.repeat('abc', 2); + * // => 'abcabc' + * + * _.repeat('abc', 0); + * // => '' + */ + function repeat(string, n) { + var result = ''; + string = baseToString(string); + n = +n; + if (n < 1 || !string || !nativeIsFinite(n)) { + return result; + } + // Leverage the exponentiation by squaring algorithm for a faster repeat. + // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. + do { + if (n % 2) { + result += string; + } + n = floor(n / 2); + string += string; + } while (n); + + return result; + } + + /** + * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the snake cased string. + * @example + * + * _.snakeCase('Foo Bar'); + * // => 'foo_bar' + * + * _.snakeCase('fooBar'); + * // => 'foo_bar' + * + * _.snakeCase('--foo-bar'); + * // => 'foo_bar' + */ + var snakeCase = createCompounder(function(result, word, index) { + return result + (index ? '_' : '') + word.toLowerCase(); + }); + + /** + * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. + * @example + * + * _.startCase('--foo-bar'); + * // => 'Foo Bar' + * + * _.startCase('fooBar'); + * // => 'Foo Bar' + * + * _.startCase('__foo_bar__'); + * // => 'Foo Bar' + */ + var startCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1)); + }); + + /** + * Checks if `string` starts with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=0] The position to search from. + * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`. + * @example + * + * _.startsWith('abc', 'a'); + * // => true + * + * _.startsWith('abc', 'b'); + * // => false + * + * _.startsWith('abc', 'b', 1); + * // => true + */ + function startsWith(string, target, position) { + string = baseToString(string); + position = position == null + ? 0 + : nativeMin(position < 0 ? 0 : (+position || 0), string.length); + + return string.lastIndexOf(target, position) == position; + } + + /** + * Creates a compiled template function that can interpolate data properties + * in "interpolate" delimiters, HTML-escape interpolated data properties in + * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data + * properties may be accessed as free variables in the template. If a setting + * object is provided it takes precedence over `_.templateSettings` values. + * + * **Note:** In the development build `_.template` utilizes + * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * for easier debugging. + * + * For more information on precompiling templates see + * [lodash's custom builds documentation](https://lodash.com/custom-builds). + * + * For more information on Chrome extension sandboxes see + * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The template string. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The HTML "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as free variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [options.sourceURL] The sourceURL of the template's compiled source. + * @param {string} [options.variable] The data object variable name. + * @param- {Object} [otherOptions] Enables the legacy `options` param signature. + * @returns {Function} Returns the compiled template function. + * @example + * + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' + * + * // using the HTML "escape" delimiter to escape data property values + * var compiled = _.template('<%- value %>'); + * compiled({ 'value': ' tag and this tag and this +``` + +Using [npm](http://npmjs.org/): + +```bash +npm install lodash + +npm install -g lodash +npm link lodash +``` + +In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/): + +```js +var _ = require('lodash'); +``` + +**Note:** If Lo-Dash is installed globally, [run `npm link lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory before requiring it. + +In [RingoJS v0.7.0-](http://ringojs.org/): + +```js +var _ = require('lodash')._; +``` + +In [Rhino](http://www.mozilla.org/rhino/): + +```js +load('lodash.js'); +``` + +In an AMD loader like [RequireJS](http://requirejs.org/): + +```js +require({ + 'paths': { + 'underscore': 'path/to/lodash' + } +}, +['underscore'], function(_) { + console.log(_.VERSION); +}); +``` + +## Resolved Underscore.js issues + + * Allow iteration of objects with a `length` property [[#799](https://github.com/documentcloud/underscore/pull/799), [test](https://github.com/lodash/lodash/blob/0.9.2/test/test.js#L545-551)] + * Fix cross-browser object iteration bugs [[#60](https://github.com/documentcloud/underscore/issues/60), [#376](https://github.com/documentcloud/underscore/issues/376), [test](https://github.com/lodash/lodash/blob/0.9.2/test/test.js#L558-582)] + * Methods should work on pages with incorrectly shimmed native methods [[#7](https://github.com/documentcloud/underscore/issues/7), [#742](https://github.com/documentcloud/underscore/issues/742), [test](https://github.com/lodash/lodash/blob/0.9.2/test/test.js#L140-146)] + * `_.isEmpty` should support jQuery/MooTools DOM query collections [[#690](https://github.com/documentcloud/underscore/pull/690), [test](https://github.com/lodash/lodash/blob/0.9.2/test/test.js#L747-752)] + * `_.isObject` should avoid V8 bug [#2291](http://code.google.com/p/8/issues/detail?id=2291) [[#605](https://github.com/documentcloud/underscore/issues/605), [test](https://github.com/lodash/lodash/blob/0.9.2/test/test.js#L828-840)] + * `_.keys` should work with `arguments` objects cross-browser [[#396](https://github.com/documentcloud/underscore/issues/396), [test](https://github.com/lodash/lodash/blob/0.9.2/test/test.js#L921-923)] + * `_.range` should coerce arguments to numbers [[#634](https://github.com/documentcloud/underscore/issues/634), [#683](https://github.com/documentcloud/underscore/issues/683), [test](https://github.com/lodash/lodash/blob/0.9.2/test/test.js#L1337-1340)] + +## Release Notes + +### v0.9.2 + + * Added `fromIndex` argument to `_.contains` + * Added `moduleId` build option + * Added Closure Compiler *“simple”* optimizations to the build process + * Added support for strings in `_.max` and `_.min` + * Added support for ES6 template delimiters to `_.template` + * Ensured re-minification of Lo-Dash by third parties avoids Closure Compiler bugs + * Optimized `_.every`, `_.find`, `_.some`, and `_.uniq` + +The full changelog is available [here](https://github.com/lodash/lodash/wiki/Changelog). + +## BestieJS + +Lo-Dash is part of the [BestieJS](https://github.com/bestiejs) *“Best in Class”* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation. + +## Author + +| [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](http://twitter.com/jdalton "Follow @jdalton on Twitter") | +|---| +| [John-David Dalton](http://allyoucanleet.com/) | + +## Contributors + +| [![twitter/blainebublitz](http://gravatar.com/avatar/ac1c67fd906c9fecd823ce302283b4c1?s=70)](http://twitter.com/blainebublitz "Follow @BlaineBublitz on Twitter") | [![twitter/kitcambridge](http://gravatar.com/avatar/6662a1d02f351b5ef2f8b4d815804661?s=70)](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter") | [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](http://twitter.com/mathias "Follow @mathias on Twitter") | +|---|---|---| +| [Blaine Bublitz](http://iceddev.com/) | [Kit Cambridge](http://kitcambridge.github.io/) | [Mathias Bynens](http://mathiasbynens.be/) | diff --git a/node_modules/lodash/lodash.js b/node_modules/lodash/lodash.js new file mode 100644 index 0000000..9eae931 --- /dev/null +++ b/node_modules/lodash/lodash.js @@ -0,0 +1,4258 @@ +/*! + * Lo-Dash v0.9.2 + * (c) 2012 John-David Dalton + * Based on Underscore.js 1.4.2 + * (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. + * Available under MIT license + */ +;(function(window, undefined) { + + /** Detect free variable `exports` */ + var freeExports = typeof exports == 'object' && exports; + + /** Detect free variable `global` and use it as `window` */ + var freeGlobal = typeof global == 'object' && global; + if (freeGlobal.global === freeGlobal) { + window = freeGlobal; + } + + /** Used for array and object method references */ + var arrayRef = [], + // avoid a Closure Compiler bug by creatively creating an object + objectRef = new function(){}; + + /** Used to generate unique IDs */ + var idCounter = 0; + + /** Used internally to indicate various things */ + var indicatorObject = objectRef; + + /** Used by `cachedContains` as the default size when optimizations are enabled for large arrays */ + var largeArraySize = 30; + + /** Used to restore the original `_` reference in `noConflict` */ + var oldDash = window._; + + /** Used to detect template delimiter values that require a with-statement */ + var reComplexDelimiter = /[-?+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/; + + /** Used to match HTML entities */ + var reEscapedHtml = /&(?:amp|lt|gt|quot|#x27);/g; + + /** Used to match empty string literals in compiled template source */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** Used to match regexp flags from their coerced string values */ + var reFlags = /\w*$/; + + /** Used to insert the data object variable into compiled template source */ + var reInsertVariable = /(?:__e|__t = )\(\s*(?![\d\s"']|this\.)/g; + + /** Used to detect if a method is native */ + var reNative = RegExp('^' + + (objectRef.valueOf + '') + .replace(/[.*+?^=!:${}()|[\]\/\\]/g, '\\$&') + .replace(/valueOf|for [^\]]+/g, '.+?') + '$' + ); + + /** + * Used to match ES6 template delimiters + * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6 + */ + var reEsTemplate = /\$\{((?:(?=\\?)\\?[\s\S])*?)}/g; + + /** Used to match "interpolate" template delimiters */ + var reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to ensure capturing order of template delimiters */ + var reNoMatch = /($^)/; + + /** Used to match HTML characters */ + var reUnescapedHtml = /[&<>"']/g; + + /** Used to match unescaped characters in compiled string literals */ + var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; + + /** Used to fix the JScript [[DontEnum]] bug */ + var shadowed = [ + 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', + 'toLocaleString', 'toString', 'valueOf' + ]; + + /** Used to make template sourceURLs easier to identify */ + var templateCounter = 0; + + /** Native method shortcuts */ + var ceil = Math.ceil, + concat = arrayRef.concat, + floor = Math.floor, + getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, + hasOwnProperty = objectRef.hasOwnProperty, + push = arrayRef.push, + propertyIsEnumerable = objectRef.propertyIsEnumerable, + slice = arrayRef.slice, + toString = objectRef.toString; + + /* Native method shortcuts for methods with the same name as other `lodash` methods */ + var nativeBind = reNative.test(nativeBind = slice.bind) && nativeBind, + nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray, + nativeIsFinite = window.isFinite, + nativeIsNaN = window.isNaN, + nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys, + nativeMax = Math.max, + nativeMin = Math.min, + nativeRandom = Math.random; + + /** `Object#toString` result shortcuts */ + var argsClass = '[object Arguments]', + arrayClass = '[object Array]', + boolClass = '[object Boolean]', + dateClass = '[object Date]', + funcClass = '[object Function]', + numberClass = '[object Number]', + objectClass = '[object Object]', + regexpClass = '[object RegExp]', + stringClass = '[object String]'; + + /** + * Detect the JScript [[DontEnum]] bug: + * + * In IE < 9 an objects own properties, shadowing non-enumerable ones, are + * made non-enumerable as well. + */ + var hasDontEnumBug; + + /** Detect if own properties are iterated after inherited properties (IE < 9) */ + var iteratesOwnLast; + + /** + * Detect if `Array#shift` and `Array#splice` augment array-like objects + * incorrectly: + * + * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` + * and `splice()` functions that fail to remove the last element, `value[0]`, + * of array-like objects even though the `length` property is set to `0`. + * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` + * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. + */ + var hasObjectSpliceBug = (hasObjectSpliceBug = { '0': 1, 'length': 1 }, + arrayRef.splice.call(hasObjectSpliceBug, 0, 1), hasObjectSpliceBug[0]); + + /** Detect if an `arguments` object's indexes are non-enumerable (IE < 9) */ + var noArgsEnum = true; + + (function() { + var props = []; + function ctor() { this.x = 1; } + ctor.prototype = { 'valueOf': 1, 'y': 1 }; + for (var prop in new ctor) { props.push(prop); } + for (prop in arguments) { noArgsEnum = !prop; } + + hasDontEnumBug = !/valueOf/.test(props); + iteratesOwnLast = props[0] != 'x'; + }(1)); + + /** Detect if an `arguments` object's [[Class]] is unresolvable (Firefox < 4, IE < 9) */ + var noArgsClass = !isArguments(arguments); + + /** Detect if `Array#slice` cannot be used to convert strings to arrays (Opera < 10.52) */ + var noArraySliceOnStrings = slice.call('x')[0] != 'x'; + + /** + * Detect lack of support for accessing string characters by index: + * + * IE < 8 can't access characters by index and IE 8 can only access + * characters by index on string literals. + */ + var noCharByIndex = ('x'[0] + Object('x')[0]) != 'xx'; + + /** + * Detect if a node's [[Class]] is unresolvable (IE < 9) + * and that the JS engine won't error when attempting to coerce an object to + * a string without a `toString` property value of `typeof` "function". + */ + try { + var noNodeClass = ({ 'toString': 0 } + '', toString.call(window.document || 0) == objectClass); + } catch(e) { } + + /* Detect if `Function#bind` exists and is inferred to be fast (all but V8) */ + var isBindFast = nativeBind && /\n|Opera/.test(nativeBind + toString.call(window.opera)); + + /* Detect if `Object.keys` exists and is inferred to be fast (IE, Opera, V8) */ + var isKeysFast = nativeKeys && /^.+$|true/.test(nativeKeys + !!window.attachEvent); + + /** + * Detect if sourceURL syntax is usable without erroring: + * + * The JS engine in Adobe products, like InDesign, will throw a syntax error + * when it encounters a single line comment beginning with the `@` symbol. + * + * The JS engine in Narwhal will generate the function `function anonymous(){//}` + * and throw a syntax error. + * + * Avoid comments beginning `@` symbols in IE because they are part of its + * non-standard conditional compilation support. + * http://msdn.microsoft.com/en-us/library/121hztk3(v=vs.94).aspx + */ + try { + var useSourceURL = (Function('//@')(), !window.attachEvent); + } catch(e) { } + + /** Used to identify object classifications that `_.clone` supports */ + var cloneableClasses = {}; + cloneableClasses[argsClass] = cloneableClasses[funcClass] = false; + cloneableClasses[arrayClass] = cloneableClasses[boolClass] = cloneableClasses[dateClass] = + cloneableClasses[numberClass] = cloneableClasses[objectClass] = cloneableClasses[regexpClass] = + cloneableClasses[stringClass] = true; + + /** Used to determine if values are of the language type Object */ + var objectTypes = { + 'boolean': false, + 'function': true, + 'object': true, + 'number': false, + 'string': false, + 'undefined': false + }; + + /** Used to escape characters for inclusion in compiled string literals */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\t': 't', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The `lodash` function. + * + * @name _ + * @constructor + * @category Chaining + * @param {Mixed} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns a `lodash` instance. + */ + function lodash(value) { + // exit early if already wrapped + if (value && value.__wrapped__) { + return value; + } + // allow invoking `lodash` without the `new` operator + if (!(this instanceof lodash)) { + return new lodash(value); + } + this.__wrapped__ = value; + } + + /** + * By default, the template delimiters used by Lo-Dash are similar to those in + * embedded Ruby (ERB). Change the following template settings to use alternative + * delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @static + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': /<%-([\s\S]+?)%>/g, + + /** + * Used to detect code to be evaluated. + * + * @static + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': /<%([\s\S]+?)%>/g, + + /** + * Used to detect `data` property values to inject. + * + * @static + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @static + * @memberOf _.templateSettings + * @type String + */ + 'variable': '' + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The template used to create iterator functions. + * + * @private + * @param {Obect} data The data object used to populate the text. + * @returns {String} Returns the interpolated text. + */ + var iteratorTemplate = template( + // conditional strict mode + '<% if (obj.useStrict) { %>\'use strict\';\n<% } %>' + + + // the `iteratee` may be reassigned by the `top` snippet + 'var index, value, iteratee = <%= firstArg %>, ' + + // assign the `result` variable an initial value + 'result = <%= firstArg %>;\n' + + // exit early if the first argument is falsey + 'if (!<%= firstArg %>) return result;\n' + + // add code before the iteration branches + '<%= top %>;\n' + + + // array-like iteration: + '<% if (arrayLoop) { %>' + + 'var length = iteratee.length; index = -1;\n' + + 'if (typeof length == \'number\') {' + + + // add support for accessing string characters by index if needed + ' <% if (noCharByIndex) { %>\n' + + ' if (isString(iteratee)) {\n' + + ' iteratee = iteratee.split(\'\')\n' + + ' }' + + ' <% } %>\n' + + + // iterate over the array-like value + ' while (++index < length) {\n' + + ' value = iteratee[index];\n' + + ' <%= arrayLoop %>\n' + + ' }\n' + + '}\n' + + 'else {' + + + // object iteration: + // add support for iterating over `arguments` objects if needed + ' <% } else if (noArgsEnum) { %>\n' + + ' var length = iteratee.length; index = -1;\n' + + ' if (length && isArguments(iteratee)) {\n' + + ' while (++index < length) {\n' + + ' value = iteratee[index += \'\'];\n' + + ' <%= objectLoop %>\n' + + ' }\n' + + ' } else {' + + ' <% } %>' + + + // Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 + // (if the prototype or a property on the prototype has been set) + // incorrectly sets a function's `prototype` property [[Enumerable]] + // value to `true`. Because of this Lo-Dash standardizes on skipping + // the the `prototype` property of functions regardless of its + // [[Enumerable]] value. + ' <% if (!hasDontEnumBug) { %>\n' + + ' var skipProto = typeof iteratee == \'function\' && \n' + + ' propertyIsEnumerable.call(iteratee, \'prototype\');\n' + + ' <% } %>' + + + // iterate own properties using `Object.keys` if it's fast + ' <% if (isKeysFast && useHas) { %>\n' + + ' var ownIndex = -1,\n' + + ' ownProps = objectTypes[typeof iteratee] ? nativeKeys(iteratee) : [],\n' + + ' length = ownProps.length;\n\n' + + ' while (++ownIndex < length) {\n' + + ' index = ownProps[ownIndex];\n' + + ' <% if (!hasDontEnumBug) { %>if (!(skipProto && index == \'prototype\')) {\n <% } %>' + + ' value = iteratee[index];\n' + + ' <%= objectLoop %>\n' + + ' <% if (!hasDontEnumBug) { %>}\n<% } %>' + + ' }' + + + // else using a for-in loop + ' <% } else { %>\n' + + ' for (index in iteratee) {<%' + + ' if (!hasDontEnumBug || useHas) { %>\n if (<%' + + ' if (!hasDontEnumBug) { %>!(skipProto && index == \'prototype\')<% }' + + ' if (!hasDontEnumBug && useHas) { %> && <% }' + + ' if (useHas) { %>hasOwnProperty.call(iteratee, index)<% }' + + ' %>) {' + + ' <% } %>\n' + + ' value = iteratee[index];\n' + + ' <%= objectLoop %>;' + + ' <% if (!hasDontEnumBug || useHas) { %>\n }<% } %>\n' + + ' }' + + ' <% } %>' + + + // Because IE < 9 can't set the `[[Enumerable]]` attribute of an + // existing property and the `constructor` property of a prototype + // defaults to non-enumerable, Lo-Dash skips the `constructor` + // property when it infers it's iterating over a `prototype` object. + ' <% if (hasDontEnumBug) { %>\n\n' + + ' var ctor = iteratee.constructor;\n' + + ' <% for (var k = 0; k < 7; k++) { %>\n' + + ' index = \'<%= shadowed[k] %>\';\n' + + ' if (<%' + + ' if (shadowed[k] == \'constructor\') {' + + ' %>!(ctor && ctor.prototype === iteratee) && <%' + + ' } %>hasOwnProperty.call(iteratee, index)) {\n' + + ' value = iteratee[index];\n' + + ' <%= objectLoop %>\n' + + ' }' + + ' <% } %>' + + ' <% } %>' + + ' <% if (arrayLoop || noArgsEnum) { %>\n}<% } %>\n' + + + // add code to the bottom of the iteration function + '<%= bottom %>;\n' + + // finally, return the `result` + 'return result' + ); + + /** + * Reusable iterator options shared by `forEach`, `forIn`, and `forOwn`. + */ + var forEachIteratorOptions = { + 'args': 'collection, callback, thisArg', + 'top': 'callback = createCallback(callback, thisArg)', + 'arrayLoop': 'if (callback(value, index, collection) === false) return result', + 'objectLoop': 'if (callback(value, index, collection) === false) return result' + }; + + /** Reusable iterator options for `defaults`, and `extend` */ + var extendIteratorOptions = { + 'useHas': false, + 'args': 'object', + 'top': + 'for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {\n' + + ' if (iteratee = arguments[argsIndex]) {', + 'objectLoop': 'result[index] = value', + 'bottom': ' }\n}' + }; + + /** Reusable iterator options for `forIn` and `forOwn` */ + var forOwnIteratorOptions = { + 'arrayLoop': null + }; + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function optimized to search large arrays for a given `value`, + * starting at `fromIndex`, using strict equality for comparisons, i.e. `===`. + * + * @private + * @param {Array} array The array to search. + * @param {Mixed} value The value to search for. + * @param {Number} [fromIndex=0] The index to search from. + * @param {Number} [largeSize=30] The length at which an array is considered large. + * @returns {Boolean} Returns `true` if `value` is found, else `false`. + */ + function cachedContains(array, fromIndex, largeSize) { + fromIndex || (fromIndex = 0); + + var length = array.length, + isLarge = (length - fromIndex) >= (largeSize || largeArraySize); + + if (isLarge) { + var cache = {}, + index = fromIndex - 1; + + while (++index < length) { + // manually coerce `value` to a string because `hasOwnProperty`, in some + // older versions of Firefox, coerces objects incorrectly + var key = array[index] + ''; + (hasOwnProperty.call(cache, key) ? cache[key] : (cache[key] = [])).push(array[index]); + } + } + return function(value) { + if (isLarge) { + var key = value + ''; + return hasOwnProperty.call(cache, key) && indexOf(cache[key], value) > -1; + } + return indexOf(array, value, fromIndex) > -1; + } + } + + /** + * Used by `_.max` and `_.min` as the default `callback` when a given + * `collection` is a string value. + * + * @private + * @param {String} value The character to inspect. + * @returns {Number} Returns the code unit of given character. + */ + function charAtCallback(value) { + return value.charCodeAt(0); + } + + /** + * Used by `sortBy` to compare transformed `collection` values, stable sorting + * them in ascending order. + * + * @private + * @param {Object} a The object to compare to `b`. + * @param {Object} b The object to compare to `a`. + * @returns {Number} Returns the sort order indicator of `1` or `-1`. + */ + function compareAscending(a, b) { + var ai = a.index, + bi = b.index; + + a = a.criteria; + b = b.criteria; + + // ensure a stable sort in V8 and other engines + // http://code.google.com/p/v8/issues/detail?id=90 + if (a !== b) { + if (a > b || a === undefined) { + return 1; + } + if (a < b || b === undefined) { + return -1; + } + } + return ai < bi ? -1 : 1; + } + + /** + * Creates a function that, when called, invokes `func` with the `this` + * binding of `thisArg` and prepends any `partailArgs` to the arguments passed + * to the bound function. + * + * @private + * @param {Function|String} func The function to bind or the method name. + * @param {Mixed} [thisArg] The `this` binding of `func`. + * @param {Array} partialArgs An array of arguments to be partially applied. + * @returns {Function} Returns the new bound function. + */ + function createBound(func, thisArg, partialArgs) { + var isFunc = isFunction(func), + isPartial = !partialArgs, + methodName = func; + + // juggle arguments + if (isPartial) { + partialArgs = thisArg; + } + + function bound() { + // `Function#bind` spec + // http://es5.github.com/#x15.3.4.5 + var args = arguments, + thisBinding = isPartial ? this : thisArg; + + if (!isFunc) { + func = thisArg[methodName]; + } + if (partialArgs.length) { + args = args.length + ? partialArgs.concat(slice.call(args)) + : partialArgs; + } + if (this instanceof bound) { + // get `func` instance if `bound` is invoked in a `new` expression + noop.prototype = func.prototype; + thisBinding = new noop; + + // mimic the constructor's `return` behavior + // http://es5.github.com/#x13.2.2 + var result = func.apply(thisBinding, args); + return isObject(result) + ? result + : thisBinding + } + return func.apply(thisBinding, args); + } + return bound; + } + + /** + * Produces an iteration callback bound to an optional `thisArg`. If `func` is + * a property name, the callback will return the property value for a given element. + * + * @private + * @param {Function|String} [func=identity|property] The function called per + * iteration or property name to query. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Function} Returns a callback function. + */ + function createCallback(func, thisArg) { + if (!func) { + return identity; + } + if (typeof func != 'function') { + return function(object) { + return object[func]; + }; + } + if (thisArg !== undefined) { + return function(value, index, object) { + return func.call(thisArg, value, index, object); + }; + } + return func; + } + + /** + * Creates compiled iteration functions. + * + * @private + * @param {Object} [options1, options2, ...] The compile options object(s). + * useHas - A boolean to specify using `hasOwnProperty` checks in the object loop. + * args - A string of comma separated arguments the iteration function will accept. + * top - A string of code to execute before the iteration branches. + * arrayLoop - A string of code to execute in the array loop. + * objectLoop - A string of code to execute in the object loop. + * bottom - A string of code to execute after the iteration branches. + * + * @returns {Function} Returns the compiled function. + */ + function createIterator() { + var data = { + 'arrayLoop': '', + 'bottom': '', + 'hasDontEnumBug': hasDontEnumBug, + 'isKeysFast': isKeysFast, + 'objectLoop': '', + 'noArgsEnum': noArgsEnum, + 'noCharByIndex': noCharByIndex, + 'shadowed': shadowed, + 'top': '', + 'useHas': true + }; + + // merge options into a template data object + for (var object, index = 0; object = arguments[index]; index++) { + for (var key in object) { + data[key] = object[key]; + } + } + var args = data.args; + data.firstArg = /^[^,]+/.exec(args)[0]; + + // create the function factory + var factory = Function( + 'createCallback, hasOwnProperty, isArguments, isString, objectTypes, ' + + 'nativeKeys, propertyIsEnumerable', + 'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}' + ); + // return the compiled function + return factory( + createCallback, hasOwnProperty, isArguments, isString, objectTypes, + nativeKeys, propertyIsEnumerable + ); + } + + /** + * Used by `template` to escape characters for inclusion in compiled + * string literals. + * + * @private + * @param {String} match The matched character to escape. + * @returns {String} Returns the escaped character. + */ + function escapeStringChar(match) { + return '\\' + stringEscapes[match]; + } + + /** + * Used by `escape` to convert characters to HTML entities. + * + * @private + * @param {String} match The matched character to escape. + * @returns {String} Returns the escaped character. + */ + function escapeHtmlChar(match) { + return htmlEscapes[match]; + } + + /** + * A no-operation function. + * + * @private + */ + function noop() { + // no operation performed + } + + /** + * Used by `unescape` to convert HTML entities to characters. + * + * @private + * @param {String} match The matched character to unescape. + * @returns {String} Returns the unescaped character. + */ + function unescapeHtmlChar(match) { + return htmlUnescapes[match]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Checks if `value` is an `arguments` object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the `value` is an `arguments` object, else `false`. + * @example + * + * (function() { return _.isArguments(arguments); })(1, 2, 3); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + return toString.call(value) == argsClass; + } + // fallback for browsers that can't detect `arguments` objects by [[Class]] + if (noArgsClass) { + isArguments = function(value) { + return value ? hasOwnProperty.call(value, 'callee') : false; + }; + } + + /** + * Iterates over `object`'s own and inherited enumerable properties, executing + * the `callback` for each property. The `callback` is bound to `thisArg` and + * invoked with three arguments; (value, key, object). Callbacks may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} callback The function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Dog(name) { + * this.name = name; + * } + * + * Dog.prototype.bark = function() { + * alert('Woof, woof!'); + * }; + * + * _.forIn(new Dog('Dagny'), function(value, key) { + * alert(key); + * }); + * // => alerts 'name' and 'bark' (order is not guaranteed) + */ + var forIn = createIterator(forEachIteratorOptions, forOwnIteratorOptions, { + 'useHas': false + }); + + /** + * Iterates over `object`'s own enumerable properties, executing the `callback` + * for each property. The `callback` is bound to `thisArg` and invoked with three + * arguments; (value, key, object). Callbacks may exit iteration early by explicitly + * returning `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} callback The function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * alert(key); + * }); + * // => alerts '0', '1', and 'length' (order is not guaranteed) + */ + var forOwn = createIterator(forEachIteratorOptions, forOwnIteratorOptions); + + /** + * A fallback implementation of `isPlainObject` that checks if a given `value` + * is an object created by the `Object` constructor, assuming objects created + * by the `Object` constructor have no inherited enumerable properties and that + * there are no `Object.prototype` extensions. + * + * @private + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if `value` is a plain object, else `false`. + */ + function shimIsPlainObject(value) { + // avoid non-objects and false positives for `arguments` objects + var result = false; + if (!(value && typeof value == 'object') || isArguments(value)) { + return result; + } + // IE < 9 presents DOM nodes as `Object` objects except they have `toString` + // methods that are `typeof` "string" and still can coerce nodes to strings. + // Also check that the constructor is `Object` (i.e. `Object instanceof Object`) + var ctor = value.constructor; + if ((!noNodeClass || !(typeof value.toString != 'function' && typeof (value + '') == 'string')) && + (!isFunction(ctor) || ctor instanceof ctor)) { + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + if (iteratesOwnLast) { + forIn(value, function(value, key, object) { + result = !hasOwnProperty.call(object, key); + return false; + }); + return result === false; + } + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + forIn(value, function(value, key) { + result = key; + }); + return result === false || hasOwnProperty.call(value, result); + } + return result; + } + + /** + * A fallback implementation of `Object.keys` that produces an array of the + * given object's own enumerable property names. + * + * @private + * @param {Object} object The object to inspect. + * @returns {Array} Returns a new array of property names. + */ + function shimKeys(object) { + var result = []; + forOwn(object, function(value, key) { + result.push(key); + }); + return result; + } + + /** + * Used to convert characters to HTML entities: + * + * Though the `>` character is escaped for symmetry, characters like `>` and `/` + * don't require escaping in HTML and have no special meaning unless they're part + * of a tag or an unquoted attribute value. + * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") + */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + /** Used to convert HTML entities to characters */ + var htmlUnescapes = invert(htmlEscapes); + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a clone of `value`. If `deep` is `true`, all nested objects will + * also be cloned otherwise they will be assigned by reference. Functions, DOM + * nodes, `arguments` objects, and objects created by constructors other than + * `Object` are **not** cloned. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to clone. + * @param {Boolean} deep A flag to indicate a deep clone. + * @param- {Object} [guard] Internally used to allow this method to work with + * others like `_.map` without using their callback `index` argument for `deep`. + * @param- {Array} [stackA=[]] Internally used to track traversed source objects. + * @param- {Array} [stackB=[]] Internally used to associate clones with their + * source counterparts. + * @returns {Mixed} Returns the cloned `value`. + * @example + * + * var stooges = [ + * { 'name': 'moe', 'age': 40 }, + * { 'name': 'larry', 'age': 50 }, + * { 'name': 'curly', 'age': 60 } + * ]; + * + * _.clone({ 'name': 'moe' }); + * // => { 'name': 'moe' } + * + * var shallow = _.clone(stooges); + * shallow[0] === stooges[0]; + * // => true + * + * var deep = _.clone(stooges, true); + * shallow[0] === stooges[0]; + * // => false + */ + function clone(value, deep, guard, stackA, stackB) { + if (value == null) { + return value; + } + if (guard) { + deep = false; + } + // inspect [[Class]] + var isObj = isObject(value); + if (isObj) { + // don't clone `arguments` objects, functions, or non-object Objects + var className = toString.call(value); + if (!cloneableClasses[className] || (noArgsClass && isArguments(value))) { + return value; + } + var isArr = className == arrayClass; + isObj = isArr || (className == objectClass ? isPlainObject(value) : isObj); + } + // shallow clone + if (!isObj || !deep) { + // don't clone functions + return isObj + ? (isArr ? slice.call(value) : extend({}, value)) + : value; + } + + var ctor = value.constructor; + switch (className) { + case boolClass: + case dateClass: + return new ctor(+value); + + case numberClass: + case stringClass: + return new ctor(value); + + case regexpClass: + return ctor(value.source, reFlags.exec(value)); + } + // check for circular references and return corresponding clone + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + // init cloned object + var result = isArr ? ctor(value.length) : {}; + + // add the source value to the stack of traversed objects + // and associate it with its clone + stackA.push(value); + stackB.push(result); + + // recursively populate clone (susceptible to call stack limits) + (isArr ? forEach : forOwn)(value, function(objValue, key) { + result[key] = clone(objValue, deep, null, stackA, stackB); + }); + + return result; + } + + /** + * Assigns enumerable properties of the default object(s) to the `destination` + * object for all `destination` properties that resolve to `null`/`undefined`. + * Once a property is set, additional defaults of the same property will be + * ignored. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The destination object. + * @param {Object} [default1, default2, ...] The default objects. + * @returns {Object} Returns the destination object. + * @example + * + * var iceCream = { 'flavor': 'chocolate' }; + * _.defaults(iceCream, { 'flavor': 'vanilla', 'sprinkles': 'rainbow' }); + * // => { 'flavor': 'chocolate', 'sprinkles': 'rainbow' } + */ + var defaults = createIterator(extendIteratorOptions, { + 'objectLoop': 'if (result[index] == null) ' + extendIteratorOptions.objectLoop + }); + + /** + * Assigns enumerable properties of the source object(s) to the `destination` + * object. Subsequent sources will overwrite propery assignments of previous + * sources. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The destination object. + * @param {Object} [source1, source2, ...] The source objects. + * @returns {Object} Returns the destination object. + * @example + * + * _.extend({ 'name': 'moe' }, { 'age': 40 }); + * // => { 'name': 'moe', 'age': 40 } + */ + var extend = createIterator(extendIteratorOptions); + + /** + * Creates a sorted array of all enumerable properties, own and inherited, + * of `object` that have function values. + * + * @static + * @memberOf _ + * @alias methods + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns a new array of property names that have function values. + * @example + * + * _.functions(_); + * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] + */ + function functions(object) { + var result = []; + forIn(object, function(value, key) { + if (isFunction(value)) { + result.push(key); + } + }); + return result.sort(); + } + + /** + * Checks if the specified object `property` exists and is a direct property, + * instead of an inherited property. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to check. + * @param {String} property The property to check for. + * @returns {Boolean} Returns `true` if key is a direct property, else `false`. + * @example + * + * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); + * // => true + */ + function has(object, property) { + return object ? hasOwnProperty.call(object, property) : false; + } + + /** + * Creates an object composed of the inverted keys and values of the given `object`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to invert. + * @returns {Object} Returns the created inverted object. + * @example + * + * _.invert({ 'first': 'Moe', 'second': 'Larry', 'third': 'Curly' }); + * // => { 'Moe': 'first', 'Larry': 'second', 'Curly': 'third' } (order is not guaranteed) + */ + function invert(object) { + var result = {}; + forOwn(object, function(value, key) { + result[value] = key; + }); + return result; + } + + /** + * Checks if `value` is an array. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the `value` is an array, else `false`. + * @example + * + * (function() { return _.isArray(arguments); })(); + * // => false + * + * _.isArray([1, 2, 3]); + * // => true + */ + var isArray = nativeIsArray || function(value) { + return toString.call(value) == arrayClass; + }; + + /** + * Checks if `value` is a boolean (`true` or `false`) value. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the `value` is a boolean value, else `false`. + * @example + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || toString.call(value) == boolClass; + } + + /** + * Checks if `value` is a date. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the `value` is a date, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + */ + function isDate(value) { + return toString.call(value) == dateClass; + } + + /** + * Checks if `value` is a DOM element. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + */ + function isElement(value) { + return value ? value.nodeType === 1 : false; + } + + /** + * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a + * length of `0` and objects with no own enumerable properties are considered + * "empty". + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object|String} value The value to inspect. + * @returns {Boolean} Returns `true` if the `value` is empty, else `false`. + * @example + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({}); + * // => true + * + * _.isEmpty(''); + * // => true + */ + function isEmpty(value) { + var result = true; + if (!value) { + return result; + } + var className = toString.call(value), + length = value.length; + + if ((className == arrayClass || className == stringClass || + className == argsClass || (noArgsClass && isArguments(value))) || + (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { + return !length; + } + forOwn(value, function() { + return (result = false); + }); + return result; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent to each other. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} a The value to compare. + * @param {Mixed} b The other value to compare. + * @param- {Object} [stackA=[]] Internally used track traversed `a` objects. + * @param- {Object} [stackB=[]] Internally used track traversed `b` objects. + * @returns {Boolean} Returns `true` if the values are equvalent, else `false`. + * @example + * + * var moe = { 'name': 'moe', 'luckyNumbers': [13, 27, 34] }; + * var clone = { 'name': 'moe', 'luckyNumbers': [13, 27, 34] }; + * + * moe == clone; + * // => false + * + * _.isEqual(moe, clone); + * // => true + */ + function isEqual(a, b, stackA, stackB) { + // exit early for identical values + if (a === b) { + // treat `+0` vs. `-0` as not equal + return a !== 0 || (1 / a == 1 / b); + } + // a strict comparison is necessary because `null == undefined` + if (a == null || b == null) { + return a === b; + } + // compare [[Class]] names + var className = toString.call(a); + if (className != toString.call(b)) { + return false; + } + switch (className) { + case boolClass: + case dateClass: + // coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0`, treating invalid dates coerced to `NaN` as not equal + return +a == +b; + + case numberClass: + // treat `NaN` vs. `NaN` as equal + return a != +a + ? b != +b + // but treat `+0` vs. `-0` as not equal + : (a == 0 ? (1 / a == 1 / b) : a == +b); + + case regexpClass: + case stringClass: + // coerce regexes to strings (http://es5.github.com/#x15.10.6.4) + // treat string primitives and their corresponding object instances as equal + return a == b + ''; + } + // exit early, in older browsers, if `a` is array-like but not `b` + var isArr = className == arrayClass || className == argsClass; + if (noArgsClass && !isArr && (isArr = isArguments(a)) && !isArguments(b)) { + return false; + } + if (!isArr) { + // unwrap any `lodash` wrapped values + if (a.__wrapped__ || b.__wrapped__) { + return isEqual(a.__wrapped__ || a, b.__wrapped__ || b); + } + // exit for functions and DOM nodes + if (className != objectClass || (noNodeClass && ( + (typeof a.toString != 'function' && typeof (a + '') == 'string') || + (typeof b.toString != 'function' && typeof (b + '') == 'string')))) { + return false; + } + var ctorA = a.constructor, + ctorB = b.constructor; + + // non `Object` object instances with different constructors are not equal + if (ctorA != ctorB && !( + isFunction(ctorA) && ctorA instanceof ctorA && + isFunction(ctorB) && ctorB instanceof ctorB + )) { + return false; + } + } + // assume cyclic structures are equal + // the algorithm for detecting cyclic structures is adapted from ES 5.1 + // section 15.12.3, abstract operation `JO` (http://es5.github.com/#x15.12.3) + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == a) { + return stackB[length] == b; + } + } + + var index = -1, + result = true, + size = 0; + + // add `a` and `b` to the stack of traversed objects + stackA.push(a); + stackB.push(b); + + // recursively compare objects and arrays (susceptible to call stack limits) + if (isArr) { + // compare lengths to determine if a deep comparison is necessary + size = a.length; + result = size == b.length; + + if (result) { + // deep compare the contents, ignoring non-numeric properties + while (size--) { + if (!(result = isEqual(a[size], b[size], stackA, stackB))) { + break; + } + } + } + return result; + } + // deep compare objects + for (var key in a) { + if (hasOwnProperty.call(a, key)) { + // count the number of properties. + size++; + // deep compare each property value. + if (!(hasOwnProperty.call(b, key) && isEqual(a[key], b[key], stackA, stackB))) { + return false; + } + } + } + // ensure both objects have the same number of properties + for (key in b) { + // The JS engine in Adobe products, like InDesign, has a bug that causes + // `!size--` to throw an error so it must be wrapped in parentheses. + // https://github.com/documentcloud/underscore/issues/355 + if (hasOwnProperty.call(b, key) && !(size--)) { + // `size` will be `-1` if `b` has more properties than `a` + return false; + } + } + // handle JScript [[DontEnum]] bug + if (hasDontEnumBug) { + while (++index < 7) { + key = shadowed[index]; + if (hasOwnProperty.call(a, key) && + !(hasOwnProperty.call(b, key) && isEqual(a[key], b[key], stackA, stackB))) { + return false; + } + } + } + return true; + } + + /** + * Checks if `value` is, or can be coerced to, a finite number. + * + * Note: This is not the same as native `isFinite`, which will return true for + * booleans and empty strings. See http://es5.github.com/#x15.1.2.5. + * + * @deprecated + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the `value` is a finite number, else `false`. + * @example + * + * _.isFinite(-101); + * // => true + * + * _.isFinite('10'); + * // => true + * + * _.isFinite(true); + * // => false + * + * _.isFinite(''); + * // => false + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); + } + + /** + * Checks if `value` is a function. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + */ + function isFunction(value) { + return typeof value == 'function'; + } + // fallback for older versions of Chrome and Safari + if (isFunction(/x/)) { + isFunction = function(value) { + return toString.call(value) == funcClass; + }; + } + + /** + * Checks if `value` is the language type of Object. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ + function isObject(value) { + // check if the value is the ECMAScript language type of Object + // http://es5.github.com/#x8 + // and avoid a V8 bug + // http://code.google.com/p/v8/issues/detail?id=2291 + return value ? objectTypes[typeof value] : false; + } + + /** + * Checks if `value` is `NaN`. + * + * Note: This is not the same as native `isNaN`, which will return true for + * `undefined` and other values. See http://es5.github.com/#x15.1.2.4. + * + * @deprecated + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // `NaN` as a primitive is the only value that is not equal to itself + // (perform the [[Class]] check first to avoid errors with some host objects in IE) + return toString.call(value) == numberClass && value != +value + } + + /** + * Checks if `value` is `null`. + * + * @deprecated + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(undefined); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is a number. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the `value` is a number, else `false`. + * @example + * + * _.isNumber(8.4 * 5); + * // => true + */ + function isNumber(value) { + return toString.call(value) == numberClass; + } + + /** + * Checks if a given `value` is an object created by the `Object` constructor. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Stooge(name, age) { + * this.name = name; + * this.age = age; + * } + * + * _.isPlainObject(new Stooge('moe', 40)); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'name': 'moe', 'age': 40 }); + * // => true + */ + var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { + if (!(value && typeof value == 'object')) { + return false; + } + var valueOf = value.valueOf, + objProto = typeof valueOf == 'function' && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); + + return objProto + ? value == objProto || (getPrototypeOf(value) == objProto && !isArguments(value)) + : shimIsPlainObject(value); + }; + + /** + * Checks if `value` is a regular expression. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the `value` is a regular expression, else `false`. + * @example + * + * _.isRegExp(/moe/); + * // => true + */ + function isRegExp(value) { + return toString.call(value) == regexpClass; + } + + /** + * Checks if `value` is a string. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the `value` is a string, else `false`. + * @example + * + * _.isString('moe'); + * // => true + */ + function isString(value) { + return toString.call(value) == stringClass; + } + + /** + * Checks if `value` is `undefined`. + * + * @deprecated + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * Creates an array composed of the own enumerable property names of `object`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns a new array of property names. + * @example + * + * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); + * // => ['one', 'two', 'three'] (order is not guaranteed) + */ + var keys = !nativeKeys ? shimKeys : function(object) { + // avoid iterating over the `prototype` property + return typeof object == 'function' && propertyIsEnumerable.call(object, 'prototype') + ? shimKeys(object) + : (isObject(object) ? nativeKeys(object) : []); + }; + + /** + * Merges enumerable properties of the source object(s) into the `destination` + * object. Subsequent sources will overwrite propery assignments of previous + * sources. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The destination object. + * @param {Object} [source1, source2, ...] The source objects. + * @param- {Object} [indicator] Internally used to indicate that the `stack` + * argument is an array of traversed objects instead of another source object. + * @param- {Array} [stackA=[]] Internally used to track traversed source objects. + * @param- {Array} [stackB=[]] Internally used to associate values with their + * source counterparts. + * @returns {Object} Returns the destination object. + * @example + * + * var stooges = [ + * { 'name': 'moe' }, + * { 'name': 'larry' } + * ]; + * + * var ages = [ + * { 'age': 40 }, + * { 'age': 50 } + * ]; + * + * _.merge(stooges, ages); + * // => [{ 'name': 'moe', 'age': 40 }, { 'name': 'larry', 'age': 50 }] + */ + function merge(object, source, indicator) { + var args = arguments, + index = 0, + length = 2, + stackA = args[3], + stackB = args[4]; + + if (indicator !== objectRef) { + stackA = []; + stackB = []; + length = args.length; + } + while (++index < length) { + forOwn(args[index], function(source, key) { + var found, isArr, value; + if (source && ((isArr = isArray(source)) || isPlainObject(source))) { + // avoid merging previously merged cyclic sources + var stackLength = stackA.length; + while (stackLength--) { + found = stackA[stackLength] == source; + if (found) { + break; + } + } + if (found) { + object[key] = stackB[stackLength]; + } + else { + // add `source` and associated `value` to the stack of traversed objects + stackA.push(source); + stackB.push(value = (value = object[key], isArr) + ? (isArray(value) ? value : []) + : (isPlainObject(value) ? value : {}) + ); + // recursively merge objects and arrays (susceptible to call stack limits) + object[key] = merge(value, source, objectRef, stackA, stackB); + } + } else if (source != null) { + object[key] = source; + } + }); + } + return object; + } + + /** + * Creates a shallow clone of `object` excluding the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If `callback` is passed, it will be executed for each property + * in the `object`, omitting the properties `callback` returns truthy for. The + * `callback` is bound to `thisArg` and invoked with three arguments; (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|String} callback|[prop1, prop2, ...] The properties to omit + * or the function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object without the omitted properties. + * @example + * + * _.omit({ 'name': 'moe', 'age': 40, 'userid': 'moe1' }, 'userid'); + * // => { 'name': 'moe', 'age': 40 } + * + * _.omit({ 'name': 'moe', '_hint': 'knucklehead', '_seed': '96c4eb' }, function(value, key) { + * return key.charAt(0) == '_'; + * }); + * // => { 'name': 'moe' } + */ + function omit(object, callback, thisArg) { + var isFunc = typeof callback == 'function', + result = {}; + + if (isFunc) { + callback = createCallback(callback, thisArg); + } else { + var props = concat.apply(arrayRef, arguments); + } + forIn(object, function(value, key, object) { + if (isFunc + ? !callback(value, key, object) + : indexOf(props, key, 1) < 0 + ) { + result[key] = value; + } + }); + return result; + } + + /** + * Creates a two dimensional array of the given object's key-value pairs, + * i.e. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns new array of key-value pairs. + * @example + * + * _.pairs({ 'moe': 30, 'larry': 40, 'curly': 50 }); + * // => [['moe', 30], ['larry', 40], ['curly', 50]] (order is not guaranteed) + */ + function pairs(object) { + var result = []; + forOwn(object, function(value, key) { + result.push([key, value]); + }); + return result; + } + + /** + * Creates a shallow clone of `object` composed of the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If `callback` is passed, it will be executed for each property + * in the `object`, picking the properties `callback` returns truthy for. The + * `callback` is bound to `thisArg` and invoked with three arguments; (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|String} callback|[prop1, prop2, ...] The properties to pick + * or the function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object composed of the picked properties. + * @example + * + * _.pick({ 'name': 'moe', 'age': 40, 'userid': 'moe1' }, 'name', 'age'); + * // => { 'name': 'moe', 'age': 40 } + * + * _.pick({ 'name': 'moe', '_hint': 'knucklehead', '_seed': '96c4eb' }, function(value, key) { + * return key.charAt(0) != '_'; + * }); + * // => { 'name': 'moe' } + */ + function pick(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var index = 0, + props = concat.apply(arrayRef, arguments), + length = props.length; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + } else { + callback = createCallback(callback, thisArg); + forIn(object, function(value, key, object) { + if (callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * Creates an array composed of the own enumerable property values of `object`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns a new array of property values. + * @example + * + * _.values({ 'one': 1, 'two': 2, 'three': 3 }); + * // => [1, 2, 3] + */ + function values(object) { + var result = []; + forOwn(object, function(value) { + result.push(value); + }); + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Checks if a given `target` element is present in a `collection` using strict + * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used + * as the offset from the end of the collection. + * + * @static + * @memberOf _ + * @alias include + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Mixed} target The value to check for. + * @param {Number} [fromIndex=0] The index to search from. + * @returns {Boolean} Returns `true` if the `target` element is found, else `false`. + * @example + * + * _.contains([1, 2, 3], 1); + * // => true + * + * _.contains([1, 2, 3], 1, 2); + * // => false + * + * _.contains({ 'name': 'moe', 'age': 40 }, 'moe'); + * // => true + * + * _.contains('curly', 'ur'); + * // => true + */ + function contains(collection, target, fromIndex) { + var index = -1, + length = collection ? collection.length : 0; + + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; + if (typeof length == 'number') { + return (isString(collection) + ? collection.indexOf(target, fromIndex) + : indexOf(collection, target, fromIndex) + ) > -1; + } + return some(collection, function(value) { + return ++index >= fromIndex && value === target; + }); + } + + /** + * Creates an object composed of keys returned from running each element of + * `collection` through a `callback`. The corresponding value of each key is + * the number of times the key was returned by `callback`. The `callback` is + * bound to `thisArg` and invoked with three arguments; (value, index|key, collection). + * The `callback` argument may also be the name of a property to count by (e.g. 'length'). + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|String} callback|property The function called per iteration + * or property name to count by. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + function countBy(collection, callback, thisArg) { + var result = {}; + callback = createCallback(callback, thisArg); + forEach(collection, function(value, key, collection) { + key = callback(value, key, collection); + (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); + }); + return result; + } + + /** + * Checks if the `callback` returns a truthy value for **all** elements of a + * `collection`. The `callback` is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). + * + * @static + * @memberOf _ + * @alias all + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Boolean} Returns `true` if all elements pass the callback check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + */ + function every(collection, callback, thisArg) { + var result = true; + callback = createCallback(callback, thisArg); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (!(result = !!callback(collection[index], index, collection))) { + break; + } + } + } else { + forEach(collection, function(value, index, collection) { + return (result = !!callback(value, index, collection)); + }); + } + return result; + } + + /** + * Examines each element in a `collection`, returning an array of all elements + * the `callback` returns truthy for. The `callback` is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * @static + * @memberOf _ + * @alias select + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that passed the callback check. + * @example + * + * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [2, 4, 6] + */ + function filter(collection, callback, thisArg) { + var result = []; + callback = createCallback(callback, thisArg); + forEach(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result.push(value); + } + }); + return result; + } + + /** + * Examines each element in a `collection`, returning the first one the `callback` + * returns truthy for. The function returns as soon as it finds an acceptable + * element, and does not iterate over the entire `collection`. The `callback` is + * bound to `thisArg` and invoked with three arguments; (value, index|key, collection). + * + * @static + * @memberOf _ + * @alias detect + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function} callback The function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Mixed} Returns the element that passed the callback check, + * else `undefined`. + * @example + * + * var even = _.find([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => 2 + */ + function find(collection, callback, thisArg) { + var result; + callback = createCallback(callback, thisArg); + forEach(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + + /** + * Iterates over a `collection`, executing the `callback` for each element in + * the `collection`. The `callback` is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). Callbacks may exit iteration early + * by explicitly returning `false`. + * + * @static + * @memberOf _ + * @alias each + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function} callback The function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|String} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEach(alert).join(','); + * // => alerts each number and returns '1,2,3' + * + * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, alert); + * // => alerts each number (order is not guaranteed) + */ + var forEach = createIterator(forEachIteratorOptions); + + /** + * Creates an object composed of keys returned from running each element of + * `collection` through a `callback`. The corresponding value of each key is an + * array of elements passed to `callback` that returned the key. The `callback` + * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection). + * The `callback` argument may also be the name of a property to group by (e.g. 'length'). + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|String} callback|property The function called per iteration + * or property name to group by. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + function groupBy(collection, callback, thisArg) { + var result = {}; + callback = createCallback(callback, thisArg); + forEach(collection, function(value, key, collection) { + key = callback(value, key, collection); + (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); + }); + return result; + } + + /** + * Invokes the method named by `methodName` on each element in the `collection`, + * returning an array of the results of each invoked method. Additional arguments + * will be passed to each invoked method. If `methodName` is a function it will + * be invoked for, and `this` bound to, each element in the `collection`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|String} methodName The name of the method to invoke or + * the function invoked per iteration. + * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with. + * @returns {Array} Returns a new array of the results of each invoked method. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + function invoke(collection, methodName) { + var args = slice.call(arguments, 2), + isFunc = typeof methodName == 'function', + result = []; + + forEach(collection, function(value) { + result.push((isFunc ? methodName : value[methodName]).apply(value, args)); + }); + return result; + } + + /** + * Creates an array of values by running each element in the `collection` + * through a `callback`. The `callback` is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * @static + * @memberOf _ + * @alias collect + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of the results of each `callback` execution. + * @example + * + * _.map([1, 2, 3], function(num) { return num * 3; }); + * // => [3, 6, 9] + * + * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); + * // => [3, 6, 9] (order is not guaranteed) + */ + function map(collection, callback, thisArg) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + callback = createCallback(callback, thisArg); + if (isArray(collection)) { + while (++index < length) { + result[index] = callback(collection[index], index, collection); + } + } else { + forEach(collection, function(value, key, collection) { + result[++index] = callback(value, key, collection); + }); + } + return result; + } + + /** + * Retrieves the maximum value of an `array`. If `callback` is passed, + * it will be executed for each value in the `array` to generate the + * criterion by which the value is ranked. The `callback` is bound to + * `thisArg` and invoked with three arguments; (value, index, collection). + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function} [callback] The function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Mixed} Returns the maximum value. + * @example + * + * var stooges = [ + * { 'name': 'moe', 'age': 40 }, + * { 'name': 'larry', 'age': 50 }, + * { 'name': 'curly', 'age': 60 } + * ]; + * + * _.max(stooges, function(stooge) { return stooge.age; }); + * // => { 'name': 'curly', 'age': 60 }; + */ + function max(collection, callback, thisArg) { + var computed = -Infinity, + index = -1, + length = collection ? collection.length : 0, + result = computed; + + if (callback || !isArray(collection)) { + callback = !callback && isString(collection) + ? charAtCallback + : createCallback(callback, thisArg); + + forEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current > computed) { + computed = current; + result = value; + } + }); + } else { + while (++index < length) { + if (collection[index] > result) { + result = collection[index]; + } + } + } + return result; + } + + /** + * Retrieves the minimum value of an `array`. If `callback` is passed, + * it will be executed for each value in the `array` to generate the + * criterion by which the value is ranked. The `callback` is bound to `thisArg` + * and invoked with three arguments; (value, index, collection). + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function} [callback] The function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Mixed} Returns the minimum value. + * @example + * + * _.min([10, 5, 100, 2, 1000]); + * // => 2 + */ + function min(collection, callback, thisArg) { + var computed = Infinity, + index = -1, + length = collection ? collection.length : 0, + result = computed; + + if (callback || !isArray(collection)) { + callback = !callback && isString(collection) + ? charAtCallback + : createCallback(callback, thisArg); + + forEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current < computed) { + computed = current; + result = value; + } + }); + } else { + while (++index < length) { + if (collection[index] < result) { + result = collection[index]; + } + } + } + return result; + } + + /** + * Retrieves the value of a specified property from all elements in + * the `collection`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {String} property The property to pluck. + * @returns {Array} Returns a new array of property values. + * @example + * + * var stooges = [ + * { 'name': 'moe', 'age': 40 }, + * { 'name': 'larry', 'age': 50 }, + * { 'name': 'curly', 'age': 60 } + * ]; + * + * _.pluck(stooges, 'name'); + * // => ['moe', 'larry', 'curly'] + */ + function pluck(collection, property) { + var result = []; + forEach(collection, function(value) { + result.push(value[property]); + }); + return result; + } + + /** + * Boils down a `collection` to a single value. The initial state of the + * reduction is `accumulator` and each successive step of it should be returned + * by the `callback`. The `callback` is bound to `thisArg` and invoked with 4 + * arguments; for arrays they are (accumulator, value, index|key, collection). + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function} callback The function called per iteration. + * @param {Mixed} [accumulator] Initial value of the accumulator. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Mixed} Returns the accumulated value. + * @example + * + * var sum = _.reduce([1, 2, 3], function(memo, num) { return memo + num; }); + * // => 6 + */ + function reduce(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = createCallback(callback, thisArg); + forEach(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection) + }); + return accumulator; + } + + /** + * The right-associative version of `_.reduce`. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function} callback The function called per iteration. + * @param {Mixed} [accumulator] Initial value of the accumulator. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Mixed} Returns the accumulated value. + * @example + * + * var list = [[0, 1], [2, 3], [4, 5]]; + * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + function reduceRight(collection, callback, accumulator, thisArg) { + var iteratee = collection, + length = collection ? collection.length : 0, + noaccum = arguments.length < 3; + + if (typeof length != 'number') { + var props = keys(collection); + length = props.length; + } else if (noCharByIndex && isString(collection)) { + iteratee = collection.split(''); + } + forEach(collection, function(value, index, collection) { + index = props ? props[--length] : --length; + accumulator = noaccum + ? (noaccum = false, iteratee[index]) + : callback.call(thisArg, accumulator, iteratee[index], index, collection); + }); + return accumulator; + } + + /** + * The opposite of `_.filter`, this method returns the values of a + * `collection` that `callback` does **not** return truthy for. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that did **not** pass the + * callback check. + * @example + * + * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [1, 3, 5] + */ + function reject(collection, callback, thisArg) { + callback = createCallback(callback, thisArg); + return filter(collection, function(value, index, collection) { + return !callback(value, index, collection); + }); + } + + /** + * Creates an array of shuffled `array` values, using a version of the + * Fisher-Yates shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to shuffle. + * @returns {Array} Returns a new shuffled collection. + * @example + * + * _.shuffle([1, 2, 3, 4, 5, 6]); + * // => [4, 1, 6, 3, 5, 2] + */ + function shuffle(collection) { + var index = -1, + result = Array(collection ? collection.length : 0); + + forEach(collection, function(value) { + var rand = floor(nativeRandom() * (++index + 1)); + result[index] = result[rand]; + result[rand] = value; + }); + return result; + } + + /** + * Gets the size of the `collection` by returning `collection.length` for arrays + * and array-like objects or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to inspect. + * @returns {Number} Returns `collection.length` or number of own enumerable properties. + * @example + * + * _.size([1, 2]); + * // => 2 + * + * _.size({ 'one': 1, 'two': 2, 'three': 3 }); + * // => 3 + * + * _.size('curly'); + * // => 5 + */ + function size(collection) { + var length = collection ? collection.length : 0; + return typeof length == 'number' ? length : keys(collection).length; + } + + /** + * Checks if the `callback` returns a truthy value for **any** element of a + * `collection`. The function returns as soon as it finds passing value, and + * does not iterate over the entire `collection`. The `callback` is bound to + * `thisArg` and invoked with three arguments; (value, index|key, collection). + * + * @static + * @memberOf _ + * @alias any + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Boolean} Returns `true` if any element passes the callback check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false]); + * // => true + */ + function some(collection, callback, thisArg) { + var result; + callback = createCallback(callback, thisArg); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (result = callback(collection[index], index, collection)) { + break; + } + } + } else { + forEach(collection, function(value, index, collection) { + return !(result = callback(value, index, collection)); + }); + } + return !!result; + } + + /** + * Creates an array, stable sorted in ascending order by the results of + * running each element of `collection` through a `callback`. The `callback` + * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection). + * The `callback` argument may also be the name of a property to sort by (e.g. 'length'). + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|String} callback|property The function called per iteration + * or property name to sort by. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of sorted elements. + * @example + * + * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); + * // => [3, 1, 2] + * + * _.sortBy(['larry', 'brendan', 'moe'], 'length'); + * // => ['moe', 'larry', 'brendan'] + */ + function sortBy(collection, callback, thisArg) { + var result = []; + callback = createCallback(callback, thisArg); + forEach(collection, function(value, index, collection) { + result.push({ + 'criteria': callback(value, index, collection), + 'index': index, + 'value': value + }); + }); + + var length = result.length; + result.sort(compareAscending); + while (length--) { + result[length] = result[length].value; + } + return result; + } + + /** + * Converts the `collection`, to an array. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to convert. + * @returns {Array} Returns the new converted array. + * @example + * + * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); + * // => [2, 3, 4] + */ + function toArray(collection) { + if (collection && typeof collection.length == 'number') { + return (noArraySliceOnStrings ? isString(collection) : typeof collection == 'string') + ? collection.split('') + : slice.call(collection); + } + return values(collection); + } + + /** + * Examines each element in a `collection`, returning an array of all elements + * that contain the given `properties`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Object} properties The object of property values to filter by. + * @returns {Array} Returns a new array of elements that contain the given `properties`. + * @example + * + * var stooges = [ + * { 'name': 'moe', 'age': 40 }, + * { 'name': 'larry', 'age': 50 }, + * { 'name': 'curly', 'age': 60 } + * ]; + * + * _.where(stooges, { 'age': 40 }); + * // => [{ 'name': 'moe', 'age': 40 }] + */ + function where(collection, properties) { + var props = []; + forIn(properties, function(value, prop) { + props.push(prop); + }); + return filter(collection, function(object) { + var length = props.length; + while (length--) { + var result = object[props[length]] === properties[props[length]]; + if (!result) { + break; + } + } + return !!result; + }); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array with all falsey values of `array` removed. The values + * `false`, `null`, `0`, `""`, `undefined` and `NaN` are all falsey. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to compact. + * @returns {Array} Returns a new filtered array. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result.push(value); + } + } + return result; + } + + /** + * Creates an array of `array` elements not present in the other arrays + * using strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to process. + * @param {Array} [array1, array2, ...] Arrays to check. + * @returns {Array} Returns a new array of `array` elements not present in the + * other arrays. + * @example + * + * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); + * // => [1, 3, 4] + */ + function difference(array) { + var index = -1, + length = array ? array.length : 0, + flattened = concat.apply(arrayRef, arguments), + contains = cachedContains(flattened, length), + result = []; + + while (++index < length) { + var value = array[index]; + if (!contains(value)) { + result.push(value); + } + } + return result; + } + + /** + * Gets the first element of the `array`. Pass `n` to return the first `n` + * elements of the `array`. + * + * @static + * @memberOf _ + * @alias head, take + * @category Arrays + * @param {Array} array The array to query. + * @param {Number} [n] The number of elements to return. + * @param- {Object} [guard] Internally used to allow this method to work with + * others like `_.map` without using their callback `index` argument for `n`. + * @returns {Mixed} Returns the first element or an array of the first `n` + * elements of `array`. + * @example + * + * _.first([5, 4, 3, 2, 1]); + * // => 5 + */ + function first(array, n, guard) { + if (array) { + return (n == null || guard) ? array[0] : slice.call(array, 0, n); + } + } + + /** + * Flattens a nested array (the nesting can be to any depth). If `shallow` is + * truthy, `array` will only be flattened a single level. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to compact. + * @param {Boolean} shallow A flag to indicate only flattening a single level. + * @returns {Array} Returns a new flattened array. + * @example + * + * _.flatten([1, [2], [3, [[4]]]]); + * // => [1, 2, 3, 4]; + * + * _.flatten([1, [2], [3, [[4]]]], true); + * // => [1, 2, 3, [[4]]]; + */ + function flatten(array, shallow) { + var index = -1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + + // recursively flatten arrays (susceptible to call stack limits) + if (isArray(value)) { + push.apply(result, shallow ? value : flatten(value)); + } else { + result.push(value); + } + } + return result; + } + + /** + * Gets the index at which the first occurrence of `value` is found using + * strict equality for comparisons, i.e. `===`. If the `array` is already + * sorted, passing `true` for `fromIndex` will run a faster binary search. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Mixed} value The value to search for. + * @param {Boolean|Number} [fromIndex=0] The index to search from or `true` to + * perform a binary search on a sorted `array`. + * @returns {Number} Returns the index of the matched value or `-1`. + * @example + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2); + * // => 1 + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 4 + * + * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + var index = -1, + length = array ? array.length : 0; + + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0) - 1; + } else if (fromIndex) { + index = sortedIndex(array, value); + return array[index] === value ? index : -1; + } + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Gets all but the last element of `array`. Pass `n` to exclude the last `n` + * elements from the result. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Number} [n=1] The number of elements to exclude. + * @param- {Object} [guard] Internally used to allow this method to work with + * others like `_.map` without using their callback `index` argument for `n`. + * @returns {Array} Returns all but the last element or `n` elements of `array`. + * @example + * + * _.initial([3, 2, 1]); + * // => [3, 2] + */ + function initial(array, n, guard) { + return array + ? slice.call(array, 0, -((n == null || guard) ? 1 : n)) + : []; + } + + /** + * Computes the intersection of all the passed-in arrays using strict equality + * for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} [array1, array2, ...] Arrays to process. + * @returns {Array} Returns a new array of unique elements, in order, that are + * present in **all** of the arrays. + * @example + * + * _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]); + * // => [1, 2] + */ + function intersection(array) { + var args = arguments, + argsLength = args.length, + cache = {}, + result = []; + + forEach(array, function(value) { + if (indexOf(result, value) < 0) { + var length = argsLength; + while (--length) { + if (!(cache[length] || (cache[length] = cachedContains(args[length])))(value)) { + return; + } + } + result.push(value); + } + }); + return result; + } + + /** + * Gets the last element of the `array`. Pass `n` to return the last `n` + * elements of the `array`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Number} [n] The number of elements to return. + * @param- {Object} [guard] Internally used to allow this method to work with + * others like `_.map` without using their callback `index` argument for `n`. + * @returns {Mixed} Returns the last element or an array of the last `n` + * elements of `array`. + * @example + * + * _.last([3, 2, 1]); + * // => 1 + */ + function last(array, n, guard) { + if (array) { + var length = array.length; + return (n == null || guard) ? array[length - 1] : slice.call(array, -n || length); + } + } + + /** + * Gets the index at which the last occurrence of `value` is found using strict + * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used + * as the offset from the end of the collection. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Mixed} value The value to search for. + * @param {Number} [fromIndex=array.length-1] The index to search from. + * @returns {Number} Returns the index of the matched value or `-1`. + * @example + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); + * // => 4 + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 1 + */ + function lastIndexOf(array, value, fromIndex) { + var index = array ? array.length : 0; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Creates an object composed from arrays of `keys` and `values`. Pass either + * a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`, or + * two arrays, one of `keys` and one of corresponding `values`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} keys The array of keys. + * @param {Array} [values=[]] The array of values. + * @returns {Object} Returns an object composed of the given keys and + * corresponding values. + * @example + * + * _.object(['moe', 'larry', 'curly'], [30, 40, 50]); + * // => { 'moe': 30, 'larry': 40, 'curly': 50 } + */ + function object(keys, values) { + var index = -1, + length = keys ? keys.length : 0, + result = {}; + + while (++index < length) { + var key = keys[index]; + if (values) { + result[key] = values[index]; + } else { + result[key[0]] = key[1]; + } + } + return result; + } + + /** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to but not including `stop`. This method is a port of Python's + * `range()` function. See http://docs.python.org/library/functions.html#range. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Number} [start=0] The start of the range. + * @param {Number} end The end of the range. + * @param {Number} [step=1] The value to increment or descrement by. + * @returns {Array} Returns a new range array. + * @example + * + * _.range(10); + * // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + * + * _.range(1, 11); + * // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + * + * _.range(0, 30, 5); + * // => [0, 5, 10, 15, 20, 25] + * + * _.range(0, -10, -1); + * // => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9] + * + * _.range(0); + * // => [] + */ + function range(start, end, step) { + start = +start || 0; + step = +step || 1; + + if (end == null) { + end = start; + start = 0; + } + // use `Array(length)` so V8 will avoid the slower "dictionary" mode + // http://www.youtube.com/watch?v=XAqIpGU8ZZk#t=16m27s + var index = -1, + length = nativeMax(0, ceil((end - start) / step)), + result = Array(length); + + while (++index < length) { + result[index] = start; + start += step; + } + return result; + } + + /** + * The opposite of `_.initial`, this method gets all but the first value of + * `array`. Pass `n` to exclude the first `n` values from the result. + * + * @static + * @memberOf _ + * @alias drop, tail + * @category Arrays + * @param {Array} array The array to query. + * @param {Number} [n=1] The number of elements to exclude. + * @param- {Object} [guard] Internally used to allow this method to work with + * others like `_.map` without using their callback `index` argument for `n`. + * @returns {Array} Returns all but the first value or `n` values of `array`. + * @example + * + * _.rest([3, 2, 1]); + * // => [2, 1] + */ + function rest(array, n, guard) { + return array + ? slice.call(array, (n == null || guard) ? 1 : n) + : []; + } + + /** + * Uses a binary search to determine the smallest index at which the `value` + * should be inserted into `array` in order to maintain the sort order of the + * sorted `array`. If `callback` is passed, it will be executed for `value` and + * each element in `array` to compute their sort ranking. The `callback` is + * bound to `thisArg` and invoked with one argument; (value). The `callback` + * argument may also be the name of a property to order by. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to iterate over. + * @param {Mixed} value The value to evaluate. + * @param {Function|String} [callback=identity|property] The function called + * per iteration or property name to order by. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Number} Returns the index at which the value should be inserted + * into `array`. + * @example + * + * _.sortedIndex([20, 30, 50], 40); + * // => 2 + * + * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 2 + * + * var dict = { + * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } + * }; + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return dict.wordToNumber[word]; + * }); + * // => 2 + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return this.wordToNumber[word]; + * }, dict); + * // => 2 + */ + function sortedIndex(array, value, callback, thisArg) { + var low = 0, + high = array ? array.length : low; + + // explicitly reference `identity` for better engine inlining + callback = callback ? createCallback(callback, thisArg) : identity; + value = callback(value); + while (low < high) { + var mid = (low + high) >>> 1; + callback(array[mid]) < value + ? low = mid + 1 + : high = mid; + } + return low; + } + + /** + * Computes the union of the passed-in arrays using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} [array1, array2, ...] Arrays to process. + * @returns {Array} Returns a new array of unique values, in order, that are + * present in one or more of the arrays. + * @example + * + * _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]); + * // => [1, 2, 3, 101, 10] + */ + function union() { + return uniq(concat.apply(arrayRef, arguments)); + } + + /** + * Creates a duplicate-value-free version of the `array` using strict equality + * for comparisons, i.e. `===`. If the `array` is already sorted, passing `true` + * for `isSorted` will run a faster algorithm. If `callback` is passed, each + * element of `array` is passed through a callback` before uniqueness is computed. + * The `callback` is bound to `thisArg` and invoked with three arguments; (value, index, array). + * + * @static + * @memberOf _ + * @alias unique + * @category Arrays + * @param {Array} array The array to process. + * @param {Boolean} [isSorted=false] A flag to indicate that the `array` is already sorted. + * @param {Function} [callback=identity] The function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a duplicate-value-free array. + * @example + * + * _.uniq([1, 2, 1, 3, 1]); + * // => [1, 2, 3] + * + * _.uniq([1, 1, 2, 2, 3], true); + * // => [1, 2, 3] + * + * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return Math.floor(num); }); + * // => [1, 2, 3] + * + * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return this.floor(num); }, Math); + * // => [1, 2, 3] + */ + function uniq(array, isSorted, callback, thisArg) { + var index = -1, + length = array ? array.length : 0, + result = [], + seen = result; + + // juggle arguments + if (typeof isSorted == 'function') { + thisArg = callback; + callback = isSorted; + isSorted = false; + } + // init value cache for large arrays + var isLarge = !isSorted && length > 74; + if (isLarge) { + var cache = {}; + } + if (callback) { + seen = []; + callback = createCallback(callback, thisArg); + } + while (++index < length) { + var value = array[index], + computed = callback ? callback(value, index, array) : value; + + if (isLarge) { + // manually coerce `computed` to a string because `hasOwnProperty`, in + // some older versions of Firefox, coerces objects incorrectly + seen = hasOwnProperty.call(cache, computed + '') ? cache[computed] : (cache[computed] = []); + } + if (isSorted + ? !index || seen[seen.length - 1] !== computed + : indexOf(seen, computed) < 0 + ) { + if (callback || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * Creates an array with all occurrences of the passed values removed using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to filter. + * @param {Mixed} [value1, value2, ...] Values to remove. + * @returns {Array} Returns a new filtered array. + * @example + * + * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); + * // => [2, 3, 4] + */ + function without(array) { + var index = -1, + length = array ? array.length : 0, + contains = cachedContains(arguments, 1, 20), + result = []; + + while (++index < length) { + var value = array[index]; + if (!contains(value)) { + result.push(value); + } + } + return result; + } + + /** + * Groups the elements of each array at their corresponding indexes. Useful for + * separate data sources that are coordinated through matching array indexes. + * For a matrix of nested arrays, `_.zip.apply(...)` can transpose the matrix + * in a similar fashion. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} [array1, array2, ...] Arrays to process. + * @returns {Array} Returns a new array of grouped elements. + * @example + * + * _.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]); + * // => [['moe', 30, true], ['larry', 40, false], ['curly', 50, false]] + */ + function zip(array) { + var index = -1, + length = array ? max(pluck(arguments, 'length')) : 0, + result = Array(length); + + while (++index < length) { + result[index] = pluck(arguments, index); + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that is restricted to executing `func` only after it is + * called `n` times. The `func` is executed with the `this` binding of the + * created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Number} n The number of times the function must be called before + * it is executed. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var renderNotes = _.after(notes.length, render); + * _.forEach(notes, function(note) { + * note.asyncSave({ 'success': renderNotes }); + * }); + * // `renderNotes` is run once, after all notes have saved + */ + function after(n, func) { + if (n < 1) { + return func(); + } + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that, when called, invokes `func` with the `this` + * binding of `thisArg` and prepends any additional `bind` arguments to those + * passed to the bound function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to bind. + * @param {Mixed} [thisArg] The `this` binding of `func`. + * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var func = function(greeting) { + * return greeting + ' ' + this.name; + * }; + * + * func = _.bind(func, { 'name': 'moe' }, 'hi'); + * func(); + * // => 'hi moe' + */ + function bind(func, thisArg) { + // use `Function#bind` if it exists and is fast + // (in V8 `Function#bind` is slower except when partially applied) + return isBindFast || (nativeBind && arguments.length > 2) + ? nativeBind.call.apply(nativeBind, arguments) + : createBound(func, thisArg, slice.call(arguments, 2)); + } + + /** + * Binds methods on `object` to `object`, overwriting the existing method. + * If no method names are provided, all the function properties of `object` + * will be bound. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object to bind and assign the bound methods to. + * @param {String} [methodName1, methodName2, ...] Method names on the object to bind. + * @returns {Object} Returns `object`. + * @example + * + * var buttonView = { + * 'label': 'lodash', + * 'onClick': function() { alert('clicked: ' + this.label); } + * }; + * + * _.bindAll(buttonView); + * jQuery('#lodash_button').on('click', buttonView.onClick); + * // => When the button is clicked, `this.label` will have the correct value + */ + function bindAll(object) { + var funcs = arguments, + index = funcs.length > 1 ? 0 : (funcs = functions(object), -1), + length = funcs.length; + + while (++index < length) { + var key = funcs[index]; + object[key] = bind(object[key], object); + } + return object; + } + + /** + * Creates a function that is the composition of the passed functions, + * where each function consumes the return value of the function that follows. + * In math terms, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. + * Each function is executed with the `this` binding of the composed function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} [func1, func2, ...] Functions to compose. + * @returns {Function} Returns the new composed function. + * @example + * + * var greet = function(name) { return 'hi: ' + name; }; + * var exclaim = function(statement) { return statement + '!'; }; + * var welcome = _.compose(exclaim, greet); + * welcome('moe'); + * // => 'hi: moe!' + */ + function compose() { + var funcs = arguments; + return function() { + var args = arguments, + length = funcs.length; + + while (length--) { + args = [funcs[length].apply(this, args)]; + } + return args[0]; + }; + } + + /** + * Creates a function that will delay the execution of `func` until after + * `wait` milliseconds have elapsed since the last time it was invoked. Pass + * `true` for `immediate` to cause debounce to invoke `func` on the leading, + * instead of the trailing, edge of the `wait` timeout. Subsequent calls to + * the debounced function will return the result of the last `func` call. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to debounce. + * @param {Number} wait The number of milliseconds to delay. + * @param {Boolean} immediate A flag to indicate execution is on the leading + * edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * var lazyLayout = _.debounce(calculateLayout, 300); + * jQuery(window).on('resize', lazyLayout); + */ + function debounce(func, wait, immediate) { + var args, + result, + thisArg, + timeoutId; + + function delayed() { + timeoutId = null; + if (!immediate) { + result = func.apply(thisArg, args); + } + } + return function() { + var isImmediate = immediate && !timeoutId; + args = arguments; + thisArg = this; + + clearTimeout(timeoutId); + timeoutId = setTimeout(delayed, wait); + + if (isImmediate) { + result = func.apply(thisArg, args); + } + return result; + }; + } + + /** + * Executes the `func` function after `wait` milliseconds. Additional arguments + * will be passed to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to delay. + * @param {Number} wait The number of milliseconds to delay execution. + * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with. + * @returns {Number} Returns the `setTimeout` timeout id. + * @example + * + * var log = _.bind(console.log, console); + * _.delay(log, 1000, 'logged later'); + * // => 'logged later' (Appears after one second.) + */ + function delay(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * Defers executing the `func` function until the current call stack has cleared. + * Additional arguments will be passed to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to defer. + * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with. + * @returns {Number} Returns the `setTimeout` timeout id. + * @example + * + * _.defer(function() { alert('deferred'); }); + * // returns from the function before `alert` is called + */ + function defer(func) { + var args = slice.call(arguments, 1); + return setTimeout(function() { func.apply(undefined, args); }, 1); + } + + /** + * Creates a function that, when called, invokes `object[methodName]` and + * prepends any additional `lateBind` arguments to those passed to the bound + * function. This method differs from `_.bind` by allowing bound functions to + * reference methods that will be redefined or don't yet exist. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object the method belongs to. + * @param {String} methodName The method name. + * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'name': 'moe', + * 'greet': function(greeting) { + * return greeting + ' ' + this.name; + * } + * }; + * + * var func = _.lateBind(object, 'greet', 'hi'); + * func(); + * // => 'hi moe' + * + * object.greet = function(greeting) { + * return greeting + ', ' + this.name + '!'; + * }; + * + * func(); + * // => 'hi, moe!' + */ + function lateBind(object, methodName) { + return createBound(methodName, object, slice.call(arguments, 2)); + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * passed, it will be used to determine the cache key for storing the result + * based on the arguments passed to the memoized function. By default, the first + * argument passed to the memoized function is used as the cache key. The `func` + * is executed with the `this` binding of the memoized function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] A function used to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var fibonacci = _.memoize(function(n) { + * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); + * }); + */ + function memoize(func, resolver) { + var cache = {}; + return function() { + var key = resolver ? resolver.apply(this, arguments) : arguments[0]; + return hasOwnProperty.call(cache, key) + ? cache[key] + : (cache[key] = func.apply(this, arguments)); + }; + } + + /** + * Creates a function that is restricted to execute `func` once. Repeat calls to + * the function will return the value of the first call. The `func` is executed + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // Application is only created once. + */ + function once(func) { + var result, + ran = false; + + return function() { + if (ran) { + return result; + } + ran = true; + result = func.apply(this, arguments); + + // clear the `func` variable so the function may be garbage collected + func = null; + return result; + }; + } + + /** + * Creates a function that, when called, invokes `func` with any additional + * `partial` arguments prepended to those passed to the new function. This + * method is similar to `bind`, except it does **not** alter the `this` binding. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { return greeting + ': ' + name; }; + * var hi = _.partial(greet, 'hi'); + * hi('moe'); + * // => 'hi: moe' + */ + function partial(func) { + return createBound(func, slice.call(arguments, 1)); + } + + /** + * Creates a function that, when executed, will only call the `func` + * function at most once per every `wait` milliseconds. If the throttled + * function is invoked more than once during the `wait` timeout, `func` will + * also be called on the trailing edge of the timeout. Subsequent calls to the + * throttled function will return the result of the last `func` call. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to throttle. + * @param {Number} wait The number of milliseconds to throttle executions to. + * @returns {Function} Returns the new throttled function. + * @example + * + * var throttled = _.throttle(updatePosition, 100); + * jQuery(window).on('scroll', throttled); + */ + function throttle(func, wait) { + var args, + result, + thisArg, + timeoutId, + lastCalled = 0; + + function trailingCall() { + lastCalled = new Date; + timeoutId = null; + result = func.apply(thisArg, args); + } + return function() { + var now = new Date, + remaining = wait - (now - lastCalled); + + args = arguments; + thisArg = this; + + if (remaining <= 0) { + clearTimeout(timeoutId); + lastCalled = now; + result = func.apply(thisArg, args); + } + else if (!timeoutId) { + timeoutId = setTimeout(trailingCall, remaining); + } + return result; + }; + } + + /** + * Creates a function that passes `value` to the `wrapper` function as its + * first argument. Additional arguments passed to the function are appended + * to those passed to the `wrapper` function. The `wrapper` is executed with + * the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Mixed} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var hello = function(name) { return 'hello ' + name; }; + * hello = _.wrap(hello, function(func) { + * return 'before, ' + func('moe') + ', after'; + * }); + * hello(); + * // => 'before, hello moe, after' + */ + function wrap(value, wrapper) { + return function() { + var args = [value]; + push.apply(args, arguments); + return wrapper.apply(this, args); + }; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their + * corresponding HTML entities. + * + * @static + * @memberOf _ + * @category Utilities + * @param {String} string The string to escape. + * @returns {String} Returns the escaped string. + * @example + * + * _.escape('Moe, Larry & Curly'); + * // => "Moe, Larry & Curly" + */ + function escape(string) { + return string == null ? '' : (string + '').replace(reUnescapedHtml, escapeHtmlChar); + } + + /** + * This function returns the first argument passed to it. + * + * Note: It is used throughout Lo-Dash as a default callback. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Mixed} value Any value. + * @returns {Mixed} Returns `value`. + * @example + * + * var moe = { 'name': 'moe' }; + * moe === _.identity(moe); + * // => true + */ + function identity(value) { + return value; + } + + /** + * Adds functions properties of `object` to the `lodash` function and chainable + * wrapper. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} object The object of function properties to add to `lodash`. + * @example + * + * _.mixin({ + * 'capitalize': function(string) { + * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); + * } + * }); + * + * _.capitalize('larry'); + * // => 'Larry' + * + * _('curly').capitalize(); + * // => 'Curly' + */ + function mixin(object) { + forEach(functions(object), function(methodName) { + var func = lodash[methodName] = object[methodName]; + + lodash.prototype[methodName] = function() { + var args = [this.__wrapped__]; + push.apply(args, arguments); + + var result = func.apply(lodash, args); + if (this.__chain__) { + result = new lodash(result); + result.__chain__ = true; + } + return result; + }; + }); + } + + /** + * Reverts the '_' variable to its previous value and returns a reference to + * the `lodash` function. + * + * @static + * @memberOf _ + * @category Utilities + * @returns {Function} Returns the `lodash` function. + * @example + * + * var lodash = _.noConflict(); + */ + function noConflict() { + window._ = oldDash; + return this; + } + + /** + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is passed, a number between `0` and the given number will be returned. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Number} [min=0] The minimum possible value. + * @param {Number} [max=1] The maximum possible value. + * @returns {Number} Returns a random number. + * @example + * + * _.random(0, 5); + * // => a number between 1 and 5 + * + * _.random(5); + * // => also a number between 1 and 5 + */ + function random(min, max) { + if (min == null && max == null) { + max = 1; + } + min = +min || 0; + if (max == null) { + max = min; + min = 0; + } + return min + floor(nativeRandom() * ((+max || 0) - min + 1)); + } + + /** + * Resolves the value of `property` on `object`. If `property` is a function + * it will be invoked and its result returned, else the property value is + * returned. If `object` is falsey, then `null` is returned. + * + * @deprecated + * @static + * @memberOf _ + * @category Utilities + * @param {Object} object The object to inspect. + * @param {String} property The property to get the value of. + * @returns {Mixed} Returns the resolved value. + * @example + * + * var object = { + * 'cheese': 'crumpets', + * 'stuff': function() { + * return 'nonsense'; + * } + * }; + * + * _.result(object, 'cheese'); + * // => 'crumpets' + * + * _.result(object, 'stuff'); + * // => 'nonsense' + */ + function result(object, property) { + // based on Backbone's private `getValue` function + // https://github.com/documentcloud/backbone/blob/0.9.2/backbone.js#L1419-1424 + var value = object ? object[property] : null; + return isFunction(value) ? object[property]() : value; + } + + /** + * A micro-templating method that handles arbitrary delimiters, preserves + * whitespace, and correctly escapes quotes within interpolated code. + * + * Note: In the development build `_.template` utilizes sourceURLs for easier + * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl + * + * Note: Lo-Dash may be used in Chrome extensions by either creating a `lodash csp` + * build and avoiding `_.template` use, or loading Lo-Dash in a sandboxed page. + * See http://developer.chrome.com/trunk/extensions/sandboxingEval.html + * + * @static + * @memberOf _ + * @category Utilities + * @param {String} text The template text. + * @param {Obect} data The data object used to populate the text. + * @param {Object} options The options object. + * escape - The "escape" delimiter regexp. + * evaluate - The "evaluate" delimiter regexp. + * interpolate - The "interpolate" delimiter regexp. + * sourceURL - The sourceURL of the template's compiled source. + * variable - The data object variable name. + * + * @returns {Function|String} Returns a compiled function when no `data` object + * is given, else it returns the interpolated text. + * @example + * + * // using a compiled template + * var compiled = _.template('hello <%= name %>'); + * compiled({ 'name': 'moe' }); + * // => 'hello moe' + * + * var list = '<% _.forEach(people, function(name) { %>
        1. <%= name %>
        2. <% }); %>'; + * _.template(list, { 'people': ['moe', 'larry', 'curly'] }); + * // => '
        3. moe
        4. larry
        5. curly
        6. ' + * + * // using the "escape" delimiter to escape HTML in data property values + * _.template('<%- value %>', { 'value': ' + diff --git a/node_modules/sax/README.md b/node_modules/sax/README.md new file mode 100644 index 0000000..c965242 --- /dev/null +++ b/node_modules/sax/README.md @@ -0,0 +1,216 @@ +# sax js + +A sax-style parser for XML and HTML. + +Designed with [node](http://nodejs.org/) in mind, but should work fine in +the browser or other CommonJS implementations. + +## What This Is + +* A very simple tool to parse through an XML string. +* A stepping stone to a streaming HTML parser. +* A handy way to deal with RSS and other mostly-ok-but-kinda-broken XML + docs. + +## What This Is (probably) Not + +* An HTML Parser - That's a fine goal, but this isn't it. It's just + XML. +* A DOM Builder - You can use it to build an object model out of XML, + but it doesn't do that out of the box. +* XSLT - No DOM = no querying. +* 100% Compliant with (some other SAX implementation) - Most SAX + implementations are in Java and do a lot more than this does. +* An XML Validator - It does a little validation when in strict mode, but + not much. +* A Schema-Aware XSD Thing - Schemas are an exercise in fetishistic + masochism. +* A DTD-aware Thing - Fetching DTDs is a much bigger job. + +## Regarding `Hello, world!').close(); + + // stream usage + // takes the same options as the parser + var saxStream = require("sax").createStream(strict, options) + saxStream.on("error", function (e) { + // unhandled errors will throw, since this is a proper node + // event emitter. + console.error("error!", e) + // clear the error + this._parser.error = null + this._parser.resume() + }) + saxStream.on("opentag", function (node) { + // same object as above + }) + // pipe is supported, and it's readable/writable + // same chunks coming in also go out. + fs.createReadStream("file.xml") + .pipe(saxStream) + .pipe(fs.createWriteStream("file-copy.xml")) + + + +## Arguments + +Pass the following arguments to the parser function. All are optional. + +`strict` - Boolean. Whether or not to be a jerk. Default: `false`. + +`opt` - Object bag of settings regarding string formatting. All default to `false`. + +Settings supported: + +* `trim` - Boolean. Whether or not to trim text and comment nodes. +* `normalize` - Boolean. If true, then turn any whitespace into a single + space. +* `lowercase` - Boolean. If true, then lowercase tag names and attribute names + in loose mode, rather than uppercasing them. +* `xmlns` - Boolean. If true, then namespaces are supported. +* `position` - Boolean. If false, then don't track line/col/position. + +## Methods + +`write` - Write bytes onto the stream. You don't have to do this all at +once. You can keep writing as much as you want. + +`close` - Close the stream. Once closed, no more data may be written until +it is done processing the buffer, which is signaled by the `end` event. + +`resume` - To gracefully handle errors, assign a listener to the `error` +event. Then, when the error is taken care of, you can call `resume` to +continue parsing. Otherwise, the parser will not continue while in an error +state. + +## Members + +At all times, the parser object will have the following members: + +`line`, `column`, `position` - Indications of the position in the XML +document where the parser currently is looking. + +`startTagPosition` - Indicates the position where the current tag starts. + +`closed` - Boolean indicating whether or not the parser can be written to. +If it's `true`, then wait for the `ready` event to write again. + +`strict` - Boolean indicating whether or not the parser is a jerk. + +`opt` - Any options passed into the constructor. + +`tag` - The current tag being dealt with. + +And a bunch of other stuff that you probably shouldn't touch. + +## Events + +All events emit with a single argument. To listen to an event, assign a +function to `on`. Functions get executed in the this-context of +the parser object. The list of supported events are also in the exported +`EVENTS` array. + +When using the stream interface, assign handlers using the EventEmitter +`on` function in the normal fashion. + +`error` - Indication that something bad happened. The error will be hanging +out on `parser.error`, and must be deleted before parsing can continue. By +listening to this event, you can keep an eye on that kind of stuff. Note: +this happens *much* more in strict mode. Argument: instance of `Error`. + +`text` - Text node. Argument: string of text. + +`doctype` - The ``. Argument: +object with `name` and `body` members. Attributes are not parsed, as +processing instructions have implementation dependent semantics. + +`sgmldeclaration` - Random SGML declarations. Stuff like `` +would trigger this kind of event. This is a weird thing to support, so it +might go away at some point. SAX isn't intended to be used to parse SGML, +after all. + +`opentag` - An opening tag. Argument: object with `name` and `attributes`. +In non-strict mode, tag names are uppercased, unless the `lowercase` +option is set. If the `xmlns` option is set, then it will contain +namespace binding information on the `ns` member, and will have a +`local`, `prefix`, and `uri` member. + +`closetag` - A closing tag. In loose mode, tags are auto-closed if their +parent closes. In strict mode, well-formedness is enforced. Note that +self-closing tags will have `closeTag` emitted immediately after `openTag`. +Argument: tag name. + +`attribute` - An attribute node. Argument: object with `name` and `value`. +In non-strict mode, attribute names are uppercased, unless the `lowercase` +option is set. If the `xmlns` option is set, it will also contains namespace +information. + +`comment` - A comment node. Argument: the string of the comment. + +`opencdata` - The opening tag of a ``) of a `` tags trigger a `"script"` +event, and their contents are not checked for special xml characters. +If you pass `noscript: true`, then this behavior is suppressed. + +## Reporting Problems + +It's best to write a failing test if you find an issue. I will always +accept pull requests with failing tests if they demonstrate intended +behavior, but it is very hard to figure out what issue you're describing +without a test. Writing a test is also the best way for you yourself +to figure out if you really understand the issue you think you have with +sax-js. diff --git a/node_modules/sax/component.json b/node_modules/sax/component.json new file mode 100644 index 0000000..96b5d73 --- /dev/null +++ b/node_modules/sax/component.json @@ -0,0 +1,12 @@ +{ + "name": "sax", + "description": "An evented streaming XML parser in JavaScript", + "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "version": "0.5.2", + "main": "lib/sax.js", + "license": "BSD", + "scripts": [ + "lib/sax.js" + ], + "repository": "git://github.com/isaacs/sax-js.git" +} diff --git a/node_modules/sax/examples/big-not-pretty.xml b/node_modules/sax/examples/big-not-pretty.xml new file mode 100644 index 0000000..fb5265d --- /dev/null +++ b/node_modules/sax/examples/big-not-pretty.xml @@ -0,0 +1,8002 @@ + + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + diff --git a/node_modules/sax/examples/example.js b/node_modules/sax/examples/example.js new file mode 100644 index 0000000..7b0246e --- /dev/null +++ b/node_modules/sax/examples/example.js @@ -0,0 +1,29 @@ + +var fs = require("fs"), + util = require("util"), + path = require("path"), + xml = fs.readFileSync(path.join(__dirname, "test.xml"), "utf8"), + sax = require("../lib/sax"), + strict = sax.parser(true), + loose = sax.parser(false, {trim:true}), + inspector = function (ev) { return function (data) { + console.error("%s %s %j", this.line+":"+this.column, ev, data); + }}; + +sax.EVENTS.forEach(function (ev) { + loose["on"+ev] = inspector(ev); +}); +loose.onend = function () { + console.error("end"); + console.error(loose); +}; + +// do this in random bits at a time to verify that it works. +(function () { + if (xml) { + var c = Math.ceil(Math.random() * 1000) + loose.write(xml.substr(0,c)); + xml = xml.substr(c); + process.nextTick(arguments.callee); + } else loose.close(); +})(); diff --git a/node_modules/sax/examples/get-products.js b/node_modules/sax/examples/get-products.js new file mode 100644 index 0000000..9e8d74a --- /dev/null +++ b/node_modules/sax/examples/get-products.js @@ -0,0 +1,58 @@ +// pull out /GeneralSearchResponse/categories/category/items/product tags +// the rest we don't care about. + +var sax = require("../lib/sax.js") +var fs = require("fs") +var path = require("path") +var xmlFile = path.resolve(__dirname, "shopping.xml") +var util = require("util") +var http = require("http") + +fs.readFile(xmlFile, function (er, d) { + http.createServer(function (req, res) { + if (er) throw er + var xmlstr = d.toString("utf8") + + var parser = sax.parser(true) + var products = [] + var product = null + var currentTag = null + + parser.onclosetag = function (tagName) { + if (tagName === "product") { + products.push(product) + currentTag = product = null + return + } + if (currentTag && currentTag.parent) { + var p = currentTag.parent + delete currentTag.parent + currentTag = p + } + } + + parser.onopentag = function (tag) { + if (tag.name !== "product" && !product) return + if (tag.name === "product") { + product = tag + } + tag.parent = currentTag + tag.children = [] + tag.parent && tag.parent.children.push(tag) + currentTag = tag + } + + parser.ontext = function (text) { + if (currentTag) currentTag.children.push(text) + } + + parser.onend = function () { + var out = util.inspect(products, false, 3, true) + res.writeHead(200, {"content-type":"application/json"}) + res.end("{\"ok\":true}") + // res.end(JSON.stringify(products)) + } + + parser.write(xmlstr).end() + }).listen(1337) +}) diff --git a/node_modules/sax/examples/hello-world.js b/node_modules/sax/examples/hello-world.js new file mode 100644 index 0000000..cbfa518 --- /dev/null +++ b/node_modules/sax/examples/hello-world.js @@ -0,0 +1,4 @@ +require("http").createServer(function (req, res) { + res.writeHead(200, {"content-type":"application/json"}) + res.end(JSON.stringify({ok: true})) +}).listen(1337) diff --git a/node_modules/sax/examples/not-pretty.xml b/node_modules/sax/examples/not-pretty.xml new file mode 100644 index 0000000..9592852 --- /dev/null +++ b/node_modules/sax/examples/not-pretty.xml @@ -0,0 +1,8 @@ + + something blerm a bit down here diff --git a/node_modules/sax/examples/pretty-print.js b/node_modules/sax/examples/pretty-print.js new file mode 100644 index 0000000..cd6aca9 --- /dev/null +++ b/node_modules/sax/examples/pretty-print.js @@ -0,0 +1,74 @@ +var sax = require("../lib/sax") + , printer = sax.createStream(false, {lowercasetags:true, trim:true}) + , fs = require("fs") + +function entity (str) { + return str.replace('"', '"') +} + +printer.tabstop = 2 +printer.level = 0 +printer.indent = function () { + print("\n") + for (var i = this.level; i > 0; i --) { + for (var j = this.tabstop; j > 0; j --) { + print(" ") + } + } +} +printer.on("opentag", function (tag) { + this.indent() + this.level ++ + print("<"+tag.name) + for (var i in tag.attributes) { + print(" "+i+"=\""+entity(tag.attributes[i])+"\"") + } + print(">") +}) + +printer.on("text", ontext) +printer.on("doctype", ontext) +function ontext (text) { + this.indent() + print(text) +} + +printer.on("closetag", function (tag) { + this.level -- + this.indent() + print("") +}) + +printer.on("cdata", function (data) { + this.indent() + print("") +}) + +printer.on("comment", function (comment) { + this.indent() + print("") +}) + +printer.on("error", function (error) { + console.error(error) + throw error +}) + +if (!process.argv[2]) { + throw new Error("Please provide an xml file to prettify\n"+ + "TODO: read from stdin or take a file") +} +var xmlfile = require("path").join(process.cwd(), process.argv[2]) +var fstr = fs.createReadStream(xmlfile, { encoding: "utf8" }) + +function print (c) { + if (!process.stdout.write(c)) { + fstr.pause() + } +} + +process.stdout.on("drain", function () { + fstr.resume() +}) + +fstr.pipe(printer) diff --git a/node_modules/sax/examples/shopping.xml b/node_modules/sax/examples/shopping.xml new file mode 100644 index 0000000..223c6c6 --- /dev/null +++ b/node_modules/sax/examples/shopping.xml @@ -0,0 +1,2 @@ + +sandbox3.1 r31.Kadu4DC.phase357782011.10.06 15:37:23 PSTp2.a121bc2aaf029435dce62011-10-21T18:38:45.982-04:00P0Y0M0DT0H0M0.169S1112You are currently using the SDC API sandbox environment! No clicks to merchant URLs from this response will be paid. Please change the host of your API requests to 'publisher.api.shopping.com' when you have finished development and testinghttp://statTest.dealtime.com/pixel/noscript?PV_EvnTyp=APPV&APPV_APITSP=10%2F21%2F11_06%3A38%3A45_PM&APPV_DSPRQSID=p2.a121bc2aaf029435dce6&APPV_IMGURL=http://img.shopping.com/sc/glb/sdc_logo_106x19.gif&APPV_LI_LNKINID=7000610&APPV_LI_SBMKYW=nikon&APPV_MTCTYP=1000&APPV_PRTID=2002&APPV_BrnID=14804http://www.shopping.com/digital-cameras/productsDigital CamerasDigital CamerasElectronicshttp://www.shopping.com/xCH-electronics-nikon~linkin_id-7000610?oq=nikonCameras and Photographyhttp://www.shopping.com/xCH-cameras_and_photography-nikon~linkin_id-7000610?oq=nikonDigital Camerashttp://www.shopping.com/digital-cameras/nikon/products?oq=nikon&linkin_id=7000610nikonnikonDigital Camerashttp://www.shopping.com/digital-cameras/nikon/products?oq=nikon&linkin_id=7000610Nikon D3100 Digital Camera14.2 Megapixel, SLR Camera, 3 in. LCD Screen, With High Definition Video, Weight: 1 lb.The Nikon D3100 digital SLR camera speaks to the growing ranks of enthusiastic D-SLR users and aspiring photographers by providing an easy-to-use and affordable entrance to the world of Nikon D-SLR’s. The 14.2-megapixel D3100 has powerful features, such as the enhanced Guide Mode that makes it easy to unleash creative potential and capture memories with still images and full HD video. Like having a personal photo tutor at your fingertips, this unique feature provides a simple graphical interface on the camera’s LCD that guides users by suggesting and/or adjusting camera settings to achieve the desired end result images. The D3100 is also the world’s first D-SLR to introduce full time auto focus (AF) in Live View and D-Movie mode to effortlessly achieve the critical focus needed when shooting Full HD 1080p video.http://di1.shopping.com/images/pi/93/bc/04/101677489-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=1http://di1.shopping.com/images/pi/93/bc/04/101677489-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=1http://di1.shopping.com/images/pi/93/bc/04/101677489-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=1http://di1.shopping.com/images/pi/93/bc/04/101677489-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=1http://di1.shopping.com/images/pi/93/bc/04/101677489-606x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=194.56http://img.shopping.com/sc/pr/sdc_stars_sm_4.5.gifhttp://www.shopping.com/Nikon-D3100/reviews~linkin_id-7000610429.001360.00http://www.shopping.com/Nikon-D3100/prices~linkin_id-7000610http://www.shopping.com/Nikon-D3100/info~linkin_id-7000610Nikon D3100 Digital SLR Camera with 18-55mm NIKKOR VR LensThe Nikon D3100 Digital SLR Camera is an affordable compact and lightweight photographic power-house. It features the all-purpose 18-55mm VR lens a high-resolution 14.2 MP CMOS sensor along with a feature set that's comprehensive yet easy to navigate - the intuitive onboard learn-as-you grow guide mode allows the photographer to understand what the 3100 can do quickly and easily. Capture beautiful pictures and amazing Full HD 1080p movies with sound and full-time autofocus. Availabilty: In Stock!7185Nikonhttp://di102.shopping.com/images/di/2d/5a/57/36424d5a717a366662532d61554c7767615f67-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di102.shopping.com/images/di/2d/5a/57/36424d5a717a366662532d61554c7767615f67-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di102.shopping.com/images/di/2d/5a/57/36424d5a717a366662532d61554c7767615f67-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di102.shopping.com/images/di/2d/5a/57/36424d5a717a366662532d61554c7767615f67-350x350-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1in-stockFree Shipping with Any Purchase!529.000.00799.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=647&BEFID=7185&aon=%5E1&MerchantID=475674&crawler_id=475674&dealId=-ZW6BMZqz6fbS-aULwga_g%3D%3D&url=http%3A%2F%2Fwww.fumfie.com%2Fproduct%2F343.5%2Fshopping-com%3F&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D3100+Digital+SLR+Camera+with+18-55mm+NIKKOR+VR+Lens&dlprc=529.0&crn=&istrsmrc=1&isathrsl=0&AR=1&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=101677489&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=1&cid=&semid1=&semid2=&IsLps=0&CC=1&SL=1&FS=1&code=&acode=658&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=FumFiehttp://img.shopping.com/cctool/merch_logos/475674.gif866 666 91985604.27http://img.shopping.com/sc/mr/sdc_checks_45.gifhttp://www.shopping.com/xMR-store_fumfie~MRD-475674~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUSF343C5Nikon Nikon D3100 14.2MP Digital SLR Camera with 18-55mm f/3.5-5.6 AF-S DX VR, CamerasNikon D3100 14.2MP Digital SLR Camera with 18-55mm f/3.5-5.6 AF-S DX VR7185Nikonhttp://di109.shopping.com/images/di/6d/64/31/65396c443876644f7534464851664a714b6e67-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/6d/64/31/65396c443876644f7534464851664a714b6e67-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/6d/64/31/65396c443876644f7534464851664a714b6e67-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/6d/64/31/65396c443876644f7534464851664a714b6e67-385x352-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2in-stock549.000.00549.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=779&BEFID=7185&aon=%5E1&MerchantID=305814&crawler_id=305814&dealId=md1e9lD8vdOu4FHQfJqKng%3D%3D&url=http%3A%2F%2Fwww.electronics-expo.com%2Findex.php%3Fpage%3Ditem%26id%3DNIKD3100%26source%3DSideCar%26scpid%3D8%26scid%3Dscsho318727%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+Nikon+D3100+14.2MP+Digital+SLR+Camera+with+18-55mm+f%2F3.5-5.6+AF-S+DX+VR%2C+Cameras&dlprc=549.0&crn=&istrsmrc=1&isathrsl=0&AR=9&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=101677489&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=9&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=771&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Electronics Expohttp://img.shopping.com/cctool/merch_logos/305814.gif1-888-707-EXPO3713.90http://img.shopping.com/sc/mr/sdc_checks_4.gifhttp://www.shopping.com/xMR-store_electronics_expo~MRD-305814~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUSNIKD3100Nikon D3100 14.2-Megapixel Digital SLR Camera With 18-55mm Zoom-Nikkor Lens, BlackSplit-second shutter response captures shots other cameras may have missed Helps eliminate the frustration of shutter delay! 14.2-megapixels for enlargements worth framing and hanging. Takes breathtaking 1080p HD movies. ISO sensitivity from 100-1600 for bright or dimly lit settings. 3.0in. color LCD for beautiful, wide-angle framing and viewing. In-camera image editing lets you retouch with no PC. Automatic scene modes include Child, Sports, Night Portrait and more. Accepts SDHC memory cards. Nikon D3100 14.2-Megapixel Digital SLR Camera With 18-55mm Zoom-Nikkor Lens, Black is one of many Digital SLR Cameras available through Office Depot. Made by Nikon.7185Nikonhttp://di109.shopping.com/images/di/79/59/75/61586e4446744359377244556a6b5932616177-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di109.shopping.com/images/di/79/59/75/61586e4446744359377244556a6b5932616177-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di109.shopping.com/images/di/79/59/75/61586e4446744359377244556a6b5932616177-250x250-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3in-stock549.990.00699.99http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=698&BEFID=7185&aon=%5E1&MerchantID=467671&crawler_id=467671&dealId=yYuaXnDFtCY7rDUjkY2aaw%3D%3D&url=http%3A%2F%2Flink.mercent.com%2Fredirect.ashx%3Fmr%3AmerchantID%3DOfficeDepot%26mr%3AtrackingCode%3DCEC9669E-6ABC-E011-9F24-0019B9C043EB%26mr%3AtargetUrl%3Dhttp%3A%2F%2Fwww.officedepot.com%2Fa%2Fproducts%2F486292%2FNikon-D3100-142-Megapixel-Digital-SLR%2F%253fcm_mmc%253dMercent-_-Shopping-_-Cameras_and_Camcorders-_-486292&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D3100+14.2-Megapixel+Digital+SLR+Camera+With+18-55mm+Zoom-Nikkor+Lens%2C+Black&dlprc=549.99&crn=&istrsmrc=1&isathrsl=0&AR=10&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=101677489&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=10&cid=&semid1=&semid2=&IsLps=0&CC=1&SL=1&FS=1&code=&acode=690&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Office Depothttp://img.shopping.com/cctool/merch_logos/467671.gif1-800-GO-DEPOT1352.37http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_office_depot_4158555~MRD-467671~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS486292Nikon® D3100™ 14.2MP Digital SLR with 18-55mm LensThe Nikon D3100 DSLR will surprise you with its simplicity and impress you with superb results.7185Nikonhttp://di103.shopping.com/images/di/52/6c/35/36553743756954597348344d475a30326c7851-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di103.shopping.com/images/di/52/6c/35/36553743756954597348344d475a30326c7851-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di103.shopping.com/images/di/52/6c/35/36553743756954597348344d475a30326c7851-220x220-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4in-stock549.996.05549.99http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=504&BEFID=7185&aon=%5E1&MerchantID=332477&crawler_id=332477&dealId=Rl56U7CuiTYsH4MGZ02lxQ%3D%3D&url=http%3A%2F%2Ftracking.searchmarketing.com%2Fgsic.asp%3Faid%3D903483107%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon%C2%AE+D3100%E2%84%A2+14.2MP+Digital+SLR+with+18-55mm+Lens&dlprc=549.99&crn=&istrsmrc=0&isathrsl=0&AR=11&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=101677489&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=11&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=496&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RadioShackhttp://img.shopping.com/cctool/merch_logos/332477.gif242.25http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_radioshack_9689~MRD-332477~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS9614867Nikon D3100 SLR w/Nikon 18-55mm VR & 55-200mm VR Lenses14.2 Megapixels3" LCDLive ViewHD 1080p Video w/ Sound & Autofocus11-point Autofocus3 Frames per Second ShootingISO 100 to 3200 (Expand to 12800-Hi2)Self Cleaning SensorEXPEED 2, Image Processing EngineScene Recognition System7185Nikonhttp://di105.shopping.com/images/di/68/75/53/36785a4b444b614b4d544d5037316549364441-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di105.shopping.com/images/di/68/75/53/36785a4b444b614b4d544d5037316549364441-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di105.shopping.com/images/di/68/75/53/36785a4b444b614b4d544d5037316549364441-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di105.shopping.com/images/di/68/75/53/36785a4b444b614b4d544d5037316549364441-345x345-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5in-stock695.000.00695.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=371&BEFID=7185&aon=%5E1&MerchantID=487342&crawler_id=487342&dealId=huS6xZKDKaKMTMP71eI6DA%3D%3D&url=http%3A%2F%2Fwww.rythercamera.com%2Fcatalog%2Fproduct_info.php%3Fcsv%3Dsh%26products_id%3D32983%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D3100+SLR+w%2FNikon+18-55mm+VR+%26+55-200mm+VR+Lenses&dlprc=695.0&crn=&istrsmrc=0&isathrsl=0&AR=15&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=101677489&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=15&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=379&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RytherCamera.comhttp://img.shopping.com/cctool/merch_logos/487342.gif1-877-644-75930http://img.shopping.com/sc/glb/flag/US.gifUS32983Nikon COOLPIX S203 Digital Camera10 Megapixel, Ultra-Compact Camera, 2.5 in. LCD Screen, 3x Optical Zoom, With Video Capability, Weight: 0.23 lb.With 10.34 mega pixel, electronic VR vibration reduction, 5-level brightness adjustment, 3x optical zoom, and TFT LCD, Nikon Coolpix s203 fulfills all the demands of any photographer. The digital camera has an inbuilt memory of 44MB and an external memory slot made for all kinds of SD (Secure Digital) cards.http://di1.shopping.com/images/pi/c4/ef/1b/95397883-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=2http://di1.shopping.com/images/pi/c4/ef/1b/95397883-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=2http://di1.shopping.com/images/pi/c4/ef/1b/95397883-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=2http://di1.shopping.com/images/pi/c4/ef/1b/95397883-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=2http://di1.shopping.com/images/pi/c4/ef/1b/95397883-500x499-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=20139.00139.00http://www.shopping.com/Nikon-Coolpix-S203/prices~linkin_id-7000610http://www.shopping.com/Nikon-Coolpix-S203/info~linkin_id-7000610Nikon Coolpix S203 Digital Camera (Red)With 10.34 mega pixel, electronic VR vibration reduction, 5-level brightness adjustment, 3x optical zoom, and TFT LCD, Nikon Coolpix s203 fulfills all the demands of any photographer. The digital camera has an inbuilt memory of 44MB and an external memory slot made for all kinds of SD (Secure Digital) cards.7185Nikonhttp://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-500x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1in-stockFantastic prices with ease & comfort of Amazon.com!139.009.50139.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=566&BEFID=7185&aon=%5E1&MerchantID=301531&crawler_id=1903313&dealId=sBd2JnIEPM-A_lBAM1RZgQ%3D%3D&url=http%3A%2F%2Fwww.amazon.com%2Fdp%2FB002T964IM%2Fref%3Dasc_df_B002T964IM1751618%3Fsmid%3DA22UHVNXG98FAT%26tag%3Ddealtime-ce-mp01feed-20%26linkCode%3Dasn%26creative%3D395105%26creativeASIN%3DB002T964IM&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+Coolpix+S203+Digital+Camera+%28Red%29&dlprc=139.0&crn=&istrsmrc=0&isathrsl=0&AR=63&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=95397883&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=63&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=518&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Amazon Marketplacehttp://img.shopping.com/cctool/merch_logos/301531.gif2132.73http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_amazon_marketplace_9689~MRD-301531~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUSB002T964IMNikon S3100 Digital Camera14.5 Megapixel, Compact Camera, 2.7 in. LCD Screen, 5x Optical Zoom, With High Definition Video, Weight: 0.23 lb.This digital camera features a wide-angle optical Zoom-NIKKOR glass lens that allows you to capture anything from landscapes to portraits to action shots. The high-definition movie mode with one-touch recording makes it easy to capture video clips.http://di1.shopping.com/images/pi/66/2d/33/106834268-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=3http://di1.shopping.com/images/pi/66/2d/33/106834268-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=3http://di1.shopping.com/images/pi/66/2d/33/106834268-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=3http://di1.shopping.com/images/pi/66/2d/33/106834268-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=3http://di1.shopping.com/images/pi/66/2d/33/106834268-507x387-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=312.00http://img.shopping.com/sc/pr/sdc_stars_sm_2.gifhttp://www.shopping.com/nikon-s3100/reviews~linkin_id-700061099.95134.95http://www.shopping.com/nikon-s3100/prices~linkin_id-7000610http://www.shopping.com/nikon-s3100/info~linkin_id-7000610CoolPix S3100 14 Megapixel Compact Digital Camera- RedNikon Coolpix S3100 - Digital camera - compact - 14.0 Mpix - optical zoom: 5 x - supported memory: SD, SDXC, SDHC - red7185Nikonhttp://di111.shopping.com/images/di/55/55/79/476f71563872302d78726b6e2d726e474e6267-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di111.shopping.com/images/di/55/55/79/476f71563872302d78726b6e2d726e474e6267-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di111.shopping.com/images/di/55/55/79/476f71563872302d78726b6e2d726e474e6267-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di111.shopping.com/images/di/55/55/79/476f71563872302d78726b6e2d726e474e6267-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1in-stockGet 30 days FREE SHIPPING w/ ShipVantage119.956.95139.95http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=578&BEFID=7185&aon=%5E1&MerchantID=485615&crawler_id=485615&dealId=UUyGoqV8r0-xrkn-rnGNbg%3D%3D&url=http%3A%2F%2Fsears.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1NbQBJpFHJ3Yx0CTAICI2BbH1lEFmgKP3QvUVpEREdlfUAUHAQPLVpFTVdtJzxAHUNYW3AhQBM0QhFvEXAbYh8EAAVmDAJeU1oyGG0GcBdhGwUGCAVqYF9SO0xSN1sZdmA7dmMdBQAJB24qX1NbQxI6AjA2ME5dVFULPDsGPFcQTTdaLTA6SR0OFlQvPAwMDxYcYlxIVkcoLTcCDA%3D%3D%26nAID%3D13736960%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=CoolPix+S3100+14+Megapixel+Compact+Digital+Camera-+Red&dlprc=119.95&crn=&istrsmrc=1&isathrsl=0&AR=28&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=106834268&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=28&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=1&FS=0&code=&acode=583&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Searshttp://img.shopping.com/cctool/merch_logos/485615.gif1-800-349-43588882.85http://img.shopping.com/sc/mr/sdc_checks_3.gifhttp://www.shopping.com/xMR-store_sears_4189479~MRD-485615~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS00337013000COOLPIX S3100 PinkNikon Coolpix S3100 - Digital camera - compact - 14.0 Mpix - optical zoom: 5 x - supported memory: SD, SDXC, SDHC - pink7185Nikonhttp://di111.shopping.com/images/di/58/38/37/4177586c573164586f4d586b34515144546f51-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di111.shopping.com/images/di/58/38/37/4177586c573164586f4d586b34515144546f51-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di111.shopping.com/images/di/58/38/37/4177586c573164586f4d586b34515144546f51-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di111.shopping.com/images/di/58/38/37/4177586c573164586f4d586b34515144546f51-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2in-stockGet 30 days FREE SHIPPING w/ ShipVantage119.956.95139.95http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=578&BEFID=7185&aon=%5E1&MerchantID=485615&crawler_id=485615&dealId=X87AwXlW1dXoMXk4QQDToQ%3D%3D&url=http%3A%2F%2Fsears.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1NbQBJpFHJxYx0CTAICI2BbH1lEFmgKP3QvUVpEREdlfUAUHAQPLVpFTVdtJzxAHUNYW3AhQBM0QhFvEXAbYh8EAAVmb2JcUFxDEGsPc3QDEkFZVQ0WFhdRW0MWbgYWDlxzdGMdAVQWRi0xDAwPFhw9TSobb05eWVVYKzsLTFVVQi5RICs3SA8MU1s2MQQKD1wf%26nAID%3D13736960%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=COOLPIX+S3100+Pink&dlprc=119.95&crn=&istrsmrc=1&isathrsl=0&AR=31&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=106834268&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=31&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=1&FS=0&code=&acode=583&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Searshttp://img.shopping.com/cctool/merch_logos/485615.gif1-800-349-43588882.85http://img.shopping.com/sc/mr/sdc_checks_3.gifhttp://www.shopping.com/xMR-store_sears_4189479~MRD-485615~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS00337015000Nikon Coolpix S3100 14.0 MP Digital Camera - SilverNikon Coolpix S3100 14.0 MP Digital Camera - Silver7185Nikonhttp://di109.shopping.com/images/di/6e/76/46/776e70664134726c413144626b736473613077-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di109.shopping.com/images/di/6e/76/46/776e70664134726c413144626b736473613077-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di109.shopping.com/images/di/6e/76/46/776e70664134726c413144626b736473613077-270x270-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3in-stock109.970.00109.97http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=803&BEFID=7185&aon=%5E&MerchantID=475774&crawler_id=475774&dealId=nvFwnpfA4rlA1Dbksdsa0w%3D%3D&url=http%3A%2F%2Fwww.thewiz.com%2Fcatalog%2Fproduct.jsp%3FmodelNo%3DS3100SILVER%26gdftrk%3DgdfV2677_a_7c996_a_7c4049_a_7c26262&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+Coolpix+S3100+14.0+MP+Digital+Camera+-+Silver&dlprc=109.97&crn=&istrsmrc=0&isathrsl=0&AR=33&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=106834268&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=33&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=797&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=TheWiz.comhttp://img.shopping.com/cctool/merch_logos/475774.gif877-542-69880http://img.shopping.com/sc/glb/flag/US.gifUS26262Nikon� COOLPIX� S3100 14MP Digital Camera (Silver)The Nikon COOLPIX S3100 is the easy way to share your life and stay connected.7185Nikonhttp://di102.shopping.com/images/di/35/47/74/614e324e6572794b7770732d5365326c2d3467-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di102.shopping.com/images/di/35/47/74/614e324e6572794b7770732d5365326c2d3467-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di102.shopping.com/images/di/35/47/74/614e324e6572794b7770732d5365326c2d3467-220x220-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4in-stock119.996.05119.99http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=504&BEFID=7185&aon=%5E1&MerchantID=332477&crawler_id=332477&dealId=5GtaN2NeryKwps-Se2l-4g%3D%3D&url=http%3A%2F%2Ftracking.searchmarketing.com%2Fgsic.asp%3Faid%3D848064082%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon%C3%AF%C2%BF%C2%BD+COOLPIX%C3%AF%C2%BF%C2%BD+S3100+14MP+Digital+Camera+%28Silver%29&dlprc=119.99&crn=&istrsmrc=0&isathrsl=0&AR=37&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=106834268&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=37&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=509&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RadioShackhttp://img.shopping.com/cctool/merch_logos/332477.gif242.25http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_radioshack_9689~MRD-332477~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS10101095COOLPIX S3100 YellowNikon Coolpix S3100 - Digital camera - compact - 14.0 Mpix - optical zoom: 5 x - supported memory: SD, SDXC, SDHC - yellow7185Nikonhttp://di107.shopping.com/images/di/61/34/33/6d305258756c5833387a436e516a5535396a77-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di107.shopping.com/images/di/61/34/33/6d305258756c5833387a436e516a5535396a77-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di107.shopping.com/images/di/61/34/33/6d305258756c5833387a436e516a5535396a77-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di107.shopping.com/images/di/61/34/33/6d305258756c5833387a436e516a5535396a77-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5in-stockGet 30 days FREE SHIPPING w/ ShipVantage119.956.95139.95http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=578&BEFID=7185&aon=%5E1&MerchantID=485615&crawler_id=485615&dealId=a43m0RXulX38zCnQjU59jw%3D%3D&url=http%3A%2F%2Fsears.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1NbQBJpFHJwYx0CTAICI2BbH1lEFmgKP3QvUVpEREdlfUAUHAQPLVpFTVdtJzxAHUNYW3AhQBM0QhFvEXAbYh8EAAVmb2JcUFxDEGoPc3QDEkFZVQ0WFhdRW0MWbgYWDlxzdGMdAVQWRi0xDAwPFhw9TSobb05eWVVYKzsLTFVVQi5RICs3SA8MU1s2MQQKD1wf%26nAID%3D13736960%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=COOLPIX+S3100+Yellow&dlprc=119.95&crn=&istrsmrc=1&isathrsl=0&AR=38&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=106834268&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=38&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=1&FS=0&code=&acode=583&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Searshttp://img.shopping.com/cctool/merch_logos/485615.gif1-800-349-43588882.85http://img.shopping.com/sc/mr/sdc_checks_3.gifhttp://www.shopping.com/xMR-store_sears_4189479~MRD-485615~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS00337014000Nikon D90 Digital Camera12.3 Megapixel, Point and Shoot Camera, 3 in. LCD Screen, With Video Capability, Weight: 1.36 lb.Untitled Document Nikon D90 SLR Digital Camera With 28-80mm 75-300mm Lens Kit The Nikon D90 SLR Digital Camera, with its 12.3-megapixel DX-format CMOS, 3" High resolution LCD display, Scene Recognition System, Picture Control, Active D-Lighting, and one-button Live View, provides photo enthusiasts with the image quality and performance they need to pursue their own vision while still being intuitive enough for use as an everyday camera.http://di1.shopping.com/images/pi/52/fb/d3/99671132-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=4http://di1.shopping.com/images/pi/52/fb/d3/99671132-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=4http://di1.shopping.com/images/pi/52/fb/d3/99671132-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=4http://di1.shopping.com/images/pi/52/fb/d3/99671132-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=4http://di1.shopping.com/images/pi/52/fb/d3/99671132-499x255-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=475.00http://img.shopping.com/sc/pr/sdc_stars_sm_5.gifhttp://www.shopping.com/Nikon-D90-with-18-270mm-Lens/reviews~linkin_id-7000610689.002299.00http://www.shopping.com/Nikon-D90-with-18-270mm-Lens/prices~linkin_id-7000610http://www.shopping.com/Nikon-D90-with-18-270mm-Lens/info~linkin_id-7000610Nikon® D90 12.3MP Digital SLR Camera (Body Only)The Nikon D90 will make you rethink what a digital SLR camera can achieve.7185Nikonhttp://di106.shopping.com/images/di/47/55/35/4a4a6b70554178653548756a4237666b774141-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di106.shopping.com/images/di/47/55/35/4a4a6b70554178653548756a4237666b774141-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di106.shopping.com/images/di/47/55/35/4a4a6b70554178653548756a4237666b774141-220x220-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1in-stock1015.996.051015.99http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=504&BEFID=7185&aon=%5E1&MerchantID=332477&crawler_id=332477&dealId=GU5JJkpUAxe5HujB7fkwAA%3D%3D&url=http%3A%2F%2Ftracking.searchmarketing.com%2Fgsic.asp%3Faid%3D851830266%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon%C2%AE+D90+12.3MP+Digital+SLR+Camera+%28Body+Only%29&dlprc=1015.99&crn=&istrsmrc=0&isathrsl=0&AR=14&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=99671132&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=14&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=496&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RadioShackhttp://img.shopping.com/cctool/merch_logos/332477.gif242.25http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_radioshack_9689~MRD-332477~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS10148659Nikon D90 SLR Digital Camera (Camera Body)The Nikon D90 SLR Digital Camera with its 12.3-megapixel DX-format CCD 3" High resolution LCD display Scene Recognition System Picture Control Active D-Lighting and one-button Live View provides photo enthusiasts with the image quality and performance they need to pursue their own vision while still being intuitive enough for use as an everyday camera. In addition the D90 introduces the D-Movie mode allowing for the first time an interchangeable lens SLR camera that is capable of recording 720p HD movie clips. Availabilty: In Stock7185Nikonhttp://di109.shopping.com/images/di/58/68/55/527553432d73704262544944666f3471667a51-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/58/68/55/527553432d73704262544944666f3471667a51-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/58/68/55/527553432d73704262544944666f3471667a51-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/58/68/55/527553432d73704262544944666f3471667a51-350x350-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2in-stockFree Shipping with Any Purchase!689.000.00900.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=647&BEFID=7185&aon=%5E1&MerchantID=475674&crawler_id=475674&dealId=XhURuSC-spBbTIDfo4qfzQ%3D%3D&url=http%3A%2F%2Fwww.fumfie.com%2Fproduct%2F169.5%2Fshopping-com%3F&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+SLR+Digital+Camera+%28Camera+Body%29&dlprc=689.0&crn=&istrsmrc=1&isathrsl=0&AR=16&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=99671132&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=16&cid=&semid1=&semid2=&IsLps=0&CC=1&SL=1&FS=1&code=&acode=658&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=FumFiehttp://img.shopping.com/cctool/merch_logos/475674.gif866 666 91985604.27http://img.shopping.com/sc/mr/sdc_checks_45.gifhttp://www.shopping.com/xMR-store_fumfie~MRD-475674~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUSF169C5Nikon D90 SLR w/Nikon 18-105mm VR & 55-200mm VR Lenses12.3 MegapixelDX Format CMOS Sensor3" VGA LCD DisplayLive ViewSelf Cleaning SensorD-Movie ModeHigh Sensitivity (ISO 3200)4.5 fps BurstIn-Camera Image Editing7185Nikonhttp://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-500x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3in-stock1189.000.001189.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=371&BEFID=7185&aon=%5E1&MerchantID=487342&crawler_id=487342&dealId=o0Px_XLWDbrxAYRy3rCmyQ%3D%3D&url=http%3A%2F%2Fwww.rythercamera.com%2Fcatalog%2Fproduct_info.php%3Fcsv%3Dsh%26products_id%3D30619%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+SLR+w%2FNikon+18-105mm+VR+%26+55-200mm+VR+Lenses&dlprc=1189.0&crn=&istrsmrc=0&isathrsl=0&AR=20&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=99671132&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=20&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=379&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RytherCamera.comhttp://img.shopping.com/cctool/merch_logos/487342.gif1-877-644-75930http://img.shopping.com/sc/glb/flag/US.gifUS30619Nikon D90 12.3 Megapixel Digital SLR Camera (Body Only)Fusing 12.3 megapixel image quality and a cinematic 24fps D-Movie Mode, the Nikon D90 exceeds the demands of passionate photographers. Coupled with Nikon's EXPEED image processing technologies and NIKKOR optics, breathtaking image fidelity is assured. Combined with fast 0.15ms power-up and split-second 65ms shooting lag, dramatic action and decisive moments are captured easily. Effective 4-frequency, ultrasonic sensor cleaning frees image degrading dust particles from the sensor's optical low pass filter.7185Nikonhttp://di110.shopping.com/images/di/34/48/67/62574a534a3873736749663842304d58497741-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di110.shopping.com/images/di/34/48/67/62574a534a3873736749663842304d58497741-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di110.shopping.com/images/di/34/48/67/62574a534a3873736749663842304d58497741-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4in-stockFREE FEDEX 2-3 DAY DELIVERY899.950.00899.95http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=269&BEFID=7185&aon=%5E&MerchantID=9296&crawler_id=811558&dealId=4HgbWJSJ8ssgIf8B0MXIwA%3D%3D&url=http%3A%2F%2Fwww.pcnation.com%2Foptics-gallery%2Fdetails.asp%3Faffid%3D305%26item%3D2N145P&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+12.3+Megapixel+Digital+SLR+Camera+%28Body+Only%29&dlprc=899.95&crn=&istrsmrc=1&isathrsl=0&AR=21&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=99671132&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=21&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=257&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=PCNationhttp://img.shopping.com/cctool/merch_logos/9296.gif800-470-707916224.43http://img.shopping.com/sc/mr/sdc_checks_45.gifhttp://www.shopping.com/xMR-store_pcnation_9689~MRD-9296~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS2N145PNikon D90 12.3MP Digital SLR Camera (Body Only)Fusing 12.3-megapixel image quality inherited from the award-winning D300 with groundbreaking features, the D90's breathtaking, low-noise image quality is further advanced with EXPEED image processing. Split-second shutter response and continuous shooting at up to 4.5 frames-per-second provide the power to capture fast action and precise moments perfectly, while Nikon's exclusive Scene Recognition System contributes to faster 11-area autofocus performance, finer white balance detection and more. The D90 delivers the control passionate photographers demand, utilizing comprehensive exposure functions and the intelligence of 3D Color Matrix Metering II. Stunning results come to life on a 3-inch 920,000-dot color LCD monitor, providing accurate image review, Live View composition and brilliant playback of the D90's cinematic-quality 24-fps HD D-Movie mode.7185Nikonhttp://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-500x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5in-stockFantastic prices with ease & comfort of Amazon.com!780.000.00780.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=566&BEFID=7185&aon=%5E1&MerchantID=301531&crawler_id=1903313&dealId=UNDa3uMDZXOnvD_7sTILYg%3D%3D&url=http%3A%2F%2Fwww.amazon.com%2Fdp%2FB001ET5U92%2Fref%3Dasc_df_B001ET5U921751618%3Fsmid%3DAHF4SYKP09WBH%26tag%3Ddealtime-ce-mp01feed-20%26linkCode%3Dasn%26creative%3D395105%26creativeASIN%3DB001ET5U92&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+12.3MP+Digital+SLR+Camera+%28Body+Only%29&dlprc=780.0&crn=&istrsmrc=0&isathrsl=0&AR=29&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=99671132&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=29&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=520&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Amazon Marketplacehttp://img.shopping.com/cctool/merch_logos/301531.gif2132.73http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_amazon_marketplace_9689~MRD-301531~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUSB001ET5U92Nikon D90 Digital Camera with 18-105mm lens12.9 Megapixel, SLR Camera, 3 in. LCD Screen, 5.8x Optical Zoom, With Video Capability, Weight: 2.3 lb.Its 12.3 megapixel DX-format CMOS image sensor and EXPEED image processing system offer outstanding image quality across a wide ISO light sensitivity range. Live View mode lets you compose and shoot via the high-resolution 3-inch LCD monitor, and an advanced Scene Recognition System and autofocus performance help capture images with astounding accuracy. Movies can be shot in Motion JPEG format using the D-Movie function. The camera’s large image sensor ensures exceptional movie image quality and you can create dramatic effects by shooting with a wide range of interchangeable NIKKOR lenses, from wide-angle to macro to fisheye, or by adjusting the lens aperture and experimenting with depth-of-field. The D90 – designed to fuel your passion for photography.http://di1.shopping.com/images/pi/57/6a/4f/70621646-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=5http://di1.shopping.com/images/pi/57/6a/4f/70621646-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=5http://di1.shopping.com/images/pi/57/6a/4f/70621646-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=5http://di1.shopping.com/images/pi/57/6a/4f/70621646-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=5http://di1.shopping.com/images/pi/57/6a/4f/70621646-490x489-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=5324.81http://img.shopping.com/sc/pr/sdc_stars_sm_5.gifhttp://www.shopping.com/Nikon-D90-with-18-105mm-lens/reviews~linkin_id-7000610849.951599.95http://www.shopping.com/Nikon-D90-with-18-105mm-lens/prices~linkin_id-7000610http://www.shopping.com/Nikon-D90-with-18-105mm-lens/info~linkin_id-7000610Nikon D90 18-105mm VR LensThe Nikon D90 SLR Digital Camera with its 12.3-megapixel DX-format CMOS 3" High resolution LCD display Scene Recognition System Picture Control Active D-Lighting and one-button Live View prov7185Nikonhttp://di111.shopping.com/images/di/33/6f/35/6531566768674a5066684c7654314a464b5441-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di111.shopping.com/images/di/33/6f/35/6531566768674a5066684c7654314a464b5441-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di111.shopping.com/images/di/33/6f/35/6531566768674a5066684c7654314a464b5441-260x260-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1in-stock849.950.00849.95http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=419&BEFID=7185&aon=%5E1&MerchantID=9390&crawler_id=1905054&dealId=3o5e1VghgJPfhLvT1JFKTA%3D%3D&url=http%3A%2F%2Fwww.ajrichard.com%2FNikon-D90-18-105mm-VR-Lens%2Fp-292%3Frefid%3DShopping%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+18-105mm+VR+Lens&dlprc=849.95&crn=&istrsmrc=0&isathrsl=0&AR=2&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=70621646&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=2&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=425&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=AJRichardhttp://img.shopping.com/cctool/merch_logos/9390.gif1-888-871-125631244.48http://img.shopping.com/sc/mr/sdc_checks_45.gifhttp://www.shopping.com/xMR-store_ajrichard~MRD-9390~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS292Nikon D90 SLR w/Nikon 18-105mm VR Lens12.3 MegapixelDX Format CMOS Sensor3" VGA LCD DisplayLive ViewSelf Cleaning SensorD-Movie ModeHigh Sensitivity (ISO 3200)4.5 fps BurstIn-Camera Image Editing7185Nikonhttp://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-500x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2in-stock909.000.00909.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=371&BEFID=7185&aon=%5E1&MerchantID=487342&crawler_id=487342&dealId=_lYWj_jbwfsSkfcwUcDuww%3D%3D&url=http%3A%2F%2Fwww.rythercamera.com%2Fcatalog%2Fproduct_info.php%3Fcsv%3Dsh%26products_id%3D30971%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+SLR+w%2FNikon+18-105mm+VR+Lens&dlprc=909.0&crn=&istrsmrc=0&isathrsl=0&AR=3&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=70621646&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=3&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=379&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RytherCamera.comhttp://img.shopping.com/cctool/merch_logos/487342.gif1-877-644-75930http://img.shopping.com/sc/glb/flag/US.gifUS3097125448/D90 12.3 Megapixel Digital Camera 18-105mm Zoom Lens w/ 3" Screen - BlackNikon D90 - Digital camera - SLR - 12.3 Mpix - Nikon AF-S DX 18-105mm lens - optical zoom: 5.8 x - supported memory: SD, SDHC7185Nikonhttp://di110.shopping.com/images/di/31/4b/43/636c4347755776747932584b5539736b616467-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di110.shopping.com/images/di/31/4b/43/636c4347755776747932584b5539736b616467-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di110.shopping.com/images/di/31/4b/43/636c4347755776747932584b5539736b616467-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di110.shopping.com/images/di/31/4b/43/636c4347755776747932584b5539736b616467-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3in-stockGet 30 days FREE SHIPPING w/ ShipVantage1199.008.201199.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=578&BEFID=7185&aon=%5E1&MerchantID=485615&crawler_id=485615&dealId=1KCclCGuWvty2XKU9skadg%3D%3D&url=http%3A%2F%2Fsears.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1NbQBRtFXpzYx0CTAICI2BbH1lEFmgKP3QvUVpEREdlfUAUHAQPLVpFTVdtJzxAHUNYW3AhQBM0QhFvEXAbYh8EAAVmb2JcVlhCGGkPc3QDEkFZVQ0WFhdRW0MWbgYWDlxzdGMdAVQWRi0xDAwPFhw9TSobb05eWVVYKzsLTFVVQi5RICs3SA8MU1s2MQQKD1wf%26nAID%3D13736960%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=25448%2FD90+12.3+Megapixel+Digital+Camera+18-105mm+Zoom+Lens+w%2F+3%22+Screen+-+Black&dlprc=1199.0&crn=&istrsmrc=1&isathrsl=0&AR=4&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=70621646&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=4&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=586&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Searshttp://img.shopping.com/cctool/merch_logos/485615.gif1-800-349-43588882.85http://img.shopping.com/sc/mr/sdc_checks_3.gifhttp://www.shopping.com/xMR-store_sears_4189479~MRD-485615~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS00353197000Nikon® D90 12.3MP Digital SLR with 18-105mm LensThe Nikon D90 will make you rethink what a digital SLR camera can achieve.7185Nikonhttp://di101.shopping.com/images/di/33/2d/56/4f53665656354a6f37486c41346b4a74616e41-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di101.shopping.com/images/di/33/2d/56/4f53665656354a6f37486c41346b4a74616e41-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di101.shopping.com/images/di/33/2d/56/4f53665656354a6f37486c41346b4a74616e41-220x220-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4in-stock1350.996.051350.99http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=504&BEFID=7185&aon=%5E1&MerchantID=332477&crawler_id=332477&dealId=3-VOSfVV5Jo7HlA4kJtanA%3D%3D&url=http%3A%2F%2Ftracking.searchmarketing.com%2Fgsic.asp%3Faid%3D982673361%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon%C2%AE+D90+12.3MP+Digital+SLR+with+18-105mm+Lens&dlprc=1350.99&crn=&istrsmrc=0&isathrsl=0&AR=5&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=70621646&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=5&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=496&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RadioShackhttp://img.shopping.com/cctool/merch_logos/332477.gif242.25http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_radioshack_9689~MRD-332477~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS11148905Nikon D90 Kit 12.3-megapixel Digital SLR with 18-105mm VR LensPhotographers, take your passion further!Now is the time for new creativity, and to rethink what a digital SLR camera can achieve. It's time for the D90, a camera with everything you would expect from Nikon's next-generation D-SLRs, and some unexpected surprises, as well. The stunning image quality is inherited from the D300, Nikon's DX-format flagship. The D90 also has Nikon's unmatched ergonomics and high performance, and now takes high-quality movies with beautifully cinematic results. The world of photography has changed, and with the D90 in your hands, it's time to make your own rules.AF-S DX NIKKOR 18-105mm f/3.5-5.6G ED VR LensWide-ratio 5.8x zoom Compact, versatile and ideal for a broad range of shooting situations, ranging from interiors and landscapes to beautiful portraits� a perfect everyday zoom. Nikon VR (Vibration Reduction) image stabilization Vibration Reduction is engineered specifically for each VR NIKKOR lens and enables handheld shooting at up to 3 shutter speeds slower than would7185Nikonhttp://di110.shopping.com/images/di/6b/51/6e/4236725334416a4e3564783568325f36333167-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di110.shopping.com/images/di/6b/51/6e/4236725334416a4e3564783568325f36333167-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di110.shopping.com/images/di/6b/51/6e/4236725334416a4e3564783568325f36333167-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di110.shopping.com/images/di/6b/51/6e/4236725334416a4e3564783568325f36333167-300x232-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5in-stockShipping Included!1050.000.001199.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=135&BEFID=7185&aon=%5E1&MerchantID=313162&crawler_id=313162&dealId=kQnB6rS4AjN5dx5h2_631g%3D%3D&url=http%3A%2F%2Fonecall.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1pZSxNoWHFwLx8GTAICa2ZeH1sPXTZLNzRpAh1HR0BxPQEGCBJNMhFHUElsFCFCVkVTTHAcBggEHQ4aHXNpGERGH3RQODsbAgdechJtbBt8fx8JAwhtZFAzJj1oGgIWCxRlNyFOUV9UUGIxBgo0T0IyTSYqJ0RWHw4QPCIBAAQXRGMDICg6TllZVBhh%26nAID%3D13736960&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+Kit+12.3-megapixel+Digital+SLR+with+18-105mm+VR+Lens&dlprc=1050.0&crn=&istrsmrc=1&isathrsl=0&AR=6&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=70621646&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=6&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=1&FS=1&code=&acode=143&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=OneCallhttp://img.shopping.com/cctool/merch_logos/313162.gif1.800.398.07661804.44http://img.shopping.com/sc/mr/sdc_checks_45.gifhttp://www.shopping.com/xMR-store_onecall_9689~MRD-313162~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS92826Price rangehttp://www.shopping.com/digital-cameras/nikon/products?oq=nikon&linkin_id=7000610$24 - $4012http://www.shopping.com/digital-cameras/nikon/products?minPrice=24&maxPrice=4012&linkin_id=7000610$4012 - $7999http://www.shopping.com/digital-cameras/nikon/products?minPrice=4012&maxPrice=7999&linkin_id=7000610Brandhttp://www.shopping.com/digital-cameras/nikon/products~all-9688-brand~MS-1?oq=nikon&linkin_id=7000610Nikonhttp://www.shopping.com/digital-cameras/nikon+brand-nikon/products~linkin_id-7000610Cranehttp://www.shopping.com/digital-cameras/nikon+9688-brand-crane/products~linkin_id-7000610Ikelitehttp://www.shopping.com/digital-cameras/nikon+ikelite/products~linkin_id-7000610Bowerhttp://www.shopping.com/digital-cameras/nikon+bower/products~linkin_id-7000610FUJIFILMhttp://www.shopping.com/digital-cameras/nikon+brand-fuji/products~linkin_id-7000610Storehttp://www.shopping.com/digital-cameras/nikon/products~all-store~MS-1?oq=nikon&linkin_id=7000610Amazon Marketplacehttp://www.shopping.com/digital-cameras/nikon+store-amazon-marketplace-9689/products~linkin_id-7000610Amazonhttp://www.shopping.com/digital-cameras/nikon+store-amazon/products~linkin_id-7000610Adoramahttp://www.shopping.com/digital-cameras/nikon+store-adorama/products~linkin_id-7000610J&R Music and Computer Worldhttp://www.shopping.com/digital-cameras/nikon+store-j-r-music-and-computer-world/products~linkin_id-7000610RytherCamera.comhttp://www.shopping.com/digital-cameras/nikon+store-rythercamera-com/products~linkin_id-7000610Resolutionhttp://www.shopping.com/digital-cameras/nikon/products~all-21885-resolution~MS-1?oq=nikon&linkin_id=7000610Under 4 Megapixelhttp://www.shopping.com/digital-cameras/nikon+under-4-megapixel/products~linkin_id-7000610At least 5 Megapixelhttp://www.shopping.com/digital-cameras/nikon+5-megapixel-digital-cameras/products~linkin_id-7000610At least 6 Megapixelhttp://www.shopping.com/digital-cameras/nikon+6-megapixel-digital-cameras/products~linkin_id-7000610At least 7 Megapixelhttp://www.shopping.com/digital-cameras/nikon+7-megapixel-digital-cameras/products~linkin_id-7000610At least 8 Megapixelhttp://www.shopping.com/digital-cameras/nikon+8-megapixel-digital-cameras/products~linkin_id-7000610Featureshttp://www.shopping.com/digital-cameras/nikon/products~all-32804-features~MS-1?oq=nikon&linkin_id=7000610Shockproofhttp://www.shopping.com/digital-cameras/nikon+32804-features-shockproof/products~linkin_id-7000610Waterproofhttp://www.shopping.com/digital-cameras/nikon+32804-features-waterproof/products~linkin_id-7000610Freezeproofhttp://www.shopping.com/digital-cameras/nikon+32804-features-freezeproof/products~linkin_id-7000610Dust proofhttp://www.shopping.com/digital-cameras/nikon+32804-features-dust-proof/products~linkin_id-7000610Image Stabilizationhttp://www.shopping.com/digital-cameras/nikon+32804-features-image-stabilization/products~linkin_id-7000610hybriddigital camerag1sonycameracanonnikonkodak digital camerakodaksony cybershotkodak easyshare digital cameranikon coolpixolympuspink digital cameracanon powershot \ No newline at end of file diff --git a/node_modules/sax/examples/strict.dtd b/node_modules/sax/examples/strict.dtd new file mode 100644 index 0000000..b274559 --- /dev/null +++ b/node_modules/sax/examples/strict.dtd @@ -0,0 +1,870 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +%HTMLlat1; + + +%HTMLsymbol; + + +%HTMLspecial; + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/node_modules/sax/examples/test.html b/node_modules/sax/examples/test.html new file mode 100644 index 0000000..61f8f1a --- /dev/null +++ b/node_modules/sax/examples/test.html @@ -0,0 +1,15 @@ + + + + + testing the parser + + + +

          hello + + + + diff --git a/node_modules/sax/examples/test.xml b/node_modules/sax/examples/test.xml new file mode 100644 index 0000000..801292d --- /dev/null +++ b/node_modules/sax/examples/test.xml @@ -0,0 +1,1254 @@ + + +]> + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + \ No newline at end of file diff --git a/node_modules/sax/lib/sax.js b/node_modules/sax/lib/sax.js new file mode 100644 index 0000000..d5c0cb6 --- /dev/null +++ b/node_modules/sax/lib/sax.js @@ -0,0 +1,1355 @@ +// wrapper for non-node envs +;(function (sax) { + +sax.parser = function (strict, opt) { return new SAXParser(strict, opt) } +sax.SAXParser = SAXParser +sax.SAXStream = SAXStream +sax.createStream = createStream + +// When we pass the MAX_BUFFER_LENGTH position, start checking for buffer overruns. +// When we check, schedule the next check for MAX_BUFFER_LENGTH - (max(buffer lengths)), +// since that's the earliest that a buffer overrun could occur. This way, checks are +// as rare as required, but as often as necessary to ensure never crossing this bound. +// Furthermore, buffers are only tested at most once per write(), so passing a very +// large string into write() might have undesirable effects, but this is manageable by +// the caller, so it is assumed to be safe. Thus, a call to write() may, in the extreme +// edge case, result in creating at most one complete copy of the string passed in. +// Set to Infinity to have unlimited buffers. +sax.MAX_BUFFER_LENGTH = 64 * 1024 + +var buffers = [ + "comment", "sgmlDecl", "textNode", "tagName", "doctype", + "procInstName", "procInstBody", "entity", "attribName", + "attribValue", "cdata", "script" +] + +sax.EVENTS = // for discoverability. + [ "text" + , "processinginstruction" + , "sgmldeclaration" + , "doctype" + , "comment" + , "attribute" + , "opentag" + , "closetag" + , "opencdata" + , "cdata" + , "closecdata" + , "error" + , "end" + , "ready" + , "script" + , "opennamespace" + , "closenamespace" + ] + +function SAXParser (strict, opt) { + if (!(this instanceof SAXParser)) return new SAXParser(strict, opt) + + var parser = this + clearBuffers(parser) + parser.q = parser.c = "" + parser.bufferCheckPosition = sax.MAX_BUFFER_LENGTH + parser.opt = opt || {} + parser.opt.lowercase = parser.opt.lowercase || parser.opt.lowercasetags + parser.looseCase = parser.opt.lowercase ? "toLowerCase" : "toUpperCase" + parser.tags = [] + parser.closed = parser.closedRoot = parser.sawRoot = false + parser.tag = parser.error = null + parser.strict = !!strict + parser.noscript = !!(strict || parser.opt.noscript) + parser.state = S.BEGIN + parser.ENTITIES = Object.create(sax.ENTITIES) + parser.attribList = [] + + // namespaces form a prototype chain. + // it always points at the current tag, + // which protos to its parent tag. + if (parser.opt.xmlns) parser.ns = Object.create(rootNS) + + // mostly just for error reporting + parser.trackPosition = parser.opt.position !== false + if (parser.trackPosition) { + parser.position = parser.line = parser.column = 0 + } + emit(parser, "onready") +} + +if (!Object.create) Object.create = function (o) { + function f () { this.__proto__ = o } + f.prototype = o + return new f +} + +if (!Object.getPrototypeOf) Object.getPrototypeOf = function (o) { + return o.__proto__ +} + +if (!Object.keys) Object.keys = function (o) { + var a = [] + for (var i in o) if (o.hasOwnProperty(i)) a.push(i) + return a +} + +function checkBufferLength (parser) { + var maxAllowed = Math.max(sax.MAX_BUFFER_LENGTH, 10) + , maxActual = 0 + for (var i = 0, l = buffers.length; i < l; i ++) { + var len = parser[buffers[i]].length + if (len > maxAllowed) { + // Text/cdata nodes can get big, and since they're buffered, + // we can get here under normal conditions. + // Avoid issues by emitting the text node now, + // so at least it won't get any bigger. + switch (buffers[i]) { + case "textNode": + closeText(parser) + break + + case "cdata": + emitNode(parser, "oncdata", parser.cdata) + parser.cdata = "" + break + + case "script": + emitNode(parser, "onscript", parser.script) + parser.script = "" + break + + default: + error(parser, "Max buffer length exceeded: "+buffers[i]) + } + } + maxActual = Math.max(maxActual, len) + } + // schedule the next check for the earliest possible buffer overrun. + parser.bufferCheckPosition = (sax.MAX_BUFFER_LENGTH - maxActual) + + parser.position +} + +function clearBuffers (parser) { + for (var i = 0, l = buffers.length; i < l; i ++) { + parser[buffers[i]] = "" + } +} + +function flushBuffers (parser) { + closeText(parser) + if (parser.cdata !== "") { + emitNode(parser, "oncdata", parser.cdata) + parser.cdata = "" + } + if (parser.script !== "") { + emitNode(parser, "onscript", parser.script) + parser.script = "" + } +} + +SAXParser.prototype = + { end: function () { end(this) } + , write: write + , resume: function () { this.error = null; return this } + , close: function () { return this.write(null) } + , flush: function () { flushBuffers(this) } + } + +try { + var Stream = require("stream").Stream +} catch (ex) { + var Stream = function () {} +} + + +var streamWraps = sax.EVENTS.filter(function (ev) { + return ev !== "error" && ev !== "end" +}) + +function createStream (strict, opt) { + return new SAXStream(strict, opt) +} + +function SAXStream (strict, opt) { + if (!(this instanceof SAXStream)) return new SAXStream(strict, opt) + + Stream.apply(this) + + this._parser = new SAXParser(strict, opt) + this.writable = true + this.readable = true + + + var me = this + + this._parser.onend = function () { + me.emit("end") + } + + this._parser.onerror = function (er) { + me.emit("error", er) + + // if didn't throw, then means error was handled. + // go ahead and clear error, so we can write again. + me._parser.error = null + } + + this._decoder = null; + + streamWraps.forEach(function (ev) { + Object.defineProperty(me, "on" + ev, { + get: function () { return me._parser["on" + ev] }, + set: function (h) { + if (!h) { + me.removeAllListeners(ev) + return me._parser["on"+ev] = h + } + me.on(ev, h) + }, + enumerable: true, + configurable: false + }) + }) +} + +SAXStream.prototype = Object.create(Stream.prototype, + { constructor: { value: SAXStream } }) + +SAXStream.prototype.write = function (data) { + if (typeof Buffer === 'function' && + typeof Buffer.isBuffer === 'function' && + Buffer.isBuffer(data)) { + if (!this._decoder) { + var SD = require('string_decoder').StringDecoder + this._decoder = new SD('utf8') + } + data = this._decoder.write(data); + } + + this._parser.write(data.toString()) + this.emit("data", data) + return true +} + +SAXStream.prototype.end = function (chunk) { + if (chunk && chunk.length) this.write(chunk) + this._parser.end() + return true +} + +SAXStream.prototype.on = function (ev, handler) { + var me = this + if (!me._parser["on"+ev] && streamWraps.indexOf(ev) !== -1) { + me._parser["on"+ev] = function () { + var args = arguments.length === 1 ? [arguments[0]] + : Array.apply(null, arguments) + args.splice(0, 0, ev) + me.emit.apply(me, args) + } + } + + return Stream.prototype.on.call(me, ev, handler) +} + + + +// character classes and tokens +var whitespace = "\r\n\t " + // this really needs to be replaced with character classes. + // XML allows all manner of ridiculous numbers and digits. + , number = "0124356789" + , letter = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + // (Letter | "_" | ":") + , quote = "'\"" + , entity = number+letter+"#" + , attribEnd = whitespace + ">" + , CDATA = "[CDATA[" + , DOCTYPE = "DOCTYPE" + , XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace" + , XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/" + , rootNS = { xml: XML_NAMESPACE, xmlns: XMLNS_NAMESPACE } + +// turn all the string character sets into character class objects. +whitespace = charClass(whitespace) +number = charClass(number) +letter = charClass(letter) + +// http://www.w3.org/TR/REC-xml/#NT-NameStartChar +// This implementation works on strings, a single character at a time +// as such, it cannot ever support astral-plane characters (10000-EFFFF) +// without a significant breaking change to either this parser, or the +// JavaScript language. Implementation of an emoji-capable xml parser +// is left as an exercise for the reader. +var nameStart = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/ + +var nameBody = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040\.\d-]/ + +quote = charClass(quote) +entity = charClass(entity) +attribEnd = charClass(attribEnd) + +function charClass (str) { + return str.split("").reduce(function (s, c) { + s[c] = true + return s + }, {}) +} + +function isRegExp (c) { + return Object.prototype.toString.call(c) === '[object RegExp]' +} + +function is (charclass, c) { + return isRegExp(charclass) ? !!c.match(charclass) : charclass[c] +} + +function not (charclass, c) { + return !is(charclass, c) +} + +var S = 0 +sax.STATE = +{ BEGIN : S++ +, TEXT : S++ // general stuff +, TEXT_ENTITY : S++ // & and such. +, OPEN_WAKA : S++ // < +, SGML_DECL : S++ // +, SCRIPT : S++ // " + , expect : + [ [ "opentag", { name: "xml", attributes: {}, isSelfClosing: false } ] + , [ "opentag", { name: "script", attributes: {}, isSelfClosing: false } ] + , [ "text", "hello world" ] + , [ "closetag", "script" ] + , [ "closetag", "xml" ] + ] + , strict : false + , opt : { lowercasetags: true, noscript: true } + } + ) + +require(__dirname).test + ( { xml : "" + , expect : + [ [ "opentag", { name: "xml", attributes: {}, isSelfClosing: false } ] + , [ "opentag", { name: "script", attributes: {}, isSelfClosing: false } ] + , [ "opencdata", undefined ] + , [ "cdata", "hello world" ] + , [ "closecdata", undefined ] + , [ "closetag", "script" ] + , [ "closetag", "xml" ] + ] + , strict : false + , opt : { lowercasetags: true, noscript: true } + } + ) + diff --git a/node_modules/sax/test/issue-84.js b/node_modules/sax/test/issue-84.js new file mode 100644 index 0000000..0e7ee69 --- /dev/null +++ b/node_modules/sax/test/issue-84.js @@ -0,0 +1,13 @@ +// https://github.com/isaacs/sax-js/issues/49 +require(__dirname).test + ( { xml : "body" + , expect : + [ [ "processinginstruction", { name: "has", body: "unbalanced \"quotes" } ], + [ "opentag", { name: "xml", attributes: {}, isSelfClosing: false } ] + , [ "text", "body" ] + , [ "closetag", "xml" ] + ] + , strict : false + , opt : { lowercasetags: true, noscript: true } + } + ) diff --git a/node_modules/sax/test/parser-position.js b/node_modules/sax/test/parser-position.js new file mode 100644 index 0000000..e4a68b1 --- /dev/null +++ b/node_modules/sax/test/parser-position.js @@ -0,0 +1,28 @@ +var sax = require("../lib/sax"), + assert = require("assert") + +function testPosition(chunks, expectedEvents) { + var parser = sax.parser(); + expectedEvents.forEach(function(expectation) { + parser['on' + expectation[0]] = function() { + for (var prop in expectation[1]) { + assert.equal(parser[prop], expectation[1][prop]); + } + } + }); + chunks.forEach(function(chunk) { + parser.write(chunk); + }); +}; + +testPosition(['

          abcdefgh
          '], + [ ['opentag', { position: 5, startTagPosition: 1 }] + , ['text', { position: 19, startTagPosition: 14 }] + , ['closetag', { position: 19, startTagPosition: 14 }] + ]); + +testPosition(['
          abcde','fgh
          '], + [ ['opentag', { position: 5, startTagPosition: 1 }] + , ['text', { position: 19, startTagPosition: 14 }] + , ['closetag', { position: 19, startTagPosition: 14 }] + ]); diff --git a/node_modules/sax/test/script-close-better.js b/node_modules/sax/test/script-close-better.js new file mode 100644 index 0000000..f4887b9 --- /dev/null +++ b/node_modules/sax/test/script-close-better.js @@ -0,0 +1,12 @@ +require(__dirname).test({ + xml : "", + expect : [ + ["opentag", {"name": "HTML","attributes": {}, isSelfClosing: false}], + ["opentag", {"name": "HEAD","attributes": {}, isSelfClosing: false}], + ["opentag", {"name": "SCRIPT","attributes": {}, isSelfClosing: false}], + ["script", "'
          foo
          ", + expect : [ + ["opentag", {"name": "HTML","attributes": {}, "isSelfClosing": false}], + ["opentag", {"name": "HEAD","attributes": {}, "isSelfClosing": false}], + ["opentag", {"name": "SCRIPT","attributes": {}, "isSelfClosing": false}], + ["script", "if (1 < 0) { console.log('elo there'); }"], + ["closetag", "SCRIPT"], + ["closetag", "HEAD"], + ["closetag", "HTML"] + ] +}); diff --git a/node_modules/sax/test/self-closing-child-strict.js b/node_modules/sax/test/self-closing-child-strict.js new file mode 100644 index 0000000..3d6e985 --- /dev/null +++ b/node_modules/sax/test/self-closing-child-strict.js @@ -0,0 +1,44 @@ + +require(__dirname).test({ + xml : + ""+ + "" + + "" + + "" + + "" + + "=(|)" + + "" + + "", + expect : [ + ["opentag", { + "name": "root", + "attributes": {}, + "isSelfClosing": false + }], + ["opentag", { + "name": "child", + "attributes": {}, + "isSelfClosing": false + }], + ["opentag", { + "name": "haha", + "attributes": {}, + "isSelfClosing": true + }], + ["closetag", "haha"], + ["closetag", "child"], + ["opentag", { + "name": "monkey", + "attributes": {}, + "isSelfClosing": false + }], + ["text", "=(|)"], + ["closetag", "monkey"], + ["closetag", "root"], + ["end"], + ["ready"] + ], + strict : true, + opt : {} +}); + diff --git a/node_modules/sax/test/self-closing-child.js b/node_modules/sax/test/self-closing-child.js new file mode 100644 index 0000000..f31c366 --- /dev/null +++ b/node_modules/sax/test/self-closing-child.js @@ -0,0 +1,44 @@ + +require(__dirname).test({ + xml : + ""+ + "" + + "" + + "" + + "" + + "=(|)" + + "" + + "", + expect : [ + ["opentag", { + "name": "ROOT", + "attributes": {}, + "isSelfClosing": false + }], + ["opentag", { + "name": "CHILD", + "attributes": {}, + "isSelfClosing": false + }], + ["opentag", { + "name": "HAHA", + "attributes": {}, + "isSelfClosing": true + }], + ["closetag", "HAHA"], + ["closetag", "CHILD"], + ["opentag", { + "name": "MONKEY", + "attributes": {}, + "isSelfClosing": false + }], + ["text", "=(|)"], + ["closetag", "MONKEY"], + ["closetag", "ROOT"], + ["end"], + ["ready"] + ], + strict : false, + opt : {} +}); + diff --git a/node_modules/sax/test/self-closing-tag.js b/node_modules/sax/test/self-closing-tag.js new file mode 100644 index 0000000..d1d8b7c --- /dev/null +++ b/node_modules/sax/test/self-closing-tag.js @@ -0,0 +1,25 @@ + +require(__dirname).test({ + xml : + " "+ + " "+ + " "+ + " "+ + "=(|) "+ + ""+ + " ", + expect : [ + ["opentag", {name:"ROOT", attributes:{}, isSelfClosing: false}], + ["opentag", {name:"HAHA", attributes:{}, isSelfClosing: true}], + ["closetag", "HAHA"], + ["opentag", {name:"HAHA", attributes:{}, isSelfClosing: true}], + ["closetag", "HAHA"], + // ["opentag", {name:"HAHA", attributes:{}}], + // ["closetag", "HAHA"], + ["opentag", {name:"MONKEY", attributes:{}, isSelfClosing: false}], + ["text", "=(|)"], + ["closetag", "MONKEY"], + ["closetag", "ROOT"] + ], + opt : { trim : true } +}); \ No newline at end of file diff --git a/node_modules/sax/test/stray-ending.js b/node_modules/sax/test/stray-ending.js new file mode 100644 index 0000000..bec467b --- /dev/null +++ b/node_modules/sax/test/stray-ending.js @@ -0,0 +1,17 @@ +// stray ending tags should just be ignored in non-strict mode. +// https://github.com/isaacs/sax-js/issues/32 +require(__dirname).test + ( { xml : + "" + , expect : + [ [ "opentag", { name: "A", attributes: {}, isSelfClosing: false } ] + , [ "opentag", { name: "B", attributes: {}, isSelfClosing: false } ] + , [ "text", "" ] + , [ "closetag", "B" ] + , [ "closetag", "A" ] + ] + , strict : false + , opt : {} + } + ) + diff --git a/node_modules/sax/test/trailing-attribute-no-value.js b/node_modules/sax/test/trailing-attribute-no-value.js new file mode 100644 index 0000000..222837f --- /dev/null +++ b/node_modules/sax/test/trailing-attribute-no-value.js @@ -0,0 +1,10 @@ + +require(__dirname).test({ + xml : + "", + expect : [ + ["attribute", {name:"ATTRIB", value:"attrib"}], + ["opentag", {name:"ROOT", attributes:{"ATTRIB":"attrib"}, isSelfClosing: false}] + ], + opt : { trim : true } +}); diff --git a/node_modules/sax/test/trailing-non-whitespace.js b/node_modules/sax/test/trailing-non-whitespace.js new file mode 100644 index 0000000..619578b --- /dev/null +++ b/node_modules/sax/test/trailing-non-whitespace.js @@ -0,0 +1,18 @@ + +require(__dirname).test({ + xml : "Welcome, to monkey land", + expect : [ + ["opentag", { + "name": "SPAN", + "attributes": {}, + isSelfClosing: false + }], + ["text", "Welcome,"], + ["closetag", "SPAN"], + ["text", " to monkey land"], + ["end"], + ["ready"] + ], + strict : false, + opt : {} +}); diff --git a/node_modules/sax/test/unclosed-root.js b/node_modules/sax/test/unclosed-root.js new file mode 100644 index 0000000..f4eeac6 --- /dev/null +++ b/node_modules/sax/test/unclosed-root.js @@ -0,0 +1,11 @@ +require(__dirname).test + ( { xml : "" + + , expect : + [ [ "opentag", { name: "root", attributes: {}, isSelfClosing: false } ] + , [ "error", "Unclosed root tag\nLine: 0\nColumn: 6\nChar: " ] + ] + , strict : true + , opt : {} + } + ) diff --git a/node_modules/sax/test/unquoted.js b/node_modules/sax/test/unquoted.js new file mode 100644 index 0000000..b3a9a81 --- /dev/null +++ b/node_modules/sax/test/unquoted.js @@ -0,0 +1,18 @@ +// unquoted attributes should be ok in non-strict mode +// https://github.com/isaacs/sax-js/issues/31 +require(__dirname).test + ( { xml : + "" + , expect : + [ [ "attribute", { name: "CLASS", value: "test" } ] + , [ "attribute", { name: "HELLO", value: "world" } ] + , [ "opentag", { name: "SPAN", + attributes: { CLASS: "test", HELLO: "world" }, + isSelfClosing: false } ] + , [ "closetag", "SPAN" ] + ] + , strict : false + , opt : {} + } + ) + diff --git a/node_modules/sax/test/utf8-split.js b/node_modules/sax/test/utf8-split.js new file mode 100644 index 0000000..e22bc10 --- /dev/null +++ b/node_modules/sax/test/utf8-split.js @@ -0,0 +1,32 @@ +var assert = require('assert') +var saxStream = require('../lib/sax').createStream() + +var b = new Buffer('误') + +saxStream.on('text', function(text) { + assert.equal(text, b.toString()) +}) + +saxStream.write(new Buffer('')) +saxStream.write(b.slice(0, 1)) +saxStream.write(b.slice(1)) +saxStream.write(new Buffer('')) +saxStream.write(b.slice(0, 2)) +saxStream.write(b.slice(2)) +saxStream.write(new Buffer('')) +saxStream.write(b) +saxStream.write(new Buffer('')) +saxStream.write(Buffer.concat([new Buffer(''), b.slice(0, 1)])) +saxStream.end(Buffer.concat([b.slice(1), new Buffer('')])) + +var saxStream2 = require('../lib/sax').createStream() + +saxStream2.on('text', function(text) { + assert.equal(text, '�') +}); + +saxStream2.write(new Buffer('')); +saxStream2.write(new Buffer([0xC0])); +saxStream2.write(new Buffer('')); +saxStream2.write(Buffer.concat([new Buffer(''), b.slice(0,1)])); +saxStream2.end(); diff --git a/node_modules/sax/test/xmlns-as-tag-name.js b/node_modules/sax/test/xmlns-as-tag-name.js new file mode 100644 index 0000000..99142ca --- /dev/null +++ b/node_modules/sax/test/xmlns-as-tag-name.js @@ -0,0 +1,15 @@ + +require(__dirname).test + ( { xml : + "" + , expect : + [ [ "opentag", { name: "xmlns", uri: "", prefix: "", local: "xmlns", + attributes: {}, ns: {}, + isSelfClosing: true} + ], + ["closetag", "xmlns"] + ] + , strict : true + , opt : { xmlns: true } + } + ); diff --git a/node_modules/sax/test/xmlns-issue-41.js b/node_modules/sax/test/xmlns-issue-41.js new file mode 100644 index 0000000..17ab45a --- /dev/null +++ b/node_modules/sax/test/xmlns-issue-41.js @@ -0,0 +1,68 @@ +var t = require(__dirname) + + , xmls = // should be the same both ways. + [ "" + , "" ] + + , ex1 = + [ [ "opennamespace" + , { prefix: "a" + , uri: "http://ATTRIBUTE" + } + ] + , [ "attribute" + , { name: "xmlns:a" + , value: "http://ATTRIBUTE" + , prefix: "xmlns" + , local: "a" + , uri: "http://www.w3.org/2000/xmlns/" + } + ] + , [ "attribute" + , { name: "a:attr" + , local: "attr" + , prefix: "a" + , uri: "http://ATTRIBUTE" + , value: "value" + } + ] + , [ "opentag" + , { name: "parent" + , uri: "" + , prefix: "" + , local: "parent" + , attributes: + { "a:attr": + { name: "a:attr" + , local: "attr" + , prefix: "a" + , uri: "http://ATTRIBUTE" + , value: "value" + } + , "xmlns:a": + { name: "xmlns:a" + , local: "a" + , prefix: "xmlns" + , uri: "http://www.w3.org/2000/xmlns/" + , value: "http://ATTRIBUTE" + } + } + , ns: {"a": "http://ATTRIBUTE"} + , isSelfClosing: true + } + ] + , ["closetag", "parent"] + , ["closenamespace", { prefix: "a", uri: "http://ATTRIBUTE" }] + ] + + // swap the order of elements 2 and 1 + , ex2 = [ex1[0], ex1[2], ex1[1]].concat(ex1.slice(3)) + , expected = [ex1, ex2] + +xmls.forEach(function (x, i) { + t.test({ xml: x + , expect: expected[i] + , strict: true + , opt: { xmlns: true } + }) +}) diff --git a/node_modules/sax/test/xmlns-rebinding.js b/node_modules/sax/test/xmlns-rebinding.js new file mode 100644 index 0000000..07e0425 --- /dev/null +++ b/node_modules/sax/test/xmlns-rebinding.js @@ -0,0 +1,63 @@ + +require(__dirname).test + ( { xml : + ""+ + ""+ + ""+ + ""+ + ""+ + "" + + , expect : + [ [ "opennamespace", { prefix: "x", uri: "x1" } ] + , [ "opennamespace", { prefix: "y", uri: "y1" } ] + , [ "attribute", { name: "xmlns:x", value: "x1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } ] + , [ "attribute", { name: "xmlns:y", value: "y1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "y" } ] + , [ "attribute", { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } ] + , [ "attribute", { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } ] + , [ "opentag", { name: "root", uri: "", prefix: "", local: "root", + attributes: { "xmlns:x": { name: "xmlns:x", value: "x1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } + , "xmlns:y": { name: "xmlns:y", value: "y1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "y" } + , "x:a": { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } + , "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } }, + ns: { x: 'x1', y: 'y1' }, + isSelfClosing: false } ] + + , [ "opennamespace", { prefix: "x", uri: "x2" } ] + , [ "attribute", { name: "xmlns:x", value: "x2", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } ] + , [ "opentag", { name: "rebind", uri: "", prefix: "", local: "rebind", + attributes: { "xmlns:x": { name: "xmlns:x", value: "x2", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } }, + ns: { x: 'x2' }, + isSelfClosing: false } ] + + , [ "attribute", { name: "x:a", value: "x2", uri: "x2", prefix: "x", local: "a" } ] + , [ "attribute", { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } ] + , [ "opentag", { name: "check", uri: "", prefix: "", local: "check", + attributes: { "x:a": { name: "x:a", value: "x2", uri: "x2", prefix: "x", local: "a" } + , "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } }, + ns: { x: 'x2' }, + isSelfClosing: true } ] + + , [ "closetag", "check" ] + + , [ "closetag", "rebind" ] + , [ "closenamespace", { prefix: "x", uri: "x2" } ] + + , [ "attribute", { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } ] + , [ "attribute", { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } ] + , [ "opentag", { name: "check", uri: "", prefix: "", local: "check", + attributes: { "x:a": { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } + , "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } }, + ns: { x: 'x1', y: 'y1' }, + isSelfClosing: true } ] + , [ "closetag", "check" ] + + , [ "closetag", "root" ] + , [ "closenamespace", { prefix: "x", uri: "x1" } ] + , [ "closenamespace", { prefix: "y", uri: "y1" } ] + ] + , strict : true + , opt : { xmlns: true } + } + ) + diff --git a/node_modules/sax/test/xmlns-strict.js b/node_modules/sax/test/xmlns-strict.js new file mode 100644 index 0000000..b5e3e51 --- /dev/null +++ b/node_modules/sax/test/xmlns-strict.js @@ -0,0 +1,74 @@ + +require(__dirname).test + ( { xml : + ""+ + ""+ + ""+ + ""+ + ""+ + ""+ + ""+ + ""+ + ""+ + "" + + , expect : + [ [ "opentag", { name: "root", prefix: "", local: "root", uri: "", + attributes: {}, ns: {}, isSelfClosing: false } ] + + , [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } ] + , [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "", + attributes: { "attr": { name: "attr", value: "normal", uri: "", prefix: "", local: "attr", uri: "" } }, + ns: {}, isSelfClosing: true } ] + , [ "closetag", "plain" ] + + , [ "opennamespace", { prefix: "", uri: "uri:default" } ] + + , [ "attribute", { name: "xmlns", value: "uri:default", prefix: "xmlns", local: "", uri: "http://www.w3.org/2000/xmlns/" } ] + , [ "opentag", { name: "ns1", prefix: "", local: "ns1", uri: "uri:default", + attributes: { "xmlns": { name: "xmlns", value: "uri:default", prefix: "xmlns", local: "", uri: "http://www.w3.org/2000/xmlns/" } }, + ns: { "": "uri:default" }, isSelfClosing: false } ] + + , [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } ] + , [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "uri:default", ns: { '': 'uri:default' }, + attributes: { "attr": { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } }, + isSelfClosing: true } ] + , [ "closetag", "plain" ] + + , [ "closetag", "ns1" ] + + , [ "closenamespace", { prefix: "", uri: "uri:default" } ] + + , [ "opennamespace", { prefix: "a", uri: "uri:nsa" } ] + + , [ "attribute", { name: "xmlns:a", value: "uri:nsa", prefix: "xmlns", local: "a", uri: "http://www.w3.org/2000/xmlns/" } ] + + , [ "opentag", { name: "ns2", prefix: "", local: "ns2", uri: "", + attributes: { "xmlns:a": { name: "xmlns:a", value: "uri:nsa", prefix: "xmlns", local: "a", uri: "http://www.w3.org/2000/xmlns/" } }, + ns: { a: "uri:nsa" }, isSelfClosing: false } ] + + , [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } ] + , [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "", + attributes: { "attr": { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } }, + ns: { a: 'uri:nsa' }, + isSelfClosing: true } ] + , [ "closetag", "plain" ] + + , [ "attribute", { name: "a:attr", value: "namespaced", prefix: "a", local: "attr", uri: "uri:nsa" } ] + , [ "opentag", { name: "a:ns", prefix: "a", local: "ns", uri: "uri:nsa", + attributes: { "a:attr": { name: "a:attr", value: "namespaced", prefix: "a", local: "attr", uri: "uri:nsa" } }, + ns: { a: 'uri:nsa' }, + isSelfClosing: true } ] + , [ "closetag", "a:ns" ] + + , [ "closetag", "ns2" ] + + , [ "closenamespace", { prefix: "a", uri: "uri:nsa" } ] + + , [ "closetag", "root" ] + ] + , strict : true + , opt : { xmlns: true } + } + ) + diff --git a/node_modules/sax/test/xmlns-unbound-element.js b/node_modules/sax/test/xmlns-unbound-element.js new file mode 100644 index 0000000..9d031a2 --- /dev/null +++ b/node_modules/sax/test/xmlns-unbound-element.js @@ -0,0 +1,33 @@ +require(__dirname).test( + { strict : true + , opt : { xmlns: true } + , expect : + [ [ "error", "Unbound namespace prefix: \"unbound:root\"\nLine: 0\nColumn: 15\nChar: >"] + , [ "opentag", { name: "unbound:root", uri: "unbound", prefix: "unbound", local: "root" + , attributes: {}, ns: {}, isSelfClosing: true } ] + , [ "closetag", "unbound:root" ] + ] + } +).write(""); + +require(__dirname).test( + { strict : true + , opt : { xmlns: true } + , expect : + [ [ "opennamespace", { prefix: "unbound", uri: "someuri" } ] + , [ "attribute", { name: 'xmlns:unbound', value: 'someuri' + , prefix: 'xmlns', local: 'unbound' + , uri: 'http://www.w3.org/2000/xmlns/' } ] + , [ "opentag", { name: "unbound:root", uri: "someuri", prefix: "unbound", local: "root" + , attributes: { 'xmlns:unbound': { + name: 'xmlns:unbound' + , value: 'someuri' + , prefix: 'xmlns' + , local: 'unbound' + , uri: 'http://www.w3.org/2000/xmlns/' } } + , ns: { "unbound": "someuri" }, isSelfClosing: true } ] + , [ "closetag", "unbound:root" ] + , [ "closenamespace", { prefix: 'unbound', uri: 'someuri' }] + ] + } +).write(""); diff --git a/node_modules/sax/test/xmlns-unbound.js b/node_modules/sax/test/xmlns-unbound.js new file mode 100644 index 0000000..b740e26 --- /dev/null +++ b/node_modules/sax/test/xmlns-unbound.js @@ -0,0 +1,15 @@ + +require(__dirname).test( + { strict : true + , opt : { xmlns: true } + , expect : + [ ["error", "Unbound namespace prefix: \"unbound\"\nLine: 0\nColumn: 28\nChar: >"] + + , [ "attribute", { name: "unbound:attr", value: "value", uri: "unbound", prefix: "unbound", local: "attr" } ] + , [ "opentag", { name: "root", uri: "", prefix: "", local: "root", + attributes: { "unbound:attr": { name: "unbound:attr", value: "value", uri: "unbound", prefix: "unbound", local: "attr" } }, + ns: {}, isSelfClosing: true } ] + , [ "closetag", "root" ] + ] + } +).write("") diff --git a/node_modules/sax/test/xmlns-xml-default-ns.js b/node_modules/sax/test/xmlns-xml-default-ns.js new file mode 100644 index 0000000..b1984d2 --- /dev/null +++ b/node_modules/sax/test/xmlns-xml-default-ns.js @@ -0,0 +1,31 @@ +var xmlns_attr = +{ + name: "xmlns", value: "http://foo", prefix: "xmlns", + local: "", uri : "http://www.w3.org/2000/xmlns/" +}; + +var attr_attr = +{ + name: "attr", value: "bar", prefix: "", + local : "attr", uri : "" +}; + + +require(__dirname).test + ( { xml : + "" + , expect : + [ [ "opennamespace", { prefix: "", uri: "http://foo" } ] + , [ "attribute", xmlns_attr ] + , [ "attribute", attr_attr ] + , [ "opentag", { name: "elm", prefix: "", local: "elm", uri : "http://foo", + ns : { "" : "http://foo" }, + attributes: { xmlns: xmlns_attr, attr: attr_attr }, + isSelfClosing: true } ] + , [ "closetag", "elm" ] + , [ "closenamespace", { prefix: "", uri: "http://foo"} ] + ] + , strict : true + , opt : {xmlns: true} + } + ) diff --git a/node_modules/sax/test/xmlns-xml-default-prefix-attribute.js b/node_modules/sax/test/xmlns-xml-default-prefix-attribute.js new file mode 100644 index 0000000..e41f218 --- /dev/null +++ b/node_modules/sax/test/xmlns-xml-default-prefix-attribute.js @@ -0,0 +1,36 @@ +require(__dirname).test( + { xml : "" + , expect : + [ [ "attribute" + , { name: "xml:lang" + , local: "lang" + , prefix: "xml" + , uri: "http://www.w3.org/XML/1998/namespace" + , value: "en" + } + ] + , [ "opentag" + , { name: "root" + , uri: "" + , prefix: "" + , local: "root" + , attributes: + { "xml:lang": + { name: "xml:lang" + , local: "lang" + , prefix: "xml" + , uri: "http://www.w3.org/XML/1998/namespace" + , value: "en" + } + } + , ns: {} + , isSelfClosing: true + } + ] + , ["closetag", "root"] + ] + , strict : true + , opt : { xmlns: true } + } +) + diff --git a/node_modules/sax/test/xmlns-xml-default-prefix.js b/node_modules/sax/test/xmlns-xml-default-prefix.js new file mode 100644 index 0000000..a85b478 --- /dev/null +++ b/node_modules/sax/test/xmlns-xml-default-prefix.js @@ -0,0 +1,21 @@ +require(__dirname).test( + { xml : "" + , expect : + [ + [ "opentag" + , { name: "xml:root" + , uri: "http://www.w3.org/XML/1998/namespace" + , prefix: "xml" + , local: "root" + , attributes: {} + , ns: {} + , isSelfClosing: true + } + ] + , ["closetag", "xml:root"] + ] + , strict : true + , opt : { xmlns: true } + } +) + diff --git a/node_modules/sax/test/xmlns-xml-default-redefine.js b/node_modules/sax/test/xmlns-xml-default-redefine.js new file mode 100644 index 0000000..d35d5a0 --- /dev/null +++ b/node_modules/sax/test/xmlns-xml-default-redefine.js @@ -0,0 +1,41 @@ +require(__dirname).test( + { xml : "" + , expect : + [ ["error" + , "xml: prefix must be bound to http://www.w3.org/XML/1998/namespace\n" + + "Actual: ERROR\n" + + "Line: 0\nColumn: 27\nChar: '" + ] + , [ "attribute" + , { name: "xmlns:xml" + , local: "xml" + , prefix: "xmlns" + , uri: "http://www.w3.org/2000/xmlns/" + , value: "ERROR" + } + ] + , [ "opentag" + , { name: "xml:root" + , uri: "http://www.w3.org/XML/1998/namespace" + , prefix: "xml" + , local: "root" + , attributes: + { "xmlns:xml": + { name: "xmlns:xml" + , local: "xml" + , prefix: "xmlns" + , uri: "http://www.w3.org/2000/xmlns/" + , value: "ERROR" + } + } + , ns: {} + , isSelfClosing: true + } + ] + , ["closetag", "xml:root"] + ] + , strict : true + , opt : { xmlns: true } + } +) + diff --git a/node_modules/semver/LICENSE b/node_modules/semver/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/node_modules/semver/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/semver/README.md b/node_modules/semver/README.md new file mode 100644 index 0000000..cbd9565 --- /dev/null +++ b/node_modules/semver/README.md @@ -0,0 +1,350 @@ +semver(1) -- The semantic versioner for npm +=========================================== + +## Usage + + $ npm install semver + $ node + var semver = require('semver') + + semver.valid('1.2.3') // '1.2.3' + semver.valid('a.b.c') // null + semver.clean(' =v1.2.3 ') // '1.2.3' + semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true + semver.gt('1.2.3', '9.8.7') // false + semver.lt('1.2.3', '9.8.7') // true + +As a command-line utility: + + $ semver -h + + SemVer 5.1.0 + + A JavaScript implementation of the http://semver.org/ specification + Copyright Isaac Z. Schlueter + + Usage: semver [options] [ [...]] + Prints valid versions sorted by SemVer precedence + + Options: + -r --range + Print versions that match the specified range. + + -i --increment [] + Increment a version by the specified level. Level can + be one of: major, minor, patch, premajor, preminor, + prepatch, or prerelease. Default level is 'patch'. + Only one version may be specified. + + --preid + Identifier to be used to prefix premajor, preminor, + prepatch or prerelease version increments. + + -l --loose + Interpret versions and ranges loosely + + Program exits successfully if any valid version satisfies + all supplied ranges, and prints all satisfying versions. + + If no satisfying versions are found, then exits failure. + + Versions are printed in ascending order, so supplying + multiple versions to the utility will just sort them. + +## Versions + +A "version" is described by the `v2.0.0` specification found at +. + +A leading `"="` or `"v"` character is stripped off and ignored. + +## Ranges + +A `version range` is a set of `comparators` which specify versions +that satisfy the range. + +A `comparator` is composed of an `operator` and a `version`. The set +of primitive `operators` is: + +* `<` Less than +* `<=` Less than or equal to +* `>` Greater than +* `>=` Greater than or equal to +* `=` Equal. If no operator is specified, then equality is assumed, + so this operator is optional, but MAY be included. + +For example, the comparator `>=1.2.7` would match the versions +`1.2.7`, `1.2.8`, `2.5.3`, and `1.3.9`, but not the versions `1.2.6` +or `1.1.0`. + +Comparators can be joined by whitespace to form a `comparator set`, +which is satisfied by the **intersection** of all of the comparators +it includes. + +A range is composed of one or more comparator sets, joined by `||`. A +version matches a range if and only if every comparator in at least +one of the `||`-separated comparator sets is satisfied by the version. + +For example, the range `>=1.2.7 <1.3.0` would match the versions +`1.2.7`, `1.2.8`, and `1.2.99`, but not the versions `1.2.6`, `1.3.0`, +or `1.1.0`. + +The range `1.2.7 || >=1.2.9 <2.0.0` would match the versions `1.2.7`, +`1.2.9`, and `1.4.6`, but not the versions `1.2.8` or `2.0.0`. + +### Prerelease Tags + +If a version has a prerelease tag (for example, `1.2.3-alpha.3`) then +it will only be allowed to satisfy comparator sets if at least one +comparator with the same `[major, minor, patch]` tuple also has a +prerelease tag. + +For example, the range `>1.2.3-alpha.3` would be allowed to match the +version `1.2.3-alpha.7`, but it would *not* be satisfied by +`3.4.5-alpha.9`, even though `3.4.5-alpha.9` is technically "greater +than" `1.2.3-alpha.3` according to the SemVer sort rules. The version +range only accepts prerelease tags on the `1.2.3` version. The +version `3.4.5` *would* satisfy the range, because it does not have a +prerelease flag, and `3.4.5` is greater than `1.2.3-alpha.7`. + +The purpose for this behavior is twofold. First, prerelease versions +frequently are updated very quickly, and contain many breaking changes +that are (by the author's design) not yet fit for public consumption. +Therefore, by default, they are excluded from range matching +semantics. + +Second, a user who has opted into using a prerelease version has +clearly indicated the intent to use *that specific* set of +alpha/beta/rc versions. By including a prerelease tag in the range, +the user is indicating that they are aware of the risk. However, it +is still not appropriate to assume that they have opted into taking a +similar risk on the *next* set of prerelease versions. + +#### Prerelease Identifiers + +The method `.inc` takes an additional `identifier` string argument that +will append the value of the string as a prerelease identifier: + +```javascript +> semver.inc('1.2.3', 'prerelease', 'beta') +'1.2.4-beta.0' +``` + +command-line example: + +```shell +$ semver 1.2.3 -i prerelease --preid beta +1.2.4-beta.0 +``` + +Which then can be used to increment further: + +```shell +$ semver 1.2.4-beta.0 -i prerelease +1.2.4-beta.1 +``` + +### Advanced Range Syntax + +Advanced range syntax desugars to primitive comparators in +deterministic ways. + +Advanced ranges may be combined in the same way as primitive +comparators using white space or `||`. + +#### Hyphen Ranges `X.Y.Z - A.B.C` + +Specifies an inclusive set. + +* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4` + +If a partial version is provided as the first version in the inclusive +range, then the missing pieces are replaced with zeroes. + +* `1.2 - 2.3.4` := `>=1.2.0 <=2.3.4` + +If a partial version is provided as the second version in the +inclusive range, then all versions that start with the supplied parts +of the tuple are accepted, but nothing that would be greater than the +provided tuple parts. + +* `1.2.3 - 2.3` := `>=1.2.3 <2.4.0` +* `1.2.3 - 2` := `>=1.2.3 <3.0.0` + +#### X-Ranges `1.2.x` `1.X` `1.2.*` `*` + +Any of `X`, `x`, or `*` may be used to "stand in" for one of the +numeric values in the `[major, minor, patch]` tuple. + +* `*` := `>=0.0.0` (Any version satisfies) +* `1.x` := `>=1.0.0 <2.0.0` (Matching major version) +* `1.2.x` := `>=1.2.0 <1.3.0` (Matching major and minor versions) + +A partial version range is treated as an X-Range, so the special +character is in fact optional. + +* `""` (empty string) := `*` := `>=0.0.0` +* `1` := `1.x.x` := `>=1.0.0 <2.0.0` +* `1.2` := `1.2.x` := `>=1.2.0 <1.3.0` + +#### Tilde Ranges `~1.2.3` `~1.2` `~1` + +Allows patch-level changes if a minor version is specified on the +comparator. Allows minor-level changes if not. + +* `~1.2.3` := `>=1.2.3 <1.(2+1).0` := `>=1.2.3 <1.3.0` +* `~1.2` := `>=1.2.0 <1.(2+1).0` := `>=1.2.0 <1.3.0` (Same as `1.2.x`) +* `~1` := `>=1.0.0 <(1+1).0.0` := `>=1.0.0 <2.0.0` (Same as `1.x`) +* `~0.2.3` := `>=0.2.3 <0.(2+1).0` := `>=0.2.3 <0.3.0` +* `~0.2` := `>=0.2.0 <0.(2+1).0` := `>=0.2.0 <0.3.0` (Same as `0.2.x`) +* `~0` := `>=0.0.0 <(0+1).0.0` := `>=0.0.0 <1.0.0` (Same as `0.x`) +* `~1.2.3-beta.2` := `>=1.2.3-beta.2 <1.3.0` Note that prereleases in + the `1.2.3` version will be allowed, if they are greater than or + equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but + `1.2.4-beta.2` would not, because it is a prerelease of a + different `[major, minor, patch]` tuple. + +#### Caret Ranges `^1.2.3` `^0.2.5` `^0.0.4` + +Allows changes that do not modify the left-most non-zero digit in the +`[major, minor, patch]` tuple. In other words, this allows patch and +minor updates for versions `1.0.0` and above, patch updates for +versions `0.X >=0.1.0`, and *no* updates for versions `0.0.X`. + +Many authors treat a `0.x` version as if the `x` were the major +"breaking-change" indicator. + +Caret ranges are ideal when an author may make breaking changes +between `0.2.4` and `0.3.0` releases, which is a common practice. +However, it presumes that there will *not* be breaking changes between +`0.2.4` and `0.2.5`. It allows for changes that are presumed to be +additive (but non-breaking), according to commonly observed practices. + +* `^1.2.3` := `>=1.2.3 <2.0.0` +* `^0.2.3` := `>=0.2.3 <0.3.0` +* `^0.0.3` := `>=0.0.3 <0.0.4` +* `^1.2.3-beta.2` := `>=1.2.3-beta.2 <2.0.0` Note that prereleases in + the `1.2.3` version will be allowed, if they are greater than or + equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but + `1.2.4-beta.2` would not, because it is a prerelease of a + different `[major, minor, patch]` tuple. +* `^0.0.3-beta` := `>=0.0.3-beta <0.0.4` Note that prereleases in the + `0.0.3` version *only* will be allowed, if they are greater than or + equal to `beta`. So, `0.0.3-pr.2` would be allowed. + +When parsing caret ranges, a missing `patch` value desugars to the +number `0`, but will allow flexibility within that value, even if the +major and minor versions are both `0`. + +* `^1.2.x` := `>=1.2.0 <2.0.0` +* `^0.0.x` := `>=0.0.0 <0.1.0` +* `^0.0` := `>=0.0.0 <0.1.0` + +A missing `minor` and `patch` values will desugar to zero, but also +allow flexibility within those values, even if the major version is +zero. + +* `^1.x` := `>=1.0.0 <2.0.0` +* `^0.x` := `>=0.0.0 <1.0.0` + +### Range Grammar + +Putting all this together, here is a Backus-Naur grammar for ranges, +for the benefit of parser authors: + +```bnf +range-set ::= range ( logical-or range ) * +logical-or ::= ( ' ' ) * '||' ( ' ' ) * +range ::= hyphen | simple ( ' ' simple ) * | '' +hyphen ::= partial ' - ' partial +simple ::= primitive | partial | tilde | caret +primitive ::= ( '<' | '>' | '>=' | '<=' | '=' | ) partial +partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )? +xr ::= 'x' | 'X' | '*' | nr +nr ::= '0' | ['1'-'9'] ( ['0'-'9'] ) * +tilde ::= '~' partial +caret ::= '^' partial +qualifier ::= ( '-' pre )? ( '+' build )? +pre ::= parts +build ::= parts +parts ::= part ( '.' part ) * +part ::= nr | [-0-9A-Za-z]+ +``` + +## Functions + +All methods and classes take a final `loose` boolean argument that, if +true, will be more forgiving about not-quite-valid semver strings. +The resulting output will always be 100% strict, of course. + +Strict-mode Comparators and Ranges will be strict about the SemVer +strings that they parse. + +* `valid(v)`: Return the parsed version, or null if it's not valid. +* `inc(v, release)`: Return the version incremented by the release + type (`major`, `premajor`, `minor`, `preminor`, `patch`, + `prepatch`, or `prerelease`), or null if it's not valid + * `premajor` in one call will bump the version up to the next major + version and down to a prerelease of that major version. + `preminor`, and `prepatch` work the same way. + * If called from a non-prerelease version, the `prerelease` will work the + same as `prepatch`. It increments the patch version, then makes a + prerelease. If the input version is already a prerelease it simply + increments it. +* `prerelease(v)`: Returns an array of prerelease components, or null + if none exist. Example: `prerelease('1.2.3-alpha.1') -> ['alpha', 1]` +* `major(v)`: Return the major version number. +* `minor(v)`: Return the minor version number. +* `patch(v)`: Return the patch version number. + +### Comparison + +* `gt(v1, v2)`: `v1 > v2` +* `gte(v1, v2)`: `v1 >= v2` +* `lt(v1, v2)`: `v1 < v2` +* `lte(v1, v2)`: `v1 <= v2` +* `eq(v1, v2)`: `v1 == v2` This is true if they're logically equivalent, + even if they're not the exact same string. You already know how to + compare strings. +* `neq(v1, v2)`: `v1 != v2` The opposite of `eq`. +* `cmp(v1, comparator, v2)`: Pass in a comparison string, and it'll call + the corresponding function above. `"==="` and `"!=="` do simple + string comparison, but are included for completeness. Throws if an + invalid comparison string is provided. +* `compare(v1, v2)`: Return `0` if `v1 == v2`, or `1` if `v1` is greater, or `-1` if + `v2` is greater. Sorts in ascending order if passed to `Array.sort()`. +* `rcompare(v1, v2)`: The reverse of compare. Sorts an array of versions + in descending order when passed to `Array.sort()`. +* `diff(v1, v2)`: Returns difference between two versions by the release type + (`major`, `premajor`, `minor`, `preminor`, `patch`, `prepatch`, or `prerelease`), + or null if the versions are the same. + + +### Ranges + +* `validRange(range)`: Return the valid range or null if it's not valid +* `satisfies(version, range)`: Return true if the version satisfies the + range. +* `maxSatisfying(versions, range)`: Return the highest version in the list + that satisfies the range, or `null` if none of them do. +* `minSatisfying(versions, range)`: Return the lowest version in the list + that satisfies the range, or `null` if none of them do. +* `gtr(version, range)`: Return `true` if version is greater than all the + versions possible in the range. +* `ltr(version, range)`: Return `true` if version is less than all the + versions possible in the range. +* `outside(version, range, hilo)`: Return true if the version is outside + the bounds of the range in either the high or low direction. The + `hilo` argument must be either the string `'>'` or `'<'`. (This is + the function called by `gtr` and `ltr`.) + +Note that, since ranges may be non-contiguous, a version might not be +greater than a range, less than a range, *or* satisfy a range! For +example, the range `1.2 <1.2.9 || >2.0.0` would have a hole from `1.2.9` +until `2.0.0`, so the version `1.2.10` would not be greater than the +range (because `2.0.1` satisfies, which is higher), nor less than the +range (since `1.2.8` satisfies, which is lower), and it also does not +satisfy the range. + +If you want to know if a version satisfies or does not satisfy a +range, use the `satisfies(version, range)` function. diff --git a/node_modules/semver/bin/semver b/node_modules/semver/bin/semver new file mode 100644 index 0000000..c5f2e85 --- /dev/null +++ b/node_modules/semver/bin/semver @@ -0,0 +1,133 @@ +#!/usr/bin/env node +// Standalone semver comparison program. +// Exits successfully and prints matching version(s) if +// any supplied version is valid and passes all tests. + +var argv = process.argv.slice(2) + , versions = [] + , range = [] + , gt = [] + , lt = [] + , eq = [] + , inc = null + , version = require("../package.json").version + , loose = false + , identifier = undefined + , semver = require("../semver") + , reverse = false + +main() + +function main () { + if (!argv.length) return help() + while (argv.length) { + var a = argv.shift() + var i = a.indexOf('=') + if (i !== -1) { + a = a.slice(0, i) + argv.unshift(a.slice(i + 1)) + } + switch (a) { + case "-rv": case "-rev": case "--rev": case "--reverse": + reverse = true + break + case "-l": case "--loose": + loose = true + break + case "-v": case "--version": + versions.push(argv.shift()) + break + case "-i": case "--inc": case "--increment": + switch (argv[0]) { + case "major": case "minor": case "patch": case "prerelease": + case "premajor": case "preminor": case "prepatch": + inc = argv.shift() + break + default: + inc = "patch" + break + } + break + case "--preid": + identifier = argv.shift() + break + case "-r": case "--range": + range.push(argv.shift()) + break + case "-h": case "--help": case "-?": + return help() + default: + versions.push(a) + break + } + } + + versions = versions.filter(function (v) { + return semver.valid(v, loose) + }) + if (!versions.length) return fail() + if (inc && (versions.length !== 1 || range.length)) + return failInc() + + for (var i = 0, l = range.length; i < l ; i ++) { + versions = versions.filter(function (v) { + return semver.satisfies(v, range[i], loose) + }) + if (!versions.length) return fail() + } + return success(versions) +} + +function failInc () { + console.error("--inc can only be used on a single version with no range") + fail() +} + +function fail () { process.exit(1) } + +function success () { + var compare = reverse ? "rcompare" : "compare" + versions.sort(function (a, b) { + return semver[compare](a, b, loose) + }).map(function (v) { + return semver.clean(v, loose) + }).map(function (v) { + return inc ? semver.inc(v, inc, loose, identifier) : v + }).forEach(function (v,i,_) { console.log(v) }) +} + +function help () { + console.log(["SemVer " + version + ,"" + ,"A JavaScript implementation of the http://semver.org/ specification" + ,"Copyright Isaac Z. Schlueter" + ,"" + ,"Usage: semver [options] [ [...]]" + ,"Prints valid versions sorted by SemVer precedence" + ,"" + ,"Options:" + ,"-r --range " + ," Print versions that match the specified range." + ,"" + ,"-i --increment []" + ," Increment a version by the specified level. Level can" + ," be one of: major, minor, patch, premajor, preminor," + ," prepatch, or prerelease. Default level is 'patch'." + ," Only one version may be specified." + ,"" + ,"--preid " + ," Identifier to be used to prefix premajor, preminor," + ," prepatch or prerelease version increments." + ,"" + ,"-l --loose" + ," Interpret versions and ranges loosely" + ,"" + ,"Program exits successfully if any valid version satisfies" + ,"all supplied ranges, and prints all satisfying versions." + ,"" + ,"If no satisfying versions are found, then exits failure." + ,"" + ,"Versions are printed in ascending order, so supplying" + ,"multiple versions to the utility will just sort them." + ].join("\n")) +} diff --git a/node_modules/semver/package.json b/node_modules/semver/package.json new file mode 100644 index 0000000..8da5329 --- /dev/null +++ b/node_modules/semver/package.json @@ -0,0 +1,95 @@ +{ + "_args": [ + [ + { + "raw": "semver@2 || 3 || 4 || 5", + "scope": null, + "escapedName": "semver", + "name": "semver", + "rawSpec": "2 || 3 || 4 || 5", + "spec": ">=2.0.0 <3.0.0||>=3.0.0 <4.0.0||>=4.0.0 <5.0.0||>=5.0.0 <6.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/normalize-package-data" + ] + ], + "_from": "semver@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0||>=4.0.0 <5.0.0||>=5.0.0 <6.0.0", + "_id": "semver@5.3.0", + "_inCache": true, + "_location": "/semver", + "_nodeVersion": "4.4.4", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/semver-5.3.0.tgz_1468515166602_0.9155273644719273" + }, + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "3.10.6", + "_phantomChildren": {}, + "_requested": { + "raw": "semver@2 || 3 || 4 || 5", + "scope": null, + "escapedName": "semver", + "name": "semver", + "rawSpec": "2 || 3 || 4 || 5", + "spec": ">=2.0.0 <3.0.0||>=3.0.0 <4.0.0||>=4.0.0 <5.0.0||>=5.0.0 <6.0.0", + "type": "range" + }, + "_requiredBy": [ + "/normalize-package-data", + "/ssh2-streams" + ], + "_resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "_shasum": "9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f", + "_shrinkwrap": null, + "_spec": "semver@2 || 3 || 4 || 5", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/normalize-package-data", + "bin": { + "semver": "./bin/semver" + }, + "bugs": { + "url": "https://github.com/npm/node-semver/issues" + }, + "dependencies": {}, + "description": "The semantic version parser used by npm.", + "devDependencies": { + "tap": "^2.0.0" + }, + "directories": {}, + "dist": { + "shasum": "9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f", + "tarball": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz" + }, + "files": [ + "bin", + "range.bnf", + "semver.js" + ], + "gitHead": "d21444a0658224b152ce54965d02dbe0856afb84", + "homepage": "https://github.com/npm/node-semver#readme", + "license": "ISC", + "main": "semver.js", + "maintainers": [ + { + "name": "isaacs", + "email": "isaacs@npmjs.com" + }, + { + "name": "othiym23", + "email": "ogd@aoaioxxysz.net" + } + ], + "name": "semver", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/node-semver.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "version": "5.3.0" +} diff --git a/node_modules/semver/range.bnf b/node_modules/semver/range.bnf new file mode 100644 index 0000000..25ebd5c --- /dev/null +++ b/node_modules/semver/range.bnf @@ -0,0 +1,16 @@ +range-set ::= range ( logical-or range ) * +logical-or ::= ( ' ' ) * '||' ( ' ' ) * +range ::= hyphen | simple ( ' ' simple ) * | '' +hyphen ::= partial ' - ' partial +simple ::= primitive | partial | tilde | caret +primitive ::= ( '<' | '>' | '>=' | '<=' | '=' | ) partial +partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )? +xr ::= 'x' | 'X' | '*' | nr +nr ::= '0' | ['1'-'9'] ( ['0'-'9'] ) * +tilde ::= '~' partial +caret ::= '^' partial +qualifier ::= ( '-' pre )? ( '+' build )? +pre ::= parts +build ::= parts +parts ::= part ( '.' part ) * +part ::= nr | [-0-9A-Za-z]+ diff --git a/node_modules/semver/semver.js b/node_modules/semver/semver.js new file mode 100644 index 0000000..5f1a3c5 --- /dev/null +++ b/node_modules/semver/semver.js @@ -0,0 +1,1203 @@ +exports = module.exports = SemVer; + +// The debug function is excluded entirely from the minified version. +/* nomin */ var debug; +/* nomin */ if (typeof process === 'object' && + /* nomin */ process.env && + /* nomin */ process.env.NODE_DEBUG && + /* nomin */ /\bsemver\b/i.test(process.env.NODE_DEBUG)) + /* nomin */ debug = function() { + /* nomin */ var args = Array.prototype.slice.call(arguments, 0); + /* nomin */ args.unshift('SEMVER'); + /* nomin */ console.log.apply(console, args); + /* nomin */ }; +/* nomin */ else + /* nomin */ debug = function() {}; + +// Note: this is the semver.org version of the spec that it implements +// Not necessarily the package version of this code. +exports.SEMVER_SPEC_VERSION = '2.0.0'; + +var MAX_LENGTH = 256; +var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; + +// The actual regexps go on exports.re +var re = exports.re = []; +var src = exports.src = []; +var R = 0; + +// The following Regular Expressions can be used for tokenizing, +// validating, and parsing SemVer version strings. + +// ## Numeric Identifier +// A single `0`, or a non-zero digit followed by zero or more digits. + +var NUMERICIDENTIFIER = R++; +src[NUMERICIDENTIFIER] = '0|[1-9]\\d*'; +var NUMERICIDENTIFIERLOOSE = R++; +src[NUMERICIDENTIFIERLOOSE] = '[0-9]+'; + + +// ## Non-numeric Identifier +// Zero or more digits, followed by a letter or hyphen, and then zero or +// more letters, digits, or hyphens. + +var NONNUMERICIDENTIFIER = R++; +src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*'; + + +// ## Main Version +// Three dot-separated numeric identifiers. + +var MAINVERSION = R++; +src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')'; + +var MAINVERSIONLOOSE = R++; +src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')'; + +// ## Pre-release Version Identifier +// A numeric identifier, or a non-numeric identifier. + +var PRERELEASEIDENTIFIER = R++; +src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + + '|' + src[NONNUMERICIDENTIFIER] + ')'; + +var PRERELEASEIDENTIFIERLOOSE = R++; +src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + + '|' + src[NONNUMERICIDENTIFIER] + ')'; + + +// ## Pre-release Version +// Hyphen, followed by one or more dot-separated pre-release version +// identifiers. + +var PRERELEASE = R++; +src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + + '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))'; + +var PRERELEASELOOSE = R++; +src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + + '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))'; + +// ## Build Metadata Identifier +// Any combination of digits, letters, or hyphens. + +var BUILDIDENTIFIER = R++; +src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+'; + +// ## Build Metadata +// Plus sign, followed by one or more period-separated build metadata +// identifiers. + +var BUILD = R++; +src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + + '(?:\\.' + src[BUILDIDENTIFIER] + ')*))'; + + +// ## Full Version String +// A main version, followed optionally by a pre-release version and +// build metadata. + +// Note that the only major, minor, patch, and pre-release sections of +// the version string are capturing groups. The build metadata is not a +// capturing group, because it should not ever be used in version +// comparison. + +var FULL = R++; +var FULLPLAIN = 'v?' + src[MAINVERSION] + + src[PRERELEASE] + '?' + + src[BUILD] + '?'; + +src[FULL] = '^' + FULLPLAIN + '$'; + +// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. +// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty +// common in the npm registry. +var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + + src[PRERELEASELOOSE] + '?' + + src[BUILD] + '?'; + +var LOOSE = R++; +src[LOOSE] = '^' + LOOSEPLAIN + '$'; + +var GTLT = R++; +src[GTLT] = '((?:<|>)?=?)'; + +// Something like "2.*" or "1.2.x". +// Note that "x.x" is a valid xRange identifer, meaning "any version" +// Only the first item is strictly required. +var XRANGEIDENTIFIERLOOSE = R++; +src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*'; +var XRANGEIDENTIFIER = R++; +src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*'; + +var XRANGEPLAIN = R++; +src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:' + src[PRERELEASE] + ')?' + + src[BUILD] + '?' + + ')?)?'; + +var XRANGEPLAINLOOSE = R++; +src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:' + src[PRERELEASELOOSE] + ')?' + + src[BUILD] + '?' + + ')?)?'; + +var XRANGE = R++; +src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$'; +var XRANGELOOSE = R++; +src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$'; + +// Tilde ranges. +// Meaning is "reasonably at or greater than" +var LONETILDE = R++; +src[LONETILDE] = '(?:~>?)'; + +var TILDETRIM = R++; +src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+'; +re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g'); +var tildeTrimReplace = '$1~'; + +var TILDE = R++; +src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$'; +var TILDELOOSE = R++; +src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$'; + +// Caret ranges. +// Meaning is "at least and backwards compatible with" +var LONECARET = R++; +src[LONECARET] = '(?:\\^)'; + +var CARETTRIM = R++; +src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+'; +re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g'); +var caretTrimReplace = '$1^'; + +var CARET = R++; +src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$'; +var CARETLOOSE = R++; +src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$'; + +// A simple gt/lt/eq thing, or just "" to indicate "any version" +var COMPARATORLOOSE = R++; +src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$'; +var COMPARATOR = R++; +src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$'; + + +// An expression to strip any whitespace between the gtlt and the thing +// it modifies, so that `> 1.2.3` ==> `>1.2.3` +var COMPARATORTRIM = R++; +src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + + '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')'; + +// this one has to use the /g flag +re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g'); +var comparatorTrimReplace = '$1$2$3'; + + +// Something like `1.2.3 - 1.2.4` +// Note that these all use the loose form, because they'll be +// checked against either the strict or loose comparator form +// later. +var HYPHENRANGE = R++; +src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAIN] + ')' + + '\\s*$'; + +var HYPHENRANGELOOSE = R++; +src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s*$'; + +// Star ranges basically just allow anything at all. +var STAR = R++; +src[STAR] = '(<|>)?=?\\s*\\*'; + +// Compile to actual regexp objects. +// All are flag-free, unless they were created above with a flag. +for (var i = 0; i < R; i++) { + debug(i, src[i]); + if (!re[i]) + re[i] = new RegExp(src[i]); +} + +exports.parse = parse; +function parse(version, loose) { + if (version instanceof SemVer) + return version; + + if (typeof version !== 'string') + return null; + + if (version.length > MAX_LENGTH) + return null; + + var r = loose ? re[LOOSE] : re[FULL]; + if (!r.test(version)) + return null; + + try { + return new SemVer(version, loose); + } catch (er) { + return null; + } +} + +exports.valid = valid; +function valid(version, loose) { + var v = parse(version, loose); + return v ? v.version : null; +} + + +exports.clean = clean; +function clean(version, loose) { + var s = parse(version.trim().replace(/^[=v]+/, ''), loose); + return s ? s.version : null; +} + +exports.SemVer = SemVer; + +function SemVer(version, loose) { + if (version instanceof SemVer) { + if (version.loose === loose) + return version; + else + version = version.version; + } else if (typeof version !== 'string') { + throw new TypeError('Invalid Version: ' + version); + } + + if (version.length > MAX_LENGTH) + throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') + + if (!(this instanceof SemVer)) + return new SemVer(version, loose); + + debug('SemVer', version, loose); + this.loose = loose; + var m = version.trim().match(loose ? re[LOOSE] : re[FULL]); + + if (!m) + throw new TypeError('Invalid Version: ' + version); + + this.raw = version; + + // these are actually numbers + this.major = +m[1]; + this.minor = +m[2]; + this.patch = +m[3]; + + if (this.major > MAX_SAFE_INTEGER || this.major < 0) + throw new TypeError('Invalid major version') + + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) + throw new TypeError('Invalid minor version') + + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) + throw new TypeError('Invalid patch version') + + // numberify any prerelease numeric ids + if (!m[4]) + this.prerelease = []; + else + this.prerelease = m[4].split('.').map(function(id) { + if (/^[0-9]+$/.test(id)) { + var num = +id; + if (num >= 0 && num < MAX_SAFE_INTEGER) + return num; + } + return id; + }); + + this.build = m[5] ? m[5].split('.') : []; + this.format(); +} + +SemVer.prototype.format = function() { + this.version = this.major + '.' + this.minor + '.' + this.patch; + if (this.prerelease.length) + this.version += '-' + this.prerelease.join('.'); + return this.version; +}; + +SemVer.prototype.toString = function() { + return this.version; +}; + +SemVer.prototype.compare = function(other) { + debug('SemVer.compare', this.version, this.loose, other); + if (!(other instanceof SemVer)) + other = new SemVer(other, this.loose); + + return this.compareMain(other) || this.comparePre(other); +}; + +SemVer.prototype.compareMain = function(other) { + if (!(other instanceof SemVer)) + other = new SemVer(other, this.loose); + + return compareIdentifiers(this.major, other.major) || + compareIdentifiers(this.minor, other.minor) || + compareIdentifiers(this.patch, other.patch); +}; + +SemVer.prototype.comparePre = function(other) { + if (!(other instanceof SemVer)) + other = new SemVer(other, this.loose); + + // NOT having a prerelease is > having one + if (this.prerelease.length && !other.prerelease.length) + return -1; + else if (!this.prerelease.length && other.prerelease.length) + return 1; + else if (!this.prerelease.length && !other.prerelease.length) + return 0; + + var i = 0; + do { + var a = this.prerelease[i]; + var b = other.prerelease[i]; + debug('prerelease compare', i, a, b); + if (a === undefined && b === undefined) + return 0; + else if (b === undefined) + return 1; + else if (a === undefined) + return -1; + else if (a === b) + continue; + else + return compareIdentifiers(a, b); + } while (++i); +}; + +// preminor will bump the version up to the next minor release, and immediately +// down to pre-release. premajor and prepatch work the same way. +SemVer.prototype.inc = function(release, identifier) { + switch (release) { + case 'premajor': + this.prerelease.length = 0; + this.patch = 0; + this.minor = 0; + this.major++; + this.inc('pre', identifier); + break; + case 'preminor': + this.prerelease.length = 0; + this.patch = 0; + this.minor++; + this.inc('pre', identifier); + break; + case 'prepatch': + // If this is already a prerelease, it will bump to the next version + // drop any prereleases that might already exist, since they are not + // relevant at this point. + this.prerelease.length = 0; + this.inc('patch', identifier); + this.inc('pre', identifier); + break; + // If the input is a non-prerelease version, this acts the same as + // prepatch. + case 'prerelease': + if (this.prerelease.length === 0) + this.inc('patch', identifier); + this.inc('pre', identifier); + break; + + case 'major': + // If this is a pre-major version, bump up to the same major version. + // Otherwise increment major. + // 1.0.0-5 bumps to 1.0.0 + // 1.1.0 bumps to 2.0.0 + if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) + this.major++; + this.minor = 0; + this.patch = 0; + this.prerelease = []; + break; + case 'minor': + // If this is a pre-minor version, bump up to the same minor version. + // Otherwise increment minor. + // 1.2.0-5 bumps to 1.2.0 + // 1.2.1 bumps to 1.3.0 + if (this.patch !== 0 || this.prerelease.length === 0) + this.minor++; + this.patch = 0; + this.prerelease = []; + break; + case 'patch': + // If this is not a pre-release version, it will increment the patch. + // If it is a pre-release it will bump up to the same patch version. + // 1.2.0-5 patches to 1.2.0 + // 1.2.0 patches to 1.2.1 + if (this.prerelease.length === 0) + this.patch++; + this.prerelease = []; + break; + // This probably shouldn't be used publicly. + // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. + case 'pre': + if (this.prerelease.length === 0) + this.prerelease = [0]; + else { + var i = this.prerelease.length; + while (--i >= 0) { + if (typeof this.prerelease[i] === 'number') { + this.prerelease[i]++; + i = -2; + } + } + if (i === -1) // didn't increment anything + this.prerelease.push(0); + } + if (identifier) { + // 1.2.0-beta.1 bumps to 1.2.0-beta.2, + // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + if (this.prerelease[0] === identifier) { + if (isNaN(this.prerelease[1])) + this.prerelease = [identifier, 0]; + } else + this.prerelease = [identifier, 0]; + } + break; + + default: + throw new Error('invalid increment argument: ' + release); + } + this.format(); + this.raw = this.version; + return this; +}; + +exports.inc = inc; +function inc(version, release, loose, identifier) { + if (typeof(loose) === 'string') { + identifier = loose; + loose = undefined; + } + + try { + return new SemVer(version, loose).inc(release, identifier).version; + } catch (er) { + return null; + } +} + +exports.diff = diff; +function diff(version1, version2) { + if (eq(version1, version2)) { + return null; + } else { + var v1 = parse(version1); + var v2 = parse(version2); + if (v1.prerelease.length || v2.prerelease.length) { + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return 'pre'+key; + } + } + } + return 'prerelease'; + } + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return key; + } + } + } + } +} + +exports.compareIdentifiers = compareIdentifiers; + +var numeric = /^[0-9]+$/; +function compareIdentifiers(a, b) { + var anum = numeric.test(a); + var bnum = numeric.test(b); + + if (anum && bnum) { + a = +a; + b = +b; + } + + return (anum && !bnum) ? -1 : + (bnum && !anum) ? 1 : + a < b ? -1 : + a > b ? 1 : + 0; +} + +exports.rcompareIdentifiers = rcompareIdentifiers; +function rcompareIdentifiers(a, b) { + return compareIdentifiers(b, a); +} + +exports.major = major; +function major(a, loose) { + return new SemVer(a, loose).major; +} + +exports.minor = minor; +function minor(a, loose) { + return new SemVer(a, loose).minor; +} + +exports.patch = patch; +function patch(a, loose) { + return new SemVer(a, loose).patch; +} + +exports.compare = compare; +function compare(a, b, loose) { + return new SemVer(a, loose).compare(b); +} + +exports.compareLoose = compareLoose; +function compareLoose(a, b) { + return compare(a, b, true); +} + +exports.rcompare = rcompare; +function rcompare(a, b, loose) { + return compare(b, a, loose); +} + +exports.sort = sort; +function sort(list, loose) { + return list.sort(function(a, b) { + return exports.compare(a, b, loose); + }); +} + +exports.rsort = rsort; +function rsort(list, loose) { + return list.sort(function(a, b) { + return exports.rcompare(a, b, loose); + }); +} + +exports.gt = gt; +function gt(a, b, loose) { + return compare(a, b, loose) > 0; +} + +exports.lt = lt; +function lt(a, b, loose) { + return compare(a, b, loose) < 0; +} + +exports.eq = eq; +function eq(a, b, loose) { + return compare(a, b, loose) === 0; +} + +exports.neq = neq; +function neq(a, b, loose) { + return compare(a, b, loose) !== 0; +} + +exports.gte = gte; +function gte(a, b, loose) { + return compare(a, b, loose) >= 0; +} + +exports.lte = lte; +function lte(a, b, loose) { + return compare(a, b, loose) <= 0; +} + +exports.cmp = cmp; +function cmp(a, op, b, loose) { + var ret; + switch (op) { + case '===': + if (typeof a === 'object') a = a.version; + if (typeof b === 'object') b = b.version; + ret = a === b; + break; + case '!==': + if (typeof a === 'object') a = a.version; + if (typeof b === 'object') b = b.version; + ret = a !== b; + break; + case '': case '=': case '==': ret = eq(a, b, loose); break; + case '!=': ret = neq(a, b, loose); break; + case '>': ret = gt(a, b, loose); break; + case '>=': ret = gte(a, b, loose); break; + case '<': ret = lt(a, b, loose); break; + case '<=': ret = lte(a, b, loose); break; + default: throw new TypeError('Invalid operator: ' + op); + } + return ret; +} + +exports.Comparator = Comparator; +function Comparator(comp, loose) { + if (comp instanceof Comparator) { + if (comp.loose === loose) + return comp; + else + comp = comp.value; + } + + if (!(this instanceof Comparator)) + return new Comparator(comp, loose); + + debug('comparator', comp, loose); + this.loose = loose; + this.parse(comp); + + if (this.semver === ANY) + this.value = ''; + else + this.value = this.operator + this.semver.version; + + debug('comp', this); +} + +var ANY = {}; +Comparator.prototype.parse = function(comp) { + var r = this.loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; + var m = comp.match(r); + + if (!m) + throw new TypeError('Invalid comparator: ' + comp); + + this.operator = m[1]; + if (this.operator === '=') + this.operator = ''; + + // if it literally is just '>' or '' then allow anything. + if (!m[2]) + this.semver = ANY; + else + this.semver = new SemVer(m[2], this.loose); +}; + +Comparator.prototype.toString = function() { + return this.value; +}; + +Comparator.prototype.test = function(version) { + debug('Comparator.test', version, this.loose); + + if (this.semver === ANY) + return true; + + if (typeof version === 'string') + version = new SemVer(version, this.loose); + + return cmp(version, this.operator, this.semver, this.loose); +}; + + +exports.Range = Range; +function Range(range, loose) { + if ((range instanceof Range) && range.loose === loose) + return range; + + if (!(this instanceof Range)) + return new Range(range, loose); + + this.loose = loose; + + // First, split based on boolean or || + this.raw = range; + this.set = range.split(/\s*\|\|\s*/).map(function(range) { + return this.parseRange(range.trim()); + }, this).filter(function(c) { + // throw out any that are not relevant for whatever reason + return c.length; + }); + + if (!this.set.length) { + throw new TypeError('Invalid SemVer Range: ' + range); + } + + this.format(); +} + +Range.prototype.format = function() { + this.range = this.set.map(function(comps) { + return comps.join(' ').trim(); + }).join('||').trim(); + return this.range; +}; + +Range.prototype.toString = function() { + return this.range; +}; + +Range.prototype.parseRange = function(range) { + var loose = this.loose; + range = range.trim(); + debug('range', range, loose); + // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` + var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE]; + range = range.replace(hr, hyphenReplace); + debug('hyphen replace', range); + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` + range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace); + debug('comparator trim', range, re[COMPARATORTRIM]); + + // `~ 1.2.3` => `~1.2.3` + range = range.replace(re[TILDETRIM], tildeTrimReplace); + + // `^ 1.2.3` => `^1.2.3` + range = range.replace(re[CARETTRIM], caretTrimReplace); + + // normalize spaces + range = range.split(/\s+/).join(' '); + + // At this point, the range is completely trimmed and + // ready to be split into comparators. + + var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; + var set = range.split(' ').map(function(comp) { + return parseComparator(comp, loose); + }).join(' ').split(/\s+/); + if (this.loose) { + // in loose mode, throw out any that are not valid comparators + set = set.filter(function(comp) { + return !!comp.match(compRe); + }); + } + set = set.map(function(comp) { + return new Comparator(comp, loose); + }); + + return set; +}; + +// Mostly just for testing and legacy API reasons +exports.toComparators = toComparators; +function toComparators(range, loose) { + return new Range(range, loose).set.map(function(comp) { + return comp.map(function(c) { + return c.value; + }).join(' ').trim().split(' '); + }); +} + +// comprised of xranges, tildes, stars, and gtlt's at this point. +// already replaced the hyphen ranges +// turn into a set of JUST comparators. +function parseComparator(comp, loose) { + debug('comp', comp); + comp = replaceCarets(comp, loose); + debug('caret', comp); + comp = replaceTildes(comp, loose); + debug('tildes', comp); + comp = replaceXRanges(comp, loose); + debug('xrange', comp); + comp = replaceStars(comp, loose); + debug('stars', comp); + return comp; +} + +function isX(id) { + return !id || id.toLowerCase() === 'x' || id === '*'; +} + +// ~, ~> --> * (any, kinda silly) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 +function replaceTildes(comp, loose) { + return comp.trim().split(/\s+/).map(function(comp) { + return replaceTilde(comp, loose); + }).join(' '); +} + +function replaceTilde(comp, loose) { + var r = loose ? re[TILDELOOSE] : re[TILDE]; + return comp.replace(r, function(_, M, m, p, pr) { + debug('tilde', comp, _, M, m, p, pr); + var ret; + + if (isX(M)) + ret = ''; + else if (isX(m)) + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; + else if (isX(p)) + // ~1.2 == >=1.2.0 <1.3.0 + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; + else if (pr) { + debug('replaceTilde pr', pr); + if (pr.charAt(0) !== '-') + pr = '-' + pr; + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + (+m + 1) + '.0'; + } else + // ~1.2.3 == >=1.2.3 <1.3.0 + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0'; + + debug('tilde return', ret); + return ret; + }); +} + +// ^ --> * (any, kinda silly) +// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 +// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 +// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 +// ^1.2.3 --> >=1.2.3 <2.0.0 +// ^1.2.0 --> >=1.2.0 <2.0.0 +function replaceCarets(comp, loose) { + return comp.trim().split(/\s+/).map(function(comp) { + return replaceCaret(comp, loose); + }).join(' '); +} + +function replaceCaret(comp, loose) { + debug('caret', comp, loose); + var r = loose ? re[CARETLOOSE] : re[CARET]; + return comp.replace(r, function(_, M, m, p, pr) { + debug('caret', comp, _, M, m, p, pr); + var ret; + + if (isX(M)) + ret = ''; + else if (isX(m)) + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; + else if (isX(p)) { + if (M === '0') + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; + else + ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0'; + } else if (pr) { + debug('replaceCaret pr', pr); + if (pr.charAt(0) !== '-') + pr = '-' + pr; + if (M === '0') { + if (m === '0') + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + m + '.' + (+p + 1); + else + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + (+m + 1) + '.0'; + } else + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + (+M + 1) + '.0.0'; + } else { + debug('no pr'); + if (M === '0') { + if (m === '0') + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + m + '.' + (+p + 1); + else + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0'; + } else + ret = '>=' + M + '.' + m + '.' + p + + ' <' + (+M + 1) + '.0.0'; + } + + debug('caret return', ret); + return ret; + }); +} + +function replaceXRanges(comp, loose) { + debug('replaceXRanges', comp, loose); + return comp.split(/\s+/).map(function(comp) { + return replaceXRange(comp, loose); + }).join(' '); +} + +function replaceXRange(comp, loose) { + comp = comp.trim(); + var r = loose ? re[XRANGELOOSE] : re[XRANGE]; + return comp.replace(r, function(ret, gtlt, M, m, p, pr) { + debug('xRange', comp, ret, gtlt, M, m, p, pr); + var xM = isX(M); + var xm = xM || isX(m); + var xp = xm || isX(p); + var anyX = xp; + + if (gtlt === '=' && anyX) + gtlt = ''; + + if (xM) { + if (gtlt === '>' || gtlt === '<') { + // nothing is allowed + ret = '<0.0.0'; + } else { + // nothing is forbidden + ret = '*'; + } + } else if (gtlt && anyX) { + // replace X with 0 + if (xm) + m = 0; + if (xp) + p = 0; + + if (gtlt === '>') { + // >1 => >=2.0.0 + // >1.2 => >=1.3.0 + // >1.2.3 => >= 1.2.4 + gtlt = '>='; + if (xm) { + M = +M + 1; + m = 0; + p = 0; + } else if (xp) { + m = +m + 1; + p = 0; + } + } else if (gtlt === '<=') { + // <=0.7.x is actually <0.8.0, since any 0.7.x should + // pass. Similarly, <=7.x is actually <8.0.0, etc. + gtlt = '<'; + if (xm) + M = +M + 1; + else + m = +m + 1; + } + + ret = gtlt + M + '.' + m + '.' + p; + } else if (xm) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; + } else if (xp) { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; + } + + debug('xRange return', ret); + + return ret; + }); +} + +// Because * is AND-ed with everything else in the comparator, +// and '' means "any version", just remove the *s entirely. +function replaceStars(comp, loose) { + debug('replaceStars', comp, loose); + // Looseness is ignored here. star is always as loose as it gets! + return comp.trim().replace(re[STAR], ''); +} + +// This function is passed to string.replace(re[HYPHENRANGE]) +// M, m, patch, prerelease, build +// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 +// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do +// 1.2 - 3.4 => >=1.2.0 <3.5.0 +function hyphenReplace($0, + from, fM, fm, fp, fpr, fb, + to, tM, tm, tp, tpr, tb) { + + if (isX(fM)) + from = ''; + else if (isX(fm)) + from = '>=' + fM + '.0.0'; + else if (isX(fp)) + from = '>=' + fM + '.' + fm + '.0'; + else + from = '>=' + from; + + if (isX(tM)) + to = ''; + else if (isX(tm)) + to = '<' + (+tM + 1) + '.0.0'; + else if (isX(tp)) + to = '<' + tM + '.' + (+tm + 1) + '.0'; + else if (tpr) + to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr; + else + to = '<=' + to; + + return (from + ' ' + to).trim(); +} + + +// if ANY of the sets match ALL of its comparators, then pass +Range.prototype.test = function(version) { + if (!version) + return false; + + if (typeof version === 'string') + version = new SemVer(version, this.loose); + + for (var i = 0; i < this.set.length; i++) { + if (testSet(this.set[i], version)) + return true; + } + return false; +}; + +function testSet(set, version) { + for (var i = 0; i < set.length; i++) { + if (!set[i].test(version)) + return false; + } + + if (version.prerelease.length) { + // Find the set of versions that are allowed to have prereleases + // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 + // That should allow `1.2.3-pr.2` to pass. + // However, `1.2.4-alpha.notready` should NOT be allowed, + // even though it's within the range set by the comparators. + for (var i = 0; i < set.length; i++) { + debug(set[i].semver); + if (set[i].semver === ANY) + continue; + + if (set[i].semver.prerelease.length > 0) { + var allowed = set[i].semver; + if (allowed.major === version.major && + allowed.minor === version.minor && + allowed.patch === version.patch) + return true; + } + } + + // Version has a -pre, but it's not one of the ones we like. + return false; + } + + return true; +} + +exports.satisfies = satisfies; +function satisfies(version, range, loose) { + try { + range = new Range(range, loose); + } catch (er) { + return false; + } + return range.test(version); +} + +exports.maxSatisfying = maxSatisfying; +function maxSatisfying(versions, range, loose) { + return versions.filter(function(version) { + return satisfies(version, range, loose); + }).sort(function(a, b) { + return rcompare(a, b, loose); + })[0] || null; +} + +exports.minSatisfying = minSatisfying; +function minSatisfying(versions, range, loose) { + return versions.filter(function(version) { + return satisfies(version, range, loose); + }).sort(function(a, b) { + return compare(a, b, loose); + })[0] || null; +} + +exports.validRange = validRange; +function validRange(range, loose) { + try { + // Return '*' instead of '' so that truthiness works. + // This will throw if it's invalid anyway + return new Range(range, loose).range || '*'; + } catch (er) { + return null; + } +} + +// Determine if version is less than all the versions possible in the range +exports.ltr = ltr; +function ltr(version, range, loose) { + return outside(version, range, '<', loose); +} + +// Determine if version is greater than all the versions possible in the range. +exports.gtr = gtr; +function gtr(version, range, loose) { + return outside(version, range, '>', loose); +} + +exports.outside = outside; +function outside(version, range, hilo, loose) { + version = new SemVer(version, loose); + range = new Range(range, loose); + + var gtfn, ltefn, ltfn, comp, ecomp; + switch (hilo) { + case '>': + gtfn = gt; + ltefn = lte; + ltfn = lt; + comp = '>'; + ecomp = '>='; + break; + case '<': + gtfn = lt; + ltefn = gte; + ltfn = gt; + comp = '<'; + ecomp = '<='; + break; + default: + throw new TypeError('Must provide a hilo val of "<" or ">"'); + } + + // If it satisifes the range it is not outside + if (satisfies(version, range, loose)) { + return false; + } + + // From now on, variable terms are as if we're in "gtr" mode. + // but note that everything is flipped for the "ltr" function. + + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i]; + + var high = null; + var low = null; + + comparators.forEach(function(comparator) { + if (comparator.semver === ANY) { + comparator = new Comparator('>=0.0.0') + } + high = high || comparator; + low = low || comparator; + if (gtfn(comparator.semver, high.semver, loose)) { + high = comparator; + } else if (ltfn(comparator.semver, low.semver, loose)) { + low = comparator; + } + }); + + // If the edge version comparator has a operator then our version + // isn't outside it + if (high.operator === comp || high.operator === ecomp) { + return false; + } + + // If the lowest version comparator has an operator and our version + // is less than it then it isn't higher than the range + if ((!low.operator || low.operator === comp) && + ltefn(version, low.semver)) { + return false; + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false; + } + } + return true; +} + +exports.prerelease = prerelease; +function prerelease(version, loose) { + var parsed = parse(version, loose); + return (parsed && parsed.prerelease.length) ? parsed.prerelease : null; +} diff --git a/node_modules/shelljs/.documentup.json b/node_modules/shelljs/.documentup.json new file mode 100644 index 0000000..57fe301 --- /dev/null +++ b/node_modules/shelljs/.documentup.json @@ -0,0 +1,6 @@ +{ + "name": "ShellJS", + "twitter": [ + "r2r" + ] +} diff --git a/node_modules/shelljs/.jshintrc b/node_modules/shelljs/.jshintrc new file mode 100644 index 0000000..a80c559 --- /dev/null +++ b/node_modules/shelljs/.jshintrc @@ -0,0 +1,7 @@ +{ + "loopfunc": true, + "sub": true, + "undef": true, + "unused": true, + "node": true +} \ No newline at end of file diff --git a/node_modules/shelljs/.npmignore b/node_modules/shelljs/.npmignore new file mode 100644 index 0000000..6b20c38 --- /dev/null +++ b/node_modules/shelljs/.npmignore @@ -0,0 +1,2 @@ +test/ +tmp/ \ No newline at end of file diff --git a/node_modules/shelljs/.travis.yml b/node_modules/shelljs/.travis.yml new file mode 100644 index 0000000..99cdc74 --- /dev/null +++ b/node_modules/shelljs/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - "0.8" + - "0.10" + - "0.11" diff --git a/node_modules/shelljs/LICENSE b/node_modules/shelljs/LICENSE new file mode 100644 index 0000000..1b35ee9 --- /dev/null +++ b/node_modules/shelljs/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2012, Artur Adib +All rights reserved. + +You may use this project under the terms of the New BSD license as follows: + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Artur Adib nor the + names of the contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL ARTUR ADIB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/node_modules/shelljs/README.md b/node_modules/shelljs/README.md new file mode 100644 index 0000000..51358bd --- /dev/null +++ b/node_modules/shelljs/README.md @@ -0,0 +1,569 @@ +# ShellJS - Unix shell commands for Node.js [![Build Status](https://secure.travis-ci.org/arturadib/shelljs.png)](http://travis-ci.org/arturadib/shelljs) + +ShellJS is a portable **(Windows/Linux/OS X)** implementation of Unix shell commands on top of the Node.js API. You can use it to eliminate your shell script's dependency on Unix while still keeping its familiar and powerful commands. You can also install it globally so you can run it from outside Node projects - say goodbye to those gnarly Bash scripts! + +The project is [unit-tested](http://travis-ci.org/arturadib/shelljs) and battled-tested in projects like: + ++ [PDF.js](http://github.com/mozilla/pdf.js) - Firefox's next-gen PDF reader ++ [Firebug](http://getfirebug.com/) - Firefox's infamous debugger ++ [JSHint](http://jshint.com) - Most popular JavaScript linter ++ [Zepto](http://zeptojs.com) - jQuery-compatible JavaScript library for modern browsers ++ [Yeoman](http://yeoman.io/) - Web application stack and development tool ++ [Deployd.com](http://deployd.com) - Open source PaaS for quick API backend generation + +and [many more](https://npmjs.org/browse/depended/shelljs). + +## Installing + +Via npm: + +```bash +$ npm install [-g] shelljs +``` + +If the global option `-g` is specified, the binary `shjs` will be installed. This makes it possible to +run ShellJS scripts much like any shell script from the command line, i.e. without requiring a `node_modules` folder: + +```bash +$ shjs my_script +``` + +You can also just copy `shell.js` into your project's directory, and `require()` accordingly. + + +## Examples + +### JavaScript + +```javascript +require('shelljs/global'); + +if (!which('git')) { + echo('Sorry, this script requires git'); + exit(1); +} + +// Copy files to release dir +mkdir('-p', 'out/Release'); +cp('-R', 'stuff/*', 'out/Release'); + +// Replace macros in each .js file +cd('lib'); +ls('*.js').forEach(function(file) { + sed('-i', 'BUILD_VERSION', 'v0.1.2', file); + sed('-i', /.*REMOVE_THIS_LINE.*\n/, '', file); + sed('-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, cat('macro.js'), file); +}); +cd('..'); + +// Run external tool synchronously +if (exec('git commit -am "Auto-commit"').code !== 0) { + echo('Error: Git commit failed'); + exit(1); +} +``` + +### CoffeeScript + +```coffeescript +require 'shelljs/global' + +if not which 'git' + echo 'Sorry, this script requires git' + exit 1 + +# Copy files to release dir +mkdir '-p', 'out/Release' +cp '-R', 'stuff/*', 'out/Release' + +# Replace macros in each .js file +cd 'lib' +for file in ls '*.js' + sed '-i', 'BUILD_VERSION', 'v0.1.2', file + sed '-i', /.*REMOVE_THIS_LINE.*\n/, '', file + sed '-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, cat 'macro.js', file +cd '..' + +# Run external tool synchronously +if (exec 'git commit -am "Auto-commit"').code != 0 + echo 'Error: Git commit failed' + exit 1 +``` + +## Global vs. Local + +The example above uses the convenience script `shelljs/global` to reduce verbosity. If polluting your global namespace is not desirable, simply require `shelljs`. + +Example: + +```javascript +var shell = require('shelljs'); +shell.echo('hello world'); +``` + +## Make tool + +A convenience script `shelljs/make` is also provided to mimic the behavior of a Unix Makefile. In this case all shell objects are global, and command line arguments will cause the script to execute only the corresponding function in the global `target` object. To avoid redundant calls, target functions are executed only once per script. + +Example (CoffeeScript): + +```coffeescript +require 'shelljs/make' + +target.all = -> + target.bundle() + target.docs() + +target.bundle = -> + cd __dirname + mkdir 'build' + cd 'lib' + (cat '*.js').to '../build/output.js' + +target.docs = -> + cd __dirname + mkdir 'docs' + cd 'lib' + for file in ls '*.js' + text = grep '//@', file # extract special comments + text.replace '//@', '' # remove comment tags + text.to 'docs/my_docs.md' +``` + +To run the target `all`, call the above script without arguments: `$ node make`. To run the target `docs`: `$ node make docs`, and so on. + + + + + + +## Command reference + + +All commands run synchronously, unless otherwise stated. + + +### cd('dir') +Changes to directory `dir` for the duration of the script + + +### pwd() +Returns the current directory. + + +### ls([options ,] path [,path ...]) +### ls([options ,] path_array) +Available options: + ++ `-R`: recursive ++ `-A`: all files (include files beginning with `.`, except for `.` and `..`) + +Examples: + +```javascript +ls('projs/*.js'); +ls('-R', '/users/me', '/tmp'); +ls('-R', ['/users/me', '/tmp']); // same as above +``` + +Returns array of files in the given path, or in current directory if no path provided. + + +### find(path [,path ...]) +### find(path_array) +Examples: + +```javascript +find('src', 'lib'); +find(['src', 'lib']); // same as above +find('.').filter(function(file) { return file.match(/\.js$/); }); +``` + +Returns array of all files (however deep) in the given paths. + +The main difference from `ls('-R', path)` is that the resulting file names +include the base directories, e.g. `lib/resources/file1` instead of just `file1`. + + +### cp([options ,] source [,source ...], dest) +### cp([options ,] source_array, dest) +Available options: + ++ `-f`: force ++ `-r, -R`: recursive + +Examples: + +```javascript +cp('file1', 'dir1'); +cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp'); +cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above +``` + +Copies files. The wildcard `*` is accepted. + + +### rm([options ,] file [, file ...]) +### rm([options ,] file_array) +Available options: + ++ `-f`: force ++ `-r, -R`: recursive + +Examples: + +```javascript +rm('-rf', '/tmp/*'); +rm('some_file.txt', 'another_file.txt'); +rm(['some_file.txt', 'another_file.txt']); // same as above +``` + +Removes files. The wildcard `*` is accepted. + + +### mv(source [, source ...], dest') +### mv(source_array, dest') +Available options: + ++ `f`: force + +Examples: + +```javascript +mv('-f', 'file', 'dir/'); +mv('file1', 'file2', 'dir/'); +mv(['file1', 'file2'], 'dir/'); // same as above +``` + +Moves files. The wildcard `*` is accepted. + + +### mkdir([options ,] dir [, dir ...]) +### mkdir([options ,] dir_array) +Available options: + ++ `p`: full path (will create intermediate dirs if necessary) + +Examples: + +```javascript +mkdir('-p', '/tmp/a/b/c/d', '/tmp/e/f/g'); +mkdir('-p', ['/tmp/a/b/c/d', '/tmp/e/f/g']); // same as above +``` + +Creates directories. + + +### test(expression) +Available expression primaries: + ++ `'-b', 'path'`: true if path is a block device ++ `'-c', 'path'`: true if path is a character device ++ `'-d', 'path'`: true if path is a directory ++ `'-e', 'path'`: true if path exists ++ `'-f', 'path'`: true if path is a regular file ++ `'-L', 'path'`: true if path is a symboilc link ++ `'-p', 'path'`: true if path is a pipe (FIFO) ++ `'-S', 'path'`: true if path is a socket + +Examples: + +```javascript +if (test('-d', path)) { /* do something with dir */ }; +if (!test('-f', path)) continue; // skip if it's a regular file +``` + +Evaluates expression using the available primaries and returns corresponding value. + + +### cat(file [, file ...]) +### cat(file_array) + +Examples: + +```javascript +var str = cat('file*.txt'); +var str = cat('file1', 'file2'); +var str = cat(['file1', 'file2']); // same as above +``` + +Returns a string containing the given file, or a concatenated string +containing the files if more than one file is given (a new line character is +introduced between each file). Wildcard `*` accepted. + + +### 'string'.to(file) + +Examples: + +```javascript +cat('input.txt').to('output.txt'); +``` + +Analogous to the redirection operator `>` in Unix, but works with JavaScript strings (such as +those returned by `cat`, `grep`, etc). _Like Unix redirections, `to()` will overwrite any existing file!_ + + +### 'string'.toEnd(file) + +Examples: + +```javascript +cat('input.txt').toEnd('output.txt'); +``` + +Analogous to the redirect-and-append operator `>>` in Unix, but works with JavaScript strings (such as +those returned by `cat`, `grep`, etc). + + +### sed([options ,] search_regex, replacement, file) +Available options: + ++ `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_ + +Examples: + +```javascript +sed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js'); +sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js'); +``` + +Reads an input string from `file` and performs a JavaScript `replace()` on the input +using the given search regex and replacement string or function. Returns the new string after replacement. + + +### grep([options ,] regex_filter, file [, file ...]) +### grep([options ,] regex_filter, file_array) +Available options: + ++ `-v`: Inverse the sense of the regex and print the lines not matching the criteria. + +Examples: + +```javascript +grep('-v', 'GLOBAL_VARIABLE', '*.js'); +grep('GLOBAL_VARIABLE', '*.js'); +``` + +Reads input string from given files and returns a string containing all lines of the +file that match the given `regex_filter`. Wildcard `*` accepted. + + +### which(command) + +Examples: + +```javascript +var nodeExec = which('node'); +``` + +Searches for `command` in the system's PATH. On Windows looks for `.exe`, `.cmd`, and `.bat` extensions. +Returns string containing the absolute path to the command. + + +### echo(string [,string ...]) + +Examples: + +```javascript +echo('hello world'); +var str = echo('hello world'); +``` + +Prints string to stdout, and returns string with additional utility methods +like `.to()`. + + +### pushd([options,] [dir | '-N' | '+N']) + +Available options: + ++ `-n`: Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated. + +Arguments: + ++ `dir`: Makes the current working directory be the top of the stack, and then executes the equivalent of `cd dir`. ++ `+N`: Brings the Nth directory (counting from the left of the list printed by dirs, starting with zero) to the top of the list by rotating the stack. ++ `-N`: Brings the Nth directory (counting from the right of the list printed by dirs, starting with zero) to the top of the list by rotating the stack. + +Examples: + +```javascript +// process.cwd() === '/usr' +pushd('/etc'); // Returns /etc /usr +pushd('+1'); // Returns /usr /etc +``` + +Save the current directory on the top of the directory stack and then cd to `dir`. With no arguments, pushd exchanges the top two directories. Returns an array of paths in the stack. + +### popd([options,] ['-N' | '+N']) + +Available options: + ++ `-n`: Suppresses the normal change of directory when removing directories from the stack, so that only the stack is manipulated. + +Arguments: + ++ `+N`: Removes the Nth directory (counting from the left of the list printed by dirs), starting with zero. ++ `-N`: Removes the Nth directory (counting from the right of the list printed by dirs), starting with zero. + +Examples: + +```javascript +echo(process.cwd()); // '/usr' +pushd('/etc'); // '/etc /usr' +echo(process.cwd()); // '/etc' +popd(); // '/usr' +echo(process.cwd()); // '/usr' +``` + +When no arguments are given, popd removes the top directory from the stack and performs a cd to the new top directory. The elements are numbered from 0 starting at the first directory listed with dirs; i.e., popd is equivalent to popd +0. Returns an array of paths in the stack. + +### dirs([options | '+N' | '-N']) + +Available options: + ++ `-c`: Clears the directory stack by deleting all of the elements. + +Arguments: + ++ `+N`: Displays the Nth directory (counting from the left of the list printed by dirs when invoked without options), starting with zero. ++ `-N`: Displays the Nth directory (counting from the right of the list printed by dirs when invoked without options), starting with zero. + +Display the list of currently remembered directories. Returns an array of paths in the stack, or a single path if +N or -N was specified. + +See also: pushd, popd + + +### ln(options, source, dest) +### ln(source, dest) +Available options: + ++ `s`: symlink ++ `f`: force + +Examples: + +```javascript +ln('file', 'newlink'); +ln('-sf', 'file', 'existing'); +``` + +Links source to dest. Use -f to force the link, should dest already exist. + + +### exit(code) +Exits the current process with the given exit code. + +### env['VAR_NAME'] +Object containing environment variables (both getter and setter). Shortcut to process.env. + +### exec(command [, options] [, callback]) +Available options (all `false` by default): + ++ `async`: Asynchronous execution. Defaults to true if a callback is provided. ++ `silent`: Do not echo program output to console. + +Examples: + +```javascript +var version = exec('node --version', {silent:true}).output; + +var child = exec('some_long_running_process', {async:true}); +child.stdout.on('data', function(data) { + /* ... do something with data ... */ +}); + +exec('some_long_running_process', function(code, output) { + console.log('Exit code:', code); + console.log('Program output:', output); +}); +``` + +Executes the given `command` _synchronously_, unless otherwise specified. +When in synchronous mode returns the object `{ code:..., output:... }`, containing the program's +`output` (stdout + stderr) and its exit `code`. Otherwise returns the child process object, and +the `callback` gets the arguments `(code, output)`. + +**Note:** For long-lived processes, it's best to run `exec()` asynchronously as +the current synchronous implementation uses a lot of CPU. This should be getting +fixed soon. + + +### chmod(octal_mode || octal_string, file) +### chmod(symbolic_mode, file) + +Available options: + ++ `-v`: output a diagnostic for every file processed ++ `-c`: like verbose but report only when a change is made ++ `-R`: change files and directories recursively + +Examples: + +```javascript +chmod(755, '/Users/brandon'); +chmod('755', '/Users/brandon'); // same as above +chmod('u+x', '/Users/brandon'); +``` + +Alters the permissions of a file or directory by either specifying the +absolute permissions in octal form or expressing the changes in symbols. +This command tries to mimic the POSIX behavior as much as possible. +Notable exceptions: + ++ In symbolic modes, 'a-r' and '-r' are identical. No consideration is + given to the umask. ++ There is no "quiet" option since default behavior is to run silent. + + +## Non-Unix commands + + +### tempdir() + +Examples: + +```javascript +var tmp = tempdir(); // "/tmp" for most *nix platforms +``` + +Searches and returns string containing a writeable, platform-dependent temporary directory. +Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir). + + +### error() +Tests if error occurred in the last command. Returns `null` if no error occurred, +otherwise returns string explaining the error + + +## Configuration + + +### config.silent +Example: + +```javascript +var silentState = config.silent; // save old silent state +config.silent = true; +/* ... */ +config.silent = silentState; // restore old silent state +``` + +Suppresses all command output if `true`, except for `echo()` calls. +Default is `false`. + +### config.fatal +Example: + +```javascript +config.fatal = true; +cp('this_file_does_not_exist', '/dev/null'); // dies here +/* more commands... */ +``` + +If `true` the script will die on errors. Default is `false`. diff --git a/node_modules/shelljs/bin/shjs b/node_modules/shelljs/bin/shjs new file mode 100644 index 0000000..d239a7a --- /dev/null +++ b/node_modules/shelljs/bin/shjs @@ -0,0 +1,51 @@ +#!/usr/bin/env node +require('../global'); + +if (process.argv.length < 3) { + console.log('ShellJS: missing argument (script name)'); + console.log(); + process.exit(1); +} + +var args, + scriptName = process.argv[2]; +env['NODE_PATH'] = __dirname + '/../..'; + +if (!scriptName.match(/\.js/) && !scriptName.match(/\.coffee/)) { + if (test('-f', scriptName + '.js')) + scriptName += '.js'; + if (test('-f', scriptName + '.coffee')) + scriptName += '.coffee'; +} + +if (!test('-f', scriptName)) { + console.log('ShellJS: script not found ('+scriptName+')'); + console.log(); + process.exit(1); +} + +args = process.argv.slice(3); + +for (var i = 0, l = args.length; i < l; i++) { + if (args[i][0] !== "-"){ + args[i] = '"' + args[i] + '"'; // fixes arguments with multiple words + } +} + +if (scriptName.match(/\.coffee$/)) { + // + // CoffeeScript + // + if (which('coffee')) { + exec('coffee ' + scriptName + ' ' + args.join(' '), { async: true }); + } else { + console.log('ShellJS: CoffeeScript interpreter not found'); + console.log(); + process.exit(1); + } +} else { + // + // JavaScript + // + exec('node ' + scriptName + ' ' + args.join(' '), { async: true }); +} diff --git a/node_modules/shelljs/global.js b/node_modules/shelljs/global.js new file mode 100644 index 0000000..97f0033 --- /dev/null +++ b/node_modules/shelljs/global.js @@ -0,0 +1,3 @@ +var shell = require('./shell.js'); +for (var cmd in shell) + global[cmd] = shell[cmd]; diff --git a/node_modules/shelljs/make.js b/node_modules/shelljs/make.js new file mode 100644 index 0000000..53e5e81 --- /dev/null +++ b/node_modules/shelljs/make.js @@ -0,0 +1,47 @@ +require('./global'); + +global.config.fatal = true; +global.target = {}; + +// This ensures we only execute the script targets after the entire script has +// been evaluated +var args = process.argv.slice(2); +setTimeout(function() { + var t; + + if (args.length === 1 && args[0] === '--help') { + console.log('Available targets:'); + for (t in global.target) + console.log(' ' + t); + return; + } + + // Wrap targets to prevent duplicate execution + for (t in global.target) { + (function(t, oldTarget){ + + // Wrap it + global.target[t] = function(force) { + if (oldTarget.done && !force) + return; + oldTarget.done = true; + return oldTarget.apply(oldTarget, arguments); + }; + + })(t, global.target[t]); + } + + // Execute desired targets + if (args.length > 0) { + args.forEach(function(arg) { + if (arg in global.target) + global.target[arg](); + else { + console.log('no such target: ' + arg); + } + }); + } else if ('all' in global.target) { + global.target.all(); + } + +}, 0); diff --git a/node_modules/shelljs/package.json b/node_modules/shelljs/package.json new file mode 100644 index 0000000..bca0af2 --- /dev/null +++ b/node_modules/shelljs/package.json @@ -0,0 +1,94 @@ +{ + "_args": [ + [ + { + "raw": "shelljs@0.3.x", + "scope": null, + "escapedName": "shelljs", + "name": "shelljs", + "rawSpec": "0.3.x", + "spec": ">=0.3.0 <0.4.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/jshint" + ] + ], + "_from": "shelljs@>=0.3.0 <0.4.0", + "_id": "shelljs@0.3.0", + "_inCache": true, + "_location": "/shelljs", + "_npmUser": { + "name": "artur", + "email": "arturadib@gmail.com" + }, + "_npmVersion": "1.3.11", + "_phantomChildren": {}, + "_requested": { + "raw": "shelljs@0.3.x", + "scope": null, + "escapedName": "shelljs", + "name": "shelljs", + "rawSpec": "0.3.x", + "spec": ">=0.3.0 <0.4.0", + "type": "range" + }, + "_requiredBy": [ + "/jshint" + ], + "_resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", + "_shasum": "3596e6307a781544f591f37da618360f31db57b1", + "_shrinkwrap": null, + "_spec": "shelljs@0.3.x", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/jshint", + "author": { + "name": "Artur Adib", + "email": "aadib@mozilla.com" + }, + "bin": { + "shjs": "./bin/shjs" + }, + "bugs": { + "url": "https://github.com/arturadib/shelljs/issues" + }, + "dependencies": {}, + "description": "Portable Unix shell commands for Node.js", + "devDependencies": { + "jshint": "~2.1.11" + }, + "directories": {}, + "dist": { + "shasum": "3596e6307a781544f591f37da618360f31db57b1", + "tarball": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz" + }, + "engines": { + "node": ">=0.8.0" + }, + "homepage": "http://github.com/arturadib/shelljs", + "keywords": [ + "unix", + "shell", + "makefile", + "make", + "jake", + "synchronous" + ], + "license": "BSD*", + "main": "./shell.js", + "maintainers": [ + { + "name": "artur", + "email": "arturadib@gmail.com" + } + ], + "name": "shelljs", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/arturadib/shelljs.git" + }, + "scripts": { + "test": "node scripts/run-tests" + }, + "version": "0.3.0" +} diff --git a/node_modules/shelljs/scripts/generate-docs.js b/node_modules/shelljs/scripts/generate-docs.js new file mode 100644 index 0000000..532fed9 --- /dev/null +++ b/node_modules/shelljs/scripts/generate-docs.js @@ -0,0 +1,21 @@ +#!/usr/bin/env node +require('../global'); + +echo('Appending docs to README.md'); + +cd(__dirname + '/..'); + +// Extract docs from shell.js +var docs = grep('//@', 'shell.js'); + +docs = docs.replace(/\/\/\@include (.+)/g, function(match, path) { + var file = path.match('.js$') ? path : path+'.js'; + return grep('//@', file); +}); + +// Remove '//@' +docs = docs.replace(/\/\/\@ ?/g, ''); +// Append docs to README +sed('-i', /## Command reference(.|\n)*/, '## Command reference\n\n' + docs, 'README.md'); + +echo('All done.'); diff --git a/node_modules/shelljs/scripts/run-tests.js b/node_modules/shelljs/scripts/run-tests.js new file mode 100644 index 0000000..f9d31e0 --- /dev/null +++ b/node_modules/shelljs/scripts/run-tests.js @@ -0,0 +1,50 @@ +#!/usr/bin/env node +require('../global'); + +var path = require('path'); + +var failed = false; + +// +// Lint +// +JSHINT_BIN = './node_modules/jshint/bin/jshint'; +cd(__dirname + '/..'); + +if (!test('-f', JSHINT_BIN)) { + echo('JSHint not found. Run `npm install` in the root dir first.'); + exit(1); +} + +if (exec(JSHINT_BIN + ' *.js test/*.js').code !== 0) { + failed = true; + echo('*** JSHINT FAILED! (return code != 0)'); + echo(); +} else { + echo('All JSHint tests passed'); + echo(); +} + +// +// Unit tests +// +cd(__dirname + '/../test'); +ls('*.js').forEach(function(file) { + echo('Running test:', file); + if (exec('node ' + file).code !== 123) { // 123 avoids false positives (e.g. premature exit) + failed = true; + echo('*** TEST FAILED! (missing exit code "123")'); + echo(); + } +}); + +if (failed) { + echo(); + echo('*******************************************************'); + echo('WARNING: Some tests did not pass!'); + echo('*******************************************************'); + exit(1); +} else { + echo(); + echo('All tests passed.'); +} diff --git a/node_modules/shelljs/shell.js b/node_modules/shelljs/shell.js new file mode 100644 index 0000000..54402c7 --- /dev/null +++ b/node_modules/shelljs/shell.js @@ -0,0 +1,157 @@ +// +// ShellJS +// Unix shell commands on top of Node's API +// +// Copyright (c) 2012 Artur Adib +// http://github.com/arturadib/shelljs +// + +var common = require('./src/common'); + + +//@ +//@ All commands run synchronously, unless otherwise stated. +//@ + +//@include ./src/cd +var _cd = require('./src/cd'); +exports.cd = common.wrap('cd', _cd); + +//@include ./src/pwd +var _pwd = require('./src/pwd'); +exports.pwd = common.wrap('pwd', _pwd); + +//@include ./src/ls +var _ls = require('./src/ls'); +exports.ls = common.wrap('ls', _ls); + +//@include ./src/find +var _find = require('./src/find'); +exports.find = common.wrap('find', _find); + +//@include ./src/cp +var _cp = require('./src/cp'); +exports.cp = common.wrap('cp', _cp); + +//@include ./src/rm +var _rm = require('./src/rm'); +exports.rm = common.wrap('rm', _rm); + +//@include ./src/mv +var _mv = require('./src/mv'); +exports.mv = common.wrap('mv', _mv); + +//@include ./src/mkdir +var _mkdir = require('./src/mkdir'); +exports.mkdir = common.wrap('mkdir', _mkdir); + +//@include ./src/test +var _test = require('./src/test'); +exports.test = common.wrap('test', _test); + +//@include ./src/cat +var _cat = require('./src/cat'); +exports.cat = common.wrap('cat', _cat); + +//@include ./src/to +var _to = require('./src/to'); +String.prototype.to = common.wrap('to', _to); + +//@include ./src/toEnd +var _toEnd = require('./src/toEnd'); +String.prototype.toEnd = common.wrap('toEnd', _toEnd); + +//@include ./src/sed +var _sed = require('./src/sed'); +exports.sed = common.wrap('sed', _sed); + +//@include ./src/grep +var _grep = require('./src/grep'); +exports.grep = common.wrap('grep', _grep); + +//@include ./src/which +var _which = require('./src/which'); +exports.which = common.wrap('which', _which); + +//@include ./src/echo +var _echo = require('./src/echo'); +exports.echo = _echo; // don't common.wrap() as it could parse '-options' + +//@include ./src/dirs +var _dirs = require('./src/dirs').dirs; +exports.dirs = common.wrap("dirs", _dirs); +var _pushd = require('./src/dirs').pushd; +exports.pushd = common.wrap('pushd', _pushd); +var _popd = require('./src/dirs').popd; +exports.popd = common.wrap("popd", _popd); + +//@include ./src/ln +var _ln = require('./src/ln'); +exports.ln = common.wrap('ln', _ln); + +//@ +//@ ### exit(code) +//@ Exits the current process with the given exit code. +exports.exit = process.exit; + +//@ +//@ ### env['VAR_NAME'] +//@ Object containing environment variables (both getter and setter). Shortcut to process.env. +exports.env = process.env; + +//@include ./src/exec +var _exec = require('./src/exec'); +exports.exec = common.wrap('exec', _exec, {notUnix:true}); + +//@include ./src/chmod +var _chmod = require('./src/chmod'); +exports.chmod = common.wrap('chmod', _chmod); + + + +//@ +//@ ## Non-Unix commands +//@ + +//@include ./src/tempdir +var _tempDir = require('./src/tempdir'); +exports.tempdir = common.wrap('tempdir', _tempDir); + + +//@include ./src/error +var _error = require('./src/error'); +exports.error = _error; + + + +//@ +//@ ## Configuration +//@ + +exports.config = common.config; + +//@ +//@ ### config.silent +//@ Example: +//@ +//@ ```javascript +//@ var silentState = config.silent; // save old silent state +//@ config.silent = true; +//@ /* ... */ +//@ config.silent = silentState; // restore old silent state +//@ ``` +//@ +//@ Suppresses all command output if `true`, except for `echo()` calls. +//@ Default is `false`. + +//@ +//@ ### config.fatal +//@ Example: +//@ +//@ ```javascript +//@ config.fatal = true; +//@ cp('this_file_does_not_exist', '/dev/null'); // dies here +//@ /* more commands... */ +//@ ``` +//@ +//@ If `true` the script will die on errors. Default is `false`. diff --git a/node_modules/shelljs/src/cat.js b/node_modules/shelljs/src/cat.js new file mode 100644 index 0000000..f6f4d25 --- /dev/null +++ b/node_modules/shelljs/src/cat.js @@ -0,0 +1,43 @@ +var common = require('./common'); +var fs = require('fs'); + +//@ +//@ ### cat(file [, file ...]) +//@ ### cat(file_array) +//@ +//@ Examples: +//@ +//@ ```javascript +//@ var str = cat('file*.txt'); +//@ var str = cat('file1', 'file2'); +//@ var str = cat(['file1', 'file2']); // same as above +//@ ``` +//@ +//@ Returns a string containing the given file, or a concatenated string +//@ containing the files if more than one file is given (a new line character is +//@ introduced between each file). Wildcard `*` accepted. +function _cat(options, files) { + var cat = ''; + + if (!files) + common.error('no paths given'); + + if (typeof files === 'string') + files = [].slice.call(arguments, 1); + // if it's array leave it as it is + + files = common.expand(files); + + files.forEach(function(file) { + if (!fs.existsSync(file)) + common.error('no such file or directory: ' + file); + + cat += fs.readFileSync(file, 'utf8') + '\n'; + }); + + if (cat[cat.length-1] === '\n') + cat = cat.substring(0, cat.length-1); + + return common.ShellString(cat); +} +module.exports = _cat; diff --git a/node_modules/shelljs/src/cd.js b/node_modules/shelljs/src/cd.js new file mode 100644 index 0000000..230f432 --- /dev/null +++ b/node_modules/shelljs/src/cd.js @@ -0,0 +1,19 @@ +var fs = require('fs'); +var common = require('./common'); + +//@ +//@ ### cd('dir') +//@ Changes to directory `dir` for the duration of the script +function _cd(options, dir) { + if (!dir) + common.error('directory not specified'); + + if (!fs.existsSync(dir)) + common.error('no such file or directory: ' + dir); + + if (!fs.statSync(dir).isDirectory()) + common.error('not a directory: ' + dir); + + process.chdir(dir); +} +module.exports = _cd; diff --git a/node_modules/shelljs/src/chmod.js b/node_modules/shelljs/src/chmod.js new file mode 100644 index 0000000..f288893 --- /dev/null +++ b/node_modules/shelljs/src/chmod.js @@ -0,0 +1,208 @@ +var common = require('./common'); +var fs = require('fs'); +var path = require('path'); + +var PERMS = (function (base) { + return { + OTHER_EXEC : base.EXEC, + OTHER_WRITE : base.WRITE, + OTHER_READ : base.READ, + + GROUP_EXEC : base.EXEC << 3, + GROUP_WRITE : base.WRITE << 3, + GROUP_READ : base.READ << 3, + + OWNER_EXEC : base.EXEC << 6, + OWNER_WRITE : base.WRITE << 6, + OWNER_READ : base.READ << 6, + + // Literal octal numbers are apparently not allowed in "strict" javascript. Using parseInt is + // the preferred way, else a jshint warning is thrown. + STICKY : parseInt('01000', 8), + SETGID : parseInt('02000', 8), + SETUID : parseInt('04000', 8), + + TYPE_MASK : parseInt('0770000', 8) + }; +})({ + EXEC : 1, + WRITE : 2, + READ : 4 +}); + +//@ +//@ ### chmod(octal_mode || octal_string, file) +//@ ### chmod(symbolic_mode, file) +//@ +//@ Available options: +//@ +//@ + `-v`: output a diagnostic for every file processed//@ +//@ + `-c`: like verbose but report only when a change is made//@ +//@ + `-R`: change files and directories recursively//@ +//@ +//@ Examples: +//@ +//@ ```javascript +//@ chmod(755, '/Users/brandon'); +//@ chmod('755', '/Users/brandon'); // same as above +//@ chmod('u+x', '/Users/brandon'); +//@ ``` +//@ +//@ Alters the permissions of a file or directory by either specifying the +//@ absolute permissions in octal form or expressing the changes in symbols. +//@ This command tries to mimic the POSIX behavior as much as possible. +//@ Notable exceptions: +//@ +//@ + In symbolic modes, 'a-r' and '-r' are identical. No consideration is +//@ given to the umask. +//@ + There is no "quiet" option since default behavior is to run silent. +function _chmod(options, mode, filePattern) { + if (!filePattern) { + if (options.length > 0 && options.charAt(0) === '-') { + // Special case where the specified file permissions started with - to subtract perms, which + // get picked up by the option parser as command flags. + // If we are down by one argument and options starts with -, shift everything over. + filePattern = mode; + mode = options; + options = ''; + } + else { + common.error('You must specify a file.'); + } + } + + options = common.parseOptions(options, { + 'R': 'recursive', + 'c': 'changes', + 'v': 'verbose' + }); + + if (typeof filePattern === 'string') { + filePattern = [ filePattern ]; + } + + var files; + + if (options.recursive) { + files = []; + common.expand(filePattern).forEach(function addFile(expandedFile) { + var stat = fs.lstatSync(expandedFile); + + if (!stat.isSymbolicLink()) { + files.push(expandedFile); + + if (stat.isDirectory()) { // intentionally does not follow symlinks. + fs.readdirSync(expandedFile).forEach(function (child) { + addFile(expandedFile + '/' + child); + }); + } + } + }); + } + else { + files = common.expand(filePattern); + } + + files.forEach(function innerChmod(file) { + file = path.resolve(file); + if (!fs.existsSync(file)) { + common.error('File not found: ' + file); + } + + // When recursing, don't follow symlinks. + if (options.recursive && fs.lstatSync(file).isSymbolicLink()) { + return; + } + + var perms = fs.statSync(file).mode; + var type = perms & PERMS.TYPE_MASK; + + var newPerms = perms; + + if (isNaN(parseInt(mode, 8))) { + // parse options + mode.split(',').forEach(function (symbolicMode) { + /*jshint regexdash:true */ + var pattern = /([ugoa]*)([=\+-])([rwxXst]*)/i; + var matches = pattern.exec(symbolicMode); + + if (matches) { + var applyTo = matches[1]; + var operator = matches[2]; + var change = matches[3]; + + var changeOwner = applyTo.indexOf('u') != -1 || applyTo === 'a' || applyTo === ''; + var changeGroup = applyTo.indexOf('g') != -1 || applyTo === 'a' || applyTo === ''; + var changeOther = applyTo.indexOf('o') != -1 || applyTo === 'a' || applyTo === ''; + + var changeRead = change.indexOf('r') != -1; + var changeWrite = change.indexOf('w') != -1; + var changeExec = change.indexOf('x') != -1; + var changeSticky = change.indexOf('t') != -1; + var changeSetuid = change.indexOf('s') != -1; + + var mask = 0; + if (changeOwner) { + mask |= (changeRead ? PERMS.OWNER_READ : 0) + (changeWrite ? PERMS.OWNER_WRITE : 0) + (changeExec ? PERMS.OWNER_EXEC : 0) + (changeSetuid ? PERMS.SETUID : 0); + } + if (changeGroup) { + mask |= (changeRead ? PERMS.GROUP_READ : 0) + (changeWrite ? PERMS.GROUP_WRITE : 0) + (changeExec ? PERMS.GROUP_EXEC : 0) + (changeSetuid ? PERMS.SETGID : 0); + } + if (changeOther) { + mask |= (changeRead ? PERMS.OTHER_READ : 0) + (changeWrite ? PERMS.OTHER_WRITE : 0) + (changeExec ? PERMS.OTHER_EXEC : 0); + } + + // Sticky bit is special - it's not tied to user, group or other. + if (changeSticky) { + mask |= PERMS.STICKY; + } + + switch (operator) { + case '+': + newPerms |= mask; + break; + + case '-': + newPerms &= ~mask; + break; + + case '=': + newPerms = type + mask; + + // According to POSIX, when using = to explicitly set the permissions, setuid and setgid can never be cleared. + if (fs.statSync(file).isDirectory()) { + newPerms |= (PERMS.SETUID + PERMS.SETGID) & perms; + } + break; + } + + if (options.verbose) { + log(file + ' -> ' + newPerms.toString(8)); + } + + if (perms != newPerms) { + if (!options.verbose && options.changes) { + log(file + ' -> ' + newPerms.toString(8)); + } + fs.chmodSync(file, newPerms); + } + } + else { + common.error('Invalid symbolic mode change: ' + symbolicMode); + } + }); + } + else { + // they gave us a full number + newPerms = type + parseInt(mode, 8); + + // POSIX rules are that setuid and setgid can only be added using numeric form, but not cleared. + if (fs.statSync(file).isDirectory()) { + newPerms |= (PERMS.SETUID + PERMS.SETGID) & perms; + } + + fs.chmodSync(file, newPerms); + } + }); +} +module.exports = _chmod; diff --git a/node_modules/shelljs/src/common.js b/node_modules/shelljs/src/common.js new file mode 100644 index 0000000..d8c2312 --- /dev/null +++ b/node_modules/shelljs/src/common.js @@ -0,0 +1,203 @@ +var os = require('os'); +var fs = require('fs'); +var _ls = require('./ls'); + +// Module globals +var config = { + silent: false, + fatal: false +}; +exports.config = config; + +var state = { + error: null, + currentCmd: 'shell.js', + tempDir: null +}; +exports.state = state; + +var platform = os.type().match(/^Win/) ? 'win' : 'unix'; +exports.platform = platform; + +function log() { + if (!config.silent) + console.log.apply(this, arguments); +} +exports.log = log; + +// Shows error message. Throws unless _continue or config.fatal are true +function error(msg, _continue) { + if (state.error === null) + state.error = ''; + state.error += state.currentCmd + ': ' + msg + '\n'; + + if (msg.length > 0) + log(state.error); + + if (config.fatal) + process.exit(1); + + if (!_continue) + throw ''; +} +exports.error = error; + +// In the future, when Proxies are default, we can add methods like `.to()` to primitive strings. +// For now, this is a dummy function to bookmark places we need such strings +function ShellString(str) { + return str; +} +exports.ShellString = ShellString; + +// Returns {'alice': true, 'bob': false} when passed a dictionary, e.g.: +// parseOptions('-a', {'a':'alice', 'b':'bob'}); +function parseOptions(str, map) { + if (!map) + error('parseOptions() internal error: no map given'); + + // All options are false by default + var options = {}; + for (var letter in map) + options[map[letter]] = false; + + if (!str) + return options; // defaults + + if (typeof str !== 'string') + error('parseOptions() internal error: wrong str'); + + // e.g. match[1] = 'Rf' for str = '-Rf' + var match = str.match(/^\-(.+)/); + if (!match) + return options; + + // e.g. chars = ['R', 'f'] + var chars = match[1].split(''); + + chars.forEach(function(c) { + if (c in map) + options[map[c]] = true; + else + error('option not recognized: '+c); + }); + + return options; +} +exports.parseOptions = parseOptions; + +// Expands wildcards with matching (ie. existing) file names. +// For example: +// expand(['file*.js']) = ['file1.js', 'file2.js', ...] +// (if the files 'file1.js', 'file2.js', etc, exist in the current dir) +function expand(list) { + var expanded = []; + list.forEach(function(listEl) { + // Wildcard present on directory names ? + if(listEl.search(/\*[^\/]*\//) > -1 || listEl.search(/\*\*[^\/]*\//) > -1) { + var match = listEl.match(/^([^*]+\/|)(.*)/); + var root = match[1]; + var rest = match[2]; + var restRegex = rest.replace(/\*\*/g, ".*").replace(/\*/g, "[^\\/]*"); + restRegex = new RegExp(restRegex); + + _ls('-R', root).filter(function (e) { + return restRegex.test(e); + }).forEach(function(file) { + expanded.push(file); + }); + } + // Wildcard present on file names ? + else if (listEl.search(/\*/) > -1) { + _ls('', listEl).forEach(function(file) { + expanded.push(file); + }); + } else { + expanded.push(listEl); + } + }); + return expanded; +} +exports.expand = expand; + +// Normalizes _unlinkSync() across platforms to match Unix behavior, i.e. +// file can be unlinked even if it's read-only, see https://github.com/joyent/node/issues/3006 +function unlinkSync(file) { + try { + fs.unlinkSync(file); + } catch(e) { + // Try to override file permission + if (e.code === 'EPERM') { + fs.chmodSync(file, '0666'); + fs.unlinkSync(file); + } else { + throw e; + } + } +} +exports.unlinkSync = unlinkSync; + +// e.g. 'shelljs_a5f185d0443ca...' +function randomFileName() { + function randomHash(count) { + if (count === 1) + return parseInt(16*Math.random(), 10).toString(16); + else { + var hash = ''; + for (var i=0; i and/or '); + } else if (arguments.length > 3) { + sources = [].slice.call(arguments, 1, arguments.length - 1); + dest = arguments[arguments.length - 1]; + } else if (typeof sources === 'string') { + sources = [sources]; + } else if ('length' in sources) { + sources = sources; // no-op for array + } else { + common.error('invalid arguments'); + } + + var exists = fs.existsSync(dest), + stats = exists && fs.statSync(dest); + + // Dest is not existing dir, but multiple sources given + if ((!exists || !stats.isDirectory()) && sources.length > 1) + common.error('dest is not a directory (too many sources)'); + + // Dest is an existing file, but no -f given + if (exists && stats.isFile() && !options.force) + common.error('dest file already exists: ' + dest); + + if (options.recursive) { + // Recursive allows the shortcut syntax "sourcedir/" for "sourcedir/*" + // (see Github issue #15) + sources.forEach(function(src, i) { + if (src[src.length - 1] === '/') + sources[i] += '*'; + }); + + // Create dest + try { + fs.mkdirSync(dest, parseInt('0777', 8)); + } catch (e) { + // like Unix's cp, keep going even if we can't create dest dir + } + } + + sources = common.expand(sources); + + sources.forEach(function(src) { + if (!fs.existsSync(src)) { + common.error('no such file or directory: '+src, true); + return; // skip file + } + + // If here, src exists + if (fs.statSync(src).isDirectory()) { + if (!options.recursive) { + // Non-Recursive + common.log(src + ' is a directory (not copied)'); + } else { + // Recursive + // 'cp /a/source dest' should create 'source' in 'dest' + var newDest = path.join(dest, path.basename(src)), + checkDir = fs.statSync(src); + try { + fs.mkdirSync(newDest, checkDir.mode); + } catch (e) { + //if the directory already exists, that's okay + if (e.code !== 'EEXIST') throw e; + } + + cpdirSyncRecursive(src, newDest, {force: options.force}); + } + return; // done with dir + } + + // If here, src is a file + + // When copying to '/path/dir': + // thisDest = '/path/dir/file1' + var thisDest = dest; + if (fs.existsSync(dest) && fs.statSync(dest).isDirectory()) + thisDest = path.normalize(dest + '/' + path.basename(src)); + + if (fs.existsSync(thisDest) && !options.force) { + common.error('dest file already exists: ' + thisDest, true); + return; // skip file + } + + copyFileSync(src, thisDest); + }); // forEach(src) +} +module.exports = _cp; diff --git a/node_modules/shelljs/src/dirs.js b/node_modules/shelljs/src/dirs.js new file mode 100644 index 0000000..58fae8b --- /dev/null +++ b/node_modules/shelljs/src/dirs.js @@ -0,0 +1,191 @@ +var common = require('./common'); +var _cd = require('./cd'); +var path = require('path'); + +// Pushd/popd/dirs internals +var _dirStack = []; + +function _isStackIndex(index) { + return (/^[\-+]\d+$/).test(index); +} + +function _parseStackIndex(index) { + if (_isStackIndex(index)) { + if (Math.abs(index) < _dirStack.length + 1) { // +1 for pwd + return (/^-/).test(index) ? Number(index) - 1 : Number(index); + } else { + common.error(index + ': directory stack index out of range'); + } + } else { + common.error(index + ': invalid number'); + } +} + +function _actualDirStack() { + return [process.cwd()].concat(_dirStack); +} + +//@ +//@ ### pushd([options,] [dir | '-N' | '+N']) +//@ +//@ Available options: +//@ +//@ + `-n`: Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated. +//@ +//@ Arguments: +//@ +//@ + `dir`: Makes the current working directory be the top of the stack, and then executes the equivalent of `cd dir`. +//@ + `+N`: Brings the Nth directory (counting from the left of the list printed by dirs, starting with zero) to the top of the list by rotating the stack. +//@ + `-N`: Brings the Nth directory (counting from the right of the list printed by dirs, starting with zero) to the top of the list by rotating the stack. +//@ +//@ Examples: +//@ +//@ ```javascript +//@ // process.cwd() === '/usr' +//@ pushd('/etc'); // Returns /etc /usr +//@ pushd('+1'); // Returns /usr /etc +//@ ``` +//@ +//@ Save the current directory on the top of the directory stack and then cd to `dir`. With no arguments, pushd exchanges the top two directories. Returns an array of paths in the stack. +function _pushd(options, dir) { + if (_isStackIndex(options)) { + dir = options; + options = ''; + } + + options = common.parseOptions(options, { + 'n' : 'no-cd' + }); + + var dirs = _actualDirStack(); + + if (dir === '+0') { + return dirs; // +0 is a noop + } else if (!dir) { + if (dirs.length > 1) { + dirs = dirs.splice(1, 1).concat(dirs); + } else { + return common.error('no other directory'); + } + } else if (_isStackIndex(dir)) { + var n = _parseStackIndex(dir); + dirs = dirs.slice(n).concat(dirs.slice(0, n)); + } else { + if (options['no-cd']) { + dirs.splice(1, 0, dir); + } else { + dirs.unshift(dir); + } + } + + if (options['no-cd']) { + dirs = dirs.slice(1); + } else { + dir = path.resolve(dirs.shift()); + _cd('', dir); + } + + _dirStack = dirs; + return _dirs(''); +} +exports.pushd = _pushd; + +//@ +//@ ### popd([options,] ['-N' | '+N']) +//@ +//@ Available options: +//@ +//@ + `-n`: Suppresses the normal change of directory when removing directories from the stack, so that only the stack is manipulated. +//@ +//@ Arguments: +//@ +//@ + `+N`: Removes the Nth directory (counting from the left of the list printed by dirs), starting with zero. +//@ + `-N`: Removes the Nth directory (counting from the right of the list printed by dirs), starting with zero. +//@ +//@ Examples: +//@ +//@ ```javascript +//@ echo(process.cwd()); // '/usr' +//@ pushd('/etc'); // '/etc /usr' +//@ echo(process.cwd()); // '/etc' +//@ popd(); // '/usr' +//@ echo(process.cwd()); // '/usr' +//@ ``` +//@ +//@ When no arguments are given, popd removes the top directory from the stack and performs a cd to the new top directory. The elements are numbered from 0 starting at the first directory listed with dirs; i.e., popd is equivalent to popd +0. Returns an array of paths in the stack. +function _popd(options, index) { + if (_isStackIndex(options)) { + index = options; + options = ''; + } + + options = common.parseOptions(options, { + 'n' : 'no-cd' + }); + + if (!_dirStack.length) { + return common.error('directory stack empty'); + } + + index = _parseStackIndex(index || '+0'); + + if (options['no-cd'] || index > 0 || _dirStack.length + index === 0) { + index = index > 0 ? index - 1 : index; + _dirStack.splice(index, 1); + } else { + var dir = path.resolve(_dirStack.shift()); + _cd('', dir); + } + + return _dirs(''); +} +exports.popd = _popd; + +//@ +//@ ### dirs([options | '+N' | '-N']) +//@ +//@ Available options: +//@ +//@ + `-c`: Clears the directory stack by deleting all of the elements. +//@ +//@ Arguments: +//@ +//@ + `+N`: Displays the Nth directory (counting from the left of the list printed by dirs when invoked without options), starting with zero. +//@ + `-N`: Displays the Nth directory (counting from the right of the list printed by dirs when invoked without options), starting with zero. +//@ +//@ Display the list of currently remembered directories. Returns an array of paths in the stack, or a single path if +N or -N was specified. +//@ +//@ See also: pushd, popd +function _dirs(options, index) { + if (_isStackIndex(options)) { + index = options; + options = ''; + } + + options = common.parseOptions(options, { + 'c' : 'clear' + }); + + if (options['clear']) { + _dirStack = []; + return _dirStack; + } + + var stack = _actualDirStack(); + + if (index) { + index = _parseStackIndex(index); + + if (index < 0) { + index = stack.length + index; + } + + common.log(stack[index]); + return stack[index]; + } + + common.log(stack.join(' ')); + + return stack; +} +exports.dirs = _dirs; diff --git a/node_modules/shelljs/src/echo.js b/node_modules/shelljs/src/echo.js new file mode 100644 index 0000000..760ea84 --- /dev/null +++ b/node_modules/shelljs/src/echo.js @@ -0,0 +1,20 @@ +var common = require('./common'); + +//@ +//@ ### echo(string [,string ...]) +//@ +//@ Examples: +//@ +//@ ```javascript +//@ echo('hello world'); +//@ var str = echo('hello world'); +//@ ``` +//@ +//@ Prints string to stdout, and returns string with additional utility methods +//@ like `.to()`. +function _echo() { + var messages = [].slice.call(arguments, 0); + console.log.apply(this, messages); + return common.ShellString(messages.join(' ')); +} +module.exports = _echo; diff --git a/node_modules/shelljs/src/error.js b/node_modules/shelljs/src/error.js new file mode 100644 index 0000000..cca3efb --- /dev/null +++ b/node_modules/shelljs/src/error.js @@ -0,0 +1,10 @@ +var common = require('./common'); + +//@ +//@ ### error() +//@ Tests if error occurred in the last command. Returns `null` if no error occurred, +//@ otherwise returns string explaining the error +function error() { + return common.state.error; +}; +module.exports = error; diff --git a/node_modules/shelljs/src/exec.js b/node_modules/shelljs/src/exec.js new file mode 100644 index 0000000..7ccdbc0 --- /dev/null +++ b/node_modules/shelljs/src/exec.js @@ -0,0 +1,181 @@ +var common = require('./common'); +var _tempDir = require('./tempdir'); +var _pwd = require('./pwd'); +var path = require('path'); +var fs = require('fs'); +var child = require('child_process'); + +// Hack to run child_process.exec() synchronously (sync avoids callback hell) +// Uses a custom wait loop that checks for a flag file, created when the child process is done. +// (Can't do a wait loop that checks for internal Node variables/messages as +// Node is single-threaded; callbacks and other internal state changes are done in the +// event loop). +function execSync(cmd, opts) { + var tempDir = _tempDir(); + var stdoutFile = path.resolve(tempDir+'/'+common.randomFileName()), + codeFile = path.resolve(tempDir+'/'+common.randomFileName()), + scriptFile = path.resolve(tempDir+'/'+common.randomFileName()), + sleepFile = path.resolve(tempDir+'/'+common.randomFileName()); + + var options = common.extend({ + silent: common.config.silent + }, opts); + + var previousStdoutContent = ''; + // Echoes stdout changes from running process, if not silent + function updateStdout() { + if (options.silent || !fs.existsSync(stdoutFile)) + return; + + var stdoutContent = fs.readFileSync(stdoutFile, 'utf8'); + // No changes since last time? + if (stdoutContent.length <= previousStdoutContent.length) + return; + + process.stdout.write(stdoutContent.substr(previousStdoutContent.length)); + previousStdoutContent = stdoutContent; + } + + function escape(str) { + return (str+'').replace(/([\\"'])/g, "\\$1").replace(/\0/g, "\\0"); + } + + cmd += ' > '+stdoutFile+' 2>&1'; // works on both win/unix + + var script = + "var child = require('child_process')," + + " fs = require('fs');" + + "child.exec('"+escape(cmd)+"', {env: process.env, maxBuffer: 20*1024*1024}, function(err) {" + + " fs.writeFileSync('"+escape(codeFile)+"', err ? err.code.toString() : '0');" + + "});"; + + if (fs.existsSync(scriptFile)) common.unlinkSync(scriptFile); + if (fs.existsSync(stdoutFile)) common.unlinkSync(stdoutFile); + if (fs.existsSync(codeFile)) common.unlinkSync(codeFile); + + fs.writeFileSync(scriptFile, script); + child.exec('"'+process.execPath+'" '+scriptFile, { + env: process.env, + cwd: _pwd(), + maxBuffer: 20*1024*1024 + }); + + // The wait loop + // sleepFile is used as a dummy I/O op to mitigate unnecessary CPU usage + // (tried many I/O sync ops, writeFileSync() seems to be only one that is effective in reducing + // CPU usage, though apparently not so much on Windows) + while (!fs.existsSync(codeFile)) { updateStdout(); fs.writeFileSync(sleepFile, 'a'); } + while (!fs.existsSync(stdoutFile)) { updateStdout(); fs.writeFileSync(sleepFile, 'a'); } + + // At this point codeFile exists, but it's not necessarily flushed yet. + // Keep reading it until it is. + var code = parseInt('', 10); + while (isNaN(code)) { + code = parseInt(fs.readFileSync(codeFile, 'utf8'), 10); + } + + var stdout = fs.readFileSync(stdoutFile, 'utf8'); + + // No biggie if we can't erase the files now -- they're in a temp dir anyway + try { common.unlinkSync(scriptFile); } catch(e) {} + try { common.unlinkSync(stdoutFile); } catch(e) {} + try { common.unlinkSync(codeFile); } catch(e) {} + try { common.unlinkSync(sleepFile); } catch(e) {} + + // some shell return codes are defined as errors, per http://tldp.org/LDP/abs/html/exitcodes.html + if (code === 1 || code === 2 || code >= 126) { + common.error('', true); // unix/shell doesn't really give an error message after non-zero exit codes + } + // True if successful, false if not + var obj = { + code: code, + output: stdout + }; + return obj; +} // execSync() + +// Wrapper around exec() to enable echoing output to console in real time +function execAsync(cmd, opts, callback) { + var output = ''; + + var options = common.extend({ + silent: common.config.silent + }, opts); + + var c = child.exec(cmd, {env: process.env, maxBuffer: 20*1024*1024}, function(err) { + if (callback) + callback(err ? err.code : 0, output); + }); + + c.stdout.on('data', function(data) { + output += data; + if (!options.silent) + process.stdout.write(data); + }); + + c.stderr.on('data', function(data) { + output += data; + if (!options.silent) + process.stdout.write(data); + }); + + return c; +} + +//@ +//@ ### exec(command [, options] [, callback]) +//@ Available options (all `false` by default): +//@ +//@ + `async`: Asynchronous execution. Defaults to true if a callback is provided. +//@ + `silent`: Do not echo program output to console. +//@ +//@ Examples: +//@ +//@ ```javascript +//@ var version = exec('node --version', {silent:true}).output; +//@ +//@ var child = exec('some_long_running_process', {async:true}); +//@ child.stdout.on('data', function(data) { +//@ /* ... do something with data ... */ +//@ }); +//@ +//@ exec('some_long_running_process', function(code, output) { +//@ console.log('Exit code:', code); +//@ console.log('Program output:', output); +//@ }); +//@ ``` +//@ +//@ Executes the given `command` _synchronously_, unless otherwise specified. +//@ When in synchronous mode returns the object `{ code:..., output:... }`, containing the program's +//@ `output` (stdout + stderr) and its exit `code`. Otherwise returns the child process object, and +//@ the `callback` gets the arguments `(code, output)`. +//@ +//@ **Note:** For long-lived processes, it's best to run `exec()` asynchronously as +//@ the current synchronous implementation uses a lot of CPU. This should be getting +//@ fixed soon. +function _exec(command, options, callback) { + if (!command) + common.error('must specify command'); + + // Callback is defined instead of options. + if (typeof options === 'function') { + callback = options; + options = { async: true }; + } + + // Callback is defined with options. + if (typeof options === 'object' && typeof callback === 'function') { + options.async = true; + } + + options = common.extend({ + silent: common.config.silent, + async: false + }, options); + + if (options.async) + return execAsync(command, options, callback); + else + return execSync(command, options); +} +module.exports = _exec; diff --git a/node_modules/shelljs/src/find.js b/node_modules/shelljs/src/find.js new file mode 100644 index 0000000..d9eeec2 --- /dev/null +++ b/node_modules/shelljs/src/find.js @@ -0,0 +1,51 @@ +var fs = require('fs'); +var common = require('./common'); +var _ls = require('./ls'); + +//@ +//@ ### find(path [,path ...]) +//@ ### find(path_array) +//@ Examples: +//@ +//@ ```javascript +//@ find('src', 'lib'); +//@ find(['src', 'lib']); // same as above +//@ find('.').filter(function(file) { return file.match(/\.js$/); }); +//@ ``` +//@ +//@ Returns array of all files (however deep) in the given paths. +//@ +//@ The main difference from `ls('-R', path)` is that the resulting file names +//@ include the base directories, e.g. `lib/resources/file1` instead of just `file1`. +function _find(options, paths) { + if (!paths) + common.error('no path specified'); + else if (typeof paths === 'object') + paths = paths; // assume array + else if (typeof paths === 'string') + paths = [].slice.call(arguments, 1); + + var list = []; + + function pushFile(file) { + if (common.platform === 'win') + file = file.replace(/\\/g, '/'); + list.push(file); + } + + // why not simply do ls('-R', paths)? because the output wouldn't give the base dirs + // to get the base dir in the output, we need instead ls('-R', 'dir/*') for every directory + + paths.forEach(function(file) { + pushFile(file); + + if (fs.statSync(file).isDirectory()) { + _ls('-RA', file+'/*').forEach(function(subfile) { + pushFile(subfile); + }); + } + }); + + return list; +} +module.exports = _find; diff --git a/node_modules/shelljs/src/grep.js b/node_modules/shelljs/src/grep.js new file mode 100644 index 0000000..00c7d6a --- /dev/null +++ b/node_modules/shelljs/src/grep.js @@ -0,0 +1,52 @@ +var common = require('./common'); +var fs = require('fs'); + +//@ +//@ ### grep([options ,] regex_filter, file [, file ...]) +//@ ### grep([options ,] regex_filter, file_array) +//@ Available options: +//@ +//@ + `-v`: Inverse the sense of the regex and print the lines not matching the criteria. +//@ +//@ Examples: +//@ +//@ ```javascript +//@ grep('-v', 'GLOBAL_VARIABLE', '*.js'); +//@ grep('GLOBAL_VARIABLE', '*.js'); +//@ ``` +//@ +//@ Reads input string from given files and returns a string containing all lines of the +//@ file that match the given `regex_filter`. Wildcard `*` accepted. +function _grep(options, regex, files) { + options = common.parseOptions(options, { + 'v': 'inverse' + }); + + if (!files) + common.error('no paths given'); + + if (typeof files === 'string') + files = [].slice.call(arguments, 2); + // if it's array leave it as it is + + files = common.expand(files); + + var grep = ''; + files.forEach(function(file) { + if (!fs.existsSync(file)) { + common.error('no such file or directory: ' + file, true); + return; + } + + var contents = fs.readFileSync(file, 'utf8'), + lines = contents.split(/\r*\n/); + lines.forEach(function(line) { + var matched = line.match(regex); + if ((options.inverse && !matched) || (!options.inverse && matched)) + grep += line + '\n'; + }); + }); + + return common.ShellString(grep); +} +module.exports = _grep; diff --git a/node_modules/shelljs/src/ln.js b/node_modules/shelljs/src/ln.js new file mode 100644 index 0000000..a7b9701 --- /dev/null +++ b/node_modules/shelljs/src/ln.js @@ -0,0 +1,53 @@ +var fs = require('fs'); +var path = require('path'); +var common = require('./common'); +var os = require('os'); + +//@ +//@ ### ln(options, source, dest) +//@ ### ln(source, dest) +//@ Available options: +//@ +//@ + `s`: symlink +//@ + `f`: force +//@ +//@ Examples: +//@ +//@ ```javascript +//@ ln('file', 'newlink'); +//@ ln('-sf', 'file', 'existing'); +//@ ``` +//@ +//@ Links source to dest. Use -f to force the link, should dest already exist. +function _ln(options, source, dest) { + options = common.parseOptions(options, { + 's': 'symlink', + 'f': 'force' + }); + + if (!source || !dest) { + common.error('Missing and/or '); + } + + source = path.resolve(process.cwd(), String(source)); + dest = path.resolve(process.cwd(), String(dest)); + + if (!fs.existsSync(source)) { + common.error('Source file does not exist', true); + } + + if (fs.existsSync(dest)) { + if (!options.force) { + common.error('Destination file exists', true); + } + + fs.unlinkSync(dest); + } + + if (options.symlink) { + fs.symlinkSync(source, dest, os.platform() === "win32" ? "junction" : null); + } else { + fs.linkSync(source, dest, os.platform() === "win32" ? "junction" : null); + } +} +module.exports = _ln; diff --git a/node_modules/shelljs/src/ls.js b/node_modules/shelljs/src/ls.js new file mode 100644 index 0000000..3345db4 --- /dev/null +++ b/node_modules/shelljs/src/ls.js @@ -0,0 +1,126 @@ +var path = require('path'); +var fs = require('fs'); +var common = require('./common'); +var _cd = require('./cd'); +var _pwd = require('./pwd'); + +//@ +//@ ### ls([options ,] path [,path ...]) +//@ ### ls([options ,] path_array) +//@ Available options: +//@ +//@ + `-R`: recursive +//@ + `-A`: all files (include files beginning with `.`, except for `.` and `..`) +//@ +//@ Examples: +//@ +//@ ```javascript +//@ ls('projs/*.js'); +//@ ls('-R', '/users/me', '/tmp'); +//@ ls('-R', ['/users/me', '/tmp']); // same as above +//@ ``` +//@ +//@ Returns array of files in the given path, or in current directory if no path provided. +function _ls(options, paths) { + options = common.parseOptions(options, { + 'R': 'recursive', + 'A': 'all', + 'a': 'all_deprecated' + }); + + if (options.all_deprecated) { + // We won't support the -a option as it's hard to image why it's useful + // (it includes '.' and '..' in addition to '.*' files) + // For backwards compatibility we'll dump a deprecated message and proceed as before + common.log('ls: Option -a is deprecated. Use -A instead'); + options.all = true; + } + + if (!paths) + paths = ['.']; + else if (typeof paths === 'object') + paths = paths; // assume array + else if (typeof paths === 'string') + paths = [].slice.call(arguments, 1); + + var list = []; + + // Conditionally pushes file to list - returns true if pushed, false otherwise + // (e.g. prevents hidden files to be included unless explicitly told so) + function pushFile(file, query) { + // hidden file? + if (path.basename(file)[0] === '.') { + // not explicitly asking for hidden files? + if (!options.all && !(path.basename(query)[0] === '.' && path.basename(query).length > 1)) + return false; + } + + if (common.platform === 'win') + file = file.replace(/\\/g, '/'); + + list.push(file); + return true; + } + + paths.forEach(function(p) { + if (fs.existsSync(p)) { + var stats = fs.statSync(p); + // Simple file? + if (stats.isFile()) { + pushFile(p, p); + return; // continue + } + + // Simple dir? + if (stats.isDirectory()) { + // Iterate over p contents + fs.readdirSync(p).forEach(function(file) { + if (!pushFile(file, p)) + return; + + // Recursive? + if (options.recursive) { + var oldDir = _pwd(); + _cd('', p); + if (fs.statSync(file).isDirectory()) + list = list.concat(_ls('-R'+(options.all?'A':''), file+'/*')); + _cd('', oldDir); + } + }); + return; // continue + } + } + + // p does not exist - possible wildcard present + + var basename = path.basename(p); + var dirname = path.dirname(p); + // Wildcard present on an existing dir? (e.g. '/tmp/*.js') + if (basename.search(/\*/) > -1 && fs.existsSync(dirname) && fs.statSync(dirname).isDirectory) { + // Escape special regular expression chars + var regexp = basename.replace(/(\^|\$|\(|\)|<|>|\[|\]|\{|\}|\.|\+|\?)/g, '\\$1'); + // Translates wildcard into regex + regexp = '^' + regexp.replace(/\*/g, '.*') + '$'; + // Iterate over directory contents + fs.readdirSync(dirname).forEach(function(file) { + if (file.match(new RegExp(regexp))) { + if (!pushFile(path.normalize(dirname+'/'+file), basename)) + return; + + // Recursive? + if (options.recursive) { + var pp = dirname + '/' + file; + if (fs.lstatSync(pp).isDirectory()) + list = list.concat(_ls('-R'+(options.all?'A':''), pp+'/*')); + } // recursive + } // if file matches + }); // forEach + return; + } + + common.error('no such file or directory: ' + p, true); + }); + + return list; +} +module.exports = _ls; diff --git a/node_modules/shelljs/src/mkdir.js b/node_modules/shelljs/src/mkdir.js new file mode 100644 index 0000000..5a7088f --- /dev/null +++ b/node_modules/shelljs/src/mkdir.js @@ -0,0 +1,68 @@ +var common = require('./common'); +var fs = require('fs'); +var path = require('path'); + +// Recursively creates 'dir' +function mkdirSyncRecursive(dir) { + var baseDir = path.dirname(dir); + + // Base dir exists, no recursion necessary + if (fs.existsSync(baseDir)) { + fs.mkdirSync(dir, parseInt('0777', 8)); + return; + } + + // Base dir does not exist, go recursive + mkdirSyncRecursive(baseDir); + + // Base dir created, can create dir + fs.mkdirSync(dir, parseInt('0777', 8)); +} + +//@ +//@ ### mkdir([options ,] dir [, dir ...]) +//@ ### mkdir([options ,] dir_array) +//@ Available options: +//@ +//@ + `p`: full path (will create intermediate dirs if necessary) +//@ +//@ Examples: +//@ +//@ ```javascript +//@ mkdir('-p', '/tmp/a/b/c/d', '/tmp/e/f/g'); +//@ mkdir('-p', ['/tmp/a/b/c/d', '/tmp/e/f/g']); // same as above +//@ ``` +//@ +//@ Creates directories. +function _mkdir(options, dirs) { + options = common.parseOptions(options, { + 'p': 'fullpath' + }); + if (!dirs) + common.error('no paths given'); + + if (typeof dirs === 'string') + dirs = [].slice.call(arguments, 1); + // if it's array leave it as it is + + dirs.forEach(function(dir) { + if (fs.existsSync(dir)) { + if (!options.fullpath) + common.error('path already exists: ' + dir, true); + return; // skip dir + } + + // Base dir does not exist, and no -p option given + var baseDir = path.dirname(dir); + if (!fs.existsSync(baseDir) && !options.fullpath) { + common.error('no such file or directory: ' + baseDir, true); + return; // skip dir + } + + if (options.fullpath) + mkdirSyncRecursive(dir); + else + fs.mkdirSync(dir, parseInt('0777', 8)); + }); +} // mkdir +module.exports = _mkdir; diff --git a/node_modules/shelljs/src/mv.js b/node_modules/shelljs/src/mv.js new file mode 100644 index 0000000..11f9607 --- /dev/null +++ b/node_modules/shelljs/src/mv.js @@ -0,0 +1,80 @@ +var fs = require('fs'); +var path = require('path'); +var common = require('./common'); + +//@ +//@ ### mv(source [, source ...], dest') +//@ ### mv(source_array, dest') +//@ Available options: +//@ +//@ + `f`: force +//@ +//@ Examples: +//@ +//@ ```javascript +//@ mv('-f', 'file', 'dir/'); +//@ mv('file1', 'file2', 'dir/'); +//@ mv(['file1', 'file2'], 'dir/'); // same as above +//@ ``` +//@ +//@ Moves files. The wildcard `*` is accepted. +function _mv(options, sources, dest) { + options = common.parseOptions(options, { + 'f': 'force' + }); + + // Get sources, dest + if (arguments.length < 3) { + common.error('missing and/or '); + } else if (arguments.length > 3) { + sources = [].slice.call(arguments, 1, arguments.length - 1); + dest = arguments[arguments.length - 1]; + } else if (typeof sources === 'string') { + sources = [sources]; + } else if ('length' in sources) { + sources = sources; // no-op for array + } else { + common.error('invalid arguments'); + } + + sources = common.expand(sources); + + var exists = fs.existsSync(dest), + stats = exists && fs.statSync(dest); + + // Dest is not existing dir, but multiple sources given + if ((!exists || !stats.isDirectory()) && sources.length > 1) + common.error('dest is not a directory (too many sources)'); + + // Dest is an existing file, but no -f given + if (exists && stats.isFile() && !options.force) + common.error('dest file already exists: ' + dest); + + sources.forEach(function(src) { + if (!fs.existsSync(src)) { + common.error('no such file or directory: '+src, true); + return; // skip file + } + + // If here, src exists + + // When copying to '/path/dir': + // thisDest = '/path/dir/file1' + var thisDest = dest; + if (fs.existsSync(dest) && fs.statSync(dest).isDirectory()) + thisDest = path.normalize(dest + '/' + path.basename(src)); + + if (fs.existsSync(thisDest) && !options.force) { + common.error('dest file already exists: ' + thisDest, true); + return; // skip file + } + + if (path.resolve(src) === path.dirname(path.resolve(thisDest))) { + common.error('cannot move to self: '+src, true); + return; // skip file + } + + fs.renameSync(src, thisDest); + }); // forEach(src) +} // mv +module.exports = _mv; diff --git a/node_modules/shelljs/src/popd.js b/node_modules/shelljs/src/popd.js new file mode 100644 index 0000000..11ea24f --- /dev/null +++ b/node_modules/shelljs/src/popd.js @@ -0,0 +1 @@ +// see dirs.js \ No newline at end of file diff --git a/node_modules/shelljs/src/pushd.js b/node_modules/shelljs/src/pushd.js new file mode 100644 index 0000000..11ea24f --- /dev/null +++ b/node_modules/shelljs/src/pushd.js @@ -0,0 +1 @@ +// see dirs.js \ No newline at end of file diff --git a/node_modules/shelljs/src/pwd.js b/node_modules/shelljs/src/pwd.js new file mode 100644 index 0000000..41727bb --- /dev/null +++ b/node_modules/shelljs/src/pwd.js @@ -0,0 +1,11 @@ +var path = require('path'); +var common = require('./common'); + +//@ +//@ ### pwd() +//@ Returns the current directory. +function _pwd(options) { + var pwd = path.resolve(process.cwd()); + return common.ShellString(pwd); +} +module.exports = _pwd; diff --git a/node_modules/shelljs/src/rm.js b/node_modules/shelljs/src/rm.js new file mode 100644 index 0000000..3abe6e1 --- /dev/null +++ b/node_modules/shelljs/src/rm.js @@ -0,0 +1,145 @@ +var common = require('./common'); +var fs = require('fs'); + +// Recursively removes 'dir' +// Adapted from https://github.com/ryanmcgrath/wrench-js +// +// Copyright (c) 2010 Ryan McGrath +// Copyright (c) 2012 Artur Adib +// +// Licensed under the MIT License +// http://www.opensource.org/licenses/mit-license.php +function rmdirSyncRecursive(dir, force) { + var files; + + files = fs.readdirSync(dir); + + // Loop through and delete everything in the sub-tree after checking it + for(var i = 0; i < files.length; i++) { + var file = dir + "/" + files[i], + currFile = fs.lstatSync(file); + + if(currFile.isDirectory()) { // Recursive function back to the beginning + rmdirSyncRecursive(file, force); + } + + else if(currFile.isSymbolicLink()) { // Unlink symlinks + if (force || isWriteable(file)) { + try { + common.unlinkSync(file); + } catch (e) { + common.error('could not remove file (code '+e.code+'): ' + file, true); + } + } + } + + else // Assume it's a file - perhaps a try/catch belongs here? + if (force || isWriteable(file)) { + try { + common.unlinkSync(file); + } catch (e) { + common.error('could not remove file (code '+e.code+'): ' + file, true); + } + } + } + + // Now that we know everything in the sub-tree has been deleted, we can delete the main directory. + // Huzzah for the shopkeep. + + var result; + try { + result = fs.rmdirSync(dir); + } catch(e) { + common.error('could not remove directory (code '+e.code+'): ' + dir, true); + } + + return result; +} // rmdirSyncRecursive + +// Hack to determine if file has write permissions for current user +// Avoids having to check user, group, etc, but it's probably slow +function isWriteable(file) { + var writePermission = true; + try { + var __fd = fs.openSync(file, 'a'); + fs.closeSync(__fd); + } catch(e) { + writePermission = false; + } + + return writePermission; +} + +//@ +//@ ### rm([options ,] file [, file ...]) +//@ ### rm([options ,] file_array) +//@ Available options: +//@ +//@ + `-f`: force +//@ + `-r, -R`: recursive +//@ +//@ Examples: +//@ +//@ ```javascript +//@ rm('-rf', '/tmp/*'); +//@ rm('some_file.txt', 'another_file.txt'); +//@ rm(['some_file.txt', 'another_file.txt']); // same as above +//@ ``` +//@ +//@ Removes files. The wildcard `*` is accepted. +function _rm(options, files) { + options = common.parseOptions(options, { + 'f': 'force', + 'r': 'recursive', + 'R': 'recursive' + }); + if (!files) + common.error('no paths given'); + + if (typeof files === 'string') + files = [].slice.call(arguments, 1); + // if it's array leave it as it is + + files = common.expand(files); + + files.forEach(function(file) { + if (!fs.existsSync(file)) { + // Path does not exist, no force flag given + if (!options.force) + common.error('no such file or directory: '+file, true); + + return; // skip file + } + + // If here, path exists + + var stats = fs.lstatSync(file); + if (stats.isFile() || stats.isSymbolicLink()) { + + // Do not check for file writing permissions + if (options.force) { + common.unlinkSync(file); + return; + } + + if (isWriteable(file)) + common.unlinkSync(file); + else + common.error('permission denied: '+file, true); + + return; + } // simple file + + // Path is an existing directory, but no -r flag given + if (stats.isDirectory() && !options.recursive) { + common.error('path is a directory', true); + return; // skip path + } + + // Recursively remove existing directory + if (stats.isDirectory() && options.recursive) { + rmdirSyncRecursive(file, options.force); + } + }); // forEach(file) +} // rm +module.exports = _rm; diff --git a/node_modules/shelljs/src/sed.js b/node_modules/shelljs/src/sed.js new file mode 100644 index 0000000..65f7cb4 --- /dev/null +++ b/node_modules/shelljs/src/sed.js @@ -0,0 +1,43 @@ +var common = require('./common'); +var fs = require('fs'); + +//@ +//@ ### sed([options ,] search_regex, replacement, file) +//@ Available options: +//@ +//@ + `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_ +//@ +//@ Examples: +//@ +//@ ```javascript +//@ sed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js'); +//@ sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js'); +//@ ``` +//@ +//@ Reads an input string from `file` and performs a JavaScript `replace()` on the input +//@ using the given search regex and replacement string or function. Returns the new string after replacement. +function _sed(options, regex, replacement, file) { + options = common.parseOptions(options, { + 'i': 'inplace' + }); + + if (typeof replacement === 'string' || typeof replacement === 'function') + replacement = replacement; // no-op + else if (typeof replacement === 'number') + replacement = replacement.toString(); // fallback + else + common.error('invalid replacement string'); + + if (!file) + common.error('no file given'); + + if (!fs.existsSync(file)) + common.error('no such file or directory: ' + file); + + var result = fs.readFileSync(file, 'utf8').replace(regex, replacement); + if (options.inplace) + fs.writeFileSync(file, result, 'utf8'); + + return common.ShellString(result); +} +module.exports = _sed; diff --git a/node_modules/shelljs/src/tempdir.js b/node_modules/shelljs/src/tempdir.js new file mode 100644 index 0000000..45953c2 --- /dev/null +++ b/node_modules/shelljs/src/tempdir.js @@ -0,0 +1,56 @@ +var common = require('./common'); +var os = require('os'); +var fs = require('fs'); + +// Returns false if 'dir' is not a writeable directory, 'dir' otherwise +function writeableDir(dir) { + if (!dir || !fs.existsSync(dir)) + return false; + + if (!fs.statSync(dir).isDirectory()) + return false; + + var testFile = dir+'/'+common.randomFileName(); + try { + fs.writeFileSync(testFile, ' '); + common.unlinkSync(testFile); + return dir; + } catch (e) { + return false; + } +} + + +//@ +//@ ### tempdir() +//@ +//@ Examples: +//@ +//@ ```javascript +//@ var tmp = tempdir(); // "/tmp" for most *nix platforms +//@ ``` +//@ +//@ Searches and returns string containing a writeable, platform-dependent temporary directory. +//@ Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir). +function _tempDir() { + var state = common.state; + if (state.tempDir) + return state.tempDir; // from cache + + state.tempDir = writeableDir(os.tempDir && os.tempDir()) || // node 0.8+ + writeableDir(process.env['TMPDIR']) || + writeableDir(process.env['TEMP']) || + writeableDir(process.env['TMP']) || + writeableDir(process.env['Wimp$ScrapDir']) || // RiscOS + writeableDir('C:\\TEMP') || // Windows + writeableDir('C:\\TMP') || // Windows + writeableDir('\\TEMP') || // Windows + writeableDir('\\TMP') || // Windows + writeableDir('/tmp') || + writeableDir('/var/tmp') || + writeableDir('/usr/tmp') || + writeableDir('.'); // last resort + + return state.tempDir; +} +module.exports = _tempDir; diff --git a/node_modules/shelljs/src/test.js b/node_modules/shelljs/src/test.js new file mode 100644 index 0000000..8a4ac7d --- /dev/null +++ b/node_modules/shelljs/src/test.js @@ -0,0 +1,85 @@ +var common = require('./common'); +var fs = require('fs'); + +//@ +//@ ### test(expression) +//@ Available expression primaries: +//@ +//@ + `'-b', 'path'`: true if path is a block device +//@ + `'-c', 'path'`: true if path is a character device +//@ + `'-d', 'path'`: true if path is a directory +//@ + `'-e', 'path'`: true if path exists +//@ + `'-f', 'path'`: true if path is a regular file +//@ + `'-L', 'path'`: true if path is a symboilc link +//@ + `'-p', 'path'`: true if path is a pipe (FIFO) +//@ + `'-S', 'path'`: true if path is a socket +//@ +//@ Examples: +//@ +//@ ```javascript +//@ if (test('-d', path)) { /* do something with dir */ }; +//@ if (!test('-f', path)) continue; // skip if it's a regular file +//@ ``` +//@ +//@ Evaluates expression using the available primaries and returns corresponding value. +function _test(options, path) { + if (!path) + common.error('no path given'); + + // hack - only works with unary primaries + options = common.parseOptions(options, { + 'b': 'block', + 'c': 'character', + 'd': 'directory', + 'e': 'exists', + 'f': 'file', + 'L': 'link', + 'p': 'pipe', + 'S': 'socket' + }); + + var canInterpret = false; + for (var key in options) + if (options[key] === true) { + canInterpret = true; + break; + } + + if (!canInterpret) + common.error('could not interpret expression'); + + if (options.link) { + try { + return fs.lstatSync(path).isSymbolicLink(); + } catch(e) { + return false; + } + } + + if (!fs.existsSync(path)) + return false; + + if (options.exists) + return true; + + var stats = fs.statSync(path); + + if (options.block) + return stats.isBlockDevice(); + + if (options.character) + return stats.isCharacterDevice(); + + if (options.directory) + return stats.isDirectory(); + + if (options.file) + return stats.isFile(); + + if (options.pipe) + return stats.isFIFO(); + + if (options.socket) + return stats.isSocket(); +} // test +module.exports = _test; diff --git a/node_modules/shelljs/src/to.js b/node_modules/shelljs/src/to.js new file mode 100644 index 0000000..f029999 --- /dev/null +++ b/node_modules/shelljs/src/to.js @@ -0,0 +1,29 @@ +var common = require('./common'); +var fs = require('fs'); +var path = require('path'); + +//@ +//@ ### 'string'.to(file) +//@ +//@ Examples: +//@ +//@ ```javascript +//@ cat('input.txt').to('output.txt'); +//@ ``` +//@ +//@ Analogous to the redirection operator `>` in Unix, but works with JavaScript strings (such as +//@ those returned by `cat`, `grep`, etc). _Like Unix redirections, `to()` will overwrite any existing file!_ +function _to(options, file) { + if (!file) + common.error('wrong arguments'); + + if (!fs.existsSync( path.dirname(file) )) + common.error('no such file or directory: ' + path.dirname(file)); + + try { + fs.writeFileSync(file, this.toString(), 'utf8'); + } catch(e) { + common.error('could not write to file (code '+e.code+'): '+file, true); + } +} +module.exports = _to; diff --git a/node_modules/shelljs/src/toEnd.js b/node_modules/shelljs/src/toEnd.js new file mode 100644 index 0000000..f6d099d --- /dev/null +++ b/node_modules/shelljs/src/toEnd.js @@ -0,0 +1,29 @@ +var common = require('./common'); +var fs = require('fs'); +var path = require('path'); + +//@ +//@ ### 'string'.toEnd(file) +//@ +//@ Examples: +//@ +//@ ```javascript +//@ cat('input.txt').toEnd('output.txt'); +//@ ``` +//@ +//@ Analogous to the redirect-and-append operator `>>` in Unix, but works with JavaScript strings (such as +//@ those returned by `cat`, `grep`, etc). +function _toEnd(options, file) { + if (!file) + common.error('wrong arguments'); + + if (!fs.existsSync( path.dirname(file) )) + common.error('no such file or directory: ' + path.dirname(file)); + + try { + fs.appendFileSync(file, this.toString(), 'utf8'); + } catch(e) { + common.error('could not append to file (code '+e.code+'): '+file, true); + } +} +module.exports = _toEnd; diff --git a/node_modules/shelljs/src/which.js b/node_modules/shelljs/src/which.js new file mode 100644 index 0000000..2822ecf --- /dev/null +++ b/node_modules/shelljs/src/which.js @@ -0,0 +1,83 @@ +var common = require('./common'); +var fs = require('fs'); +var path = require('path'); + +// Cross-platform method for splitting environment PATH variables +function splitPath(p) { + for (i=1;i<2;i++) {} + + if (!p) + return []; + + if (common.platform === 'win') + return p.split(';'); + else + return p.split(':'); +} + +function checkPath(path) { + return fs.existsSync(path) && fs.statSync(path).isDirectory() == false; +} + +//@ +//@ ### which(command) +//@ +//@ Examples: +//@ +//@ ```javascript +//@ var nodeExec = which('node'); +//@ ``` +//@ +//@ Searches for `command` in the system's PATH. On Windows looks for `.exe`, `.cmd`, and `.bat` extensions. +//@ Returns string containing the absolute path to the command. +function _which(options, cmd) { + if (!cmd) + common.error('must specify command'); + + var pathEnv = process.env.path || process.env.Path || process.env.PATH, + pathArray = splitPath(pathEnv), + where = null; + + // No relative/absolute paths provided? + if (cmd.search(/\//) === -1) { + // Search for command in PATH + pathArray.forEach(function(dir) { + if (where) + return; // already found it + + var attempt = path.resolve(dir + '/' + cmd); + if (checkPath(attempt)) { + where = attempt; + return; + } + + if (common.platform === 'win') { + var baseAttempt = attempt; + attempt = baseAttempt + '.exe'; + if (checkPath(attempt)) { + where = attempt; + return; + } + attempt = baseAttempt + '.cmd'; + if (checkPath(attempt)) { + where = attempt; + return; + } + attempt = baseAttempt + '.bat'; + if (checkPath(attempt)) { + where = attempt; + return; + } + } // if 'win' + }); + } + + // Command not found anywhere? + if (!checkPath(cmd) && !where) + return null; + + where = where || path.resolve(cmd); + + return common.ShellString(where); +} +module.exports = _which; diff --git a/node_modules/sigmund/LICENSE b/node_modules/sigmund/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/node_modules/sigmund/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/sigmund/README.md b/node_modules/sigmund/README.md new file mode 100644 index 0000000..25a38a5 --- /dev/null +++ b/node_modules/sigmund/README.md @@ -0,0 +1,53 @@ +# sigmund + +Quick and dirty signatures for Objects. + +This is like a much faster `deepEquals` comparison, which returns a +string key suitable for caches and the like. + +## Usage + +```javascript +function doSomething (someObj) { + var key = sigmund(someObj, maxDepth) // max depth defaults to 10 + var cached = cache.get(key) + if (cached) return cached + + var result = expensiveCalculation(someObj) + cache.set(key, result) + return result +} +``` + +The resulting key will be as unique and reproducible as calling +`JSON.stringify` or `util.inspect` on the object, but is much faster. +In order to achieve this speed, some differences are glossed over. +For example, the object `{0:'foo'}` will be treated identically to the +array `['foo']`. + +Also, just as there is no way to summon the soul from the scribblings +of a cocaine-addled psychoanalyst, there is no way to revive the object +from the signature string that sigmund gives you. In fact, it's +barely even readable. + +As with `util.inspect` and `JSON.stringify`, larger objects will +produce larger signature strings. + +Because sigmund is a bit less strict than the more thorough +alternatives, the strings will be shorter, and also there is a +slightly higher chance for collisions. For example, these objects +have the same signature: + + var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]} + var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']} + +Like a good Freudian, sigmund is most effective when you already have +some understanding of what you're looking for. It can help you help +yourself, but you must be willing to do some work as well. + +Cycles are handled, and cyclical objects are silently omitted (though +the key is included in the signature output.) + +The second argument is the maximum depth, which defaults to 10, +because that is the maximum object traversal depth covered by most +insurance carriers. diff --git a/node_modules/sigmund/bench.js b/node_modules/sigmund/bench.js new file mode 100644 index 0000000..5acfd6d --- /dev/null +++ b/node_modules/sigmund/bench.js @@ -0,0 +1,283 @@ +// different ways to id objects +// use a req/res pair, since it's crazy deep and cyclical + +// sparseFE10 and sigmund are usually pretty close, which is to be expected, +// since they are essentially the same algorithm, except that sigmund handles +// regular expression objects properly. + + +var http = require('http') +var util = require('util') +var sigmund = require('./sigmund.js') +var sreq, sres, creq, cres, test + +http.createServer(function (q, s) { + sreq = q + sres = s + sres.end('ok') + this.close(function () { setTimeout(function () { + start() + }, 200) }) +}).listen(1337, function () { + creq = http.get({ port: 1337 }) + creq.on('response', function (s) { cres = s }) +}) + +function start () { + test = [sreq, sres, creq, cres] + // test = sreq + // sreq.sres = sres + // sreq.creq = creq + // sreq.cres = cres + + for (var i in exports.compare) { + console.log(i) + var hash = exports.compare[i]() + console.log(hash) + console.log(hash.length) + console.log('') + } + + require('bench').runMain() +} + +function customWs (obj, md, d) { + d = d || 0 + var to = typeof obj + if (to === 'undefined' || to === 'function' || to === null) return '' + if (d > md || !obj || to !== 'object') return ('' + obj).replace(/[\n ]+/g, '') + + if (Array.isArray(obj)) { + return obj.map(function (i, _, __) { + return customWs(i, md, d + 1) + }).reduce(function (a, b) { return a + b }, '') + } + + var keys = Object.keys(obj) + return keys.map(function (k, _, __) { + return k + ':' + customWs(obj[k], md, d + 1) + }).reduce(function (a, b) { return a + b }, '') +} + +function custom (obj, md, d) { + d = d || 0 + var to = typeof obj + if (to === 'undefined' || to === 'function' || to === null) return '' + if (d > md || !obj || to !== 'object') return '' + obj + + if (Array.isArray(obj)) { + return obj.map(function (i, _, __) { + return custom(i, md, d + 1) + }).reduce(function (a, b) { return a + b }, '') + } + + var keys = Object.keys(obj) + return keys.map(function (k, _, __) { + return k + ':' + custom(obj[k], md, d + 1) + }).reduce(function (a, b) { return a + b }, '') +} + +function sparseFE2 (obj, maxDepth) { + var seen = [] + var soFar = '' + function ch (v, depth) { + if (depth > maxDepth) return + if (typeof v === 'function' || typeof v === 'undefined') return + if (typeof v !== 'object' || !v) { + soFar += v + return + } + if (seen.indexOf(v) !== -1 || depth === maxDepth) return + seen.push(v) + soFar += '{' + Object.keys(v).forEach(function (k, _, __) { + // pseudo-private values. skip those. + if (k.charAt(0) === '_') return + var to = typeof v[k] + if (to === 'function' || to === 'undefined') return + soFar += k + ':' + ch(v[k], depth + 1) + }) + soFar += '}' + } + ch(obj, 0) + return soFar +} + +function sparseFE (obj, maxDepth) { + var seen = [] + var soFar = '' + function ch (v, depth) { + if (depth > maxDepth) return + if (typeof v === 'function' || typeof v === 'undefined') return + if (typeof v !== 'object' || !v) { + soFar += v + return + } + if (seen.indexOf(v) !== -1 || depth === maxDepth) return + seen.push(v) + soFar += '{' + Object.keys(v).forEach(function (k, _, __) { + // pseudo-private values. skip those. + if (k.charAt(0) === '_') return + var to = typeof v[k] + if (to === 'function' || to === 'undefined') return + soFar += k + ch(v[k], depth + 1) + }) + } + ch(obj, 0) + return soFar +} + +function sparse (obj, maxDepth) { + var seen = [] + var soFar = '' + function ch (v, depth) { + if (depth > maxDepth) return + if (typeof v === 'function' || typeof v === 'undefined') return + if (typeof v !== 'object' || !v) { + soFar += v + return + } + if (seen.indexOf(v) !== -1 || depth === maxDepth) return + seen.push(v) + soFar += '{' + for (var k in v) { + // pseudo-private values. skip those. + if (k.charAt(0) === '_') continue + var to = typeof v[k] + if (to === 'function' || to === 'undefined') continue + soFar += k + ch(v[k], depth + 1) + } + } + ch(obj, 0) + return soFar +} + +function noCommas (obj, maxDepth) { + var seen = [] + var soFar = '' + function ch (v, depth) { + if (depth > maxDepth) return + if (typeof v === 'function' || typeof v === 'undefined') return + if (typeof v !== 'object' || !v) { + soFar += v + return + } + if (seen.indexOf(v) !== -1 || depth === maxDepth) return + seen.push(v) + soFar += '{' + for (var k in v) { + // pseudo-private values. skip those. + if (k.charAt(0) === '_') continue + var to = typeof v[k] + if (to === 'function' || to === 'undefined') continue + soFar += k + ':' + ch(v[k], depth + 1) + } + soFar += '}' + } + ch(obj, 0) + return soFar +} + + +function flatten (obj, maxDepth) { + var seen = [] + var soFar = '' + function ch (v, depth) { + if (depth > maxDepth) return + if (typeof v === 'function' || typeof v === 'undefined') return + if (typeof v !== 'object' || !v) { + soFar += v + return + } + if (seen.indexOf(v) !== -1 || depth === maxDepth) return + seen.push(v) + soFar += '{' + for (var k in v) { + // pseudo-private values. skip those. + if (k.charAt(0) === '_') continue + var to = typeof v[k] + if (to === 'function' || to === 'undefined') continue + soFar += k + ':' + ch(v[k], depth + 1) + soFar += ',' + } + soFar += '}' + } + ch(obj, 0) + return soFar +} + +exports.compare = +{ + // 'custom 2': function () { + // return custom(test, 2, 0) + // }, + // 'customWs 2': function () { + // return customWs(test, 2, 0) + // }, + 'JSON.stringify (guarded)': function () { + var seen = [] + return JSON.stringify(test, function (k, v) { + if (typeof v !== 'object' || !v) return v + if (seen.indexOf(v) !== -1) return undefined + seen.push(v) + return v + }) + }, + + 'flatten 10': function () { + return flatten(test, 10) + }, + + // 'flattenFE 10': function () { + // return flattenFE(test, 10) + // }, + + 'noCommas 10': function () { + return noCommas(test, 10) + }, + + 'sparse 10': function () { + return sparse(test, 10) + }, + + 'sparseFE 10': function () { + return sparseFE(test, 10) + }, + + 'sparseFE2 10': function () { + return sparseFE2(test, 10) + }, + + sigmund: function() { + return sigmund(test, 10) + }, + + + // 'util.inspect 1': function () { + // return util.inspect(test, false, 1, false) + // }, + // 'util.inspect undefined': function () { + // util.inspect(test) + // }, + // 'util.inspect 2': function () { + // util.inspect(test, false, 2, false) + // }, + // 'util.inspect 3': function () { + // util.inspect(test, false, 3, false) + // }, + // 'util.inspect 4': function () { + // util.inspect(test, false, 4, false) + // }, + // 'util.inspect Infinity': function () { + // util.inspect(test, false, Infinity, false) + // } +} + +/** results +**/ diff --git a/node_modules/sigmund/package.json b/node_modules/sigmund/package.json new file mode 100644 index 0000000..ce427fe --- /dev/null +++ b/node_modules/sigmund/package.json @@ -0,0 +1,94 @@ +{ + "_args": [ + [ + { + "raw": "sigmund@~1.0.0", + "scope": null, + "escapedName": "sigmund", + "name": "sigmund", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/findup-sync/node_modules/minimatch" + ] + ], + "_from": "sigmund@>=1.0.0 <1.1.0", + "_id": "sigmund@1.0.1", + "_inCache": true, + "_location": "/sigmund", + "_nodeVersion": "2.0.1", + "_npmUser": { + "name": "isaacs", + "email": "isaacs@npmjs.com" + }, + "_npmVersion": "2.10.0", + "_phantomChildren": {}, + "_requested": { + "raw": "sigmund@~1.0.0", + "scope": null, + "escapedName": "sigmund", + "name": "sigmund", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/findup-sync/minimatch", + "/minimatch" + ], + "_resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "_shasum": "3ff21f198cad2175f9f3b781853fd94d0d19b590", + "_shrinkwrap": null, + "_spec": "sigmund@~1.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/findup-sync/node_modules/minimatch", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/sigmund/issues" + }, + "dependencies": {}, + "description": "Quick and dirty signatures for Objects.", + "devDependencies": { + "tap": "~0.3.0" + }, + "directories": { + "test": "test" + }, + "dist": { + "shasum": "3ff21f198cad2175f9f3b781853fd94d0d19b590", + "tarball": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz" + }, + "gitHead": "527f97aa5bb253d927348698c0cd3bb267d098c6", + "homepage": "https://github.com/isaacs/sigmund#readme", + "keywords": [ + "object", + "signature", + "key", + "data", + "psychoanalysis" + ], + "license": "ISC", + "main": "sigmund.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "sigmund", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/sigmund.git" + }, + "scripts": { + "bench": "node bench.js", + "test": "tap test/*.js" + }, + "version": "1.0.1" +} diff --git a/node_modules/sigmund/sigmund.js b/node_modules/sigmund/sigmund.js new file mode 100644 index 0000000..82c7ab8 --- /dev/null +++ b/node_modules/sigmund/sigmund.js @@ -0,0 +1,39 @@ +module.exports = sigmund +function sigmund (subject, maxSessions) { + maxSessions = maxSessions || 10; + var notes = []; + var analysis = ''; + var RE = RegExp; + + function psychoAnalyze (subject, session) { + if (session > maxSessions) return; + + if (typeof subject === 'function' || + typeof subject === 'undefined') { + return; + } + + if (typeof subject !== 'object' || !subject || + (subject instanceof RE)) { + analysis += subject; + return; + } + + if (notes.indexOf(subject) !== -1 || session === maxSessions) return; + + notes.push(subject); + analysis += '{'; + Object.keys(subject).forEach(function (issue, _, __) { + // pseudo-private values. skip those. + if (issue.charAt(0) === '_') return; + var to = typeof subject[issue]; + if (to === 'function' || to === 'undefined') return; + analysis += issue; + psychoAnalyze(subject[issue], session + 1); + }); + } + psychoAnalyze(subject, 0); + return analysis; +} + +// vim: set softtabstop=4 shiftwidth=4: diff --git a/node_modules/sigmund/test/basic.js b/node_modules/sigmund/test/basic.js new file mode 100644 index 0000000..50c53a1 --- /dev/null +++ b/node_modules/sigmund/test/basic.js @@ -0,0 +1,24 @@ +var test = require('tap').test +var sigmund = require('../sigmund.js') + + +// occasionally there are duplicates +// that's an acceptable edge-case. JSON.stringify and util.inspect +// have some collision potential as well, though less, and collision +// detection is expensive. +var hash = '{abc/def/g{0h1i2{jkl' +var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]} +var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']} + +var obj3 = JSON.parse(JSON.stringify(obj1)) +obj3.c = /def/ +obj3.g[2].cycle = obj3 +var cycleHash = '{abc/def/g{0h1i2{jklcycle' + +test('basic', function (t) { + t.equal(sigmund(obj1), hash) + t.equal(sigmund(obj2), hash) + t.equal(sigmund(obj3), cycleHash) + t.end() +}) + diff --git a/node_modules/signal-exit/CHANGELOG.md b/node_modules/signal-exit/CHANGELOG.md new file mode 100644 index 0000000..e2f70d2 --- /dev/null +++ b/node_modules/signal-exit/CHANGELOG.md @@ -0,0 +1,27 @@ +# Change Log + +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + + +## [3.0.1](https://github.com/tapjs/signal-exit/compare/v3.0.0...v3.0.1) (2016-09-08) + + +### Bug Fixes + +* do not listen on SIGBUS, SIGFPE, SIGSEGV and SIGILL ([#40](https://github.com/tapjs/signal-exit/issues/40)) ([5b105fb](https://github.com/tapjs/signal-exit/commit/5b105fb)) + + + + +# [3.0.0](https://github.com/tapjs/signal-exit/compare/v2.1.2...v3.0.0) (2016-06-13) + + +### Bug Fixes + +* get our test suite running on Windows ([#23](https://github.com/tapjs/signal-exit/issues/23)) ([6f3eda8](https://github.com/tapjs/signal-exit/commit/6f3eda8)) +* hooking SIGPROF was interfering with profilers see [#21](https://github.com/tapjs/signal-exit/issues/21) ([#24](https://github.com/tapjs/signal-exit/issues/24)) ([1248a4c](https://github.com/tapjs/signal-exit/commit/1248a4c)) + + +### BREAKING CHANGES + +* signal-exit no longer wires into SIGPROF diff --git a/node_modules/signal-exit/LICENSE.txt b/node_modules/signal-exit/LICENSE.txt new file mode 100644 index 0000000..eead04a --- /dev/null +++ b/node_modules/signal-exit/LICENSE.txt @@ -0,0 +1,16 @@ +The ISC License + +Copyright (c) 2015, Contributors + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice +appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE +LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/signal-exit/README.md b/node_modules/signal-exit/README.md new file mode 100644 index 0000000..8ebccab --- /dev/null +++ b/node_modules/signal-exit/README.md @@ -0,0 +1,40 @@ +# signal-exit + +[![Build Status](https://travis-ci.org/tapjs/signal-exit.png)](https://travis-ci.org/tapjs/signal-exit) +[![Coverage](https://coveralls.io/repos/tapjs/signal-exit/badge.svg?branch=master)](https://coveralls.io/r/tapjs/signal-exit?branch=master) +[![NPM version](https://img.shields.io/npm/v/signal-exit.svg)](https://www.npmjs.com/package/signal-exit) +[![Windows Tests](https://img.shields.io/appveyor/ci/bcoe/signal-exit/master.svg?label=Windows%20Tests)](https://ci.appveyor.com/project/bcoe/signal-exit) +[![Standard Version](https://img.shields.io/badge/release-standard%20version-brightgreen.svg)](https://github.com/conventional-changelog/standard-version) + +When you want to fire an event no matter how a process exits: + +* reaching the end of execution. +* explicitly having `process.exit(code)` called. +* having `process.kill(pid, sig)` called. +* receiving a fatal signal from outside the process + +Use `signal-exit`. + +```js +var onExit = require('signal-exit') + +onExit(function (code, signal) { + console.log('process exited!') +}) +``` + +## API + +`var remove = onExit(function (code, signal) {}, options)` + +The return value of the function is a function that will remove the +handler. + +Note that the function *only* fires for signals if the signal would +cause the proces to exit. That is, there are no other listeners, and +it is a fatal signal. + +## Options + +* `alwaysLast`: Run this handler after any other signal or exit + handlers. This causes `process.emit` to be monkeypatched. diff --git a/node_modules/signal-exit/index.js b/node_modules/signal-exit/index.js new file mode 100644 index 0000000..337f691 --- /dev/null +++ b/node_modules/signal-exit/index.js @@ -0,0 +1,157 @@ +// Note: since nyc uses this module to output coverage, any lines +// that are in the direct sync flow of nyc's outputCoverage are +// ignored, since we can never get coverage for them. +var assert = require('assert') +var signals = require('./signals.js') + +var EE = require('events') +/* istanbul ignore if */ +if (typeof EE !== 'function') { + EE = EE.EventEmitter +} + +var emitter +if (process.__signal_exit_emitter__) { + emitter = process.__signal_exit_emitter__ +} else { + emitter = process.__signal_exit_emitter__ = new EE() + emitter.count = 0 + emitter.emitted = {} +} + +// Because this emitter is a global, we have to check to see if a +// previous version of this library failed to enable infinite listeners. +// I know what you're about to say. But literally everything about +// signal-exit is a compromise with evil. Get used to it. +if (!emitter.infinite) { + emitter.setMaxListeners(Infinity) + emitter.infinite = true +} + +module.exports = function (cb, opts) { + assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler') + + if (loaded === false) { + load() + } + + var ev = 'exit' + if (opts && opts.alwaysLast) { + ev = 'afterexit' + } + + var remove = function () { + emitter.removeListener(ev, cb) + if (emitter.listeners('exit').length === 0 && + emitter.listeners('afterexit').length === 0) { + unload() + } + } + emitter.on(ev, cb) + + return remove +} + +module.exports.unload = unload +function unload () { + if (!loaded) { + return + } + loaded = false + + signals.forEach(function (sig) { + try { + process.removeListener(sig, sigListeners[sig]) + } catch (er) {} + }) + process.emit = originalProcessEmit + process.reallyExit = originalProcessReallyExit + emitter.count -= 1 +} + +function emit (event, code, signal) { + if (emitter.emitted[event]) { + return + } + emitter.emitted[event] = true + emitter.emit(event, code, signal) +} + +// { : , ... } +var sigListeners = {} +signals.forEach(function (sig) { + sigListeners[sig] = function listener () { + // If there are no other listeners, an exit is coming! + // Simplest way: remove us and then re-send the signal. + // We know that this will kill the process, so we can + // safely emit now. + var listeners = process.listeners(sig) + if (listeners.length === emitter.count) { + unload() + emit('exit', null, sig) + /* istanbul ignore next */ + emit('afterexit', null, sig) + /* istanbul ignore next */ + process.kill(process.pid, sig) + } + } +}) + +module.exports.signals = function () { + return signals +} + +module.exports.load = load + +var loaded = false + +function load () { + if (loaded) { + return + } + loaded = true + + // This is the number of onSignalExit's that are in play. + // It's important so that we can count the correct number of + // listeners on signals, and don't wait for the other one to + // handle it instead of us. + emitter.count += 1 + + signals = signals.filter(function (sig) { + try { + process.on(sig, sigListeners[sig]) + return true + } catch (er) { + return false + } + }) + + process.emit = processEmit + process.reallyExit = processReallyExit +} + +var originalProcessReallyExit = process.reallyExit +function processReallyExit (code) { + process.exitCode = code || 0 + emit('exit', process.exitCode, null) + /* istanbul ignore next */ + emit('afterexit', process.exitCode, null) + /* istanbul ignore next */ + originalProcessReallyExit.call(process, process.exitCode) +} + +var originalProcessEmit = process.emit +function processEmit (ev, arg) { + if (ev === 'exit') { + if (arg !== undefined) { + process.exitCode = arg + } + var ret = originalProcessEmit.apply(this, arguments) + emit('exit', process.exitCode, null) + /* istanbul ignore next */ + emit('afterexit', process.exitCode, null) + return ret + } else { + return originalProcessEmit.apply(this, arguments) + } +} diff --git a/node_modules/signal-exit/package.json b/node_modules/signal-exit/package.json new file mode 100644 index 0000000..bb5bda5 --- /dev/null +++ b/node_modules/signal-exit/package.json @@ -0,0 +1,106 @@ +{ + "_args": [ + [ + { + "raw": "signal-exit@^3.0.0", + "scope": null, + "escapedName": "signal-exit", + "name": "signal-exit", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/loud-rejection" + ] + ], + "_from": "signal-exit@>=3.0.0 <4.0.0", + "_id": "signal-exit@3.0.2", + "_inCache": true, + "_location": "/signal-exit", + "_nodeVersion": "6.5.0", + "_npmOperationalInternal": { + "host": "packages-18-east.internal.npmjs.com", + "tmp": "tmp/signal-exit-3.0.2.tgz_1480821660838_0.6809983775019646" + }, + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "3.10.9", + "_phantomChildren": {}, + "_requested": { + "raw": "signal-exit@^3.0.0", + "scope": null, + "escapedName": "signal-exit", + "name": "signal-exit", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/loud-rejection" + ], + "_resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "_shasum": "b5fdc08f1287ea1178628e415e25132b73646c6d", + "_shrinkwrap": null, + "_spec": "signal-exit@^3.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/loud-rejection", + "author": { + "name": "Ben Coe", + "email": "ben@npmjs.com" + }, + "bugs": { + "url": "https://github.com/tapjs/signal-exit/issues" + }, + "dependencies": {}, + "description": "when you want to fire an event no matter how a process exits.", + "devDependencies": { + "chai": "^3.5.0", + "coveralls": "^2.11.10", + "nyc": "^8.1.0", + "standard": "^7.1.2", + "standard-version": "^2.3.0", + "tap": "^8.0.1" + }, + "directories": {}, + "dist": { + "shasum": "b5fdc08f1287ea1178628e415e25132b73646c6d", + "tarball": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz" + }, + "files": [ + "index.js", + "signals.js" + ], + "gitHead": "9c5ad9809fe6135ef22e2623989deaffe2a4fa8a", + "homepage": "https://github.com/tapjs/signal-exit", + "keywords": [ + "signal", + "exit" + ], + "license": "ISC", + "main": "index.js", + "maintainers": [ + { + "name": "bcoe", + "email": "ben@npmjs.com" + }, + { + "name": "isaacs", + "email": "isaacs@npmjs.com" + } + ], + "name": "signal-exit", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/tapjs/signal-exit.git" + }, + "scripts": { + "coverage": "nyc report --reporter=text-lcov | coveralls", + "pretest": "standard", + "release": "standard-version", + "test": "tap --timeout=240 ./test/*.js --cov" + }, + "version": "3.0.2" +} diff --git a/node_modules/signal-exit/signals.js b/node_modules/signal-exit/signals.js new file mode 100644 index 0000000..3bd67a8 --- /dev/null +++ b/node_modules/signal-exit/signals.js @@ -0,0 +1,53 @@ +// This is not the set of all possible signals. +// +// It IS, however, the set of all signals that trigger +// an exit on either Linux or BSD systems. Linux is a +// superset of the signal names supported on BSD, and +// the unknown signals just fail to register, so we can +// catch that easily enough. +// +// Don't bother with SIGKILL. It's uncatchable, which +// means that we can't fire any callbacks anyway. +// +// If a user does happen to register a handler on a non- +// fatal signal like SIGWINCH or something, and then +// exit, it'll end up firing `process.emit('exit')`, so +// the handler will be fired anyway. +// +// SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised +// artificially, inherently leave the process in a +// state from which it is not safe to try and enter JS +// listeners. +module.exports = [ + 'SIGABRT', + 'SIGALRM', + 'SIGHUP', + 'SIGINT', + 'SIGTERM' +] + +if (process.platform !== 'win32') { + module.exports.push( + 'SIGVTALRM', + 'SIGXCPU', + 'SIGXFSZ', + 'SIGUSR2', + 'SIGTRAP', + 'SIGSYS', + 'SIGQUIT', + 'SIGIOT' + // should detect profiler and enable/disable accordingly. + // see #21 + // 'SIGPROF' + ) +} + +if (process.platform === 'linux') { + module.exports.push( + 'SIGIO', + 'SIGPOLL', + 'SIGPWR', + 'SIGSTKFLT', + 'SIGUNUSED' + ) +} diff --git a/node_modules/source-map/CHANGELOG.md b/node_modules/source-map/CHANGELOG.md new file mode 100644 index 0000000..3a8c066 --- /dev/null +++ b/node_modules/source-map/CHANGELOG.md @@ -0,0 +1,301 @@ +# Change Log + +## 0.5.6 + +* Fix for regression when people were using numbers as names in source maps. See + #236. + +## 0.5.5 + +* Fix "regression" of unsupported, implementation behavior that half the world + happens to have come to depend on. See #235. + +* Fix regression involving function hoisting in SpiderMonkey. See #233. + +## 0.5.4 + +* Large performance improvements to source-map serialization. See #228 and #229. + +## 0.5.3 + +* Do not include unnecessary distribution files. See + commit ef7006f8d1647e0a83fdc60f04f5a7ca54886f86. + +## 0.5.2 + +* Include browser distributions of the library in package.json's `files`. See + issue #212. + +## 0.5.1 + +* Fix latent bugs in IndexedSourceMapConsumer.prototype._parseMappings. See + ff05274becc9e6e1295ed60f3ea090d31d843379. + +## 0.5.0 + +* Node 0.8 is no longer supported. + +* Use webpack instead of dryice for bundling. + +* Big speedups serializing source maps. See pull request #203. + +* Fix a bug with `SourceMapConsumer.prototype.sourceContentFor` and sources that + explicitly start with the source root. See issue #199. + +## 0.4.4 + +* Fix an issue where using a `SourceMapGenerator` after having created a + `SourceMapConsumer` from it via `SourceMapConsumer.fromSourceMap` failed. See + issue #191. + +* Fix an issue with where `SourceMapGenerator` would mistakenly consider + different mappings as duplicates of each other and avoid generating them. See + issue #192. + +## 0.4.3 + +* A very large number of performance improvements, particularly when parsing + source maps. Collectively about 75% of time shaved off of the source map + parsing benchmark! + +* Fix a bug in `SourceMapConsumer.prototype.allGeneratedPositionsFor` and fuzzy + searching in the presence of a column option. See issue #177. + +* Fix a bug with joining a source and its source root when the source is above + the root. See issue #182. + +* Add the `SourceMapConsumer.prototype.hasContentsOfAllSources` method to + determine when all sources' contents are inlined into the source map. See + issue #190. + +## 0.4.2 + +* Add an `.npmignore` file so that the benchmarks aren't pulled down by + dependent projects. Issue #169. + +* Add an optional `column` argument to + `SourceMapConsumer.prototype.allGeneratedPositionsFor` and better handle lines + with no mappings. Issues #172 and #173. + +## 0.4.1 + +* Fix accidentally defining a global variable. #170. + +## 0.4.0 + +* The default direction for fuzzy searching was changed back to its original + direction. See #164. + +* There is now a `bias` option you can supply to `SourceMapConsumer` to control + the fuzzy searching direction. See #167. + +* About an 8% speed up in parsing source maps. See #159. + +* Added a benchmark for parsing and generating source maps. + +## 0.3.0 + +* Change the default direction that searching for positions fuzzes when there is + not an exact match. See #154. + +* Support for environments using json2.js for JSON serialization. See #156. + +## 0.2.0 + +* Support for consuming "indexed" source maps which do not have any remote + sections. See pull request #127. This introduces a minor backwards + incompatibility if you are monkey patching `SourceMapConsumer.prototype` + methods. + +## 0.1.43 + +* Performance improvements for `SourceMapGenerator` and `SourceNode`. See issue + #148 for some discussion and issues #150, #151, and #152 for implementations. + +## 0.1.42 + +* Fix an issue where `SourceNode`s from different versions of the source-map + library couldn't be used in conjunction with each other. See issue #142. + +## 0.1.41 + +* Fix a bug with getting the source content of relative sources with a "./" + prefix. See issue #145 and [Bug 1090768](bugzil.la/1090768). + +* Add the `SourceMapConsumer.prototype.computeColumnSpans` method to compute the + column span of each mapping. + +* Add the `SourceMapConsumer.prototype.allGeneratedPositionsFor` method to find + all generated positions associated with a given original source and line. + +## 0.1.40 + +* Performance improvements for parsing source maps in SourceMapConsumer. + +## 0.1.39 + +* Fix a bug where setting a source's contents to null before any source content + had been set before threw a TypeError. See issue #131. + +## 0.1.38 + +* Fix a bug where finding relative paths from an empty path were creating + absolute paths. See issue #129. + +## 0.1.37 + +* Fix a bug where if the source root was an empty string, relative source paths + would turn into absolute source paths. Issue #124. + +## 0.1.36 + +* Allow the `names` mapping property to be an empty string. Issue #121. + +## 0.1.35 + +* A third optional parameter was added to `SourceNode.fromStringWithSourceMap` + to specify a path that relative sources in the second parameter should be + relative to. Issue #105. + +* If no file property is given to a `SourceMapGenerator`, then the resulting + source map will no longer have a `null` file property. The property will + simply not exist. Issue #104. + +* Fixed a bug where consecutive newlines were ignored in `SourceNode`s. + Issue #116. + +## 0.1.34 + +* Make `SourceNode` work with windows style ("\r\n") newlines. Issue #103. + +* Fix bug involving source contents and the + `SourceMapGenerator.prototype.applySourceMap`. Issue #100. + +## 0.1.33 + +* Fix some edge cases surrounding path joining and URL resolution. + +* Add a third parameter for relative path to + `SourceMapGenerator.prototype.applySourceMap`. + +* Fix issues with mappings and EOLs. + +## 0.1.32 + +* Fixed a bug where SourceMapConsumer couldn't handle negative relative columns + (issue 92). + +* Fixed test runner to actually report number of failed tests as its process + exit code. + +* Fixed a typo when reporting bad mappings (issue 87). + +## 0.1.31 + +* Delay parsing the mappings in SourceMapConsumer until queried for a source + location. + +* Support Sass source maps (which at the time of writing deviate from the spec + in small ways) in SourceMapConsumer. + +## 0.1.30 + +* Do not join source root with a source, when the source is a data URI. + +* Extend the test runner to allow running single specific test files at a time. + +* Performance improvements in `SourceNode.prototype.walk` and + `SourceMapConsumer.prototype.eachMapping`. + +* Source map browser builds will now work inside Workers. + +* Better error messages when attempting to add an invalid mapping to a + `SourceMapGenerator`. + +## 0.1.29 + +* Allow duplicate entries in the `names` and `sources` arrays of source maps + (usually from TypeScript) we are parsing. Fixes github issue 72. + +## 0.1.28 + +* Skip duplicate mappings when creating source maps from SourceNode; github + issue 75. + +## 0.1.27 + +* Don't throw an error when the `file` property is missing in SourceMapConsumer, + we don't use it anyway. + +## 0.1.26 + +* Fix SourceNode.fromStringWithSourceMap for empty maps. Fixes github issue 70. + +## 0.1.25 + +* Make compatible with browserify + +## 0.1.24 + +* Fix issue with absolute paths and `file://` URIs. See + https://bugzilla.mozilla.org/show_bug.cgi?id=885597 + +## 0.1.23 + +* Fix issue with absolute paths and sourcesContent, github issue 64. + +## 0.1.22 + +* Ignore duplicate mappings in SourceMapGenerator. Fixes github issue 21. + +## 0.1.21 + +* Fixed handling of sources that start with a slash so that they are relative to + the source root's host. + +## 0.1.20 + +* Fixed github issue #43: absolute URLs aren't joined with the source root + anymore. + +## 0.1.19 + +* Using Travis CI to run tests. + +## 0.1.18 + +* Fixed a bug in the handling of sourceRoot. + +## 0.1.17 + +* Added SourceNode.fromStringWithSourceMap. + +## 0.1.16 + +* Added missing documentation. + +* Fixed the generating of empty mappings in SourceNode. + +## 0.1.15 + +* Added SourceMapGenerator.applySourceMap. + +## 0.1.14 + +* The sourceRoot is now handled consistently. + +## 0.1.13 + +* Added SourceMapGenerator.fromSourceMap. + +## 0.1.12 + +* SourceNode now generates empty mappings too. + +## 0.1.11 + +* Added name support to SourceNode. + +## 0.1.10 + +* Added sourcesContent support to the customer and generator. diff --git a/node_modules/source-map/LICENSE b/node_modules/source-map/LICENSE new file mode 100644 index 0000000..ed1b7cf --- /dev/null +++ b/node_modules/source-map/LICENSE @@ -0,0 +1,28 @@ + +Copyright (c) 2009-2011, Mozilla Foundation and contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the names of the Mozilla Foundation nor the names of project + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/node_modules/source-map/README.md b/node_modules/source-map/README.md new file mode 100644 index 0000000..99d3861 --- /dev/null +++ b/node_modules/source-map/README.md @@ -0,0 +1,729 @@ +# Source Map + +[![Build Status](https://travis-ci.org/mozilla/source-map.png?branch=master)](https://travis-ci.org/mozilla/source-map) + +[![NPM](https://nodei.co/npm/source-map.png?downloads=true&downloadRank=true)](https://www.npmjs.com/package/source-map) + +This is a library to generate and consume the source map format +[described here][format]. + +[format]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit + +## Use with Node + + $ npm install source-map + +## Use on the Web + + + +-------------------------------------------------------------------------------- + + + + + +## Table of Contents + +- [Examples](#examples) + - [Consuming a source map](#consuming-a-source-map) + - [Generating a source map](#generating-a-source-map) + - [With SourceNode (high level API)](#with-sourcenode-high-level-api) + - [With SourceMapGenerator (low level API)](#with-sourcemapgenerator-low-level-api) +- [API](#api) + - [SourceMapConsumer](#sourcemapconsumer) + - [new SourceMapConsumer(rawSourceMap)](#new-sourcemapconsumerrawsourcemap) + - [SourceMapConsumer.prototype.computeColumnSpans()](#sourcemapconsumerprototypecomputecolumnspans) + - [SourceMapConsumer.prototype.originalPositionFor(generatedPosition)](#sourcemapconsumerprototypeoriginalpositionforgeneratedposition) + - [SourceMapConsumer.prototype.generatedPositionFor(originalPosition)](#sourcemapconsumerprototypegeneratedpositionfororiginalposition) + - [SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)](#sourcemapconsumerprototypeallgeneratedpositionsfororiginalposition) + - [SourceMapConsumer.prototype.hasContentsOfAllSources()](#sourcemapconsumerprototypehascontentsofallsources) + - [SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])](#sourcemapconsumerprototypesourcecontentforsource-returnnullonmissing) + - [SourceMapConsumer.prototype.eachMapping(callback, context, order)](#sourcemapconsumerprototypeeachmappingcallback-context-order) + - [SourceMapGenerator](#sourcemapgenerator) + - [new SourceMapGenerator([startOfSourceMap])](#new-sourcemapgeneratorstartofsourcemap) + - [SourceMapGenerator.fromSourceMap(sourceMapConsumer)](#sourcemapgeneratorfromsourcemapsourcemapconsumer) + - [SourceMapGenerator.prototype.addMapping(mapping)](#sourcemapgeneratorprototypeaddmappingmapping) + - [SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)](#sourcemapgeneratorprototypesetsourcecontentsourcefile-sourcecontent) + - [SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])](#sourcemapgeneratorprototypeapplysourcemapsourcemapconsumer-sourcefile-sourcemappath) + - [SourceMapGenerator.prototype.toString()](#sourcemapgeneratorprototypetostring) + - [SourceNode](#sourcenode) + - [new SourceNode([line, column, source[, chunk[, name]]])](#new-sourcenodeline-column-source-chunk-name) + - [SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])](#sourcenodefromstringwithsourcemapcode-sourcemapconsumer-relativepath) + - [SourceNode.prototype.add(chunk)](#sourcenodeprototypeaddchunk) + - [SourceNode.prototype.prepend(chunk)](#sourcenodeprototypeprependchunk) + - [SourceNode.prototype.setSourceContent(sourceFile, sourceContent)](#sourcenodeprototypesetsourcecontentsourcefile-sourcecontent) + - [SourceNode.prototype.walk(fn)](#sourcenodeprototypewalkfn) + - [SourceNode.prototype.walkSourceContents(fn)](#sourcenodeprototypewalksourcecontentsfn) + - [SourceNode.prototype.join(sep)](#sourcenodeprototypejoinsep) + - [SourceNode.prototype.replaceRight(pattern, replacement)](#sourcenodeprototypereplacerightpattern-replacement) + - [SourceNode.prototype.toString()](#sourcenodeprototypetostring) + - [SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])](#sourcenodeprototypetostringwithsourcemapstartofsourcemap) + + + +## Examples + +### Consuming a source map + +```js +var rawSourceMap = { + version: 3, + file: 'min.js', + names: ['bar', 'baz', 'n'], + sources: ['one.js', 'two.js'], + sourceRoot: 'http://example.com/www/js/', + mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA' +}; + +var smc = new SourceMapConsumer(rawSourceMap); + +console.log(smc.sources); +// [ 'http://example.com/www/js/one.js', +// 'http://example.com/www/js/two.js' ] + +console.log(smc.originalPositionFor({ + line: 2, + column: 28 +})); +// { source: 'http://example.com/www/js/two.js', +// line: 2, +// column: 10, +// name: 'n' } + +console.log(smc.generatedPositionFor({ + source: 'http://example.com/www/js/two.js', + line: 2, + column: 10 +})); +// { line: 2, column: 28 } + +smc.eachMapping(function (m) { + // ... +}); +``` + +### Generating a source map + +In depth guide: +[**Compiling to JavaScript, and Debugging with Source Maps**](https://hacks.mozilla.org/2013/05/compiling-to-javascript-and-debugging-with-source-maps/) + +#### With SourceNode (high level API) + +```js +function compile(ast) { + switch (ast.type) { + case 'BinaryExpression': + return new SourceNode( + ast.location.line, + ast.location.column, + ast.location.source, + [compile(ast.left), " + ", compile(ast.right)] + ); + case 'Literal': + return new SourceNode( + ast.location.line, + ast.location.column, + ast.location.source, + String(ast.value) + ); + // ... + default: + throw new Error("Bad AST"); + } +} + +var ast = parse("40 + 2", "add.js"); +console.log(compile(ast).toStringWithSourceMap({ + file: 'add.js' +})); +// { code: '40 + 2', +// map: [object SourceMapGenerator] } +``` + +#### With SourceMapGenerator (low level API) + +```js +var map = new SourceMapGenerator({ + file: "source-mapped.js" +}); + +map.addMapping({ + generated: { + line: 10, + column: 35 + }, + source: "foo.js", + original: { + line: 33, + column: 2 + }, + name: "christopher" +}); + +console.log(map.toString()); +// '{"version":3,"file":"source-mapped.js","sources":["foo.js"],"names":["christopher"],"mappings":";;;;;;;;;mCAgCEA"}' +``` + +## API + +Get a reference to the module: + +```js +// Node.js +var sourceMap = require('source-map'); + +// Browser builds +var sourceMap = window.sourceMap; + +// Inside Firefox +const sourceMap = require("devtools/toolkit/sourcemap/source-map.js"); +``` + +### SourceMapConsumer + +A SourceMapConsumer instance represents a parsed source map which we can query +for information about the original file positions by giving it a file position +in the generated source. + +#### new SourceMapConsumer(rawSourceMap) + +The only parameter is the raw source map (either as a string which can be +`JSON.parse`'d, or an object). According to the spec, source maps have the +following attributes: + +* `version`: Which version of the source map spec this map is following. + +* `sources`: An array of URLs to the original source files. + +* `names`: An array of identifiers which can be referenced by individual + mappings. + +* `sourceRoot`: Optional. The URL root from which all sources are relative. + +* `sourcesContent`: Optional. An array of contents of the original source files. + +* `mappings`: A string of base64 VLQs which contain the actual mappings. + +* `file`: Optional. The generated filename this source map is associated with. + +```js +var consumer = new sourceMap.SourceMapConsumer(rawSourceMapJsonData); +``` + +#### SourceMapConsumer.prototype.computeColumnSpans() + +Compute the last column for each generated mapping. The last column is +inclusive. + +```js +// Before: +consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }) +// [ { line: 2, +// column: 1 }, +// { line: 2, +// column: 10 }, +// { line: 2, +// column: 20 } ] + +consumer.computeColumnSpans(); + +// After: +consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }) +// [ { line: 2, +// column: 1, +// lastColumn: 9 }, +// { line: 2, +// column: 10, +// lastColumn: 19 }, +// { line: 2, +// column: 20, +// lastColumn: Infinity } ] + +``` + +#### SourceMapConsumer.prototype.originalPositionFor(generatedPosition) + +Returns the original source, line, and column information for the generated +source's line and column positions provided. The only argument is an object with +the following properties: + +* `line`: The line number in the generated source. + +* `column`: The column number in the generated source. + +* `bias`: Either `SourceMapConsumer.GREATEST_LOWER_BOUND` or + `SourceMapConsumer.LEAST_UPPER_BOUND`. Specifies whether to return the closest + element that is smaller than or greater than the one we are searching for, + respectively, if the exact element cannot be found. Defaults to + `SourceMapConsumer.GREATEST_LOWER_BOUND`. + +and an object is returned with the following properties: + +* `source`: The original source file, or null if this information is not + available. + +* `line`: The line number in the original source, or null if this information is + not available. + +* `column`: The column number in the original source, or null or null if this + information is not available. + +* `name`: The original identifier, or null if this information is not available. + +```js +consumer.originalPositionFor({ line: 2, column: 10 }) +// { source: 'foo.coffee', +// line: 2, +// column: 2, +// name: null } + +consumer.originalPositionFor({ line: 99999999999999999, column: 999999999999999 }) +// { source: null, +// line: null, +// column: null, +// name: null } +``` + +#### SourceMapConsumer.prototype.generatedPositionFor(originalPosition) + +Returns the generated line and column information for the original source, +line, and column positions provided. The only argument is an object with +the following properties: + +* `source`: The filename of the original source. + +* `line`: The line number in the original source. + +* `column`: The column number in the original source. + +and an object is returned with the following properties: + +* `line`: The line number in the generated source, or null. + +* `column`: The column number in the generated source, or null. + +```js +consumer.generatedPositionFor({ source: "example.js", line: 2, column: 10 }) +// { line: 1, +// column: 56 } +``` + +#### SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition) + +Returns all generated line and column information for the original source, line, +and column provided. If no column is provided, returns all mappings +corresponding to a either the line we are searching for or the next closest line +that has any mappings. Otherwise, returns all mappings corresponding to the +given line and either the column we are searching for or the next closest column +that has any offsets. + +The only argument is an object with the following properties: + +* `source`: The filename of the original source. + +* `line`: The line number in the original source. + +* `column`: Optional. The column number in the original source. + +and an array of objects is returned, each with the following properties: + +* `line`: The line number in the generated source, or null. + +* `column`: The column number in the generated source, or null. + +```js +consumer.allGeneratedpositionsfor({ line: 2, source: "foo.coffee" }) +// [ { line: 2, +// column: 1 }, +// { line: 2, +// column: 10 }, +// { line: 2, +// column: 20 } ] +``` + +#### SourceMapConsumer.prototype.hasContentsOfAllSources() + +Return true if we have the embedded source content for every source listed in +the source map, false otherwise. + +In other words, if this method returns `true`, then +`consumer.sourceContentFor(s)` will succeed for every source `s` in +`consumer.sources`. + +```js +// ... +if (consumer.hasContentsOfAllSources()) { + consumerReadyCallback(consumer); +} else { + fetchSources(consumer, consumerReadyCallback); +} +// ... +``` + +#### SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing]) + +Returns the original source content for the source provided. The only +argument is the URL of the original source file. + +If the source content for the given source is not found, then an error is +thrown. Optionally, pass `true` as the second param to have `null` returned +instead. + +```js +consumer.sources +// [ "my-cool-lib.clj" ] + +consumer.sourceContentFor("my-cool-lib.clj") +// "..." + +consumer.sourceContentFor("this is not in the source map"); +// Error: "this is not in the source map" is not in the source map + +consumer.sourceContentFor("this is not in the source map", true); +// null +``` + +#### SourceMapConsumer.prototype.eachMapping(callback, context, order) + +Iterate over each mapping between an original source/line/column and a +generated line/column in this source map. + +* `callback`: The function that is called with each mapping. Mappings have the + form `{ source, generatedLine, generatedColumn, originalLine, originalColumn, + name }` + +* `context`: Optional. If specified, this object will be the value of `this` + every time that `callback` is called. + +* `order`: Either `SourceMapConsumer.GENERATED_ORDER` or + `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to iterate over + the mappings sorted by the generated file's line/column order or the + original's source/line/column order, respectively. Defaults to + `SourceMapConsumer.GENERATED_ORDER`. + +```js +consumer.eachMapping(function (m) { console.log(m); }) +// ... +// { source: 'illmatic.js', +// generatedLine: 1, +// generatedColumn: 0, +// originalLine: 1, +// originalColumn: 0, +// name: null } +// { source: 'illmatic.js', +// generatedLine: 2, +// generatedColumn: 0, +// originalLine: 2, +// originalColumn: 0, +// name: null } +// ... +``` +### SourceMapGenerator + +An instance of the SourceMapGenerator represents a source map which is being +built incrementally. + +#### new SourceMapGenerator([startOfSourceMap]) + +You may pass an object with the following properties: + +* `file`: The filename of the generated source that this source map is + associated with. + +* `sourceRoot`: A root for all relative URLs in this source map. + +* `skipValidation`: Optional. When `true`, disables validation of mappings as + they are added. This can improve performance but should be used with + discretion, as a last resort. Even then, one should avoid using this flag when + running tests, if possible. + +```js +var generator = new sourceMap.SourceMapGenerator({ + file: "my-generated-javascript-file.js", + sourceRoot: "http://example.com/app/js/" +}); +``` + +#### SourceMapGenerator.fromSourceMap(sourceMapConsumer) + +Creates a new `SourceMapGenerator` from an existing `SourceMapConsumer` instance. + +* `sourceMapConsumer` The SourceMap. + +```js +var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer); +``` + +#### SourceMapGenerator.prototype.addMapping(mapping) + +Add a single mapping from original source line and column to the generated +source's line and column for this source map being created. The mapping object +should have the following properties: + +* `generated`: An object with the generated line and column positions. + +* `original`: An object with the original line and column positions. + +* `source`: The original source file (relative to the sourceRoot). + +* `name`: An optional original token name for this mapping. + +```js +generator.addMapping({ + source: "module-one.scm", + original: { line: 128, column: 0 }, + generated: { line: 3, column: 456 } +}) +``` + +#### SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent) + +Set the source content for an original source file. + +* `sourceFile` the URL of the original source file. + +* `sourceContent` the content of the source file. + +```js +generator.setSourceContent("module-one.scm", + fs.readFileSync("path/to/module-one.scm")) +``` + +#### SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]]) + +Applies a SourceMap for a source file to the SourceMap. +Each mapping to the supplied source file is rewritten using the +supplied SourceMap. Note: The resolution for the resulting mappings +is the minimum of this map and the supplied map. + +* `sourceMapConsumer`: The SourceMap to be applied. + +* `sourceFile`: Optional. The filename of the source file. + If omitted, sourceMapConsumer.file will be used, if it exists. + Otherwise an error will be thrown. + +* `sourceMapPath`: Optional. The dirname of the path to the SourceMap + to be applied. If relative, it is relative to the SourceMap. + + This parameter is needed when the two SourceMaps aren't in the same + directory, and the SourceMap to be applied contains relative source + paths. If so, those relative source paths need to be rewritten + relative to the SourceMap. + + If omitted, it is assumed that both SourceMaps are in the same directory, + thus not needing any rewriting. (Supplying `'.'` has the same effect.) + +#### SourceMapGenerator.prototype.toString() + +Renders the source map being generated to a string. + +```js +generator.toString() +// '{"version":3,"sources":["module-one.scm"],"names":[],"mappings":"...snip...","file":"my-generated-javascript-file.js","sourceRoot":"http://example.com/app/js/"}' +``` + +### SourceNode + +SourceNodes provide a way to abstract over interpolating and/or concatenating +snippets of generated JavaScript source code, while maintaining the line and +column information associated between those snippets and the original source +code. This is useful as the final intermediate representation a compiler might +use before outputting the generated JS and source map. + +#### new SourceNode([line, column, source[, chunk[, name]]]) + +* `line`: The original line number associated with this source node, or null if + it isn't associated with an original line. + +* `column`: The original column number associated with this source node, or null + if it isn't associated with an original column. + +* `source`: The original source's filename; null if no filename is provided. + +* `chunk`: Optional. Is immediately passed to `SourceNode.prototype.add`, see + below. + +* `name`: Optional. The original identifier. + +```js +var node = new SourceNode(1, 2, "a.cpp", [ + new SourceNode(3, 4, "b.cpp", "extern int status;\n"), + new SourceNode(5, 6, "c.cpp", "std::string* make_string(size_t n);\n"), + new SourceNode(7, 8, "d.cpp", "int main(int argc, char** argv) {}\n"), +]); +``` + +#### SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath]) + +Creates a SourceNode from generated code and a SourceMapConsumer. + +* `code`: The generated code + +* `sourceMapConsumer` The SourceMap for the generated code + +* `relativePath` The optional path that relative sources in `sourceMapConsumer` + should be relative to. + +```js +var consumer = new SourceMapConsumer(fs.readFileSync("path/to/my-file.js.map")); +var node = SourceNode.fromStringWithSourceMap(fs.readFileSync("path/to/my-file.js"), + consumer); +``` + +#### SourceNode.prototype.add(chunk) + +Add a chunk of generated JS to this source node. + +* `chunk`: A string snippet of generated JS code, another instance of + `SourceNode`, or an array where each member is one of those things. + +```js +node.add(" + "); +node.add(otherNode); +node.add([leftHandOperandNode, " + ", rightHandOperandNode]); +``` + +#### SourceNode.prototype.prepend(chunk) + +Prepend a chunk of generated JS to this source node. + +* `chunk`: A string snippet of generated JS code, another instance of + `SourceNode`, or an array where each member is one of those things. + +```js +node.prepend("/** Build Id: f783haef86324gf **/\n\n"); +``` + +#### SourceNode.prototype.setSourceContent(sourceFile, sourceContent) + +Set the source content for a source file. This will be added to the +`SourceMap` in the `sourcesContent` field. + +* `sourceFile`: The filename of the source file + +* `sourceContent`: The content of the source file + +```js +node.setSourceContent("module-one.scm", + fs.readFileSync("path/to/module-one.scm")) +``` + +#### SourceNode.prototype.walk(fn) + +Walk over the tree of JS snippets in this node and its children. The walking +function is called once for each snippet of JS and is passed that snippet and +the its original associated source's line/column location. + +* `fn`: The traversal function. + +```js +var node = new SourceNode(1, 2, "a.js", [ + new SourceNode(3, 4, "b.js", "uno"), + "dos", + [ + "tres", + new SourceNode(5, 6, "c.js", "quatro") + ] +]); + +node.walk(function (code, loc) { console.log("WALK:", code, loc); }) +// WALK: uno { source: 'b.js', line: 3, column: 4, name: null } +// WALK: dos { source: 'a.js', line: 1, column: 2, name: null } +// WALK: tres { source: 'a.js', line: 1, column: 2, name: null } +// WALK: quatro { source: 'c.js', line: 5, column: 6, name: null } +``` + +#### SourceNode.prototype.walkSourceContents(fn) + +Walk over the tree of SourceNodes. The walking function is called for each +source file content and is passed the filename and source content. + +* `fn`: The traversal function. + +```js +var a = new SourceNode(1, 2, "a.js", "generated from a"); +a.setSourceContent("a.js", "original a"); +var b = new SourceNode(1, 2, "b.js", "generated from b"); +b.setSourceContent("b.js", "original b"); +var c = new SourceNode(1, 2, "c.js", "generated from c"); +c.setSourceContent("c.js", "original c"); + +var node = new SourceNode(null, null, null, [a, b, c]); +node.walkSourceContents(function (source, contents) { console.log("WALK:", source, ":", contents); }) +// WALK: a.js : original a +// WALK: b.js : original b +// WALK: c.js : original c +``` + +#### SourceNode.prototype.join(sep) + +Like `Array.prototype.join` except for SourceNodes. Inserts the separator +between each of this source node's children. + +* `sep`: The separator. + +```js +var lhs = new SourceNode(1, 2, "a.rs", "my_copy"); +var operand = new SourceNode(3, 4, "a.rs", "="); +var rhs = new SourceNode(5, 6, "a.rs", "orig.clone()"); + +var node = new SourceNode(null, null, null, [ lhs, operand, rhs ]); +var joinedNode = node.join(" "); +``` + +#### SourceNode.prototype.replaceRight(pattern, replacement) + +Call `String.prototype.replace` on the very right-most source snippet. Useful +for trimming white space from the end of a source node, etc. + +* `pattern`: The pattern to replace. + +* `replacement`: The thing to replace the pattern with. + +```js +// Trim trailing white space. +node.replaceRight(/\s*$/, ""); +``` + +#### SourceNode.prototype.toString() + +Return the string representation of this source node. Walks over the tree and +concatenates all the various snippets together to one string. + +```js +var node = new SourceNode(1, 2, "a.js", [ + new SourceNode(3, 4, "b.js", "uno"), + "dos", + [ + "tres", + new SourceNode(5, 6, "c.js", "quatro") + ] +]); + +node.toString() +// 'unodostresquatro' +``` + +#### SourceNode.prototype.toStringWithSourceMap([startOfSourceMap]) + +Returns the string representation of this tree of source nodes, plus a +SourceMapGenerator which contains all the mappings between the generated and +original sources. + +The arguments are the same as those to `new SourceMapGenerator`. + +```js +var node = new SourceNode(1, 2, "a.js", [ + new SourceNode(3, 4, "b.js", "uno"), + "dos", + [ + "tres", + new SourceNode(5, 6, "c.js", "quatro") + ] +]); + +node.toStringWithSourceMap({ file: "my-output-file.js" }) +// { code: 'unodostresquatro', +// map: [object SourceMapGenerator] } +``` diff --git a/node_modules/source-map/dist/source-map.debug.js b/node_modules/source-map/dist/source-map.debug.js new file mode 100644 index 0000000..a3bcda1 --- /dev/null +++ b/node_modules/source-map/dist/source-map.debug.js @@ -0,0 +1,3056 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["sourceMap"] = factory(); + else + root["sourceMap"] = factory(); +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; +/******/ +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.loaded = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + /* + * Copyright 2009-2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE.txt or: + * http://opensource.org/licenses/BSD-3-Clause + */ + exports.SourceMapGenerator = __webpack_require__(1).SourceMapGenerator; + exports.SourceMapConsumer = __webpack_require__(7).SourceMapConsumer; + exports.SourceNode = __webpack_require__(10).SourceNode; + + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var base64VLQ = __webpack_require__(2); + var util = __webpack_require__(4); + var ArraySet = __webpack_require__(5).ArraySet; + var MappingList = __webpack_require__(6).MappingList; + + /** + * An instance of the SourceMapGenerator represents a source map which is + * being built incrementally. You may pass an object with the following + * properties: + * + * - file: The filename of the generated source. + * - sourceRoot: A root for all relative URLs in this source map. + */ + function SourceMapGenerator(aArgs) { + if (!aArgs) { + aArgs = {}; + } + this._file = util.getArg(aArgs, 'file', null); + this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null); + this._skipValidation = util.getArg(aArgs, 'skipValidation', false); + this._sources = new ArraySet(); + this._names = new ArraySet(); + this._mappings = new MappingList(); + this._sourcesContents = null; + } + + SourceMapGenerator.prototype._version = 3; + + /** + * Creates a new SourceMapGenerator based on a SourceMapConsumer + * + * @param aSourceMapConsumer The SourceMap. + */ + SourceMapGenerator.fromSourceMap = + function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) { + var sourceRoot = aSourceMapConsumer.sourceRoot; + var generator = new SourceMapGenerator({ + file: aSourceMapConsumer.file, + sourceRoot: sourceRoot + }); + aSourceMapConsumer.eachMapping(function (mapping) { + var newMapping = { + generated: { + line: mapping.generatedLine, + column: mapping.generatedColumn + } + }; + + if (mapping.source != null) { + newMapping.source = mapping.source; + if (sourceRoot != null) { + newMapping.source = util.relative(sourceRoot, newMapping.source); + } + + newMapping.original = { + line: mapping.originalLine, + column: mapping.originalColumn + }; + + if (mapping.name != null) { + newMapping.name = mapping.name; + } + } + + generator.addMapping(newMapping); + }); + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + generator.setSourceContent(sourceFile, content); + } + }); + return generator; + }; + + /** + * Add a single mapping from original source line and column to the generated + * source's line and column for this source map being created. The mapping + * object should have the following properties: + * + * - generated: An object with the generated line and column positions. + * - original: An object with the original line and column positions. + * - source: The original source file (relative to the sourceRoot). + * - name: An optional original token name for this mapping. + */ + SourceMapGenerator.prototype.addMapping = + function SourceMapGenerator_addMapping(aArgs) { + var generated = util.getArg(aArgs, 'generated'); + var original = util.getArg(aArgs, 'original', null); + var source = util.getArg(aArgs, 'source', null); + var name = util.getArg(aArgs, 'name', null); + + if (!this._skipValidation) { + this._validateMapping(generated, original, source, name); + } + + if (source != null) { + source = String(source); + if (!this._sources.has(source)) { + this._sources.add(source); + } + } + + if (name != null) { + name = String(name); + if (!this._names.has(name)) { + this._names.add(name); + } + } + + this._mappings.add({ + generatedLine: generated.line, + generatedColumn: generated.column, + originalLine: original != null && original.line, + originalColumn: original != null && original.column, + source: source, + name: name + }); + }; + + /** + * Set the source content for a source file. + */ + SourceMapGenerator.prototype.setSourceContent = + function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { + var source = aSourceFile; + if (this._sourceRoot != null) { + source = util.relative(this._sourceRoot, source); + } + + if (aSourceContent != null) { + // Add the source content to the _sourcesContents map. + // Create a new _sourcesContents map if the property is null. + if (!this._sourcesContents) { + this._sourcesContents = Object.create(null); + } + this._sourcesContents[util.toSetString(source)] = aSourceContent; + } else if (this._sourcesContents) { + // Remove the source file from the _sourcesContents map. + // If the _sourcesContents map is empty, set the property to null. + delete this._sourcesContents[util.toSetString(source)]; + if (Object.keys(this._sourcesContents).length === 0) { + this._sourcesContents = null; + } + } + }; + + /** + * Applies the mappings of a sub-source-map for a specific source file to the + * source map being generated. Each mapping to the supplied source file is + * rewritten using the supplied source map. Note: The resolution for the + * resulting mappings is the minimium of this map and the supplied map. + * + * @param aSourceMapConsumer The source map to be applied. + * @param aSourceFile Optional. The filename of the source file. + * If omitted, SourceMapConsumer's file property will be used. + * @param aSourceMapPath Optional. The dirname of the path to the source map + * to be applied. If relative, it is relative to the SourceMapConsumer. + * This parameter is needed when the two source maps aren't in the same + * directory, and the source map to be applied contains relative source + * paths. If so, those relative source paths need to be rewritten + * relative to the SourceMapGenerator. + */ + SourceMapGenerator.prototype.applySourceMap = + function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) { + var sourceFile = aSourceFile; + // If aSourceFile is omitted, we will use the file property of the SourceMap + if (aSourceFile == null) { + if (aSourceMapConsumer.file == null) { + throw new Error( + 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' + + 'or the source map\'s "file" property. Both were omitted.' + ); + } + sourceFile = aSourceMapConsumer.file; + } + var sourceRoot = this._sourceRoot; + // Make "sourceFile" relative if an absolute Url is passed. + if (sourceRoot != null) { + sourceFile = util.relative(sourceRoot, sourceFile); + } + // Applying the SourceMap can add and remove items from the sources and + // the names array. + var newSources = new ArraySet(); + var newNames = new ArraySet(); + + // Find mappings for the "sourceFile" + this._mappings.unsortedForEach(function (mapping) { + if (mapping.source === sourceFile && mapping.originalLine != null) { + // Check if it can be mapped by the source map, then update the mapping. + var original = aSourceMapConsumer.originalPositionFor({ + line: mapping.originalLine, + column: mapping.originalColumn + }); + if (original.source != null) { + // Copy mapping + mapping.source = original.source; + if (aSourceMapPath != null) { + mapping.source = util.join(aSourceMapPath, mapping.source) + } + if (sourceRoot != null) { + mapping.source = util.relative(sourceRoot, mapping.source); + } + mapping.originalLine = original.line; + mapping.originalColumn = original.column; + if (original.name != null) { + mapping.name = original.name; + } + } + } + + var source = mapping.source; + if (source != null && !newSources.has(source)) { + newSources.add(source); + } + + var name = mapping.name; + if (name != null && !newNames.has(name)) { + newNames.add(name); + } + + }, this); + this._sources = newSources; + this._names = newNames; + + // Copy sourcesContents of applied map. + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aSourceMapPath != null) { + sourceFile = util.join(aSourceMapPath, sourceFile); + } + if (sourceRoot != null) { + sourceFile = util.relative(sourceRoot, sourceFile); + } + this.setSourceContent(sourceFile, content); + } + }, this); + }; + + /** + * A mapping can have one of the three levels of data: + * + * 1. Just the generated position. + * 2. The Generated position, original position, and original source. + * 3. Generated and original position, original source, as well as a name + * token. + * + * To maintain consistency, we validate that any new mapping being added falls + * in to one of these categories. + */ + SourceMapGenerator.prototype._validateMapping = + function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, + aName) { + if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aGenerated.line > 0 && aGenerated.column >= 0 + && !aOriginal && !aSource && !aName) { + // Case 1. + return; + } + else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aOriginal && 'line' in aOriginal && 'column' in aOriginal + && aGenerated.line > 0 && aGenerated.column >= 0 + && aOriginal.line > 0 && aOriginal.column >= 0 + && aSource) { + // Cases 2 and 3. + return; + } + else { + throw new Error('Invalid mapping: ' + JSON.stringify({ + generated: aGenerated, + source: aSource, + original: aOriginal, + name: aName + })); + } + }; + + /** + * Serialize the accumulated mappings in to the stream of base 64 VLQs + * specified by the source map format. + */ + SourceMapGenerator.prototype._serializeMappings = + function SourceMapGenerator_serializeMappings() { + var previousGeneratedColumn = 0; + var previousGeneratedLine = 1; + var previousOriginalColumn = 0; + var previousOriginalLine = 0; + var previousName = 0; + var previousSource = 0; + var result = ''; + var next; + var mapping; + var nameIdx; + var sourceIdx; + + var mappings = this._mappings.toArray(); + for (var i = 0, len = mappings.length; i < len; i++) { + mapping = mappings[i]; + next = '' + + if (mapping.generatedLine !== previousGeneratedLine) { + previousGeneratedColumn = 0; + while (mapping.generatedLine !== previousGeneratedLine) { + next += ';'; + previousGeneratedLine++; + } + } + else { + if (i > 0) { + if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) { + continue; + } + next += ','; + } + } + + next += base64VLQ.encode(mapping.generatedColumn + - previousGeneratedColumn); + previousGeneratedColumn = mapping.generatedColumn; + + if (mapping.source != null) { + sourceIdx = this._sources.indexOf(mapping.source); + next += base64VLQ.encode(sourceIdx - previousSource); + previousSource = sourceIdx; + + // lines are stored 0-based in SourceMap spec version 3 + next += base64VLQ.encode(mapping.originalLine - 1 + - previousOriginalLine); + previousOriginalLine = mapping.originalLine - 1; + + next += base64VLQ.encode(mapping.originalColumn + - previousOriginalColumn); + previousOriginalColumn = mapping.originalColumn; + + if (mapping.name != null) { + nameIdx = this._names.indexOf(mapping.name); + next += base64VLQ.encode(nameIdx - previousName); + previousName = nameIdx; + } + } + + result += next; + } + + return result; + }; + + SourceMapGenerator.prototype._generateSourcesContent = + function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) { + return aSources.map(function (source) { + if (!this._sourcesContents) { + return null; + } + if (aSourceRoot != null) { + source = util.relative(aSourceRoot, source); + } + var key = util.toSetString(source); + return Object.prototype.hasOwnProperty.call(this._sourcesContents, key) + ? this._sourcesContents[key] + : null; + }, this); + }; + + /** + * Externalize the source map. + */ + SourceMapGenerator.prototype.toJSON = + function SourceMapGenerator_toJSON() { + var map = { + version: this._version, + sources: this._sources.toArray(), + names: this._names.toArray(), + mappings: this._serializeMappings() + }; + if (this._file != null) { + map.file = this._file; + } + if (this._sourceRoot != null) { + map.sourceRoot = this._sourceRoot; + } + if (this._sourcesContents) { + map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); + } + + return map; + }; + + /** + * Render the source map being generated to a string. + */ + SourceMapGenerator.prototype.toString = + function SourceMapGenerator_toString() { + return JSON.stringify(this.toJSON()); + }; + + exports.SourceMapGenerator = SourceMapGenerator; + + +/***/ }, +/* 2 */ +/***/ function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + * + * Based on the Base 64 VLQ implementation in Closure Compiler: + * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java + * + * Copyright 2011 The Closure Compiler Authors. All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + var base64 = __webpack_require__(3); + + // A single base 64 digit can contain 6 bits of data. For the base 64 variable + // length quantities we use in the source map spec, the first bit is the sign, + // the next four bits are the actual value, and the 6th bit is the + // continuation bit. The continuation bit tells us whether there are more + // digits in this value following this digit. + // + // Continuation + // | Sign + // | | + // V V + // 101011 + + var VLQ_BASE_SHIFT = 5; + + // binary: 100000 + var VLQ_BASE = 1 << VLQ_BASE_SHIFT; + + // binary: 011111 + var VLQ_BASE_MASK = VLQ_BASE - 1; + + // binary: 100000 + var VLQ_CONTINUATION_BIT = VLQ_BASE; + + /** + * Converts from a two-complement value to a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) + * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) + */ + function toVLQSigned(aValue) { + return aValue < 0 + ? ((-aValue) << 1) + 1 + : (aValue << 1) + 0; + } + + /** + * Converts to a two-complement value from a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 + * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 + */ + function fromVLQSigned(aValue) { + var isNegative = (aValue & 1) === 1; + var shifted = aValue >> 1; + return isNegative + ? -shifted + : shifted; + } + + /** + * Returns the base 64 VLQ encoded value. + */ + exports.encode = function base64VLQ_encode(aValue) { + var encoded = ""; + var digit; + + var vlq = toVLQSigned(aValue); + + do { + digit = vlq & VLQ_BASE_MASK; + vlq >>>= VLQ_BASE_SHIFT; + if (vlq > 0) { + // There are still more digits in this value, so we must make sure the + // continuation bit is marked. + digit |= VLQ_CONTINUATION_BIT; + } + encoded += base64.encode(digit); + } while (vlq > 0); + + return encoded; + }; + + /** + * Decodes the next base 64 VLQ value from the given string and returns the + * value and the rest of the string via the out parameter. + */ + exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { + var strLen = aStr.length; + var result = 0; + var shift = 0; + var continuation, digit; + + do { + if (aIndex >= strLen) { + throw new Error("Expected more digits in base 64 VLQ value."); + } + + digit = base64.decode(aStr.charCodeAt(aIndex++)); + if (digit === -1) { + throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1)); + } + + continuation = !!(digit & VLQ_CONTINUATION_BIT); + digit &= VLQ_BASE_MASK; + result = result + (digit << shift); + shift += VLQ_BASE_SHIFT; + } while (continuation); + + aOutParam.value = fromVLQSigned(result); + aOutParam.rest = aIndex; + }; + + +/***/ }, +/* 3 */ +/***/ function(module, exports) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); + + /** + * Encode an integer in the range of 0 to 63 to a single base 64 digit. + */ + exports.encode = function (number) { + if (0 <= number && number < intToCharMap.length) { + return intToCharMap[number]; + } + throw new TypeError("Must be between 0 and 63: " + number); + }; + + /** + * Decode a single base 64 character code digit to an integer. Returns -1 on + * failure. + */ + exports.decode = function (charCode) { + var bigA = 65; // 'A' + var bigZ = 90; // 'Z' + + var littleA = 97; // 'a' + var littleZ = 122; // 'z' + + var zero = 48; // '0' + var nine = 57; // '9' + + var plus = 43; // '+' + var slash = 47; // '/' + + var littleOffset = 26; + var numberOffset = 52; + + // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ + if (bigA <= charCode && charCode <= bigZ) { + return (charCode - bigA); + } + + // 26 - 51: abcdefghijklmnopqrstuvwxyz + if (littleA <= charCode && charCode <= littleZ) { + return (charCode - littleA + littleOffset); + } + + // 52 - 61: 0123456789 + if (zero <= charCode && charCode <= nine) { + return (charCode - zero + numberOffset); + } + + // 62: + + if (charCode == plus) { + return 62; + } + + // 63: / + if (charCode == slash) { + return 63; + } + + // Invalid base64 digit. + return -1; + }; + + +/***/ }, +/* 4 */ +/***/ function(module, exports) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + /** + * This is a helper function for getting values from parameter/options + * objects. + * + * @param args The object we are extracting values from + * @param name The name of the property we are getting. + * @param defaultValue An optional value to return if the property is missing + * from the object. If this is not specified and the property is missing, an + * error will be thrown. + */ + function getArg(aArgs, aName, aDefaultValue) { + if (aName in aArgs) { + return aArgs[aName]; + } else if (arguments.length === 3) { + return aDefaultValue; + } else { + throw new Error('"' + aName + '" is a required argument.'); + } + } + exports.getArg = getArg; + + var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/; + var dataUrlRegexp = /^data:.+\,.+$/; + + function urlParse(aUrl) { + var match = aUrl.match(urlRegexp); + if (!match) { + return null; + } + return { + scheme: match[1], + auth: match[2], + host: match[3], + port: match[4], + path: match[5] + }; + } + exports.urlParse = urlParse; + + function urlGenerate(aParsedUrl) { + var url = ''; + if (aParsedUrl.scheme) { + url += aParsedUrl.scheme + ':'; + } + url += '//'; + if (aParsedUrl.auth) { + url += aParsedUrl.auth + '@'; + } + if (aParsedUrl.host) { + url += aParsedUrl.host; + } + if (aParsedUrl.port) { + url += ":" + aParsedUrl.port + } + if (aParsedUrl.path) { + url += aParsedUrl.path; + } + return url; + } + exports.urlGenerate = urlGenerate; + + /** + * Normalizes a path, or the path portion of a URL: + * + * - Replaces consequtive slashes with one slash. + * - Removes unnecessary '.' parts. + * - Removes unnecessary '/..' parts. + * + * Based on code in the Node.js 'path' core module. + * + * @param aPath The path or url to normalize. + */ + function normalize(aPath) { + var path = aPath; + var url = urlParse(aPath); + if (url) { + if (!url.path) { + return aPath; + } + path = url.path; + } + var isAbsolute = exports.isAbsolute(path); + + var parts = path.split(/\/+/); + for (var part, up = 0, i = parts.length - 1; i >= 0; i--) { + part = parts[i]; + if (part === '.') { + parts.splice(i, 1); + } else if (part === '..') { + up++; + } else if (up > 0) { + if (part === '') { + // The first part is blank if the path is absolute. Trying to go + // above the root is a no-op. Therefore we can remove all '..' parts + // directly after the root. + parts.splice(i + 1, up); + up = 0; + } else { + parts.splice(i, 2); + up--; + } + } + } + path = parts.join('/'); + + if (path === '') { + path = isAbsolute ? '/' : '.'; + } + + if (url) { + url.path = path; + return urlGenerate(url); + } + return path; + } + exports.normalize = normalize; + + /** + * Joins two paths/URLs. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be joined with the root. + * + * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a + * scheme-relative URL: Then the scheme of aRoot, if any, is prepended + * first. + * - Otherwise aPath is a path. If aRoot is a URL, then its path portion + * is updated with the result and aRoot is returned. Otherwise the result + * is returned. + * - If aPath is absolute, the result is aPath. + * - Otherwise the two paths are joined with a slash. + * - Joining for example 'http://' and 'www.example.com' is also supported. + */ + function join(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + if (aPath === "") { + aPath = "."; + } + var aPathUrl = urlParse(aPath); + var aRootUrl = urlParse(aRoot); + if (aRootUrl) { + aRoot = aRootUrl.path || '/'; + } + + // `join(foo, '//www.example.org')` + if (aPathUrl && !aPathUrl.scheme) { + if (aRootUrl) { + aPathUrl.scheme = aRootUrl.scheme; + } + return urlGenerate(aPathUrl); + } + + if (aPathUrl || aPath.match(dataUrlRegexp)) { + return aPath; + } + + // `join('http://', 'www.example.com')` + if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { + aRootUrl.host = aPath; + return urlGenerate(aRootUrl); + } + + var joined = aPath.charAt(0) === '/' + ? aPath + : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); + + if (aRootUrl) { + aRootUrl.path = joined; + return urlGenerate(aRootUrl); + } + return joined; + } + exports.join = join; + + exports.isAbsolute = function (aPath) { + return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp); + }; + + /** + * Make a path relative to a URL or another path. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be made relative to aRoot. + */ + function relative(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + + aRoot = aRoot.replace(/\/$/, ''); + + // It is possible for the path to be above the root. In this case, simply + // checking whether the root is a prefix of the path won't work. Instead, we + // need to remove components from the root one by one, until either we find + // a prefix that fits, or we run out of components to remove. + var level = 0; + while (aPath.indexOf(aRoot + '/') !== 0) { + var index = aRoot.lastIndexOf("/"); + if (index < 0) { + return aPath; + } + + // If the only part of the root that is left is the scheme (i.e. http://, + // file:///, etc.), one or more slashes (/), or simply nothing at all, we + // have exhausted all components, so the path is not relative to the root. + aRoot = aRoot.slice(0, index); + if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { + return aPath; + } + + ++level; + } + + // Make sure we add a "../" for each component we removed from the root. + return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1); + } + exports.relative = relative; + + var supportsNullProto = (function () { + var obj = Object.create(null); + return !('__proto__' in obj); + }()); + + function identity (s) { + return s; + } + + /** + * Because behavior goes wacky when you set `__proto__` on objects, we + * have to prefix all the strings in our set with an arbitrary character. + * + * See https://github.com/mozilla/source-map/pull/31 and + * https://github.com/mozilla/source-map/issues/30 + * + * @param String aStr + */ + function toSetString(aStr) { + if (isProtoString(aStr)) { + return '$' + aStr; + } + + return aStr; + } + exports.toSetString = supportsNullProto ? identity : toSetString; + + function fromSetString(aStr) { + if (isProtoString(aStr)) { + return aStr.slice(1); + } + + return aStr; + } + exports.fromSetString = supportsNullProto ? identity : fromSetString; + + function isProtoString(s) { + if (!s) { + return false; + } + + var length = s.length; + + if (length < 9 /* "__proto__".length */) { + return false; + } + + if (s.charCodeAt(length - 1) !== 95 /* '_' */ || + s.charCodeAt(length - 2) !== 95 /* '_' */ || + s.charCodeAt(length - 3) !== 111 /* 'o' */ || + s.charCodeAt(length - 4) !== 116 /* 't' */ || + s.charCodeAt(length - 5) !== 111 /* 'o' */ || + s.charCodeAt(length - 6) !== 114 /* 'r' */ || + s.charCodeAt(length - 7) !== 112 /* 'p' */ || + s.charCodeAt(length - 8) !== 95 /* '_' */ || + s.charCodeAt(length - 9) !== 95 /* '_' */) { + return false; + } + + for (var i = length - 10; i >= 0; i--) { + if (s.charCodeAt(i) !== 36 /* '$' */) { + return false; + } + } + + return true; + } + + /** + * Comparator between two mappings where the original positions are compared. + * + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same original source/line/column, but different generated + * line and column the same. Useful when searching for a mapping with a + * stubbed out mapping. + */ + function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { + var cmp = mappingA.source - mappingB.source; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0 || onlyCompareOriginal) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + return mappingA.name - mappingB.name; + } + exports.compareByOriginalPositions = compareByOriginalPositions; + + /** + * Comparator between two mappings with deflated source and name indices where + * the generated positions are compared. + * + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same generated line and column, but different + * source/name/original line and column the same. Useful when searching for a + * mapping with a stubbed out mapping. + */ + function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0 || onlyCompareGenerated) { + return cmp; + } + + cmp = mappingA.source - mappingB.source; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } + + return mappingA.name - mappingB.name; + } + exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; + + function strcmp(aStr1, aStr2) { + if (aStr1 === aStr2) { + return 0; + } + + if (aStr1 > aStr2) { + return 1; + } + + return -1; + } + + /** + * Comparator between two mappings with inflated source and name strings where + * the generated positions are compared. + */ + function compareByGeneratedPositionsInflated(mappingA, mappingB) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } + + cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } + + return strcmp(mappingA.name, mappingB.name); + } + exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; + + +/***/ }, +/* 5 */ +/***/ function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var util = __webpack_require__(4); + var has = Object.prototype.hasOwnProperty; + + /** + * A data structure which is a combination of an array and a set. Adding a new + * member is O(1), testing for membership is O(1), and finding the index of an + * element is O(1). Removing elements from the set is not supported. Only + * strings are supported for membership. + */ + function ArraySet() { + this._array = []; + this._set = Object.create(null); + } + + /** + * Static method for creating ArraySet instances from an existing array. + */ + ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) { + var set = new ArraySet(); + for (var i = 0, len = aArray.length; i < len; i++) { + set.add(aArray[i], aAllowDuplicates); + } + return set; + }; + + /** + * Return how many unique items are in this ArraySet. If duplicates have been + * added, than those do not count towards the size. + * + * @returns Number + */ + ArraySet.prototype.size = function ArraySet_size() { + return Object.getOwnPropertyNames(this._set).length; + }; + + /** + * Add the given string to this set. + * + * @param String aStr + */ + ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) { + var sStr = util.toSetString(aStr); + var isDuplicate = has.call(this._set, sStr); + var idx = this._array.length; + if (!isDuplicate || aAllowDuplicates) { + this._array.push(aStr); + } + if (!isDuplicate) { + this._set[sStr] = idx; + } + }; + + /** + * Is the given string a member of this set? + * + * @param String aStr + */ + ArraySet.prototype.has = function ArraySet_has(aStr) { + var sStr = util.toSetString(aStr); + return has.call(this._set, sStr); + }; + + /** + * What is the index of the given string in the array? + * + * @param String aStr + */ + ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) { + var sStr = util.toSetString(aStr); + if (has.call(this._set, sStr)) { + return this._set[sStr]; + } + throw new Error('"' + aStr + '" is not in the set.'); + }; + + /** + * What is the element at the given index? + * + * @param Number aIdx + */ + ArraySet.prototype.at = function ArraySet_at(aIdx) { + if (aIdx >= 0 && aIdx < this._array.length) { + return this._array[aIdx]; + } + throw new Error('No element indexed by ' + aIdx); + }; + + /** + * Returns the array representation of this set (which has the proper indices + * indicated by indexOf). Note that this is a copy of the internal array used + * for storing the members so that no one can mess with internal state. + */ + ArraySet.prototype.toArray = function ArraySet_toArray() { + return this._array.slice(); + }; + + exports.ArraySet = ArraySet; + + +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2014 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var util = __webpack_require__(4); + + /** + * Determine whether mappingB is after mappingA with respect to generated + * position. + */ + function generatedPositionAfter(mappingA, mappingB) { + // Optimized for most common case + var lineA = mappingA.generatedLine; + var lineB = mappingB.generatedLine; + var columnA = mappingA.generatedColumn; + var columnB = mappingB.generatedColumn; + return lineB > lineA || lineB == lineA && columnB >= columnA || + util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0; + } + + /** + * A data structure to provide a sorted view of accumulated mappings in a + * performance conscious manner. It trades a neglibable overhead in general + * case for a large speedup in case of mappings being added in order. + */ + function MappingList() { + this._array = []; + this._sorted = true; + // Serves as infimum + this._last = {generatedLine: -1, generatedColumn: 0}; + } + + /** + * Iterate through internal items. This method takes the same arguments that + * `Array.prototype.forEach` takes. + * + * NOTE: The order of the mappings is NOT guaranteed. + */ + MappingList.prototype.unsortedForEach = + function MappingList_forEach(aCallback, aThisArg) { + this._array.forEach(aCallback, aThisArg); + }; + + /** + * Add the given source mapping. + * + * @param Object aMapping + */ + MappingList.prototype.add = function MappingList_add(aMapping) { + if (generatedPositionAfter(this._last, aMapping)) { + this._last = aMapping; + this._array.push(aMapping); + } else { + this._sorted = false; + this._array.push(aMapping); + } + }; + + /** + * Returns the flat, sorted array of mappings. The mappings are sorted by + * generated position. + * + * WARNING: This method returns internal data without copying, for + * performance. The return value must NOT be mutated, and should be treated as + * an immutable borrow. If you want to take ownership, you must make your own + * copy. + */ + MappingList.prototype.toArray = function MappingList_toArray() { + if (!this._sorted) { + this._array.sort(util.compareByGeneratedPositionsInflated); + this._sorted = true; + } + return this._array; + }; + + exports.MappingList = MappingList; + + +/***/ }, +/* 7 */ +/***/ function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var util = __webpack_require__(4); + var binarySearch = __webpack_require__(8); + var ArraySet = __webpack_require__(5).ArraySet; + var base64VLQ = __webpack_require__(2); + var quickSort = __webpack_require__(9).quickSort; + + function SourceMapConsumer(aSourceMap) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); + } + + return sourceMap.sections != null + ? new IndexedSourceMapConsumer(sourceMap) + : new BasicSourceMapConsumer(sourceMap); + } + + SourceMapConsumer.fromSourceMap = function(aSourceMap) { + return BasicSourceMapConsumer.fromSourceMap(aSourceMap); + } + + /** + * The version of the source mapping spec that we are consuming. + */ + SourceMapConsumer.prototype._version = 3; + + // `__generatedMappings` and `__originalMappings` are arrays that hold the + // parsed mapping coordinates from the source map's "mappings" attribute. They + // are lazily instantiated, accessed via the `_generatedMappings` and + // `_originalMappings` getters respectively, and we only parse the mappings + // and create these arrays once queried for a source location. We jump through + // these hoops because there can be many thousands of mappings, and parsing + // them is expensive, so we only want to do it if we must. + // + // Each object in the arrays is of the form: + // + // { + // generatedLine: The line number in the generated code, + // generatedColumn: The column number in the generated code, + // source: The path to the original source file that generated this + // chunk of code, + // originalLine: The line number in the original source that + // corresponds to this chunk of generated code, + // originalColumn: The column number in the original source that + // corresponds to this chunk of generated code, + // name: The name of the original symbol which generated this chunk of + // code. + // } + // + // All properties except for `generatedLine` and `generatedColumn` can be + // `null`. + // + // `_generatedMappings` is ordered by the generated positions. + // + // `_originalMappings` is ordered by the original positions. + + SourceMapConsumer.prototype.__generatedMappings = null; + Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', { + get: function () { + if (!this.__generatedMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__generatedMappings; + } + }); + + SourceMapConsumer.prototype.__originalMappings = null; + Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { + get: function () { + if (!this.__originalMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__originalMappings; + } + }); + + SourceMapConsumer.prototype._charIsMappingSeparator = + function SourceMapConsumer_charIsMappingSeparator(aStr, index) { + var c = aStr.charAt(index); + return c === ";" || c === ","; + }; + + /** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ + SourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + throw new Error("Subclasses must implement _parseMappings"); + }; + + SourceMapConsumer.GENERATED_ORDER = 1; + SourceMapConsumer.ORIGINAL_ORDER = 2; + + SourceMapConsumer.GREATEST_LOWER_BOUND = 1; + SourceMapConsumer.LEAST_UPPER_BOUND = 2; + + /** + * Iterate over each mapping between an original source/line/column and a + * generated line/column in this source map. + * + * @param Function aCallback + * The function that is called with each mapping. + * @param Object aContext + * Optional. If specified, this object will be the value of `this` every + * time that `aCallback` is called. + * @param aOrder + * Either `SourceMapConsumer.GENERATED_ORDER` or + * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to + * iterate over the mappings sorted by the generated file's line/column + * order or the original's source/line/column order, respectively. Defaults to + * `SourceMapConsumer.GENERATED_ORDER`. + */ + SourceMapConsumer.prototype.eachMapping = + function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { + var context = aContext || null; + var order = aOrder || SourceMapConsumer.GENERATED_ORDER; + + var mappings; + switch (order) { + case SourceMapConsumer.GENERATED_ORDER: + mappings = this._generatedMappings; + break; + case SourceMapConsumer.ORIGINAL_ORDER: + mappings = this._originalMappings; + break; + default: + throw new Error("Unknown order of iteration."); + } + + var sourceRoot = this.sourceRoot; + mappings.map(function (mapping) { + var source = mapping.source === null ? null : this._sources.at(mapping.source); + if (source != null && sourceRoot != null) { + source = util.join(sourceRoot, source); + } + return { + source: source, + generatedLine: mapping.generatedLine, + generatedColumn: mapping.generatedColumn, + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: mapping.name === null ? null : this._names.at(mapping.name) + }; + }, this).forEach(aCallback, context); + }; + + /** + * Returns all generated line and column information for the original source, + * line, and column provided. If no column is provided, returns all mappings + * corresponding to a either the line we are searching for or the next + * closest line that has any mappings. Otherwise, returns all mappings + * corresponding to the given line and either the column we are searching for + * or the next closest column that has any offsets. + * + * The only argument is an object with the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. + * - column: Optional. the column number in the original source. + * + * and an array of objects is returned, each with the following properties: + * + * - line: The line number in the generated source, or null. + * - column: The column number in the generated source, or null. + */ + SourceMapConsumer.prototype.allGeneratedPositionsFor = + function SourceMapConsumer_allGeneratedPositionsFor(aArgs) { + var line = util.getArg(aArgs, 'line'); + + // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping + // returns the index of the closest mapping less than the needle. By + // setting needle.originalColumn to 0, we thus find the last mapping for + // the given line, provided such a mapping exists. + var needle = { + source: util.getArg(aArgs, 'source'), + originalLine: line, + originalColumn: util.getArg(aArgs, 'column', 0) + }; + + if (this.sourceRoot != null) { + needle.source = util.relative(this.sourceRoot, needle.source); + } + if (!this._sources.has(needle.source)) { + return []; + } + needle.source = this._sources.indexOf(needle.source); + + var mappings = []; + + var index = this._findMapping(needle, + this._originalMappings, + "originalLine", + "originalColumn", + util.compareByOriginalPositions, + binarySearch.LEAST_UPPER_BOUND); + if (index >= 0) { + var mapping = this._originalMappings[index]; + + if (aArgs.column === undefined) { + var originalLine = mapping.originalLine; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we found. Since + // mappings are sorted, this is guaranteed to find all mappings for + // the line we found. + while (mapping && mapping.originalLine === originalLine) { + mappings.push({ + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } + } else { + var originalColumn = mapping.originalColumn; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we were searching for. + // Since mappings are sorted, this is guaranteed to find all mappings for + // the line we are searching for. + while (mapping && + mapping.originalLine === line && + mapping.originalColumn == originalColumn) { + mappings.push({ + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } + } + } + + return mappings; + }; + + exports.SourceMapConsumer = SourceMapConsumer; + + /** + * A BasicSourceMapConsumer instance represents a parsed source map which we can + * query for information about the original file positions by giving it a file + * position in the generated source. + * + * The only parameter is the raw source map (either as a JSON string, or + * already parsed to an object). According to the spec, source maps have the + * following attributes: + * + * - version: Which version of the source map spec this map is following. + * - sources: An array of URLs to the original source files. + * - names: An array of identifiers which can be referrenced by individual mappings. + * - sourceRoot: Optional. The URL root from which all sources are relative. + * - sourcesContent: Optional. An array of contents of the original source files. + * - mappings: A string of base64 VLQs which contain the actual mappings. + * - file: Optional. The generated file this source map is associated with. + * + * Here is an example source map, taken from the source map spec[0]: + * + * { + * version : 3, + * file: "out.js", + * sourceRoot : "", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AA,AB;;ABCDE;" + * } + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# + */ + function BasicSourceMapConsumer(aSourceMap) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); + } + + var version = util.getArg(sourceMap, 'version'); + var sources = util.getArg(sourceMap, 'sources'); + // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which + // requires the array) to play nice here. + var names = util.getArg(sourceMap, 'names', []); + var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null); + var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null); + var mappings = util.getArg(sourceMap, 'mappings'); + var file = util.getArg(sourceMap, 'file', null); + + // Once again, Sass deviates from the spec and supplies the version as a + // string rather than a number, so we use loose equality checking here. + if (version != this._version) { + throw new Error('Unsupported version: ' + version); + } + + sources = sources + .map(String) + // Some source maps produce relative source paths like "./foo.js" instead of + // "foo.js". Normalize these first so that future comparisons will succeed. + // See bugzil.la/1090768. + .map(util.normalize) + // Always ensure that absolute sources are internally stored relative to + // the source root, if the source root is absolute. Not doing this would + // be particularly problematic when the source root is a prefix of the + // source (valid, but why??). See github issue #199 and bugzil.la/1188982. + .map(function (source) { + return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source) + ? util.relative(sourceRoot, source) + : source; + }); + + // Pass `true` below to allow duplicate names and sources. While source maps + // are intended to be compressed and deduplicated, the TypeScript compiler + // sometimes generates source maps with duplicates in them. See Github issue + // #72 and bugzil.la/889492. + this._names = ArraySet.fromArray(names.map(String), true); + this._sources = ArraySet.fromArray(sources, true); + + this.sourceRoot = sourceRoot; + this.sourcesContent = sourcesContent; + this._mappings = mappings; + this.file = file; + } + + BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); + BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer; + + /** + * Create a BasicSourceMapConsumer from a SourceMapGenerator. + * + * @param SourceMapGenerator aSourceMap + * The source map that will be consumed. + * @returns BasicSourceMapConsumer + */ + BasicSourceMapConsumer.fromSourceMap = + function SourceMapConsumer_fromSourceMap(aSourceMap) { + var smc = Object.create(BasicSourceMapConsumer.prototype); + + var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true); + var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true); + smc.sourceRoot = aSourceMap._sourceRoot; + smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), + smc.sourceRoot); + smc.file = aSourceMap._file; + + // Because we are modifying the entries (by converting string sources and + // names to indices into the sources and names ArraySets), we have to make + // a copy of the entry or else bad things happen. Shared mutable state + // strikes again! See github issue #191. + + var generatedMappings = aSourceMap._mappings.toArray().slice(); + var destGeneratedMappings = smc.__generatedMappings = []; + var destOriginalMappings = smc.__originalMappings = []; + + for (var i = 0, length = generatedMappings.length; i < length; i++) { + var srcMapping = generatedMappings[i]; + var destMapping = new Mapping; + destMapping.generatedLine = srcMapping.generatedLine; + destMapping.generatedColumn = srcMapping.generatedColumn; + + if (srcMapping.source) { + destMapping.source = sources.indexOf(srcMapping.source); + destMapping.originalLine = srcMapping.originalLine; + destMapping.originalColumn = srcMapping.originalColumn; + + if (srcMapping.name) { + destMapping.name = names.indexOf(srcMapping.name); + } + + destOriginalMappings.push(destMapping); + } + + destGeneratedMappings.push(destMapping); + } + + quickSort(smc.__originalMappings, util.compareByOriginalPositions); + + return smc; + }; + + /** + * The version of the source mapping spec that we are consuming. + */ + BasicSourceMapConsumer.prototype._version = 3; + + /** + * The list of original sources. + */ + Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', { + get: function () { + return this._sources.toArray().map(function (s) { + return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s; + }, this); + } + }); + + /** + * Provide the JIT with a nice shape / hidden class. + */ + function Mapping() { + this.generatedLine = 0; + this.generatedColumn = 0; + this.source = null; + this.originalLine = null; + this.originalColumn = null; + this.name = null; + } + + /** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ + BasicSourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + var generatedLine = 1; + var previousGeneratedColumn = 0; + var previousOriginalLine = 0; + var previousOriginalColumn = 0; + var previousSource = 0; + var previousName = 0; + var length = aStr.length; + var index = 0; + var cachedSegments = {}; + var temp = {}; + var originalMappings = []; + var generatedMappings = []; + var mapping, str, segment, end, value; + + while (index < length) { + if (aStr.charAt(index) === ';') { + generatedLine++; + index++; + previousGeneratedColumn = 0; + } + else if (aStr.charAt(index) === ',') { + index++; + } + else { + mapping = new Mapping(); + mapping.generatedLine = generatedLine; + + // Because each offset is encoded relative to the previous one, + // many segments often have the same encoding. We can exploit this + // fact by caching the parsed variable length fields of each segment, + // allowing us to avoid a second parse if we encounter the same + // segment again. + for (end = index; end < length; end++) { + if (this._charIsMappingSeparator(aStr, end)) { + break; + } + } + str = aStr.slice(index, end); + + segment = cachedSegments[str]; + if (segment) { + index += str.length; + } else { + segment = []; + while (index < end) { + base64VLQ.decode(aStr, index, temp); + value = temp.value; + index = temp.rest; + segment.push(value); + } + + if (segment.length === 2) { + throw new Error('Found a source, but no line and column'); + } + + if (segment.length === 3) { + throw new Error('Found a source and line, but no column'); + } + + cachedSegments[str] = segment; + } + + // Generated column. + mapping.generatedColumn = previousGeneratedColumn + segment[0]; + previousGeneratedColumn = mapping.generatedColumn; + + if (segment.length > 1) { + // Original source. + mapping.source = previousSource + segment[1]; + previousSource += segment[1]; + + // Original line. + mapping.originalLine = previousOriginalLine + segment[2]; + previousOriginalLine = mapping.originalLine; + // Lines are stored 0-based + mapping.originalLine += 1; + + // Original column. + mapping.originalColumn = previousOriginalColumn + segment[3]; + previousOriginalColumn = mapping.originalColumn; + + if (segment.length > 4) { + // Original name. + mapping.name = previousName + segment[4]; + previousName += segment[4]; + } + } + + generatedMappings.push(mapping); + if (typeof mapping.originalLine === 'number') { + originalMappings.push(mapping); + } + } + } + + quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated); + this.__generatedMappings = generatedMappings; + + quickSort(originalMappings, util.compareByOriginalPositions); + this.__originalMappings = originalMappings; + }; + + /** + * Find the mapping that best matches the hypothetical "needle" mapping that + * we are searching for in the given "haystack" of mappings. + */ + BasicSourceMapConsumer.prototype._findMapping = + function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, + aColumnName, aComparator, aBias) { + // To return the position we are searching for, we must first find the + // mapping for the given position and then return the opposite position it + // points to. Because the mappings are sorted, we can use binary search to + // find the best mapping. + + if (aNeedle[aLineName] <= 0) { + throw new TypeError('Line must be greater than or equal to 1, got ' + + aNeedle[aLineName]); + } + if (aNeedle[aColumnName] < 0) { + throw new TypeError('Column must be greater than or equal to 0, got ' + + aNeedle[aColumnName]); + } + + return binarySearch.search(aNeedle, aMappings, aComparator, aBias); + }; + + /** + * Compute the last column for each generated mapping. The last column is + * inclusive. + */ + BasicSourceMapConsumer.prototype.computeColumnSpans = + function SourceMapConsumer_computeColumnSpans() { + for (var index = 0; index < this._generatedMappings.length; ++index) { + var mapping = this._generatedMappings[index]; + + // Mappings do not contain a field for the last generated columnt. We + // can come up with an optimistic estimate, however, by assuming that + // mappings are contiguous (i.e. given two consecutive mappings, the + // first mapping ends where the second one starts). + if (index + 1 < this._generatedMappings.length) { + var nextMapping = this._generatedMappings[index + 1]; + + if (mapping.generatedLine === nextMapping.generatedLine) { + mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1; + continue; + } + } + + // The last mapping for each line spans the entire line. + mapping.lastGeneratedColumn = Infinity; + } + }; + + /** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. + * - column: The column number in the generated source. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. + * - column: The column number in the original source, or null. + * - name: The original identifier, or null. + */ + BasicSourceMapConsumer.prototype.originalPositionFor = + function SourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util.getArg(aArgs, 'line'), + generatedColumn: util.getArg(aArgs, 'column') + }; + + var index = this._findMapping( + needle, + this._generatedMappings, + "generatedLine", + "generatedColumn", + util.compareByGeneratedPositionsDeflated, + util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); + + if (index >= 0) { + var mapping = this._generatedMappings[index]; + + if (mapping.generatedLine === needle.generatedLine) { + var source = util.getArg(mapping, 'source', null); + if (source !== null) { + source = this._sources.at(source); + if (this.sourceRoot != null) { + source = util.join(this.sourceRoot, source); + } + } + var name = util.getArg(mapping, 'name', null); + if (name !== null) { + name = this._names.at(name); + } + return { + source: source, + line: util.getArg(mapping, 'originalLine', null), + column: util.getArg(mapping, 'originalColumn', null), + name: name + }; + } + } + + return { + source: null, + line: null, + column: null, + name: null + }; + }; + + /** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ + BasicSourceMapConsumer.prototype.hasContentsOfAllSources = + function BasicSourceMapConsumer_hasContentsOfAllSources() { + if (!this.sourcesContent) { + return false; + } + return this.sourcesContent.length >= this._sources.size() && + !this.sourcesContent.some(function (sc) { return sc == null; }); + }; + + /** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ + BasicSourceMapConsumer.prototype.sourceContentFor = + function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + if (!this.sourcesContent) { + return null; + } + + if (this.sourceRoot != null) { + aSource = util.relative(this.sourceRoot, aSource); + } + + if (this._sources.has(aSource)) { + return this.sourcesContent[this._sources.indexOf(aSource)]; + } + + var url; + if (this.sourceRoot != null + && (url = util.urlParse(this.sourceRoot))) { + // XXX: file:// URIs and absolute paths lead to unexpected behavior for + // many users. We can help them out when they expect file:// URIs to + // behave like it would if they were running a local HTTP server. See + // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. + var fileUriAbsPath = aSource.replace(/^file:\/\//, ""); + if (url.scheme == "file" + && this._sources.has(fileUriAbsPath)) { + return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] + } + + if ((!url.path || url.path == "/") + && this._sources.has("/" + aSource)) { + return this.sourcesContent[this._sources.indexOf("/" + aSource)]; + } + } + + // This function is used recursively from + // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we + // don't want to throw if we can't find the source - we just want to + // return null, so we provide a flag to exit gracefully. + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + aSource + '" is not in the SourceMap.'); + } + }; + + /** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. + * - column: The column number in the original source. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. + * - column: The column number in the generated source, or null. + */ + BasicSourceMapConsumer.prototype.generatedPositionFor = + function SourceMapConsumer_generatedPositionFor(aArgs) { + var source = util.getArg(aArgs, 'source'); + if (this.sourceRoot != null) { + source = util.relative(this.sourceRoot, source); + } + if (!this._sources.has(source)) { + return { + line: null, + column: null, + lastColumn: null + }; + } + source = this._sources.indexOf(source); + + var needle = { + source: source, + originalLine: util.getArg(aArgs, 'line'), + originalColumn: util.getArg(aArgs, 'column') + }; + + var index = this._findMapping( + needle, + this._originalMappings, + "originalLine", + "originalColumn", + util.compareByOriginalPositions, + util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); + + if (index >= 0) { + var mapping = this._originalMappings[index]; + + if (mapping.source === needle.source) { + return { + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }; + } + } + + return { + line: null, + column: null, + lastColumn: null + }; + }; + + exports.BasicSourceMapConsumer = BasicSourceMapConsumer; + + /** + * An IndexedSourceMapConsumer instance represents a parsed source map which + * we can query for information. It differs from BasicSourceMapConsumer in + * that it takes "indexed" source maps (i.e. ones with a "sections" field) as + * input. + * + * The only parameter is a raw source map (either as a JSON string, or already + * parsed to an object). According to the spec for indexed source maps, they + * have the following attributes: + * + * - version: Which version of the source map spec this map is following. + * - file: Optional. The generated file this source map is associated with. + * - sections: A list of section definitions. + * + * Each value under the "sections" field has two fields: + * - offset: The offset into the original specified at which this section + * begins to apply, defined as an object with a "line" and "column" + * field. + * - map: A source map definition. This source map could also be indexed, + * but doesn't have to be. + * + * Instead of the "map" field, it's also possible to have a "url" field + * specifying a URL to retrieve a source map from, but that's currently + * unsupported. + * + * Here's an example source map, taken from the source map spec[0], but + * modified to omit a section which uses the "url" field. + * + * { + * version : 3, + * file: "app.js", + * sections: [{ + * offset: {line:100, column:10}, + * map: { + * version : 3, + * file: "section.js", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AAAA,E;;ABCDE;" + * } + * }], + * } + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt + */ + function IndexedSourceMapConsumer(aSourceMap) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); + } + + var version = util.getArg(sourceMap, 'version'); + var sections = util.getArg(sourceMap, 'sections'); + + if (version != this._version) { + throw new Error('Unsupported version: ' + version); + } + + this._sources = new ArraySet(); + this._names = new ArraySet(); + + var lastOffset = { + line: -1, + column: 0 + }; + this._sections = sections.map(function (s) { + if (s.url) { + // The url field will require support for asynchronicity. + // See https://github.com/mozilla/source-map/issues/16 + throw new Error('Support for url field in sections not implemented.'); + } + var offset = util.getArg(s, 'offset'); + var offsetLine = util.getArg(offset, 'line'); + var offsetColumn = util.getArg(offset, 'column'); + + if (offsetLine < lastOffset.line || + (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) { + throw new Error('Section offsets must be ordered and non-overlapping.'); + } + lastOffset = offset; + + return { + generatedOffset: { + // The offset fields are 0-based, but we use 1-based indices when + // encoding/decoding from VLQ. + generatedLine: offsetLine + 1, + generatedColumn: offsetColumn + 1 + }, + consumer: new SourceMapConsumer(util.getArg(s, 'map')) + } + }); + } + + IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); + IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer; + + /** + * The version of the source mapping spec that we are consuming. + */ + IndexedSourceMapConsumer.prototype._version = 3; + + /** + * The list of original sources. + */ + Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', { + get: function () { + var sources = []; + for (var i = 0; i < this._sections.length; i++) { + for (var j = 0; j < this._sections[i].consumer.sources.length; j++) { + sources.push(this._sections[i].consumer.sources[j]); + } + } + return sources; + } + }); + + /** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. + * - column: The column number in the generated source. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. + * - column: The column number in the original source, or null. + * - name: The original identifier, or null. + */ + IndexedSourceMapConsumer.prototype.originalPositionFor = + function IndexedSourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util.getArg(aArgs, 'line'), + generatedColumn: util.getArg(aArgs, 'column') + }; + + // Find the section containing the generated position we're trying to map + // to an original position. + var sectionIndex = binarySearch.search(needle, this._sections, + function(needle, section) { + var cmp = needle.generatedLine - section.generatedOffset.generatedLine; + if (cmp) { + return cmp; + } + + return (needle.generatedColumn - + section.generatedOffset.generatedColumn); + }); + var section = this._sections[sectionIndex]; + + if (!section) { + return { + source: null, + line: null, + column: null, + name: null + }; + } + + return section.consumer.originalPositionFor({ + line: needle.generatedLine - + (section.generatedOffset.generatedLine - 1), + column: needle.generatedColumn - + (section.generatedOffset.generatedLine === needle.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + bias: aArgs.bias + }); + }; + + /** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ + IndexedSourceMapConsumer.prototype.hasContentsOfAllSources = + function IndexedSourceMapConsumer_hasContentsOfAllSources() { + return this._sections.every(function (s) { + return s.consumer.hasContentsOfAllSources(); + }); + }; + + /** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ + IndexedSourceMapConsumer.prototype.sourceContentFor = + function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + + var content = section.consumer.sourceContentFor(aSource, true); + if (content) { + return content; + } + } + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + aSource + '" is not in the SourceMap.'); + } + }; + + /** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. + * - column: The column number in the original source. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. + * - column: The column number in the generated source, or null. + */ + IndexedSourceMapConsumer.prototype.generatedPositionFor = + function IndexedSourceMapConsumer_generatedPositionFor(aArgs) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + + // Only consider this section if the requested source is in the list of + // sources of the consumer. + if (section.consumer.sources.indexOf(util.getArg(aArgs, 'source')) === -1) { + continue; + } + var generatedPosition = section.consumer.generatedPositionFor(aArgs); + if (generatedPosition) { + var ret = { + line: generatedPosition.line + + (section.generatedOffset.generatedLine - 1), + column: generatedPosition.column + + (section.generatedOffset.generatedLine === generatedPosition.line + ? section.generatedOffset.generatedColumn - 1 + : 0) + }; + return ret; + } + } + + return { + line: null, + column: null + }; + }; + + /** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ + IndexedSourceMapConsumer.prototype._parseMappings = + function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) { + this.__generatedMappings = []; + this.__originalMappings = []; + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + var sectionMappings = section.consumer._generatedMappings; + for (var j = 0; j < sectionMappings.length; j++) { + var mapping = sectionMappings[j]; + + var source = section.consumer._sources.at(mapping.source); + if (section.consumer.sourceRoot !== null) { + source = util.join(section.consumer.sourceRoot, source); + } + this._sources.add(source); + source = this._sources.indexOf(source); + + var name = section.consumer._names.at(mapping.name); + this._names.add(name); + name = this._names.indexOf(name); + + // The mappings coming from the consumer for the section have + // generated positions relative to the start of the section, so we + // need to offset them to be relative to the start of the concatenated + // generated file. + var adjustedMapping = { + source: source, + generatedLine: mapping.generatedLine + + (section.generatedOffset.generatedLine - 1), + generatedColumn: mapping.generatedColumn + + (section.generatedOffset.generatedLine === mapping.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: name + }; + + this.__generatedMappings.push(adjustedMapping); + if (typeof adjustedMapping.originalLine === 'number') { + this.__originalMappings.push(adjustedMapping); + } + } + } + + quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated); + quickSort(this.__originalMappings, util.compareByOriginalPositions); + }; + + exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; + + +/***/ }, +/* 8 */ +/***/ function(module, exports) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + exports.GREATEST_LOWER_BOUND = 1; + exports.LEAST_UPPER_BOUND = 2; + + /** + * Recursive implementation of binary search. + * + * @param aLow Indices here and lower do not contain the needle. + * @param aHigh Indices here and higher do not contain the needle. + * @param aNeedle The element being searched for. + * @param aHaystack The non-empty array being searched. + * @param aCompare Function which takes two elements and returns -1, 0, or 1. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + */ + function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { + // This function terminates when one of the following is true: + // + // 1. We find the exact element we are looking for. + // + // 2. We did not find the exact element, but we can return the index of + // the next-closest element. + // + // 3. We did not find the exact element, and there is no next-closest + // element than the one we are searching for, so we return -1. + var mid = Math.floor((aHigh - aLow) / 2) + aLow; + var cmp = aCompare(aNeedle, aHaystack[mid], true); + if (cmp === 0) { + // Found the element we are looking for. + return mid; + } + else if (cmp > 0) { + // Our needle is greater than aHaystack[mid]. + if (aHigh - mid > 1) { + // The element is in the upper half. + return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias); + } + + // The exact needle element was not found in this haystack. Determine if + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return aHigh < aHaystack.length ? aHigh : -1; + } else { + return mid; + } + } + else { + // Our needle is less than aHaystack[mid]. + if (mid - aLow > 1) { + // The element is in the lower half. + return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias); + } + + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return mid; + } else { + return aLow < 0 ? -1 : aLow; + } + } + } + + /** + * This is an implementation of binary search which will always try and return + * the index of the closest element if there is no exact hit. This is because + * mappings between original and generated line/col pairs are single points, + * and there is an implicit region between each of them, so a miss just means + * that you aren't on the very start of a region. + * + * @param aNeedle The element you are looking for. + * @param aHaystack The array that is being searched. + * @param aCompare A function which takes the needle and an element in the + * array and returns -1, 0, or 1 depending on whether the needle is less + * than, equal to, or greater than the element, respectively. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'. + */ + exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { + if (aHaystack.length === 0) { + return -1; + } + + var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, + aCompare, aBias || exports.GREATEST_LOWER_BOUND); + if (index < 0) { + return -1; + } + + // We have found either the exact element, or the next-closest element than + // the one we are searching for. However, there may be more than one such + // element. Make sure we always return the smallest of these. + while (index - 1 >= 0) { + if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) { + break; + } + --index; + } + + return index; + }; + + +/***/ }, +/* 9 */ +/***/ function(module, exports) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + // It turns out that some (most?) JavaScript engines don't self-host + // `Array.prototype.sort`. This makes sense because C++ will likely remain + // faster than JS when doing raw CPU-intensive sorting. However, when using a + // custom comparator function, calling back and forth between the VM's C++ and + // JIT'd JS is rather slow *and* loses JIT type information, resulting in + // worse generated code for the comparator function than would be optimal. In + // fact, when sorting with a comparator, these costs outweigh the benefits of + // sorting in C++. By using our own JS-implemented Quick Sort (below), we get + // a ~3500ms mean speed-up in `bench/bench.html`. + + /** + * Swap the elements indexed by `x` and `y` in the array `ary`. + * + * @param {Array} ary + * The array. + * @param {Number} x + * The index of the first item. + * @param {Number} y + * The index of the second item. + */ + function swap(ary, x, y) { + var temp = ary[x]; + ary[x] = ary[y]; + ary[y] = temp; + } + + /** + * Returns a random integer within the range `low .. high` inclusive. + * + * @param {Number} low + * The lower bound on the range. + * @param {Number} high + * The upper bound on the range. + */ + function randomIntInRange(low, high) { + return Math.round(low + (Math.random() * (high - low))); + } + + /** + * The Quick Sort algorithm. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + * @param {Number} p + * Start index of the array + * @param {Number} r + * End index of the array + */ + function doQuickSort(ary, comparator, p, r) { + // If our lower bound is less than our upper bound, we (1) partition the + // array into two pieces and (2) recurse on each half. If it is not, this is + // the empty array and our base case. + + if (p < r) { + // (1) Partitioning. + // + // The partitioning chooses a pivot between `p` and `r` and moves all + // elements that are less than or equal to the pivot to the before it, and + // all the elements that are greater than it after it. The effect is that + // once partition is done, the pivot is in the exact place it will be when + // the array is put in sorted order, and it will not need to be moved + // again. This runs in O(n) time. + + // Always choose a random pivot so that an input array which is reverse + // sorted does not cause O(n^2) running time. + var pivotIndex = randomIntInRange(p, r); + var i = p - 1; + + swap(ary, pivotIndex, r); + var pivot = ary[r]; + + // Immediately after `j` is incremented in this loop, the following hold + // true: + // + // * Every element in `ary[p .. i]` is less than or equal to the pivot. + // + // * Every element in `ary[i+1 .. j-1]` is greater than the pivot. + for (var j = p; j < r; j++) { + if (comparator(ary[j], pivot) <= 0) { + i += 1; + swap(ary, i, j); + } + } + + swap(ary, i + 1, j); + var q = i + 1; + + // (2) Recurse on each half. + + doQuickSort(ary, comparator, p, q - 1); + doQuickSort(ary, comparator, q + 1, r); + } + } + + /** + * Sort the given array in-place with the given comparator function. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + */ + exports.quickSort = function (ary, comparator) { + doQuickSort(ary, comparator, 0, ary.length - 1); + }; + + +/***/ }, +/* 10 */ +/***/ function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var SourceMapGenerator = __webpack_require__(1).SourceMapGenerator; + var util = __webpack_require__(4); + + // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other + // operating systems these days (capturing the result). + var REGEX_NEWLINE = /(\r?\n)/; + + // Newline character code for charCodeAt() comparisons + var NEWLINE_CODE = 10; + + // Private symbol for identifying `SourceNode`s when multiple versions of + // the source-map library are loaded. This MUST NOT CHANGE across + // versions! + var isSourceNode = "$$$isSourceNode$$$"; + + /** + * SourceNodes provide a way to abstract over interpolating/concatenating + * snippets of generated JavaScript source code while maintaining the line and + * column information associated with the original source code. + * + * @param aLine The original line number. + * @param aColumn The original column number. + * @param aSource The original source's filename. + * @param aChunks Optional. An array of strings which are snippets of + * generated JS, or other SourceNodes. + * @param aName The original identifier. + */ + function SourceNode(aLine, aColumn, aSource, aChunks, aName) { + this.children = []; + this.sourceContents = {}; + this.line = aLine == null ? null : aLine; + this.column = aColumn == null ? null : aColumn; + this.source = aSource == null ? null : aSource; + this.name = aName == null ? null : aName; + this[isSourceNode] = true; + if (aChunks != null) this.add(aChunks); + } + + /** + * Creates a SourceNode from generated code and a SourceMapConsumer. + * + * @param aGeneratedCode The generated code + * @param aSourceMapConsumer The SourceMap for the generated code + * @param aRelativePath Optional. The path that relative sources in the + * SourceMapConsumer should be relative to. + */ + SourceNode.fromStringWithSourceMap = + function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) { + // The SourceNode we want to fill with the generated code + // and the SourceMap + var node = new SourceNode(); + + // All even indices of this array are one line of the generated code, + // while all odd indices are the newlines between two adjacent lines + // (since `REGEX_NEWLINE` captures its match). + // Processed fragments are removed from this array, by calling `shiftNextLine`. + var remainingLines = aGeneratedCode.split(REGEX_NEWLINE); + var shiftNextLine = function() { + var lineContents = remainingLines.shift(); + // The last line of a file might not have a newline. + var newLine = remainingLines.shift() || ""; + return lineContents + newLine; + }; + + // We need to remember the position of "remainingLines" + var lastGeneratedLine = 1, lastGeneratedColumn = 0; + + // The generate SourceNodes we need a code range. + // To extract it current and last mapping is used. + // Here we store the last mapping. + var lastMapping = null; + + aSourceMapConsumer.eachMapping(function (mapping) { + if (lastMapping !== null) { + // We add the code from "lastMapping" to "mapping": + // First check if there is a new line in between. + if (lastGeneratedLine < mapping.generatedLine) { + // Associate first line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + lastGeneratedLine++; + lastGeneratedColumn = 0; + // The remaining code is added without mapping + } else { + // There is no new line in between. + // Associate the code between "lastGeneratedColumn" and + // "mapping.generatedColumn" with "lastMapping" + var nextLine = remainingLines[0]; + var code = nextLine.substr(0, mapping.generatedColumn - + lastGeneratedColumn); + remainingLines[0] = nextLine.substr(mapping.generatedColumn - + lastGeneratedColumn); + lastGeneratedColumn = mapping.generatedColumn; + addMappingWithCode(lastMapping, code); + // No more remaining code, continue + lastMapping = mapping; + return; + } + } + // We add the generated code until the first mapping + // to the SourceNode without any mapping. + // Each line is added as separate string. + while (lastGeneratedLine < mapping.generatedLine) { + node.add(shiftNextLine()); + lastGeneratedLine++; + } + if (lastGeneratedColumn < mapping.generatedColumn) { + var nextLine = remainingLines[0]; + node.add(nextLine.substr(0, mapping.generatedColumn)); + remainingLines[0] = nextLine.substr(mapping.generatedColumn); + lastGeneratedColumn = mapping.generatedColumn; + } + lastMapping = mapping; + }, this); + // We have processed all mappings. + if (remainingLines.length > 0) { + if (lastMapping) { + // Associate the remaining code in the current line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + } + // and add the remaining lines without any mapping + node.add(remainingLines.join("")); + } + + // Copy sourcesContent into SourceNode + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aRelativePath != null) { + sourceFile = util.join(aRelativePath, sourceFile); + } + node.setSourceContent(sourceFile, content); + } + }); + + return node; + + function addMappingWithCode(mapping, code) { + if (mapping === null || mapping.source === undefined) { + node.add(code); + } else { + var source = aRelativePath + ? util.join(aRelativePath, mapping.source) + : mapping.source; + node.add(new SourceNode(mapping.originalLine, + mapping.originalColumn, + source, + code, + mapping.name)); + } + } + }; + + /** + * Add a chunk of generated JS to this source node. + * + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. + */ + SourceNode.prototype.add = function SourceNode_add(aChunk) { + if (Array.isArray(aChunk)) { + aChunk.forEach(function (chunk) { + this.add(chunk); + }, this); + } + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + if (aChunk) { + this.children.push(aChunk); + } + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; + }; + + /** + * Add a chunk of generated JS to the beginning of this source node. + * + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. + */ + SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) { + if (Array.isArray(aChunk)) { + for (var i = aChunk.length-1; i >= 0; i--) { + this.prepend(aChunk[i]); + } + } + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + this.children.unshift(aChunk); + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; + }; + + /** + * Walk over the tree of JS snippets in this node and its children. The + * walking function is called once for each snippet of JS and is passed that + * snippet and the its original associated source's line/column location. + * + * @param aFn The traversal function. + */ + SourceNode.prototype.walk = function SourceNode_walk(aFn) { + var chunk; + for (var i = 0, len = this.children.length; i < len; i++) { + chunk = this.children[i]; + if (chunk[isSourceNode]) { + chunk.walk(aFn); + } + else { + if (chunk !== '') { + aFn(chunk, { source: this.source, + line: this.line, + column: this.column, + name: this.name }); + } + } + } + }; + + /** + * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between + * each of `this.children`. + * + * @param aSep The separator. + */ + SourceNode.prototype.join = function SourceNode_join(aSep) { + var newChildren; + var i; + var len = this.children.length; + if (len > 0) { + newChildren = []; + for (i = 0; i < len-1; i++) { + newChildren.push(this.children[i]); + newChildren.push(aSep); + } + newChildren.push(this.children[i]); + this.children = newChildren; + } + return this; + }; + + /** + * Call String.prototype.replace on the very right-most source snippet. Useful + * for trimming whitespace from the end of a source node, etc. + * + * @param aPattern The pattern to replace. + * @param aReplacement The thing to replace the pattern with. + */ + SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) { + var lastChild = this.children[this.children.length - 1]; + if (lastChild[isSourceNode]) { + lastChild.replaceRight(aPattern, aReplacement); + } + else if (typeof lastChild === 'string') { + this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); + } + else { + this.children.push(''.replace(aPattern, aReplacement)); + } + return this; + }; + + /** + * Set the source content for a source file. This will be added to the SourceMapGenerator + * in the sourcesContent field. + * + * @param aSourceFile The filename of the source file + * @param aSourceContent The content of the source file + */ + SourceNode.prototype.setSourceContent = + function SourceNode_setSourceContent(aSourceFile, aSourceContent) { + this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; + }; + + /** + * Walk over the tree of SourceNodes. The walking function is called for each + * source file content and is passed the filename and source content. + * + * @param aFn The traversal function. + */ + SourceNode.prototype.walkSourceContents = + function SourceNode_walkSourceContents(aFn) { + for (var i = 0, len = this.children.length; i < len; i++) { + if (this.children[i][isSourceNode]) { + this.children[i].walkSourceContents(aFn); + } + } + + var sources = Object.keys(this.sourceContents); + for (var i = 0, len = sources.length; i < len; i++) { + aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); + } + }; + + /** + * Return the string representation of this source node. Walks over the tree + * and concatenates all the various snippets together to one string. + */ + SourceNode.prototype.toString = function SourceNode_toString() { + var str = ""; + this.walk(function (chunk) { + str += chunk; + }); + return str; + }; + + /** + * Returns the string representation of this source node along with a source + * map. + */ + SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) { + var generated = { + code: "", + line: 1, + column: 0 + }; + var map = new SourceMapGenerator(aArgs); + var sourceMappingActive = false; + var lastOriginalSource = null; + var lastOriginalLine = null; + var lastOriginalColumn = null; + var lastOriginalName = null; + this.walk(function (chunk, original) { + generated.code += chunk; + if (original.source !== null + && original.line !== null + && original.column !== null) { + if(lastOriginalSource !== original.source + || lastOriginalLine !== original.line + || lastOriginalColumn !== original.column + || lastOriginalName !== original.name) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + lastOriginalSource = original.source; + lastOriginalLine = original.line; + lastOriginalColumn = original.column; + lastOriginalName = original.name; + sourceMappingActive = true; + } else if (sourceMappingActive) { + map.addMapping({ + generated: { + line: generated.line, + column: generated.column + } + }); + lastOriginalSource = null; + sourceMappingActive = false; + } + for (var idx = 0, length = chunk.length; idx < length; idx++) { + if (chunk.charCodeAt(idx) === NEWLINE_CODE) { + generated.line++; + generated.column = 0; + // Mappings end at eol + if (idx + 1 === length) { + lastOriginalSource = null; + sourceMappingActive = false; + } else if (sourceMappingActive) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + } else { + generated.column++; + } + } + }); + this.walkSourceContents(function (sourceFile, sourceContent) { + map.setSourceContent(sourceFile, sourceContent); + }); + + return { code: generated.code, map: map }; + }; + + exports.SourceNode = SourceNode; + + +/***/ } +/******/ ]) +}); +; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovLy93ZWJwYWNrL2Jvb3RzdHJhcCBlMTM0NGZmMjJhYzA2Zjk0NWVlNCIsIndlYnBhY2s6Ly8vLi9zb3VyY2UtbWFwLmpzIiwid2VicGFjazovLy8uL2xpYi9zb3VyY2UtbWFwLWdlbmVyYXRvci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LXZscS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsLmpzIiwid2VicGFjazovLy8uL2xpYi9hcnJheS1zZXQuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21hcHBpbmctbGlzdC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvc291cmNlLW1hcC1jb25zdW1lci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmluYXJ5LXNlYXJjaC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvcXVpY2stc29ydC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvc291cmNlLW5vZGUuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNELE87QUNWQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1QkFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNQQSxpQkFBZ0Isb0JBQW9CO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsTUFBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJDQUEwQyxTQUFTO0FBQ25EO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EscUJBQW9CO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7OztBQ25aQSxpQkFBZ0Isb0JBQW9CO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0REFBMkQ7QUFDM0QscUJBQW9CO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBOzs7Ozs7O0FDM0lBLGlCQUFnQixvQkFBb0I7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFnQjtBQUNoQixpQkFBZ0I7O0FBRWhCLG9CQUFtQjtBQUNuQixxQkFBb0I7O0FBRXBCLGlCQUFnQjtBQUNoQixpQkFBZ0I7O0FBRWhCLGlCQUFnQjtBQUNoQixrQkFBaUI7O0FBRWpCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7Ozs7O0FDbEVBLGlCQUFnQixvQkFBb0I7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLCtDQUE4QyxRQUFRO0FBQ3REO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw0QkFBMkIsUUFBUTtBQUNuQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7Ozs7O0FDaGFBLGlCQUFnQixvQkFBb0I7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBc0MsU0FBUztBQUMvQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7Ozs7QUN2R0EsaUJBQWdCLG9CQUFvQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFnQjtBQUNoQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7Ozs7QUM5RUEsaUJBQWdCLG9CQUFvQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsdURBQXNEO0FBQ3REOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0Esb0JBQW1CO0FBQ25COztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFXOztBQUVYO0FBQ0E7QUFDQSxRQUFPO0FBQ1A7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVc7O0FBRVg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUEyQixNQUFNO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdURBQXNEO0FBQ3REOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSx1REFBc0QsWUFBWTtBQUNsRTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQSxFQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG9DQUFtQztBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQXlCLGNBQWM7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxVQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF1Qix3Q0FBd0M7QUFDL0Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUErQyxtQkFBbUIsRUFBRTtBQUNwRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBaUIsb0JBQW9CO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBNkIsTUFBTTtBQUNuQztBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVEQUFzRDtBQUN0RDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBbUIsMkJBQTJCO0FBQzlDLHNCQUFxQiwrQ0FBK0M7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFFBQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFtQiwyQkFBMkI7QUFDOUM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW1CLDJCQUEyQjtBQUM5Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBbUIsMkJBQTJCO0FBQzlDO0FBQ0E7QUFDQSxzQkFBcUIsNEJBQTRCO0FBQ2pEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7OztBQ3pqQ0EsaUJBQWdCLG9CQUFvQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7Ozs7Ozs7QUM5R0EsaUJBQWdCLG9CQUFvQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLE1BQU07QUFDakI7QUFDQSxZQUFXLE9BQU87QUFDbEI7QUFDQSxZQUFXLE9BQU87QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxPQUFPO0FBQ2xCO0FBQ0EsWUFBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxNQUFNO0FBQ2pCO0FBQ0EsWUFBVyxTQUFTO0FBQ3BCO0FBQ0EsWUFBVyxPQUFPO0FBQ2xCO0FBQ0EsWUFBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBbUIsT0FBTztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxNQUFNO0FBQ2pCO0FBQ0EsWUFBVyxTQUFTO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNqSEEsaUJBQWdCLG9CQUFvQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7O0FBRUw7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFpQyxRQUFRO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhDQUE2QyxTQUFTO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFvQjtBQUNwQjtBQUNBO0FBQ0EsdUNBQXNDO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFlLFdBQVc7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUErQyxTQUFTO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMENBQXlDLFNBQVM7QUFDbEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFXO0FBQ1g7QUFDQTtBQUNBO0FBQ0EsWUFBVztBQUNYO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLDZDQUE0QyxjQUFjO0FBQzFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsY0FBYTtBQUNiO0FBQ0EsWUFBVztBQUNYO0FBQ0EsUUFBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0EsSUFBRzs7QUFFSCxXQUFVO0FBQ1Y7O0FBRUEiLCJmaWxlIjoic291cmNlLW1hcC5kZWJ1Zy5qcyIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiB3ZWJwYWNrVW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbihyb290LCBmYWN0b3J5KSB7XG5cdGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0Jylcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0ZGVmaW5lKFtdLCBmYWN0b3J5KTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcInNvdXJjZU1hcFwiXSA9IGZhY3RvcnkoKTtcblx0ZWxzZVxuXHRcdHJvb3RbXCJzb3VyY2VNYXBcIl0gPSBmYWN0b3J5KCk7XG59KSh0aGlzLCBmdW5jdGlvbigpIHtcbnJldHVybiBcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiB3ZWJwYWNrL3VuaXZlcnNhbE1vZHVsZURlZmluaXRpb25cbiAqKi8iLCIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSlcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcblxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0ZXhwb3J0czoge30sXG4gXHRcdFx0aWQ6IG1vZHVsZUlkLFxuIFx0XHRcdGxvYWRlZDogZmFsc2VcbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubG9hZGVkID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIHdlYnBhY2svYm9vdHN0cmFwIGUxMzQ0ZmYyMmFjMDZmOTQ1ZWU0XG4gKiovIiwiLypcbiAqIENvcHlyaWdodCAyMDA5LTIwMTEgTW96aWxsYSBGb3VuZGF0aW9uIGFuZCBjb250cmlidXRvcnNcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBOZXcgQlNEIGxpY2Vuc2UuIFNlZSBMSUNFTlNFLnR4dCBvcjpcbiAqIGh0dHA6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9CU0QtMy1DbGF1c2VcbiAqL1xuZXhwb3J0cy5Tb3VyY2VNYXBHZW5lcmF0b3IgPSByZXF1aXJlKCcuL2xpYi9zb3VyY2UtbWFwLWdlbmVyYXRvcicpLlNvdXJjZU1hcEdlbmVyYXRvcjtcbmV4cG9ydHMuU291cmNlTWFwQ29uc3VtZXIgPSByZXF1aXJlKCcuL2xpYi9zb3VyY2UtbWFwLWNvbnN1bWVyJykuU291cmNlTWFwQ29uc3VtZXI7XG5leHBvcnRzLlNvdXJjZU5vZGUgPSByZXF1aXJlKCcuL2xpYi9zb3VyY2Utbm9kZScpLlNvdXJjZU5vZGU7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc291cmNlLW1hcC5qc1xuICoqIG1vZHVsZSBpZCA9IDBcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qIC0qLSBNb2RlOiBqczsganMtaW5kZW50LWxldmVsOiAyOyAtKi0gKi9cbi8qXG4gKiBDb3B5cmlnaHQgMjAxMSBNb3ppbGxhIEZvdW5kYXRpb24gYW5kIGNvbnRyaWJ1dG9yc1xuICogTGljZW5zZWQgdW5kZXIgdGhlIE5ldyBCU0QgbGljZW5zZS4gU2VlIExJQ0VOU0Ugb3I6XG4gKiBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvQlNELTMtQ2xhdXNlXG4gKi9cblxudmFyIGJhc2U2NFZMUSA9IHJlcXVpcmUoJy4vYmFzZTY0LXZscScpO1xudmFyIHV0aWwgPSByZXF1aXJlKCcuL3V0aWwnKTtcbnZhciBBcnJheVNldCA9IHJlcXVpcmUoJy4vYXJyYXktc2V0JykuQXJyYXlTZXQ7XG52YXIgTWFwcGluZ0xpc3QgPSByZXF1aXJlKCcuL21hcHBpbmctbGlzdCcpLk1hcHBpbmdMaXN0O1xuXG4vKipcbiAqIEFuIGluc3RhbmNlIG9mIHRoZSBTb3VyY2VNYXBHZW5lcmF0b3IgcmVwcmVzZW50cyBhIHNvdXJjZSBtYXAgd2hpY2ggaXNcbiAqIGJlaW5nIGJ1aWx0IGluY3JlbWVudGFsbHkuIFlvdSBtYXkgcGFzcyBhbiBvYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nXG4gKiBwcm9wZXJ0aWVzOlxuICpcbiAqICAgLSBmaWxlOiBUaGUgZmlsZW5hbWUgb2YgdGhlIGdlbmVyYXRlZCBzb3VyY2UuXG4gKiAgIC0gc291cmNlUm9vdDogQSByb290IGZvciBhbGwgcmVsYXRpdmUgVVJMcyBpbiB0aGlzIHNvdXJjZSBtYXAuXG4gKi9cbmZ1bmN0aW9uIFNvdXJjZU1hcEdlbmVyYXRvcihhQXJncykge1xuICBpZiAoIWFBcmdzKSB7XG4gICAgYUFyZ3MgPSB7fTtcbiAgfVxuICB0aGlzLl9maWxlID0gdXRpbC5nZXRBcmcoYUFyZ3MsICdmaWxlJywgbnVsbCk7XG4gIHRoaXMuX3NvdXJjZVJvb3QgPSB1dGlsLmdldEFyZyhhQXJncywgJ3NvdXJjZVJvb3QnLCBudWxsKTtcbiAgdGhpcy5fc2tpcFZhbGlkYXRpb24gPSB1dGlsLmdldEFyZyhhQXJncywgJ3NraXBWYWxpZGF0aW9uJywgZmFsc2UpO1xuICB0aGlzLl9zb3VyY2VzID0gbmV3IEFycmF5U2V0KCk7XG4gIHRoaXMuX25hbWVzID0gbmV3IEFycmF5U2V0KCk7XG4gIHRoaXMuX21hcHBpbmdzID0gbmV3IE1hcHBpbmdMaXN0KCk7XG4gIHRoaXMuX3NvdXJjZXNDb250ZW50cyA9IG51bGw7XG59XG5cblNvdXJjZU1hcEdlbmVyYXRvci5wcm90b3R5cGUuX3ZlcnNpb24gPSAzO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgU291cmNlTWFwR2VuZXJhdG9yIGJhc2VkIG9uIGEgU291cmNlTWFwQ29uc3VtZXJcbiAqXG4gKiBAcGFyYW0gYVNvdXJjZU1hcENvbnN1bWVyIFRoZSBTb3VyY2VNYXAuXG4gKi9cblNvdXJjZU1hcEdlbmVyYXRvci5mcm9tU291cmNlTWFwID1cbiAgZnVuY3Rpb24gU291cmNlTWFwR2VuZXJhdG9yX2Zyb21Tb3VyY2VNYXAoYVNvdXJjZU1hcENvbnN1bWVyKSB7XG4gICAgdmFyIHNvdXJjZVJvb3QgPSBhU291cmNlTWFwQ29uc3VtZXIuc291cmNlUm9vdDtcbiAgICB2YXIgZ2VuZXJhdG9yID0gbmV3IFNvdXJjZU1hcEdlbmVyYXRvcih7XG4gICAgICBmaWxlOiBhU291cmNlTWFwQ29uc3VtZXIuZmlsZSxcbiAgICAgIHNvdXJjZVJvb3Q6IHNvdXJjZVJvb3RcbiAgICB9KTtcbiAgICBhU291cmNlTWFwQ29uc3VtZXIuZWFjaE1hcHBpbmcoZnVuY3Rpb24gKG1hcHBpbmcpIHtcbiAgICAgIHZhciBuZXdNYXBwaW5nID0ge1xuICAgICAgICBnZW5lcmF0ZWQ6IHtcbiAgICAgICAgICBsaW5lOiBtYXBwaW5nLmdlbmVyYXRlZExpbmUsXG4gICAgICAgICAgY29sdW1uOiBtYXBwaW5nLmdlbmVyYXRlZENvbHVtblxuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBpZiAobWFwcGluZy5zb3VyY2UgIT0gbnVsbCkge1xuICAgICAgICBuZXdNYXBwaW5nLnNvdXJjZSA9IG1hcHBpbmcuc291cmNlO1xuICAgICAgICBpZiAoc291cmNlUm9vdCAhPSBudWxsKSB7XG4gICAgICAgICAgbmV3TWFwcGluZy5zb3VyY2UgPSB1dGlsLnJlbGF0aXZlKHNvdXJjZVJvb3QsIG5ld01hcHBpbmcuc291cmNlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5ld01hcHBpbmcub3JpZ2luYWwgPSB7XG4gICAgICAgICAgbGluZTogbWFwcGluZy5vcmlnaW5hbExpbmUsXG4gICAgICAgICAgY29sdW1uOiBtYXBwaW5nLm9yaWdpbmFsQ29sdW1uXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG1hcHBpbmcubmFtZSAhPSBudWxsKSB7XG4gICAgICAgICAgbmV3TWFwcGluZy5uYW1lID0gbWFwcGluZy5uYW1lO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGdlbmVyYXRvci5hZGRNYXBwaW5nKG5ld01hcHBpbmcpO1xuICAgIH0pO1xuICAgIGFTb3VyY2VNYXBDb25zdW1lci5zb3VyY2VzLmZvckVhY2goZnVuY3Rpb24gKHNvdXJjZUZpbGUpIHtcbiAgICAgIHZhciBjb250ZW50ID0gYVNvdXJjZU1hcENvbnN1bWVyLnNvdXJjZUNvbnRlbnRGb3Ioc291cmNlRmlsZSk7XG4gICAgICBpZiAoY29udGVudCAhPSBudWxsKSB7XG4gICAgICAgIGdlbmVyYXRvci5zZXRTb3VyY2VDb250ZW50KHNvdXJjZUZpbGUsIGNvbnRlbnQpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBnZW5lcmF0b3I7XG4gIH07XG5cbi8qKlxuICogQWRkIGEgc2luZ2xlIG1hcHBpbmcgZnJvbSBvcmlnaW5hbCBzb3VyY2UgbGluZSBhbmQgY29sdW1uIHRvIHRoZSBnZW5lcmF0ZWRcbiAqIHNvdXJjZSdzIGxpbmUgYW5kIGNvbHVtbiBmb3IgdGhpcyBzb3VyY2UgbWFwIGJlaW5nIGNyZWF0ZWQuIFRoZSBtYXBwaW5nXG4gKiBvYmplY3Qgc2hvdWxkIGhhdmUgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICpcbiAqICAgLSBnZW5lcmF0ZWQ6IEFuIG9iamVjdCB3aXRoIHRoZSBnZW5lcmF0ZWQgbGluZSBhbmQgY29sdW1uIHBvc2l0aW9ucy5cbiAqICAgLSBvcmlnaW5hbDogQW4gb2JqZWN0IHdpdGggdGhlIG9yaWdpbmFsIGxpbmUgYW5kIGNvbHVtbiBwb3NpdGlvbnMuXG4gKiAgIC0gc291cmNlOiBUaGUgb3JpZ2luYWwgc291cmNlIGZpbGUgKHJlbGF0aXZlIHRvIHRoZSBzb3VyY2VSb290KS5cbiAqICAgLSBuYW1lOiBBbiBvcHRpb25hbCBvcmlnaW5hbCB0b2tlbiBuYW1lIGZvciB0aGlzIG1hcHBpbmcuXG4gKi9cblNvdXJjZU1hcEdlbmVyYXRvci5wcm90b3R5cGUuYWRkTWFwcGluZyA9XG4gIGZ1bmN0aW9uIFNvdXJjZU1hcEdlbmVyYXRvcl9hZGRNYXBwaW5nKGFBcmdzKSB7XG4gICAgdmFyIGdlbmVyYXRlZCA9IHV0aWwuZ2V0QXJnKGFBcmdzLCAnZ2VuZXJhdGVkJyk7XG4gICAgdmFyIG9yaWdpbmFsID0gdXRpbC5nZXRBcmcoYUFyZ3MsICdvcmlnaW5hbCcsIG51bGwpO1xuICAgIHZhciBzb3VyY2UgPSB1dGlsLmdldEFyZyhhQXJncywgJ3NvdXJjZScsIG51bGwpO1xuICAgIHZhciBuYW1lID0gdXRpbC5nZXRBcmcoYUFyZ3MsICduYW1lJywgbnVsbCk7XG5cbiAgICBpZiAoIXRoaXMuX3NraXBWYWxpZGF0aW9uKSB7XG4gICAgICB0aGlzLl92YWxpZGF0ZU1hcHBpbmcoZ2VuZXJhdGVkLCBvcmlnaW5hbCwgc291cmNlLCBuYW1lKTtcbiAgICB9XG5cbiAgICBpZiAoc291cmNlICE9IG51bGwpIHtcbiAgICAgIHNvdXJjZSA9IFN0cmluZyhzb3VyY2UpO1xuICAgICAgaWYgKCF0aGlzLl9zb3VyY2VzLmhhcyhzb3VyY2UpKSB7XG4gICAgICAgIHRoaXMuX3NvdXJjZXMuYWRkKHNvdXJjZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG5hbWUgIT0gbnVsbCkge1xuICAgICAgbmFtZSA9IFN0cmluZyhuYW1lKTtcbiAgICAgIGlmICghdGhpcy5fbmFtZXMuaGFzKG5hbWUpKSB7XG4gICAgICAgIHRoaXMuX25hbWVzLmFkZChuYW1lKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9tYXBwaW5ncy5hZGQoe1xuICAgICAgZ2VuZXJhdGVkTGluZTogZ2VuZXJhdGVkLmxpbmUsXG4gICAgICBnZW5lcmF0ZWRDb2x1bW46IGdlbmVyYXRlZC5jb2x1bW4sXG4gICAgICBvcmlnaW5hbExpbmU6IG9yaWdpbmFsICE9IG51bGwgJiYgb3JpZ2luYWwubGluZSxcbiAgICAgIG9yaWdpbmFsQ29sdW1uOiBvcmlnaW5hbCAhPSBudWxsICYmIG9yaWdpbmFsLmNvbHVtbixcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgbmFtZTogbmFtZVxuICAgIH0pO1xuICB9O1xuXG4vKipcbiAqIFNldCB0aGUgc291cmNlIGNvbnRlbnQgZm9yIGEgc291cmNlIGZpbGUuXG4gKi9cblNvdXJjZU1hcEdlbmVyYXRvci5wcm90b3R5cGUuc2V0U291cmNlQ29udGVudCA9XG4gIGZ1bmN0aW9uIFNvdXJjZU1hcEdlbmVyYXRvcl9zZXRTb3VyY2VDb250ZW50KGFTb3VyY2VGaWxlLCBhU291cmNlQ29udGVudCkge1xuICAgIHZhciBzb3VyY2UgPSBhU291cmNlRmlsZTtcbiAgICBpZiAodGhpcy5fc291cmNlUm9vdCAhPSBudWxsKSB7XG4gICAgICBzb3VyY2UgPSB1dGlsLnJlbGF0aXZlKHRoaXMuX3NvdXJjZVJvb3QsIHNvdXJjZSk7XG4gICAgfVxuXG4gICAgaWYgKGFTb3VyY2VDb250ZW50ICE9IG51bGwpIHtcbiAgICAgIC8vIEFkZCB0aGUgc291cmNlIGNvbnRlbnQgdG8gdGhlIF9zb3VyY2VzQ29udGVudHMgbWFwLlxuICAgICAgLy8gQ3JlYXRlIGEgbmV3IF9zb3VyY2VzQ29udGVudHMgbWFwIGlmIHRoZSBwcm9wZXJ0eSBpcyBudWxsLlxuICAgICAgaWYgKCF0aGlzLl9zb3VyY2VzQ29udGVudHMpIHtcbiAgICAgICAgdGhpcy5fc291cmNlc0NvbnRlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX3NvdXJjZXNDb250ZW50c1t1dGlsLnRvU2V0U3RyaW5nKHNvdXJjZSldID0gYVNvdXJjZUNvbnRlbnQ7XG4gICAgfSBlbHNlIGlmICh0aGlzLl9zb3VyY2VzQ29udGVudHMpIHtcbiAgICAgIC8vIFJlbW92ZSB0aGUgc291cmNlIGZpbGUgZnJvbSB0aGUgX3NvdXJjZXNDb250ZW50cyBtYXAuXG4gICAgICAvLyBJZiB0aGUgX3NvdXJjZXNDb250ZW50cyBtYXAgaXMgZW1wdHksIHNldCB0aGUgcHJvcGVydHkgdG8gbnVsbC5cbiAgICAgIGRlbGV0ZSB0aGlzLl9zb3VyY2VzQ29udGVudHNbdXRpbC50b1NldFN0cmluZyhzb3VyY2UpXTtcbiAgICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLl9zb3VyY2VzQ29udGVudHMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLl9zb3VyY2VzQ29udGVudHMgPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuLyoqXG4gKiBBcHBsaWVzIHRoZSBtYXBwaW5ncyBvZiBhIHN1Yi1zb3VyY2UtbWFwIGZvciBhIHNwZWNpZmljIHNvdXJjZSBmaWxlIHRvIHRoZVxuICogc291cmNlIG1hcCBiZWluZyBnZW5lcmF0ZWQuIEVhY2ggbWFwcGluZyB0byB0aGUgc3VwcGxpZWQgc291cmNlIGZpbGUgaXNcbiAqIHJld3JpdHRlbiB1c2luZyB0aGUgc3VwcGxpZWQgc291cmNlIG1hcC4gTm90ZTogVGhlIHJlc29sdXRpb24gZm9yIHRoZVxuICogcmVzdWx0aW5nIG1hcHBpbmdzIGlzIHRoZSBtaW5pbWl1bSBvZiB0aGlzIG1hcCBhbmQgdGhlIHN1cHBsaWVkIG1hcC5cbiAqXG4gKiBAcGFyYW0gYVNvdXJjZU1hcENvbnN1bWVyIFRoZSBzb3VyY2UgbWFwIHRvIGJlIGFwcGxpZWQuXG4gKiBAcGFyYW0gYVNvdXJjZUZpbGUgT3B0aW9uYWwuIFRoZSBmaWxlbmFtZSBvZiB0aGUgc291cmNlIGZpbGUuXG4gKiAgICAgICAgSWYgb21pdHRlZCwgU291cmNlTWFwQ29uc3VtZXIncyBmaWxlIHByb3BlcnR5IHdpbGwgYmUgdXNlZC5cbiAqIEBwYXJhbSBhU291cmNlTWFwUGF0aCBPcHRpb25hbC4gVGhlIGRpcm5hbWUgb2YgdGhlIHBhdGggdG8gdGhlIHNvdXJjZSBtYXBcbiAqICAgICAgICB0byBiZSBhcHBsaWVkLiBJZiByZWxhdGl2ZSwgaXQgaXMgcmVsYXRpdmUgdG8gdGhlIFNvdXJjZU1hcENvbnN1bWVyLlxuICogICAgICAgIFRoaXMgcGFyYW1ldGVyIGlzIG5lZWRlZCB3aGVuIHRoZSB0d28gc291cmNlIG1hcHMgYXJlbid0IGluIHRoZSBzYW1lXG4gKiAgICAgICAgZGlyZWN0b3J5LCBhbmQgdGhlIHNvdXJjZSBtYXAgdG8gYmUgYXBwbGllZCBjb250YWlucyByZWxhdGl2ZSBzb3VyY2VcbiAqICAgICAgICBwYXRocy4gSWYgc28sIHRob3NlIHJlbGF0aXZlIHNvdXJjZSBwYXRocyBuZWVkIHRvIGJlIHJld3JpdHRlblxuICogICAgICAgIHJlbGF0aXZlIHRvIHRoZSBTb3VyY2VNYXBHZW5lcmF0b3IuXG4gKi9cblNvdXJjZU1hcEdlbmVyYXRvci5wcm90b3R5cGUuYXBwbHlTb3VyY2VNYXAgPVxuICBmdW5jdGlvbiBTb3VyY2VNYXBHZW5lcmF0b3JfYXBwbHlTb3VyY2VNYXAoYVNvdXJjZU1hcENvbnN1bWVyLCBhU291cmNlRmlsZSwgYVNvdXJjZU1hcFBhdGgpIHtcbiAgICB2YXIgc291cmNlRmlsZSA9IGFTb3VyY2VGaWxlO1xuICAgIC8vIElmIGFTb3VyY2VGaWxlIGlzIG9taXR0ZWQsIHdlIHdpbGwgdXNlIHRoZSBmaWxlIHByb3BlcnR5IG9mIHRoZSBTb3VyY2VNYXBcbiAgICBpZiAoYVNvdXJjZUZpbGUgPT0gbnVsbCkge1xuICAgICAgaWYgKGFTb3VyY2VNYXBDb25zdW1lci5maWxlID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdTb3VyY2VNYXBHZW5lcmF0b3IucHJvdG90eXBlLmFwcGx5U291cmNlTWFwIHJlcXVpcmVzIGVpdGhlciBhbiBleHBsaWNpdCBzb3VyY2UgZmlsZSwgJyArXG4gICAgICAgICAgJ29yIHRoZSBzb3VyY2UgbWFwXFwncyBcImZpbGVcIiBwcm9wZXJ0eS4gQm90aCB3ZXJlIG9taXR0ZWQuJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgICAgc291cmNlRmlsZSA9IGFTb3VyY2VNYXBDb25zdW1lci5maWxlO1xuICAgIH1cbiAgICB2YXIgc291cmNlUm9vdCA9IHRoaXMuX3NvdXJjZVJvb3Q7XG4gICAgLy8gTWFrZSBcInNvdXJjZUZpbGVcIiByZWxhdGl2ZSBpZiBhbiBhYnNvbHV0ZSBVcmwgaXMgcGFzc2VkLlxuICAgIGlmIChzb3VyY2VSb290ICE9IG51bGwpIHtcbiAgICAgIHNvdXJjZUZpbGUgPSB1dGlsLnJlbGF0aXZlKHNvdXJjZVJvb3QsIHNvdXJjZUZpbGUpO1xuICAgIH1cbiAgICAvLyBBcHBseWluZyB0aGUgU291cmNlTWFwIGNhbiBhZGQgYW5kIHJlbW92ZSBpdGVtcyBmcm9tIHRoZSBzb3VyY2VzIGFuZFxuICAgIC8vIHRoZSBuYW1lcyBhcnJheS5cbiAgICB2YXIgbmV3U291cmNlcyA9IG5ldyBBcnJheVNldCgpO1xuICAgIHZhciBuZXdOYW1lcyA9IG5ldyBBcnJheVNldCgpO1xuXG4gICAgLy8gRmluZCBtYXBwaW5ncyBmb3IgdGhlIFwic291cmNlRmlsZVwiXG4gICAgdGhpcy5fbWFwcGluZ3MudW5zb3J0ZWRGb3JFYWNoKGZ1bmN0aW9uIChtYXBwaW5nKSB7XG4gICAgICBpZiAobWFwcGluZy5zb3VyY2UgPT09IHNvdXJjZUZpbGUgJiYgbWFwcGluZy5vcmlnaW5hbExpbmUgIT0gbnVsbCkge1xuICAgICAgICAvLyBDaGVjayBpZiBpdCBjYW4gYmUgbWFwcGVkIGJ5IHRoZSBzb3VyY2UgbWFwLCB0aGVuIHVwZGF0ZSB0aGUgbWFwcGluZy5cbiAgICAgICAgdmFyIG9yaWdpbmFsID0gYVNvdXJjZU1hcENvbnN1bWVyLm9yaWdpbmFsUG9zaXRpb25Gb3Ioe1xuICAgICAgICAgIGxpbmU6IG1hcHBpbmcub3JpZ2luYWxMaW5lLFxuICAgICAgICAgIGNvbHVtbjogbWFwcGluZy5vcmlnaW5hbENvbHVtblxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKG9yaWdpbmFsLnNvdXJjZSAhPSBudWxsKSB7XG4gICAgICAgICAgLy8gQ29weSBtYXBwaW5nXG4gICAgICAgICAgbWFwcGluZy5zb3VyY2UgPSBvcmlnaW5hbC5zb3VyY2U7XG4gICAgICAgICAgaWYgKGFTb3VyY2VNYXBQYXRoICE9IG51bGwpIHtcbiAgICAgICAgICAgIG1hcHBpbmcuc291cmNlID0gdXRpbC5qb2luKGFTb3VyY2VNYXBQYXRoLCBtYXBwaW5nLnNvdXJjZSlcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHNvdXJjZVJvb3QgIT0gbnVsbCkge1xuICAgICAgICAgICAgbWFwcGluZy5zb3VyY2UgPSB1dGlsLnJlbGF0aXZlKHNvdXJjZVJvb3QsIG1hcHBpbmcuc291cmNlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbWFwcGluZy5vcmlnaW5hbExpbmUgPSBvcmlnaW5hbC5saW5lO1xuICAgICAgICAgIG1hcHBpbmcub3JpZ2luYWxDb2x1bW4gPSBvcmlnaW5hbC5jb2x1bW47XG4gICAgICAgICAgaWYgKG9yaWdpbmFsLm5hbWUgIT0gbnVsbCkge1xuICAgICAgICAgICAgbWFwcGluZy5uYW1lID0gb3JpZ2luYWwubmFtZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIHNvdXJjZSA9IG1hcHBpbmcuc291cmNlO1xuICAgICAgaWYgKHNvdXJjZSAhPSBudWxsICYmICFuZXdTb3VyY2VzLmhhcyhzb3VyY2UpKSB7XG4gICAgICAgIG5ld1NvdXJjZXMuYWRkKHNvdXJjZSk7XG4gICAgICB9XG5cbiAgICAgIHZhciBuYW1lID0gbWFwcGluZy5uYW1lO1xuICAgICAgaWYgKG5hbWUgIT0gbnVsbCAmJiAhbmV3TmFtZXMuaGFzKG5hbWUpKSB7XG4gICAgICAgIG5ld05hbWVzLmFkZChuYW1lKTtcbiAgICAgIH1cblxuICAgIH0sIHRoaXMpO1xuICAgIHRoaXMuX3NvdXJjZXMgPSBuZXdTb3VyY2VzO1xuICAgIHRoaXMuX25hbWVzID0gbmV3TmFtZXM7XG5cbiAgICAvLyBDb3B5IHNvdXJjZXNDb250ZW50cyBvZiBhcHBsaWVkIG1hcC5cbiAgICBhU291cmNlTWFwQ29uc3VtZXIuc291cmNlcy5mb3JFYWNoKGZ1bmN0aW9uIChzb3VyY2VGaWxlKSB7XG4gICAgICB2YXIgY29udGVudCA9IGFTb3VyY2VNYXBDb25zdW1lci5zb3VyY2VDb250ZW50Rm9yKHNvdXJjZUZpbGUpO1xuICAgICAgaWYgKGNvbnRlbnQgIT0gbnVsbCkge1xuICAgICAgICBpZiAoYVNvdXJjZU1hcFBhdGggIT0gbnVsbCkge1xuICAgICAgICAgIHNvdXJjZUZpbGUgPSB1dGlsLmpvaW4oYVNvdXJjZU1hcFBhdGgsIHNvdXJjZUZpbGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzb3VyY2VSb290ICE9IG51bGwpIHtcbiAgICAgICAgICBzb3VyY2VGaWxlID0gdXRpbC5yZWxhdGl2ZShzb3VyY2VSb290LCBzb3VyY2VGaWxlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFNvdXJjZUNvbnRlbnQoc291cmNlRmlsZSwgY29udGVudCk7XG4gICAgICB9XG4gICAgfSwgdGhpcyk7XG4gIH07XG5cbi8qKlxuICogQSBtYXBwaW5nIGNhbiBoYXZlIG9uZSBvZiB0aGUgdGhyZWUgbGV2ZWxzIG9mIGRhdGE6XG4gKlxuICogICAxLiBKdXN0IHRoZSBnZW5lcmF0ZWQgcG9zaXRpb24uXG4gKiAgIDIuIFRoZSBHZW5lcmF0ZWQgcG9zaXRpb24sIG9yaWdpbmFsIHBvc2l0aW9uLCBhbmQgb3JpZ2luYWwgc291cmNlLlxuICogICAzLiBHZW5lcmF0ZWQgYW5kIG9yaWdpbmFsIHBvc2l0aW9uLCBvcmlnaW5hbCBzb3VyY2UsIGFzIHdlbGwgYXMgYSBuYW1lXG4gKiAgICAgIHRva2VuLlxuICpcbiAqIFRvIG1haW50YWluIGNvbnNpc3RlbmN5LCB3ZSB2YWxpZGF0ZSB0aGF0IGFueSBuZXcgbWFwcGluZyBiZWluZyBhZGRlZCBmYWxsc1xuICogaW4gdG8gb25lIG9mIHRoZXNlIGNhdGVnb3JpZXMuXG4gKi9cblNvdXJjZU1hcEdlbmVyYXRvci5wcm90b3R5cGUuX3ZhbGlkYXRlTWFwcGluZyA9XG4gIGZ1bmN0aW9uIFNvdXJjZU1hcEdlbmVyYXRvcl92YWxpZGF0ZU1hcHBpbmcoYUdlbmVyYXRlZCwgYU9yaWdpbmFsLCBhU291cmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFOYW1lKSB7XG4gICAgaWYgKGFHZW5lcmF0ZWQgJiYgJ2xpbmUnIGluIGFHZW5lcmF0ZWQgJiYgJ2NvbHVtbicgaW4gYUdlbmVyYXRlZFxuICAgICAgICAmJiBhR2VuZXJhdGVkLmxpbmUgPiAwICYmIGFHZW5lcmF0ZWQuY29sdW1uID49IDBcbiAgICAgICAgJiYgIWFPcmlnaW5hbCAmJiAhYVNvdXJjZSAmJiAhYU5hbWUpIHtcbiAgICAgIC8vIENhc2UgMS5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZWxzZSBpZiAoYUdlbmVyYXRlZCAmJiAnbGluZScgaW4gYUdlbmVyYXRlZCAmJiAnY29sdW1uJyBpbiBhR2VuZXJhdGVkXG4gICAgICAgICAgICAgJiYgYU9yaWdpbmFsICYmICdsaW5lJyBpbiBhT3JpZ2luYWwgJiYgJ2NvbHVtbicgaW4gYU9yaWdpbmFsXG4gICAgICAgICAgICAgJiYgYUdlbmVyYXRlZC5saW5lID4gMCAmJiBhR2VuZXJhdGVkLmNvbHVtbiA+PSAwXG4gICAgICAgICAgICAgJiYgYU9yaWdpbmFsLmxpbmUgPiAwICYmIGFPcmlnaW5hbC5jb2x1bW4gPj0gMFxuICAgICAgICAgICAgICYmIGFTb3VyY2UpIHtcbiAgICAgIC8vIENhc2VzIDIgYW5kIDMuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG1hcHBpbmc6ICcgKyBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIGdlbmVyYXRlZDogYUdlbmVyYXRlZCxcbiAgICAgICAgc291cmNlOiBhU291cmNlLFxuICAgICAgICBvcmlnaW5hbDogYU9yaWdpbmFsLFxuICAgICAgICBuYW1lOiBhTmFtZVxuICAgICAgfSkpO1xuICAgIH1cbiAgfTtcblxuLyoqXG4gKiBTZXJpYWxpemUgdGhlIGFjY3VtdWxhdGVkIG1hcHBpbmdzIGluIHRvIHRoZSBzdHJlYW0gb2YgYmFzZSA2NCBWTFFzXG4gKiBzcGVjaWZpZWQgYnkgdGhlIHNvdXJjZSBtYXAgZm9ybWF0LlxuICovXG5Tb3VyY2VNYXBHZW5lcmF0b3IucHJvdG90eXBlLl9zZXJpYWxpemVNYXBwaW5ncyA9XG4gIGZ1bmN0aW9uIFNvdXJjZU1hcEdlbmVyYXRvcl9zZXJpYWxpemVNYXBwaW5ncygpIHtcbiAgICB2YXIgcHJldmlvdXNHZW5lcmF0ZWRDb2x1bW4gPSAwO1xuICAgIHZhciBwcmV2aW91c0dlbmVyYXRlZExpbmUgPSAxO1xuICAgIHZhciBwcmV2aW91c09yaWdpbmFsQ29sdW1uID0gMDtcbiAgICB2YXIgcHJldmlvdXNPcmlnaW5hbExpbmUgPSAwO1xuICAgIHZhciBwcmV2aW91c05hbWUgPSAwO1xuICAgIHZhciBwcmV2aW91c1NvdXJjZSA9IDA7XG4gICAgdmFyIHJlc3VsdCA9ICcnO1xuICAgIHZhciBuZXh0O1xuICAgIHZhciBtYXBwaW5nO1xuICAgIHZhciBuYW1lSWR4O1xuICAgIHZhciBzb3VyY2VJZHg7XG5cbiAgICB2YXIgbWFwcGluZ3MgPSB0aGlzLl9tYXBwaW5ncy50b0FycmF5KCk7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IG1hcHBpbmdzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBtYXBwaW5nID0gbWFwcGluZ3NbaV07XG4gICAgICBuZXh0ID0gJydcblxuICAgICAgaWYgKG1hcHBpbmcuZ2VuZXJhdGVkTGluZSAhPT0gcHJldmlvdXNHZW5lcmF0ZWRMaW5lKSB7XG4gICAgICAgIHByZXZpb3VzR2VuZXJhdGVkQ29sdW1uID0gMDtcbiAgICAgICAgd2hpbGUgKG1hcHBpbmcuZ2VuZXJhdGVkTGluZSAhPT0gcHJldmlvdXNHZW5lcmF0ZWRMaW5lKSB7XG4gICAgICAgICAgbmV4dCArPSAnOyc7XG4gICAgICAgICAgcHJldmlvdXNHZW5lcmF0ZWRMaW5lKys7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBpZiAoaSA+IDApIHtcbiAgICAgICAgICBpZiAoIXV0aWwuY29tcGFyZUJ5R2VuZXJhdGVkUG9zaXRpb25zSW5mbGF0ZWQobWFwcGluZywgbWFwcGluZ3NbaSAtIDFdKSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIG5leHQgKz0gJywnO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIG5leHQgKz0gYmFzZTY0VkxRLmVuY29kZShtYXBwaW5nLmdlbmVyYXRlZENvbHVtblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBwcmV2aW91c0dlbmVyYXRlZENvbHVtbik7XG4gICAgICBwcmV2aW91c0dlbmVyYXRlZENvbHVtbiA9IG1hcHBpbmcuZ2VuZXJhdGVkQ29sdW1uO1xuXG4gICAgICBpZiAobWFwcGluZy5zb3VyY2UgIT0gbnVsbCkge1xuICAgICAgICBzb3VyY2VJZHggPSB0aGlzLl9zb3VyY2VzLmluZGV4T2YobWFwcGluZy5zb3VyY2UpO1xuICAgICAgICBuZXh0ICs9IGJhc2U2NFZMUS5lbmNvZGUoc291cmNlSWR4IC0gcHJldmlvdXNTb3VyY2UpO1xuICAgICAgICBwcmV2aW91c1NvdXJjZSA9IHNvdXJjZUlkeDtcblxuICAgICAgICAvLyBsaW5lcyBhcmUgc3RvcmVkIDAtYmFzZWQgaW4gU291cmNlTWFwIHNwZWMgdmVyc2lvbiAzXG4gICAgICAgIG5leHQgKz0gYmFzZTY0VkxRLmVuY29kZShtYXBwaW5nLm9yaWdpbmFsTGluZSAtIDFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBwcmV2aW91c09yaWdpbmFsTGluZSk7XG4gICAgICAgIHByZXZpb3VzT3JpZ2luYWxMaW5lID0gbWFwcGluZy5vcmlnaW5hbExpbmUgLSAxO1xuXG4gICAgICAgIG5leHQgKz0gYmFzZTY0VkxRLmVuY29kZShtYXBwaW5nLm9yaWdpbmFsQ29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gcHJldmlvdXNPcmlnaW5hbENvbHVtbik7XG4gICAgICAgIHByZXZpb3VzT3JpZ2luYWxDb2x1bW4gPSBtYXBwaW5nLm9yaWdpbmFsQ29sdW1uO1xuXG4gICAgICAgIGlmIChtYXBwaW5nLm5hbWUgIT0gbnVsbCkge1xuICAgICAgICAgIG5hbWVJZHggPSB0aGlzLl9uYW1lcy5pbmRleE9mKG1hcHBpbmcubmFtZSk7XG4gICAgICAgICAgbmV4dCArPSBiYXNlNjRWTFEuZW5jb2RlKG5hbWVJZHggLSBwcmV2aW91c05hbWUpO1xuICAgICAgICAgIHByZXZpb3VzTmFtZSA9IG5hbWVJZHg7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmVzdWx0ICs9IG5leHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuU291cmNlTWFwR2VuZXJhdG9yLnByb3RvdHlwZS5fZ2VuZXJhdGVTb3VyY2VzQ29udGVudCA9XG4gIGZ1bmN0aW9uIFNvdXJjZU1hcEdlbmVyYXRvcl9nZW5lcmF0ZVNvdXJjZXNDb250ZW50KGFTb3VyY2VzLCBhU291cmNlUm9vdCkge1xuICAgIHJldHVybiBhU291cmNlcy5tYXAoZnVuY3Rpb24gKHNvdXJjZSkge1xuICAgICAgaWYgKCF0aGlzLl9zb3VyY2VzQ29udGVudHMpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICBpZiAoYVNvdXJjZVJvb3QgIT0gbnVsbCkge1xuICAgICAgICBzb3VyY2UgPSB1dGlsLnJlbGF0aXZlKGFTb3VyY2VSb290LCBzb3VyY2UpO1xuICAgICAgfVxuICAgICAgdmFyIGtleSA9IHV0aWwudG9TZXRTdHJpbmcoc291cmNlKTtcbiAgICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5fc291cmNlc0NvbnRlbnRzLCBrZXkpXG4gICAgICAgID8gdGhpcy5fc291cmNlc0NvbnRlbnRzW2tleV1cbiAgICAgICAgOiBudWxsO1xuICAgIH0sIHRoaXMpO1xuICB9O1xuXG4vKipcbiAqIEV4dGVybmFsaXplIHRoZSBzb3VyY2UgbWFwLlxuICovXG5Tb3VyY2VNYXBHZW5lcmF0b3IucHJvdG90eXBlLnRvSlNPTiA9XG4gIGZ1bmN0aW9uIFNvdXJjZU1hcEdlbmVyYXRvcl90b0pTT04oKSB7XG4gICAgdmFyIG1hcCA9IHtcbiAgICAgIHZlcnNpb246IHRoaXMuX3ZlcnNpb24sXG4gICAgICBzb3VyY2VzOiB0aGlzLl9zb3VyY2VzLnRvQXJyYXkoKSxcbiAgICAgIG5hbWVzOiB0aGlzLl9uYW1lcy50b0FycmF5KCksXG4gICAgICBtYXBwaW5nczogdGhpcy5fc2VyaWFsaXplTWFwcGluZ3MoKVxuICAgIH07XG4gICAgaWYgKHRoaXMuX2ZpbGUgIT0gbnVsbCkge1xuICAgICAgbWFwLmZpbGUgPSB0aGlzLl9maWxlO1xuICAgIH1cbiAgICBpZiAodGhpcy5fc291cmNlUm9vdCAhPSBudWxsKSB7XG4gICAgICBtYXAuc291cmNlUm9vdCA9IHRoaXMuX3NvdXJjZVJvb3Q7XG4gICAgfVxuICAgIGlmICh0aGlzLl9zb3VyY2VzQ29udGVudHMpIHtcbiAgICAgIG1hcC5zb3VyY2VzQ29udGVudCA9IHRoaXMuX2dlbmVyYXRlU291cmNlc0NvbnRlbnQobWFwLnNvdXJjZXMsIG1hcC5zb3VyY2VSb290KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWFwO1xuICB9O1xuXG4vKipcbiAqIFJlbmRlciB0aGUgc291cmNlIG1hcCBiZWluZyBnZW5lcmF0ZWQgdG8gYSBzdHJpbmcuXG4gKi9cblNvdXJjZU1hcEdlbmVyYXRvci5wcm90b3R5cGUudG9TdHJpbmcgPVxuICBmdW5jdGlvbiBTb3VyY2VNYXBHZW5lcmF0b3JfdG9TdHJpbmcoKSB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRoaXMudG9KU09OKCkpO1xuICB9O1xuXG5leHBvcnRzLlNvdXJjZU1hcEdlbmVyYXRvciA9IFNvdXJjZU1hcEdlbmVyYXRvcjtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9saWIvc291cmNlLW1hcC1nZW5lcmF0b3IuanNcbiAqKiBtb2R1bGUgaWQgPSAxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKiAtKi0gTW9kZToganM7IGpzLWluZGVudC1sZXZlbDogMjsgLSotICovXG4vKlxuICogQ29weXJpZ2h0IDIwMTEgTW96aWxsYSBGb3VuZGF0aW9uIGFuZCBjb250cmlidXRvcnNcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBOZXcgQlNEIGxpY2Vuc2UuIFNlZSBMSUNFTlNFIG9yOlxuICogaHR0cDovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL0JTRC0zLUNsYXVzZVxuICpcbiAqIEJhc2VkIG9uIHRoZSBCYXNlIDY0IFZMUSBpbXBsZW1lbnRhdGlvbiBpbiBDbG9zdXJlIENvbXBpbGVyOlxuICogaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jbG9zdXJlLWNvbXBpbGVyL3NvdXJjZS9icm93c2UvdHJ1bmsvc3JjL2NvbS9nb29nbGUvZGVidWdnaW5nL3NvdXJjZW1hcC9CYXNlNjRWTFEuamF2YVxuICpcbiAqIENvcHlyaWdodCAyMDExIFRoZSBDbG9zdXJlIENvbXBpbGVyIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmVcbiAqIG1ldDpcbiAqXG4gKiAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICogICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZVxuICogICAgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiAqICAgIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZFxuICogICAgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICogICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0c1xuICogICAgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4gKiAgICBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SU1xuICogXCJBUyBJU1wiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVFxuICogTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SXG4gKiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVFxuICogT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsXG4gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UXG4gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSxcbiAqIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWVxuICogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFXG4gKiBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICovXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCcuL2Jhc2U2NCcpO1xuXG4vLyBBIHNpbmdsZSBiYXNlIDY0IGRpZ2l0IGNhbiBjb250YWluIDYgYml0cyBvZiBkYXRhLiBGb3IgdGhlIGJhc2UgNjQgdmFyaWFibGVcbi8vIGxlbmd0aCBxdWFudGl0aWVzIHdlIHVzZSBpbiB0aGUgc291cmNlIG1hcCBzcGVjLCB0aGUgZmlyc3QgYml0IGlzIHRoZSBzaWduLFxuLy8gdGhlIG5leHQgZm91ciBiaXRzIGFyZSB0aGUgYWN0dWFsIHZhbHVlLCBhbmQgdGhlIDZ0aCBiaXQgaXMgdGhlXG4vLyBjb250aW51YXRpb24gYml0LiBUaGUgY29udGludWF0aW9uIGJpdCB0ZWxscyB1cyB3aGV0aGVyIHRoZXJlIGFyZSBtb3JlXG4vLyBkaWdpdHMgaW4gdGhpcyB2YWx1ZSBmb2xsb3dpbmcgdGhpcyBkaWdpdC5cbi8vXG4vLyAgIENvbnRpbnVhdGlvblxuLy8gICB8ICAgIFNpZ25cbi8vICAgfCAgICB8XG4vLyAgIFYgICAgVlxuLy8gICAxMDEwMTFcblxudmFyIFZMUV9CQVNFX1NISUZUID0gNTtcblxuLy8gYmluYXJ5OiAxMDAwMDBcbnZhciBWTFFfQkFTRSA9IDEgPDwgVkxRX0JBU0VfU0hJRlQ7XG5cbi8vIGJpbmFyeTogMDExMTExXG52YXIgVkxRX0JBU0VfTUFTSyA9IFZMUV9CQVNFIC0gMTtcblxuLy8gYmluYXJ5OiAxMDAwMDBcbnZhciBWTFFfQ09OVElOVUFUSU9OX0JJVCA9IFZMUV9CQVNFO1xuXG4vKipcbiAqIENvbnZlcnRzIGZyb20gYSB0d28tY29tcGxlbWVudCB2YWx1ZSB0byBhIHZhbHVlIHdoZXJlIHRoZSBzaWduIGJpdCBpc1xuICogcGxhY2VkIGluIHRoZSBsZWFzdCBzaWduaWZpY2FudCBiaXQuICBGb3IgZXhhbXBsZSwgYXMgZGVjaW1hbHM6XG4gKiAgIDEgYmVjb21lcyAyICgxMCBiaW5hcnkpLCAtMSBiZWNvbWVzIDMgKDExIGJpbmFyeSlcbiAqICAgMiBiZWNvbWVzIDQgKDEwMCBiaW5hcnkpLCAtMiBiZWNvbWVzIDUgKDEwMSBiaW5hcnkpXG4gKi9cbmZ1bmN0aW9uIHRvVkxRU2lnbmVkKGFWYWx1ZSkge1xuICByZXR1cm4gYVZhbHVlIDwgMFxuICAgID8gKCgtYVZhbHVlKSA8PCAxKSArIDFcbiAgICA6IChhVmFsdWUgPDwgMSkgKyAwO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRvIGEgdHdvLWNvbXBsZW1lbnQgdmFsdWUgZnJvbSBhIHZhbHVlIHdoZXJlIHRoZSBzaWduIGJpdCBpc1xuICogcGxhY2VkIGluIHRoZSBsZWFzdCBzaWduaWZpY2FudCBiaXQuICBGb3IgZXhhbXBsZSwgYXMgZGVjaW1hbHM6XG4gKiAgIDIgKDEwIGJpbmFyeSkgYmVjb21lcyAxLCAzICgxMSBiaW5hcnkpIGJlY29tZXMgLTFcbiAqICAgNCAoMTAwIGJpbmFyeSkgYmVjb21lcyAyLCA1ICgxMDEgYmluYXJ5KSBiZWNvbWVzIC0yXG4gKi9cbmZ1bmN0aW9uIGZyb21WTFFTaWduZWQoYVZhbHVlKSB7XG4gIHZhciBpc05lZ2F0aXZlID0gKGFWYWx1ZSAmIDEpID09PSAxO1xuICB2YXIgc2hpZnRlZCA9IGFWYWx1ZSA+PiAxO1xuICByZXR1cm4gaXNOZWdhdGl2ZVxuICAgID8gLXNoaWZ0ZWRcbiAgICA6IHNoaWZ0ZWQ7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgYmFzZSA2NCBWTFEgZW5jb2RlZCB2YWx1ZS5cbiAqL1xuZXhwb3J0cy5lbmNvZGUgPSBmdW5jdGlvbiBiYXNlNjRWTFFfZW5jb2RlKGFWYWx1ZSkge1xuICB2YXIgZW5jb2RlZCA9IFwiXCI7XG4gIHZhciBkaWdpdDtcblxuICB2YXIgdmxxID0gdG9WTFFTaWduZWQoYVZhbHVlKTtcblxuICBkbyB7XG4gICAgZGlnaXQgPSB2bHEgJiBWTFFfQkFTRV9NQVNLO1xuICAgIHZscSA+Pj49IFZMUV9CQVNFX1NISUZUO1xuICAgIGlmICh2bHEgPiAwKSB7XG4gICAgICAvLyBUaGVyZSBhcmUgc3RpbGwgbW9yZSBkaWdpdHMgaW4gdGhpcyB2YWx1ZSwgc28gd2UgbXVzdCBtYWtlIHN1cmUgdGhlXG4gICAgICAvLyBjb250aW51YXRpb24gYml0IGlzIG1hcmtlZC5cbiAgICAgIGRpZ2l0IHw9IFZMUV9DT05USU5VQVRJT05fQklUO1xuICAgIH1cbiAgICBlbmNvZGVkICs9IGJhc2U2NC5lbmNvZGUoZGlnaXQpO1xuICB9IHdoaWxlICh2bHEgPiAwKTtcblxuICByZXR1cm4gZW5jb2RlZDtcbn07XG5cbi8qKlxuICogRGVjb2RlcyB0aGUgbmV4dCBiYXNlIDY0IFZMUSB2YWx1ZSBmcm9tIHRoZSBnaXZlbiBzdHJpbmcgYW5kIHJldHVybnMgdGhlXG4gKiB2YWx1ZSBhbmQgdGhlIHJlc3Qgb2YgdGhlIHN0cmluZyB2aWEgdGhlIG91dCBwYXJhbWV0ZXIuXG4gKi9cbmV4cG9ydHMuZGVjb2RlID0gZnVuY3Rpb24gYmFzZTY0VkxRX2RlY29kZShhU3RyLCBhSW5kZXgsIGFPdXRQYXJhbSkge1xuICB2YXIgc3RyTGVuID0gYVN0ci5sZW5ndGg7XG4gIHZhciByZXN1bHQgPSAwO1xuICB2YXIgc2hpZnQgPSAwO1xuICB2YXIgY29udGludWF0aW9uLCBkaWdpdDtcblxuICBkbyB7XG4gICAgaWYgKGFJbmRleCA+PSBzdHJMZW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkV4cGVjdGVkIG1vcmUgZGlnaXRzIGluIGJhc2UgNjQgVkxRIHZhbHVlLlwiKTtcbiAgICB9XG5cbiAgICBkaWdpdCA9IGJhc2U2NC5kZWNvZGUoYVN0ci5jaGFyQ29kZUF0KGFJbmRleCsrKSk7XG4gICAgaWYgKGRpZ2l0ID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBiYXNlNjQgZGlnaXQ6IFwiICsgYVN0ci5jaGFyQXQoYUluZGV4IC0gMSkpO1xuICAgIH1cblxuICAgIGNvbnRpbnVhdGlvbiA9ICEhKGRpZ2l0ICYgVkxRX0NPTlRJTlVBVElPTl9CSVQpO1xuICAgIGRpZ2l0ICY9IFZMUV9CQVNFX01BU0s7XG4gICAgcmVzdWx0ID0gcmVzdWx0ICsgKGRpZ2l0IDw8IHNoaWZ0KTtcbiAgICBzaGlmdCArPSBWTFFfQkFTRV9TSElGVDtcbiAgfSB3aGlsZSAoY29udGludWF0aW9uKTtcblxuICBhT3V0UGFyYW0udmFsdWUgPSBmcm9tVkxRU2lnbmVkKHJlc3VsdCk7XG4gIGFPdXRQYXJhbS5yZXN0ID0gYUluZGV4O1xufTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9saWIvYmFzZTY0LXZscS5qc1xuICoqIG1vZHVsZSBpZCA9IDJcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qIC0qLSBNb2RlOiBqczsganMtaW5kZW50LWxldmVsOiAyOyAtKi0gKi9cbi8qXG4gKiBDb3B5cmlnaHQgMjAxMSBNb3ppbGxhIEZvdW5kYXRpb24gYW5kIGNvbnRyaWJ1dG9yc1xuICogTGljZW5zZWQgdW5kZXIgdGhlIE5ldyBCU0QgbGljZW5zZS4gU2VlIExJQ0VOU0Ugb3I6XG4gKiBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvQlNELTMtQ2xhdXNlXG4gKi9cblxudmFyIGludFRvQ2hhck1hcCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJy5zcGxpdCgnJyk7XG5cbi8qKlxuICogRW5jb2RlIGFuIGludGVnZXIgaW4gdGhlIHJhbmdlIG9mIDAgdG8gNjMgdG8gYSBzaW5nbGUgYmFzZSA2NCBkaWdpdC5cbiAqL1xuZXhwb3J0cy5lbmNvZGUgPSBmdW5jdGlvbiAobnVtYmVyKSB7XG4gIGlmICgwIDw9IG51bWJlciAmJiBudW1iZXIgPCBpbnRUb0NoYXJNYXAubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGludFRvQ2hhck1hcFtudW1iZXJdO1xuICB9XG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXCJNdXN0IGJlIGJldHdlZW4gMCBhbmQgNjM6IFwiICsgbnVtYmVyKTtcbn07XG5cbi8qKlxuICogRGVjb2RlIGEgc2luZ2xlIGJhc2UgNjQgY2hhcmFjdGVyIGNvZGUgZGlnaXQgdG8gYW4gaW50ZWdlci4gUmV0dXJucyAtMSBvblxuICogZmFpbHVyZS5cbiAqL1xuZXhwb3J0cy5kZWNvZGUgPSBmdW5jdGlvbiAoY2hhckNvZGUpIHtcbiAgdmFyIGJpZ0EgPSA2NTsgICAgIC8vICdBJ1xuICB2YXIgYmlnWiA9IDkwOyAgICAgLy8gJ1onXG5cbiAgdmFyIGxpdHRsZUEgPSA5NzsgIC8vICdhJ1xuICB2YXIgbGl0dGxlWiA9IDEyMjsgLy8gJ3onXG5cbiAgdmFyIHplcm8gPSA0ODsgICAgIC8vICcwJ1xuICB2YXIgbmluZSA9IDU3OyAgICAgLy8gJzknXG5cbiAgdmFyIHBsdXMgPSA0MzsgICAgIC8vICcrJ1xuICB2YXIgc2xhc2ggPSA0NzsgICAgLy8gJy8nXG5cbiAgdmFyIGxpdHRsZU9mZnNldCA9IDI2O1xuICB2YXIgbnVtYmVyT2Zmc2V0ID0gNTI7XG5cbiAgLy8gMCAtIDI1OiBBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWlxuICBpZiAoYmlnQSA8PSBjaGFyQ29kZSAmJiBjaGFyQ29kZSA8PSBiaWdaKSB7XG4gICAgcmV0dXJuIChjaGFyQ29kZSAtIGJpZ0EpO1xuICB9XG5cbiAgLy8gMjYgLSA1MTogYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpcbiAgaWYgKGxpdHRsZUEgPD0gY2hhckNvZGUgJiYgY2hhckNvZGUgPD0gbGl0dGxlWikge1xuICAgIHJldHVybiAoY2hhckNvZGUgLSBsaXR0bGVBICsgbGl0dGxlT2Zmc2V0KTtcbiAgfVxuXG4gIC8vIDUyIC0gNjE6IDAxMjM0NTY3ODlcbiAgaWYgKHplcm8gPD0gY2hhckNvZGUgJiYgY2hhckNvZGUgPD0gbmluZSkge1xuICAgIHJldHVybiAoY2hhckNvZGUgLSB6ZXJvICsgbnVtYmVyT2Zmc2V0KTtcbiAgfVxuXG4gIC8vIDYyOiArXG4gIGlmIChjaGFyQ29kZSA9PSBwbHVzKSB7XG4gICAgcmV0dXJuIDYyO1xuICB9XG5cbiAgLy8gNjM6IC9cbiAgaWYgKGNoYXJDb2RlID09IHNsYXNoKSB7XG4gICAgcmV0dXJuIDYzO1xuICB9XG5cbiAgLy8gSW52YWxpZCBiYXNlNjQgZGlnaXQuXG4gIHJldHVybiAtMTtcbn07XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vbGliL2Jhc2U2NC5qc1xuICoqIG1vZHVsZSBpZCA9IDNcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qIC0qLSBNb2RlOiBqczsganMtaW5kZW50LWxldmVsOiAyOyAtKi0gKi9cbi8qXG4gKiBDb3B5cmlnaHQgMjAxMSBNb3ppbGxhIEZvdW5kYXRpb24gYW5kIGNvbnRyaWJ1dG9yc1xuICogTGljZW5zZWQgdW5kZXIgdGhlIE5ldyBCU0QgbGljZW5zZS4gU2VlIExJQ0VOU0Ugb3I6XG4gKiBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvQlNELTMtQ2xhdXNlXG4gKi9cblxuLyoqXG4gKiBUaGlzIGlzIGEgaGVscGVyIGZ1bmN0aW9uIGZvciBnZXR0aW5nIHZhbHVlcyBmcm9tIHBhcmFtZXRlci9vcHRpb25zXG4gKiBvYmplY3RzLlxuICpcbiAqIEBwYXJhbSBhcmdzIFRoZSBvYmplY3Qgd2UgYXJlIGV4dHJhY3RpbmcgdmFsdWVzIGZyb21cbiAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB3ZSBhcmUgZ2V0dGluZy5cbiAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgQW4gb3B0aW9uYWwgdmFsdWUgdG8gcmV0dXJuIGlmIHRoZSBwcm9wZXJ0eSBpcyBtaXNzaW5nXG4gKiBmcm9tIHRoZSBvYmplY3QuIElmIHRoaXMgaXMgbm90IHNwZWNpZmllZCBhbmQgdGhlIHByb3BlcnR5IGlzIG1pc3NpbmcsIGFuXG4gKiBlcnJvciB3aWxsIGJlIHRocm93bi5cbiAqL1xuZnVuY3Rpb24gZ2V0QXJnKGFBcmdzLCBhTmFtZSwgYURlZmF1bHRWYWx1ZSkge1xuICBpZiAoYU5hbWUgaW4gYUFyZ3MpIHtcbiAgICByZXR1cm4gYUFyZ3NbYU5hbWVdO1xuICB9IGVsc2UgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpIHtcbiAgICByZXR1cm4gYURlZmF1bHRWYWx1ZTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1wiJyArIGFOYW1lICsgJ1wiIGlzIGEgcmVxdWlyZWQgYXJndW1lbnQuJyk7XG4gIH1cbn1cbmV4cG9ydHMuZ2V0QXJnID0gZ2V0QXJnO1xuXG52YXIgdXJsUmVnZXhwID0gL14oPzooW1xcdytcXC0uXSspOik/XFwvXFwvKD86KFxcdys6XFx3KylAKT8oW1xcdy5dKikoPzo6KFxcZCspKT8oXFxTKikkLztcbnZhciBkYXRhVXJsUmVnZXhwID0gL15kYXRhOi4rXFwsLiskLztcblxuZnVuY3Rpb24gdXJsUGFyc2UoYVVybCkge1xuICB2YXIgbWF0Y2ggPSBhVXJsLm1hdGNoKHVybFJlZ2V4cCk7XG4gIGlmICghbWF0Y2gpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICByZXR1cm4ge1xuICAgIHNjaGVtZTogbWF0Y2hbMV0sXG4gICAgYXV0aDogbWF0Y2hbMl0sXG4gICAgaG9zdDogbWF0Y2hbM10sXG4gICAgcG9ydDogbWF0Y2hbNF0sXG4gICAgcGF0aDogbWF0Y2hbNV1cbiAgfTtcbn1cbmV4cG9ydHMudXJsUGFyc2UgPSB1cmxQYXJzZTtcblxuZnVuY3Rpb24gdXJsR2VuZXJhdGUoYVBhcnNlZFVybCkge1xuICB2YXIgdXJsID0gJyc7XG4gIGlmIChhUGFyc2VkVXJsLnNjaGVtZSkge1xuICAgIHVybCArPSBhUGFyc2VkVXJsLnNjaGVtZSArICc6JztcbiAgfVxuICB1cmwgKz0gJy8vJztcbiAgaWYgKGFQYXJzZWRVcmwuYXV0aCkge1xuICAgIHVybCArPSBhUGFyc2VkVXJsLmF1dGggKyAnQCc7XG4gIH1cbiAgaWYgKGFQYXJzZWRVcmwuaG9zdCkge1xuICAgIHVybCArPSBhUGFyc2VkVXJsLmhvc3Q7XG4gIH1cbiAgaWYgKGFQYXJzZWRVcmwucG9ydCkge1xuICAgIHVybCArPSBcIjpcIiArIGFQYXJzZWRVcmwucG9ydFxuICB9XG4gIGlmIChhUGFyc2VkVXJsLnBhdGgpIHtcbiAgICB1cmwgKz0gYVBhcnNlZFVybC5wYXRoO1xuICB9XG4gIHJldHVybiB1cmw7XG59XG5leHBvcnRzLnVybEdlbmVyYXRlID0gdXJsR2VuZXJhdGU7XG5cbi8qKlxuICogTm9ybWFsaXplcyBhIHBhdGgsIG9yIHRoZSBwYXRoIHBvcnRpb24gb2YgYSBVUkw6XG4gKlxuICogLSBSZXBsYWNlcyBjb25zZXF1dGl2ZSBzbGFzaGVzIHdpdGggb25lIHNsYXNoLlxuICogLSBSZW1vdmVzIHVubmVjZXNzYXJ5ICcuJyBwYXJ0cy5cbiAqIC0gUmVtb3ZlcyB1bm5lY2Vzc2FyeSAnPGRpcj4vLi4nIHBhcnRzLlxuICpcbiAqIEJhc2VkIG9uIGNvZGUgaW4gdGhlIE5vZGUuanMgJ3BhdGgnIGNvcmUgbW9kdWxlLlxuICpcbiAqIEBwYXJhbSBhUGF0aCBUaGUgcGF0aCBvciB1cmwgdG8gbm9ybWFsaXplLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemUoYVBhdGgpIHtcbiAgdmFyIHBhdGggPSBhUGF0aDtcbiAgdmFyIHVybCA9IHVybFBhcnNlKGFQYXRoKTtcbiAgaWYgKHVybCkge1xuICAgIGlmICghdXJsLnBhdGgpIHtcbiAgICAgIHJldHVybiBhUGF0aDtcbiAgICB9XG4gICAgcGF0aCA9IHVybC5wYXRoO1xuICB9XG4gIHZhciBpc0Fic29sdXRlID0gZXhwb3J0cy5pc0Fic29sdXRlKHBhdGgpO1xuXG4gIHZhciBwYXJ0cyA9IHBhdGguc3BsaXQoL1xcLysvKTtcbiAgZm9yICh2YXIgcGFydCwgdXAgPSAwLCBpID0gcGFydHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBwYXJ0ID0gcGFydHNbaV07XG4gICAgaWYgKHBhcnQgPT09ICcuJykge1xuICAgICAgcGFydHMuc3BsaWNlKGksIDEpO1xuICAgIH0gZWxzZSBpZiAocGFydCA9PT0gJy4uJykge1xuICAgICAgdXArKztcbiAgICB9IGVsc2UgaWYgKHVwID4gMCkge1xuICAgICAgaWYgKHBhcnQgPT09ICcnKSB7XG4gICAgICAgIC8vIFRoZSBmaXJzdCBwYXJ0IGlzIGJsYW5rIGlmIHRoZSBwYXRoIGlzIGFic29sdXRlLiBUcnlpbmcgdG8gZ29cbiAgICAgICAgLy8gYWJvdmUgdGhlIHJvb3QgaXMgYSBuby1vcC4gVGhlcmVmb3JlIHdlIGNhbiByZW1vdmUgYWxsICcuLicgcGFydHNcbiAgICAgICAgLy8gZGlyZWN0bHkgYWZ0ZXIgdGhlIHJvb3QuXG4gICAgICAgIHBhcnRzLnNwbGljZShpICsgMSwgdXApO1xuICAgICAgICB1cCA9IDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXJ0cy5zcGxpY2UoaSwgMik7XG4gICAgICAgIHVwLS07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHBhdGggPSBwYXJ0cy5qb2luKCcvJyk7XG5cbiAgaWYgKHBhdGggPT09ICcnKSB7XG4gICAgcGF0aCA9IGlzQWJzb2x1dGUgPyAnLycgOiAnLic7XG4gIH1cblxuICBpZiAodXJsKSB7XG4gICAgdXJsLnBhdGggPSBwYXRoO1xuICAgIHJldHVybiB1cmxHZW5lcmF0ZSh1cmwpO1xuICB9XG4gIHJldHVybiBwYXRoO1xufVxuZXhwb3J0cy5ub3JtYWxpemUgPSBub3JtYWxpemU7XG5cbi8qKlxuICogSm9pbnMgdHdvIHBhdGhzL1VSTHMuXG4gKlxuICogQHBhcmFtIGFSb290IFRoZSByb290IHBhdGggb3IgVVJMLlxuICogQHBhcmFtIGFQYXRoIFRoZSBwYXRoIG9yIFVSTCB0byBiZSBqb2luZWQgd2l0aCB0aGUgcm9vdC5cbiAqXG4gKiAtIElmIGFQYXRoIGlzIGEgVVJMIG9yIGEgZGF0YSBVUkksIGFQYXRoIGlzIHJldHVybmVkLCB1bmxlc3MgYVBhdGggaXMgYVxuICogICBzY2hlbWUtcmVsYXRpdmUgVVJMOiBUaGVuIHRoZSBzY2hlbWUgb2YgYVJvb3QsIGlmIGFueSwgaXMgcHJlcGVuZGVkXG4gKiAgIGZpcnN0LlxuICogLSBPdGhlcndpc2UgYVBhdGggaXMgYSBwYXRoLiBJZiBhUm9vdCBpcyBhIFVSTCwgdGhlbiBpdHMgcGF0aCBwb3J0aW9uXG4gKiAgIGlzIHVwZGF0ZWQgd2l0aCB0aGUgcmVzdWx0IGFuZCBhUm9vdCBpcyByZXR1cm5lZC4gT3RoZXJ3aXNlIHRoZSByZXN1bHRcbiAqICAgaXMgcmV0dXJuZWQuXG4gKiAgIC0gSWYgYVBhdGggaXMgYWJzb2x1dGUsIHRoZSByZXN1bHQgaXMgYVBhdGguXG4gKiAgIC0gT3RoZXJ3aXNlIHRoZSB0d28gcGF0aHMgYXJlIGpvaW5lZCB3aXRoIGEgc2xhc2guXG4gKiAtIEpvaW5pbmcgZm9yIGV4YW1wbGUgJ2h0dHA6Ly8nIGFuZCAnd3d3LmV4YW1wbGUuY29tJyBpcyBhbHNvIHN1cHBvcnRlZC5cbiAqL1xuZnVuY3Rpb24gam9pbihhUm9vdCwgYVBhdGgpIHtcbiAgaWYgKGFSb290ID09PSBcIlwiKSB7XG4gICAgYVJvb3QgPSBcIi5cIjtcbiAgfVxuICBpZiAoYVBhdGggPT09IFwiXCIpIHtcbiAgICBhUGF0aCA9IFwiLlwiO1xuICB9XG4gIHZhciBhUGF0aFVybCA9IHVybFBhcnNlKGFQYXRoKTtcbiAgdmFyIGFSb290VXJsID0gdXJsUGFyc2UoYVJvb3QpO1xuICBpZiAoYVJvb3RVcmwpIHtcbiAgICBhUm9vdCA9IGFSb290VXJsLnBhdGggfHwgJy8nO1xuICB9XG5cbiAgLy8gYGpvaW4oZm9vLCAnLy93d3cuZXhhbXBsZS5vcmcnKWBcbiAgaWYgKGFQYXRoVXJsICYmICFhUGF0aFVybC5zY2hlbWUpIHtcbiAgICBpZiAoYVJvb3RVcmwpIHtcbiAgICAgIGFQYXRoVXJsLnNjaGVtZSA9IGFSb290VXJsLnNjaGVtZTtcbiAgICB9XG4gICAgcmV0dXJuIHVybEdlbmVyYXRlKGFQYXRoVXJsKTtcbiAgfVxuXG4gIGlmIChhUGF0aFVybCB8fCBhUGF0aC5tYXRjaChkYXRhVXJsUmVnZXhwKSkge1xuICAgIHJldHVybiBhUGF0aDtcbiAgfVxuXG4gIC8vIGBqb2luKCdodHRwOi8vJywgJ3d3dy5leGFtcGxlLmNvbScpYFxuICBpZiAoYVJvb3RVcmwgJiYgIWFSb290VXJsLmhvc3QgJiYgIWFSb290VXJsLnBhdGgpIHtcbiAgICBhUm9vdFVybC5ob3N0ID0gYVBhdGg7XG4gICAgcmV0dXJuIHVybEdlbmVyYXRlKGFSb290VXJsKTtcbiAgfVxuXG4gIHZhciBqb2luZWQgPSBhUGF0aC5jaGFyQXQoMCkgPT09ICcvJ1xuICAgID8gYVBhdGhcbiAgICA6IG5vcm1hbGl6ZShhUm9vdC5yZXBsYWNlKC9cXC8rJC8sICcnKSArICcvJyArIGFQYXRoKTtcblxuICBpZiAoYVJvb3RVcmwpIHtcbiAgICBhUm9vdFVybC5wYXRoID0gam9pbmVkO1xuICAgIHJldHVybiB1cmxHZW5lcmF0ZShhUm9vdFVybCk7XG4gIH1cbiAgcmV0dXJuIGpvaW5lZDtcbn1cbmV4cG9ydHMuam9pbiA9IGpvaW47XG5cbmV4cG9ydHMuaXNBYnNvbHV0ZSA9IGZ1bmN0aW9uIChhUGF0aCkge1xuICByZXR1cm4gYVBhdGguY2hhckF0KDApID09PSAnLycgfHwgISFhUGF0aC5tYXRjaCh1cmxSZWdleHApO1xufTtcblxuLyoqXG4gKiBNYWtlIGEgcGF0aCByZWxhdGl2ZSB0byBhIFVSTCBvciBhbm90aGVyIHBhdGguXG4gKlxuICogQHBhcmFtIGFSb290IFRoZSByb290IHBhdGggb3IgVVJMLlxuICogQHBhcmFtIGFQYXRoIFRoZSBwYXRoIG9yIFVSTCB0byBiZSBtYWRlIHJlbGF0aXZlIHRvIGFSb290LlxuICovXG5mdW5jdGlvbiByZWxhdGl2ZShhUm9vdCwgYVBhdGgpIHtcbiAgaWYgKGFSb290ID09PSBcIlwiKSB7XG4gICAgYVJvb3QgPSBcIi5cIjtcbiAgfVxuXG4gIGFSb290ID0gYVJvb3QucmVwbGFjZSgvXFwvJC8sICcnKTtcblxuICAvLyBJdCBpcyBwb3NzaWJsZSBmb3IgdGhlIHBhdGggdG8gYmUgYWJvdmUgdGhlIHJvb3QuIEluIHRoaXMgY2FzZSwgc2ltcGx5XG4gIC8vIGNoZWNraW5nIHdoZXRoZXIgdGhlIHJvb3QgaXMgYSBwcmVmaXggb2YgdGhlIHBhdGggd29uJ3Qgd29yay4gSW5zdGVhZCwgd2VcbiAgLy8gbmVlZCB0byByZW1vdmUgY29tcG9uZW50cyBmcm9tIHRoZSByb290IG9uZSBieSBvbmUsIHVudGlsIGVpdGhlciB3ZSBmaW5kXG4gIC8vIGEgcHJlZml4IHRoYXQgZml0cywgb3Igd2UgcnVuIG91dCBvZiBjb21wb25lbnRzIHRvIHJlbW92ZS5cbiAgdmFyIGxldmVsID0gMDtcbiAgd2hpbGUgKGFQYXRoLmluZGV4T2YoYVJvb3QgKyAnLycpICE9PSAwKSB7XG4gICAgdmFyIGluZGV4ID0gYVJvb3QubGFzdEluZGV4T2YoXCIvXCIpO1xuICAgIGlmIChpbmRleCA8IDApIHtcbiAgICAgIHJldHVybiBhUGF0aDtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgb25seSBwYXJ0IG9mIHRoZSByb290IHRoYXQgaXMgbGVmdCBpcyB0aGUgc2NoZW1lIChpLmUuIGh0dHA6Ly8sXG4gICAgLy8gZmlsZTovLy8sIGV0Yy4pLCBvbmUgb3IgbW9yZSBzbGFzaGVzICgvKSwgb3Igc2ltcGx5IG5vdGhpbmcgYXQgYWxsLCB3ZVxuICAgIC8vIGhhdmUgZXhoYXVzdGVkIGFsbCBjb21wb25lbnRzLCBzbyB0aGUgcGF0aCBpcyBub3QgcmVsYXRpdmUgdG8gdGhlIHJvb3QuXG4gICAgYVJvb3QgPSBhUm9vdC5zbGljZSgwLCBpbmRleCk7XG4gICAgaWYgKGFSb290Lm1hdGNoKC9eKFteXFwvXSs6XFwvKT9cXC8qJC8pKSB7XG4gICAgICByZXR1cm4gYVBhdGg7XG4gICAgfVxuXG4gICAgKytsZXZlbDtcbiAgfVxuXG4gIC8vIE1ha2Ugc3VyZSB3ZSBhZGQgYSBcIi4uL1wiIGZvciBlYWNoIGNvbXBvbmVudCB3ZSByZW1vdmVkIGZyb20gdGhlIHJvb3QuXG4gIHJldHVybiBBcnJheShsZXZlbCArIDEpLmpvaW4oXCIuLi9cIikgKyBhUGF0aC5zdWJzdHIoYVJvb3QubGVuZ3RoICsgMSk7XG59XG5leHBvcnRzLnJlbGF0aXZlID0gcmVsYXRpdmU7XG5cbnZhciBzdXBwb3J0c051bGxQcm90byA9IChmdW5jdGlvbiAoKSB7XG4gIHZhciBvYmogPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICByZXR1cm4gISgnX19wcm90b19fJyBpbiBvYmopO1xufSgpKTtcblxuZnVuY3Rpb24gaWRlbnRpdHkgKHMpIHtcbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogQmVjYXVzZSBiZWhhdmlvciBnb2VzIHdhY2t5IHdoZW4geW91IHNldCBgX19wcm90b19fYCBvbiBvYmplY3RzLCB3ZVxuICogaGF2ZSB0byBwcmVmaXggYWxsIHRoZSBzdHJpbmdzIGluIG91ciBzZXQgd2l0aCBhbiBhcmJpdHJhcnkgY2hhcmFjdGVyLlxuICpcbiAqIFNlZSBodHRwczovL2dpdGh1Yi5jb20vbW96aWxsYS9zb3VyY2UtbWFwL3B1bGwvMzEgYW5kXG4gKiBodHRwczovL2dpdGh1Yi5jb20vbW96aWxsYS9zb3VyY2UtbWFwL2lzc3Vlcy8zMFxuICpcbiAqIEBwYXJhbSBTdHJpbmcgYVN0clxuICovXG5mdW5jdGlvbiB0b1NldFN0cmluZyhhU3RyKSB7XG4gIGlmIChpc1Byb3RvU3RyaW5nKGFTdHIpKSB7XG4gICAgcmV0dXJuICckJyArIGFTdHI7XG4gIH1cblxuICByZXR1cm4gYVN0cjtcbn1cbmV4cG9ydHMudG9TZXRTdHJpbmcgPSBzdXBwb3J0c051bGxQcm90byA/IGlkZW50aXR5IDogdG9TZXRTdHJpbmc7XG5cbmZ1bmN0aW9uIGZyb21TZXRTdHJpbmcoYVN0cikge1xuICBpZiAoaXNQcm90b1N0cmluZyhhU3RyKSkge1xuICAgIHJldHVybiBhU3RyLnNsaWNlKDEpO1xuICB9XG5cbiAgcmV0dXJuIGFTdHI7XG59XG5leHBvcnRzLmZyb21TZXRTdHJpbmcgPSBzdXBwb3J0c051bGxQcm90byA/IGlkZW50aXR5IDogZnJvbVNldFN0cmluZztcblxuZnVuY3Rpb24gaXNQcm90b1N0cmluZyhzKSB7XG4gIGlmICghcykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBsZW5ndGggPSBzLmxlbmd0aDtcblxuICBpZiAobGVuZ3RoIDwgOSAvKiBcIl9fcHJvdG9fX1wiLmxlbmd0aCAqLykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChzLmNoYXJDb2RlQXQobGVuZ3RoIC0gMSkgIT09IDk1ICAvKiAnXycgKi8gfHxcbiAgICAgIHMuY2hhckNvZGVBdChsZW5ndGggLSAyKSAhPT0gOTUgIC8qICdfJyAqLyB8fFxuICAgICAgcy5jaGFyQ29kZUF0KGxlbmd0aCAtIDMpICE9PSAxMTEgLyogJ28nICovIHx8XG4gICAgICBzLmNoYXJDb2RlQXQobGVuZ3RoIC0gNCkgIT09IDExNiAvKiAndCcgKi8gfHxcbiAgICAgIHMuY2hhckNvZGVBdChsZW5ndGggLSA1KSAhPT0gMTExIC8qICdvJyAqLyB8fFxuICAgICAgcy5jaGFyQ29kZUF0KGxlbmd0aCAtIDYpICE9PSAxMTQgLyogJ3InICovIHx8XG4gICAgICBzLmNoYXJDb2RlQXQobGVuZ3RoIC0gNykgIT09IDExMiAvKiAncCcgKi8gfHxcbiAgICAgIHMuY2hhckNvZGVBdChsZW5ndGggLSA4KSAhPT0gOTUgIC8qICdfJyAqLyB8fFxuICAgICAgcy5jaGFyQ29kZUF0KGxlbmd0aCAtIDkpICE9PSA5NSAgLyogJ18nICovKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZm9yICh2YXIgaSA9IGxlbmd0aCAtIDEwOyBpID49IDA7IGktLSkge1xuICAgIGlmIChzLmNoYXJDb2RlQXQoaSkgIT09IDM2IC8qICckJyAqLykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIENvbXBhcmF0b3IgYmV0d2VlbiB0d28gbWFwcGluZ3Mgd2hlcmUgdGhlIG9yaWdpbmFsIHBvc2l0aW9ucyBhcmUgY29tcGFyZWQuXG4gKlxuICogT3B0aW9uYWxseSBwYXNzIGluIGB0cnVlYCBhcyBgb25seUNvbXBhcmVHZW5lcmF0ZWRgIHRvIGNvbnNpZGVyIHR3b1xuICogbWFwcGluZ3Mgd2l0aCB0aGUgc2FtZSBvcmlnaW5hbCBzb3VyY2UvbGluZS9jb2x1bW4sIGJ1dCBkaWZmZXJlbnQgZ2VuZXJhdGVkXG4gKiBsaW5lIGFuZCBjb2x1bW4gdGhlIHNhbWUuIFVzZWZ1bCB3aGVuIHNlYXJjaGluZyBmb3IgYSBtYXBwaW5nIHdpdGggYVxuICogc3R1YmJlZCBvdXQgbWFwcGluZy5cbiAqL1xuZnVuY3Rpb24gY29tcGFyZUJ5T3JpZ2luYWxQb3NpdGlvbnMobWFwcGluZ0EsIG1hcHBpbmdCLCBvbmx5Q29tcGFyZU9yaWdpbmFsKSB7XG4gIHZhciBjbXAgPSBtYXBwaW5nQS5zb3VyY2UgLSBtYXBwaW5nQi5zb3VyY2U7XG4gIGlmIChjbXAgIT09IDApIHtcbiAgICByZXR1cm4gY21wO1xuICB9XG5cbiAgY21wID0gbWFwcGluZ0Eub3JpZ2luYWxMaW5lIC0gbWFwcGluZ0Iub3JpZ2luYWxMaW5lO1xuICBpZiAoY21wICE9PSAwKSB7XG4gICAgcmV0dXJuIGNtcDtcbiAgfVxuXG4gIGNtcCA9IG1hcHBpbmdBLm9yaWdpbmFsQ29sdW1uIC0gbWFwcGluZ0Iub3JpZ2luYWxDb2x1bW47XG4gIGlmIChjbXAgIT09IDAgfHwgb25seUNvbXBhcmVPcmlnaW5hbCkge1xuICAgIHJldHVybiBjbXA7XG4gIH1cblxuICBjbXAgPSBtYXBwaW5nQS5nZW5lcmF0ZWRDb2x1bW4gLSBtYXBwaW5nQi5nZW5lcmF0ZWRDb2x1bW47XG4gIGlmIChjbXAgIT09IDApIHtcbiAgICByZXR1cm4gY21wO1xuICB9XG5cbiAgY21wID0gbWFwcGluZ0EuZ2VuZXJhdGVkTGluZSAtIG1hcHBpbmdCLmdlbmVyYXRlZExpbmU7XG4gIGlmIChjbXAgIT09IDApIHtcbiAgICByZXR1cm4gY21wO1xuICB9XG5cbiAgcmV0dXJuIG1hcHBpbmdBLm5hbWUgLSBtYXBwaW5nQi5uYW1lO1xufVxuZXhwb3J0cy5jb21wYXJlQnlPcmlnaW5hbFBvc2l0aW9ucyA9IGNvbXBhcmVCeU9yaWdpbmFsUG9zaXRpb25zO1xuXG4vKipcbiAqIENvbXBhcmF0b3IgYmV0d2VlbiB0d28gbWFwcGluZ3Mgd2l0aCBkZWZsYXRlZCBzb3VyY2UgYW5kIG5hbWUgaW5kaWNlcyB3aGVyZVxuICogdGhlIGdlbmVyYXRlZCBwb3NpdGlvbnMgYXJlIGNvbXBhcmVkLlxuICpcbiAqIE9wdGlvbmFsbHkgcGFzcyBpbiBgdHJ1ZWAgYXMgYG9ubHlDb21wYXJlR2VuZXJhdGVkYCB0byBjb25zaWRlciB0d29cbiAqIG1hcHBpbmdzIHdpdGggdGhlIHNhbWUgZ2VuZXJhdGVkIGxpbmUgYW5kIGNvbHVtbiwgYnV0IGRpZmZlcmVudFxuICogc291cmNlL25hbWUvb3JpZ2luYWwgbGluZSBhbmQgY29sdW1uIHRoZSBzYW1lLiBVc2VmdWwgd2hlbiBzZWFyY2hpbmcgZm9yIGFcbiAqIG1hcHBpbmcgd2l0aCBhIHN0dWJiZWQgb3V0IG1hcHBpbmcuXG4gKi9cbmZ1bmN0aW9uIGNvbXBhcmVCeUdlbmVyYXRlZFBvc2l0aW9uc0RlZmxhdGVkKG1hcHBpbmdBLCBtYXBwaW5nQiwgb25seUNvbXBhcmVHZW5lcmF0ZWQpIHtcbiAgdmFyIGNtcCA9IG1hcHBpbmdBLmdlbmVyYXRlZExpbmUgLSBtYXBwaW5nQi5nZW5lcmF0ZWRMaW5lO1xuICBpZiAoY21wICE9PSAwKSB7XG4gICAgcmV0dXJuIGNtcDtcbiAgfVxuXG4gIGNtcCA9IG1hcHBpbmdBLmdlbmVyYXRlZENvbHVtbiAtIG1hcHBpbmdCLmdlbmVyYXRlZENvbHVtbjtcbiAgaWYgKGNtcCAhPT0gMCB8fCBvbmx5Q29tcGFyZUdlbmVyYXRlZCkge1xuICAgIHJldHVybiBjbXA7XG4gIH1cblxuICBjbXAgPSBtYXBwaW5nQS5zb3VyY2UgLSBtYXBwaW5nQi5zb3VyY2U7XG4gIGlmIChjbXAgIT09IDApIHtcbiAgICByZXR1cm4gY21wO1xuICB9XG5cbiAgY21wID0gbWFwcGluZ0Eub3JpZ2luYWxMaW5lIC0gbWFwcGluZ0Iub3JpZ2luYWxMaW5lO1xuICBpZiAoY21wICE9PSAwKSB7XG4gICAgcmV0dXJuIGNtcDtcbiAgfVxuXG4gIGNtcCA9IG1hcHBpbmdBLm9yaWdpbmFsQ29sdW1uIC0gbWFwcGluZ0Iub3JpZ2luYWxDb2x1bW47XG4gIGlmIChjbXAgIT09IDApIHtcbiAgICByZXR1cm4gY21wO1xuICB9XG5cbiAgcmV0dXJuIG1hcHBpbmdBLm5hbWUgLSBtYXBwaW5nQi5uYW1lO1xufVxuZXhwb3J0cy5jb21wYXJlQnlHZW5lcmF0ZWRQb3NpdGlvbnNEZWZsYXRlZCA9IGNvbXBhcmVCeUdlbmVyYXRlZFBvc2l0aW9uc0RlZmxhdGVkO1xuXG5mdW5jdGlvbiBzdHJjbXAoYVN0cjEsIGFTdHIyKSB7XG4gIGlmIChhU3RyMSA9PT0gYVN0cjIpIHtcbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIGlmIChhU3RyMSA+IGFTdHIyKSB7XG4gICAgcmV0dXJuIDE7XG4gIH1cblxuICByZXR1cm4gLTE7XG59XG5cbi8qKlxuICogQ29tcGFyYXRvciBiZXR3ZWVuIHR3byBtYXBwaW5ncyB3aXRoIGluZmxhdGVkIHNvdXJjZSBhbmQgbmFtZSBzdHJpbmdzIHdoZXJlXG4gKiB0aGUgZ2VuZXJhdGVkIHBvc2l0aW9ucyBhcmUgY29tcGFyZWQuXG4gKi9cbmZ1bmN0aW9uIGNvbXBhcmVCeUdlbmVyYXRlZFBvc2l0aW9uc0luZmxhdGVkKG1hcHBpbmdBLCBtYXBwaW5nQikge1xuICB2YXIgY21wID0gbWFwcGluZ0EuZ2VuZXJhdGVkTGluZSAtIG1hcHBpbmdCLmdlbmVyYXRlZExpbmU7XG4gIGlmIChjbXAgIT09IDApIHtcbiAgICByZXR1cm4gY21wO1xuICB9XG5cbiAgY21wID0gbWFwcGluZ0EuZ2VuZXJhdGVkQ29sdW1uIC0gbWFwcGluZ0IuZ2VuZXJhdGVkQ29sdW1uO1xuICBpZiAoY21wICE9PSAwKSB7XG4gICAgcmV0dXJuIGNtcDtcbiAgfVxuXG4gIGNtcCA9IHN0cmNtcChtYXBwaW5nQS5zb3VyY2UsIG1hcHBpbmdCLnNvdXJjZSk7XG4gIGlmIChjbXAgIT09IDApIHtcbiAgICByZXR1cm4gY21wO1xuICB9XG5cbiAgY21wID0gbWFwcGluZ0Eub3JpZ2luYWxMaW5lIC0gbWFwcGluZ0Iub3JpZ2luYWxMaW5lO1xuICBpZiAoY21wICE9PSAwKSB7XG4gICAgcmV0dXJuIGNtcDtcbiAgfVxuXG4gIGNtcCA9IG1hcHBpbmdBLm9yaWdpbmFsQ29sdW1uIC0gbWFwcGluZ0Iub3JpZ2luYWxDb2x1bW47XG4gIGlmIChjbXAgIT09IDApIHtcbiAgICByZXR1cm4gY21wO1xuICB9XG5cbiAgcmV0dXJuIHN0cmNtcChtYXBwaW5nQS5uYW1lLCBtYXBwaW5nQi5uYW1lKTtcbn1cbmV4cG9ydHMuY29tcGFyZUJ5R2VuZXJhdGVkUG9zaXRpb25zSW5mbGF0ZWQgPSBjb21wYXJlQnlHZW5lcmF0ZWRQb3NpdGlvbnNJbmZsYXRlZDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9saWIvdXRpbC5qc1xuICoqIG1vZHVsZSBpZCA9IDRcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qIC0qLSBNb2RlOiBqczsganMtaW5kZW50LWxldmVsOiAyOyAtKi0gKi9cbi8qXG4gKiBDb3B5cmlnaHQgMjAxMSBNb3ppbGxhIEZvdW5kYXRpb24gYW5kIGNvbnRyaWJ1dG9yc1xuICogTGljZW5zZWQgdW5kZXIgdGhlIE5ldyBCU0QgbGljZW5zZS4gU2VlIExJQ0VOU0Ugb3I6XG4gKiBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvQlNELTMtQ2xhdXNlXG4gKi9cblxudmFyIHV0aWwgPSByZXF1aXJlKCcuL3V0aWwnKTtcbnZhciBoYXMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIEEgZGF0YSBzdHJ1Y3R1cmUgd2hpY2ggaXMgYSBjb21iaW5hdGlvbiBvZiBhbiBhcnJheSBhbmQgYSBzZXQuIEFkZGluZyBhIG5ld1xuICogbWVtYmVyIGlzIE8oMSksIHRlc3RpbmcgZm9yIG1lbWJlcnNoaXAgaXMgTygxKSwgYW5kIGZpbmRpbmcgdGhlIGluZGV4IG9mIGFuXG4gKiBlbGVtZW50IGlzIE8oMSkuIFJlbW92aW5nIGVsZW1lbnRzIGZyb20gdGhlIHNldCBpcyBub3Qgc3VwcG9ydGVkLiBPbmx5XG4gKiBzdHJpbmdzIGFyZSBzdXBwb3J0ZWQgZm9yIG1lbWJlcnNoaXAuXG4gKi9cbmZ1bmN0aW9uIEFycmF5U2V0KCkge1xuICB0aGlzLl9hcnJheSA9IFtdO1xuICB0aGlzLl9zZXQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xufVxuXG4vKipcbiAqIFN0YXRpYyBtZXRob2QgZm9yIGNyZWF0aW5nIEFycmF5U2V0IGluc3RhbmNlcyBmcm9tIGFuIGV4aXN0aW5nIGFycmF5LlxuICovXG5BcnJheVNldC5mcm9tQXJyYXkgPSBmdW5jdGlvbiBBcnJheVNldF9mcm9tQXJyYXkoYUFycmF5LCBhQWxsb3dEdXBsaWNhdGVzKSB7XG4gIHZhciBzZXQgPSBuZXcgQXJyYXlTZXQoKTtcbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGFBcnJheS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIHNldC5hZGQoYUFycmF5W2ldLCBhQWxsb3dEdXBsaWNhdGVzKTtcbiAgfVxuICByZXR1cm4gc2V0O1xufTtcblxuLyoqXG4gKiBSZXR1cm4gaG93IG1hbnkgdW5pcXVlIGl0ZW1zIGFyZSBpbiB0aGlzIEFycmF5U2V0LiBJZiBkdXBsaWNhdGVzIGhhdmUgYmVlblxuICogYWRkZWQsIHRoYW4gdGhvc2UgZG8gbm90IGNvdW50IHRvd2FyZHMgdGhlIHNpemUuXG4gKlxuICogQHJldHVybnMgTnVtYmVyXG4gKi9cbkFycmF5U2V0LnByb3RvdHlwZS5zaXplID0gZnVuY3Rpb24gQXJyYXlTZXRfc2l6ZSgpIHtcbiAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRoaXMuX3NldCkubGVuZ3RoO1xufTtcblxuLyoqXG4gKiBBZGQgdGhlIGdpdmVuIHN0cmluZyB0byB0aGlzIHNldC5cbiAqXG4gKiBAcGFyYW0gU3RyaW5nIGFTdHJcbiAqL1xuQXJyYXlTZXQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIEFycmF5U2V0X2FkZChhU3RyLCBhQWxsb3dEdXBsaWNhdGVzKSB7XG4gIHZhciBzU3RyID0gdXRpbC50b1NldFN0cmluZyhhU3RyKTtcbiAgdmFyIGlzRHVwbGljYXRlID0gaGFzLmNhbGwodGhpcy5fc2V0LCBzU3RyKTtcbiAgdmFyIGlkeCA9IHRoaXMuX2FycmF5Lmxlbmd0aDtcbiAgaWYgKCFpc0R1cGxpY2F0ZSB8fCBhQWxsb3dEdXBsaWNhdGVzKSB7XG4gICAgdGhpcy5fYXJyYXkucHVzaChhU3RyKTtcbiAgfVxuICBpZiAoIWlzRHVwbGljYXRlKSB7XG4gICAgdGhpcy5fc2V0W3NTdHJdID0gaWR4O1xuICB9XG59O1xuXG4vKipcbiAqIElzIHRoZSBnaXZlbiBzdHJpbmcgYSBtZW1iZXIgb2YgdGhpcyBzZXQ/XG4gKlxuICogQHBhcmFtIFN0cmluZyBhU3RyXG4gKi9cbkFycmF5U2V0LnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiBBcnJheVNldF9oYXMoYVN0cikge1xuICB2YXIgc1N0ciA9IHV0aWwudG9TZXRTdHJpbmcoYVN0cik7XG4gIHJldHVybiBoYXMuY2FsbCh0aGlzLl9zZXQsIHNTdHIpO1xufTtcblxuLyoqXG4gKiBXaGF0IGlzIHRoZSBpbmRleCBvZiB0aGUgZ2l2ZW4gc3RyaW5nIGluIHRoZSBhcnJheT9cbiAqXG4gKiBAcGFyYW0gU3RyaW5nIGFTdHJcbiAqL1xuQXJyYXlTZXQucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbiBBcnJheVNldF9pbmRleE9mKGFTdHIpIHtcbiAgdmFyIHNTdHIgPSB1dGlsLnRvU2V0U3RyaW5nKGFTdHIpO1xuICBpZiAoaGFzLmNhbGwodGhpcy5fc2V0LCBzU3RyKSkge1xuICAgIHJldHVybiB0aGlzLl9zZXRbc1N0cl07XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKCdcIicgKyBhU3RyICsgJ1wiIGlzIG5vdCBpbiB0aGUgc2V0LicpO1xufTtcblxuLyoqXG4gKiBXaGF0IGlzIHRoZSBlbGVtZW50IGF0IHRoZSBnaXZlbiBpbmRleD9cbiAqXG4gKiBAcGFyYW0gTnVtYmVyIGFJZHhcbiAqL1xuQXJyYXlTZXQucHJvdG90eXBlLmF0ID0gZnVuY3Rpb24gQXJyYXlTZXRfYXQoYUlkeCkge1xuICBpZiAoYUlkeCA+PSAwICYmIGFJZHggPCB0aGlzLl9hcnJheS5sZW5ndGgpIHtcbiAgICByZXR1cm4gdGhpcy5fYXJyYXlbYUlkeF07XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKCdObyBlbGVtZW50IGluZGV4ZWQgYnkgJyArIGFJZHgpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBhcnJheSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHNldCAod2hpY2ggaGFzIHRoZSBwcm9wZXIgaW5kaWNlc1xuICogaW5kaWNhdGVkIGJ5IGluZGV4T2YpLiBOb3RlIHRoYXQgdGhpcyBpcyBhIGNvcHkgb2YgdGhlIGludGVybmFsIGFycmF5IHVzZWRcbiAqIGZvciBzdG9yaW5nIHRoZSBtZW1iZXJzIHNvIHRoYXQgbm8gb25lIGNhbiBtZXNzIHdpdGggaW50ZXJuYWwgc3RhdGUuXG4gKi9cbkFycmF5U2V0LnByb3RvdHlwZS50b0FycmF5ID0gZnVuY3Rpb24gQXJyYXlTZXRfdG9BcnJheSgpIHtcbiAgcmV0dXJuIHRoaXMuX2FycmF5LnNsaWNlKCk7XG59O1xuXG5leHBvcnRzLkFycmF5U2V0ID0gQXJyYXlTZXQ7XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vbGliL2FycmF5LXNldC5qc1xuICoqIG1vZHVsZSBpZCA9IDVcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qIC0qLSBNb2RlOiBqczsganMtaW5kZW50LWxldmVsOiAyOyAtKi0gKi9cbi8qXG4gKiBDb3B5cmlnaHQgMjAxNCBNb3ppbGxhIEZvdW5kYXRpb24gYW5kIGNvbnRyaWJ1dG9yc1xuICogTGljZW5zZWQgdW5kZXIgdGhlIE5ldyBCU0QgbGljZW5zZS4gU2VlIExJQ0VOU0Ugb3I6XG4gKiBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvQlNELTMtQ2xhdXNlXG4gKi9cblxudmFyIHV0aWwgPSByZXF1aXJlKCcuL3V0aWwnKTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciBtYXBwaW5nQiBpcyBhZnRlciBtYXBwaW5nQSB3aXRoIHJlc3BlY3QgdG8gZ2VuZXJhdGVkXG4gKiBwb3NpdGlvbi5cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVkUG9zaXRpb25BZnRlcihtYXBwaW5nQSwgbWFwcGluZ0IpIHtcbiAgLy8gT3B0aW1pemVkIGZvciBtb3N0IGNvbW1vbiBjYXNlXG4gIHZhciBsaW5lQSA9IG1hcHBpbmdBLmdlbmVyYXRlZExpbmU7XG4gIHZhciBsaW5lQiA9IG1hcHBpbmdCLmdlbmVyYXRlZExpbmU7XG4gIHZhciBjb2x1bW5BID0gbWFwcGluZ0EuZ2VuZXJhdGVkQ29sdW1uO1xuICB2YXIgY29sdW1uQiA9IG1hcHBpbmdCLmdlbmVyYXRlZENvbHVtbjtcbiAgcmV0dXJuIGxpbmVCID4gbGluZUEgfHwgbGluZUIgPT0gbGluZUEgJiYgY29sdW1uQiA+PSBjb2x1bW5BIHx8XG4gICAgICAgICB1dGlsLmNvbXBhcmVCeUdlbmVyYXRlZFBvc2l0aW9uc0luZmxhdGVkKG1hcHBpbmdBLCBtYXBwaW5nQikgPD0gMDtcbn1cblxuLyoqXG4gKiBBIGRhdGEgc3RydWN0dXJlIHRvIHByb3ZpZGUgYSBzb3J0ZWQgdmlldyBvZiBhY2N1bXVsYXRlZCBtYXBwaW5ncyBpbiBhXG4gKiBwZXJmb3JtYW5jZSBjb25zY2lvdXMgbWFubmVyLiBJdCB0cmFkZXMgYSBuZWdsaWJhYmxlIG92ZXJoZWFkIGluIGdlbmVyYWxcbiAqIGNhc2UgZm9yIGEgbGFyZ2Ugc3BlZWR1cCBpbiBjYXNlIG9mIG1hcHBpbmdzIGJlaW5nIGFkZGVkIGluIG9yZGVyLlxuICovXG5mdW5jdGlvbiBNYXBwaW5nTGlzdCgpIHtcbiAgdGhpcy5fYXJyYXkgPSBbXTtcbiAgdGhpcy5fc29ydGVkID0gdHJ1ZTtcbiAgLy8gU2VydmVzIGFzIGluZmltdW1cbiAgdGhpcy5fbGFzdCA9IHtnZW5lcmF0ZWRMaW5lOiAtMSwgZ2VuZXJhdGVkQ29sdW1uOiAwfTtcbn1cblxuLyoqXG4gKiBJdGVyYXRlIHRocm91Z2ggaW50ZXJuYWwgaXRlbXMuIFRoaXMgbWV0aG9kIHRha2VzIHRoZSBzYW1lIGFyZ3VtZW50cyB0aGF0XG4gKiBgQXJyYXkucHJvdG90eXBlLmZvckVhY2hgIHRha2VzLlxuICpcbiAqIE5PVEU6IFRoZSBvcmRlciBvZiB0aGUgbWFwcGluZ3MgaXMgTk9UIGd1YXJhbnRlZWQuXG4gKi9cbk1hcHBpbmdMaXN0LnByb3RvdHlwZS51bnNvcnRlZEZvckVhY2ggPVxuICBmdW5jdGlvbiBNYXBwaW5nTGlzdF9mb3JFYWNoKGFDYWxsYmFjaywgYVRoaXNBcmcpIHtcbiAgICB0aGlzLl9hcnJheS5mb3JFYWNoKGFDYWxsYmFjaywgYVRoaXNBcmcpO1xuICB9O1xuXG4vKipcbiAqIEFkZCB0aGUgZ2l2ZW4gc291cmNlIG1hcHBpbmcuXG4gKlxuICogQHBhcmFtIE9iamVjdCBhTWFwcGluZ1xuICovXG5NYXBwaW5nTGlzdC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gTWFwcGluZ0xpc3RfYWRkKGFNYXBwaW5nKSB7XG4gIGlmIChnZW5lcmF0ZWRQb3NpdGlvbkFmdGVyKHRoaXMuX2xhc3QsIGFNYXBwaW5nKSkge1xuICAgIHRoaXMuX2xhc3QgPSBhTWFwcGluZztcbiAgICB0aGlzLl9hcnJheS5wdXNoKGFNYXBwaW5nKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLl9zb3J0ZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9hcnJheS5wdXNoKGFNYXBwaW5nKTtcbiAgfVxufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBmbGF0LCBzb3J0ZWQgYXJyYXkgb2YgbWFwcGluZ3MuIFRoZSBtYXBwaW5ncyBhcmUgc29ydGVkIGJ5XG4gKiBnZW5lcmF0ZWQgcG9zaXRpb24uXG4gKlxuICogV0FSTklORzogVGhpcyBtZXRob2QgcmV0dXJucyBpbnRlcm5hbCBkYXRhIHdpdGhvdXQgY29weWluZywgZm9yXG4gKiBwZXJmb3JtYW5jZS4gVGhlIHJldHVybiB2YWx1ZSBtdXN0IE5PVCBiZSBtdXRhdGVkLCBhbmQgc2hvdWxkIGJlIHRyZWF0ZWQgYXNcbiAqIGFuIGltbXV0YWJsZSBib3Jyb3cuIElmIHlvdSB3YW50IHRvIHRha2Ugb3duZXJzaGlwLCB5b3UgbXVzdCBtYWtlIHlvdXIgb3duXG4gKiBjb3B5LlxuICovXG5NYXBwaW5nTGlzdC5wcm90b3R5cGUudG9BcnJheSA9IGZ1bmN0aW9uIE1hcHBpbmdMaXN0X3RvQXJyYXkoKSB7XG4gIGlmICghdGhpcy5fc29ydGVkKSB7XG4gICAgdGhpcy5fYXJyYXkuc29ydCh1dGlsLmNvbXBhcmVCeUdlbmVyYXRlZFBvc2l0aW9uc0luZmxhdGVkKTtcbiAgICB0aGlzLl9zb3J0ZWQgPSB0cnVlO1xuICB9XG4gIHJldHVybiB0aGlzLl9hcnJheTtcbn07XG5cbmV4cG9ydHMuTWFwcGluZ0xpc3QgPSBNYXBwaW5nTGlzdDtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9saWIvbWFwcGluZy1saXN0LmpzXG4gKiogbW9kdWxlIGlkID0gNlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyogLSotIE1vZGU6IGpzOyBqcy1pbmRlbnQtbGV2ZWw6IDI7IC0qLSAqL1xuLypcbiAqIENvcHlyaWdodCAyMDExIE1vemlsbGEgRm91bmRhdGlvbiBhbmQgY29udHJpYnV0b3JzXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTmV3IEJTRCBsaWNlbnNlLiBTZWUgTElDRU5TRSBvcjpcbiAqIGh0dHA6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9CU0QtMy1DbGF1c2VcbiAqL1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4vdXRpbCcpO1xudmFyIGJpbmFyeVNlYXJjaCA9IHJlcXVpcmUoJy4vYmluYXJ5LXNlYXJjaCcpO1xudmFyIEFycmF5U2V0ID0gcmVxdWlyZSgnLi9hcnJheS1zZXQnKS5BcnJheVNldDtcbnZhciBiYXNlNjRWTFEgPSByZXF1aXJlKCcuL2Jhc2U2NC12bHEnKTtcbnZhciBxdWlja1NvcnQgPSByZXF1aXJlKCcuL3F1aWNrLXNvcnQnKS5xdWlja1NvcnQ7XG5cbmZ1bmN0aW9uIFNvdXJjZU1hcENvbnN1bWVyKGFTb3VyY2VNYXApIHtcbiAgdmFyIHNvdXJjZU1hcCA9IGFTb3VyY2VNYXA7XG4gIGlmICh0eXBlb2YgYVNvdXJjZU1hcCA9PT0gJ3N0cmluZycpIHtcbiAgICBzb3VyY2VNYXAgPSBKU09OLnBhcnNlKGFTb3VyY2VNYXAucmVwbGFjZSgvXlxcKVxcXVxcfScvLCAnJykpO1xuICB9XG5cbiAgcmV0dXJuIHNvdXJjZU1hcC5zZWN0aW9ucyAhPSBudWxsXG4gICAgPyBuZXcgSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyKHNvdXJjZU1hcClcbiAgICA6IG5ldyBCYXNpY1NvdXJjZU1hcENvbnN1bWVyKHNvdXJjZU1hcCk7XG59XG5cblNvdXJjZU1hcENvbnN1bWVyLmZyb21Tb3VyY2VNYXAgPSBmdW5jdGlvbihhU291cmNlTWFwKSB7XG4gIHJldHVybiBCYXNpY1NvdXJjZU1hcENvbnN1bWVyLmZyb21Tb3VyY2VNYXAoYVNvdXJjZU1hcCk7XG59XG5cbi8qKlxuICogVGhlIHZlcnNpb24gb2YgdGhlIHNvdXJjZSBtYXBwaW5nIHNwZWMgdGhhdCB3ZSBhcmUgY29uc3VtaW5nLlxuICovXG5Tb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUuX3ZlcnNpb24gPSAzO1xuXG4vLyBgX19nZW5lcmF0ZWRNYXBwaW5nc2AgYW5kIGBfX29yaWdpbmFsTWFwcGluZ3NgIGFyZSBhcnJheXMgdGhhdCBob2xkIHRoZVxuLy8gcGFyc2VkIG1hcHBpbmcgY29vcmRpbmF0ZXMgZnJvbSB0aGUgc291cmNlIG1hcCdzIFwibWFwcGluZ3NcIiBhdHRyaWJ1dGUuIFRoZXlcbi8vIGFyZSBsYXppbHkgaW5zdGFudGlhdGVkLCBhY2Nlc3NlZCB2aWEgdGhlIGBfZ2VuZXJhdGVkTWFwcGluZ3NgIGFuZFxuLy8gYF9vcmlnaW5hbE1hcHBpbmdzYCBnZXR0ZXJzIHJlc3BlY3RpdmVseSwgYW5kIHdlIG9ubHkgcGFyc2UgdGhlIG1hcHBpbmdzXG4vLyBhbmQgY3JlYXRlIHRoZXNlIGFycmF5cyBvbmNlIHF1ZXJpZWQgZm9yIGEgc291cmNlIGxvY2F0aW9uLiBXZSBqdW1wIHRocm91Z2hcbi8vIHRoZXNlIGhvb3BzIGJlY2F1c2UgdGhlcmUgY2FuIGJlIG1hbnkgdGhvdXNhbmRzIG9mIG1hcHBpbmdzLCBhbmQgcGFyc2luZ1xuLy8gdGhlbSBpcyBleHBlbnNpdmUsIHNvIHdlIG9ubHkgd2FudCB0byBkbyBpdCBpZiB3ZSBtdXN0LlxuLy9cbi8vIEVhY2ggb2JqZWN0IGluIHRoZSBhcnJheXMgaXMgb2YgdGhlIGZvcm06XG4vL1xuLy8gICAgIHtcbi8vICAgICAgIGdlbmVyYXRlZExpbmU6IFRoZSBsaW5lIG51bWJlciBpbiB0aGUgZ2VuZXJhdGVkIGNvZGUsXG4vLyAgICAgICBnZW5lcmF0ZWRDb2x1bW46IFRoZSBjb2x1bW4gbnVtYmVyIGluIHRoZSBnZW5lcmF0ZWQgY29kZSxcbi8vICAgICAgIHNvdXJjZTogVGhlIHBhdGggdG8gdGhlIG9yaWdpbmFsIHNvdXJjZSBmaWxlIHRoYXQgZ2VuZXJhdGVkIHRoaXNcbi8vICAgICAgICAgICAgICAgY2h1bmsgb2YgY29kZSxcbi8vICAgICAgIG9yaWdpbmFsTGluZTogVGhlIGxpbmUgbnVtYmVyIGluIHRoZSBvcmlnaW5hbCBzb3VyY2UgdGhhdFxuLy8gICAgICAgICAgICAgICAgICAgICBjb3JyZXNwb25kcyB0byB0aGlzIGNodW5rIG9mIGdlbmVyYXRlZCBjb2RlLFxuLy8gICAgICAgb3JpZ2luYWxDb2x1bW46IFRoZSBjb2x1bW4gbnVtYmVyIGluIHRoZSBvcmlnaW5hbCBzb3VyY2UgdGhhdFxuLy8gICAgICAgICAgICAgICAgICAgICAgIGNvcnJlc3BvbmRzIHRvIHRoaXMgY2h1bmsgb2YgZ2VuZXJhdGVkIGNvZGUsXG4vLyAgICAgICBuYW1lOiBUaGUgbmFtZSBvZiB0aGUgb3JpZ2luYWwgc3ltYm9sIHdoaWNoIGdlbmVyYXRlZCB0aGlzIGNodW5rIG9mXG4vLyAgICAgICAgICAgICBjb2RlLlxuLy8gICAgIH1cbi8vXG4vLyBBbGwgcHJvcGVydGllcyBleGNlcHQgZm9yIGBnZW5lcmF0ZWRMaW5lYCBhbmQgYGdlbmVyYXRlZENvbHVtbmAgY2FuIGJlXG4vLyBgbnVsbGAuXG4vL1xuLy8gYF9nZW5lcmF0ZWRNYXBwaW5nc2AgaXMgb3JkZXJlZCBieSB0aGUgZ2VuZXJhdGVkIHBvc2l0aW9ucy5cbi8vXG4vLyBgX29yaWdpbmFsTWFwcGluZ3NgIGlzIG9yZGVyZWQgYnkgdGhlIG9yaWdpbmFsIHBvc2l0aW9ucy5cblxuU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLl9fZ2VuZXJhdGVkTWFwcGluZ3MgPSBudWxsO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KFNvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZSwgJ19nZW5lcmF0ZWRNYXBwaW5ncycsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLl9fZ2VuZXJhdGVkTWFwcGluZ3MpIHtcbiAgICAgIHRoaXMuX3BhcnNlTWFwcGluZ3ModGhpcy5fbWFwcGluZ3MsIHRoaXMuc291cmNlUm9vdCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX19nZW5lcmF0ZWRNYXBwaW5ncztcbiAgfVxufSk7XG5cblNvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5fX29yaWdpbmFsTWFwcGluZ3MgPSBudWxsO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KFNvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZSwgJ19vcmlnaW5hbE1hcHBpbmdzJywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXRoaXMuX19vcmlnaW5hbE1hcHBpbmdzKSB7XG4gICAgICB0aGlzLl9wYXJzZU1hcHBpbmdzKHRoaXMuX21hcHBpbmdzLCB0aGlzLnNvdXJjZVJvb3QpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9fb3JpZ2luYWxNYXBwaW5ncztcbiAgfVxufSk7XG5cblNvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5fY2hhcklzTWFwcGluZ1NlcGFyYXRvciA9XG4gIGZ1bmN0aW9uIFNvdXJjZU1hcENvbnN1bWVyX2NoYXJJc01hcHBpbmdTZXBhcmF0b3IoYVN0ciwgaW5kZXgpIHtcbiAgICB2YXIgYyA9IGFTdHIuY2hhckF0KGluZGV4KTtcbiAgICByZXR1cm4gYyA9PT0gXCI7XCIgfHwgYyA9PT0gXCIsXCI7XG4gIH07XG5cbi8qKlxuICogUGFyc2UgdGhlIG1hcHBpbmdzIGluIGEgc3RyaW5nIGluIHRvIGEgZGF0YSBzdHJ1Y3R1cmUgd2hpY2ggd2UgY2FuIGVhc2lseVxuICogcXVlcnkgKHRoZSBvcmRlcmVkIGFycmF5cyBpbiB0aGUgYHRoaXMuX19nZW5lcmF0ZWRNYXBwaW5nc2AgYW5kXG4gKiBgdGhpcy5fX29yaWdpbmFsTWFwcGluZ3NgIHByb3BlcnRpZXMpLlxuICovXG5Tb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUuX3BhcnNlTWFwcGluZ3MgPVxuICBmdW5jdGlvbiBTb3VyY2VNYXBDb25zdW1lcl9wYXJzZU1hcHBpbmdzKGFTdHIsIGFTb3VyY2VSb290KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiU3ViY2xhc3NlcyBtdXN0IGltcGxlbWVudCBfcGFyc2VNYXBwaW5nc1wiKTtcbiAgfTtcblxuU291cmNlTWFwQ29uc3VtZXIuR0VORVJBVEVEX09SREVSID0gMTtcblNvdXJjZU1hcENvbnN1bWVyLk9SSUdJTkFMX09SREVSID0gMjtcblxuU291cmNlTWFwQ29uc3VtZXIuR1JFQVRFU1RfTE9XRVJfQk9VTkQgPSAxO1xuU291cmNlTWFwQ29uc3VtZXIuTEVBU1RfVVBQRVJfQk9VTkQgPSAyO1xuXG4vKipcbiAqIEl0ZXJhdGUgb3ZlciBlYWNoIG1hcHBpbmcgYmV0d2VlbiBhbiBvcmlnaW5hbCBzb3VyY2UvbGluZS9jb2x1bW4gYW5kIGFcbiAqIGdlbmVyYXRlZCBsaW5lL2NvbHVtbiBpbiB0aGlzIHNvdXJjZSBtYXAuXG4gKlxuICogQHBhcmFtIEZ1bmN0aW9uIGFDYWxsYmFja1xuICogICAgICAgIFRoZSBmdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aXRoIGVhY2ggbWFwcGluZy5cbiAqIEBwYXJhbSBPYmplY3QgYUNvbnRleHRcbiAqICAgICAgICBPcHRpb25hbC4gSWYgc3BlY2lmaWVkLCB0aGlzIG9iamVjdCB3aWxsIGJlIHRoZSB2YWx1ZSBvZiBgdGhpc2AgZXZlcnlcbiAqICAgICAgICB0aW1lIHRoYXQgYGFDYWxsYmFja2AgaXMgY2FsbGVkLlxuICogQHBhcmFtIGFPcmRlclxuICogICAgICAgIEVpdGhlciBgU291cmNlTWFwQ29uc3VtZXIuR0VORVJBVEVEX09SREVSYCBvclxuICogICAgICAgIGBTb3VyY2VNYXBDb25zdW1lci5PUklHSU5BTF9PUkRFUmAuIFNwZWNpZmllcyB3aGV0aGVyIHlvdSB3YW50IHRvXG4gKiAgICAgICAgaXRlcmF0ZSBvdmVyIHRoZSBtYXBwaW5ncyBzb3J0ZWQgYnkgdGhlIGdlbmVyYXRlZCBmaWxlJ3MgbGluZS9jb2x1bW5cbiAqICAgICAgICBvcmRlciBvciB0aGUgb3JpZ2luYWwncyBzb3VyY2UvbGluZS9jb2x1bW4gb3JkZXIsIHJlc3BlY3RpdmVseS4gRGVmYXVsdHMgdG9cbiAqICAgICAgICBgU291cmNlTWFwQ29uc3VtZXIuR0VORVJBVEVEX09SREVSYC5cbiAqL1xuU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLmVhY2hNYXBwaW5nID1cbiAgZnVuY3Rpb24gU291cmNlTWFwQ29uc3VtZXJfZWFjaE1hcHBpbmcoYUNhbGxiYWNrLCBhQ29udGV4dCwgYU9yZGVyKSB7XG4gICAgdmFyIGNvbnRleHQgPSBhQ29udGV4dCB8fCBudWxsO1xuICAgIHZhciBvcmRlciA9IGFPcmRlciB8fCBTb3VyY2VNYXBDb25zdW1lci5HRU5FUkFURURfT1JERVI7XG5cbiAgICB2YXIgbWFwcGluZ3M7XG4gICAgc3dpdGNoIChvcmRlcikge1xuICAgIGNhc2UgU291cmNlTWFwQ29uc3VtZXIuR0VORVJBVEVEX09SREVSOlxuICAgICAgbWFwcGluZ3MgPSB0aGlzLl9nZW5lcmF0ZWRNYXBwaW5ncztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgU291cmNlTWFwQ29uc3VtZXIuT1JJR0lOQUxfT1JERVI6XG4gICAgICBtYXBwaW5ncyA9IHRoaXMuX29yaWdpbmFsTWFwcGluZ3M7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvcmRlciBvZiBpdGVyYXRpb24uXCIpO1xuICAgIH1cblxuICAgIHZhciBzb3VyY2VSb290ID0gdGhpcy5zb3VyY2VSb290O1xuICAgIG1hcHBpbmdzLm1hcChmdW5jdGlvbiAobWFwcGluZykge1xuICAgICAgdmFyIHNvdXJjZSA9IG1hcHBpbmcuc291cmNlID09PSBudWxsID8gbnVsbCA6IHRoaXMuX3NvdXJjZXMuYXQobWFwcGluZy5zb3VyY2UpO1xuICAgICAgaWYgKHNvdXJjZSAhPSBudWxsICYmIHNvdXJjZVJvb3QgIT0gbnVsbCkge1xuICAgICAgICBzb3VyY2UgPSB1dGlsLmpvaW4oc291cmNlUm9vdCwgc291cmNlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgICBnZW5lcmF0ZWRMaW5lOiBtYXBwaW5nLmdlbmVyYXRlZExpbmUsXG4gICAgICAgIGdlbmVyYXRlZENvbHVtbjogbWFwcGluZy5nZW5lcmF0ZWRDb2x1bW4sXG4gICAgICAgIG9yaWdpbmFsTGluZTogbWFwcGluZy5vcmlnaW5hbExpbmUsXG4gICAgICAgIG9yaWdpbmFsQ29sdW1uOiBtYXBwaW5nLm9yaWdpbmFsQ29sdW1uLFxuICAgICAgICBuYW1lOiBtYXBwaW5nLm5hbWUgPT09IG51bGwgPyBudWxsIDogdGhpcy5fbmFtZXMuYXQobWFwcGluZy5uYW1lKVxuICAgICAgfTtcbiAgICB9LCB0aGlzKS5mb3JFYWNoKGFDYWxsYmFjaywgY29udGV4dCk7XG4gIH07XG5cbi8qKlxuICogUmV0dXJucyBhbGwgZ2VuZXJhdGVkIGxpbmUgYW5kIGNvbHVtbiBpbmZvcm1hdGlvbiBmb3IgdGhlIG9yaWdpbmFsIHNvdXJjZSxcbiAqIGxpbmUsIGFuZCBjb2x1bW4gcHJvdmlkZWQuIElmIG5vIGNvbHVtbiBpcyBwcm92aWRlZCwgcmV0dXJucyBhbGwgbWFwcGluZ3NcbiAqIGNvcnJlc3BvbmRpbmcgdG8gYSBlaXRoZXIgdGhlIGxpbmUgd2UgYXJlIHNlYXJjaGluZyBmb3Igb3IgdGhlIG5leHRcbiAqIGNsb3Nlc3QgbGluZSB0aGF0IGhhcyBhbnkgbWFwcGluZ3MuIE90aGVyd2lzZSwgcmV0dXJucyBhbGwgbWFwcGluZ3NcbiAqIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIGxpbmUgYW5kIGVpdGhlciB0aGUgY29sdW1uIHdlIGFyZSBzZWFyY2hpbmcgZm9yXG4gKiBvciB0aGUgbmV4dCBjbG9zZXN0IGNvbHVtbiB0aGF0IGhhcyBhbnkgb2Zmc2V0cy5cbiAqXG4gKiBUaGUgb25seSBhcmd1bWVudCBpcyBhbiBvYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogICAtIHNvdXJjZTogVGhlIGZpbGVuYW1lIG9mIHRoZSBvcmlnaW5hbCBzb3VyY2UuXG4gKiAgIC0gbGluZTogVGhlIGxpbmUgbnVtYmVyIGluIHRoZSBvcmlnaW5hbCBzb3VyY2UuXG4gKiAgIC0gY29sdW1uOiBPcHRpb25hbC4gdGhlIGNvbHVtbiBudW1iZXIgaW4gdGhlIG9yaWdpbmFsIHNvdXJjZS5cbiAqXG4gKiBhbmQgYW4gYXJyYXkgb2Ygb2JqZWN0cyBpcyByZXR1cm5lZCwgZWFjaCB3aXRoIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczpcbiAqXG4gKiAgIC0gbGluZTogVGhlIGxpbmUgbnVtYmVyIGluIHRoZSBnZW5lcmF0ZWQgc291cmNlLCBvciBudWxsLlxuICogICAtIGNvbHVtbjogVGhlIGNvbHVtbiBudW1iZXIgaW4gdGhlIGdlbmVyYXRlZCBzb3VyY2UsIG9yIG51bGwuXG4gKi9cblNvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5hbGxHZW5lcmF0ZWRQb3NpdGlvbnNGb3IgPVxuICBmdW5jdGlvbiBTb3VyY2VNYXBDb25zdW1lcl9hbGxHZW5lcmF0ZWRQb3NpdGlvbnNGb3IoYUFyZ3MpIHtcbiAgICB2YXIgbGluZSA9IHV0aWwuZ2V0QXJnKGFBcmdzLCAnbGluZScpO1xuXG4gICAgLy8gV2hlbiB0aGVyZSBpcyBubyBleGFjdCBtYXRjaCwgQmFzaWNTb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUuX2ZpbmRNYXBwaW5nXG4gICAgLy8gcmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGNsb3Nlc3QgbWFwcGluZyBsZXNzIHRoYW4gdGhlIG5lZWRsZS4gQnlcbiAgICAvLyBzZXR0aW5nIG5lZWRsZS5vcmlnaW5hbENvbHVtbiB0byAwLCB3ZSB0aHVzIGZpbmQgdGhlIGxhc3QgbWFwcGluZyBmb3JcbiAgICAvLyB0aGUgZ2l2ZW4gbGluZSwgcHJvdmlkZWQgc3VjaCBhIG1hcHBpbmcgZXhpc3RzLlxuICAgIHZhciBuZWVkbGUgPSB7XG4gICAgICBzb3VyY2U6IHV0aWwuZ2V0QXJnKGFBcmdzLCAnc291cmNlJyksXG4gICAgICBvcmlnaW5hbExpbmU6IGxpbmUsXG4gICAgICBvcmlnaW5hbENvbHVtbjogdXRpbC5nZXRBcmcoYUFyZ3MsICdjb2x1bW4nLCAwKVxuICAgIH07XG5cbiAgICBpZiAodGhpcy5zb3VyY2VSb290ICE9IG51bGwpIHtcbiAgICAgIG5lZWRsZS5zb3VyY2UgPSB1dGlsLnJlbGF0aXZlKHRoaXMuc291cmNlUm9vdCwgbmVlZGxlLnNvdXJjZSk7XG4gICAgfVxuICAgIGlmICghdGhpcy5fc291cmNlcy5oYXMobmVlZGxlLnNvdXJjZSkpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgbmVlZGxlLnNvdXJjZSA9IHRoaXMuX3NvdXJjZXMuaW5kZXhPZihuZWVkbGUuc291cmNlKTtcblxuICAgIHZhciBtYXBwaW5ncyA9IFtdO1xuXG4gICAgdmFyIGluZGV4ID0gdGhpcy5fZmluZE1hcHBpbmcobmVlZGxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX29yaWdpbmFsTWFwcGluZ3MsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJvcmlnaW5hbExpbmVcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIm9yaWdpbmFsQ29sdW1uXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXRpbC5jb21wYXJlQnlPcmlnaW5hbFBvc2l0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaW5hcnlTZWFyY2guTEVBU1RfVVBQRVJfQk9VTkQpO1xuICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICB2YXIgbWFwcGluZyA9IHRoaXMuX29yaWdpbmFsTWFwcGluZ3NbaW5kZXhdO1xuXG4gICAgICBpZiAoYUFyZ3MuY29sdW1uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFyIG9yaWdpbmFsTGluZSA9IG1hcHBpbmcub3JpZ2luYWxMaW5lO1xuXG4gICAgICAgIC8vIEl0ZXJhdGUgdW50aWwgZWl0aGVyIHdlIHJ1biBvdXQgb2YgbWFwcGluZ3MsIG9yIHdlIHJ1biBpbnRvXG4gICAgICAgIC8vIGEgbWFwcGluZyBmb3IgYSBkaWZmZXJlbnQgbGluZSB0aGFuIHRoZSBvbmUgd2UgZm91bmQuIFNpbmNlXG4gICAgICAgIC8vIG1hcHBpbmdzIGFyZSBzb3J0ZWQsIHRoaXMgaXMgZ3VhcmFudGVlZCB0byBmaW5kIGFsbCBtYXBwaW5ncyBmb3JcbiAgICAgICAgLy8gdGhlIGxpbmUgd2UgZm91bmQuXG4gICAgICAgIHdoaWxlIChtYXBwaW5nICYmIG1hcHBpbmcub3JpZ2luYWxMaW5lID09PSBvcmlnaW5hbExpbmUpIHtcbiAgICAgICAgICBtYXBwaW5ncy5wdXNoKHtcbiAgICAgICAgICAgIGxpbmU6IHV0aWwuZ2V0QXJnKG1hcHBpbmcsICdnZW5lcmF0ZWRMaW5lJywgbnVsbCksXG4gICAgICAgICAgICBjb2x1bW46IHV0aWwuZ2V0QXJnKG1hcHBpbmcsICdnZW5lcmF0ZWRDb2x1bW4nLCBudWxsKSxcbiAgICAgICAgICAgIGxhc3RDb2x1bW46IHV0aWwuZ2V0QXJnKG1hcHBpbmcsICdsYXN0R2VuZXJhdGVkQ29sdW1uJywgbnVsbClcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIG1hcHBpbmcgPSB0aGlzLl9vcmlnaW5hbE1hcHBpbmdzWysraW5kZXhdO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgb3JpZ2luYWxDb2x1bW4gPSBtYXBwaW5nLm9yaWdpbmFsQ29sdW1uO1xuXG4gICAgICAgIC8vIEl0ZXJhdGUgdW50aWwgZWl0aGVyIHdlIHJ1biBvdXQgb2YgbWFwcGluZ3MsIG9yIHdlIHJ1biBpbnRvXG4gICAgICAgIC8vIGEgbWFwcGluZyBmb3IgYSBkaWZmZXJlbnQgbGluZSB0aGFuIHRoZSBvbmUgd2Ugd2VyZSBzZWFyY2hpbmcgZm9yLlxuICAgICAgICAvLyBTaW5jZSBtYXBwaW5ncyBhcmUgc29ydGVkLCB0aGlzIGlzIGd1YXJhbnRlZWQgdG8gZmluZCBhbGwgbWFwcGluZ3MgZm9yXG4gICAgICAgIC8vIHRoZSBsaW5lIHdlIGFyZSBzZWFyY2hpbmcgZm9yLlxuICAgICAgICB3aGlsZSAobWFwcGluZyAmJlxuICAgICAgICAgICAgICAgbWFwcGluZy5vcmlnaW5hbExpbmUgPT09IGxpbmUgJiZcbiAgICAgICAgICAgICAgIG1hcHBpbmcub3JpZ2luYWxDb2x1bW4gPT0gb3JpZ2luYWxDb2x1bW4pIHtcbiAgICAgICAgICBtYXBwaW5ncy5wdXNoKHtcbiAgICAgICAgICAgIGxpbmU6IHV0aWwuZ2V0QXJnKG1hcHBpbmcsICdnZW5lcmF0ZWRMaW5lJywgbnVsbCksXG4gICAgICAgICAgICBjb2x1bW46IHV0aWwuZ2V0QXJnKG1hcHBpbmcsICdnZW5lcmF0ZWRDb2x1bW4nLCBudWxsKSxcbiAgICAgICAgICAgIGxhc3RDb2x1bW46IHV0aWwuZ2V0QXJnKG1hcHBpbmcsICdsYXN0R2VuZXJhdGVkQ29sdW1uJywgbnVsbClcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIG1hcHBpbmcgPSB0aGlzLl9vcmlnaW5hbE1hcHBpbmdzWysraW5kZXhdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1hcHBpbmdzO1xuICB9O1xuXG5leHBvcnRzLlNvdXJjZU1hcENvbnN1bWVyID0gU291cmNlTWFwQ29uc3VtZXI7XG5cbi8qKlxuICogQSBCYXNpY1NvdXJjZU1hcENvbnN1bWVyIGluc3RhbmNlIHJlcHJlc2VudHMgYSBwYXJzZWQgc291cmNlIG1hcCB3aGljaCB3ZSBjYW5cbiAqIHF1ZXJ5IGZvciBpbmZvcm1hdGlvbiBhYm91dCB0aGUgb3JpZ2luYWwgZmlsZSBwb3NpdGlvbnMgYnkgZ2l2aW5nIGl0IGEgZmlsZVxuICogcG9zaXRpb24gaW4gdGhlIGdlbmVyYXRlZCBzb3VyY2UuXG4gKlxuICogVGhlIG9ubHkgcGFyYW1ldGVyIGlzIHRoZSByYXcgc291cmNlIG1hcCAoZWl0aGVyIGFzIGEgSlNPTiBzdHJpbmcsIG9yXG4gKiBhbHJlYWR5IHBhcnNlZCB0byBhbiBvYmplY3QpLiBBY2NvcmRpbmcgdG8gdGhlIHNwZWMsIHNvdXJjZSBtYXBzIGhhdmUgdGhlXG4gKiBmb2xsb3dpbmcgYXR0cmlidXRlczpcbiAqXG4gKiAgIC0gdmVyc2lvbjogV2hpY2ggdmVyc2lvbiBvZiB0aGUgc291cmNlIG1hcCBzcGVjIHRoaXMgbWFwIGlzIGZvbGxvd2luZy5cbiAqICAgLSBzb3VyY2VzOiBBbiBhcnJheSBvZiBVUkxzIHRvIHRoZSBvcmlnaW5hbCBzb3VyY2UgZmlsZXMuXG4gKiAgIC0gbmFtZXM6IEFuIGFycmF5IG9mIGlkZW50aWZpZXJzIHdoaWNoIGNhbiBiZSByZWZlcnJlbmNlZCBieSBpbmRpdmlkdWFsIG1hcHBpbmdzLlxuICogICAtIHNvdXJjZVJvb3Q6IE9wdGlvbmFsLiBUaGUgVVJMIHJvb3QgZnJvbSB3aGljaCBhbGwgc291cmNlcyBhcmUgcmVsYXRpdmUuXG4gKiAgIC0gc291cmNlc0NvbnRlbnQ6IE9wdGlvbmFsLiBBbiBhcnJheSBvZiBjb250ZW50cyBvZiB0aGUgb3JpZ2luYWwgc291cmNlIGZpbGVzLlxuICogICAtIG1hcHBpbmdzOiBBIHN0cmluZyBvZiBiYXNlNjQgVkxRcyB3aGljaCBjb250YWluIHRoZSBhY3R1YWwgbWFwcGluZ3MuXG4gKiAgIC0gZmlsZTogT3B0aW9uYWwuIFRoZSBnZW5lcmF0ZWQgZmlsZSB0aGlzIHNvdXJjZSBtYXAgaXMgYXNzb2NpYXRlZCB3aXRoLlxuICpcbiAqIEhlcmUgaXMgYW4gZXhhbXBsZSBzb3VyY2UgbWFwLCB0YWtlbiBmcm9tIHRoZSBzb3VyY2UgbWFwIHNwZWNbMF06XG4gKlxuICogICAgIHtcbiAqICAgICAgIHZlcnNpb24gOiAzLFxuICogICAgICAgZmlsZTogXCJvdXQuanNcIixcbiAqICAgICAgIHNvdXJjZVJvb3QgOiBcIlwiLFxuICogICAgICAgc291cmNlczogW1wiZm9vLmpzXCIsIFwiYmFyLmpzXCJdLFxuICogICAgICAgbmFtZXM6IFtcInNyY1wiLCBcIm1hcHNcIiwgXCJhcmVcIiwgXCJmdW5cIl0sXG4gKiAgICAgICBtYXBwaW5nczogXCJBQSxBQjs7QUJDREU7XCJcbiAqICAgICB9XG4gKlxuICogWzBdOiBodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9kb2N1bWVudC9kLzFVMVJHQWVoUXdSeXBVVG92RjFLUmxwaU9GemUwYi1fMmdjNmZBSDBLWTBrL2VkaXQ/cGxpPTEjXG4gKi9cbmZ1bmN0aW9uIEJhc2ljU291cmNlTWFwQ29uc3VtZXIoYVNvdXJjZU1hcCkge1xuICB2YXIgc291cmNlTWFwID0gYVNvdXJjZU1hcDtcbiAgaWYgKHR5cGVvZiBhU291cmNlTWFwID09PSAnc3RyaW5nJykge1xuICAgIHNvdXJjZU1hcCA9IEpTT04ucGFyc2UoYVNvdXJjZU1hcC5yZXBsYWNlKC9eXFwpXFxdXFx9Jy8sICcnKSk7XG4gIH1cblxuICB2YXIgdmVyc2lvbiA9IHV0aWwuZ2V0QXJnKHNvdXJjZU1hcCwgJ3ZlcnNpb24nKTtcbiAgdmFyIHNvdXJjZXMgPSB1dGlsLmdldEFyZyhzb3VyY2VNYXAsICdzb3VyY2VzJyk7XG4gIC8vIFNhc3MgMy4zIGxlYXZlcyBvdXQgdGhlICduYW1lcycgYXJyYXksIHNvIHdlIGRldmlhdGUgZnJvbSB0aGUgc3BlYyAod2hpY2hcbiAgLy8gcmVxdWlyZXMgdGhlIGFycmF5KSB0byBwbGF5IG5pY2UgaGVyZS5cbiAgdmFyIG5hbWVzID0gdXRpbC5nZXRBcmcoc291cmNlTWFwLCAnbmFtZXMnLCBbXSk7XG4gIHZhciBzb3VyY2VSb290ID0gdXRpbC5nZXRBcmcoc291cmNlTWFwLCAnc291cmNlUm9vdCcsIG51bGwpO1xuICB2YXIgc291cmNlc0NvbnRlbnQgPSB1dGlsLmdldEFyZyhzb3VyY2VNYXAsICdzb3VyY2VzQ29udGVudCcsIG51bGwpO1xuICB2YXIgbWFwcGluZ3MgPSB1dGlsLmdldEFyZyhzb3VyY2VNYXAsICdtYXBwaW5ncycpO1xuICB2YXIgZmlsZSA9IHV0aWwuZ2V0QXJnKHNvdXJjZU1hcCwgJ2ZpbGUnLCBudWxsKTtcblxuICAvLyBPbmNlIGFnYWluLCBTYXNzIGRldmlhdGVzIGZyb20gdGhlIHNwZWMgYW5kIHN1cHBsaWVzIHRoZSB2ZXJzaW9uIGFzIGFcbiAgLy8gc3RyaW5nIHJhdGhlciB0aGFuIGEgbnVtYmVyLCBzbyB3ZSB1c2UgbG9vc2UgZXF1YWxpdHkgY2hlY2tpbmcgaGVyZS5cbiAgaWYgKHZlcnNpb24gIT0gdGhpcy5fdmVyc2lvbikge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgdmVyc2lvbjogJyArIHZlcnNpb24pO1xuICB9XG5cbiAgc291cmNlcyA9IHNvdXJjZXNcbiAgICAubWFwKFN0cmluZylcbiAgICAvLyBTb21lIHNvdXJjZSBtYXBzIHByb2R1Y2UgcmVsYXRpdmUgc291cmNlIHBhdGhzIGxpa2UgXCIuL2Zvby5qc1wiIGluc3RlYWQgb2ZcbiAgICAvLyBcImZvby5qc1wiLiAgTm9ybWFsaXplIHRoZXNlIGZpcnN0IHNvIHRoYXQgZnV0dXJlIGNvbXBhcmlzb25zIHdpbGwgc3VjY2VlZC5cbiAgICAvLyBTZWUgYnVnemlsLmxhLzEwOTA3NjguXG4gICAgLm1hcCh1dGlsLm5vcm1hbGl6ZSlcbiAgICAvLyBBbHdheXMgZW5zdXJlIHRoYXQgYWJzb2x1dGUgc291cmNlcyBhcmUgaW50ZXJuYWxseSBzdG9yZWQgcmVsYXRpdmUgdG9cbiAgICAvLyB0aGUgc291cmNlIHJvb3QsIGlmIHRoZSBzb3VyY2Ugcm9vdCBpcyBhYnNvbHV0ZS4gTm90IGRvaW5nIHRoaXMgd291bGRcbiAgICAvLyBiZSBwYXJ0aWN1bGFybHkgcHJvYmxlbWF0aWMgd2hlbiB0aGUgc291cmNlIHJvb3QgaXMgYSBwcmVmaXggb2YgdGhlXG4gICAgLy8gc291cmNlICh2YWxpZCwgYnV0IHdoeT8/KS4gU2VlIGdpdGh1YiBpc3N1ZSAjMTk5IGFuZCBidWd6aWwubGEvMTE4ODk4Mi5cbiAgICAubWFwKGZ1bmN0aW9uIChzb3VyY2UpIHtcbiAgICAgIHJldHVybiBzb3VyY2VSb290ICYmIHV0aWwuaXNBYnNvbHV0ZShzb3VyY2VSb290KSAmJiB1dGlsLmlzQWJzb2x1dGUoc291cmNlKVxuICAgICAgICA/IHV0aWwucmVsYXRpdmUoc291cmNlUm9vdCwgc291cmNlKVxuICAgICAgICA6IHNvdXJjZTtcbiAgICB9KTtcblxuICAvLyBQYXNzIGB0cnVlYCBiZWxvdyB0byBhbGxvdyBkdXBsaWNhdGUgbmFtZXMgYW5kIHNvdXJjZXMuIFdoaWxlIHNvdXJjZSBtYXBzXG4gIC8vIGFyZSBpbnRlbmRlZCB0byBiZSBjb21wcmVzc2VkIGFuZCBkZWR1cGxpY2F0ZWQsIHRoZSBUeXBlU2NyaXB0IGNvbXBpbGVyXG4gIC8vIHNvbWV0aW1lcyBnZW5lcmF0ZXMgc291cmNlIG1hcHMgd2l0aCBkdXBsaWNhdGVzIGluIHRoZW0uIFNlZSBHaXRodWIgaXNzdWVcbiAgLy8gIzcyIGFuZCBidWd6aWwubGEvODg5NDkyLlxuICB0aGlzLl9uYW1lcyA9IEFycmF5U2V0LmZyb21BcnJheShuYW1lcy5tYXAoU3RyaW5nKSwgdHJ1ZSk7XG4gIHRoaXMuX3NvdXJjZXMgPSBBcnJheVNldC5mcm9tQXJyYXkoc291cmNlcywgdHJ1ZSk7XG5cbiAgdGhpcy5zb3VyY2VSb290ID0gc291cmNlUm9vdDtcbiAgdGhpcy5zb3VyY2VzQ29udGVudCA9IHNvdXJjZXNDb250ZW50O1xuICB0aGlzLl9tYXBwaW5ncyA9IG1hcHBpbmdzO1xuICB0aGlzLmZpbGUgPSBmaWxlO1xufVxuXG5CYXNpY1NvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlKTtcbkJhc2ljU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLmNvbnN1bWVyID0gU291cmNlTWFwQ29uc3VtZXI7XG5cbi8qKlxuICogQ3JlYXRlIGEgQmFzaWNTb3VyY2VNYXBDb25zdW1lciBmcm9tIGEgU291cmNlTWFwR2VuZXJhdG9yLlxuICpcbiAqIEBwYXJhbSBTb3VyY2VNYXBHZW5lcmF0b3IgYVNvdXJjZU1hcFxuICogICAgICAgIFRoZSBzb3VyY2UgbWFwIHRoYXQgd2lsbCBiZSBjb25zdW1lZC5cbiAqIEByZXR1cm5zIEJhc2ljU291cmNlTWFwQ29uc3VtZXJcbiAqL1xuQmFzaWNTb3VyY2VNYXBDb25zdW1lci5mcm9tU291cmNlTWFwID1cbiAgZnVuY3Rpb24gU291cmNlTWFwQ29uc3VtZXJfZnJvbVNvdXJjZU1hcChhU291cmNlTWFwKSB7XG4gICAgdmFyIHNtYyA9IE9iamVjdC5jcmVhdGUoQmFzaWNTb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUpO1xuXG4gICAgdmFyIG5hbWVzID0gc21jLl9uYW1lcyA9IEFycmF5U2V0LmZyb21BcnJheShhU291cmNlTWFwLl9uYW1lcy50b0FycmF5KCksIHRydWUpO1xuICAgIHZhciBzb3VyY2VzID0gc21jLl9zb3VyY2VzID0gQXJyYXlTZXQuZnJvbUFycmF5KGFTb3VyY2VNYXAuX3NvdXJjZXMudG9BcnJheSgpLCB0cnVlKTtcbiAgICBzbWMuc291cmNlUm9vdCA9IGFTb3VyY2VNYXAuX3NvdXJjZVJvb3Q7XG4gICAgc21jLnNvdXJjZXNDb250ZW50ID0gYVNvdXJjZU1hcC5fZ2VuZXJhdGVTb3VyY2VzQ29udGVudChzbWMuX3NvdXJjZXMudG9BcnJheSgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc21jLnNvdXJjZVJvb3QpO1xuICAgIHNtYy5maWxlID0gYVNvdXJjZU1hcC5fZmlsZTtcblxuICAgIC8vIEJlY2F1c2Ugd2UgYXJlIG1vZGlmeWluZyB0aGUgZW50cmllcyAoYnkgY29udmVydGluZyBzdHJpbmcgc291cmNlcyBhbmRcbiAgICAvLyBuYW1lcyB0byBpbmRpY2VzIGludG8gdGhlIHNvdXJjZXMgYW5kIG5hbWVzIEFycmF5U2V0cyksIHdlIGhhdmUgdG8gbWFrZVxuICAgIC8vIGEgY29weSBvZiB0aGUgZW50cnkgb3IgZWxzZSBiYWQgdGhpbmdzIGhhcHBlbi4gU2hhcmVkIG11dGFibGUgc3RhdGVcbiAgICAvLyBzdHJpa2VzIGFnYWluISBTZWUgZ2l0aHViIGlzc3VlICMxOTEuXG5cbiAgICB2YXIgZ2VuZXJhdGVkTWFwcGluZ3MgPSBhU291cmNlTWFwLl9tYXBwaW5ncy50b0FycmF5KCkuc2xpY2UoKTtcbiAgICB2YXIgZGVzdEdlbmVyYXRlZE1hcHBpbmdzID0gc21jLl9fZ2VuZXJhdGVkTWFwcGluZ3MgPSBbXTtcbiAgICB2YXIgZGVzdE9yaWdpbmFsTWFwcGluZ3MgPSBzbWMuX19vcmlnaW5hbE1hcHBpbmdzID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gZ2VuZXJhdGVkTWFwcGluZ3MubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBzcmNNYXBwaW5nID0gZ2VuZXJhdGVkTWFwcGluZ3NbaV07XG4gICAgICB2YXIgZGVzdE1hcHBpbmcgPSBuZXcgTWFwcGluZztcbiAgICAgIGRlc3RNYXBwaW5nLmdlbmVyYXRlZExpbmUgPSBzcmNNYXBwaW5nLmdlbmVyYXRlZExpbmU7XG4gICAgICBkZXN0TWFwcGluZy5nZW5lcmF0ZWRDb2x1bW4gPSBzcmNNYXBwaW5nLmdlbmVyYXRlZENvbHVtbjtcblxuICAgICAgaWYgKHNyY01hcHBpbmcuc291cmNlKSB7XG4gICAgICAgIGRlc3RNYXBwaW5nLnNvdXJjZSA9IHNvdXJjZXMuaW5kZXhPZihzcmNNYXBwaW5nLnNvdXJjZSk7XG4gICAgICAgIGRlc3RNYXBwaW5nLm9yaWdpbmFsTGluZSA9IHNyY01hcHBpbmcub3JpZ2luYWxMaW5lO1xuICAgICAgICBkZXN0TWFwcGluZy5vcmlnaW5hbENvbHVtbiA9IHNyY01hcHBpbmcub3JpZ2luYWxDb2x1bW47XG5cbiAgICAgICAgaWYgKHNyY01hcHBpbmcubmFtZSkge1xuICAgICAgICAgIGRlc3RNYXBwaW5nLm5hbWUgPSBuYW1lcy5pbmRleE9mKHNyY01hcHBpbmcubmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBkZXN0T3JpZ2luYWxNYXBwaW5ncy5wdXNoKGRlc3RNYXBwaW5nKTtcbiAgICAgIH1cblxuICAgICAgZGVzdEdlbmVyYXRlZE1hcHBpbmdzLnB1c2goZGVzdE1hcHBpbmcpO1xuICAgIH1cblxuICAgIHF1aWNrU29ydChzbWMuX19vcmlnaW5hbE1hcHBpbmdzLCB1dGlsLmNvbXBhcmVCeU9yaWdpbmFsUG9zaXRpb25zKTtcblxuICAgIHJldHVybiBzbWM7XG4gIH07XG5cbi8qKlxuICogVGhlIHZlcnNpb24gb2YgdGhlIHNvdXJjZSBtYXBwaW5nIHNwZWMgdGhhdCB3ZSBhcmUgY29uc3VtaW5nLlxuICovXG5CYXNpY1NvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5fdmVyc2lvbiA9IDM7XG5cbi8qKlxuICogVGhlIGxpc3Qgb2Ygb3JpZ2luYWwgc291cmNlcy5cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KEJhc2ljU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLCAnc291cmNlcycsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3NvdXJjZXMudG9BcnJheSgpLm1hcChmdW5jdGlvbiAocykge1xuICAgICAgcmV0dXJuIHRoaXMuc291cmNlUm9vdCAhPSBudWxsID8gdXRpbC5qb2luKHRoaXMuc291cmNlUm9vdCwgcykgOiBzO1xuICAgIH0sIHRoaXMpO1xuICB9XG59KTtcblxuLyoqXG4gKiBQcm92aWRlIHRoZSBKSVQgd2l0aCBhIG5pY2Ugc2hhcGUgLyBoaWRkZW4gY2xhc3MuXG4gKi9cbmZ1bmN0aW9uIE1hcHBpbmcoKSB7XG4gIHRoaXMuZ2VuZXJhdGVkTGluZSA9IDA7XG4gIHRoaXMuZ2VuZXJhdGVkQ29sdW1uID0gMDtcbiAgdGhpcy5zb3VyY2UgPSBudWxsO1xuICB0aGlzLm9yaWdpbmFsTGluZSA9IG51bGw7XG4gIHRoaXMub3JpZ2luYWxDb2x1bW4gPSBudWxsO1xuICB0aGlzLm5hbWUgPSBudWxsO1xufVxuXG4vKipcbiAqIFBhcnNlIHRoZSBtYXBwaW5ncyBpbiBhIHN0cmluZyBpbiB0byBhIGRhdGEgc3RydWN0dXJlIHdoaWNoIHdlIGNhbiBlYXNpbHlcbiAqIHF1ZXJ5ICh0aGUgb3JkZXJlZCBhcnJheXMgaW4gdGhlIGB0aGlzLl9fZ2VuZXJhdGVkTWFwcGluZ3NgIGFuZFxuICogYHRoaXMuX19vcmlnaW5hbE1hcHBpbmdzYCBwcm9wZXJ0aWVzKS5cbiAqL1xuQmFzaWNTb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUuX3BhcnNlTWFwcGluZ3MgPVxuICBmdW5jdGlvbiBTb3VyY2VNYXBDb25zdW1lcl9wYXJzZU1hcHBpbmdzKGFTdHIsIGFTb3VyY2VSb290KSB7XG4gICAgdmFyIGdlbmVyYXRlZExpbmUgPSAxO1xuICAgIHZhciBwcmV2aW91c0dlbmVyYXRlZENvbHVtbiA9IDA7XG4gICAgdmFyIHByZXZpb3VzT3JpZ2luYWxMaW5lID0gMDtcbiAgICB2YXIgcHJldmlvdXNPcmlnaW5hbENvbHVtbiA9IDA7XG4gICAgdmFyIHByZXZpb3VzU291cmNlID0gMDtcbiAgICB2YXIgcHJldmlvdXNOYW1lID0gMDtcbiAgICB2YXIgbGVuZ3RoID0gYVN0ci5sZW5ndGg7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgY2FjaGVkU2VnbWVudHMgPSB7fTtcbiAgICB2YXIgdGVtcCA9IHt9O1xuICAgIHZhciBvcmlnaW5hbE1hcHBpbmdzID0gW107XG4gICAgdmFyIGdlbmVyYXRlZE1hcHBpbmdzID0gW107XG4gICAgdmFyIG1hcHBpbmcsIHN0ciwgc2VnbWVudCwgZW5kLCB2YWx1ZTtcblxuICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgaWYgKGFTdHIuY2hhckF0KGluZGV4KSA9PT0gJzsnKSB7XG4gICAgICAgIGdlbmVyYXRlZExpbmUrKztcbiAgICAgICAgaW5kZXgrKztcbiAgICAgICAgcHJldmlvdXNHZW5lcmF0ZWRDb2x1bW4gPSAwO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAoYVN0ci5jaGFyQXQoaW5kZXgpID09PSAnLCcpIHtcbiAgICAgICAgaW5kZXgrKztcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBtYXBwaW5nID0gbmV3IE1hcHBpbmcoKTtcbiAgICAgICAgbWFwcGluZy5nZW5lcmF0ZWRMaW5lID0gZ2VuZXJhdGVkTGluZTtcblxuICAgICAgICAvLyBCZWNhdXNlIGVhY2ggb2Zmc2V0IGlzIGVuY29kZWQgcmVsYXRpdmUgdG8gdGhlIHByZXZpb3VzIG9uZSxcbiAgICAgICAgLy8gbWFueSBzZWdtZW50cyBvZnRlbiBoYXZlIHRoZSBzYW1lIGVuY29kaW5nLiBXZSBjYW4gZXhwbG9pdCB0aGlzXG4gICAgICAgIC8vIGZhY3QgYnkgY2FjaGluZyB0aGUgcGFyc2VkIHZhcmlhYmxlIGxlbmd0aCBmaWVsZHMgb2YgZWFjaCBzZWdtZW50LFxuICAgICAgICAvLyBhbGxvd2luZyB1cyB0byBhdm9pZCBhIHNlY29uZCBwYXJzZSBpZiB3ZSBlbmNvdW50ZXIgdGhlIHNhbWVcbiAgICAgICAgLy8gc2VnbWVudCBhZ2Fpbi5cbiAgICAgICAgZm9yIChlbmQgPSBpbmRleDsgZW5kIDwgbGVuZ3RoOyBlbmQrKykge1xuICAgICAgICAgIGlmICh0aGlzLl9jaGFySXNNYXBwaW5nU2VwYXJhdG9yKGFTdHIsIGVuZCkpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdHIgPSBhU3RyLnNsaWNlKGluZGV4LCBlbmQpO1xuXG4gICAgICAgIHNlZ21lbnQgPSBjYWNoZWRTZWdtZW50c1tzdHJdO1xuICAgICAgICBpZiAoc2VnbWVudCkge1xuICAgICAgICAgIGluZGV4ICs9IHN0ci5sZW5ndGg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2VnbWVudCA9IFtdO1xuICAgICAgICAgIHdoaWxlIChpbmRleCA8IGVuZCkge1xuICAgICAgICAgICAgYmFzZTY0VkxRLmRlY29kZShhU3RyLCBpbmRleCwgdGVtcCk7XG4gICAgICAgICAgICB2YWx1ZSA9IHRlbXAudmFsdWU7XG4gICAgICAgICAgICBpbmRleCA9IHRlbXAucmVzdDtcbiAgICAgICAgICAgIHNlZ21lbnQucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZvdW5kIGEgc291cmNlLCBidXQgbm8gbGluZSBhbmQgY29sdW1uJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoID09PSAzKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZvdW5kIGEgc291cmNlIGFuZCBsaW5lLCBidXQgbm8gY29sdW1uJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY2FjaGVkU2VnbWVudHNbc3RyXSA9IHNlZ21lbnQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZW5lcmF0ZWQgY29sdW1uLlxuICAgICAgICBtYXBwaW5nLmdlbmVyYXRlZENvbHVtbiA9IHByZXZpb3VzR2VuZXJhdGVkQ29sdW1uICsgc2VnbWVudFswXTtcbiAgICAgICAgcHJldmlvdXNHZW5lcmF0ZWRDb2x1bW4gPSBtYXBwaW5nLmdlbmVyYXRlZENvbHVtbjtcblxuICAgICAgICBpZiAoc2VnbWVudC5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgLy8gT3JpZ2luYWwgc291cmNlLlxuICAgICAgICAgIG1hcHBpbmcuc291cmNlID0gcHJldmlvdXNTb3VyY2UgKyBzZWdtZW50WzFdO1xuICAgICAgICAgIHByZXZpb3VzU291cmNlICs9IHNlZ21lbnRbMV07XG5cbiAgICAgICAgICAvLyBPcmlnaW5hbCBsaW5lLlxuICAgICAgICAgIG1hcHBpbmcub3JpZ2luYWxMaW5lID0gcHJldmlvdXNPcmlnaW5hbExpbmUgKyBzZWdtZW50WzJdO1xuICAgICAgICAgIHByZXZpb3VzT3JpZ2luYWxMaW5lID0gbWFwcGluZy5vcmlnaW5hbExpbmU7XG4gICAgICAgICAgLy8gTGluZXMgYXJlIHN0b3JlZCAwLWJhc2VkXG4gICAgICAgICAgbWFwcGluZy5vcmlnaW5hbExpbmUgKz0gMTtcblxuICAgICAgICAgIC8vIE9yaWdpbmFsIGNvbHVtbi5cbiAgICAgICAgICBtYXBwaW5nLm9yaWdpbmFsQ29sdW1uID0gcHJldmlvdXNPcmlnaW5hbENvbHVtbiArIHNlZ21lbnRbM107XG4gICAgICAgICAgcHJldmlvdXNPcmlnaW5hbENvbHVtbiA9IG1hcHBpbmcub3JpZ2luYWxDb2x1bW47XG5cbiAgICAgICAgICBpZiAoc2VnbWVudC5sZW5ndGggPiA0KSB7XG4gICAgICAgICAgICAvLyBPcmlnaW5hbCBuYW1lLlxuICAgICAgICAgICAgbWFwcGluZy5uYW1lID0gcHJldmlvdXNOYW1lICsgc2VnbWVudFs0XTtcbiAgICAgICAgICAgIHByZXZpb3VzTmFtZSArPSBzZWdtZW50WzRdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGdlbmVyYXRlZE1hcHBpbmdzLnB1c2gobWFwcGluZyk7XG4gICAgICAgIGlmICh0eXBlb2YgbWFwcGluZy5vcmlnaW5hbExpbmUgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgb3JpZ2luYWxNYXBwaW5ncy5wdXNoKG1hcHBpbmcpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcXVpY2tTb3J0KGdlbmVyYXRlZE1hcHBpbmdzLCB1dGlsLmNvbXBhcmVCeUdlbmVyYXRlZFBvc2l0aW9uc0RlZmxhdGVkKTtcbiAgICB0aGlzLl9fZ2VuZXJhdGVkTWFwcGluZ3MgPSBnZW5lcmF0ZWRNYXBwaW5ncztcblxuICAgIHF1aWNrU29ydChvcmlnaW5hbE1hcHBpbmdzLCB1dGlsLmNvbXBhcmVCeU9yaWdpbmFsUG9zaXRpb25zKTtcbiAgICB0aGlzLl9fb3JpZ2luYWxNYXBwaW5ncyA9IG9yaWdpbmFsTWFwcGluZ3M7XG4gIH07XG5cbi8qKlxuICogRmluZCB0aGUgbWFwcGluZyB0aGF0IGJlc3QgbWF0Y2hlcyB0aGUgaHlwb3RoZXRpY2FsIFwibmVlZGxlXCIgbWFwcGluZyB0aGF0XG4gKiB3ZSBhcmUgc2VhcmNoaW5nIGZvciBpbiB0aGUgZ2l2ZW4gXCJoYXlzdGFja1wiIG9mIG1hcHBpbmdzLlxuICovXG5CYXNpY1NvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5fZmluZE1hcHBpbmcgPVxuICBmdW5jdGlvbiBTb3VyY2VNYXBDb25zdW1lcl9maW5kTWFwcGluZyhhTmVlZGxlLCBhTWFwcGluZ3MsIGFMaW5lTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUNvbHVtbk5hbWUsIGFDb21wYXJhdG9yLCBhQmlhcykge1xuICAgIC8vIFRvIHJldHVybiB0aGUgcG9zaXRpb24gd2UgYXJlIHNlYXJjaGluZyBmb3IsIHdlIG11c3QgZmlyc3QgZmluZCB0aGVcbiAgICAvLyBtYXBwaW5nIGZvciB0aGUgZ2l2ZW4gcG9zaXRpb24gYW5kIHRoZW4gcmV0dXJuIHRoZSBvcHBvc2l0ZSBwb3NpdGlvbiBpdFxuICAgIC8vIHBvaW50cyB0by4gQmVjYXVzZSB0aGUgbWFwcGluZ3MgYXJlIHNvcnRlZCwgd2UgY2FuIHVzZSBiaW5hcnkgc2VhcmNoIHRvXG4gICAgLy8gZmluZCB0aGUgYmVzdCBtYXBwaW5nLlxuXG4gICAgaWYgKGFOZWVkbGVbYUxpbmVOYW1lXSA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdMaW5lIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEsIGdvdCAnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICsgYU5lZWRsZVthTGluZU5hbWVdKTtcbiAgICB9XG4gICAgaWYgKGFOZWVkbGVbYUNvbHVtbk5hbWVdIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQ29sdW1uIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDAsIGdvdCAnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICsgYU5lZWRsZVthQ29sdW1uTmFtZV0pO1xuICAgIH1cblxuICAgIHJldHVybiBiaW5hcnlTZWFyY2guc2VhcmNoKGFOZWVkbGUsIGFNYXBwaW5ncywgYUNvbXBhcmF0b3IsIGFCaWFzKTtcbiAgfTtcblxuLyoqXG4gKiBDb21wdXRlIHRoZSBsYXN0IGNvbHVtbiBmb3IgZWFjaCBnZW5lcmF0ZWQgbWFwcGluZy4gVGhlIGxhc3QgY29sdW1uIGlzXG4gKiBpbmNsdXNpdmUuXG4gKi9cbkJhc2ljU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLmNvbXB1dGVDb2x1bW5TcGFucyA9XG4gIGZ1bmN0aW9uIFNvdXJjZU1hcENvbnN1bWVyX2NvbXB1dGVDb2x1bW5TcGFucygpIHtcbiAgICBmb3IgKHZhciBpbmRleCA9IDA7IGluZGV4IDwgdGhpcy5fZ2VuZXJhdGVkTWFwcGluZ3MubGVuZ3RoOyArK2luZGV4KSB7XG4gICAgICB2YXIgbWFwcGluZyA9IHRoaXMuX2dlbmVyYXRlZE1hcHBpbmdzW2luZGV4XTtcblxuICAgICAgLy8gTWFwcGluZ3MgZG8gbm90IGNvbnRhaW4gYSBmaWVsZCBmb3IgdGhlIGxhc3QgZ2VuZXJhdGVkIGNvbHVtbnQuIFdlXG4gICAgICAvLyBjYW4gY29tZSB1cCB3aXRoIGFuIG9wdGltaXN0aWMgZXN0aW1hdGUsIGhvd2V2ZXIsIGJ5IGFzc3VtaW5nIHRoYXRcbiAgICAgIC8vIG1hcHBpbmdzIGFyZSBjb250aWd1b3VzIChpLmUuIGdpdmVuIHR3byBjb25zZWN1dGl2ZSBtYXBwaW5ncywgdGhlXG4gICAgICAvLyBmaXJzdCBtYXBwaW5nIGVuZHMgd2hlcmUgdGhlIHNlY29uZCBvbmUgc3RhcnRzKS5cbiAgICAgIGlmIChpbmRleCArIDEgPCB0aGlzLl9nZW5lcmF0ZWRNYXBwaW5ncy5sZW5ndGgpIHtcbiAgICAgICAgdmFyIG5leHRNYXBwaW5nID0gdGhpcy5fZ2VuZXJhdGVkTWFwcGluZ3NbaW5kZXggKyAxXTtcblxuICAgICAgICBpZiAobWFwcGluZy5nZW5lcmF0ZWRMaW5lID09PSBuZXh0TWFwcGluZy5nZW5lcmF0ZWRMaW5lKSB7XG4gICAgICAgICAgbWFwcGluZy5sYXN0R2VuZXJhdGVkQ29sdW1uID0gbmV4dE1hcHBpbmcuZ2VuZXJhdGVkQ29sdW1uIC0gMTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBUaGUgbGFzdCBtYXBwaW5nIGZvciBlYWNoIGxpbmUgc3BhbnMgdGhlIGVudGlyZSBsaW5lLlxuICAgICAgbWFwcGluZy5sYXN0R2VuZXJhdGVkQ29sdW1uID0gSW5maW5pdHk7XG4gICAgfVxuICB9O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIG9yaWdpbmFsIHNvdXJjZSwgbGluZSwgYW5kIGNvbHVtbiBpbmZvcm1hdGlvbiBmb3IgdGhlIGdlbmVyYXRlZFxuICogc291cmNlJ3MgbGluZSBhbmQgY29sdW1uIHBvc2l0aW9ucyBwcm92aWRlZC4gVGhlIG9ubHkgYXJndW1lbnQgaXMgYW4gb2JqZWN0XG4gKiB3aXRoIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczpcbiAqXG4gKiAgIC0gbGluZTogVGhlIGxpbmUgbnVtYmVyIGluIHRoZSBnZW5lcmF0ZWQgc291cmNlLlxuICogICAtIGNvbHVtbjogVGhlIGNvbHVtbiBudW1iZXIgaW4gdGhlIGdlbmVyYXRlZCBzb3VyY2UuXG4gKiAgIC0gYmlhczogRWl0aGVyICdTb3VyY2VNYXBDb25zdW1lci5HUkVBVEVTVF9MT1dFUl9CT1VORCcgb3JcbiAqICAgICAnU291cmNlTWFwQ29uc3VtZXIuTEVBU1RfVVBQRVJfQk9VTkQnLiBTcGVjaWZpZXMgd2hldGhlciB0byByZXR1cm4gdGhlXG4gKiAgICAgY2xvc2VzdCBlbGVtZW50IHRoYXQgaXMgc21hbGxlciB0aGFuIG9yIGdyZWF0ZXIgdGhhbiB0aGUgb25lIHdlIGFyZVxuICogICAgIHNlYXJjaGluZyBmb3IsIHJlc3BlY3RpdmVseSwgaWYgdGhlIGV4YWN0IGVsZW1lbnQgY2Fubm90IGJlIGZvdW5kLlxuICogICAgIERlZmF1bHRzIHRvICdTb3VyY2VNYXBDb25zdW1lci5HUkVBVEVTVF9MT1dFUl9CT1VORCcuXG4gKlxuICogYW5kIGFuIG9iamVjdCBpcyByZXR1cm5lZCB3aXRoIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczpcbiAqXG4gKiAgIC0gc291cmNlOiBUaGUgb3JpZ2luYWwgc291cmNlIGZpbGUsIG9yIG51bGwuXG4gKiAgIC0gbGluZTogVGhlIGxpbmUgbnVtYmVyIGluIHRoZSBvcmlnaW5hbCBzb3VyY2UsIG9yIG51bGwuXG4gKiAgIC0gY29sdW1uOiBUaGUgY29sdW1uIG51bWJlciBpbiB0aGUgb3JpZ2luYWwgc291cmNlLCBvciBudWxsLlxuICogICAtIG5hbWU6IFRoZSBvcmlnaW5hbCBpZGVudGlmaWVyLCBvciBudWxsLlxuICovXG5CYXNpY1NvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5vcmlnaW5hbFBvc2l0aW9uRm9yID1cbiAgZnVuY3Rpb24gU291cmNlTWFwQ29uc3VtZXJfb3JpZ2luYWxQb3NpdGlvbkZvcihhQXJncykge1xuICAgIHZhciBuZWVkbGUgPSB7XG4gICAgICBnZW5lcmF0ZWRMaW5lOiB1dGlsLmdldEFyZyhhQXJncywgJ2xpbmUnKSxcbiAgICAgIGdlbmVyYXRlZENvbHVtbjogdXRpbC5nZXRBcmcoYUFyZ3MsICdjb2x1bW4nKVxuICAgIH07XG5cbiAgICB2YXIgaW5kZXggPSB0aGlzLl9maW5kTWFwcGluZyhcbiAgICAgIG5lZWRsZSxcbiAgICAgIHRoaXMuX2dlbmVyYXRlZE1hcHBpbmdzLFxuICAgICAgXCJnZW5lcmF0ZWRMaW5lXCIsXG4gICAgICBcImdlbmVyYXRlZENvbHVtblwiLFxuICAgICAgdXRpbC5jb21wYXJlQnlHZW5lcmF0ZWRQb3NpdGlvbnNEZWZsYXRlZCxcbiAgICAgIHV0aWwuZ2V0QXJnKGFBcmdzLCAnYmlhcycsIFNvdXJjZU1hcENvbnN1bWVyLkdSRUFURVNUX0xPV0VSX0JPVU5EKVxuICAgICk7XG5cbiAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgdmFyIG1hcHBpbmcgPSB0aGlzLl9nZW5lcmF0ZWRNYXBwaW5nc1tpbmRleF07XG5cbiAgICAgIGlmIChtYXBwaW5nLmdlbmVyYXRlZExpbmUgPT09IG5lZWRsZS5nZW5lcmF0ZWRMaW5lKSB7XG4gICAgICAgIHZhciBzb3VyY2UgPSB1dGlsLmdldEFyZyhtYXBwaW5nLCAnc291cmNlJywgbnVsbCk7XG4gICAgICAgIGlmIChzb3VyY2UgIT09IG51bGwpIHtcbiAgICAgICAgICBzb3VyY2UgPSB0aGlzLl9zb3VyY2VzLmF0KHNvdXJjZSk7XG4gICAgICAgICAgaWYgKHRoaXMuc291cmNlUm9vdCAhPSBudWxsKSB7XG4gICAgICAgICAgICBzb3VyY2UgPSB1dGlsLmpvaW4odGhpcy5zb3VyY2VSb290LCBzb3VyY2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YXIgbmFtZSA9IHV0aWwuZ2V0QXJnKG1hcHBpbmcsICduYW1lJywgbnVsbCk7XG4gICAgICAgIGlmIChuYW1lICE9PSBudWxsKSB7XG4gICAgICAgICAgbmFtZSA9IHRoaXMuX25hbWVzLmF0KG5hbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc291cmNlOiBzb3VyY2UsXG4gICAgICAgICAgbGluZTogdXRpbC5nZXRBcmcobWFwcGluZywgJ29yaWdpbmFsTGluZScsIG51bGwpLFxuICAgICAgICAgIGNvbHVtbjogdXRpbC5nZXRBcmcobWFwcGluZywgJ29yaWdpbmFsQ29sdW1uJywgbnVsbCksXG4gICAgICAgICAgbmFtZTogbmFtZVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBzb3VyY2U6IG51bGwsXG4gICAgICBsaW5lOiBudWxsLFxuICAgICAgY29sdW1uOiBudWxsLFxuICAgICAgbmFtZTogbnVsbFxuICAgIH07XG4gIH07XG5cbi8qKlxuICogUmV0dXJuIHRydWUgaWYgd2UgaGF2ZSB0aGUgc291cmNlIGNvbnRlbnQgZm9yIGV2ZXJ5IHNvdXJjZSBpbiB0aGUgc291cmNlXG4gKiBtYXAsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuQmFzaWNTb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUuaGFzQ29udGVudHNPZkFsbFNvdXJjZXMgPVxuICBmdW5jdGlvbiBCYXNpY1NvdXJjZU1hcENvbnN1bWVyX2hhc0NvbnRlbnRzT2ZBbGxTb3VyY2VzKCkge1xuICAgIGlmICghdGhpcy5zb3VyY2VzQ29udGVudCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zb3VyY2VzQ29udGVudC5sZW5ndGggPj0gdGhpcy5fc291cmNlcy5zaXplKCkgJiZcbiAgICAgICF0aGlzLnNvdXJjZXNDb250ZW50LnNvbWUoZnVuY3Rpb24gKHNjKSB7IHJldHVybiBzYyA9PSBudWxsOyB9KTtcbiAgfTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBvcmlnaW5hbCBzb3VyY2UgY29udGVudC4gVGhlIG9ubHkgYXJndW1lbnQgaXMgdGhlIHVybCBvZiB0aGVcbiAqIG9yaWdpbmFsIHNvdXJjZSBmaWxlLiBSZXR1cm5zIG51bGwgaWYgbm8gb3JpZ2luYWwgc291cmNlIGNvbnRlbnQgaXNcbiAqIGF2YWlsYWJsZS5cbiAqL1xuQmFzaWNTb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUuc291cmNlQ29udGVudEZvciA9XG4gIGZ1bmN0aW9uIFNvdXJjZU1hcENvbnN1bWVyX3NvdXJjZUNvbnRlbnRGb3IoYVNvdXJjZSwgbnVsbE9uTWlzc2luZykge1xuICAgIGlmICghdGhpcy5zb3VyY2VzQ29udGVudCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc291cmNlUm9vdCAhPSBudWxsKSB7XG4gICAgICBhU291cmNlID0gdXRpbC5yZWxhdGl2ZSh0aGlzLnNvdXJjZVJvb3QsIGFTb3VyY2UpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9zb3VyY2VzLmhhcyhhU291cmNlKSkge1xuICAgICAgcmV0dXJuIHRoaXMuc291cmNlc0NvbnRlbnRbdGhpcy5fc291cmNlcy5pbmRleE9mKGFTb3VyY2UpXTtcbiAgICB9XG5cbiAgICB2YXIgdXJsO1xuICAgIGlmICh0aGlzLnNvdXJjZVJvb3QgIT0gbnVsbFxuICAgICAgICAmJiAodXJsID0gdXRpbC51cmxQYXJzZSh0aGlzLnNvdXJjZVJvb3QpKSkge1xuICAgICAgLy8gWFhYOiBmaWxlOi8vIFVSSXMgYW5kIGFic29sdXRlIHBhdGhzIGxlYWQgdG8gdW5leHBlY3RlZCBiZWhhdmlvciBmb3JcbiAgICAgIC8vIG1hbnkgdXNlcnMuIFdlIGNhbiBoZWxwIHRoZW0gb3V0IHdoZW4gdGhleSBleHBlY3QgZmlsZTovLyBVUklzIHRvXG4gICAgICAvLyBiZWhhdmUgbGlrZSBpdCB3b3VsZCBpZiB0aGV5IHdlcmUgcnVubmluZyBhIGxvY2FsIEhUVFAgc2VydmVyLiBTZWVcbiAgICAgIC8vIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTg4NTU5Ny5cbiAgICAgIHZhciBmaWxlVXJpQWJzUGF0aCA9IGFTb3VyY2UucmVwbGFjZSgvXmZpbGU6XFwvXFwvLywgXCJcIik7XG4gICAgICBpZiAodXJsLnNjaGVtZSA9PSBcImZpbGVcIlxuICAgICAgICAgICYmIHRoaXMuX3NvdXJjZXMuaGFzKGZpbGVVcmlBYnNQYXRoKSkge1xuICAgICAgICByZXR1cm4gdGhpcy5zb3VyY2VzQ29udGVudFt0aGlzLl9zb3VyY2VzLmluZGV4T2YoZmlsZVVyaUFic1BhdGgpXVxuICAgICAgfVxuXG4gICAgICBpZiAoKCF1cmwucGF0aCB8fCB1cmwucGF0aCA9PSBcIi9cIilcbiAgICAgICAgICAmJiB0aGlzLl9zb3VyY2VzLmhhcyhcIi9cIiArIGFTb3VyY2UpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNvdXJjZXNDb250ZW50W3RoaXMuX3NvdXJjZXMuaW5kZXhPZihcIi9cIiArIGFTb3VyY2UpXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgcmVjdXJzaXZlbHkgZnJvbVxuICAgIC8vIEluZGV4ZWRTb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUuc291cmNlQ29udGVudEZvci4gSW4gdGhhdCBjYXNlLCB3ZVxuICAgIC8vIGRvbid0IHdhbnQgdG8gdGhyb3cgaWYgd2UgY2FuJ3QgZmluZCB0aGUgc291cmNlIC0gd2UganVzdCB3YW50IHRvXG4gICAgLy8gcmV0dXJuIG51bGwsIHNvIHdlIHByb3ZpZGUgYSBmbGFnIHRvIGV4aXQgZ3JhY2VmdWxseS5cbiAgICBpZiAobnVsbE9uTWlzc2luZykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdcIicgKyBhU291cmNlICsgJ1wiIGlzIG5vdCBpbiB0aGUgU291cmNlTWFwLicpO1xuICAgIH1cbiAgfTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBnZW5lcmF0ZWQgbGluZSBhbmQgY29sdW1uIGluZm9ybWF0aW9uIGZvciB0aGUgb3JpZ2luYWwgc291cmNlLFxuICogbGluZSwgYW5kIGNvbHVtbiBwb3NpdGlvbnMgcHJvdmlkZWQuIFRoZSBvbmx5IGFyZ3VtZW50IGlzIGFuIG9iamVjdCB3aXRoXG4gKiB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogICAtIHNvdXJjZTogVGhlIGZpbGVuYW1lIG9mIHRoZSBvcmlnaW5hbCBzb3VyY2UuXG4gKiAgIC0gbGluZTogVGhlIGxpbmUgbnVtYmVyIGluIHRoZSBvcmlnaW5hbCBzb3VyY2UuXG4gKiAgIC0gY29sdW1uOiBUaGUgY29sdW1uIG51bWJlciBpbiB0aGUgb3JpZ2luYWwgc291cmNlLlxuICogICAtIGJpYXM6IEVpdGhlciAnU291cmNlTWFwQ29uc3VtZXIuR1JFQVRFU1RfTE9XRVJfQk9VTkQnIG9yXG4gKiAgICAgJ1NvdXJjZU1hcENvbnN1bWVyLkxFQVNUX1VQUEVSX0JPVU5EJy4gU3BlY2lmaWVzIHdoZXRoZXIgdG8gcmV0dXJuIHRoZVxuICogICAgIGNsb3Nlc3QgZWxlbWVudCB0aGF0IGlzIHNtYWxsZXIgdGhhbiBvciBncmVhdGVyIHRoYW4gdGhlIG9uZSB3ZSBhcmVcbiAqICAgICBzZWFyY2hpbmcgZm9yLCByZXNwZWN0aXZlbHksIGlmIHRoZSBleGFjdCBlbGVtZW50IGNhbm5vdCBiZSBmb3VuZC5cbiAqICAgICBEZWZhdWx0cyB0byAnU291cmNlTWFwQ29uc3VtZXIuR1JFQVRFU1RfTE9XRVJfQk9VTkQnLlxuICpcbiAqIGFuZCBhbiBvYmplY3QgaXMgcmV0dXJuZWQgd2l0aCB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogICAtIGxpbmU6IFRoZSBsaW5lIG51bWJlciBpbiB0aGUgZ2VuZXJhdGVkIHNvdXJjZSwgb3IgbnVsbC5cbiAqICAgLSBjb2x1bW46IFRoZSBjb2x1bW4gbnVtYmVyIGluIHRoZSBnZW5lcmF0ZWQgc291cmNlLCBvciBudWxsLlxuICovXG5CYXNpY1NvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5nZW5lcmF0ZWRQb3NpdGlvbkZvciA9XG4gIGZ1bmN0aW9uIFNvdXJjZU1hcENvbnN1bWVyX2dlbmVyYXRlZFBvc2l0aW9uRm9yKGFBcmdzKSB7XG4gICAgdmFyIHNvdXJjZSA9IHV0aWwuZ2V0QXJnKGFBcmdzLCAnc291cmNlJyk7XG4gICAgaWYgKHRoaXMuc291cmNlUm9vdCAhPSBudWxsKSB7XG4gICAgICBzb3VyY2UgPSB1dGlsLnJlbGF0aXZlKHRoaXMuc291cmNlUm9vdCwgc291cmNlKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLl9zb3VyY2VzLmhhcyhzb3VyY2UpKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBsaW5lOiBudWxsLFxuICAgICAgICBjb2x1bW46IG51bGwsXG4gICAgICAgIGxhc3RDb2x1bW46IG51bGxcbiAgICAgIH07XG4gICAgfVxuICAgIHNvdXJjZSA9IHRoaXMuX3NvdXJjZXMuaW5kZXhPZihzb3VyY2UpO1xuXG4gICAgdmFyIG5lZWRsZSA9IHtcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgb3JpZ2luYWxMaW5lOiB1dGlsLmdldEFyZyhhQXJncywgJ2xpbmUnKSxcbiAgICAgIG9yaWdpbmFsQ29sdW1uOiB1dGlsLmdldEFyZyhhQXJncywgJ2NvbHVtbicpXG4gICAgfTtcblxuICAgIHZhciBpbmRleCA9IHRoaXMuX2ZpbmRNYXBwaW5nKFxuICAgICAgbmVlZGxlLFxuICAgICAgdGhpcy5fb3JpZ2luYWxNYXBwaW5ncyxcbiAgICAgIFwib3JpZ2luYWxMaW5lXCIsXG4gICAgICBcIm9yaWdpbmFsQ29sdW1uXCIsXG4gICAgICB1dGlsLmNvbXBhcmVCeU9yaWdpbmFsUG9zaXRpb25zLFxuICAgICAgdXRpbC5nZXRBcmcoYUFyZ3MsICdiaWFzJywgU291cmNlTWFwQ29uc3VtZXIuR1JFQVRFU1RfTE9XRVJfQk9VTkQpXG4gICAgKTtcblxuICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICB2YXIgbWFwcGluZyA9IHRoaXMuX29yaWdpbmFsTWFwcGluZ3NbaW5kZXhdO1xuXG4gICAgICBpZiAobWFwcGluZy5zb3VyY2UgPT09IG5lZWRsZS5zb3VyY2UpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBsaW5lOiB1dGlsLmdldEFyZyhtYXBwaW5nLCAnZ2VuZXJhdGVkTGluZScsIG51bGwpLFxuICAgICAgICAgIGNvbHVtbjogdXRpbC5nZXRBcmcobWFwcGluZywgJ2dlbmVyYXRlZENvbHVtbicsIG51bGwpLFxuICAgICAgICAgIGxhc3RDb2x1bW46IHV0aWwuZ2V0QXJnKG1hcHBpbmcsICdsYXN0R2VuZXJhdGVkQ29sdW1uJywgbnVsbClcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgbGluZTogbnVsbCxcbiAgICAgIGNvbHVtbjogbnVsbCxcbiAgICAgIGxhc3RDb2x1bW46IG51bGxcbiAgICB9O1xuICB9O1xuXG5leHBvcnRzLkJhc2ljU291cmNlTWFwQ29uc3VtZXIgPSBCYXNpY1NvdXJjZU1hcENvbnN1bWVyO1xuXG4vKipcbiAqIEFuIEluZGV4ZWRTb3VyY2VNYXBDb25zdW1lciBpbnN0YW5jZSByZXByZXNlbnRzIGEgcGFyc2VkIHNvdXJjZSBtYXAgd2hpY2hcbiAqIHdlIGNhbiBxdWVyeSBmb3IgaW5mb3JtYXRpb24uIEl0IGRpZmZlcnMgZnJvbSBCYXNpY1NvdXJjZU1hcENvbnN1bWVyIGluXG4gKiB0aGF0IGl0IHRha2VzIFwiaW5kZXhlZFwiIHNvdXJjZSBtYXBzIChpLmUuIG9uZXMgd2l0aCBhIFwic2VjdGlvbnNcIiBmaWVsZCkgYXNcbiAqIGlucHV0LlxuICpcbiAqIFRoZSBvbmx5IHBhcmFtZXRlciBpcyBhIHJhdyBzb3VyY2UgbWFwIChlaXRoZXIgYXMgYSBKU09OIHN0cmluZywgb3IgYWxyZWFkeVxuICogcGFyc2VkIHRvIGFuIG9iamVjdCkuIEFjY29yZGluZyB0byB0aGUgc3BlYyBmb3IgaW5kZXhlZCBzb3VyY2UgbWFwcywgdGhleVxuICogaGF2ZSB0aGUgZm9sbG93aW5nIGF0dHJpYnV0ZXM6XG4gKlxuICogICAtIHZlcnNpb246IFdoaWNoIHZlcnNpb24gb2YgdGhlIHNvdXJjZSBtYXAgc3BlYyB0aGlzIG1hcCBpcyBmb2xsb3dpbmcuXG4gKiAgIC0gZmlsZTogT3B0aW9uYWwuIFRoZSBnZW5lcmF0ZWQgZmlsZSB0aGlzIHNvdXJjZSBtYXAgaXMgYXNzb2NpYXRlZCB3aXRoLlxuICogICAtIHNlY3Rpb25zOiBBIGxpc3Qgb2Ygc2VjdGlvbiBkZWZpbml0aW9ucy5cbiAqXG4gKiBFYWNoIHZhbHVlIHVuZGVyIHRoZSBcInNlY3Rpb25zXCIgZmllbGQgaGFzIHR3byBmaWVsZHM6XG4gKiAgIC0gb2Zmc2V0OiBUaGUgb2Zmc2V0IGludG8gdGhlIG9yaWdpbmFsIHNwZWNpZmllZCBhdCB3aGljaCB0aGlzIHNlY3Rpb25cbiAqICAgICAgIGJlZ2lucyB0byBhcHBseSwgZGVmaW5lZCBhcyBhbiBvYmplY3Qgd2l0aCBhIFwibGluZVwiIGFuZCBcImNvbHVtblwiXG4gKiAgICAgICBmaWVsZC5cbiAqICAgLSBtYXA6IEEgc291cmNlIG1hcCBkZWZpbml0aW9uLiBUaGlzIHNvdXJjZSBtYXAgY291bGQgYWxzbyBiZSBpbmRleGVkLFxuICogICAgICAgYnV0IGRvZXNuJ3QgaGF2ZSB0byBiZS5cbiAqXG4gKiBJbnN0ZWFkIG9mIHRoZSBcIm1hcFwiIGZpZWxkLCBpdCdzIGFsc28gcG9zc2libGUgdG8gaGF2ZSBhIFwidXJsXCIgZmllbGRcbiAqIHNwZWNpZnlpbmcgYSBVUkwgdG8gcmV0cmlldmUgYSBzb3VyY2UgbWFwIGZyb20sIGJ1dCB0aGF0J3MgY3VycmVudGx5XG4gKiB1bnN1cHBvcnRlZC5cbiAqXG4gKiBIZXJlJ3MgYW4gZXhhbXBsZSBzb3VyY2UgbWFwLCB0YWtlbiBmcm9tIHRoZSBzb3VyY2UgbWFwIHNwZWNbMF0sIGJ1dFxuICogbW9kaWZpZWQgdG8gb21pdCBhIHNlY3Rpb24gd2hpY2ggdXNlcyB0aGUgXCJ1cmxcIiBmaWVsZC5cbiAqXG4gKiAge1xuICogICAgdmVyc2lvbiA6IDMsXG4gKiAgICBmaWxlOiBcImFwcC5qc1wiLFxuICogICAgc2VjdGlvbnM6IFt7XG4gKiAgICAgIG9mZnNldDoge2xpbmU6MTAwLCBjb2x1bW46MTB9LFxuICogICAgICBtYXA6IHtcbiAqICAgICAgICB2ZXJzaW9uIDogMyxcbiAqICAgICAgICBmaWxlOiBcInNlY3Rpb24uanNcIixcbiAqICAgICAgICBzb3VyY2VzOiBbXCJmb28uanNcIiwgXCJiYXIuanNcIl0sXG4gKiAgICAgICAgbmFtZXM6IFtcInNyY1wiLCBcIm1hcHNcIiwgXCJhcmVcIiwgXCJmdW5cIl0sXG4gKiAgICAgICAgbWFwcGluZ3M6IFwiQUFBQSxFOztBQkNERTtcIlxuICogICAgICB9XG4gKiAgICB9XSxcbiAqICB9XG4gKlxuICogWzBdOiBodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9kb2N1bWVudC9kLzFVMVJHQWVoUXdSeXBVVG92RjFLUmxwaU9GemUwYi1fMmdjNmZBSDBLWTBrL2VkaXQjaGVhZGluZz1oLjUzNWVzM3hlcHJndFxuICovXG5mdW5jdGlvbiBJbmRleGVkU291cmNlTWFwQ29uc3VtZXIoYVNvdXJjZU1hcCkge1xuICB2YXIgc291cmNlTWFwID0gYVNvdXJjZU1hcDtcbiAgaWYgKHR5cGVvZiBhU291cmNlTWFwID09PSAnc3RyaW5nJykge1xuICAgIHNvdXJjZU1hcCA9IEpTT04ucGFyc2UoYVNvdXJjZU1hcC5yZXBsYWNlKC9eXFwpXFxdXFx9Jy8sICcnKSk7XG4gIH1cblxuICB2YXIgdmVyc2lvbiA9IHV0aWwuZ2V0QXJnKHNvdXJjZU1hcCwgJ3ZlcnNpb24nKTtcbiAgdmFyIHNlY3Rpb25zID0gdXRpbC5nZXRBcmcoc291cmNlTWFwLCAnc2VjdGlvbnMnKTtcblxuICBpZiAodmVyc2lvbiAhPSB0aGlzLl92ZXJzaW9uKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCB2ZXJzaW9uOiAnICsgdmVyc2lvbik7XG4gIH1cblxuICB0aGlzLl9zb3VyY2VzID0gbmV3IEFycmF5U2V0KCk7XG4gIHRoaXMuX25hbWVzID0gbmV3IEFycmF5U2V0KCk7XG5cbiAgdmFyIGxhc3RPZmZzZXQgPSB7XG4gICAgbGluZTogLTEsXG4gICAgY29sdW1uOiAwXG4gIH07XG4gIHRoaXMuX3NlY3Rpb25zID0gc2VjdGlvbnMubWFwKGZ1bmN0aW9uIChzKSB7XG4gICAgaWYgKHMudXJsKSB7XG4gICAgICAvLyBUaGUgdXJsIGZpZWxkIHdpbGwgcmVxdWlyZSBzdXBwb3J0IGZvciBhc3luY2hyb25pY2l0eS5cbiAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vbW96aWxsYS9zb3VyY2UtbWFwL2lzc3Vlcy8xNlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdTdXBwb3J0IGZvciB1cmwgZmllbGQgaW4gc2VjdGlvbnMgbm90IGltcGxlbWVudGVkLicpO1xuICAgIH1cbiAgICB2YXIgb2Zmc2V0ID0gdXRpbC5nZXRBcmcocywgJ29mZnNldCcpO1xuICAgIHZhciBvZmZzZXRMaW5lID0gdXRpbC5nZXRBcmcob2Zmc2V0LCAnbGluZScpO1xuICAgIHZhciBvZmZzZXRDb2x1bW4gPSB1dGlsLmdldEFyZyhvZmZzZXQsICdjb2x1bW4nKTtcblxuICAgIGlmIChvZmZzZXRMaW5lIDwgbGFzdE9mZnNldC5saW5lIHx8XG4gICAgICAgIChvZmZzZXRMaW5lID09PSBsYXN0T2Zmc2V0LmxpbmUgJiYgb2Zmc2V0Q29sdW1uIDwgbGFzdE9mZnNldC5jb2x1bW4pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NlY3Rpb24gb2Zmc2V0cyBtdXN0IGJlIG9yZGVyZWQgYW5kIG5vbi1vdmVybGFwcGluZy4nKTtcbiAgICB9XG4gICAgbGFzdE9mZnNldCA9IG9mZnNldDtcblxuICAgIHJldHVybiB7XG4gICAgICBnZW5lcmF0ZWRPZmZzZXQ6IHtcbiAgICAgICAgLy8gVGhlIG9mZnNldCBmaWVsZHMgYXJlIDAtYmFzZWQsIGJ1dCB3ZSB1c2UgMS1iYXNlZCBpbmRpY2VzIHdoZW5cbiAgICAgICAgLy8gZW5jb2RpbmcvZGVjb2RpbmcgZnJvbSBWTFEuXG4gICAgICAgIGdlbmVyYXRlZExpbmU6IG9mZnNldExpbmUgKyAxLFxuICAgICAgICBnZW5lcmF0ZWRDb2x1bW46IG9mZnNldENvbHVtbiArIDFcbiAgICAgIH0sXG4gICAgICBjb25zdW1lcjogbmV3IFNvdXJjZU1hcENvbnN1bWVyKHV0aWwuZ2V0QXJnKHMsICdtYXAnKSlcbiAgICB9XG4gIH0pO1xufVxuXG5JbmRleGVkU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShTb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUpO1xuSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFNvdXJjZU1hcENvbnN1bWVyO1xuXG4vKipcbiAqIFRoZSB2ZXJzaW9uIG9mIHRoZSBzb3VyY2UgbWFwcGluZyBzcGVjIHRoYXQgd2UgYXJlIGNvbnN1bWluZy5cbiAqL1xuSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5fdmVyc2lvbiA9IDM7XG5cbi8qKlxuICogVGhlIGxpc3Qgb2Ygb3JpZ2luYWwgc291cmNlcy5cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KEluZGV4ZWRTb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUsICdzb3VyY2VzJywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc291cmNlcyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fc2VjdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdGhpcy5fc2VjdGlvbnNbaV0uY29uc3VtZXIuc291cmNlcy5sZW5ndGg7IGorKykge1xuICAgICAgICBzb3VyY2VzLnB1c2godGhpcy5fc2VjdGlvbnNbaV0uY29uc3VtZXIuc291cmNlc1tqXSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzb3VyY2VzO1xuICB9XG59KTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBvcmlnaW5hbCBzb3VyY2UsIGxpbmUsIGFuZCBjb2x1bW4gaW5mb3JtYXRpb24gZm9yIHRoZSBnZW5lcmF0ZWRcbiAqIHNvdXJjZSdzIGxpbmUgYW5kIGNvbHVtbiBwb3NpdGlvbnMgcHJvdmlkZWQuIFRoZSBvbmx5IGFyZ3VtZW50IGlzIGFuIG9iamVjdFxuICogd2l0aCB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogICAtIGxpbmU6IFRoZSBsaW5lIG51bWJlciBpbiB0aGUgZ2VuZXJhdGVkIHNvdXJjZS5cbiAqICAgLSBjb2x1bW46IFRoZSBjb2x1bW4gbnVtYmVyIGluIHRoZSBnZW5lcmF0ZWQgc291cmNlLlxuICpcbiAqIGFuZCBhbiBvYmplY3QgaXMgcmV0dXJuZWQgd2l0aCB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogICAtIHNvdXJjZTogVGhlIG9yaWdpbmFsIHNvdXJjZSBmaWxlLCBvciBudWxsLlxuICogICAtIGxpbmU6IFRoZSBsaW5lIG51bWJlciBpbiB0aGUgb3JpZ2luYWwgc291cmNlLCBvciBudWxsLlxuICogICAtIGNvbHVtbjogVGhlIGNvbHVtbiBudW1iZXIgaW4gdGhlIG9yaWdpbmFsIHNvdXJjZSwgb3IgbnVsbC5cbiAqICAgLSBuYW1lOiBUaGUgb3JpZ2luYWwgaWRlbnRpZmllciwgb3IgbnVsbC5cbiAqL1xuSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5vcmlnaW5hbFBvc2l0aW9uRm9yID1cbiAgZnVuY3Rpb24gSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyX29yaWdpbmFsUG9zaXRpb25Gb3IoYUFyZ3MpIHtcbiAgICB2YXIgbmVlZGxlID0ge1xuICAgICAgZ2VuZXJhdGVkTGluZTogdXRpbC5nZXRBcmcoYUFyZ3MsICdsaW5lJyksXG4gICAgICBnZW5lcmF0ZWRDb2x1bW46IHV0aWwuZ2V0QXJnKGFBcmdzLCAnY29sdW1uJylcbiAgICB9O1xuXG4gICAgLy8gRmluZCB0aGUgc2VjdGlvbiBjb250YWluaW5nIHRoZSBnZW5lcmF0ZWQgcG9zaXRpb24gd2UncmUgdHJ5aW5nIHRvIG1hcFxuICAgIC8vIHRvIGFuIG9yaWdpbmFsIHBvc2l0aW9uLlxuICAgIHZhciBzZWN0aW9uSW5kZXggPSBiaW5hcnlTZWFyY2guc2VhcmNoKG5lZWRsZSwgdGhpcy5fc2VjdGlvbnMsXG4gICAgICBmdW5jdGlvbihuZWVkbGUsIHNlY3Rpb24pIHtcbiAgICAgICAgdmFyIGNtcCA9IG5lZWRsZS5nZW5lcmF0ZWRMaW5lIC0gc2VjdGlvbi5nZW5lcmF0ZWRPZmZzZXQuZ2VuZXJhdGVkTGluZTtcbiAgICAgICAgaWYgKGNtcCkge1xuICAgICAgICAgIHJldHVybiBjbXA7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gKG5lZWRsZS5nZW5lcmF0ZWRDb2x1bW4gLVxuICAgICAgICAgICAgICAgIHNlY3Rpb24uZ2VuZXJhdGVkT2Zmc2V0LmdlbmVyYXRlZENvbHVtbik7XG4gICAgICB9KTtcbiAgICB2YXIgc2VjdGlvbiA9IHRoaXMuX3NlY3Rpb25zW3NlY3Rpb25JbmRleF07XG5cbiAgICBpZiAoIXNlY3Rpb24pIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHNvdXJjZTogbnVsbCxcbiAgICAgICAgbGluZTogbnVsbCxcbiAgICAgICAgY29sdW1uOiBudWxsLFxuICAgICAgICBuYW1lOiBudWxsXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBzZWN0aW9uLmNvbnN1bWVyLm9yaWdpbmFsUG9zaXRpb25Gb3Ioe1xuICAgICAgbGluZTogbmVlZGxlLmdlbmVyYXRlZExpbmUgLVxuICAgICAgICAoc2VjdGlvbi5nZW5lcmF0ZWRPZmZzZXQuZ2VuZXJhdGVkTGluZSAtIDEpLFxuICAgICAgY29sdW1uOiBuZWVkbGUuZ2VuZXJhdGVkQ29sdW1uIC1cbiAgICAgICAgKHNlY3Rpb24uZ2VuZXJhdGVkT2Zmc2V0LmdlbmVyYXRlZExpbmUgPT09IG5lZWRsZS5nZW5lcmF0ZWRMaW5lXG4gICAgICAgICA/IHNlY3Rpb24uZ2VuZXJhdGVkT2Zmc2V0LmdlbmVyYXRlZENvbHVtbiAtIDFcbiAgICAgICAgIDogMCksXG4gICAgICBiaWFzOiBhQXJncy5iaWFzXG4gICAgfSk7XG4gIH07XG5cbi8qKlxuICogUmV0dXJuIHRydWUgaWYgd2UgaGF2ZSB0aGUgc291cmNlIGNvbnRlbnQgZm9yIGV2ZXJ5IHNvdXJjZSBpbiB0aGUgc291cmNlXG4gKiBtYXAsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5oYXNDb250ZW50c09mQWxsU291cmNlcyA9XG4gIGZ1bmN0aW9uIEluZGV4ZWRTb3VyY2VNYXBDb25zdW1lcl9oYXNDb250ZW50c09mQWxsU291cmNlcygpIHtcbiAgICByZXR1cm4gdGhpcy5fc2VjdGlvbnMuZXZlcnkoZnVuY3Rpb24gKHMpIHtcbiAgICAgIHJldHVybiBzLmNvbnN1bWVyLmhhc0NvbnRlbnRzT2ZBbGxTb3VyY2VzKCk7XG4gICAgfSk7XG4gIH07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgb3JpZ2luYWwgc291cmNlIGNvbnRlbnQuIFRoZSBvbmx5IGFyZ3VtZW50IGlzIHRoZSB1cmwgb2YgdGhlXG4gKiBvcmlnaW5hbCBzb3VyY2UgZmlsZS4gUmV0dXJucyBudWxsIGlmIG5vIG9yaWdpbmFsIHNvdXJjZSBjb250ZW50IGlzXG4gKiBhdmFpbGFibGUuXG4gKi9cbkluZGV4ZWRTb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUuc291cmNlQ29udGVudEZvciA9XG4gIGZ1bmN0aW9uIEluZGV4ZWRTb3VyY2VNYXBDb25zdW1lcl9zb3VyY2VDb250ZW50Rm9yKGFTb3VyY2UsIG51bGxPbk1pc3NpbmcpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX3NlY3Rpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgc2VjdGlvbiA9IHRoaXMuX3NlY3Rpb25zW2ldO1xuXG4gICAgICB2YXIgY29udGVudCA9IHNlY3Rpb24uY29uc3VtZXIuc291cmNlQ29udGVudEZvcihhU291cmNlLCB0cnVlKTtcbiAgICAgIGlmIChjb250ZW50KSB7XG4gICAgICAgIHJldHVybiBjb250ZW50O1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAobnVsbE9uTWlzc2luZykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdcIicgKyBhU291cmNlICsgJ1wiIGlzIG5vdCBpbiB0aGUgU291cmNlTWFwLicpO1xuICAgIH1cbiAgfTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBnZW5lcmF0ZWQgbGluZSBhbmQgY29sdW1uIGluZm9ybWF0aW9uIGZvciB0aGUgb3JpZ2luYWwgc291cmNlLFxuICogbGluZSwgYW5kIGNvbHVtbiBwb3NpdGlvbnMgcHJvdmlkZWQuIFRoZSBvbmx5IGFyZ3VtZW50IGlzIGFuIG9iamVjdCB3aXRoXG4gKiB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogICAtIHNvdXJjZTogVGhlIGZpbGVuYW1lIG9mIHRoZSBvcmlnaW5hbCBzb3VyY2UuXG4gKiAgIC0gbGluZTogVGhlIGxpbmUgbnVtYmVyIGluIHRoZSBvcmlnaW5hbCBzb3VyY2UuXG4gKiAgIC0gY29sdW1uOiBUaGUgY29sdW1uIG51bWJlciBpbiB0aGUgb3JpZ2luYWwgc291cmNlLlxuICpcbiAqIGFuZCBhbiBvYmplY3QgaXMgcmV0dXJuZWQgd2l0aCB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogICAtIGxpbmU6IFRoZSBsaW5lIG51bWJlciBpbiB0aGUgZ2VuZXJhdGVkIHNvdXJjZSwgb3IgbnVsbC5cbiAqICAgLSBjb2x1bW46IFRoZSBjb2x1bW4gbnVtYmVyIGluIHRoZSBnZW5lcmF0ZWQgc291cmNlLCBvciBudWxsLlxuICovXG5JbmRleGVkU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLmdlbmVyYXRlZFBvc2l0aW9uRm9yID1cbiAgZnVuY3Rpb24gSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyX2dlbmVyYXRlZFBvc2l0aW9uRm9yKGFBcmdzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLl9zZWN0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHNlY3Rpb24gPSB0aGlzLl9zZWN0aW9uc1tpXTtcblxuICAgICAgLy8gT25seSBjb25zaWRlciB0aGlzIHNlY3Rpb24gaWYgdGhlIHJlcXVlc3RlZCBzb3VyY2UgaXMgaW4gdGhlIGxpc3Qgb2ZcbiAgICAgIC8vIHNvdXJjZXMgb2YgdGhlIGNvbnN1bWVyLlxuICAgICAgaWYgKHNlY3Rpb24uY29uc3VtZXIuc291cmNlcy5pbmRleE9mKHV0aWwuZ2V0QXJnKGFBcmdzLCAnc291cmNlJykpID09PSAtMSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHZhciBnZW5lcmF0ZWRQb3NpdGlvbiA9IHNlY3Rpb24uY29uc3VtZXIuZ2VuZXJhdGVkUG9zaXRpb25Gb3IoYUFyZ3MpO1xuICAgICAgaWYgKGdlbmVyYXRlZFBvc2l0aW9uKSB7XG4gICAgICAgIHZhciByZXQgPSB7XG4gICAgICAgICAgbGluZTogZ2VuZXJhdGVkUG9zaXRpb24ubGluZSArXG4gICAgICAgICAgICAoc2VjdGlvbi5nZW5lcmF0ZWRPZmZzZXQuZ2VuZXJhdGVkTGluZSAtIDEpLFxuICAgICAgICAgIGNvbHVtbjogZ2VuZXJhdGVkUG9zaXRpb24uY29sdW1uICtcbiAgICAgICAgICAgIChzZWN0aW9uLmdlbmVyYXRlZE9mZnNldC5nZW5lcmF0ZWRMaW5lID09PSBnZW5lcmF0ZWRQb3NpdGlvbi5saW5lXG4gICAgICAgICAgICAgPyBzZWN0aW9uLmdlbmVyYXRlZE9mZnNldC5nZW5lcmF0ZWRDb2x1bW4gLSAxXG4gICAgICAgICAgICAgOiAwKVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBsaW5lOiBudWxsLFxuICAgICAgY29sdW1uOiBudWxsXG4gICAgfTtcbiAgfTtcblxuLyoqXG4gKiBQYXJzZSB0aGUgbWFwcGluZ3MgaW4gYSBzdHJpbmcgaW4gdG8gYSBkYXRhIHN0cnVjdHVyZSB3aGljaCB3ZSBjYW4gZWFzaWx5XG4gKiBxdWVyeSAodGhlIG9yZGVyZWQgYXJyYXlzIGluIHRoZSBgdGhpcy5fX2dlbmVyYXRlZE1hcHBpbmdzYCBhbmRcbiAqIGB0aGlzLl9fb3JpZ2luYWxNYXBwaW5nc2AgcHJvcGVydGllcykuXG4gKi9cbkluZGV4ZWRTb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUuX3BhcnNlTWFwcGluZ3MgPVxuICBmdW5jdGlvbiBJbmRleGVkU291cmNlTWFwQ29uc3VtZXJfcGFyc2VNYXBwaW5ncyhhU3RyLCBhU291cmNlUm9vdCkge1xuICAgIHRoaXMuX19nZW5lcmF0ZWRNYXBwaW5ncyA9IFtdO1xuICAgIHRoaXMuX19vcmlnaW5hbE1hcHBpbmdzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLl9zZWN0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHNlY3Rpb24gPSB0aGlzLl9zZWN0aW9uc1tpXTtcbiAgICAgIHZhciBzZWN0aW9uTWFwcGluZ3MgPSBzZWN0aW9uLmNvbnN1bWVyLl9nZW5lcmF0ZWRNYXBwaW5ncztcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgc2VjdGlvbk1hcHBpbmdzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIHZhciBtYXBwaW5nID0gc2VjdGlvbk1hcHBpbmdzW2pdO1xuXG4gICAgICAgIHZhciBzb3VyY2UgPSBzZWN0aW9uLmNvbnN1bWVyLl9zb3VyY2VzLmF0KG1hcHBpbmcuc291cmNlKTtcbiAgICAgICAgaWYgKHNlY3Rpb24uY29uc3VtZXIuc291cmNlUm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgIHNvdXJjZSA9IHV0aWwuam9pbihzZWN0aW9uLmNvbnN1bWVyLnNvdXJjZVJvb3QsIHNvdXJjZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc291cmNlcy5hZGQoc291cmNlKTtcbiAgICAgICAgc291cmNlID0gdGhpcy5fc291cmNlcy5pbmRleE9mKHNvdXJjZSk7XG5cbiAgICAgICAgdmFyIG5hbWUgPSBzZWN0aW9uLmNvbnN1bWVyLl9uYW1lcy5hdChtYXBwaW5nLm5hbWUpO1xuICAgICAgICB0aGlzLl9uYW1lcy5hZGQobmFtZSk7XG4gICAgICAgIG5hbWUgPSB0aGlzLl9uYW1lcy5pbmRleE9mKG5hbWUpO1xuXG4gICAgICAgIC8vIFRoZSBtYXBwaW5ncyBjb21pbmcgZnJvbSB0aGUgY29uc3VtZXIgZm9yIHRoZSBzZWN0aW9uIGhhdmVcbiAgICAgICAgLy8gZ2VuZXJhdGVkIHBvc2l0aW9ucyByZWxhdGl2ZSB0byB0aGUgc3RhcnQgb2YgdGhlIHNlY3Rpb24sIHNvIHdlXG4gICAgICAgIC8vIG5lZWQgdG8gb2Zmc2V0IHRoZW0gdG8gYmUgcmVsYXRpdmUgdG8gdGhlIHN0YXJ0IG9mIHRoZSBjb25jYXRlbmF0ZWRcbiAgICAgICAgLy8gZ2VuZXJhdGVkIGZpbGUuXG4gICAgICAgIHZhciBhZGp1c3RlZE1hcHBpbmcgPSB7XG4gICAgICAgICAgc291cmNlOiBzb3VyY2UsXG4gICAgICAgICAgZ2VuZXJhdGVkTGluZTogbWFwcGluZy5nZW5lcmF0ZWRMaW5lICtcbiAgICAgICAgICAgIChzZWN0aW9uLmdlbmVyYXRlZE9mZnNldC5nZW5lcmF0ZWRMaW5lIC0gMSksXG4gICAgICAgICAgZ2VuZXJhdGVkQ29sdW1uOiBtYXBwaW5nLmdlbmVyYXRlZENvbHVtbiArXG4gICAgICAgICAgICAoc2VjdGlvbi5nZW5lcmF0ZWRPZmZzZXQuZ2VuZXJhdGVkTGluZSA9PT0gbWFwcGluZy5nZW5lcmF0ZWRMaW5lXG4gICAgICAgICAgICA/IHNlY3Rpb24uZ2VuZXJhdGVkT2Zmc2V0LmdlbmVyYXRlZENvbHVtbiAtIDFcbiAgICAgICAgICAgIDogMCksXG4gICAgICAgICAgb3JpZ2luYWxMaW5lOiBtYXBwaW5nLm9yaWdpbmFsTGluZSxcbiAgICAgICAgICBvcmlnaW5hbENvbHVtbjogbWFwcGluZy5vcmlnaW5hbENvbHVtbixcbiAgICAgICAgICBuYW1lOiBuYW1lXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5fX2dlbmVyYXRlZE1hcHBpbmdzLnB1c2goYWRqdXN0ZWRNYXBwaW5nKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhZGp1c3RlZE1hcHBpbmcub3JpZ2luYWxMaW5lID09PSAnbnVtYmVyJykge1xuICAgICAgICAgIHRoaXMuX19vcmlnaW5hbE1hcHBpbmdzLnB1c2goYWRqdXN0ZWRNYXBwaW5nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHF1aWNrU29ydCh0aGlzLl9fZ2VuZXJhdGVkTWFwcGluZ3MsIHV0aWwuY29tcGFyZUJ5R2VuZXJhdGVkUG9zaXRpb25zRGVmbGF0ZWQpO1xuICAgIHF1aWNrU29ydCh0aGlzLl9fb3JpZ2luYWxNYXBwaW5ncywgdXRpbC5jb21wYXJlQnlPcmlnaW5hbFBvc2l0aW9ucyk7XG4gIH07XG5cbmV4cG9ydHMuSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyID0gSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyO1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL2xpYi9zb3VyY2UtbWFwLWNvbnN1bWVyLmpzXG4gKiogbW9kdWxlIGlkID0gN1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyogLSotIE1vZGU6IGpzOyBqcy1pbmRlbnQtbGV2ZWw6IDI7IC0qLSAqL1xuLypcbiAqIENvcHlyaWdodCAyMDExIE1vemlsbGEgRm91bmRhdGlvbiBhbmQgY29udHJpYnV0b3JzXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTmV3IEJTRCBsaWNlbnNlLiBTZWUgTElDRU5TRSBvcjpcbiAqIGh0dHA6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9CU0QtMy1DbGF1c2VcbiAqL1xuXG5leHBvcnRzLkdSRUFURVNUX0xPV0VSX0JPVU5EID0gMTtcbmV4cG9ydHMuTEVBU1RfVVBQRVJfQk9VTkQgPSAyO1xuXG4vKipcbiAqIFJlY3Vyc2l2ZSBpbXBsZW1lbnRhdGlvbiBvZiBiaW5hcnkgc2VhcmNoLlxuICpcbiAqIEBwYXJhbSBhTG93IEluZGljZXMgaGVyZSBhbmQgbG93ZXIgZG8gbm90IGNvbnRhaW4gdGhlIG5lZWRsZS5cbiAqIEBwYXJhbSBhSGlnaCBJbmRpY2VzIGhlcmUgYW5kIGhpZ2hlciBkbyBub3QgY29udGFpbiB0aGUgbmVlZGxlLlxuICogQHBhcmFtIGFOZWVkbGUgVGhlIGVsZW1lbnQgYmVpbmcgc2VhcmNoZWQgZm9yLlxuICogQHBhcmFtIGFIYXlzdGFjayBUaGUgbm9uLWVtcHR5IGFycmF5IGJlaW5nIHNlYXJjaGVkLlxuICogQHBhcmFtIGFDb21wYXJlIEZ1bmN0aW9uIHdoaWNoIHRha2VzIHR3byBlbGVtZW50cyBhbmQgcmV0dXJucyAtMSwgMCwgb3IgMS5cbiAqIEBwYXJhbSBhQmlhcyBFaXRoZXIgJ2JpbmFyeVNlYXJjaC5HUkVBVEVTVF9MT1dFUl9CT1VORCcgb3JcbiAqICAgICAnYmluYXJ5U2VhcmNoLkxFQVNUX1VQUEVSX0JPVU5EJy4gU3BlY2lmaWVzIHdoZXRoZXIgdG8gcmV0dXJuIHRoZVxuICogICAgIGNsb3Nlc3QgZWxlbWVudCB0aGF0IGlzIHNtYWxsZXIgdGhhbiBvciBncmVhdGVyIHRoYW4gdGhlIG9uZSB3ZSBhcmVcbiAqICAgICBzZWFyY2hpbmcgZm9yLCByZXNwZWN0aXZlbHksIGlmIHRoZSBleGFjdCBlbGVtZW50IGNhbm5vdCBiZSBmb3VuZC5cbiAqL1xuZnVuY3Rpb24gcmVjdXJzaXZlU2VhcmNoKGFMb3csIGFIaWdoLCBhTmVlZGxlLCBhSGF5c3RhY2ssIGFDb21wYXJlLCBhQmlhcykge1xuICAvLyBUaGlzIGZ1bmN0aW9uIHRlcm1pbmF0ZXMgd2hlbiBvbmUgb2YgdGhlIGZvbGxvd2luZyBpcyB0cnVlOlxuICAvL1xuICAvLyAgIDEuIFdlIGZpbmQgdGhlIGV4YWN0IGVsZW1lbnQgd2UgYXJlIGxvb2tpbmcgZm9yLlxuICAvL1xuICAvLyAgIDIuIFdlIGRpZCBub3QgZmluZCB0aGUgZXhhY3QgZWxlbWVudCwgYnV0IHdlIGNhbiByZXR1cm4gdGhlIGluZGV4IG9mXG4gIC8vICAgICAgdGhlIG5leHQtY2xvc2VzdCBlbGVtZW50LlxuICAvL1xuICAvLyAgIDMuIFdlIGRpZCBub3QgZmluZCB0aGUgZXhhY3QgZWxlbWVudCwgYW5kIHRoZXJlIGlzIG5vIG5leHQtY2xvc2VzdFxuICAvLyAgICAgIGVsZW1lbnQgdGhhbiB0aGUgb25lIHdlIGFyZSBzZWFyY2hpbmcgZm9yLCBzbyB3ZSByZXR1cm4gLTEuXG4gIHZhciBtaWQgPSBNYXRoLmZsb29yKChhSGlnaCAtIGFMb3cpIC8gMikgKyBhTG93O1xuICB2YXIgY21wID0gYUNvbXBhcmUoYU5lZWRsZSwgYUhheXN0YWNrW21pZF0sIHRydWUpO1xuICBpZiAoY21wID09PSAwKSB7XG4gICAgLy8gRm91bmQgdGhlIGVsZW1lbnQgd2UgYXJlIGxvb2tpbmcgZm9yLlxuICAgIHJldHVybiBtaWQ7XG4gIH1cbiAgZWxzZSBpZiAoY21wID4gMCkge1xuICAgIC8vIE91ciBuZWVkbGUgaXMgZ3JlYXRlciB0aGFuIGFIYXlzdGFja1ttaWRdLlxuICAgIGlmIChhSGlnaCAtIG1pZCA+IDEpIHtcbiAgICAgIC8vIFRoZSBlbGVtZW50IGlzIGluIHRoZSB1cHBlciBoYWxmLlxuICAgICAgcmV0dXJuIHJlY3Vyc2l2ZVNlYXJjaChtaWQsIGFIaWdoLCBhTmVlZGxlLCBhSGF5c3RhY2ssIGFDb21wYXJlLCBhQmlhcyk7XG4gICAgfVxuXG4gICAgLy8gVGhlIGV4YWN0IG5lZWRsZSBlbGVtZW50IHdhcyBub3QgZm91bmQgaW4gdGhpcyBoYXlzdGFjay4gRGV0ZXJtaW5lIGlmXG4gICAgLy8gd2UgYXJlIGluIHRlcm1pbmF0aW9uIGNhc2UgKDMpIG9yICgyKSBhbmQgcmV0dXJuIHRoZSBhcHByb3ByaWF0ZSB0aGluZy5cbiAgICBpZiAoYUJpYXMgPT0gZXhwb3J0cy5MRUFTVF9VUFBFUl9CT1VORCkge1xuICAgICAgcmV0dXJuIGFIaWdoIDwgYUhheXN0YWNrLmxlbmd0aCA/IGFIaWdoIDogLTE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBtaWQ7XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIC8vIE91ciBuZWVkbGUgaXMgbGVzcyB0aGFuIGFIYXlzdGFja1ttaWRdLlxuICAgIGlmIChtaWQgLSBhTG93ID4gMSkge1xuICAgICAgLy8gVGhlIGVsZW1lbnQgaXMgaW4gdGhlIGxvd2VyIGhhbGYuXG4gICAgICByZXR1cm4gcmVjdXJzaXZlU2VhcmNoKGFMb3csIG1pZCwgYU5lZWRsZSwgYUhheXN0YWNrLCBhQ29tcGFyZSwgYUJpYXMpO1xuICAgIH1cblxuICAgIC8vIHdlIGFyZSBpbiB0ZXJtaW5hdGlvbiBjYXNlICgzKSBvciAoMikgYW5kIHJldHVybiB0aGUgYXBwcm9wcmlhdGUgdGhpbmcuXG4gICAgaWYgKGFCaWFzID09IGV4cG9ydHMuTEVBU1RfVVBQRVJfQk9VTkQpIHtcbiAgICAgIHJldHVybiBtaWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBhTG93IDwgMCA/IC0xIDogYUxvdztcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBUaGlzIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIGJpbmFyeSBzZWFyY2ggd2hpY2ggd2lsbCBhbHdheXMgdHJ5IGFuZCByZXR1cm5cbiAqIHRoZSBpbmRleCBvZiB0aGUgY2xvc2VzdCBlbGVtZW50IGlmIHRoZXJlIGlzIG5vIGV4YWN0IGhpdC4gVGhpcyBpcyBiZWNhdXNlXG4gKiBtYXBwaW5ncyBiZXR3ZWVuIG9yaWdpbmFsIGFuZCBnZW5lcmF0ZWQgbGluZS9jb2wgcGFpcnMgYXJlIHNpbmdsZSBwb2ludHMsXG4gKiBhbmQgdGhlcmUgaXMgYW4gaW1wbGljaXQgcmVnaW9uIGJldHdlZW4gZWFjaCBvZiB0aGVtLCBzbyBhIG1pc3MganVzdCBtZWFuc1xuICogdGhhdCB5b3UgYXJlbid0IG9uIHRoZSB2ZXJ5IHN0YXJ0IG9mIGEgcmVnaW9uLlxuICpcbiAqIEBwYXJhbSBhTmVlZGxlIFRoZSBlbGVtZW50IHlvdSBhcmUgbG9va2luZyBmb3IuXG4gKiBAcGFyYW0gYUhheXN0YWNrIFRoZSBhcnJheSB0aGF0IGlzIGJlaW5nIHNlYXJjaGVkLlxuICogQHBhcmFtIGFDb21wYXJlIEEgZnVuY3Rpb24gd2hpY2ggdGFrZXMgdGhlIG5lZWRsZSBhbmQgYW4gZWxlbWVudCBpbiB0aGVcbiAqICAgICBhcnJheSBhbmQgcmV0dXJucyAtMSwgMCwgb3IgMSBkZXBlbmRpbmcgb24gd2hldGhlciB0aGUgbmVlZGxlIGlzIGxlc3NcbiAqICAgICB0aGFuLCBlcXVhbCB0bywgb3IgZ3JlYXRlciB0aGFuIHRoZSBlbGVtZW50LCByZXNwZWN0aXZlbHkuXG4gKiBAcGFyYW0gYUJpYXMgRWl0aGVyICdiaW5hcnlTZWFyY2guR1JFQVRFU1RfTE9XRVJfQk9VTkQnIG9yXG4gKiAgICAgJ2JpbmFyeVNlYXJjaC5MRUFTVF9VUFBFUl9CT1VORCcuIFNwZWNpZmllcyB3aGV0aGVyIHRvIHJldHVybiB0aGVcbiAqICAgICBjbG9zZXN0IGVsZW1lbnQgdGhhdCBpcyBzbWFsbGVyIHRoYW4gb3IgZ3JlYXRlciB0aGFuIHRoZSBvbmUgd2UgYXJlXG4gKiAgICAgc2VhcmNoaW5nIGZvciwgcmVzcGVjdGl2ZWx5LCBpZiB0aGUgZXhhY3QgZWxlbWVudCBjYW5ub3QgYmUgZm91bmQuXG4gKiAgICAgRGVmYXVsdHMgdG8gJ2JpbmFyeVNlYXJjaC5HUkVBVEVTVF9MT1dFUl9CT1VORCcuXG4gKi9cbmV4cG9ydHMuc2VhcmNoID0gZnVuY3Rpb24gc2VhcmNoKGFOZWVkbGUsIGFIYXlzdGFjaywgYUNvbXBhcmUsIGFCaWFzKSB7XG4gIGlmIChhSGF5c3RhY2subGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG5cbiAgdmFyIGluZGV4ID0gcmVjdXJzaXZlU2VhcmNoKC0xLCBhSGF5c3RhY2subGVuZ3RoLCBhTmVlZGxlLCBhSGF5c3RhY2ssXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhQ29tcGFyZSwgYUJpYXMgfHwgZXhwb3J0cy5HUkVBVEVTVF9MT1dFUl9CT1VORCk7XG4gIGlmIChpbmRleCA8IDApIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICAvLyBXZSBoYXZlIGZvdW5kIGVpdGhlciB0aGUgZXhhY3QgZWxlbWVudCwgb3IgdGhlIG5leHQtY2xvc2VzdCBlbGVtZW50IHRoYW5cbiAgLy8gdGhlIG9uZSB3ZSBhcmUgc2VhcmNoaW5nIGZvci4gSG93ZXZlciwgdGhlcmUgbWF5IGJlIG1vcmUgdGhhbiBvbmUgc3VjaFxuICAvLyBlbGVtZW50LiBNYWtlIHN1cmUgd2UgYWx3YXlzIHJldHVybiB0aGUgc21hbGxlc3Qgb2YgdGhlc2UuXG4gIHdoaWxlIChpbmRleCAtIDEgPj0gMCkge1xuICAgIGlmIChhQ29tcGFyZShhSGF5c3RhY2tbaW5kZXhdLCBhSGF5c3RhY2tbaW5kZXggLSAxXSwgdHJ1ZSkgIT09IDApIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICAtLWluZGV4O1xuICB9XG5cbiAgcmV0dXJuIGluZGV4O1xufTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9saWIvYmluYXJ5LXNlYXJjaC5qc1xuICoqIG1vZHVsZSBpZCA9IDhcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qIC0qLSBNb2RlOiBqczsganMtaW5kZW50LWxldmVsOiAyOyAtKi0gKi9cbi8qXG4gKiBDb3B5cmlnaHQgMjAxMSBNb3ppbGxhIEZvdW5kYXRpb24gYW5kIGNvbnRyaWJ1dG9yc1xuICogTGljZW5zZWQgdW5kZXIgdGhlIE5ldyBCU0QgbGljZW5zZS4gU2VlIExJQ0VOU0Ugb3I6XG4gKiBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvQlNELTMtQ2xhdXNlXG4gKi9cblxuLy8gSXQgdHVybnMgb3V0IHRoYXQgc29tZSAobW9zdD8pIEphdmFTY3JpcHQgZW5naW5lcyBkb24ndCBzZWxmLWhvc3Rcbi8vIGBBcnJheS5wcm90b3R5cGUuc29ydGAuIFRoaXMgbWFrZXMgc2Vuc2UgYmVjYXVzZSBDKysgd2lsbCBsaWtlbHkgcmVtYWluXG4vLyBmYXN0ZXIgdGhhbiBKUyB3aGVuIGRvaW5nIHJhdyBDUFUtaW50ZW5zaXZlIHNvcnRpbmcuIEhvd2V2ZXIsIHdoZW4gdXNpbmcgYVxuLy8gY3VzdG9tIGNvbXBhcmF0b3IgZnVuY3Rpb24sIGNhbGxpbmcgYmFjayBhbmQgZm9ydGggYmV0d2VlbiB0aGUgVk0ncyBDKysgYW5kXG4vLyBKSVQnZCBKUyBpcyByYXRoZXIgc2xvdyAqYW5kKiBsb3NlcyBKSVQgdHlwZSBpbmZvcm1hdGlvbiwgcmVzdWx0aW5nIGluXG4vLyB3b3JzZSBnZW5lcmF0ZWQgY29kZSBmb3IgdGhlIGNvbXBhcmF0b3IgZnVuY3Rpb24gdGhhbiB3b3VsZCBiZSBvcHRpbWFsLiBJblxuLy8gZmFjdCwgd2hlbiBzb3J0aW5nIHdpdGggYSBjb21wYXJhdG9yLCB0aGVzZSBjb3N0cyBvdXR3ZWlnaCB0aGUgYmVuZWZpdHMgb2Zcbi8vIHNvcnRpbmcgaW4gQysrLiBCeSB1c2luZyBvdXIgb3duIEpTLWltcGxlbWVudGVkIFF1aWNrIFNvcnQgKGJlbG93KSwgd2UgZ2V0XG4vLyBhIH4zNTAwbXMgbWVhbiBzcGVlZC11cCBpbiBgYmVuY2gvYmVuY2guaHRtbGAuXG5cbi8qKlxuICogU3dhcCB0aGUgZWxlbWVudHMgaW5kZXhlZCBieSBgeGAgYW5kIGB5YCBpbiB0aGUgYXJyYXkgYGFyeWAuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gYXJ5XG4gKiAgICAgICAgVGhlIGFycmF5LlxuICogQHBhcmFtIHtOdW1iZXJ9IHhcbiAqICAgICAgICBUaGUgaW5kZXggb2YgdGhlIGZpcnN0IGl0ZW0uXG4gKiBAcGFyYW0ge051bWJlcn0geVxuICogICAgICAgIFRoZSBpbmRleCBvZiB0aGUgc2Vjb25kIGl0ZW0uXG4gKi9cbmZ1bmN0aW9uIHN3YXAoYXJ5LCB4LCB5KSB7XG4gIHZhciB0ZW1wID0gYXJ5W3hdO1xuICBhcnlbeF0gPSBhcnlbeV07XG4gIGFyeVt5XSA9IHRlbXA7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIHJhbmRvbSBpbnRlZ2VyIHdpdGhpbiB0aGUgcmFuZ2UgYGxvdyAuLiBoaWdoYCBpbmNsdXNpdmUuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGxvd1xuICogICAgICAgIFRoZSBsb3dlciBib3VuZCBvbiB0aGUgcmFuZ2UuXG4gKiBAcGFyYW0ge051bWJlcn0gaGlnaFxuICogICAgICAgIFRoZSB1cHBlciBib3VuZCBvbiB0aGUgcmFuZ2UuXG4gKi9cbmZ1bmN0aW9uIHJhbmRvbUludEluUmFuZ2UobG93LCBoaWdoKSB7XG4gIHJldHVybiBNYXRoLnJvdW5kKGxvdyArIChNYXRoLnJhbmRvbSgpICogKGhpZ2ggLSBsb3cpKSk7XG59XG5cbi8qKlxuICogVGhlIFF1aWNrIFNvcnQgYWxnb3JpdGhtLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IGFyeVxuICogICAgICAgIEFuIGFycmF5IHRvIHNvcnQuXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjb21wYXJhdG9yXG4gKiAgICAgICAgRnVuY3Rpb24gdG8gdXNlIHRvIGNvbXBhcmUgdHdvIGl0ZW1zLlxuICogQHBhcmFtIHtOdW1iZXJ9IHBcbiAqICAgICAgICBTdGFydCBpbmRleCBvZiB0aGUgYXJyYXlcbiAqIEBwYXJhbSB7TnVtYmVyfSByXG4gKiAgICAgICAgRW5kIGluZGV4IG9mIHRoZSBhcnJheVxuICovXG5mdW5jdGlvbiBkb1F1aWNrU29ydChhcnksIGNvbXBhcmF0b3IsIHAsIHIpIHtcbiAgLy8gSWYgb3VyIGxvd2VyIGJvdW5kIGlzIGxlc3MgdGhhbiBvdXIgdXBwZXIgYm91bmQsIHdlICgxKSBwYXJ0aXRpb24gdGhlXG4gIC8vIGFycmF5IGludG8gdHdvIHBpZWNlcyBhbmQgKDIpIHJlY3Vyc2Ugb24gZWFjaCBoYWxmLiBJZiBpdCBpcyBub3QsIHRoaXMgaXNcbiAgLy8gdGhlIGVtcHR5IGFycmF5IGFuZCBvdXIgYmFzZSBjYXNlLlxuXG4gIGlmIChwIDwgcikge1xuICAgIC8vICgxKSBQYXJ0aXRpb25pbmcuXG4gICAgLy9cbiAgICAvLyBUaGUgcGFydGl0aW9uaW5nIGNob29zZXMgYSBwaXZvdCBiZXR3ZWVuIGBwYCBhbmQgYHJgIGFuZCBtb3ZlcyBhbGxcbiAgICAvLyBlbGVtZW50cyB0aGF0IGFyZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHBpdm90IHRvIHRoZSBiZWZvcmUgaXQsIGFuZFxuICAgIC8vIGFsbCB0aGUgZWxlbWVudHMgdGhhdCBhcmUgZ3JlYXRlciB0aGFuIGl0IGFmdGVyIGl0LiBUaGUgZWZmZWN0IGlzIHRoYXRcbiAgICAvLyBvbmNlIHBhcnRpdGlvbiBpcyBkb25lLCB0aGUgcGl2b3QgaXMgaW4gdGhlIGV4YWN0IHBsYWNlIGl0IHdpbGwgYmUgd2hlblxuICAgIC8vIHRoZSBhcnJheSBpcyBwdXQgaW4gc29ydGVkIG9yZGVyLCBhbmQgaXQgd2lsbCBub3QgbmVlZCB0byBiZSBtb3ZlZFxuICAgIC8vIGFnYWluLiBUaGlzIHJ1bnMgaW4gTyhuKSB0aW1lLlxuXG4gICAgLy8gQWx3YXlzIGNob29zZSBhIHJhbmRvbSBwaXZvdCBzbyB0aGF0IGFuIGlucHV0IGFycmF5IHdoaWNoIGlzIHJldmVyc2VcbiAgICAvLyBzb3J0ZWQgZG9lcyBub3QgY2F1c2UgTyhuXjIpIHJ1bm5pbmcgdGltZS5cbiAgICB2YXIgcGl2b3RJbmRleCA9IHJhbmRvbUludEluUmFuZ2UocCwgcik7XG4gICAgdmFyIGkgPSBwIC0gMTtcblxuICAgIHN3YXAoYXJ5LCBwaXZvdEluZGV4LCByKTtcbiAgICB2YXIgcGl2b3QgPSBhcnlbcl07XG5cbiAgICAvLyBJbW1lZGlhdGVseSBhZnRlciBgamAgaXMgaW5jcmVtZW50ZWQgaW4gdGhpcyBsb29wLCB0aGUgZm9sbG93aW5nIGhvbGRcbiAgICAvLyB0cnVlOlxuICAgIC8vXG4gICAgLy8gICAqIEV2ZXJ5IGVsZW1lbnQgaW4gYGFyeVtwIC4uIGldYCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHBpdm90LlxuICAgIC8vXG4gICAgLy8gICAqIEV2ZXJ5IGVsZW1lbnQgaW4gYGFyeVtpKzEgLi4gai0xXWAgaXMgZ3JlYXRlciB0aGFuIHRoZSBwaXZvdC5cbiAgICBmb3IgKHZhciBqID0gcDsgaiA8IHI7IGorKykge1xuICAgICAgaWYgKGNvbXBhcmF0b3IoYXJ5W2pdLCBwaXZvdCkgPD0gMCkge1xuICAgICAgICBpICs9IDE7XG4gICAgICAgIHN3YXAoYXJ5LCBpLCBqKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzd2FwKGFyeSwgaSArIDEsIGopO1xuICAgIHZhciBxID0gaSArIDE7XG5cbiAgICAvLyAoMikgUmVjdXJzZSBvbiBlYWNoIGhhbGYuXG5cbiAgICBkb1F1aWNrU29ydChhcnksIGNvbXBhcmF0b3IsIHAsIHEgLSAxKTtcbiAgICBkb1F1aWNrU29ydChhcnksIGNvbXBhcmF0b3IsIHEgKyAxLCByKTtcbiAgfVxufVxuXG4vKipcbiAqIFNvcnQgdGhlIGdpdmVuIGFycmF5IGluLXBsYWNlIHdpdGggdGhlIGdpdmVuIGNvbXBhcmF0b3IgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIHtBcnJheX0gYXJ5XG4gKiAgICAgICAgQW4gYXJyYXkgdG8gc29ydC5cbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGNvbXBhcmF0b3JcbiAqICAgICAgICBGdW5jdGlvbiB0byB1c2UgdG8gY29tcGFyZSB0d28gaXRlbXMuXG4gKi9cbmV4cG9ydHMucXVpY2tTb3J0ID0gZnVuY3Rpb24gKGFyeSwgY29tcGFyYXRvcikge1xuICBkb1F1aWNrU29ydChhcnksIGNvbXBhcmF0b3IsIDAsIGFyeS5sZW5ndGggLSAxKTtcbn07XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vbGliL3F1aWNrLXNvcnQuanNcbiAqKiBtb2R1bGUgaWQgPSA5XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKiAtKi0gTW9kZToganM7IGpzLWluZGVudC1sZXZlbDogMjsgLSotICovXG4vKlxuICogQ29weXJpZ2h0IDIwMTEgTW96aWxsYSBGb3VuZGF0aW9uIGFuZCBjb250cmlidXRvcnNcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBOZXcgQlNEIGxpY2Vuc2UuIFNlZSBMSUNFTlNFIG9yOlxuICogaHR0cDovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL0JTRC0zLUNsYXVzZVxuICovXG5cbnZhciBTb3VyY2VNYXBHZW5lcmF0b3IgPSByZXF1aXJlKCcuL3NvdXJjZS1tYXAtZ2VuZXJhdG9yJykuU291cmNlTWFwR2VuZXJhdG9yO1xudmFyIHV0aWwgPSByZXF1aXJlKCcuL3V0aWwnKTtcblxuLy8gTWF0Y2hlcyBhIFdpbmRvd3Mtc3R5bGUgYFxcclxcbmAgbmV3bGluZSBvciBhIGBcXG5gIG5ld2xpbmUgdXNlZCBieSBhbGwgb3RoZXJcbi8vIG9wZXJhdGluZyBzeXN0ZW1zIHRoZXNlIGRheXMgKGNhcHR1cmluZyB0aGUgcmVzdWx0KS5cbnZhciBSRUdFWF9ORVdMSU5FID0gLyhcXHI/XFxuKS87XG5cbi8vIE5ld2xpbmUgY2hhcmFjdGVyIGNvZGUgZm9yIGNoYXJDb2RlQXQoKSBjb21wYXJpc29uc1xudmFyIE5FV0xJTkVfQ09ERSA9IDEwO1xuXG4vLyBQcml2YXRlIHN5bWJvbCBmb3IgaWRlbnRpZnlpbmcgYFNvdXJjZU5vZGVgcyB3aGVuIG11bHRpcGxlIHZlcnNpb25zIG9mXG4vLyB0aGUgc291cmNlLW1hcCBsaWJyYXJ5IGFyZSBsb2FkZWQuIFRoaXMgTVVTVCBOT1QgQ0hBTkdFIGFjcm9zc1xuLy8gdmVyc2lvbnMhXG52YXIgaXNTb3VyY2VOb2RlID0gXCIkJCRpc1NvdXJjZU5vZGUkJCRcIjtcblxuLyoqXG4gKiBTb3VyY2VOb2RlcyBwcm92aWRlIGEgd2F5IHRvIGFic3RyYWN0IG92ZXIgaW50ZXJwb2xhdGluZy9jb25jYXRlbmF0aW5nXG4gKiBzbmlwcGV0cyBvZiBnZW5lcmF0ZWQgSmF2YVNjcmlwdCBzb3VyY2UgY29kZSB3aGlsZSBtYWludGFpbmluZyB0aGUgbGluZSBhbmRcbiAqIGNvbHVtbiBpbmZvcm1hdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhlIG9yaWdpbmFsIHNvdXJjZSBjb2RlLlxuICpcbiAqIEBwYXJhbSBhTGluZSBUaGUgb3JpZ2luYWwgbGluZSBudW1iZXIuXG4gKiBAcGFyYW0gYUNvbHVtbiBUaGUgb3JpZ2luYWwgY29sdW1uIG51bWJlci5cbiAqIEBwYXJhbSBhU291cmNlIFRoZSBvcmlnaW5hbCBzb3VyY2UncyBmaWxlbmFtZS5cbiAqIEBwYXJhbSBhQ2h1bmtzIE9wdGlvbmFsLiBBbiBhcnJheSBvZiBzdHJpbmdzIHdoaWNoIGFyZSBzbmlwcGV0cyBvZlxuICogICAgICAgIGdlbmVyYXRlZCBKUywgb3Igb3RoZXIgU291cmNlTm9kZXMuXG4gKiBAcGFyYW0gYU5hbWUgVGhlIG9yaWdpbmFsIGlkZW50aWZpZXIuXG4gKi9cbmZ1bmN0aW9uIFNvdXJjZU5vZGUoYUxpbmUsIGFDb2x1bW4sIGFTb3VyY2UsIGFDaHVua3MsIGFOYW1lKSB7XG4gIHRoaXMuY2hpbGRyZW4gPSBbXTtcbiAgdGhpcy5zb3VyY2VDb250ZW50cyA9IHt9O1xuICB0aGlzLmxpbmUgPSBhTGluZSA9PSBudWxsID8gbnVsbCA6IGFMaW5lO1xuICB0aGlzLmNvbHVtbiA9IGFDb2x1bW4gPT0gbnVsbCA/IG51bGwgOiBhQ29sdW1uO1xuICB0aGlzLnNvdXJjZSA9IGFTb3VyY2UgPT0gbnVsbCA/IG51bGwgOiBhU291cmNlO1xuICB0aGlzLm5hbWUgPSBhTmFtZSA9PSBudWxsID8gbnVsbCA6IGFOYW1lO1xuICB0aGlzW2lzU291cmNlTm9kZV0gPSB0cnVlO1xuICBpZiAoYUNodW5rcyAhPSBudWxsKSB0aGlzLmFkZChhQ2h1bmtzKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgU291cmNlTm9kZSBmcm9tIGdlbmVyYXRlZCBjb2RlIGFuZCBhIFNvdXJjZU1hcENvbnN1bWVyLlxuICpcbiAqIEBwYXJhbSBhR2VuZXJhdGVkQ29kZSBUaGUgZ2VuZXJhdGVkIGNvZGVcbiAqIEBwYXJhbSBhU291cmNlTWFwQ29uc3VtZXIgVGhlIFNvdXJjZU1hcCBmb3IgdGhlIGdlbmVyYXRlZCBjb2RlXG4gKiBAcGFyYW0gYVJlbGF0aXZlUGF0aCBPcHRpb25hbC4gVGhlIHBhdGggdGhhdCByZWxhdGl2ZSBzb3VyY2VzIGluIHRoZVxuICogICAgICAgIFNvdXJjZU1hcENvbnN1bWVyIHNob3VsZCBiZSByZWxhdGl2ZSB0by5cbiAqL1xuU291cmNlTm9kZS5mcm9tU3RyaW5nV2l0aFNvdXJjZU1hcCA9XG4gIGZ1bmN0aW9uIFNvdXJjZU5vZGVfZnJvbVN0cmluZ1dpdGhTb3VyY2VNYXAoYUdlbmVyYXRlZENvZGUsIGFTb3VyY2VNYXBDb25zdW1lciwgYVJlbGF0aXZlUGF0aCkge1xuICAgIC8vIFRoZSBTb3VyY2VOb2RlIHdlIHdhbnQgdG8gZmlsbCB3aXRoIHRoZSBnZW5lcmF0ZWQgY29kZVxuICAgIC8vIGFuZCB0aGUgU291cmNlTWFwXG4gICAgdmFyIG5vZGUgPSBuZXcgU291cmNlTm9kZSgpO1xuXG4gICAgLy8gQWxsIGV2ZW4gaW5kaWNlcyBvZiB0aGlzIGFycmF5IGFyZSBvbmUgbGluZSBvZiB0aGUgZ2VuZXJhdGVkIGNvZGUsXG4gICAgLy8gd2hpbGUgYWxsIG9kZCBpbmRpY2VzIGFyZSB0aGUgbmV3bGluZXMgYmV0d2VlbiB0d28gYWRqYWNlbnQgbGluZXNcbiAgICAvLyAoc2luY2UgYFJFR0VYX05FV0xJTkVgIGNhcHR1cmVzIGl0cyBtYXRjaCkuXG4gICAgLy8gUHJvY2Vzc2VkIGZyYWdtZW50cyBhcmUgcmVtb3ZlZCBmcm9tIHRoaXMgYXJyYXksIGJ5IGNhbGxpbmcgYHNoaWZ0TmV4dExpbmVgLlxuICAgIHZhciByZW1haW5pbmdMaW5lcyA9IGFHZW5lcmF0ZWRDb2RlLnNwbGl0KFJFR0VYX05FV0xJTkUpO1xuICAgIHZhciBzaGlmdE5leHRMaW5lID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgbGluZUNvbnRlbnRzID0gcmVtYWluaW5nTGluZXMuc2hpZnQoKTtcbiAgICAgIC8vIFRoZSBsYXN0IGxpbmUgb2YgYSBmaWxlIG1pZ2h0IG5vdCBoYXZlIGEgbmV3bGluZS5cbiAgICAgIHZhciBuZXdMaW5lID0gcmVtYWluaW5nTGluZXMuc2hpZnQoKSB8fCBcIlwiO1xuICAgICAgcmV0dXJuIGxpbmVDb250ZW50cyArIG5ld0xpbmU7XG4gICAgfTtcblxuICAgIC8vIFdlIG5lZWQgdG8gcmVtZW1iZXIgdGhlIHBvc2l0aW9uIG9mIFwicmVtYWluaW5nTGluZXNcIlxuICAgIHZhciBsYXN0R2VuZXJhdGVkTGluZSA9IDEsIGxhc3RHZW5lcmF0ZWRDb2x1bW4gPSAwO1xuXG4gICAgLy8gVGhlIGdlbmVyYXRlIFNvdXJjZU5vZGVzIHdlIG5lZWQgYSBjb2RlIHJhbmdlLlxuICAgIC8vIFRvIGV4dHJhY3QgaXQgY3VycmVudCBhbmQgbGFzdCBtYXBwaW5nIGlzIHVzZWQuXG4gICAgLy8gSGVyZSB3ZSBzdG9yZSB0aGUgbGFzdCBtYXBwaW5nLlxuICAgIHZhciBsYXN0TWFwcGluZyA9IG51bGw7XG5cbiAgICBhU291cmNlTWFwQ29uc3VtZXIuZWFjaE1hcHBpbmcoZnVuY3Rpb24gKG1hcHBpbmcpIHtcbiAgICAgIGlmIChsYXN0TWFwcGluZyAhPT0gbnVsbCkge1xuICAgICAgICAvLyBXZSBhZGQgdGhlIGNvZGUgZnJvbSBcImxhc3RNYXBwaW5nXCIgdG8gXCJtYXBwaW5nXCI6XG4gICAgICAgIC8vIEZpcnN0IGNoZWNrIGlmIHRoZXJlIGlzIGEgbmV3IGxpbmUgaW4gYmV0d2Vlbi5cbiAgICAgICAgaWYgKGxhc3RHZW5lcmF0ZWRMaW5lIDwgbWFwcGluZy5nZW5lcmF0ZWRMaW5lKSB7XG4gICAgICAgICAgLy8gQXNzb2NpYXRlIGZpcnN0IGxpbmUgd2l0aCBcImxhc3RNYXBwaW5nXCJcbiAgICAgICAgICBhZGRNYXBwaW5nV2l0aENvZGUobGFzdE1hcHBpbmcsIHNoaWZ0TmV4dExpbmUoKSk7XG4gICAgICAgICAgbGFzdEdlbmVyYXRlZExpbmUrKztcbiAgICAgICAgICBsYXN0R2VuZXJhdGVkQ29sdW1uID0gMDtcbiAgICAgICAgICAvLyBUaGUgcmVtYWluaW5nIGNvZGUgaXMgYWRkZWQgd2l0aG91dCBtYXBwaW5nXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gVGhlcmUgaXMgbm8gbmV3IGxpbmUgaW4gYmV0d2Vlbi5cbiAgICAgICAgICAvLyBBc3NvY2lhdGUgdGhlIGNvZGUgYmV0d2VlbiBcImxhc3RHZW5lcmF0ZWRDb2x1bW5cIiBhbmRcbiAgICAgICAgICAvLyBcIm1hcHBpbmcuZ2VuZXJhdGVkQ29sdW1uXCIgd2l0aCBcImxhc3RNYXBwaW5nXCJcbiAgICAgICAgICB2YXIgbmV4dExpbmUgPSByZW1haW5pbmdMaW5lc1swXTtcbiAgICAgICAgICB2YXIgY29kZSA9IG5leHRMaW5lLnN1YnN0cigwLCBtYXBwaW5nLmdlbmVyYXRlZENvbHVtbiAtXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFzdEdlbmVyYXRlZENvbHVtbik7XG4gICAgICAgICAgcmVtYWluaW5nTGluZXNbMF0gPSBuZXh0TGluZS5zdWJzdHIobWFwcGluZy5nZW5lcmF0ZWRDb2x1bW4gLVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RHZW5lcmF0ZWRDb2x1bW4pO1xuICAgICAgICAgIGxhc3RHZW5lcmF0ZWRDb2x1bW4gPSBtYXBwaW5nLmdlbmVyYXRlZENvbHVtbjtcbiAgICAgICAgICBhZGRNYXBwaW5nV2l0aENvZGUobGFzdE1hcHBpbmcsIGNvZGUpO1xuICAgICAgICAgIC8vIE5vIG1vcmUgcmVtYWluaW5nIGNvZGUsIGNvbnRpbnVlXG4gICAgICAgICAgbGFzdE1hcHBpbmcgPSBtYXBwaW5nO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gV2UgYWRkIHRoZSBnZW5lcmF0ZWQgY29kZSB1bnRpbCB0aGUgZmlyc3QgbWFwcGluZ1xuICAgICAgLy8gdG8gdGhlIFNvdXJjZU5vZGUgd2l0aG91dCBhbnkgbWFwcGluZy5cbiAgICAgIC8vIEVhY2ggbGluZSBpcyBhZGRlZCBhcyBzZXBhcmF0ZSBzdHJpbmcuXG4gICAgICB3aGlsZSAobGFzdEdlbmVyYXRlZExpbmUgPCBtYXBwaW5nLmdlbmVyYXRlZExpbmUpIHtcbiAgICAgICAgbm9kZS5hZGQoc2hpZnROZXh0TGluZSgpKTtcbiAgICAgICAgbGFzdEdlbmVyYXRlZExpbmUrKztcbiAgICAgIH1cbiAgICAgIGlmIChsYXN0R2VuZXJhdGVkQ29sdW1uIDwgbWFwcGluZy5nZW5lcmF0ZWRDb2x1bW4pIHtcbiAgICAgICAgdmFyIG5leHRMaW5lID0gcmVtYWluaW5nTGluZXNbMF07XG4gICAgICAgIG5vZGUuYWRkKG5leHRMaW5lLnN1YnN0cigwLCBtYXBwaW5nLmdlbmVyYXRlZENvbHVtbikpO1xuICAgICAgICByZW1haW5pbmdMaW5lc1swXSA9IG5leHRMaW5lLnN1YnN0cihtYXBwaW5nLmdlbmVyYXRlZENvbHVtbik7XG4gICAgICAgIGxhc3RHZW5lcmF0ZWRDb2x1bW4gPSBtYXBwaW5nLmdlbmVyYXRlZENvbHVtbjtcbiAgICAgIH1cbiAgICAgIGxhc3RNYXBwaW5nID0gbWFwcGluZztcbiAgICB9LCB0aGlzKTtcbiAgICAvLyBXZSBoYXZlIHByb2Nlc3NlZCBhbGwgbWFwcGluZ3MuXG4gICAgaWYgKHJlbWFpbmluZ0xpbmVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmIChsYXN0TWFwcGluZykge1xuICAgICAgICAvLyBBc3NvY2lhdGUgdGhlIHJlbWFpbmluZyBjb2RlIGluIHRoZSBjdXJyZW50IGxpbmUgd2l0aCBcImxhc3RNYXBwaW5nXCJcbiAgICAgICAgYWRkTWFwcGluZ1dpdGhDb2RlKGxhc3RNYXBwaW5nLCBzaGlmdE5leHRMaW5lKCkpO1xuICAgICAgfVxuICAgICAgLy8gYW5kIGFkZCB0aGUgcmVtYWluaW5nIGxpbmVzIHdpdGhvdXQgYW55IG1hcHBpbmdcbiAgICAgIG5vZGUuYWRkKHJlbWFpbmluZ0xpbmVzLmpvaW4oXCJcIikpO1xuICAgIH1cblxuICAgIC8vIENvcHkgc291cmNlc0NvbnRlbnQgaW50byBTb3VyY2VOb2RlXG4gICAgYVNvdXJjZU1hcENvbnN1bWVyLnNvdXJjZXMuZm9yRWFjaChmdW5jdGlvbiAoc291cmNlRmlsZSkge1xuICAgICAgdmFyIGNvbnRlbnQgPSBhU291cmNlTWFwQ29uc3VtZXIuc291cmNlQ29udGVudEZvcihzb3VyY2VGaWxlKTtcbiAgICAgIGlmIChjb250ZW50ICE9IG51bGwpIHtcbiAgICAgICAgaWYgKGFSZWxhdGl2ZVBhdGggIT0gbnVsbCkge1xuICAgICAgICAgIHNvdXJjZUZpbGUgPSB1dGlsLmpvaW4oYVJlbGF0aXZlUGF0aCwgc291cmNlRmlsZSk7XG4gICAgICAgIH1cbiAgICAgICAgbm9kZS5zZXRTb3VyY2VDb250ZW50KHNvdXJjZUZpbGUsIGNvbnRlbnQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIG5vZGU7XG5cbiAgICBmdW5jdGlvbiBhZGRNYXBwaW5nV2l0aENvZGUobWFwcGluZywgY29kZSkge1xuICAgICAgaWYgKG1hcHBpbmcgPT09IG51bGwgfHwgbWFwcGluZy5zb3VyY2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBub2RlLmFkZChjb2RlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBzb3VyY2UgPSBhUmVsYXRpdmVQYXRoXG4gICAgICAgICAgPyB1dGlsLmpvaW4oYVJlbGF0aXZlUGF0aCwgbWFwcGluZy5zb3VyY2UpXG4gICAgICAgICAgOiBtYXBwaW5nLnNvdXJjZTtcbiAgICAgICAgbm9kZS5hZGQobmV3IFNvdXJjZU5vZGUobWFwcGluZy5vcmlnaW5hbExpbmUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcHBpbmcub3JpZ2luYWxDb2x1bW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29kZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwcGluZy5uYW1lKSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4vKipcbiAqIEFkZCBhIGNodW5rIG9mIGdlbmVyYXRlZCBKUyB0byB0aGlzIHNvdXJjZSBub2RlLlxuICpcbiAqIEBwYXJhbSBhQ2h1bmsgQSBzdHJpbmcgc25pcHBldCBvZiBnZW5lcmF0ZWQgSlMgY29kZSwgYW5vdGhlciBpbnN0YW5jZSBvZlxuICogICAgICAgIFNvdXJjZU5vZGUsIG9yIGFuIGFycmF5IHdoZXJlIGVhY2ggbWVtYmVyIGlzIG9uZSBvZiB0aG9zZSB0aGluZ3MuXG4gKi9cblNvdXJjZU5vZGUucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIFNvdXJjZU5vZGVfYWRkKGFDaHVuaykge1xuICBpZiAoQXJyYXkuaXNBcnJheShhQ2h1bmspKSB7XG4gICAgYUNodW5rLmZvckVhY2goZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgICB0aGlzLmFkZChjaHVuayk7XG4gICAgfSwgdGhpcyk7XG4gIH1cbiAgZWxzZSBpZiAoYUNodW5rW2lzU291cmNlTm9kZV0gfHwgdHlwZW9mIGFDaHVuayA9PT0gXCJzdHJpbmdcIikge1xuICAgIGlmIChhQ2h1bmspIHtcbiAgICAgIHRoaXMuY2hpbGRyZW4ucHVzaChhQ2h1bmspO1xuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgXCJFeHBlY3RlZCBhIFNvdXJjZU5vZGUsIHN0cmluZywgb3IgYW4gYXJyYXkgb2YgU291cmNlTm9kZXMgYW5kIHN0cmluZ3MuIEdvdCBcIiArIGFDaHVua1xuICAgICk7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEFkZCBhIGNodW5rIG9mIGdlbmVyYXRlZCBKUyB0byB0aGUgYmVnaW5uaW5nIG9mIHRoaXMgc291cmNlIG5vZGUuXG4gKlxuICogQHBhcmFtIGFDaHVuayBBIHN0cmluZyBzbmlwcGV0IG9mIGdlbmVyYXRlZCBKUyBjb2RlLCBhbm90aGVyIGluc3RhbmNlIG9mXG4gKiAgICAgICAgU291cmNlTm9kZSwgb3IgYW4gYXJyYXkgd2hlcmUgZWFjaCBtZW1iZXIgaXMgb25lIG9mIHRob3NlIHRoaW5ncy5cbiAqL1xuU291cmNlTm9kZS5wcm90b3R5cGUucHJlcGVuZCA9IGZ1bmN0aW9uIFNvdXJjZU5vZGVfcHJlcGVuZChhQ2h1bmspIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoYUNodW5rKSkge1xuICAgIGZvciAodmFyIGkgPSBhQ2h1bmsubGVuZ3RoLTE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB0aGlzLnByZXBlbmQoYUNodW5rW2ldKTtcbiAgICB9XG4gIH1cbiAgZWxzZSBpZiAoYUNodW5rW2lzU291cmNlTm9kZV0gfHwgdHlwZW9mIGFDaHVuayA9PT0gXCJzdHJpbmdcIikge1xuICAgIHRoaXMuY2hpbGRyZW4udW5zaGlmdChhQ2h1bmspO1xuICB9XG4gIGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICBcIkV4cGVjdGVkIGEgU291cmNlTm9kZSwgc3RyaW5nLCBvciBhbiBhcnJheSBvZiBTb3VyY2VOb2RlcyBhbmQgc3RyaW5ncy4gR290IFwiICsgYUNodW5rXG4gICAgKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogV2FsayBvdmVyIHRoZSB0cmVlIG9mIEpTIHNuaXBwZXRzIGluIHRoaXMgbm9kZSBhbmQgaXRzIGNoaWxkcmVuLiBUaGVcbiAqIHdhbGtpbmcgZnVuY3Rpb24gaXMgY2FsbGVkIG9uY2UgZm9yIGVhY2ggc25pcHBldCBvZiBKUyBhbmQgaXMgcGFzc2VkIHRoYXRcbiAqIHNuaXBwZXQgYW5kIHRoZSBpdHMgb3JpZ2luYWwgYXNzb2NpYXRlZCBzb3VyY2UncyBsaW5lL2NvbHVtbiBsb2NhdGlvbi5cbiAqXG4gKiBAcGFyYW0gYUZuIFRoZSB0cmF2ZXJzYWwgZnVuY3Rpb24uXG4gKi9cblNvdXJjZU5vZGUucHJvdG90eXBlLndhbGsgPSBmdW5jdGlvbiBTb3VyY2VOb2RlX3dhbGsoYUZuKSB7XG4gIHZhciBjaHVuaztcbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBjaHVuayA9IHRoaXMuY2hpbGRyZW5baV07XG4gICAgaWYgKGNodW5rW2lzU291cmNlTm9kZV0pIHtcbiAgICAgIGNodW5rLndhbGsoYUZuKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBpZiAoY2h1bmsgIT09ICcnKSB7XG4gICAgICAgIGFGbihjaHVuaywgeyBzb3VyY2U6IHRoaXMuc291cmNlLFxuICAgICAgICAgICAgICAgICAgICAgbGluZTogdGhpcy5saW5lLFxuICAgICAgICAgICAgICAgICAgICAgY29sdW1uOiB0aGlzLmNvbHVtbixcbiAgICAgICAgICAgICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogTGlrZSBgU3RyaW5nLnByb3RvdHlwZS5qb2luYCBleGNlcHQgZm9yIFNvdXJjZU5vZGVzLiBJbnNlcnRzIGBhU3RyYCBiZXR3ZWVuXG4gKiBlYWNoIG9mIGB0aGlzLmNoaWxkcmVuYC5cbiAqXG4gKiBAcGFyYW0gYVNlcCBUaGUgc2VwYXJhdG9yLlxuICovXG5Tb3VyY2VOb2RlLnByb3RvdHlwZS5qb2luID0gZnVuY3Rpb24gU291cmNlTm9kZV9qb2luKGFTZXApIHtcbiAgdmFyIG5ld0NoaWxkcmVuO1xuICB2YXIgaTtcbiAgdmFyIGxlbiA9IHRoaXMuY2hpbGRyZW4ubGVuZ3RoO1xuICBpZiAobGVuID4gMCkge1xuICAgIG5ld0NoaWxkcmVuID0gW107XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbi0xOyBpKyspIHtcbiAgICAgIG5ld0NoaWxkcmVuLnB1c2godGhpcy5jaGlsZHJlbltpXSk7XG4gICAgICBuZXdDaGlsZHJlbi5wdXNoKGFTZXApO1xuICAgIH1cbiAgICBuZXdDaGlsZHJlbi5wdXNoKHRoaXMuY2hpbGRyZW5baV0pO1xuICAgIHRoaXMuY2hpbGRyZW4gPSBuZXdDaGlsZHJlbjtcbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ2FsbCBTdHJpbmcucHJvdG90eXBlLnJlcGxhY2Ugb24gdGhlIHZlcnkgcmlnaHQtbW9zdCBzb3VyY2Ugc25pcHBldC4gVXNlZnVsXG4gKiBmb3IgdHJpbW1pbmcgd2hpdGVzcGFjZSBmcm9tIHRoZSBlbmQgb2YgYSBzb3VyY2Ugbm9kZSwgZXRjLlxuICpcbiAqIEBwYXJhbSBhUGF0dGVybiBUaGUgcGF0dGVybiB0byByZXBsYWNlLlxuICogQHBhcmFtIGFSZXBsYWNlbWVudCBUaGUgdGhpbmcgdG8gcmVwbGFjZSB0aGUgcGF0dGVybiB3aXRoLlxuICovXG5Tb3VyY2VOb2RlLnByb3RvdHlwZS5yZXBsYWNlUmlnaHQgPSBmdW5jdGlvbiBTb3VyY2VOb2RlX3JlcGxhY2VSaWdodChhUGF0dGVybiwgYVJlcGxhY2VtZW50KSB7XG4gIHZhciBsYXN0Q2hpbGQgPSB0aGlzLmNoaWxkcmVuW3RoaXMuY2hpbGRyZW4ubGVuZ3RoIC0gMV07XG4gIGlmIChsYXN0Q2hpbGRbaXNTb3VyY2VOb2RlXSkge1xuICAgIGxhc3RDaGlsZC5yZXBsYWNlUmlnaHQoYVBhdHRlcm4sIGFSZXBsYWNlbWVudCk7XG4gIH1cbiAgZWxzZSBpZiAodHlwZW9mIGxhc3RDaGlsZCA9PT0gJ3N0cmluZycpIHtcbiAgICB0aGlzLmNoaWxkcmVuW3RoaXMuY2hpbGRyZW4ubGVuZ3RoIC0gMV0gPSBsYXN0Q2hpbGQucmVwbGFjZShhUGF0dGVybiwgYVJlcGxhY2VtZW50KTtcbiAgfVxuICBlbHNlIHtcbiAgICB0aGlzLmNoaWxkcmVuLnB1c2goJycucmVwbGFjZShhUGF0dGVybiwgYVJlcGxhY2VtZW50KSk7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldCB0aGUgc291cmNlIGNvbnRlbnQgZm9yIGEgc291cmNlIGZpbGUuIFRoaXMgd2lsbCBiZSBhZGRlZCB0byB0aGUgU291cmNlTWFwR2VuZXJhdG9yXG4gKiBpbiB0aGUgc291cmNlc0NvbnRlbnQgZmllbGQuXG4gKlxuICogQHBhcmFtIGFTb3VyY2VGaWxlIFRoZSBmaWxlbmFtZSBvZiB0aGUgc291cmNlIGZpbGVcbiAqIEBwYXJhbSBhU291cmNlQ29udGVudCBUaGUgY29udGVudCBvZiB0aGUgc291cmNlIGZpbGVcbiAqL1xuU291cmNlTm9kZS5wcm90b3R5cGUuc2V0U291cmNlQ29udGVudCA9XG4gIGZ1bmN0aW9uIFNvdXJjZU5vZGVfc2V0U291cmNlQ29udGVudChhU291cmNlRmlsZSwgYVNvdXJjZUNvbnRlbnQpIHtcbiAgICB0aGlzLnNvdXJjZUNvbnRlbnRzW3V0aWwudG9TZXRTdHJpbmcoYVNvdXJjZUZpbGUpXSA9IGFTb3VyY2VDb250ZW50O1xuICB9O1xuXG4vKipcbiAqIFdhbGsgb3ZlciB0aGUgdHJlZSBvZiBTb3VyY2VOb2Rlcy4gVGhlIHdhbGtpbmcgZnVuY3Rpb24gaXMgY2FsbGVkIGZvciBlYWNoXG4gKiBzb3VyY2UgZmlsZSBjb250ZW50IGFuZCBpcyBwYXNzZWQgdGhlIGZpbGVuYW1lIGFuZCBzb3VyY2UgY29udGVudC5cbiAqXG4gKiBAcGFyYW0gYUZuIFRoZSB0cmF2ZXJzYWwgZnVuY3Rpb24uXG4gKi9cblNvdXJjZU5vZGUucHJvdG90eXBlLndhbGtTb3VyY2VDb250ZW50cyA9XG4gIGZ1bmN0aW9uIFNvdXJjZU5vZGVfd2Fsa1NvdXJjZUNvbnRlbnRzKGFGbikge1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSB0aGlzLmNoaWxkcmVuLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBpZiAodGhpcy5jaGlsZHJlbltpXVtpc1NvdXJjZU5vZGVdKSB7XG4gICAgICAgIHRoaXMuY2hpbGRyZW5baV0ud2Fsa1NvdXJjZUNvbnRlbnRzKGFGbik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHNvdXJjZXMgPSBPYmplY3Qua2V5cyh0aGlzLnNvdXJjZUNvbnRlbnRzKTtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gc291cmNlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgYUZuKHV0aWwuZnJvbVNldFN0cmluZyhzb3VyY2VzW2ldKSwgdGhpcy5zb3VyY2VDb250ZW50c1tzb3VyY2VzW2ldXSk7XG4gICAgfVxuICB9O1xuXG4vKipcbiAqIFJldHVybiB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgc291cmNlIG5vZGUuIFdhbGtzIG92ZXIgdGhlIHRyZWVcbiAqIGFuZCBjb25jYXRlbmF0ZXMgYWxsIHRoZSB2YXJpb3VzIHNuaXBwZXRzIHRvZ2V0aGVyIHRvIG9uZSBzdHJpbmcuXG4gKi9cblNvdXJjZU5vZGUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gU291cmNlTm9kZV90b1N0cmluZygpIHtcbiAgdmFyIHN0ciA9IFwiXCI7XG4gIHRoaXMud2FsayhmdW5jdGlvbiAoY2h1bmspIHtcbiAgICBzdHIgKz0gY2h1bms7XG4gIH0pO1xuICByZXR1cm4gc3RyO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBzb3VyY2Ugbm9kZSBhbG9uZyB3aXRoIGEgc291cmNlXG4gKiBtYXAuXG4gKi9cblNvdXJjZU5vZGUucHJvdG90eXBlLnRvU3RyaW5nV2l0aFNvdXJjZU1hcCA9IGZ1bmN0aW9uIFNvdXJjZU5vZGVfdG9TdHJpbmdXaXRoU291cmNlTWFwKGFBcmdzKSB7XG4gIHZhciBnZW5lcmF0ZWQgPSB7XG4gICAgY29kZTogXCJcIixcbiAgICBsaW5lOiAxLFxuICAgIGNvbHVtbjogMFxuICB9O1xuICB2YXIgbWFwID0gbmV3IFNvdXJjZU1hcEdlbmVyYXRvcihhQXJncyk7XG4gIHZhciBzb3VyY2VNYXBwaW5nQWN0aXZlID0gZmFsc2U7XG4gIHZhciBsYXN0T3JpZ2luYWxTb3VyY2UgPSBudWxsO1xuICB2YXIgbGFzdE9yaWdpbmFsTGluZSA9IG51bGw7XG4gIHZhciBsYXN0T3JpZ2luYWxDb2x1bW4gPSBudWxsO1xuICB2YXIgbGFzdE9yaWdpbmFsTmFtZSA9IG51bGw7XG4gIHRoaXMud2FsayhmdW5jdGlvbiAoY2h1bmssIG9yaWdpbmFsKSB7XG4gICAgZ2VuZXJhdGVkLmNvZGUgKz0gY2h1bms7XG4gICAgaWYgKG9yaWdpbmFsLnNvdXJjZSAhPT0gbnVsbFxuICAgICAgICAmJiBvcmlnaW5hbC5saW5lICE9PSBudWxsXG4gICAgICAgICYmIG9yaWdpbmFsLmNvbHVtbiAhPT0gbnVsbCkge1xuICAgICAgaWYobGFzdE9yaWdpbmFsU291cmNlICE9PSBvcmlnaW5hbC5zb3VyY2VcbiAgICAgICAgIHx8IGxhc3RPcmlnaW5hbExpbmUgIT09IG9yaWdpbmFsLmxpbmVcbiAgICAgICAgIHx8IGxhc3RPcmlnaW5hbENvbHVtbiAhPT0gb3JpZ2luYWwuY29sdW1uXG4gICAgICAgICB8fCBsYXN0T3JpZ2luYWxOYW1lICE9PSBvcmlnaW5hbC5uYW1lKSB7XG4gICAgICAgIG1hcC5hZGRNYXBwaW5nKHtcbiAgICAgICAgICBzb3VyY2U6IG9yaWdpbmFsLnNvdXJjZSxcbiAgICAgICAgICBvcmlnaW5hbDoge1xuICAgICAgICAgICAgbGluZTogb3JpZ2luYWwubGluZSxcbiAgICAgICAgICAgIGNvbHVtbjogb3JpZ2luYWwuY29sdW1uXG4gICAgICAgICAgfSxcbiAgICAgICAgICBnZW5lcmF0ZWQ6IHtcbiAgICAgICAgICAgIGxpbmU6IGdlbmVyYXRlZC5saW5lLFxuICAgICAgICAgICAgY29sdW1uOiBnZW5lcmF0ZWQuY29sdW1uXG4gICAgICAgICAgfSxcbiAgICAgICAgICBuYW1lOiBvcmlnaW5hbC5uYW1lXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgbGFzdE9yaWdpbmFsU291cmNlID0gb3JpZ2luYWwuc291cmNlO1xuICAgICAgbGFzdE9yaWdpbmFsTGluZSA9IG9yaWdpbmFsLmxpbmU7XG4gICAgICBsYXN0T3JpZ2luYWxDb2x1bW4gPSBvcmlnaW5hbC5jb2x1bW47XG4gICAgICBsYXN0T3JpZ2luYWxOYW1lID0gb3JpZ2luYWwubmFtZTtcbiAgICAgIHNvdXJjZU1hcHBpbmdBY3RpdmUgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAoc291cmNlTWFwcGluZ0FjdGl2ZSkge1xuICAgICAgbWFwLmFkZE1hcHBpbmcoe1xuICAgICAgICBnZW5lcmF0ZWQ6IHtcbiAgICAgICAgICBsaW5lOiBnZW5lcmF0ZWQubGluZSxcbiAgICAgICAgICBjb2x1bW46IGdlbmVyYXRlZC5jb2x1bW5cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBsYXN0T3JpZ2luYWxTb3VyY2UgPSBudWxsO1xuICAgICAgc291cmNlTWFwcGluZ0FjdGl2ZSA9IGZhbHNlO1xuICAgIH1cbiAgICBmb3IgKHZhciBpZHggPSAwLCBsZW5ndGggPSBjaHVuay5sZW5ndGg7IGlkeCA8IGxlbmd0aDsgaWR4KyspIHtcbiAgICAgIGlmIChjaHVuay5jaGFyQ29kZUF0KGlkeCkgPT09IE5FV0xJTkVfQ09ERSkge1xuICAgICAgICBnZW5lcmF0ZWQubGluZSsrO1xuICAgICAgICBnZW5lcmF0ZWQuY29sdW1uID0gMDtcbiAgICAgICAgLy8gTWFwcGluZ3MgZW5kIGF0IGVvbFxuICAgICAgICBpZiAoaWR4ICsgMSA9PT0gbGVuZ3RoKSB7XG4gICAgICAgICAgbGFzdE9yaWdpbmFsU291cmNlID0gbnVsbDtcbiAgICAgICAgICBzb3VyY2VNYXBwaW5nQWN0aXZlID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSBpZiAoc291cmNlTWFwcGluZ0FjdGl2ZSkge1xuICAgICAgICAgIG1hcC5hZGRNYXBwaW5nKHtcbiAgICAgICAgICAgIHNvdXJjZTogb3JpZ2luYWwuc291cmNlLFxuICAgICAgICAgICAgb3JpZ2luYWw6IHtcbiAgICAgICAgICAgICAgbGluZTogb3JpZ2luYWwubGluZSxcbiAgICAgICAgICAgICAgY29sdW1uOiBvcmlnaW5hbC5jb2x1bW5cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZW5lcmF0ZWQ6IHtcbiAgICAgICAgICAgICAgbGluZTogZ2VuZXJhdGVkLmxpbmUsXG4gICAgICAgICAgICAgIGNvbHVtbjogZ2VuZXJhdGVkLmNvbHVtblxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG5hbWU6IG9yaWdpbmFsLm5hbWVcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZ2VuZXJhdGVkLmNvbHVtbisrO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHRoaXMud2Fsa1NvdXJjZUNvbnRlbnRzKGZ1bmN0aW9uIChzb3VyY2VGaWxlLCBzb3VyY2VDb250ZW50KSB7XG4gICAgbWFwLnNldFNvdXJjZUNvbnRlbnQoc291cmNlRmlsZSwgc291cmNlQ29udGVudCk7XG4gIH0pO1xuXG4gIHJldHVybiB7IGNvZGU6IGdlbmVyYXRlZC5jb2RlLCBtYXA6IG1hcCB9O1xufTtcblxuZXhwb3J0cy5Tb3VyY2VOb2RlID0gU291cmNlTm9kZTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9saWIvc291cmNlLW5vZGUuanNcbiAqKiBtb2R1bGUgaWQgPSAxMFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIl0sInNvdXJjZVJvb3QiOiIifQ== \ No newline at end of file diff --git a/node_modules/source-map/dist/source-map.js b/node_modules/source-map/dist/source-map.js new file mode 100644 index 0000000..61c0d8d --- /dev/null +++ b/node_modules/source-map/dist/source-map.js @@ -0,0 +1,3055 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["sourceMap"] = factory(); + else + root["sourceMap"] = factory(); +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + /* + * Copyright 2009-2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE.txt or: + * http://opensource.org/licenses/BSD-3-Clause + */ + exports.SourceMapGenerator = __webpack_require__(1).SourceMapGenerator; + exports.SourceMapConsumer = __webpack_require__(7).SourceMapConsumer; + exports.SourceNode = __webpack_require__(10).SourceNode; + + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var base64VLQ = __webpack_require__(2); + var util = __webpack_require__(4); + var ArraySet = __webpack_require__(5).ArraySet; + var MappingList = __webpack_require__(6).MappingList; + + /** + * An instance of the SourceMapGenerator represents a source map which is + * being built incrementally. You may pass an object with the following + * properties: + * + * - file: The filename of the generated source. + * - sourceRoot: A root for all relative URLs in this source map. + */ + function SourceMapGenerator(aArgs) { + if (!aArgs) { + aArgs = {}; + } + this._file = util.getArg(aArgs, 'file', null); + this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null); + this._skipValidation = util.getArg(aArgs, 'skipValidation', false); + this._sources = new ArraySet(); + this._names = new ArraySet(); + this._mappings = new MappingList(); + this._sourcesContents = null; + } + + SourceMapGenerator.prototype._version = 3; + + /** + * Creates a new SourceMapGenerator based on a SourceMapConsumer + * + * @param aSourceMapConsumer The SourceMap. + */ + SourceMapGenerator.fromSourceMap = + function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) { + var sourceRoot = aSourceMapConsumer.sourceRoot; + var generator = new SourceMapGenerator({ + file: aSourceMapConsumer.file, + sourceRoot: sourceRoot + }); + aSourceMapConsumer.eachMapping(function (mapping) { + var newMapping = { + generated: { + line: mapping.generatedLine, + column: mapping.generatedColumn + } + }; + + if (mapping.source != null) { + newMapping.source = mapping.source; + if (sourceRoot != null) { + newMapping.source = util.relative(sourceRoot, newMapping.source); + } + + newMapping.original = { + line: mapping.originalLine, + column: mapping.originalColumn + }; + + if (mapping.name != null) { + newMapping.name = mapping.name; + } + } + + generator.addMapping(newMapping); + }); + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + generator.setSourceContent(sourceFile, content); + } + }); + return generator; + }; + + /** + * Add a single mapping from original source line and column to the generated + * source's line and column for this source map being created. The mapping + * object should have the following properties: + * + * - generated: An object with the generated line and column positions. + * - original: An object with the original line and column positions. + * - source: The original source file (relative to the sourceRoot). + * - name: An optional original token name for this mapping. + */ + SourceMapGenerator.prototype.addMapping = + function SourceMapGenerator_addMapping(aArgs) { + var generated = util.getArg(aArgs, 'generated'); + var original = util.getArg(aArgs, 'original', null); + var source = util.getArg(aArgs, 'source', null); + var name = util.getArg(aArgs, 'name', null); + + if (!this._skipValidation) { + this._validateMapping(generated, original, source, name); + } + + if (source != null) { + source = String(source); + if (!this._sources.has(source)) { + this._sources.add(source); + } + } + + if (name != null) { + name = String(name); + if (!this._names.has(name)) { + this._names.add(name); + } + } + + this._mappings.add({ + generatedLine: generated.line, + generatedColumn: generated.column, + originalLine: original != null && original.line, + originalColumn: original != null && original.column, + source: source, + name: name + }); + }; + + /** + * Set the source content for a source file. + */ + SourceMapGenerator.prototype.setSourceContent = + function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { + var source = aSourceFile; + if (this._sourceRoot != null) { + source = util.relative(this._sourceRoot, source); + } + + if (aSourceContent != null) { + // Add the source content to the _sourcesContents map. + // Create a new _sourcesContents map if the property is null. + if (!this._sourcesContents) { + this._sourcesContents = Object.create(null); + } + this._sourcesContents[util.toSetString(source)] = aSourceContent; + } else if (this._sourcesContents) { + // Remove the source file from the _sourcesContents map. + // If the _sourcesContents map is empty, set the property to null. + delete this._sourcesContents[util.toSetString(source)]; + if (Object.keys(this._sourcesContents).length === 0) { + this._sourcesContents = null; + } + } + }; + + /** + * Applies the mappings of a sub-source-map for a specific source file to the + * source map being generated. Each mapping to the supplied source file is + * rewritten using the supplied source map. Note: The resolution for the + * resulting mappings is the minimium of this map and the supplied map. + * + * @param aSourceMapConsumer The source map to be applied. + * @param aSourceFile Optional. The filename of the source file. + * If omitted, SourceMapConsumer's file property will be used. + * @param aSourceMapPath Optional. The dirname of the path to the source map + * to be applied. If relative, it is relative to the SourceMapConsumer. + * This parameter is needed when the two source maps aren't in the same + * directory, and the source map to be applied contains relative source + * paths. If so, those relative source paths need to be rewritten + * relative to the SourceMapGenerator. + */ + SourceMapGenerator.prototype.applySourceMap = + function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) { + var sourceFile = aSourceFile; + // If aSourceFile is omitted, we will use the file property of the SourceMap + if (aSourceFile == null) { + if (aSourceMapConsumer.file == null) { + throw new Error( + 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' + + 'or the source map\'s "file" property. Both were omitted.' + ); + } + sourceFile = aSourceMapConsumer.file; + } + var sourceRoot = this._sourceRoot; + // Make "sourceFile" relative if an absolute Url is passed. + if (sourceRoot != null) { + sourceFile = util.relative(sourceRoot, sourceFile); + } + // Applying the SourceMap can add and remove items from the sources and + // the names array. + var newSources = new ArraySet(); + var newNames = new ArraySet(); + + // Find mappings for the "sourceFile" + this._mappings.unsortedForEach(function (mapping) { + if (mapping.source === sourceFile && mapping.originalLine != null) { + // Check if it can be mapped by the source map, then update the mapping. + var original = aSourceMapConsumer.originalPositionFor({ + line: mapping.originalLine, + column: mapping.originalColumn + }); + if (original.source != null) { + // Copy mapping + mapping.source = original.source; + if (aSourceMapPath != null) { + mapping.source = util.join(aSourceMapPath, mapping.source) + } + if (sourceRoot != null) { + mapping.source = util.relative(sourceRoot, mapping.source); + } + mapping.originalLine = original.line; + mapping.originalColumn = original.column; + if (original.name != null) { + mapping.name = original.name; + } + } + } + + var source = mapping.source; + if (source != null && !newSources.has(source)) { + newSources.add(source); + } + + var name = mapping.name; + if (name != null && !newNames.has(name)) { + newNames.add(name); + } + + }, this); + this._sources = newSources; + this._names = newNames; + + // Copy sourcesContents of applied map. + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aSourceMapPath != null) { + sourceFile = util.join(aSourceMapPath, sourceFile); + } + if (sourceRoot != null) { + sourceFile = util.relative(sourceRoot, sourceFile); + } + this.setSourceContent(sourceFile, content); + } + }, this); + }; + + /** + * A mapping can have one of the three levels of data: + * + * 1. Just the generated position. + * 2. The Generated position, original position, and original source. + * 3. Generated and original position, original source, as well as a name + * token. + * + * To maintain consistency, we validate that any new mapping being added falls + * in to one of these categories. + */ + SourceMapGenerator.prototype._validateMapping = + function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, + aName) { + if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aGenerated.line > 0 && aGenerated.column >= 0 + && !aOriginal && !aSource && !aName) { + // Case 1. + return; + } + else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aOriginal && 'line' in aOriginal && 'column' in aOriginal + && aGenerated.line > 0 && aGenerated.column >= 0 + && aOriginal.line > 0 && aOriginal.column >= 0 + && aSource) { + // Cases 2 and 3. + return; + } + else { + throw new Error('Invalid mapping: ' + JSON.stringify({ + generated: aGenerated, + source: aSource, + original: aOriginal, + name: aName + })); + } + }; + + /** + * Serialize the accumulated mappings in to the stream of base 64 VLQs + * specified by the source map format. + */ + SourceMapGenerator.prototype._serializeMappings = + function SourceMapGenerator_serializeMappings() { + var previousGeneratedColumn = 0; + var previousGeneratedLine = 1; + var previousOriginalColumn = 0; + var previousOriginalLine = 0; + var previousName = 0; + var previousSource = 0; + var result = ''; + var next; + var mapping; + var nameIdx; + var sourceIdx; + + var mappings = this._mappings.toArray(); + for (var i = 0, len = mappings.length; i < len; i++) { + mapping = mappings[i]; + next = '' + + if (mapping.generatedLine !== previousGeneratedLine) { + previousGeneratedColumn = 0; + while (mapping.generatedLine !== previousGeneratedLine) { + next += ';'; + previousGeneratedLine++; + } + } + else { + if (i > 0) { + if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) { + continue; + } + next += ','; + } + } + + next += base64VLQ.encode(mapping.generatedColumn + - previousGeneratedColumn); + previousGeneratedColumn = mapping.generatedColumn; + + if (mapping.source != null) { + sourceIdx = this._sources.indexOf(mapping.source); + next += base64VLQ.encode(sourceIdx - previousSource); + previousSource = sourceIdx; + + // lines are stored 0-based in SourceMap spec version 3 + next += base64VLQ.encode(mapping.originalLine - 1 + - previousOriginalLine); + previousOriginalLine = mapping.originalLine - 1; + + next += base64VLQ.encode(mapping.originalColumn + - previousOriginalColumn); + previousOriginalColumn = mapping.originalColumn; + + if (mapping.name != null) { + nameIdx = this._names.indexOf(mapping.name); + next += base64VLQ.encode(nameIdx - previousName); + previousName = nameIdx; + } + } + + result += next; + } + + return result; + }; + + SourceMapGenerator.prototype._generateSourcesContent = + function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) { + return aSources.map(function (source) { + if (!this._sourcesContents) { + return null; + } + if (aSourceRoot != null) { + source = util.relative(aSourceRoot, source); + } + var key = util.toSetString(source); + return Object.prototype.hasOwnProperty.call(this._sourcesContents, key) + ? this._sourcesContents[key] + : null; + }, this); + }; + + /** + * Externalize the source map. + */ + SourceMapGenerator.prototype.toJSON = + function SourceMapGenerator_toJSON() { + var map = { + version: this._version, + sources: this._sources.toArray(), + names: this._names.toArray(), + mappings: this._serializeMappings() + }; + if (this._file != null) { + map.file = this._file; + } + if (this._sourceRoot != null) { + map.sourceRoot = this._sourceRoot; + } + if (this._sourcesContents) { + map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); + } + + return map; + }; + + /** + * Render the source map being generated to a string. + */ + SourceMapGenerator.prototype.toString = + function SourceMapGenerator_toString() { + return JSON.stringify(this.toJSON()); + }; + + exports.SourceMapGenerator = SourceMapGenerator; + + +/***/ }, +/* 2 */ +/***/ function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + * + * Based on the Base 64 VLQ implementation in Closure Compiler: + * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java + * + * Copyright 2011 The Closure Compiler Authors. All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + var base64 = __webpack_require__(3); + + // A single base 64 digit can contain 6 bits of data. For the base 64 variable + // length quantities we use in the source map spec, the first bit is the sign, + // the next four bits are the actual value, and the 6th bit is the + // continuation bit. The continuation bit tells us whether there are more + // digits in this value following this digit. + // + // Continuation + // | Sign + // | | + // V V + // 101011 + + var VLQ_BASE_SHIFT = 5; + + // binary: 100000 + var VLQ_BASE = 1 << VLQ_BASE_SHIFT; + + // binary: 011111 + var VLQ_BASE_MASK = VLQ_BASE - 1; + + // binary: 100000 + var VLQ_CONTINUATION_BIT = VLQ_BASE; + + /** + * Converts from a two-complement value to a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) + * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) + */ + function toVLQSigned(aValue) { + return aValue < 0 + ? ((-aValue) << 1) + 1 + : (aValue << 1) + 0; + } + + /** + * Converts to a two-complement value from a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 + * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 + */ + function fromVLQSigned(aValue) { + var isNegative = (aValue & 1) === 1; + var shifted = aValue >> 1; + return isNegative + ? -shifted + : shifted; + } + + /** + * Returns the base 64 VLQ encoded value. + */ + exports.encode = function base64VLQ_encode(aValue) { + var encoded = ""; + var digit; + + var vlq = toVLQSigned(aValue); + + do { + digit = vlq & VLQ_BASE_MASK; + vlq >>>= VLQ_BASE_SHIFT; + if (vlq > 0) { + // There are still more digits in this value, so we must make sure the + // continuation bit is marked. + digit |= VLQ_CONTINUATION_BIT; + } + encoded += base64.encode(digit); + } while (vlq > 0); + + return encoded; + }; + + /** + * Decodes the next base 64 VLQ value from the given string and returns the + * value and the rest of the string via the out parameter. + */ + exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { + var strLen = aStr.length; + var result = 0; + var shift = 0; + var continuation, digit; + + do { + if (aIndex >= strLen) { + throw new Error("Expected more digits in base 64 VLQ value."); + } + + digit = base64.decode(aStr.charCodeAt(aIndex++)); + if (digit === -1) { + throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1)); + } + + continuation = !!(digit & VLQ_CONTINUATION_BIT); + digit &= VLQ_BASE_MASK; + result = result + (digit << shift); + shift += VLQ_BASE_SHIFT; + } while (continuation); + + aOutParam.value = fromVLQSigned(result); + aOutParam.rest = aIndex; + }; + + +/***/ }, +/* 3 */ +/***/ function(module, exports) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); + + /** + * Encode an integer in the range of 0 to 63 to a single base 64 digit. + */ + exports.encode = function (number) { + if (0 <= number && number < intToCharMap.length) { + return intToCharMap[number]; + } + throw new TypeError("Must be between 0 and 63: " + number); + }; + + /** + * Decode a single base 64 character code digit to an integer. Returns -1 on + * failure. + */ + exports.decode = function (charCode) { + var bigA = 65; // 'A' + var bigZ = 90; // 'Z' + + var littleA = 97; // 'a' + var littleZ = 122; // 'z' + + var zero = 48; // '0' + var nine = 57; // '9' + + var plus = 43; // '+' + var slash = 47; // '/' + + var littleOffset = 26; + var numberOffset = 52; + + // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ + if (bigA <= charCode && charCode <= bigZ) { + return (charCode - bigA); + } + + // 26 - 51: abcdefghijklmnopqrstuvwxyz + if (littleA <= charCode && charCode <= littleZ) { + return (charCode - littleA + littleOffset); + } + + // 52 - 61: 0123456789 + if (zero <= charCode && charCode <= nine) { + return (charCode - zero + numberOffset); + } + + // 62: + + if (charCode == plus) { + return 62; + } + + // 63: / + if (charCode == slash) { + return 63; + } + + // Invalid base64 digit. + return -1; + }; + + +/***/ }, +/* 4 */ +/***/ function(module, exports) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + /** + * This is a helper function for getting values from parameter/options + * objects. + * + * @param args The object we are extracting values from + * @param name The name of the property we are getting. + * @param defaultValue An optional value to return if the property is missing + * from the object. If this is not specified and the property is missing, an + * error will be thrown. + */ + function getArg(aArgs, aName, aDefaultValue) { + if (aName in aArgs) { + return aArgs[aName]; + } else if (arguments.length === 3) { + return aDefaultValue; + } else { + throw new Error('"' + aName + '" is a required argument.'); + } + } + exports.getArg = getArg; + + var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/; + var dataUrlRegexp = /^data:.+\,.+$/; + + function urlParse(aUrl) { + var match = aUrl.match(urlRegexp); + if (!match) { + return null; + } + return { + scheme: match[1], + auth: match[2], + host: match[3], + port: match[4], + path: match[5] + }; + } + exports.urlParse = urlParse; + + function urlGenerate(aParsedUrl) { + var url = ''; + if (aParsedUrl.scheme) { + url += aParsedUrl.scheme + ':'; + } + url += '//'; + if (aParsedUrl.auth) { + url += aParsedUrl.auth + '@'; + } + if (aParsedUrl.host) { + url += aParsedUrl.host; + } + if (aParsedUrl.port) { + url += ":" + aParsedUrl.port + } + if (aParsedUrl.path) { + url += aParsedUrl.path; + } + return url; + } + exports.urlGenerate = urlGenerate; + + /** + * Normalizes a path, or the path portion of a URL: + * + * - Replaces consequtive slashes with one slash. + * - Removes unnecessary '.' parts. + * - Removes unnecessary '/..' parts. + * + * Based on code in the Node.js 'path' core module. + * + * @param aPath The path or url to normalize. + */ + function normalize(aPath) { + var path = aPath; + var url = urlParse(aPath); + if (url) { + if (!url.path) { + return aPath; + } + path = url.path; + } + var isAbsolute = exports.isAbsolute(path); + + var parts = path.split(/\/+/); + for (var part, up = 0, i = parts.length - 1; i >= 0; i--) { + part = parts[i]; + if (part === '.') { + parts.splice(i, 1); + } else if (part === '..') { + up++; + } else if (up > 0) { + if (part === '') { + // The first part is blank if the path is absolute. Trying to go + // above the root is a no-op. Therefore we can remove all '..' parts + // directly after the root. + parts.splice(i + 1, up); + up = 0; + } else { + parts.splice(i, 2); + up--; + } + } + } + path = parts.join('/'); + + if (path === '') { + path = isAbsolute ? '/' : '.'; + } + + if (url) { + url.path = path; + return urlGenerate(url); + } + return path; + } + exports.normalize = normalize; + + /** + * Joins two paths/URLs. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be joined with the root. + * + * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a + * scheme-relative URL: Then the scheme of aRoot, if any, is prepended + * first. + * - Otherwise aPath is a path. If aRoot is a URL, then its path portion + * is updated with the result and aRoot is returned. Otherwise the result + * is returned. + * - If aPath is absolute, the result is aPath. + * - Otherwise the two paths are joined with a slash. + * - Joining for example 'http://' and 'www.example.com' is also supported. + */ + function join(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + if (aPath === "") { + aPath = "."; + } + var aPathUrl = urlParse(aPath); + var aRootUrl = urlParse(aRoot); + if (aRootUrl) { + aRoot = aRootUrl.path || '/'; + } + + // `join(foo, '//www.example.org')` + if (aPathUrl && !aPathUrl.scheme) { + if (aRootUrl) { + aPathUrl.scheme = aRootUrl.scheme; + } + return urlGenerate(aPathUrl); + } + + if (aPathUrl || aPath.match(dataUrlRegexp)) { + return aPath; + } + + // `join('http://', 'www.example.com')` + if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { + aRootUrl.host = aPath; + return urlGenerate(aRootUrl); + } + + var joined = aPath.charAt(0) === '/' + ? aPath + : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); + + if (aRootUrl) { + aRootUrl.path = joined; + return urlGenerate(aRootUrl); + } + return joined; + } + exports.join = join; + + exports.isAbsolute = function (aPath) { + return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp); + }; + + /** + * Make a path relative to a URL or another path. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be made relative to aRoot. + */ + function relative(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + + aRoot = aRoot.replace(/\/$/, ''); + + // It is possible for the path to be above the root. In this case, simply + // checking whether the root is a prefix of the path won't work. Instead, we + // need to remove components from the root one by one, until either we find + // a prefix that fits, or we run out of components to remove. + var level = 0; + while (aPath.indexOf(aRoot + '/') !== 0) { + var index = aRoot.lastIndexOf("/"); + if (index < 0) { + return aPath; + } + + // If the only part of the root that is left is the scheme (i.e. http://, + // file:///, etc.), one or more slashes (/), or simply nothing at all, we + // have exhausted all components, so the path is not relative to the root. + aRoot = aRoot.slice(0, index); + if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { + return aPath; + } + + ++level; + } + + // Make sure we add a "../" for each component we removed from the root. + return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1); + } + exports.relative = relative; + + var supportsNullProto = (function () { + var obj = Object.create(null); + return !('__proto__' in obj); + }()); + + function identity (s) { + return s; + } + + /** + * Because behavior goes wacky when you set `__proto__` on objects, we + * have to prefix all the strings in our set with an arbitrary character. + * + * See https://github.com/mozilla/source-map/pull/31 and + * https://github.com/mozilla/source-map/issues/30 + * + * @param String aStr + */ + function toSetString(aStr) { + if (isProtoString(aStr)) { + return '$' + aStr; + } + + return aStr; + } + exports.toSetString = supportsNullProto ? identity : toSetString; + + function fromSetString(aStr) { + if (isProtoString(aStr)) { + return aStr.slice(1); + } + + return aStr; + } + exports.fromSetString = supportsNullProto ? identity : fromSetString; + + function isProtoString(s) { + if (!s) { + return false; + } + + var length = s.length; + + if (length < 9 /* "__proto__".length */) { + return false; + } + + if (s.charCodeAt(length - 1) !== 95 /* '_' */ || + s.charCodeAt(length - 2) !== 95 /* '_' */ || + s.charCodeAt(length - 3) !== 111 /* 'o' */ || + s.charCodeAt(length - 4) !== 116 /* 't' */ || + s.charCodeAt(length - 5) !== 111 /* 'o' */ || + s.charCodeAt(length - 6) !== 114 /* 'r' */ || + s.charCodeAt(length - 7) !== 112 /* 'p' */ || + s.charCodeAt(length - 8) !== 95 /* '_' */ || + s.charCodeAt(length - 9) !== 95 /* '_' */) { + return false; + } + + for (var i = length - 10; i >= 0; i--) { + if (s.charCodeAt(i) !== 36 /* '$' */) { + return false; + } + } + + return true; + } + + /** + * Comparator between two mappings where the original positions are compared. + * + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same original source/line/column, but different generated + * line and column the same. Useful when searching for a mapping with a + * stubbed out mapping. + */ + function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { + var cmp = mappingA.source - mappingB.source; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0 || onlyCompareOriginal) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + return mappingA.name - mappingB.name; + } + exports.compareByOriginalPositions = compareByOriginalPositions; + + /** + * Comparator between two mappings with deflated source and name indices where + * the generated positions are compared. + * + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same generated line and column, but different + * source/name/original line and column the same. Useful when searching for a + * mapping with a stubbed out mapping. + */ + function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0 || onlyCompareGenerated) { + return cmp; + } + + cmp = mappingA.source - mappingB.source; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } + + return mappingA.name - mappingB.name; + } + exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; + + function strcmp(aStr1, aStr2) { + if (aStr1 === aStr2) { + return 0; + } + + if (aStr1 > aStr2) { + return 1; + } + + return -1; + } + + /** + * Comparator between two mappings with inflated source and name strings where + * the generated positions are compared. + */ + function compareByGeneratedPositionsInflated(mappingA, mappingB) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } + + cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } + + return strcmp(mappingA.name, mappingB.name); + } + exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; + + +/***/ }, +/* 5 */ +/***/ function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var util = __webpack_require__(4); + var has = Object.prototype.hasOwnProperty; + + /** + * A data structure which is a combination of an array and a set. Adding a new + * member is O(1), testing for membership is O(1), and finding the index of an + * element is O(1). Removing elements from the set is not supported. Only + * strings are supported for membership. + */ + function ArraySet() { + this._array = []; + this._set = Object.create(null); + } + + /** + * Static method for creating ArraySet instances from an existing array. + */ + ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) { + var set = new ArraySet(); + for (var i = 0, len = aArray.length; i < len; i++) { + set.add(aArray[i], aAllowDuplicates); + } + return set; + }; + + /** + * Return how many unique items are in this ArraySet. If duplicates have been + * added, than those do not count towards the size. + * + * @returns Number + */ + ArraySet.prototype.size = function ArraySet_size() { + return Object.getOwnPropertyNames(this._set).length; + }; + + /** + * Add the given string to this set. + * + * @param String aStr + */ + ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) { + var sStr = util.toSetString(aStr); + var isDuplicate = has.call(this._set, sStr); + var idx = this._array.length; + if (!isDuplicate || aAllowDuplicates) { + this._array.push(aStr); + } + if (!isDuplicate) { + this._set[sStr] = idx; + } + }; + + /** + * Is the given string a member of this set? + * + * @param String aStr + */ + ArraySet.prototype.has = function ArraySet_has(aStr) { + var sStr = util.toSetString(aStr); + return has.call(this._set, sStr); + }; + + /** + * What is the index of the given string in the array? + * + * @param String aStr + */ + ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) { + var sStr = util.toSetString(aStr); + if (has.call(this._set, sStr)) { + return this._set[sStr]; + } + throw new Error('"' + aStr + '" is not in the set.'); + }; + + /** + * What is the element at the given index? + * + * @param Number aIdx + */ + ArraySet.prototype.at = function ArraySet_at(aIdx) { + if (aIdx >= 0 && aIdx < this._array.length) { + return this._array[aIdx]; + } + throw new Error('No element indexed by ' + aIdx); + }; + + /** + * Returns the array representation of this set (which has the proper indices + * indicated by indexOf). Note that this is a copy of the internal array used + * for storing the members so that no one can mess with internal state. + */ + ArraySet.prototype.toArray = function ArraySet_toArray() { + return this._array.slice(); + }; + + exports.ArraySet = ArraySet; + + +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2014 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var util = __webpack_require__(4); + + /** + * Determine whether mappingB is after mappingA with respect to generated + * position. + */ + function generatedPositionAfter(mappingA, mappingB) { + // Optimized for most common case + var lineA = mappingA.generatedLine; + var lineB = mappingB.generatedLine; + var columnA = mappingA.generatedColumn; + var columnB = mappingB.generatedColumn; + return lineB > lineA || lineB == lineA && columnB >= columnA || + util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0; + } + + /** + * A data structure to provide a sorted view of accumulated mappings in a + * performance conscious manner. It trades a neglibable overhead in general + * case for a large speedup in case of mappings being added in order. + */ + function MappingList() { + this._array = []; + this._sorted = true; + // Serves as infimum + this._last = {generatedLine: -1, generatedColumn: 0}; + } + + /** + * Iterate through internal items. This method takes the same arguments that + * `Array.prototype.forEach` takes. + * + * NOTE: The order of the mappings is NOT guaranteed. + */ + MappingList.prototype.unsortedForEach = + function MappingList_forEach(aCallback, aThisArg) { + this._array.forEach(aCallback, aThisArg); + }; + + /** + * Add the given source mapping. + * + * @param Object aMapping + */ + MappingList.prototype.add = function MappingList_add(aMapping) { + if (generatedPositionAfter(this._last, aMapping)) { + this._last = aMapping; + this._array.push(aMapping); + } else { + this._sorted = false; + this._array.push(aMapping); + } + }; + + /** + * Returns the flat, sorted array of mappings. The mappings are sorted by + * generated position. + * + * WARNING: This method returns internal data without copying, for + * performance. The return value must NOT be mutated, and should be treated as + * an immutable borrow. If you want to take ownership, you must make your own + * copy. + */ + MappingList.prototype.toArray = function MappingList_toArray() { + if (!this._sorted) { + this._array.sort(util.compareByGeneratedPositionsInflated); + this._sorted = true; + } + return this._array; + }; + + exports.MappingList = MappingList; + + +/***/ }, +/* 7 */ +/***/ function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var util = __webpack_require__(4); + var binarySearch = __webpack_require__(8); + var ArraySet = __webpack_require__(5).ArraySet; + var base64VLQ = __webpack_require__(2); + var quickSort = __webpack_require__(9).quickSort; + + function SourceMapConsumer(aSourceMap) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); + } + + return sourceMap.sections != null + ? new IndexedSourceMapConsumer(sourceMap) + : new BasicSourceMapConsumer(sourceMap); + } + + SourceMapConsumer.fromSourceMap = function(aSourceMap) { + return BasicSourceMapConsumer.fromSourceMap(aSourceMap); + } + + /** + * The version of the source mapping spec that we are consuming. + */ + SourceMapConsumer.prototype._version = 3; + + // `__generatedMappings` and `__originalMappings` are arrays that hold the + // parsed mapping coordinates from the source map's "mappings" attribute. They + // are lazily instantiated, accessed via the `_generatedMappings` and + // `_originalMappings` getters respectively, and we only parse the mappings + // and create these arrays once queried for a source location. We jump through + // these hoops because there can be many thousands of mappings, and parsing + // them is expensive, so we only want to do it if we must. + // + // Each object in the arrays is of the form: + // + // { + // generatedLine: The line number in the generated code, + // generatedColumn: The column number in the generated code, + // source: The path to the original source file that generated this + // chunk of code, + // originalLine: The line number in the original source that + // corresponds to this chunk of generated code, + // originalColumn: The column number in the original source that + // corresponds to this chunk of generated code, + // name: The name of the original symbol which generated this chunk of + // code. + // } + // + // All properties except for `generatedLine` and `generatedColumn` can be + // `null`. + // + // `_generatedMappings` is ordered by the generated positions. + // + // `_originalMappings` is ordered by the original positions. + + SourceMapConsumer.prototype.__generatedMappings = null; + Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', { + get: function () { + if (!this.__generatedMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__generatedMappings; + } + }); + + SourceMapConsumer.prototype.__originalMappings = null; + Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { + get: function () { + if (!this.__originalMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__originalMappings; + } + }); + + SourceMapConsumer.prototype._charIsMappingSeparator = + function SourceMapConsumer_charIsMappingSeparator(aStr, index) { + var c = aStr.charAt(index); + return c === ";" || c === ","; + }; + + /** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ + SourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + throw new Error("Subclasses must implement _parseMappings"); + }; + + SourceMapConsumer.GENERATED_ORDER = 1; + SourceMapConsumer.ORIGINAL_ORDER = 2; + + SourceMapConsumer.GREATEST_LOWER_BOUND = 1; + SourceMapConsumer.LEAST_UPPER_BOUND = 2; + + /** + * Iterate over each mapping between an original source/line/column and a + * generated line/column in this source map. + * + * @param Function aCallback + * The function that is called with each mapping. + * @param Object aContext + * Optional. If specified, this object will be the value of `this` every + * time that `aCallback` is called. + * @param aOrder + * Either `SourceMapConsumer.GENERATED_ORDER` or + * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to + * iterate over the mappings sorted by the generated file's line/column + * order or the original's source/line/column order, respectively. Defaults to + * `SourceMapConsumer.GENERATED_ORDER`. + */ + SourceMapConsumer.prototype.eachMapping = + function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { + var context = aContext || null; + var order = aOrder || SourceMapConsumer.GENERATED_ORDER; + + var mappings; + switch (order) { + case SourceMapConsumer.GENERATED_ORDER: + mappings = this._generatedMappings; + break; + case SourceMapConsumer.ORIGINAL_ORDER: + mappings = this._originalMappings; + break; + default: + throw new Error("Unknown order of iteration."); + } + + var sourceRoot = this.sourceRoot; + mappings.map(function (mapping) { + var source = mapping.source === null ? null : this._sources.at(mapping.source); + if (source != null && sourceRoot != null) { + source = util.join(sourceRoot, source); + } + return { + source: source, + generatedLine: mapping.generatedLine, + generatedColumn: mapping.generatedColumn, + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: mapping.name === null ? null : this._names.at(mapping.name) + }; + }, this).forEach(aCallback, context); + }; + + /** + * Returns all generated line and column information for the original source, + * line, and column provided. If no column is provided, returns all mappings + * corresponding to a either the line we are searching for or the next + * closest line that has any mappings. Otherwise, returns all mappings + * corresponding to the given line and either the column we are searching for + * or the next closest column that has any offsets. + * + * The only argument is an object with the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. + * - column: Optional. the column number in the original source. + * + * and an array of objects is returned, each with the following properties: + * + * - line: The line number in the generated source, or null. + * - column: The column number in the generated source, or null. + */ + SourceMapConsumer.prototype.allGeneratedPositionsFor = + function SourceMapConsumer_allGeneratedPositionsFor(aArgs) { + var line = util.getArg(aArgs, 'line'); + + // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping + // returns the index of the closest mapping less than the needle. By + // setting needle.originalColumn to 0, we thus find the last mapping for + // the given line, provided such a mapping exists. + var needle = { + source: util.getArg(aArgs, 'source'), + originalLine: line, + originalColumn: util.getArg(aArgs, 'column', 0) + }; + + if (this.sourceRoot != null) { + needle.source = util.relative(this.sourceRoot, needle.source); + } + if (!this._sources.has(needle.source)) { + return []; + } + needle.source = this._sources.indexOf(needle.source); + + var mappings = []; + + var index = this._findMapping(needle, + this._originalMappings, + "originalLine", + "originalColumn", + util.compareByOriginalPositions, + binarySearch.LEAST_UPPER_BOUND); + if (index >= 0) { + var mapping = this._originalMappings[index]; + + if (aArgs.column === undefined) { + var originalLine = mapping.originalLine; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we found. Since + // mappings are sorted, this is guaranteed to find all mappings for + // the line we found. + while (mapping && mapping.originalLine === originalLine) { + mappings.push({ + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } + } else { + var originalColumn = mapping.originalColumn; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we were searching for. + // Since mappings are sorted, this is guaranteed to find all mappings for + // the line we are searching for. + while (mapping && + mapping.originalLine === line && + mapping.originalColumn == originalColumn) { + mappings.push({ + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } + } + } + + return mappings; + }; + + exports.SourceMapConsumer = SourceMapConsumer; + + /** + * A BasicSourceMapConsumer instance represents a parsed source map which we can + * query for information about the original file positions by giving it a file + * position in the generated source. + * + * The only parameter is the raw source map (either as a JSON string, or + * already parsed to an object). According to the spec, source maps have the + * following attributes: + * + * - version: Which version of the source map spec this map is following. + * - sources: An array of URLs to the original source files. + * - names: An array of identifiers which can be referrenced by individual mappings. + * - sourceRoot: Optional. The URL root from which all sources are relative. + * - sourcesContent: Optional. An array of contents of the original source files. + * - mappings: A string of base64 VLQs which contain the actual mappings. + * - file: Optional. The generated file this source map is associated with. + * + * Here is an example source map, taken from the source map spec[0]: + * + * { + * version : 3, + * file: "out.js", + * sourceRoot : "", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AA,AB;;ABCDE;" + * } + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# + */ + function BasicSourceMapConsumer(aSourceMap) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); + } + + var version = util.getArg(sourceMap, 'version'); + var sources = util.getArg(sourceMap, 'sources'); + // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which + // requires the array) to play nice here. + var names = util.getArg(sourceMap, 'names', []); + var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null); + var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null); + var mappings = util.getArg(sourceMap, 'mappings'); + var file = util.getArg(sourceMap, 'file', null); + + // Once again, Sass deviates from the spec and supplies the version as a + // string rather than a number, so we use loose equality checking here. + if (version != this._version) { + throw new Error('Unsupported version: ' + version); + } + + sources = sources + .map(String) + // Some source maps produce relative source paths like "./foo.js" instead of + // "foo.js". Normalize these first so that future comparisons will succeed. + // See bugzil.la/1090768. + .map(util.normalize) + // Always ensure that absolute sources are internally stored relative to + // the source root, if the source root is absolute. Not doing this would + // be particularly problematic when the source root is a prefix of the + // source (valid, but why??). See github issue #199 and bugzil.la/1188982. + .map(function (source) { + return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source) + ? util.relative(sourceRoot, source) + : source; + }); + + // Pass `true` below to allow duplicate names and sources. While source maps + // are intended to be compressed and deduplicated, the TypeScript compiler + // sometimes generates source maps with duplicates in them. See Github issue + // #72 and bugzil.la/889492. + this._names = ArraySet.fromArray(names.map(String), true); + this._sources = ArraySet.fromArray(sources, true); + + this.sourceRoot = sourceRoot; + this.sourcesContent = sourcesContent; + this._mappings = mappings; + this.file = file; + } + + BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); + BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer; + + /** + * Create a BasicSourceMapConsumer from a SourceMapGenerator. + * + * @param SourceMapGenerator aSourceMap + * The source map that will be consumed. + * @returns BasicSourceMapConsumer + */ + BasicSourceMapConsumer.fromSourceMap = + function SourceMapConsumer_fromSourceMap(aSourceMap) { + var smc = Object.create(BasicSourceMapConsumer.prototype); + + var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true); + var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true); + smc.sourceRoot = aSourceMap._sourceRoot; + smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), + smc.sourceRoot); + smc.file = aSourceMap._file; + + // Because we are modifying the entries (by converting string sources and + // names to indices into the sources and names ArraySets), we have to make + // a copy of the entry or else bad things happen. Shared mutable state + // strikes again! See github issue #191. + + var generatedMappings = aSourceMap._mappings.toArray().slice(); + var destGeneratedMappings = smc.__generatedMappings = []; + var destOriginalMappings = smc.__originalMappings = []; + + for (var i = 0, length = generatedMappings.length; i < length; i++) { + var srcMapping = generatedMappings[i]; + var destMapping = new Mapping; + destMapping.generatedLine = srcMapping.generatedLine; + destMapping.generatedColumn = srcMapping.generatedColumn; + + if (srcMapping.source) { + destMapping.source = sources.indexOf(srcMapping.source); + destMapping.originalLine = srcMapping.originalLine; + destMapping.originalColumn = srcMapping.originalColumn; + + if (srcMapping.name) { + destMapping.name = names.indexOf(srcMapping.name); + } + + destOriginalMappings.push(destMapping); + } + + destGeneratedMappings.push(destMapping); + } + + quickSort(smc.__originalMappings, util.compareByOriginalPositions); + + return smc; + }; + + /** + * The version of the source mapping spec that we are consuming. + */ + BasicSourceMapConsumer.prototype._version = 3; + + /** + * The list of original sources. + */ + Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', { + get: function () { + return this._sources.toArray().map(function (s) { + return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s; + }, this); + } + }); + + /** + * Provide the JIT with a nice shape / hidden class. + */ + function Mapping() { + this.generatedLine = 0; + this.generatedColumn = 0; + this.source = null; + this.originalLine = null; + this.originalColumn = null; + this.name = null; + } + + /** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ + BasicSourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + var generatedLine = 1; + var previousGeneratedColumn = 0; + var previousOriginalLine = 0; + var previousOriginalColumn = 0; + var previousSource = 0; + var previousName = 0; + var length = aStr.length; + var index = 0; + var cachedSegments = {}; + var temp = {}; + var originalMappings = []; + var generatedMappings = []; + var mapping, str, segment, end, value; + + while (index < length) { + if (aStr.charAt(index) === ';') { + generatedLine++; + index++; + previousGeneratedColumn = 0; + } + else if (aStr.charAt(index) === ',') { + index++; + } + else { + mapping = new Mapping(); + mapping.generatedLine = generatedLine; + + // Because each offset is encoded relative to the previous one, + // many segments often have the same encoding. We can exploit this + // fact by caching the parsed variable length fields of each segment, + // allowing us to avoid a second parse if we encounter the same + // segment again. + for (end = index; end < length; end++) { + if (this._charIsMappingSeparator(aStr, end)) { + break; + } + } + str = aStr.slice(index, end); + + segment = cachedSegments[str]; + if (segment) { + index += str.length; + } else { + segment = []; + while (index < end) { + base64VLQ.decode(aStr, index, temp); + value = temp.value; + index = temp.rest; + segment.push(value); + } + + if (segment.length === 2) { + throw new Error('Found a source, but no line and column'); + } + + if (segment.length === 3) { + throw new Error('Found a source and line, but no column'); + } + + cachedSegments[str] = segment; + } + + // Generated column. + mapping.generatedColumn = previousGeneratedColumn + segment[0]; + previousGeneratedColumn = mapping.generatedColumn; + + if (segment.length > 1) { + // Original source. + mapping.source = previousSource + segment[1]; + previousSource += segment[1]; + + // Original line. + mapping.originalLine = previousOriginalLine + segment[2]; + previousOriginalLine = mapping.originalLine; + // Lines are stored 0-based + mapping.originalLine += 1; + + // Original column. + mapping.originalColumn = previousOriginalColumn + segment[3]; + previousOriginalColumn = mapping.originalColumn; + + if (segment.length > 4) { + // Original name. + mapping.name = previousName + segment[4]; + previousName += segment[4]; + } + } + + generatedMappings.push(mapping); + if (typeof mapping.originalLine === 'number') { + originalMappings.push(mapping); + } + } + } + + quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated); + this.__generatedMappings = generatedMappings; + + quickSort(originalMappings, util.compareByOriginalPositions); + this.__originalMappings = originalMappings; + }; + + /** + * Find the mapping that best matches the hypothetical "needle" mapping that + * we are searching for in the given "haystack" of mappings. + */ + BasicSourceMapConsumer.prototype._findMapping = + function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, + aColumnName, aComparator, aBias) { + // To return the position we are searching for, we must first find the + // mapping for the given position and then return the opposite position it + // points to. Because the mappings are sorted, we can use binary search to + // find the best mapping. + + if (aNeedle[aLineName] <= 0) { + throw new TypeError('Line must be greater than or equal to 1, got ' + + aNeedle[aLineName]); + } + if (aNeedle[aColumnName] < 0) { + throw new TypeError('Column must be greater than or equal to 0, got ' + + aNeedle[aColumnName]); + } + + return binarySearch.search(aNeedle, aMappings, aComparator, aBias); + }; + + /** + * Compute the last column for each generated mapping. The last column is + * inclusive. + */ + BasicSourceMapConsumer.prototype.computeColumnSpans = + function SourceMapConsumer_computeColumnSpans() { + for (var index = 0; index < this._generatedMappings.length; ++index) { + var mapping = this._generatedMappings[index]; + + // Mappings do not contain a field for the last generated columnt. We + // can come up with an optimistic estimate, however, by assuming that + // mappings are contiguous (i.e. given two consecutive mappings, the + // first mapping ends where the second one starts). + if (index + 1 < this._generatedMappings.length) { + var nextMapping = this._generatedMappings[index + 1]; + + if (mapping.generatedLine === nextMapping.generatedLine) { + mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1; + continue; + } + } + + // The last mapping for each line spans the entire line. + mapping.lastGeneratedColumn = Infinity; + } + }; + + /** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. + * - column: The column number in the generated source. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. + * - column: The column number in the original source, or null. + * - name: The original identifier, or null. + */ + BasicSourceMapConsumer.prototype.originalPositionFor = + function SourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util.getArg(aArgs, 'line'), + generatedColumn: util.getArg(aArgs, 'column') + }; + + var index = this._findMapping( + needle, + this._generatedMappings, + "generatedLine", + "generatedColumn", + util.compareByGeneratedPositionsDeflated, + util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); + + if (index >= 0) { + var mapping = this._generatedMappings[index]; + + if (mapping.generatedLine === needle.generatedLine) { + var source = util.getArg(mapping, 'source', null); + if (source !== null) { + source = this._sources.at(source); + if (this.sourceRoot != null) { + source = util.join(this.sourceRoot, source); + } + } + var name = util.getArg(mapping, 'name', null); + if (name !== null) { + name = this._names.at(name); + } + return { + source: source, + line: util.getArg(mapping, 'originalLine', null), + column: util.getArg(mapping, 'originalColumn', null), + name: name + }; + } + } + + return { + source: null, + line: null, + column: null, + name: null + }; + }; + + /** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ + BasicSourceMapConsumer.prototype.hasContentsOfAllSources = + function BasicSourceMapConsumer_hasContentsOfAllSources() { + if (!this.sourcesContent) { + return false; + } + return this.sourcesContent.length >= this._sources.size() && + !this.sourcesContent.some(function (sc) { return sc == null; }); + }; + + /** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ + BasicSourceMapConsumer.prototype.sourceContentFor = + function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + if (!this.sourcesContent) { + return null; + } + + if (this.sourceRoot != null) { + aSource = util.relative(this.sourceRoot, aSource); + } + + if (this._sources.has(aSource)) { + return this.sourcesContent[this._sources.indexOf(aSource)]; + } + + var url; + if (this.sourceRoot != null + && (url = util.urlParse(this.sourceRoot))) { + // XXX: file:// URIs and absolute paths lead to unexpected behavior for + // many users. We can help them out when they expect file:// URIs to + // behave like it would if they were running a local HTTP server. See + // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. + var fileUriAbsPath = aSource.replace(/^file:\/\//, ""); + if (url.scheme == "file" + && this._sources.has(fileUriAbsPath)) { + return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] + } + + if ((!url.path || url.path == "/") + && this._sources.has("/" + aSource)) { + return this.sourcesContent[this._sources.indexOf("/" + aSource)]; + } + } + + // This function is used recursively from + // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we + // don't want to throw if we can't find the source - we just want to + // return null, so we provide a flag to exit gracefully. + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + aSource + '" is not in the SourceMap.'); + } + }; + + /** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. + * - column: The column number in the original source. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. + * - column: The column number in the generated source, or null. + */ + BasicSourceMapConsumer.prototype.generatedPositionFor = + function SourceMapConsumer_generatedPositionFor(aArgs) { + var source = util.getArg(aArgs, 'source'); + if (this.sourceRoot != null) { + source = util.relative(this.sourceRoot, source); + } + if (!this._sources.has(source)) { + return { + line: null, + column: null, + lastColumn: null + }; + } + source = this._sources.indexOf(source); + + var needle = { + source: source, + originalLine: util.getArg(aArgs, 'line'), + originalColumn: util.getArg(aArgs, 'column') + }; + + var index = this._findMapping( + needle, + this._originalMappings, + "originalLine", + "originalColumn", + util.compareByOriginalPositions, + util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); + + if (index >= 0) { + var mapping = this._originalMappings[index]; + + if (mapping.source === needle.source) { + return { + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }; + } + } + + return { + line: null, + column: null, + lastColumn: null + }; + }; + + exports.BasicSourceMapConsumer = BasicSourceMapConsumer; + + /** + * An IndexedSourceMapConsumer instance represents a parsed source map which + * we can query for information. It differs from BasicSourceMapConsumer in + * that it takes "indexed" source maps (i.e. ones with a "sections" field) as + * input. + * + * The only parameter is a raw source map (either as a JSON string, or already + * parsed to an object). According to the spec for indexed source maps, they + * have the following attributes: + * + * - version: Which version of the source map spec this map is following. + * - file: Optional. The generated file this source map is associated with. + * - sections: A list of section definitions. + * + * Each value under the "sections" field has two fields: + * - offset: The offset into the original specified at which this section + * begins to apply, defined as an object with a "line" and "column" + * field. + * - map: A source map definition. This source map could also be indexed, + * but doesn't have to be. + * + * Instead of the "map" field, it's also possible to have a "url" field + * specifying a URL to retrieve a source map from, but that's currently + * unsupported. + * + * Here's an example source map, taken from the source map spec[0], but + * modified to omit a section which uses the "url" field. + * + * { + * version : 3, + * file: "app.js", + * sections: [{ + * offset: {line:100, column:10}, + * map: { + * version : 3, + * file: "section.js", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AAAA,E;;ABCDE;" + * } + * }], + * } + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt + */ + function IndexedSourceMapConsumer(aSourceMap) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); + } + + var version = util.getArg(sourceMap, 'version'); + var sections = util.getArg(sourceMap, 'sections'); + + if (version != this._version) { + throw new Error('Unsupported version: ' + version); + } + + this._sources = new ArraySet(); + this._names = new ArraySet(); + + var lastOffset = { + line: -1, + column: 0 + }; + this._sections = sections.map(function (s) { + if (s.url) { + // The url field will require support for asynchronicity. + // See https://github.com/mozilla/source-map/issues/16 + throw new Error('Support for url field in sections not implemented.'); + } + var offset = util.getArg(s, 'offset'); + var offsetLine = util.getArg(offset, 'line'); + var offsetColumn = util.getArg(offset, 'column'); + + if (offsetLine < lastOffset.line || + (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) { + throw new Error('Section offsets must be ordered and non-overlapping.'); + } + lastOffset = offset; + + return { + generatedOffset: { + // The offset fields are 0-based, but we use 1-based indices when + // encoding/decoding from VLQ. + generatedLine: offsetLine + 1, + generatedColumn: offsetColumn + 1 + }, + consumer: new SourceMapConsumer(util.getArg(s, 'map')) + } + }); + } + + IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); + IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer; + + /** + * The version of the source mapping spec that we are consuming. + */ + IndexedSourceMapConsumer.prototype._version = 3; + + /** + * The list of original sources. + */ + Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', { + get: function () { + var sources = []; + for (var i = 0; i < this._sections.length; i++) { + for (var j = 0; j < this._sections[i].consumer.sources.length; j++) { + sources.push(this._sections[i].consumer.sources[j]); + } + } + return sources; + } + }); + + /** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. + * - column: The column number in the generated source. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. + * - column: The column number in the original source, or null. + * - name: The original identifier, or null. + */ + IndexedSourceMapConsumer.prototype.originalPositionFor = + function IndexedSourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util.getArg(aArgs, 'line'), + generatedColumn: util.getArg(aArgs, 'column') + }; + + // Find the section containing the generated position we're trying to map + // to an original position. + var sectionIndex = binarySearch.search(needle, this._sections, + function(needle, section) { + var cmp = needle.generatedLine - section.generatedOffset.generatedLine; + if (cmp) { + return cmp; + } + + return (needle.generatedColumn - + section.generatedOffset.generatedColumn); + }); + var section = this._sections[sectionIndex]; + + if (!section) { + return { + source: null, + line: null, + column: null, + name: null + }; + } + + return section.consumer.originalPositionFor({ + line: needle.generatedLine - + (section.generatedOffset.generatedLine - 1), + column: needle.generatedColumn - + (section.generatedOffset.generatedLine === needle.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + bias: aArgs.bias + }); + }; + + /** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ + IndexedSourceMapConsumer.prototype.hasContentsOfAllSources = + function IndexedSourceMapConsumer_hasContentsOfAllSources() { + return this._sections.every(function (s) { + return s.consumer.hasContentsOfAllSources(); + }); + }; + + /** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ + IndexedSourceMapConsumer.prototype.sourceContentFor = + function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + + var content = section.consumer.sourceContentFor(aSource, true); + if (content) { + return content; + } + } + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + aSource + '" is not in the SourceMap.'); + } + }; + + /** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. + * - column: The column number in the original source. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. + * - column: The column number in the generated source, or null. + */ + IndexedSourceMapConsumer.prototype.generatedPositionFor = + function IndexedSourceMapConsumer_generatedPositionFor(aArgs) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + + // Only consider this section if the requested source is in the list of + // sources of the consumer. + if (section.consumer.sources.indexOf(util.getArg(aArgs, 'source')) === -1) { + continue; + } + var generatedPosition = section.consumer.generatedPositionFor(aArgs); + if (generatedPosition) { + var ret = { + line: generatedPosition.line + + (section.generatedOffset.generatedLine - 1), + column: generatedPosition.column + + (section.generatedOffset.generatedLine === generatedPosition.line + ? section.generatedOffset.generatedColumn - 1 + : 0) + }; + return ret; + } + } + + return { + line: null, + column: null + }; + }; + + /** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ + IndexedSourceMapConsumer.prototype._parseMappings = + function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) { + this.__generatedMappings = []; + this.__originalMappings = []; + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + var sectionMappings = section.consumer._generatedMappings; + for (var j = 0; j < sectionMappings.length; j++) { + var mapping = sectionMappings[j]; + + var source = section.consumer._sources.at(mapping.source); + if (section.consumer.sourceRoot !== null) { + source = util.join(section.consumer.sourceRoot, source); + } + this._sources.add(source); + source = this._sources.indexOf(source); + + var name = section.consumer._names.at(mapping.name); + this._names.add(name); + name = this._names.indexOf(name); + + // The mappings coming from the consumer for the section have + // generated positions relative to the start of the section, so we + // need to offset them to be relative to the start of the concatenated + // generated file. + var adjustedMapping = { + source: source, + generatedLine: mapping.generatedLine + + (section.generatedOffset.generatedLine - 1), + generatedColumn: mapping.generatedColumn + + (section.generatedOffset.generatedLine === mapping.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: name + }; + + this.__generatedMappings.push(adjustedMapping); + if (typeof adjustedMapping.originalLine === 'number') { + this.__originalMappings.push(adjustedMapping); + } + } + } + + quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated); + quickSort(this.__originalMappings, util.compareByOriginalPositions); + }; + + exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; + + +/***/ }, +/* 8 */ +/***/ function(module, exports) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + exports.GREATEST_LOWER_BOUND = 1; + exports.LEAST_UPPER_BOUND = 2; + + /** + * Recursive implementation of binary search. + * + * @param aLow Indices here and lower do not contain the needle. + * @param aHigh Indices here and higher do not contain the needle. + * @param aNeedle The element being searched for. + * @param aHaystack The non-empty array being searched. + * @param aCompare Function which takes two elements and returns -1, 0, or 1. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + */ + function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { + // This function terminates when one of the following is true: + // + // 1. We find the exact element we are looking for. + // + // 2. We did not find the exact element, but we can return the index of + // the next-closest element. + // + // 3. We did not find the exact element, and there is no next-closest + // element than the one we are searching for, so we return -1. + var mid = Math.floor((aHigh - aLow) / 2) + aLow; + var cmp = aCompare(aNeedle, aHaystack[mid], true); + if (cmp === 0) { + // Found the element we are looking for. + return mid; + } + else if (cmp > 0) { + // Our needle is greater than aHaystack[mid]. + if (aHigh - mid > 1) { + // The element is in the upper half. + return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias); + } + + // The exact needle element was not found in this haystack. Determine if + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return aHigh < aHaystack.length ? aHigh : -1; + } else { + return mid; + } + } + else { + // Our needle is less than aHaystack[mid]. + if (mid - aLow > 1) { + // The element is in the lower half. + return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias); + } + + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return mid; + } else { + return aLow < 0 ? -1 : aLow; + } + } + } + + /** + * This is an implementation of binary search which will always try and return + * the index of the closest element if there is no exact hit. This is because + * mappings between original and generated line/col pairs are single points, + * and there is an implicit region between each of them, so a miss just means + * that you aren't on the very start of a region. + * + * @param aNeedle The element you are looking for. + * @param aHaystack The array that is being searched. + * @param aCompare A function which takes the needle and an element in the + * array and returns -1, 0, or 1 depending on whether the needle is less + * than, equal to, or greater than the element, respectively. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'. + */ + exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { + if (aHaystack.length === 0) { + return -1; + } + + var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, + aCompare, aBias || exports.GREATEST_LOWER_BOUND); + if (index < 0) { + return -1; + } + + // We have found either the exact element, or the next-closest element than + // the one we are searching for. However, there may be more than one such + // element. Make sure we always return the smallest of these. + while (index - 1 >= 0) { + if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) { + break; + } + --index; + } + + return index; + }; + + +/***/ }, +/* 9 */ +/***/ function(module, exports) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + // It turns out that some (most?) JavaScript engines don't self-host + // `Array.prototype.sort`. This makes sense because C++ will likely remain + // faster than JS when doing raw CPU-intensive sorting. However, when using a + // custom comparator function, calling back and forth between the VM's C++ and + // JIT'd JS is rather slow *and* loses JIT type information, resulting in + // worse generated code for the comparator function than would be optimal. In + // fact, when sorting with a comparator, these costs outweigh the benefits of + // sorting in C++. By using our own JS-implemented Quick Sort (below), we get + // a ~3500ms mean speed-up in `bench/bench.html`. + + /** + * Swap the elements indexed by `x` and `y` in the array `ary`. + * + * @param {Array} ary + * The array. + * @param {Number} x + * The index of the first item. + * @param {Number} y + * The index of the second item. + */ + function swap(ary, x, y) { + var temp = ary[x]; + ary[x] = ary[y]; + ary[y] = temp; + } + + /** + * Returns a random integer within the range `low .. high` inclusive. + * + * @param {Number} low + * The lower bound on the range. + * @param {Number} high + * The upper bound on the range. + */ + function randomIntInRange(low, high) { + return Math.round(low + (Math.random() * (high - low))); + } + + /** + * The Quick Sort algorithm. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + * @param {Number} p + * Start index of the array + * @param {Number} r + * End index of the array + */ + function doQuickSort(ary, comparator, p, r) { + // If our lower bound is less than our upper bound, we (1) partition the + // array into two pieces and (2) recurse on each half. If it is not, this is + // the empty array and our base case. + + if (p < r) { + // (1) Partitioning. + // + // The partitioning chooses a pivot between `p` and `r` and moves all + // elements that are less than or equal to the pivot to the before it, and + // all the elements that are greater than it after it. The effect is that + // once partition is done, the pivot is in the exact place it will be when + // the array is put in sorted order, and it will not need to be moved + // again. This runs in O(n) time. + + // Always choose a random pivot so that an input array which is reverse + // sorted does not cause O(n^2) running time. + var pivotIndex = randomIntInRange(p, r); + var i = p - 1; + + swap(ary, pivotIndex, r); + var pivot = ary[r]; + + // Immediately after `j` is incremented in this loop, the following hold + // true: + // + // * Every element in `ary[p .. i]` is less than or equal to the pivot. + // + // * Every element in `ary[i+1 .. j-1]` is greater than the pivot. + for (var j = p; j < r; j++) { + if (comparator(ary[j], pivot) <= 0) { + i += 1; + swap(ary, i, j); + } + } + + swap(ary, i + 1, j); + var q = i + 1; + + // (2) Recurse on each half. + + doQuickSort(ary, comparator, p, q - 1); + doQuickSort(ary, comparator, q + 1, r); + } + } + + /** + * Sort the given array in-place with the given comparator function. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + */ + exports.quickSort = function (ary, comparator) { + doQuickSort(ary, comparator, 0, ary.length - 1); + }; + + +/***/ }, +/* 10 */ +/***/ function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var SourceMapGenerator = __webpack_require__(1).SourceMapGenerator; + var util = __webpack_require__(4); + + // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other + // operating systems these days (capturing the result). + var REGEX_NEWLINE = /(\r?\n)/; + + // Newline character code for charCodeAt() comparisons + var NEWLINE_CODE = 10; + + // Private symbol for identifying `SourceNode`s when multiple versions of + // the source-map library are loaded. This MUST NOT CHANGE across + // versions! + var isSourceNode = "$$$isSourceNode$$$"; + + /** + * SourceNodes provide a way to abstract over interpolating/concatenating + * snippets of generated JavaScript source code while maintaining the line and + * column information associated with the original source code. + * + * @param aLine The original line number. + * @param aColumn The original column number. + * @param aSource The original source's filename. + * @param aChunks Optional. An array of strings which are snippets of + * generated JS, or other SourceNodes. + * @param aName The original identifier. + */ + function SourceNode(aLine, aColumn, aSource, aChunks, aName) { + this.children = []; + this.sourceContents = {}; + this.line = aLine == null ? null : aLine; + this.column = aColumn == null ? null : aColumn; + this.source = aSource == null ? null : aSource; + this.name = aName == null ? null : aName; + this[isSourceNode] = true; + if (aChunks != null) this.add(aChunks); + } + + /** + * Creates a SourceNode from generated code and a SourceMapConsumer. + * + * @param aGeneratedCode The generated code + * @param aSourceMapConsumer The SourceMap for the generated code + * @param aRelativePath Optional. The path that relative sources in the + * SourceMapConsumer should be relative to. + */ + SourceNode.fromStringWithSourceMap = + function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) { + // The SourceNode we want to fill with the generated code + // and the SourceMap + var node = new SourceNode(); + + // All even indices of this array are one line of the generated code, + // while all odd indices are the newlines between two adjacent lines + // (since `REGEX_NEWLINE` captures its match). + // Processed fragments are removed from this array, by calling `shiftNextLine`. + var remainingLines = aGeneratedCode.split(REGEX_NEWLINE); + var shiftNextLine = function() { + var lineContents = remainingLines.shift(); + // The last line of a file might not have a newline. + var newLine = remainingLines.shift() || ""; + return lineContents + newLine; + }; + + // We need to remember the position of "remainingLines" + var lastGeneratedLine = 1, lastGeneratedColumn = 0; + + // The generate SourceNodes we need a code range. + // To extract it current and last mapping is used. + // Here we store the last mapping. + var lastMapping = null; + + aSourceMapConsumer.eachMapping(function (mapping) { + if (lastMapping !== null) { + // We add the code from "lastMapping" to "mapping": + // First check if there is a new line in between. + if (lastGeneratedLine < mapping.generatedLine) { + // Associate first line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + lastGeneratedLine++; + lastGeneratedColumn = 0; + // The remaining code is added without mapping + } else { + // There is no new line in between. + // Associate the code between "lastGeneratedColumn" and + // "mapping.generatedColumn" with "lastMapping" + var nextLine = remainingLines[0]; + var code = nextLine.substr(0, mapping.generatedColumn - + lastGeneratedColumn); + remainingLines[0] = nextLine.substr(mapping.generatedColumn - + lastGeneratedColumn); + lastGeneratedColumn = mapping.generatedColumn; + addMappingWithCode(lastMapping, code); + // No more remaining code, continue + lastMapping = mapping; + return; + } + } + // We add the generated code until the first mapping + // to the SourceNode without any mapping. + // Each line is added as separate string. + while (lastGeneratedLine < mapping.generatedLine) { + node.add(shiftNextLine()); + lastGeneratedLine++; + } + if (lastGeneratedColumn < mapping.generatedColumn) { + var nextLine = remainingLines[0]; + node.add(nextLine.substr(0, mapping.generatedColumn)); + remainingLines[0] = nextLine.substr(mapping.generatedColumn); + lastGeneratedColumn = mapping.generatedColumn; + } + lastMapping = mapping; + }, this); + // We have processed all mappings. + if (remainingLines.length > 0) { + if (lastMapping) { + // Associate the remaining code in the current line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + } + // and add the remaining lines without any mapping + node.add(remainingLines.join("")); + } + + // Copy sourcesContent into SourceNode + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aRelativePath != null) { + sourceFile = util.join(aRelativePath, sourceFile); + } + node.setSourceContent(sourceFile, content); + } + }); + + return node; + + function addMappingWithCode(mapping, code) { + if (mapping === null || mapping.source === undefined) { + node.add(code); + } else { + var source = aRelativePath + ? util.join(aRelativePath, mapping.source) + : mapping.source; + node.add(new SourceNode(mapping.originalLine, + mapping.originalColumn, + source, + code, + mapping.name)); + } + } + }; + + /** + * Add a chunk of generated JS to this source node. + * + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. + */ + SourceNode.prototype.add = function SourceNode_add(aChunk) { + if (Array.isArray(aChunk)) { + aChunk.forEach(function (chunk) { + this.add(chunk); + }, this); + } + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + if (aChunk) { + this.children.push(aChunk); + } + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; + }; + + /** + * Add a chunk of generated JS to the beginning of this source node. + * + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. + */ + SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) { + if (Array.isArray(aChunk)) { + for (var i = aChunk.length-1; i >= 0; i--) { + this.prepend(aChunk[i]); + } + } + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + this.children.unshift(aChunk); + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; + }; + + /** + * Walk over the tree of JS snippets in this node and its children. The + * walking function is called once for each snippet of JS and is passed that + * snippet and the its original associated source's line/column location. + * + * @param aFn The traversal function. + */ + SourceNode.prototype.walk = function SourceNode_walk(aFn) { + var chunk; + for (var i = 0, len = this.children.length; i < len; i++) { + chunk = this.children[i]; + if (chunk[isSourceNode]) { + chunk.walk(aFn); + } + else { + if (chunk !== '') { + aFn(chunk, { source: this.source, + line: this.line, + column: this.column, + name: this.name }); + } + } + } + }; + + /** + * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between + * each of `this.children`. + * + * @param aSep The separator. + */ + SourceNode.prototype.join = function SourceNode_join(aSep) { + var newChildren; + var i; + var len = this.children.length; + if (len > 0) { + newChildren = []; + for (i = 0; i < len-1; i++) { + newChildren.push(this.children[i]); + newChildren.push(aSep); + } + newChildren.push(this.children[i]); + this.children = newChildren; + } + return this; + }; + + /** + * Call String.prototype.replace on the very right-most source snippet. Useful + * for trimming whitespace from the end of a source node, etc. + * + * @param aPattern The pattern to replace. + * @param aReplacement The thing to replace the pattern with. + */ + SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) { + var lastChild = this.children[this.children.length - 1]; + if (lastChild[isSourceNode]) { + lastChild.replaceRight(aPattern, aReplacement); + } + else if (typeof lastChild === 'string') { + this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); + } + else { + this.children.push(''.replace(aPattern, aReplacement)); + } + return this; + }; + + /** + * Set the source content for a source file. This will be added to the SourceMapGenerator + * in the sourcesContent field. + * + * @param aSourceFile The filename of the source file + * @param aSourceContent The content of the source file + */ + SourceNode.prototype.setSourceContent = + function SourceNode_setSourceContent(aSourceFile, aSourceContent) { + this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; + }; + + /** + * Walk over the tree of SourceNodes. The walking function is called for each + * source file content and is passed the filename and source content. + * + * @param aFn The traversal function. + */ + SourceNode.prototype.walkSourceContents = + function SourceNode_walkSourceContents(aFn) { + for (var i = 0, len = this.children.length; i < len; i++) { + if (this.children[i][isSourceNode]) { + this.children[i].walkSourceContents(aFn); + } + } + + var sources = Object.keys(this.sourceContents); + for (var i = 0, len = sources.length; i < len; i++) { + aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); + } + }; + + /** + * Return the string representation of this source node. Walks over the tree + * and concatenates all the various snippets together to one string. + */ + SourceNode.prototype.toString = function SourceNode_toString() { + var str = ""; + this.walk(function (chunk) { + str += chunk; + }); + return str; + }; + + /** + * Returns the string representation of this source node along with a source + * map. + */ + SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) { + var generated = { + code: "", + line: 1, + column: 0 + }; + var map = new SourceMapGenerator(aArgs); + var sourceMappingActive = false; + var lastOriginalSource = null; + var lastOriginalLine = null; + var lastOriginalColumn = null; + var lastOriginalName = null; + this.walk(function (chunk, original) { + generated.code += chunk; + if (original.source !== null + && original.line !== null + && original.column !== null) { + if(lastOriginalSource !== original.source + || lastOriginalLine !== original.line + || lastOriginalColumn !== original.column + || lastOriginalName !== original.name) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + lastOriginalSource = original.source; + lastOriginalLine = original.line; + lastOriginalColumn = original.column; + lastOriginalName = original.name; + sourceMappingActive = true; + } else if (sourceMappingActive) { + map.addMapping({ + generated: { + line: generated.line, + column: generated.column + } + }); + lastOriginalSource = null; + sourceMappingActive = false; + } + for (var idx = 0, length = chunk.length; idx < length; idx++) { + if (chunk.charCodeAt(idx) === NEWLINE_CODE) { + generated.line++; + generated.column = 0; + // Mappings end at eol + if (idx + 1 === length) { + lastOriginalSource = null; + sourceMappingActive = false; + } else if (sourceMappingActive) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + } else { + generated.column++; + } + } + }); + this.walkSourceContents(function (sourceFile, sourceContent) { + map.setSourceContent(sourceFile, sourceContent); + }); + + return { code: generated.code, map: map }; + }; + + exports.SourceNode = SourceNode; + + +/***/ } +/******/ ]) +}); +; \ No newline at end of file diff --git a/node_modules/source-map/dist/source-map.min.js b/node_modules/source-map/dist/source-map.min.js new file mode 100644 index 0000000..e03b6d5 --- /dev/null +++ b/node_modules/source-map/dist/source-map.min.js @@ -0,0 +1,2 @@ +!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.sourceMap=n():e.sourceMap=n()}(this,function(){return function(e){function n(t){if(r[t])return r[t].exports;var o=r[t]={exports:{},id:t,loaded:!1};return e[t].call(o.exports,o,o.exports,n),o.loaded=!0,o.exports}var r={};return n.m=e,n.c=r,n.p="",n(0)}([function(e,n,r){n.SourceMapGenerator=r(1).SourceMapGenerator,n.SourceMapConsumer=r(7).SourceMapConsumer,n.SourceNode=r(10).SourceNode},function(e,n,r){function t(e){e||(e={}),this._file=i.getArg(e,"file",null),this._sourceRoot=i.getArg(e,"sourceRoot",null),this._skipValidation=i.getArg(e,"skipValidation",!1),this._sources=new s,this._names=new s,this._mappings=new a,this._sourcesContents=null}var o=r(2),i=r(4),s=r(5).ArraySet,a=r(6).MappingList;t.prototype._version=3,t.fromSourceMap=function(e){var n=e.sourceRoot,r=new t({file:e.file,sourceRoot:n});return e.eachMapping(function(e){var t={generated:{line:e.generatedLine,column:e.generatedColumn}};null!=e.source&&(t.source=e.source,null!=n&&(t.source=i.relative(n,t.source)),t.original={line:e.originalLine,column:e.originalColumn},null!=e.name&&(t.name=e.name)),r.addMapping(t)}),e.sources.forEach(function(n){var t=e.sourceContentFor(n);null!=t&&r.setSourceContent(n,t)}),r},t.prototype.addMapping=function(e){var n=i.getArg(e,"generated"),r=i.getArg(e,"original",null),t=i.getArg(e,"source",null),o=i.getArg(e,"name",null);this._skipValidation||this._validateMapping(n,r,t,o),null!=t&&(t=String(t),this._sources.has(t)||this._sources.add(t)),null!=o&&(o=String(o),this._names.has(o)||this._names.add(o)),this._mappings.add({generatedLine:n.line,generatedColumn:n.column,originalLine:null!=r&&r.line,originalColumn:null!=r&&r.column,source:t,name:o})},t.prototype.setSourceContent=function(e,n){var r=e;null!=this._sourceRoot&&(r=i.relative(this._sourceRoot,r)),null!=n?(this._sourcesContents||(this._sourcesContents=Object.create(null)),this._sourcesContents[i.toSetString(r)]=n):this._sourcesContents&&(delete this._sourcesContents[i.toSetString(r)],0===Object.keys(this._sourcesContents).length&&(this._sourcesContents=null))},t.prototype.applySourceMap=function(e,n,r){var t=n;if(null==n){if(null==e.file)throw new Error('SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map\'s "file" property. Both were omitted.');t=e.file}var o=this._sourceRoot;null!=o&&(t=i.relative(o,t));var a=new s,u=new s;this._mappings.unsortedForEach(function(n){if(n.source===t&&null!=n.originalLine){var s=e.originalPositionFor({line:n.originalLine,column:n.originalColumn});null!=s.source&&(n.source=s.source,null!=r&&(n.source=i.join(r,n.source)),null!=o&&(n.source=i.relative(o,n.source)),n.originalLine=s.line,n.originalColumn=s.column,null!=s.name&&(n.name=s.name))}var l=n.source;null==l||a.has(l)||a.add(l);var c=n.name;null==c||u.has(c)||u.add(c)},this),this._sources=a,this._names=u,e.sources.forEach(function(n){var t=e.sourceContentFor(n);null!=t&&(null!=r&&(n=i.join(r,n)),null!=o&&(n=i.relative(o,n)),this.setSourceContent(n,t))},this)},t.prototype._validateMapping=function(e,n,r,t){if((!(e&&"line"in e&&"column"in e&&e.line>0&&e.column>=0)||n||r||t)&&!(e&&"line"in e&&"column"in e&&n&&"line"in n&&"column"in n&&e.line>0&&e.column>=0&&n.line>0&&n.column>=0&&r))throw new Error("Invalid mapping: "+JSON.stringify({generated:e,source:r,original:n,name:t}))},t.prototype._serializeMappings=function(){for(var e,n,r,t,s=0,a=1,u=0,l=0,c=0,g=0,p="",h=this._mappings.toArray(),f=0,d=h.length;d>f;f++){if(n=h[f],e="",n.generatedLine!==a)for(s=0;n.generatedLine!==a;)e+=";",a++;else if(f>0){if(!i.compareByGeneratedPositionsInflated(n,h[f-1]))continue;e+=","}e+=o.encode(n.generatedColumn-s),s=n.generatedColumn,null!=n.source&&(t=this._sources.indexOf(n.source),e+=o.encode(t-g),g=t,e+=o.encode(n.originalLine-1-l),l=n.originalLine-1,e+=o.encode(n.originalColumn-u),u=n.originalColumn,null!=n.name&&(r=this._names.indexOf(n.name),e+=o.encode(r-c),c=r)),p+=e}return p},t.prototype._generateSourcesContent=function(e,n){return e.map(function(e){if(!this._sourcesContents)return null;null!=n&&(e=i.relative(n,e));var r=i.toSetString(e);return Object.prototype.hasOwnProperty.call(this._sourcesContents,r)?this._sourcesContents[r]:null},this)},t.prototype.toJSON=function(){var e={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return null!=this._file&&(e.file=this._file),null!=this._sourceRoot&&(e.sourceRoot=this._sourceRoot),this._sourcesContents&&(e.sourcesContent=this._generateSourcesContent(e.sources,e.sourceRoot)),e},t.prototype.toString=function(){return JSON.stringify(this.toJSON())},n.SourceMapGenerator=t},function(e,n,r){function t(e){return 0>e?(-e<<1)+1:(e<<1)+0}function o(e){var n=1===(1&e),r=e>>1;return n?-r:r}var i=r(3),s=5,a=1<>>=s,o>0&&(n|=l),r+=i.encode(n);while(o>0);return r},n.decode=function(e,n,r){var t,a,c=e.length,g=0,p=0;do{if(n>=c)throw new Error("Expected more digits in base 64 VLQ value.");if(a=i.decode(e.charCodeAt(n++)),-1===a)throw new Error("Invalid base64 digit: "+e.charAt(n-1));t=!!(a&l),a&=u,g+=a<=0&&e=n&&r>=e?e-n:e>=t&&o>=e?e-t+l:e>=i&&s>=e?e-i+c:e==a?62:e==u?63:-1}},function(e,n){function r(e,n,r){if(n in e)return e[n];if(3===arguments.length)return r;throw new Error('"'+n+'" is a required argument.')}function t(e){var n=e.match(m);return n?{scheme:n[1],auth:n[2],host:n[3],port:n[4],path:n[5]}:null}function o(e){var n="";return e.scheme&&(n+=e.scheme+":"),n+="//",e.auth&&(n+=e.auth+"@"),e.host&&(n+=e.host),e.port&&(n+=":"+e.port),e.path&&(n+=e.path),n}function i(e){var r=e,i=t(e);if(i){if(!i.path)return e;r=i.path}for(var s,a=n.isAbsolute(r),u=r.split(/\/+/),l=0,c=u.length-1;c>=0;c--)s=u[c],"."===s?u.splice(c,1):".."===s?l++:l>0&&(""===s?(u.splice(c+1,l),l=0):(u.splice(c,2),l--));return r=u.join("/"),""===r&&(r=a?"/":"."),i?(i.path=r,o(i)):r}function s(e,n){""===e&&(e="."),""===n&&(n=".");var r=t(n),s=t(e);if(s&&(e=s.path||"/"),r&&!r.scheme)return s&&(r.scheme=s.scheme),o(r);if(r||n.match(_))return n;if(s&&!s.host&&!s.path)return s.host=n,o(s);var a="/"===n.charAt(0)?n:i(e.replace(/\/+$/,"")+"/"+n);return s?(s.path=a,o(s)):a}function a(e,n){""===e&&(e="."),e=e.replace(/\/$/,"");for(var r=0;0!==n.indexOf(e+"/");){var t=e.lastIndexOf("/");if(0>t)return n;if(e=e.slice(0,t),e.match(/^([^\/]+:\/)?\/*$/))return n;++r}return Array(r+1).join("../")+n.substr(e.length+1)}function u(e){return e}function l(e){return g(e)?"$"+e:e}function c(e){return g(e)?e.slice(1):e}function g(e){if(!e)return!1;var n=e.length;if(9>n)return!1;if(95!==e.charCodeAt(n-1)||95!==e.charCodeAt(n-2)||111!==e.charCodeAt(n-3)||116!==e.charCodeAt(n-4)||111!==e.charCodeAt(n-5)||114!==e.charCodeAt(n-6)||112!==e.charCodeAt(n-7)||95!==e.charCodeAt(n-8)||95!==e.charCodeAt(n-9))return!1;for(var r=n-10;r>=0;r--)if(36!==e.charCodeAt(r))return!1;return!0}function p(e,n,r){var t=e.source-n.source;return 0!==t?t:(t=e.originalLine-n.originalLine,0!==t?t:(t=e.originalColumn-n.originalColumn,0!==t||r?t:(t=e.generatedColumn-n.generatedColumn,0!==t?t:(t=e.generatedLine-n.generatedLine,0!==t?t:e.name-n.name))))}function h(e,n,r){var t=e.generatedLine-n.generatedLine;return 0!==t?t:(t=e.generatedColumn-n.generatedColumn,0!==t||r?t:(t=e.source-n.source,0!==t?t:(t=e.originalLine-n.originalLine,0!==t?t:(t=e.originalColumn-n.originalColumn,0!==t?t:e.name-n.name))))}function f(e,n){return e===n?0:e>n?1:-1}function d(e,n){var r=e.generatedLine-n.generatedLine;return 0!==r?r:(r=e.generatedColumn-n.generatedColumn,0!==r?r:(r=f(e.source,n.source),0!==r?r:(r=e.originalLine-n.originalLine,0!==r?r:(r=e.originalColumn-n.originalColumn,0!==r?r:f(e.name,n.name)))))}n.getArg=r;var m=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/,_=/^data:.+\,.+$/;n.urlParse=t,n.urlGenerate=o,n.normalize=i,n.join=s,n.isAbsolute=function(e){return"/"===e.charAt(0)||!!e.match(m)},n.relative=a;var v=function(){var e=Object.create(null);return!("__proto__"in e)}();n.toSetString=v?u:l,n.fromSetString=v?u:c,n.compareByOriginalPositions=p,n.compareByGeneratedPositionsDeflated=h,n.compareByGeneratedPositionsInflated=d},function(e,n,r){function t(){this._array=[],this._set=Object.create(null)}var o=r(4),i=Object.prototype.hasOwnProperty;t.fromArray=function(e,n){for(var r=new t,o=0,i=e.length;i>o;o++)r.add(e[o],n);return r},t.prototype.size=function(){return Object.getOwnPropertyNames(this._set).length},t.prototype.add=function(e,n){var r=o.toSetString(e),t=i.call(this._set,r),s=this._array.length;(!t||n)&&this._array.push(e),t||(this._set[r]=s)},t.prototype.has=function(e){var n=o.toSetString(e);return i.call(this._set,n)},t.prototype.indexOf=function(e){var n=o.toSetString(e);if(i.call(this._set,n))return this._set[n];throw new Error('"'+e+'" is not in the set.')},t.prototype.at=function(e){if(e>=0&&er||t==r&&s>=o||i.compareByGeneratedPositionsInflated(e,n)<=0}function o(){this._array=[],this._sorted=!0,this._last={generatedLine:-1,generatedColumn:0}}var i=r(4);o.prototype.unsortedForEach=function(e,n){this._array.forEach(e,n)},o.prototype.add=function(e){t(this._last,e)?(this._last=e,this._array.push(e)):(this._sorted=!1,this._array.push(e))},o.prototype.toArray=function(){return this._sorted||(this._array.sort(i.compareByGeneratedPositionsInflated),this._sorted=!0),this._array},n.MappingList=o},function(e,n,r){function t(e){var n=e;return"string"==typeof e&&(n=JSON.parse(e.replace(/^\)\]\}'/,""))),null!=n.sections?new s(n):new o(n)}function o(e){var n=e;"string"==typeof e&&(n=JSON.parse(e.replace(/^\)\]\}'/,"")));var r=a.getArg(n,"version"),t=a.getArg(n,"sources"),o=a.getArg(n,"names",[]),i=a.getArg(n,"sourceRoot",null),s=a.getArg(n,"sourcesContent",null),u=a.getArg(n,"mappings"),c=a.getArg(n,"file",null);if(r!=this._version)throw new Error("Unsupported version: "+r);t=t.map(String).map(a.normalize).map(function(e){return i&&a.isAbsolute(i)&&a.isAbsolute(e)?a.relative(i,e):e}),this._names=l.fromArray(o.map(String),!0),this._sources=l.fromArray(t,!0),this.sourceRoot=i,this.sourcesContent=s,this._mappings=u,this.file=c}function i(){this.generatedLine=0,this.generatedColumn=0,this.source=null,this.originalLine=null,this.originalColumn=null,this.name=null}function s(e){var n=e;"string"==typeof e&&(n=JSON.parse(e.replace(/^\)\]\}'/,"")));var r=a.getArg(n,"version"),o=a.getArg(n,"sections");if(r!=this._version)throw new Error("Unsupported version: "+r);this._sources=new l,this._names=new l;var i={line:-1,column:0};this._sections=o.map(function(e){if(e.url)throw new Error("Support for url field in sections not implemented.");var n=a.getArg(e,"offset"),r=a.getArg(n,"line"),o=a.getArg(n,"column");if(r=0){var i=this._originalMappings[o];if(void 0===e.column)for(var s=i.originalLine;i&&i.originalLine===s;)t.push({line:a.getArg(i,"generatedLine",null),column:a.getArg(i,"generatedColumn",null),lastColumn:a.getArg(i,"lastGeneratedColumn",null)}),i=this._originalMappings[++o];else for(var l=i.originalColumn;i&&i.originalLine===n&&i.originalColumn==l;)t.push({line:a.getArg(i,"generatedLine",null),column:a.getArg(i,"generatedColumn",null),lastColumn:a.getArg(i,"lastGeneratedColumn",null)}),i=this._originalMappings[++o]}return t},n.SourceMapConsumer=t,o.prototype=Object.create(t.prototype),o.prototype.consumer=t,o.fromSourceMap=function(e){var n=Object.create(o.prototype),r=n._names=l.fromArray(e._names.toArray(),!0),t=n._sources=l.fromArray(e._sources.toArray(),!0);n.sourceRoot=e._sourceRoot,n.sourcesContent=e._generateSourcesContent(n._sources.toArray(),n.sourceRoot),n.file=e._file;for(var s=e._mappings.toArray().slice(),u=n.__generatedMappings=[],c=n.__originalMappings=[],p=0,h=s.length;h>p;p++){var f=s[p],d=new i;d.generatedLine=f.generatedLine,d.generatedColumn=f.generatedColumn,f.source&&(d.source=t.indexOf(f.source),d.originalLine=f.originalLine,d.originalColumn=f.originalColumn,f.name&&(d.name=r.indexOf(f.name)),c.push(d)),u.push(d)}return g(n.__originalMappings,a.compareByOriginalPositions),n},o.prototype._version=3,Object.defineProperty(o.prototype,"sources",{get:function(){return this._sources.toArray().map(function(e){return null!=this.sourceRoot?a.join(this.sourceRoot,e):e},this)}}),o.prototype._parseMappings=function(e,n){for(var r,t,o,s,u,l=1,p=0,h=0,f=0,d=0,m=0,_=e.length,v=0,C={},y={},A=[],S=[];_>v;)if(";"===e.charAt(v))l++,v++,p=0;else if(","===e.charAt(v))v++;else{for(r=new i,r.generatedLine=l,s=v;_>s&&!this._charIsMappingSeparator(e,s);s++);if(t=e.slice(v,s),o=C[t])v+=t.length;else{for(o=[];s>v;)c.decode(e,v,y),u=y.value,v=y.rest,o.push(u);if(2===o.length)throw new Error("Found a source, but no line and column");if(3===o.length)throw new Error("Found a source and line, but no column");C[t]=o}r.generatedColumn=p+o[0],p=r.generatedColumn,o.length>1&&(r.source=d+o[1],d+=o[1],r.originalLine=h+o[2],h=r.originalLine,r.originalLine+=1,r.originalColumn=f+o[3],f=r.originalColumn,o.length>4&&(r.name=m+o[4],m+=o[4])),S.push(r),"number"==typeof r.originalLine&&A.push(r)}g(S,a.compareByGeneratedPositionsDeflated),this.__generatedMappings=S,g(A,a.compareByOriginalPositions),this.__originalMappings=A},o.prototype._findMapping=function(e,n,r,t,o,i){if(e[r]<=0)throw new TypeError("Line must be greater than or equal to 1, got "+e[r]);if(e[t]<0)throw new TypeError("Column must be greater than or equal to 0, got "+e[t]);return u.search(e,n,o,i)},o.prototype.computeColumnSpans=function(){for(var e=0;e=0){var o=this._generatedMappings[r];if(o.generatedLine===n.generatedLine){var i=a.getArg(o,"source",null);null!==i&&(i=this._sources.at(i),null!=this.sourceRoot&&(i=a.join(this.sourceRoot,i)));var s=a.getArg(o,"name",null);return null!==s&&(s=this._names.at(s)),{source:i,line:a.getArg(o,"originalLine",null),column:a.getArg(o,"originalColumn",null),name:s}}}return{source:null,line:null,column:null,name:null}},o.prototype.hasContentsOfAllSources=function(){return this.sourcesContent?this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some(function(e){return null==e}):!1},o.prototype.sourceContentFor=function(e,n){if(!this.sourcesContent)return null;if(null!=this.sourceRoot&&(e=a.relative(this.sourceRoot,e)),this._sources.has(e))return this.sourcesContent[this._sources.indexOf(e)];var r;if(null!=this.sourceRoot&&(r=a.urlParse(this.sourceRoot))){var t=e.replace(/^file:\/\//,"");if("file"==r.scheme&&this._sources.has(t))return this.sourcesContent[this._sources.indexOf(t)];if((!r.path||"/"==r.path)&&this._sources.has("/"+e))return this.sourcesContent[this._sources.indexOf("/"+e)]}if(n)return null;throw new Error('"'+e+'" is not in the SourceMap.')},o.prototype.generatedPositionFor=function(e){var n=a.getArg(e,"source");if(null!=this.sourceRoot&&(n=a.relative(this.sourceRoot,n)),!this._sources.has(n))return{line:null,column:null,lastColumn:null};n=this._sources.indexOf(n);var r={source:n,originalLine:a.getArg(e,"line"),originalColumn:a.getArg(e,"column")},o=this._findMapping(r,this._originalMappings,"originalLine","originalColumn",a.compareByOriginalPositions,a.getArg(e,"bias",t.GREATEST_LOWER_BOUND));if(o>=0){var i=this._originalMappings[o];if(i.source===r.source)return{line:a.getArg(i,"generatedLine",null),column:a.getArg(i,"generatedColumn",null),lastColumn:a.getArg(i,"lastGeneratedColumn",null)}}return{line:null,column:null,lastColumn:null}},n.BasicSourceMapConsumer=o,s.prototype=Object.create(t.prototype),s.prototype.constructor=t,s.prototype._version=3,Object.defineProperty(s.prototype,"sources",{get:function(){for(var e=[],n=0;n0?t-u>1?r(u,t,o,i,s,a):a==n.LEAST_UPPER_BOUND?t1?r(e,u,o,i,s,a):a==n.LEAST_UPPER_BOUND?u:0>e?-1:e}n.GREATEST_LOWER_BOUND=1,n.LEAST_UPPER_BOUND=2,n.search=function(e,t,o,i){if(0===t.length)return-1;var s=r(-1,t.length,e,t,o,i||n.GREATEST_LOWER_BOUND);if(0>s)return-1;for(;s-1>=0&&0===o(t[s],t[s-1],!0);)--s;return s}},function(e,n){function r(e,n,r){var t=e[n];e[n]=e[r],e[r]=t}function t(e,n){return Math.round(e+Math.random()*(n-e))}function o(e,n,i,s){if(s>i){var a=t(i,s),u=i-1;r(e,a,s);for(var l=e[s],c=i;s>c;c++)n(e[c],l)<=0&&(u+=1,r(e,u,c));r(e,u+1,c);var g=u+1;o(e,n,i,g-1),o(e,n,g+1,s)}}n.quickSort=function(e,n){o(e,n,0,e.length-1)}},function(e,n,r){function t(e,n,r,t,o){this.children=[],this.sourceContents={},this.line=null==e?null:e,this.column=null==n?null:n,this.source=null==r?null:r,this.name=null==o?null:o,this[u]=!0,null!=t&&this.add(t)}var o=r(1).SourceMapGenerator,i=r(4),s=/(\r?\n)/,a=10,u="$$$isSourceNode$$$";t.fromStringWithSourceMap=function(e,n,r){function o(e,n){if(null===e||void 0===e.source)a.add(n);else{var o=r?i.join(r,e.source):e.source;a.add(new t(e.originalLine,e.originalColumn,o,n,e.name))}}var a=new t,u=e.split(s),l=function(){var e=u.shift(),n=u.shift()||"";return e+n},c=1,g=0,p=null;return n.eachMapping(function(e){if(null!==p){if(!(c0&&(p&&o(p,l()),a.add(u.join(""))),n.sources.forEach(function(e){var t=n.sourceContentFor(e);null!=t&&(null!=r&&(e=i.join(r,e)),a.setSourceContent(e,t))}),a},t.prototype.add=function(e){if(Array.isArray(e))e.forEach(function(e){this.add(e)},this);else{if(!e[u]&&"string"!=typeof e)throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+e);e&&this.children.push(e)}return this},t.prototype.prepend=function(e){if(Array.isArray(e))for(var n=e.length-1;n>=0;n--)this.prepend(e[n]);else{if(!e[u]&&"string"!=typeof e)throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+e);this.children.unshift(e)}return this},t.prototype.walk=function(e){for(var n,r=0,t=this.children.length;t>r;r++)n=this.children[r],n[u]?n.walk(e):""!==n&&e(n,{source:this.source,line:this.line,column:this.column,name:this.name})},t.prototype.join=function(e){var n,r,t=this.children.length;if(t>0){for(n=[],r=0;t-1>r;r++)n.push(this.children[r]),n.push(e);n.push(this.children[r]),this.children=n}return this},t.prototype.replaceRight=function(e,n){var r=this.children[this.children.length-1];return r[u]?r.replaceRight(e,n):"string"==typeof r?this.children[this.children.length-1]=r.replace(e,n):this.children.push("".replace(e,n)),this},t.prototype.setSourceContent=function(e,n){this.sourceContents[i.toSetString(e)]=n},t.prototype.walkSourceContents=function(e){for(var n=0,r=this.children.length;r>n;n++)this.children[n][u]&&this.children[n].walkSourceContents(e);for(var t=Object.keys(this.sourceContents),n=0,r=t.length;r>n;n++)e(i.fromSetString(t[n]),this.sourceContents[t[n]])},t.prototype.toString=function(){var e="";return this.walk(function(n){e+=n}),e},t.prototype.toStringWithSourceMap=function(e){var n={code:"",line:1,column:0},r=new o(e),t=!1,i=null,s=null,u=null,l=null;return this.walk(function(e,o){n.code+=e,null!==o.source&&null!==o.line&&null!==o.column?((i!==o.source||s!==o.line||u!==o.column||l!==o.name)&&r.addMapping({source:o.source,original:{line:o.line,column:o.column},generated:{line:n.line,column:n.column},name:o.name}),i=o.source,s=o.line,u=o.column,l=o.name,t=!0):t&&(r.addMapping({generated:{line:n.line,column:n.column}}),i=null,t=!1);for(var c=0,g=e.length;g>c;c++)e.charCodeAt(c)===a?(n.line++,n.column=0,c+1===g?(i=null,t=!1):t&&r.addMapping({source:o.source,original:{line:o.line,column:o.column},generated:{line:n.line,column:n.column},name:o.name})):n.column++}),this.walkSourceContents(function(e,n){r.setSourceContent(e,n)}),{code:n.code,map:r}},n.SourceNode=t}])}); +//# sourceMappingURL=source-map.min.js.map \ No newline at end of file diff --git a/node_modules/source-map/dist/source-map.min.js.map b/node_modules/source-map/dist/source-map.min.js.map new file mode 100644 index 0000000..3275a32 --- /dev/null +++ b/node_modules/source-map/dist/source-map.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///source-map.min.js","webpack:///webpack/bootstrap 5d9a9f4df3bd553ed2f9","webpack:///./source-map.js","webpack:///./lib/source-map-generator.js","webpack:///./lib/base64-vlq.js","webpack:///./lib/base64.js","webpack:///./lib/util.js","webpack:///./lib/array-set.js","webpack:///./lib/mapping-list.js","webpack:///./lib/source-map-consumer.js","webpack:///./lib/binary-search.js","webpack:///./lib/quick-sort.js","webpack:///./lib/source-node.js"],"names":["root","factory","exports","module","define","amd","this","modules","__webpack_require__","moduleId","installedModules","id","loaded","call","m","c","p","SourceMapGenerator","SourceMapConsumer","SourceNode","aArgs","_file","util","getArg","_sourceRoot","_skipValidation","_sources","ArraySet","_names","_mappings","MappingList","_sourcesContents","base64VLQ","prototype","_version","fromSourceMap","aSourceMapConsumer","sourceRoot","generator","file","eachMapping","mapping","newMapping","generated","line","generatedLine","column","generatedColumn","source","relative","original","originalLine","originalColumn","name","addMapping","sources","forEach","sourceFile","content","sourceContentFor","setSourceContent","_validateMapping","String","has","add","aSourceFile","aSourceContent","Object","create","toSetString","keys","length","applySourceMap","aSourceMapPath","Error","newSources","newNames","unsortedForEach","originalPositionFor","join","aGenerated","aOriginal","aSource","aName","JSON","stringify","_serializeMappings","next","nameIdx","sourceIdx","previousGeneratedColumn","previousGeneratedLine","previousOriginalColumn","previousOriginalLine","previousName","previousSource","result","mappings","toArray","i","len","compareByGeneratedPositionsInflated","encode","indexOf","_generateSourcesContent","aSources","aSourceRoot","map","key","hasOwnProperty","toJSON","version","names","sourcesContent","toString","toVLQSigned","aValue","fromVLQSigned","isNegative","shifted","base64","VLQ_BASE_SHIFT","VLQ_BASE","VLQ_BASE_MASK","VLQ_CONTINUATION_BIT","digit","encoded","vlq","decode","aStr","aIndex","aOutParam","continuation","strLen","shift","charCodeAt","charAt","value","rest","intToCharMap","split","number","TypeError","charCode","bigA","bigZ","littleA","littleZ","zero","nine","plus","slash","littleOffset","numberOffset","aDefaultValue","arguments","urlParse","aUrl","match","urlRegexp","scheme","auth","host","port","path","urlGenerate","aParsedUrl","url","normalize","aPath","part","isAbsolute","parts","up","splice","aRoot","aPathUrl","aRootUrl","dataUrlRegexp","joined","replace","level","index","lastIndexOf","slice","Array","substr","identity","s","isProtoString","fromSetString","compareByOriginalPositions","mappingA","mappingB","onlyCompareOriginal","cmp","compareByGeneratedPositionsDeflated","onlyCompareGenerated","strcmp","aStr1","aStr2","supportsNullProto","obj","_array","_set","fromArray","aArray","aAllowDuplicates","set","size","getOwnPropertyNames","sStr","isDuplicate","idx","push","at","aIdx","generatedPositionAfter","lineA","lineB","columnA","columnB","_sorted","_last","aCallback","aThisArg","aMapping","sort","aSourceMap","sourceMap","parse","sections","IndexedSourceMapConsumer","BasicSourceMapConsumer","Mapping","lastOffset","_sections","offset","offsetLine","offsetColumn","generatedOffset","consumer","binarySearch","quickSort","__generatedMappings","defineProperty","get","_parseMappings","__originalMappings","_charIsMappingSeparator","GENERATED_ORDER","ORIGINAL_ORDER","GREATEST_LOWER_BOUND","LEAST_UPPER_BOUND","aContext","aOrder","context","order","_generatedMappings","_originalMappings","allGeneratedPositionsFor","needle","_findMapping","undefined","lastColumn","smc","generatedMappings","destGeneratedMappings","destOriginalMappings","srcMapping","destMapping","str","segment","end","cachedSegments","temp","originalMappings","aNeedle","aMappings","aLineName","aColumnName","aComparator","aBias","search","computeColumnSpans","nextMapping","lastGeneratedColumn","Infinity","hasContentsOfAllSources","some","sc","nullOnMissing","fileUriAbsPath","generatedPositionFor","constructor","j","sectionIndex","section","bias","every","generatedPosition","ret","sectionMappings","adjustedMapping","recursiveSearch","aLow","aHigh","aHaystack","aCompare","mid","Math","floor","swap","ary","x","y","randomIntInRange","low","high","round","random","doQuickSort","comparator","r","pivotIndex","pivot","q","aLine","aColumn","aChunks","children","sourceContents","isSourceNode","REGEX_NEWLINE","NEWLINE_CODE","fromStringWithSourceMap","aGeneratedCode","aRelativePath","addMappingWithCode","code","node","remainingLines","shiftNextLine","lineContents","newLine","lastGeneratedLine","lastMapping","nextLine","aChunk","isArray","chunk","prepend","unshift","walk","aFn","aSep","newChildren","replaceRight","aPattern","aReplacement","lastChild","walkSourceContents","toStringWithSourceMap","sourceMappingActive","lastOriginalSource","lastOriginalLine","lastOriginalColumn","lastOriginalName","sourceContent"],"mappings":"CAAA,SAAAA,EAAAC,GACA,gBAAAC,UAAA,gBAAAC,QACAA,OAAAD,QAAAD,IACA,kBAAAG,gBAAAC,IACAD,UAAAH,GACA,gBAAAC,SACAA,QAAA,UAAAD,IAEAD,EAAA,UAAAC,KACCK,KAAA,WACD,MCAgB,UAAUC,GCN1B,QAAAC,GAAAC,GAGA,GAAAC,EAAAD,GACA,MAAAC,GAAAD,GAAAP,OAGA,IAAAC,GAAAO,EAAAD,IACAP,WACAS,GAAAF,EACAG,QAAA,EAUA,OANAL,GAAAE,GAAAI,KAAAV,EAAAD,QAAAC,IAAAD,QAAAM,GAGAL,EAAAS,QAAA,EAGAT,EAAAD,QAvBA,GAAAQ,KAqCA,OATAF,GAAAM,EAAAP,EAGAC,EAAAO,EAAAL,EAGAF,EAAAQ,EAAA,GAGAR,EAAA,KDgBM,SAASL,EAAQD,EAASM,GEjDhCN,EAAAe,mBAAAT,EAAA,GAAAS,mBACAf,EAAAgB,kBAAAV,EAAA,GAAAU,kBACAhB,EAAAiB,WAAAX,EAAA,IAAAW,YF6DM,SAAShB,EAAQD,EAASM,GGhDhC,QAAAS,GAAAG,GACAA,IACAA,MAEAd,KAAAe,MAAAC,EAAAC,OAAAH,EAAA,aACAd,KAAAkB,YAAAF,EAAAC,OAAAH,EAAA,mBACAd,KAAAmB,gBAAAH,EAAAC,OAAAH,EAAA,qBACAd,KAAAoB,SAAA,GAAAC,GACArB,KAAAsB,OAAA,GAAAD,GACArB,KAAAuB,UAAA,GAAAC,GACAxB,KAAAyB,iBAAA,KAvBA,GAAAC,GAAAxB,EAAA,GACAc,EAAAd,EAAA,GACAmB,EAAAnB,EAAA,GAAAmB,SACAG,EAAAtB,EAAA,GAAAsB,WAuBAb,GAAAgB,UAAAC,SAAA,EAOAjB,EAAAkB,cACA,SAAAC,GACA,GAAAC,GAAAD,EAAAC,WACAC,EAAA,GAAArB,IACAsB,KAAAH,EAAAG,KACAF,cAkCA,OAhCAD,GAAAI,YAAA,SAAAC,GACA,GAAAC,IACAC,WACAC,KAAAH,EAAAI,cACAC,OAAAL,EAAAM,iBAIA,OAAAN,EAAAO,SACAN,EAAAM,OAAAP,EAAAO,OACA,MAAAX,IACAK,EAAAM,OAAA1B,EAAA2B,SAAAZ,EAAAK,EAAAM,SAGAN,EAAAQ,UACAN,KAAAH,EAAAU,aACAL,OAAAL,EAAAW,gBAGA,MAAAX,EAAAY,OACAX,EAAAW,KAAAZ,EAAAY,OAIAf,EAAAgB,WAAAZ,KAEAN,EAAAmB,QAAAC,QAAA,SAAAC,GACA,GAAAC,GAAAtB,EAAAuB,iBAAAF,EACA,OAAAC,GACApB,EAAAsB,iBAAAH,EAAAC,KAGApB,GAaArB,EAAAgB,UAAAqB,WACA,SAAAlC,GACA,GAAAuB,GAAArB,EAAAC,OAAAH,EAAA,aACA8B,EAAA5B,EAAAC,OAAAH,EAAA,iBACA4B,EAAA1B,EAAAC,OAAAH,EAAA,eACAiC,EAAA/B,EAAAC,OAAAH,EAAA,YAEAd,MAAAmB,iBACAnB,KAAAuD,iBAAAlB,EAAAO,EAAAF,EAAAK,GAGA,MAAAL,IACAA,EAAAc,OAAAd,GACA1C,KAAAoB,SAAAqC,IAAAf,IACA1C,KAAAoB,SAAAsC,IAAAhB,IAIA,MAAAK,IACAA,EAAAS,OAAAT,GACA/C,KAAAsB,OAAAmC,IAAAV,IACA/C,KAAAsB,OAAAoC,IAAAX,IAIA/C,KAAAuB,UAAAmC,KACAnB,cAAAF,EAAAC,KACAG,gBAAAJ,EAAAG,OACAK,aAAA,MAAAD,KAAAN,KACAQ,eAAA,MAAAF,KAAAJ,OACAE,SACAK,UAOApC,EAAAgB,UAAA2B,iBACA,SAAAK,EAAAC,GACA,GAAAlB,GAAAiB,CACA,OAAA3D,KAAAkB,cACAwB,EAAA1B,EAAA2B,SAAA3C,KAAAkB,YAAAwB,IAGA,MAAAkB,GAGA5D,KAAAyB,mBACAzB,KAAAyB,iBAAAoC,OAAAC,OAAA,OAEA9D,KAAAyB,iBAAAT,EAAA+C,YAAArB,IAAAkB,GACK5D,KAAAyB,yBAGLzB,MAAAyB,iBAAAT,EAAA+C,YAAArB,IACA,IAAAmB,OAAAG,KAAAhE,KAAAyB,kBAAAwC,SACAjE,KAAAyB,iBAAA,QAqBAd,EAAAgB,UAAAuC,eACA,SAAApC,EAAA6B,EAAAQ,GACA,GAAAhB,GAAAQ,CAEA,UAAAA,EAAA,CACA,SAAA7B,EAAAG,KACA,SAAAmC,OACA,gJAIAjB,GAAArB,EAAAG,KAEA,GAAAF,GAAA/B,KAAAkB,WAEA,OAAAa,IACAoB,EAAAnC,EAAA2B,SAAAZ,EAAAoB,GAIA,IAAAkB,GAAA,GAAAhD,GACAiD,EAAA,GAAAjD,EAGArB,MAAAuB,UAAAgD,gBAAA,SAAApC,GACA,GAAAA,EAAAO,SAAAS,GAAA,MAAAhB,EAAAU,aAAA,CAEA,GAAAD,GAAAd,EAAA0C,qBACAlC,KAAAH,EAAAU,aACAL,OAAAL,EAAAW,gBAEA,OAAAF,EAAAF,SAEAP,EAAAO,OAAAE,EAAAF,OACA,MAAAyB,IACAhC,EAAAO,OAAA1B,EAAAyD,KAAAN,EAAAhC,EAAAO,SAEA,MAAAX,IACAI,EAAAO,OAAA1B,EAAA2B,SAAAZ,EAAAI,EAAAO,SAEAP,EAAAU,aAAAD,EAAAN,KACAH,EAAAW,eAAAF,EAAAJ,OACA,MAAAI,EAAAG,OACAZ,EAAAY,KAAAH,EAAAG,OAKA,GAAAL,GAAAP,EAAAO,MACA,OAAAA,GAAA2B,EAAAZ,IAAAf,IACA2B,EAAAX,IAAAhB,EAGA,IAAAK,GAAAZ,EAAAY,IACA,OAAAA,GAAAuB,EAAAb,IAAAV,IACAuB,EAAAZ,IAAAX,IAGK/C,MACLA,KAAAoB,SAAAiD,EACArE,KAAAsB,OAAAgD,EAGAxC,EAAAmB,QAAAC,QAAA,SAAAC,GACA,GAAAC,GAAAtB,EAAAuB,iBAAAF,EACA,OAAAC,IACA,MAAAe,IACAhB,EAAAnC,EAAAyD,KAAAN,EAAAhB,IAEA,MAAApB,IACAoB,EAAAnC,EAAA2B,SAAAZ,EAAAoB,IAEAnD,KAAAsD,iBAAAH,EAAAC,KAEKpD,OAcLW,EAAAgB,UAAA4B,iBACA,SAAAmB,EAAAC,EAAAC,EACAC,GACA,MAAAH,GAAA,QAAAA,IAAA,UAAAA,IACAA,EAAApC,KAAA,GAAAoC,EAAAlC,QAAA,IACAmC,GAAAC,GAAAC,MAIAH,GAAA,QAAAA,IAAA,UAAAA,IACAC,GAAA,QAAAA,IAAA,UAAAA,IACAD,EAAApC,KAAA,GAAAoC,EAAAlC,QAAA,GACAmC,EAAArC,KAAA,GAAAqC,EAAAnC,QAAA,GACAoC,GAKA,SAAAR,OAAA,oBAAAU,KAAAC,WACA1C,UAAAqC,EACAhC,OAAAkC,EACAhC,SAAA+B,EACA5B,KAAA8B,MASAlE,EAAAgB,UAAAqD,mBACA,WAcA,OANAC,GACA9C,EACA+C,EACAC,EAVAC,EAAA,EACAC,EAAA,EACAC,EAAA,EACAC,EAAA,EACAC,EAAA,EACAC,EAAA,EACAC,EAAA,GAMAC,EAAA3F,KAAAuB,UAAAqE,UACAC,EAAA,EAAAC,EAAAH,EAAA1B,OAA0C6B,EAAAD,EAASA,IAAA,CAInD,GAHA1D,EAAAwD,EAAAE,GACAZ,EAAA,GAEA9C,EAAAI,gBAAA8C,EAEA,IADAD,EAAA,EACAjD,EAAAI,gBAAA8C,GACAJ,GAAA,IACAI,QAIA,IAAAQ,EAAA,GACA,IAAA7E,EAAA+E,oCAAA5D,EAAAwD,EAAAE,EAAA,IACA,QAEAZ,IAAA,IAIAA,GAAAvD,EAAAsE,OAAA7D,EAAAM,gBACA2C,GACAA,EAAAjD,EAAAM,gBAEA,MAAAN,EAAAO,SACAyC,EAAAnF,KAAAoB,SAAA6E,QAAA9D,EAAAO,QACAuC,GAAAvD,EAAAsE,OAAAb,EAAAM,GACAA,EAAAN,EAGAF,GAAAvD,EAAAsE,OAAA7D,EAAAU,aAAA,EACA0C,GACAA,EAAApD,EAAAU,aAAA,EAEAoC,GAAAvD,EAAAsE,OAAA7D,EAAAW,eACAwC,GACAA,EAAAnD,EAAAW,eAEA,MAAAX,EAAAY,OACAmC,EAAAlF,KAAAsB,OAAA2E,QAAA9D,EAAAY,MACAkC,GAAAvD,EAAAsE,OAAAd,EAAAM,GACAA,EAAAN,IAIAQ,GAAAT,EAGA,MAAAS,IAGA/E,EAAAgB,UAAAuE,wBACA,SAAAC,EAAAC,GACA,MAAAD,GAAAE,IAAA,SAAA3D,GACA,IAAA1C,KAAAyB,iBACA,WAEA,OAAA2E,IACA1D,EAAA1B,EAAA2B,SAAAyD,EAAA1D,GAEA,IAAA4D,GAAAtF,EAAA+C,YAAArB,EACA,OAAAmB,QAAAlC,UAAA4E,eAAAhG,KAAAP,KAAAyB,iBAAA6E,GACAtG,KAAAyB,iBAAA6E,GACA,MACKtG,OAMLW,EAAAgB,UAAA6E,OACA,WACA,GAAAH,IACAI,QAAAzG,KAAA4B,SACAqB,QAAAjD,KAAAoB,SAAAwE,UACAc,MAAA1G,KAAAsB,OAAAsE,UACAD,SAAA3F,KAAAgF,qBAYA,OAVA,OAAAhF,KAAAe,QACAsF,EAAApE,KAAAjC,KAAAe,OAEA,MAAAf,KAAAkB,cACAmF,EAAAtE,WAAA/B,KAAAkB,aAEAlB,KAAAyB,mBACA4E,EAAAM,eAAA3G,KAAAkG,wBAAAG,EAAApD,QAAAoD,EAAAtE,aAGAsE,GAMA1F,EAAAgB,UAAAiF,SACA,WACA,MAAA9B,MAAAC,UAAA/E,KAAAwG,WAGA5G,EAAAe,sBH2EM,SAASd,EAAQD,EAASM,GI1ZhC,QAAA2G,GAAAC,GACA,SAAAA,IACAA,GAAA,MACAA,GAAA,KASA,QAAAC,GAAAD,GACA,GAAAE,GAAA,OAAAF,GACAG,EAAAH,GAAA,CACA,OAAAE,IACAC,EACAA,EAhDA,GAAAC,GAAAhH,EAAA,GAcAiH,EAAA,EAGAC,EAAA,GAAAD,EAGAE,EAAAD,EAAA,EAGAE,EAAAF,CA+BAxH,GAAAoG,OAAA,SAAAc,GACA,GACAS,GADAC,EAAA,GAGAC,EAAAZ,EAAAC,EAEA,GACAS,GAAAE,EAAAJ,EACAI,KAAAN,EACAM,EAAA,IAGAF,GAAAD,GAEAE,GAAAN,EAAAlB,OAAAuB,SACGE,EAAA,EAEH,OAAAD,IAOA5H,EAAA8H,OAAA,SAAAC,EAAAC,EAAAC,GACA,GAGAC,GAAAP,EAHAQ,EAAAJ,EAAA1D,OACAyB,EAAA,EACAsC,EAAA,CAGA,IACA,GAAAJ,GAAAG,EACA,SAAA3D,OAAA,6CAIA,IADAmD,EAAAL,EAAAQ,OAAAC,EAAAM,WAAAL,MACA,KAAAL,EACA,SAAAnD,OAAA,yBAAAuD,EAAAO,OAAAN,EAAA,GAGAE,MAAAP,EAAAD,GACAC,GAAAF,EACA3B,GAAA6B,GAAAS,EACAA,GAAAb,QACGW,EAEHD,GAAAM,MAAApB,EAAArB,GACAmC,EAAAO,KAAAR,IJseM,SAAS/H,EAAQD,GKzmBvB,GAAAyI,GAAA,mEAAAC,MAAA,GAKA1I,GAAAoG,OAAA,SAAAuC,GACA,GAAAA,GAAA,GAAAA,EAAAF,EAAApE,OACA,MAAAoE,GAAAE,EAEA,UAAAC,WAAA,6BAAAD,IAOA3I,EAAA8H,OAAA,SAAAe,GACA,GAAAC,GAAA,GACAC,EAAA,GAEAC,EAAA,GACAC,EAAA,IAEAC,EAAA,GACAC,EAAA,GAEAC,EAAA,GACAC,EAAA,GAEAC,EAAA,GACAC,EAAA,EAGA,OAAAV,IAAAC,GAAAC,GAAAF,EACAA,EAAAC,EAIAD,GAAAG,GAAAC,GAAAJ,EACAA,EAAAG,EAAAM,EAIAT,GAAAK,GAAAC,GAAAN,EACAA,EAAAK,EAAAK,EAIAV,GAAAO,EACA,GAIAP,GAAAQ,EACA,GAIA,KLwnBM,SAASpJ,EAAQD,GMxqBvB,QAAAqB,GAAAH,EAAA+D,EAAAuE,GACA,GAAAvE,IAAA/D,GACA,MAAAA,GAAA+D,EACG,QAAAwE,UAAApF,OACH,MAAAmF,EAEA,UAAAhF,OAAA,IAAAS,EAAA,6BAQA,QAAAyE,GAAAC,GACA,GAAAC,GAAAD,EAAAC,MAAAC,EACA,OAAAD,IAIAE,OAAAF,EAAA,GACAG,KAAAH,EAAA,GACAI,KAAAJ,EAAA,GACAK,KAAAL,EAAA,GACAM,KAAAN,EAAA,IAPA,KAYA,QAAAO,GAAAC,GACA,GAAAC,GAAA,EAiBA,OAhBAD,GAAAN,SACAO,GAAAD,EAAAN,OAAA,KAEAO,GAAA,KACAD,EAAAL,OACAM,GAAAD,EAAAL,KAAA,KAEAK,EAAAJ,OACAK,GAAAD,EAAAJ,MAEAI,EAAAH,OACAI,GAAA,IAAAD,EAAAH,MAEAG,EAAAF,OACAG,GAAAD,EAAAF,MAEAG,EAeA,QAAAC,GAAAC,GACA,GAAAL,GAAAK,EACAF,EAAAX,EAAAa,EACA,IAAAF,EAAA,CACA,IAAAA,EAAAH,KACA,MAAAK,EAEAL,GAAAG,EAAAH,KAKA,OAAAM,GAHAC,EAAAzK,EAAAyK,WAAAP,GAEAQ,EAAAR,EAAAxB,MAAA,OACAiC,EAAA,EAAA1E,EAAAyE,EAAArG,OAAA,EAA8C4B,GAAA,EAAQA,IACtDuE,EAAAE,EAAAzE,GACA,MAAAuE,EACAE,EAAAE,OAAA3E,EAAA,GACK,OAAAuE,EACLG,IACKA,EAAA,IACL,KAAAH,GAIAE,EAAAE,OAAA3E,EAAA,EAAA0E,GACAA,EAAA,IAEAD,EAAAE,OAAA3E,EAAA,GACA0E,KAUA,OANAT,GAAAQ,EAAA7F,KAAA,KAEA,KAAAqF,IACAA,EAAAO,EAAA,SAGAJ,GACAA,EAAAH,OACAC,EAAAE,IAEAH,EAoBA,QAAArF,GAAAgG,EAAAN,GACA,KAAAM,IACAA,EAAA,KAEA,KAAAN,IACAA,EAAA,IAEA,IAAAO,GAAApB,EAAAa,GACAQ,EAAArB,EAAAmB,EAMA,IALAE,IACAF,EAAAE,EAAAb,MAAA,KAIAY,MAAAhB,OAIA,MAHAiB,KACAD,EAAAhB,OAAAiB,EAAAjB,QAEAK,EAAAW,EAGA,IAAAA,GAAAP,EAAAX,MAAAoB,GACA,MAAAT,EAIA,IAAAQ,MAAAf,OAAAe,EAAAb,KAEA,MADAa,GAAAf,KAAAO,EACAJ,EAAAY,EAGA,IAAAE,GAAA,MAAAV,EAAAjC,OAAA,GACAiC,EACAD,EAAAO,EAAAK,QAAA,eAAAX,EAEA,OAAAQ,IACAA,EAAAb,KAAAe,EACAd,EAAAY,IAEAE,EAcA,QAAAlI,GAAA8H,EAAAN,GACA,KAAAM,IACAA,EAAA,KAGAA,IAAAK,QAAA,SAOA,KADA,GAAAC,GAAA,EACA,IAAAZ,EAAAlE,QAAAwE,EAAA,OACA,GAAAO,GAAAP,EAAAQ,YAAA,IACA,MAAAD,EACA,MAAAb,EAOA,IADAM,IAAAS,MAAA,EAAAF,GACAP,EAAAjB,MAAA,qBACA,MAAAW,KAGAY,EAIA,MAAAI,OAAAJ,EAAA,GAAAtG,KAAA,OAAA0F,EAAAiB,OAAAX,EAAAxG,OAAA,GASA,QAAAoH,GAAAC,GACA,MAAAA,GAYA,QAAAvH,GAAA4D,GACA,MAAA4D,GAAA5D,GACA,IAAAA,EAGAA,EAIA,QAAA6D,GAAA7D,GACA,MAAA4D,GAAA5D,GACAA,EAAAuD,MAAA,GAGAvD,EAIA,QAAA4D,GAAAD,GACA,IAAAA,EACA,QAGA,IAAArH,GAAAqH,EAAArH,MAEA,MAAAA,EACA,QAGA,SAAAqH,EAAArD,WAAAhE,EAAA,IACA,KAAAqH,EAAArD,WAAAhE,EAAA,IACA,MAAAqH,EAAArD,WAAAhE,EAAA,IACA,MAAAqH,EAAArD,WAAAhE,EAAA,IACA,MAAAqH,EAAArD,WAAAhE,EAAA,IACA,MAAAqH,EAAArD,WAAAhE,EAAA,IACA,MAAAqH,EAAArD,WAAAhE,EAAA,IACA,KAAAqH,EAAArD,WAAAhE,EAAA,IACA,KAAAqH,EAAArD,WAAAhE,EAAA,GACA,QAGA,QAAA4B,GAAA5B,EAAA,GAA2B4B,GAAA,EAAQA,IACnC,QAAAyF,EAAArD,WAAApC,GACA,QAIA,UAWA,QAAA4F,GAAAC,EAAAC,EAAAC,GACA,GAAAC,GAAAH,EAAAhJ,OAAAiJ,EAAAjJ,MACA,YAAAmJ,EACAA,GAGAA,EAAAH,EAAA7I,aAAA8I,EAAA9I,aACA,IAAAgJ,EACAA,GAGAA,EAAAH,EAAA5I,eAAA6I,EAAA7I,eACA,IAAA+I,GAAAD,EACAC,GAGAA,EAAAH,EAAAjJ,gBAAAkJ,EAAAlJ,gBACA,IAAAoJ,EACAA,GAGAA,EAAAH,EAAAnJ,cAAAoJ,EAAApJ,cACA,IAAAsJ,EACAA,EAGAH,EAAA3I,KAAA4I,EAAA5I,SAaA,QAAA+I,GAAAJ,EAAAC,EAAAI,GACA,GAAAF,GAAAH,EAAAnJ,cAAAoJ,EAAApJ,aACA,YAAAsJ,EACAA,GAGAA,EAAAH,EAAAjJ,gBAAAkJ,EAAAlJ,gBACA,IAAAoJ,GAAAE,EACAF,GAGAA,EAAAH,EAAAhJ,OAAAiJ,EAAAjJ,OACA,IAAAmJ,EACAA,GAGAA,EAAAH,EAAA7I,aAAA8I,EAAA9I,aACA,IAAAgJ,EACAA,GAGAA,EAAAH,EAAA5I,eAAA6I,EAAA7I,eACA,IAAA+I,EACAA,EAGAH,EAAA3I,KAAA4I,EAAA5I,SAIA,QAAAiJ,GAAAC,EAAAC,GACA,MAAAD,KAAAC,EACA,EAGAD,EAAAC,EACA,EAGA,GAOA,QAAAnG,GAAA2F,EAAAC,GACA,GAAAE,GAAAH,EAAAnJ,cAAAoJ,EAAApJ,aACA,YAAAsJ,EACAA,GAGAA,EAAAH,EAAAjJ,gBAAAkJ,EAAAlJ,gBACA,IAAAoJ,EACAA,GAGAA,EAAAG,EAAAN,EAAAhJ,OAAAiJ,EAAAjJ,QACA,IAAAmJ,EACAA,GAGAA,EAAAH,EAAA7I,aAAA8I,EAAA9I,aACA,IAAAgJ,EACAA,GAGAA,EAAAH,EAAA5I,eAAA6I,EAAA7I,eACA,IAAA+I,EACAA,EAGAG,EAAAN,EAAA3I,KAAA4I,EAAA5I,UApYAnD,EAAAqB,QAEA,IAAAwI,GAAA,iEACAmB,EAAA,eAeAhL,GAAA0J,WAsBA1J,EAAAmK,cAwDAnK,EAAAsK,YA2DAtK,EAAA6E,OAEA7E,EAAAyK,WAAA,SAAAF,GACA,YAAAA,EAAAjC,OAAA,MAAAiC,EAAAX,MAAAC,IAyCA7J,EAAA+C,UAEA,IAAAwJ,GAAA,WACA,GAAAC,GAAAvI,OAAAC,OAAA,KACA,sBAAAsI,MAuBAxM,GAAAmE,YAAAoI,EAAAd,EAAAtH,EASAnE,EAAA4L,cAAAW,EAAAd,EAAAG,EAsEA5L,EAAA6L,6BAuCA7L,EAAAkM,sCA8CAlM,EAAAmG,uCNgsBM,SAASlG,EAAQD,EAASM,GOhlChC,QAAAmB,KACArB,KAAAqM,UACArM,KAAAsM,KAAAzI,OAAAC,OAAA,MAXA,GAAA9C,GAAAd,EAAA,GACAuD,EAAAI,OAAAlC,UAAA4E,cAgBAlF,GAAAkL,UAAA,SAAAC,EAAAC,GAEA,OADAC,GAAA,GAAArL,GACAwE,EAAA,EAAAC,EAAA0G,EAAAvI,OAAsC6B,EAAAD,EAASA,IAC/C6G,EAAAhJ,IAAA8I,EAAA3G,GAAA4G,EAEA,OAAAC,IASArL,EAAAM,UAAAgL,KAAA,WACA,MAAA9I,QAAA+I,oBAAA5M,KAAAsM,MAAArI,QAQA5C,EAAAM,UAAA+B,IAAA,SAAAiE,EAAA8E,GACA,GAAAI,GAAA7L,EAAA+C,YAAA4D,GACAmF,EAAArJ,EAAAlD,KAAAP,KAAAsM,KAAAO,GACAE,EAAA/M,KAAAqM,OAAApI,SACA6I,GAAAL,IACAzM,KAAAqM,OAAAW,KAAArF,GAEAmF,IACA9M,KAAAsM,KAAAO,GAAAE,IASA1L,EAAAM,UAAA8B,IAAA,SAAAkE,GACA,GAAAkF,GAAA7L,EAAA+C,YAAA4D,EACA,OAAAlE,GAAAlD,KAAAP,KAAAsM,KAAAO,IAQAxL,EAAAM,UAAAsE,QAAA,SAAA0B,GACA,GAAAkF,GAAA7L,EAAA+C,YAAA4D,EACA,IAAAlE,EAAAlD,KAAAP,KAAAsM,KAAAO,GACA,MAAA7M,MAAAsM,KAAAO,EAEA,UAAAzI,OAAA,IAAAuD,EAAA,yBAQAtG,EAAAM,UAAAsL,GAAA,SAAAC,GACA,GAAAA,GAAA,GAAAA,EAAAlN,KAAAqM,OAAApI,OACA,MAAAjE,MAAAqM,OAAAa,EAEA,UAAA9I,OAAA,yBAAA8I,IAQA7L,EAAAM,UAAAiE,QAAA,WACA,MAAA5F,MAAAqM,OAAAnB,SAGAtL,EAAAyB,YPumCM,SAASxB,EAAQD,EAASM,GQjsChC,QAAAiN,GAAAzB,EAAAC,GAEA,GAAAyB,GAAA1B,EAAAnJ,cACA8K,EAAA1B,EAAApJ,cACA+K,EAAA5B,EAAAjJ,gBACA8K,EAAA5B,EAAAlJ,eACA,OAAA4K,GAAAD,GAAAC,GAAAD,GAAAG,GAAAD,GACAtM,EAAA+E,oCAAA2F,EAAAC,IAAA,EAQA,QAAAnK,KACAxB,KAAAqM,UACArM,KAAAwN,SAAA,EAEAxN,KAAAyN,OAAgBlL,cAAA,GAAAE,gBAAA,GAzBhB,GAAAzB,GAAAd,EAAA,EAkCAsB,GAAAG,UAAA4C,gBACA,SAAAmJ,EAAAC,GACA3N,KAAAqM,OAAAnJ,QAAAwK,EAAAC,IAQAnM,EAAAG,UAAA+B,IAAA,SAAAkK,GACAT,EAAAnN,KAAAyN,MAAAG,IACA5N,KAAAyN,MAAAG,EACA5N,KAAAqM,OAAAW,KAAAY,KAEA5N,KAAAwN,SAAA,EACAxN,KAAAqM,OAAAW,KAAAY,KAaApM,EAAAG,UAAAiE,QAAA,WAKA,MAJA5F,MAAAwN,UACAxN,KAAAqM,OAAAwB,KAAA7M,EAAA+E,qCACA/F,KAAAwN,SAAA,GAEAxN,KAAAqM,QAGAzM,EAAA4B,eRqtCM,SAAS3B,EAAQD,EAASM,GStxChC,QAAAU,GAAAkN,GACA,GAAAC,GAAAD,CAKA,OAJA,gBAAAA,KACAC,EAAAjJ,KAAAkJ,MAAAF,EAAAhD,QAAA,WAAsD,MAGtD,MAAAiD,EAAAE,SACA,GAAAC,GAAAH,GACA,GAAAI,GAAAJ,GAoQA,QAAAI,GAAAL,GACA,GAAAC,GAAAD,CACA,iBAAAA,KACAC,EAAAjJ,KAAAkJ,MAAAF,EAAAhD,QAAA,WAAsD,KAGtD,IAAArE,GAAAzF,EAAAC,OAAA8M,EAAA,WACA9K,EAAAjC,EAAAC,OAAA8M,EAAA,WAGArH,EAAA1F,EAAAC,OAAA8M,EAAA,YACAhM,EAAAf,EAAAC,OAAA8M,EAAA,mBACApH,EAAA3F,EAAAC,OAAA8M,EAAA,uBACApI,EAAA3E,EAAAC,OAAA8M,EAAA,YACA9L,EAAAjB,EAAAC,OAAA8M,EAAA,YAIA,IAAAtH,GAAAzG,KAAA4B,SACA,SAAAwC,OAAA,wBAAAqC,EAGAxD,KACAoD,IAAA7C,QAIA6C,IAAArF,EAAAkJ,WAKA7D,IAAA,SAAA3D,GACA,MAAAX,IAAAf,EAAAqJ,WAAAtI,IAAAf,EAAAqJ,WAAA3H,GACA1B,EAAA2B,SAAAZ,EAAAW,GACAA,IAOA1C,KAAAsB,OAAAD,EAAAkL,UAAA7F,EAAAL,IAAA7C,SAAA,GACAxD,KAAAoB,SAAAC,EAAAkL,UAAAtJ,GAAA,GAEAjD,KAAA+B,aACA/B,KAAA2G,iBACA3G,KAAAuB,UAAAoE,EACA3F,KAAAiC,OA8EA,QAAAmM,KACApO,KAAAuC,cAAA,EACAvC,KAAAyC,gBAAA,EACAzC,KAAA0C,OAAA,KACA1C,KAAA6C,aAAA,KACA7C,KAAA8C,eAAA,KACA9C,KAAA+C,KAAA,KAyZA,QAAAmL,GAAAJ,GACA,GAAAC,GAAAD,CACA,iBAAAA,KACAC,EAAAjJ,KAAAkJ,MAAAF,EAAAhD,QAAA,WAAsD,KAGtD,IAAArE,GAAAzF,EAAAC,OAAA8M,EAAA,WACAE,EAAAjN,EAAAC,OAAA8M,EAAA,WAEA,IAAAtH,GAAAzG,KAAA4B,SACA,SAAAwC,OAAA,wBAAAqC,EAGAzG,MAAAoB,SAAA,GAAAC,GACArB,KAAAsB,OAAA,GAAAD,EAEA,IAAAgN,IACA/L,KAAA,GACAE,OAAA,EAEAxC,MAAAsO,UAAAL,EAAA5H,IAAA,SAAAiF,GACA,GAAAA,EAAArB,IAGA,SAAA7F,OAAA,qDAEA,IAAAmK,GAAAvN,EAAAC,OAAAqK,EAAA,UACAkD,EAAAxN,EAAAC,OAAAsN,EAAA,QACAE,EAAAzN,EAAAC,OAAAsN,EAAA,SAEA,IAAAC,EAAAH,EAAA/L,MACAkM,IAAAH,EAAA/L,MAAAmM,EAAAJ,EAAA7L,OACA,SAAA4B,OAAA,uDAIA,OAFAiK,GAAAE,GAGAG,iBAGAnM,cAAAiM,EAAA,EACA/L,gBAAAgM,EAAA,GAEAE,SAAA,GAAA/N,GAAAI,EAAAC,OAAAqK,EAAA,WA11BA,GAAAtK,GAAAd,EAAA,GACA0O,EAAA1O,EAAA,GACAmB,EAAAnB,EAAA,GAAAmB,SACAK,EAAAxB,EAAA,GACA2O,EAAA3O,EAAA,GAAA2O,SAaAjO,GAAAiB,cAAA,SAAAiM,GACA,MAAAK,GAAAtM,cAAAiM,IAMAlN,EAAAe,UAAAC,SAAA,EAgCAhB,EAAAe,UAAAmN,oBAAA,KACAjL,OAAAkL,eAAAnO,EAAAe,UAAA,sBACAqN,IAAA,WAKA,MAJAhP,MAAA8O,qBACA9O,KAAAiP,eAAAjP,KAAAuB,UAAAvB,KAAA+B,YAGA/B,KAAA8O,uBAIAlO,EAAAe,UAAAuN,mBAAA,KACArL,OAAAkL,eAAAnO,EAAAe,UAAA,qBACAqN,IAAA,WAKA,MAJAhP,MAAAkP,oBACAlP,KAAAiP,eAAAjP,KAAAuB,UAAAvB,KAAA+B,YAGA/B,KAAAkP,sBAIAtO,EAAAe,UAAAwN,wBACA,SAAAxH,EAAAqD,GACA,GAAAvK,GAAAkH,EAAAO,OAAA8C,EACA,aAAAvK,GAAmB,MAAAA,GAQnBG,EAAAe,UAAAsN,eACA,SAAAtH,EAAAvB,GACA,SAAAhC,OAAA,6CAGAxD,EAAAwO,gBAAA,EACAxO,EAAAyO,eAAA,EAEAzO,EAAA0O,qBAAA,EACA1O,EAAA2O,kBAAA,EAkBA3O,EAAAe,UAAAO,YACA,SAAAwL,EAAA8B,EAAAC,GACA,GAGA9J,GAHA+J,EAAAF,GAAA,KACAG,EAAAF,GAAA7O,EAAAwO,eAGA,QAAAO,GACA,IAAA/O,GAAAwO,gBACAzJ,EAAA3F,KAAA4P,kBACA,MACA,KAAAhP,GAAAyO,eACA1J,EAAA3F,KAAA6P,iBACA,MACA,SACA,SAAAzL,OAAA,+BAGA,GAAArC,GAAA/B,KAAA+B,UACA4D,GAAAU,IAAA,SAAAlE,GACA,GAAAO,GAAA,OAAAP,EAAAO,OAAA,KAAA1C,KAAAoB,SAAA6L,GAAA9K,EAAAO,OAIA,OAHA,OAAAA,GAAA,MAAAX,IACAW,EAAA1B,EAAAyD,KAAA1C,EAAAW,KAGAA,SACAH,cAAAJ,EAAAI,cACAE,gBAAAN,EAAAM,gBACAI,aAAAV,EAAAU,aACAC,eAAAX,EAAAW,eACAC,KAAA,OAAAZ,EAAAY,KAAA,KAAA/C,KAAAsB,OAAA2L,GAAA9K,EAAAY,QAEK/C,MAAAkD,QAAAwK,EAAAgC,IAsBL9O,EAAAe,UAAAmO,yBACA,SAAAhP,GACA,GAAAwB,GAAAtB,EAAAC,OAAAH,EAAA,QAMAiP,GACArN,OAAA1B,EAAAC,OAAAH,EAAA,UACA+B,aAAAP,EACAQ,eAAA9B,EAAAC,OAAAH,EAAA,YAMA,IAHA,MAAAd,KAAA+B,aACAgO,EAAArN,OAAA1B,EAAA2B,SAAA3C,KAAA+B,WAAAgO,EAAArN,UAEA1C,KAAAoB,SAAAqC,IAAAsM,EAAArN,QACA,QAEAqN,GAAArN,OAAA1C,KAAAoB,SAAA6E,QAAA8J,EAAArN,OAEA,IAAAiD,MAEAqF,EAAAhL,KAAAgQ,aAAAD,EACA/P,KAAA6P,kBACA,eACA,iBACA7O,EAAAyK,2BACAmD,EAAAW,kBACA,IAAAvE,GAAA,GACA,GAAA7I,GAAAnC,KAAA6P,kBAAA7E,EAEA,IAAAiF,SAAAnP,EAAA0B,OAOA,IANA,GAAAK,GAAAV,EAAAU,aAMAV,KAAAU,kBACA8C,EAAAqH,MACA1K,KAAAtB,EAAAC,OAAAkB,EAAA,sBACAK,OAAAxB,EAAAC,OAAAkB,EAAA,wBACA+N,WAAAlP,EAAAC,OAAAkB,EAAA,8BAGAA,EAAAnC,KAAA6P,oBAAA7E,OASA,KANA,GAAAlI,GAAAX,EAAAW,eAMAX,GACAA,EAAAU,eAAAP,GACAH,EAAAW,mBACA6C,EAAAqH,MACA1K,KAAAtB,EAAAC,OAAAkB,EAAA,sBACAK,OAAAxB,EAAAC,OAAAkB,EAAA,wBACA+N,WAAAlP,EAAAC,OAAAkB,EAAA,8BAGAA,EAAAnC,KAAA6P,oBAAA7E,GAKA,MAAArF,IAGA/F,EAAAgB,oBAmFAuN,EAAAxM,UAAAkC,OAAAC,OAAAlD,EAAAe,WACAwM,EAAAxM,UAAAgN,SAAA/N,EASAuN,EAAAtM,cACA,SAAAiM,GACA,GAAAqC,GAAAtM,OAAAC,OAAAqK,EAAAxM,WAEA+E,EAAAyJ,EAAA7O,OAAAD,EAAAkL,UAAAuB,EAAAxM,OAAAsE,WAAA,GACA3C,EAAAkN,EAAA/O,SAAAC,EAAAkL,UAAAuB,EAAA1M,SAAAwE,WAAA,EACAuK,GAAApO,WAAA+L,EAAA5M,YACAiP,EAAAxJ,eAAAmH,EAAA5H,wBAAAiK,EAAA/O,SAAAwE,UACAuK,EAAApO,YACAoO,EAAAlO,KAAA6L,EAAA/M,KAWA,QAJAqP,GAAAtC,EAAAvM,UAAAqE,UAAAsF,QACAmF,EAAAF,EAAArB,uBACAwB,EAAAH,EAAAjB,sBAEArJ,EAAA,EAAA5B,EAAAmM,EAAAnM,OAAsDA,EAAA4B,EAAYA,IAAA,CAClE,GAAA0K,GAAAH,EAAAvK,GACA2K,EAAA,GAAApC,EACAoC,GAAAjO,cAAAgO,EAAAhO,cACAiO,EAAA/N,gBAAA8N,EAAA9N,gBAEA8N,EAAA7N,SACA8N,EAAA9N,OAAAO,EAAAgD,QAAAsK,EAAA7N,QACA8N,EAAA3N,aAAA0N,EAAA1N,aACA2N,EAAA1N,eAAAyN,EAAAzN,eAEAyN,EAAAxN,OACAyN,EAAAzN,KAAA2D,EAAAT,QAAAsK,EAAAxN,OAGAuN,EAAAtD,KAAAwD,IAGAH,EAAArD,KAAAwD,GAKA,MAFA3B,GAAAsB,EAAAjB,mBAAAlO,EAAAyK,4BAEA0E,GAMAhC,EAAAxM,UAAAC,SAAA,EAKAiC,OAAAkL,eAAAZ,EAAAxM,UAAA,WACAqN,IAAA,WACA,MAAAhP,MAAAoB,SAAAwE,UAAAS,IAAA,SAAAiF,GACA,aAAAtL,KAAA+B,WAAAf,EAAAyD,KAAAzE,KAAA+B,WAAAuJ,MACKtL,SAqBLmO,EAAAxM,UAAAsN,eACA,SAAAtH,EAAAvB,GAeA,IAdA,GAYAjE,GAAAsO,EAAAC,EAAAC,EAAAxI,EAZA5F,EAAA,EACA6C,EAAA,EACAG,EAAA,EACAD,EAAA,EACAG,EAAA,EACAD,EAAA,EACAvB,EAAA0D,EAAA1D,OACA+G,EAAA,EACA4F,KACAC,KACAC,KACAV,KAGAnM,EAAA+G,GACA,SAAArD,EAAAO,OAAA8C,GACAzI,IACAyI,IACA5F,EAAA,MAEA,UAAAuC,EAAAO,OAAA8C,GACAA,QAEA,CASA,IARA7I,EAAA,GAAAiM,GACAjM,EAAAI,gBAOAoO,EAAA3F,EAAyB/G,EAAA0M,IACzB3Q,KAAAmP,wBAAAxH,EAAAgJ,GADuCA,KAQvC,GAHAF,EAAA9I,EAAAuD,MAAAF,EAAA2F,GAEAD,EAAAE,EAAAH,GAEAzF,GAAAyF,EAAAxM,WACS,CAET,IADAyM,KACAC,EAAA3F,GACAtJ,EAAAgG,OAAAC,EAAAqD,EAAA6F,GACA1I,EAAA0I,EAAA1I,MACA6C,EAAA6F,EAAAzI,KACAsI,EAAA1D,KAAA7E,EAGA,QAAAuI,EAAAzM,OACA,SAAAG,OAAA,yCAGA,QAAAsM,EAAAzM,OACA,SAAAG,OAAA,yCAGAwM,GAAAH,GAAAC,EAIAvO,EAAAM,gBAAA2C,EAAAsL,EAAA,GACAtL,EAAAjD,EAAAM,gBAEAiO,EAAAzM,OAAA,IAEA9B,EAAAO,OAAA+C,EAAAiL,EAAA,GACAjL,GAAAiL,EAAA,GAGAvO,EAAAU,aAAA0C,EAAAmL,EAAA,GACAnL,EAAApD,EAAAU,aAEAV,EAAAU,cAAA,EAGAV,EAAAW,eAAAwC,EAAAoL,EAAA,GACApL,EAAAnD,EAAAW,eAEA4N,EAAAzM,OAAA,IAEA9B,EAAAY,KAAAyC,EAAAkL,EAAA,GACAlL,GAAAkL,EAAA,KAIAN,EAAApD,KAAA7K,GACA,gBAAAA,GAAAU,cACAiO,EAAA9D,KAAA7K,GAKA0M,EAAAuB,EAAApP,EAAA8K,qCACA9L,KAAA8O,oBAAAsB,EAEAvB,EAAAiC,EAAA9P,EAAAyK,4BACAzL,KAAAkP,mBAAA4B,GAOA3C,EAAAxM,UAAAqO,aACA,SAAAe,EAAAC,EAAAC,EACAC,EAAAC,EAAAC,GAMA,GAAAL,EAAAE,IAAA,EACA,SAAAzI,WAAA,gDACAuI,EAAAE,GAEA,IAAAF,EAAAG,GAAA,EACA,SAAA1I,WAAA,kDACAuI,EAAAG,GAGA,OAAAtC,GAAAyC,OAAAN,EAAAC,EAAAG,EAAAC,IAOAjD,EAAAxM,UAAA2P,mBACA,WACA,OAAAtG,GAAA,EAAuBA,EAAAhL,KAAA4P,mBAAA3L,SAAwC+G,EAAA,CAC/D,GAAA7I,GAAAnC,KAAA4P,mBAAA5E,EAMA,IAAAA,EAAA,EAAAhL,KAAA4P,mBAAA3L,OAAA,CACA,GAAAsN,GAAAvR,KAAA4P,mBAAA5E,EAAA,EAEA,IAAA7I,EAAAI,gBAAAgP,EAAAhP,cAAA,CACAJ,EAAAqP,oBAAAD,EAAA9O,gBAAA,CACA,WAKAN,EAAAqP,oBAAAC,MAwBAtD,EAAAxM,UAAA6C,oBACA,SAAA1D,GACA,GAAAiP,IACAxN,cAAAvB,EAAAC,OAAAH,EAAA,QACA2B,gBAAAzB,EAAAC,OAAAH,EAAA,WAGAkK,EAAAhL,KAAAgQ,aACAD,EACA/P,KAAA4P,mBACA,gBACA,kBACA5O,EAAA8K,oCACA9K,EAAAC,OAAAH,EAAA,OAAAF,EAAA0O,sBAGA,IAAAtE,GAAA,GACA,GAAA7I,GAAAnC,KAAA4P,mBAAA5E,EAEA,IAAA7I,EAAAI,gBAAAwN,EAAAxN,cAAA,CACA,GAAAG,GAAA1B,EAAAC,OAAAkB,EAAA,cACA,QAAAO,IACAA,EAAA1C,KAAAoB,SAAA6L,GAAAvK,GACA,MAAA1C,KAAA+B,aACAW,EAAA1B,EAAAyD,KAAAzE,KAAA+B,WAAAW,IAGA,IAAAK,GAAA/B,EAAAC,OAAAkB,EAAA,YAIA,OAHA,QAAAY,IACAA,EAAA/C,KAAAsB,OAAA2L,GAAAlK,KAGAL,SACAJ,KAAAtB,EAAAC,OAAAkB,EAAA,qBACAK,OAAAxB,EAAAC,OAAAkB,EAAA,uBACAY,SAKA,OACAL,OAAA,KACAJ,KAAA,KACAE,OAAA,KACAO,KAAA,OAQAoL,EAAAxM,UAAA+P,wBACA,WACA,MAAA1R,MAAA2G,eAGA3G,KAAA2G,eAAA1C,QAAAjE,KAAAoB,SAAAuL,SACA3M,KAAA2G,eAAAgL,KAAA,SAAAC,GAA+C,aAAAA,KAH/C,GAWAzD,EAAAxM,UAAA0B,iBACA,SAAAuB,EAAAiN,GACA,IAAA7R,KAAA2G,eACA,WAOA,IAJA,MAAA3G,KAAA+B,aACA6C,EAAA5D,EAAA2B,SAAA3C,KAAA+B,WAAA6C,IAGA5E,KAAAoB,SAAAqC,IAAAmB,GACA,MAAA5E,MAAA2G,eAAA3G,KAAAoB,SAAA6E,QAAArB,GAGA,IAAAqF,EACA,UAAAjK,KAAA+B,aACAkI,EAAAjJ,EAAAsI,SAAAtJ,KAAA+B,aAAA,CAKA,GAAA+P,GAAAlN,EAAAkG,QAAA,gBACA,YAAAb,EAAAP,QACA1J,KAAAoB,SAAAqC,IAAAqO,GACA,MAAA9R,MAAA2G,eAAA3G,KAAAoB,SAAA6E,QAAA6L,GAGA,MAAA7H,EAAAH,MAAA,KAAAG,EAAAH,OACA9J,KAAAoB,SAAAqC,IAAA,IAAAmB,GACA,MAAA5E,MAAA2G,eAAA3G,KAAAoB,SAAA6E,QAAA,IAAArB,IAQA,GAAAiN,EACA,WAGA,UAAAzN,OAAA,IAAAQ,EAAA,+BAuBAuJ,EAAAxM,UAAAoQ,qBACA,SAAAjR,GACA,GAAA4B,GAAA1B,EAAAC,OAAAH,EAAA,SAIA,IAHA,MAAAd,KAAA+B,aACAW,EAAA1B,EAAA2B,SAAA3C,KAAA+B,WAAAW,KAEA1C,KAAAoB,SAAAqC,IAAAf,GACA,OACAJ,KAAA,KACAE,OAAA,KACA0N,WAAA,KAGAxN,GAAA1C,KAAAoB,SAAA6E,QAAAvD,EAEA,IAAAqN,IACArN,SACAG,aAAA7B,EAAAC,OAAAH,EAAA,QACAgC,eAAA9B,EAAAC,OAAAH,EAAA,WAGAkK,EAAAhL,KAAAgQ,aACAD,EACA/P,KAAA6P,kBACA,eACA,iBACA7O,EAAAyK,2BACAzK,EAAAC,OAAAH,EAAA,OAAAF,EAAA0O,sBAGA,IAAAtE,GAAA,GACA,GAAA7I,GAAAnC,KAAA6P,kBAAA7E,EAEA,IAAA7I,EAAAO,SAAAqN,EAAArN,OACA,OACAJ,KAAAtB,EAAAC,OAAAkB,EAAA,sBACAK,OAAAxB,EAAAC,OAAAkB,EAAA,wBACA+N,WAAAlP,EAAAC,OAAAkB,EAAA,6BAKA,OACAG,KAAA,KACAE,OAAA,KACA0N,WAAA,OAIAtQ,EAAAuO,yBA+FAD,EAAAvM,UAAAkC,OAAAC,OAAAlD,EAAAe,WACAuM,EAAAvM,UAAAqQ,YAAApR,EAKAsN,EAAAvM,UAAAC,SAAA,EAKAiC,OAAAkL,eAAAb,EAAAvM,UAAA,WACAqN,IAAA,WAEA,OADA/L,MACA4C,EAAA,EAAmBA,EAAA7F,KAAAsO,UAAArK,OAA2B4B,IAC9C,OAAAoM,GAAA,EAAqBA,EAAAjS,KAAAsO,UAAAzI,GAAA8I,SAAA1L,QAAAgB,OAA+CgO,IACpEhP,EAAA+J,KAAAhN,KAAAsO,UAAAzI,GAAA8I,SAAA1L,QAAAgP,GAGA,OAAAhP,MAmBAiL,EAAAvM,UAAA6C,oBACA,SAAA1D,GACA,GAAAiP,IACAxN,cAAAvB,EAAAC,OAAAH,EAAA,QACA2B,gBAAAzB,EAAAC,OAAAH,EAAA,WAKAoR,EAAAtD,EAAAyC,OAAAtB,EAAA/P,KAAAsO,UACA,SAAAyB,EAAAoC,GACA,GAAAtG,GAAAkE,EAAAxN,cAAA4P,EAAAzD,gBAAAnM,aACA,OAAAsJ,GACAA,EAGAkE,EAAAtN,gBACA0P,EAAAzD,gBAAAjM,kBAEA0P,EAAAnS,KAAAsO,UAAA4D,EAEA,OAAAC,GASAA,EAAAxD,SAAAnK,qBACAlC,KAAAyN,EAAAxN,eACA4P,EAAAzD,gBAAAnM,cAAA,GACAC,OAAAuN,EAAAtN,iBACA0P,EAAAzD,gBAAAnM,gBAAAwN,EAAAxN,cACA4P,EAAAzD,gBAAAjM,gBAAA,EACA,GACA2P,KAAAtR,EAAAsR,QAdA1P,OAAA,KACAJ,KAAA,KACAE,OAAA,KACAO,KAAA,OAmBAmL,EAAAvM,UAAA+P,wBACA,WACA,MAAA1R,MAAAsO,UAAA+D,MAAA,SAAA/G,GACA,MAAAA,GAAAqD,SAAA+C,6BASAxD,EAAAvM,UAAA0B,iBACA,SAAAuB,EAAAiN,GACA,OAAAhM,GAAA,EAAmBA,EAAA7F,KAAAsO,UAAArK,OAA2B4B,IAAA,CAC9C,GAAAsM,GAAAnS,KAAAsO,UAAAzI,GAEAzC,EAAA+O,EAAAxD,SAAAtL,iBAAAuB,GAAA,EACA,IAAAxB,EACA,MAAAA,GAGA,GAAAyO,EACA,WAGA,UAAAzN,OAAA,IAAAQ,EAAA,+BAkBAsJ,EAAAvM,UAAAoQ,qBACA,SAAAjR,GACA,OAAA+E,GAAA,EAAmBA,EAAA7F,KAAAsO,UAAArK,OAA2B4B,IAAA,CAC9C,GAAAsM,GAAAnS,KAAAsO,UAAAzI,EAIA,SAAAsM,EAAAxD,SAAA1L,QAAAgD,QAAAjF,EAAAC,OAAAH,EAAA,YAGA,GAAAwR,GAAAH,EAAAxD,SAAAoD,qBAAAjR,EACA,IAAAwR,EAAA,CACA,GAAAC,IACAjQ,KAAAgQ,EAAAhQ,MACA6P,EAAAzD,gBAAAnM,cAAA,GACAC,OAAA8P,EAAA9P,QACA2P,EAAAzD,gBAAAnM,gBAAA+P,EAAAhQ,KACA6P,EAAAzD,gBAAAjM,gBAAA,EACA,GAEA,OAAA8P,KAIA,OACAjQ,KAAA,KACAE,OAAA,OASA0L,EAAAvM,UAAAsN,eACA,SAAAtH,EAAAvB,GACApG,KAAA8O,uBACA9O,KAAAkP,qBACA,QAAArJ,GAAA,EAAmBA,EAAA7F,KAAAsO,UAAArK,OAA2B4B,IAG9C,OAFAsM,GAAAnS,KAAAsO,UAAAzI,GACA2M,EAAAL,EAAAxD,SAAAiB,mBACAqC,EAAA,EAAqBA,EAAAO,EAAAvO,OAA4BgO,IAAA,CACjD,GAAA9P,GAAAqQ,EAAAP,GAEAvP,EAAAyP,EAAAxD,SAAAvN,SAAA6L,GAAA9K,EAAAO,OACA,QAAAyP,EAAAxD,SAAA5M,aACAW,EAAA1B,EAAAyD,KAAA0N,EAAAxD,SAAA5M,WAAAW,IAEA1C,KAAAoB,SAAAsC,IAAAhB,GACAA,EAAA1C,KAAAoB,SAAA6E,QAAAvD,EAEA,IAAAK,GAAAoP,EAAAxD,SAAArN,OAAA2L,GAAA9K,EAAAY,KACA/C,MAAAsB,OAAAoC,IAAAX,GACAA,EAAA/C,KAAAsB,OAAA2E,QAAAlD,EAMA,IAAA0P,IACA/P,SACAH,cAAAJ,EAAAI,eACA4P,EAAAzD,gBAAAnM,cAAA,GACAE,gBAAAN,EAAAM,iBACA0P,EAAAzD,gBAAAnM,gBAAAJ,EAAAI,cACA4P,EAAAzD,gBAAAjM,gBAAA,EACA,GACAI,aAAAV,EAAAU,aACAC,eAAAX,EAAAW,eACAC,OAGA/C,MAAA8O,oBAAA9B,KAAAyF,GACA,gBAAAA,GAAA5P,cACA7C,KAAAkP,mBAAAlC,KAAAyF,GAKA5D,EAAA7O,KAAA8O,oBAAA9N,EAAA8K,qCACA+C,EAAA7O,KAAAkP,mBAAAlO,EAAAyK,6BAGA7L,EAAAsO,4BT0yCM,SAASrO,EAAQD,GU50EvB,QAAA8S,GAAAC,EAAAC,EAAA7B,EAAA8B,EAAAC,EAAA1B,GAUA,GAAA2B,GAAAC,KAAAC,OAAAL,EAAAD,GAAA,GAAAA,EACA9G,EAAAiH,EAAA/B,EAAA8B,EAAAE,IAAA,EACA,YAAAlH,EAEAkH,EAEAlH,EAAA,EAEA+G,EAAAG,EAAA,EAEAL,EAAAK,EAAAH,EAAA7B,EAAA8B,EAAAC,EAAA1B,GAKAA,GAAAxR,EAAA2P,kBACAqD,EAAAC,EAAA5O,OAAA2O,EAAA,GAEAG,EAKAA,EAAAJ,EAAA,EAEAD,EAAAC,EAAAI,EAAAhC,EAAA8B,EAAAC,EAAA1B,GAIAA,GAAAxR,EAAA2P,kBACAwD,EAEA,EAAAJ,EAAA,GAAAA,EA1DA/S,EAAA0P,qBAAA,EACA1P,EAAA2P,kBAAA,EAgFA3P,EAAAyR,OAAA,SAAAN,EAAA8B,EAAAC,EAAA1B,GACA,OAAAyB,EAAA5O,OACA,QAGA,IAAA+G,GAAA0H,EAAA,GAAAG,EAAA5O,OAAA8M,EAAA8B,EACAC,EAAA1B,GAAAxR,EAAA0P,qBACA,MAAAtE,EACA,QAMA,MAAAA,EAAA,MACA,IAAA8H,EAAAD,EAAA7H,GAAA6H,EAAA7H,EAAA,UAGAA,CAGA,OAAAA,KV22EM,SAASnL,EAAQD,GW77EvB,QAAAsT,GAAAC,EAAAC,EAAAC,GACA,GAAAxC,GAAAsC,EAAAC,EACAD,GAAAC,GAAAD,EAAAE,GACAF,EAAAE,GAAAxC,EAWA,QAAAyC,GAAAC,EAAAC,GACA,MAAAR,MAAAS,MAAAF,EAAAP,KAAAU,UAAAF,EAAAD,IAeA,QAAAI,GAAAR,EAAAS,EAAAlT,EAAAmT,GAKA,GAAAA,EAAAnT,EAAA,CAYA,GAAAoT,GAAAR,EAAA5S,EAAAmT,GACAhO,EAAAnF,EAAA,CAEAwS,GAAAC,EAAAW,EAAAD,EASA,QARAE,GAAAZ,EAAAU,GAQA5B,EAAAvR,EAAmBmT,EAAA5B,EAAOA,IAC1B2B,EAAAT,EAAAlB,GAAA8B,IAAA,IACAlO,GAAA,EACAqN,EAAAC,EAAAtN,EAAAoM,GAIAiB,GAAAC,EAAAtN,EAAA,EAAAoM,EACA,IAAA+B,GAAAnO,EAAA,CAIA8N,GAAAR,EAAAS,EAAAlT,EAAAsT,EAAA,GACAL,EAAAR,EAAAS,EAAAI,EAAA,EAAAH,IAYAjU,EAAAiP,UAAA,SAAAsE,EAAAS,GACAD,EAAAR,EAAAS,EAAA,EAAAT,EAAAlP,OAAA,KXg+EM,SAASpE,EAAQD,EAASM,GY9iFhC,QAAAW,GAAAoT,EAAAC,EAAAtP,EAAAuP,EAAAtP,GACA7E,KAAAoU,YACApU,KAAAqU,kBACArU,KAAAsC,KAAA,MAAA2R,EAAA,KAAAA,EACAjU,KAAAwC,OAAA,MAAA0R,EAAA,KAAAA,EACAlU,KAAA0C,OAAA,MAAAkC,EAAA,KAAAA,EACA5E,KAAA+C,KAAA,MAAA8B,EAAA,KAAAA,EACA7E,KAAAsU,IAAA,EACA,MAAAH,GAAAnU,KAAA0D,IAAAyQ,GAnCA,GAAAxT,GAAAT,EAAA,GAAAS,mBACAK,EAAAd,EAAA,GAIAqU,EAAA,UAGAC,EAAA,GAKAF,EAAA,oBAiCAzT,GAAA4T,wBACA,SAAAC,EAAA5S,EAAA6S,GAyFA,QAAAC,GAAAzS,EAAA0S,GACA,UAAA1S,GAAA8N,SAAA9N,EAAAO,OACAoS,EAAApR,IAAAmR,OACO,CACP,GAAAnS,GAAAiS,EACA3T,EAAAyD,KAAAkQ,EAAAxS,EAAAO,QACAP,EAAAO,MACAoS,GAAApR,IAAA,GAAA7C,GAAAsB,EAAAU,aACAV,EAAAW,eACAJ,EACAmS,EACA1S,EAAAY,QAjGA,GAAA+R,GAAA,GAAAjU,GAMAkU,EAAAL,EAAApM,MAAAiM,GACAS,EAAA,WACA,GAAAC,GAAAF,EAAA/M,QAEAkN,EAAAH,EAAA/M,SAAA,EACA,OAAAiN,GAAAC,GAIAC,EAAA,EAAA3D,EAAA,EAKA4D,EAAA,IAgEA,OA9DAtT,GAAAI,YAAA,SAAAC,GACA,UAAAiT,EAAA,CAGA,KAAAD,EAAAhT,EAAAI,eAMS,CAIT,GAAA8S,GAAAN,EAAA,GACAF,EAAAQ,EAAAjK,OAAA,EAAAjJ,EAAAM,gBACA+O,EAOA,OANAuD,GAAA,GAAAM,EAAAjK,OAAAjJ,EAAAM,gBACA+O,GACAA,EAAArP,EAAAM,gBACAmS,EAAAQ,EAAAP,QAEAO,EAAAjT,GAhBAyS,EAAAQ,EAAAJ,KACAG,IACA3D,EAAA,EAqBA,KAAA2D,EAAAhT,EAAAI,eACAuS,EAAApR,IAAAsR,KACAG,GAEA,IAAA3D,EAAArP,EAAAM,gBAAA,CACA,GAAA4S,GAAAN,EAAA,EACAD,GAAApR,IAAA2R,EAAAjK,OAAA,EAAAjJ,EAAAM,kBACAsS,EAAA,GAAAM,EAAAjK,OAAAjJ,EAAAM,iBACA+O,EAAArP,EAAAM,gBAEA2S,EAAAjT,GACKnC,MAEL+U,EAAA9Q,OAAA,IACAmR,GAEAR,EAAAQ,EAAAJ,KAGAF,EAAApR,IAAAqR,EAAAtQ,KAAA,MAIA3C,EAAAmB,QAAAC,QAAA,SAAAC,GACA,GAAAC,GAAAtB,EAAAuB,iBAAAF,EACA,OAAAC,IACA,MAAAuR,IACAxR,EAAAnC,EAAAyD,KAAAkQ,EAAAxR,IAEA2R,EAAAxR,iBAAAH,EAAAC,MAIA0R,GAwBAjU,EAAAc,UAAA+B,IAAA,SAAA4R,GACA,GAAAnK,MAAAoK,QAAAD,GACAA,EAAApS,QAAA,SAAAsS,GACAxV,KAAA0D,IAAA8R,IACKxV,UAEL,KAAAsV,EAAAhB,IAAA,gBAAAgB,GAMA,SAAA9M,WACA,8EAAA8M,EANAA,IACAtV,KAAAoU,SAAApH,KAAAsI,GAQA,MAAAtV,OASAa,EAAAc,UAAA8T,QAAA,SAAAH,GACA,GAAAnK,MAAAoK,QAAAD,GACA,OAAAzP,GAAAyP,EAAArR,OAAA,EAAiC4B,GAAA,EAAQA,IACzC7F,KAAAyV,QAAAH,EAAAzP,QAGA,KAAAyP,EAAAhB,IAAA,gBAAAgB,GAIA,SAAA9M,WACA,8EAAA8M,EAJAtV,MAAAoU,SAAAsB,QAAAJ,GAOA,MAAAtV,OAUAa,EAAAc,UAAAgU,KAAA,SAAAC,GAEA,OADAJ,GACA3P,EAAA,EAAAC,EAAA9F,KAAAoU,SAAAnQ,OAA6C6B,EAAAD,EAASA,IACtD2P,EAAAxV,KAAAoU,SAAAvO,GACA2P,EAAAlB,GACAkB,EAAAG,KAAAC,GAGA,KAAAJ,GACAI,EAAAJ,GAAoB9S,OAAA1C,KAAA0C,OACpBJ,KAAAtC,KAAAsC,KACAE,OAAAxC,KAAAwC,OACAO,KAAA/C,KAAA+C,QAYAlC,EAAAc,UAAA8C,KAAA,SAAAoR,GACA,GAAAC,GACAjQ,EACAC,EAAA9F,KAAAoU,SAAAnQ,MACA,IAAA6B,EAAA,GAEA,IADAgQ,KACAjQ,EAAA,EAAeC,EAAA,EAAAD,EAAWA,IAC1BiQ,EAAA9I,KAAAhN,KAAAoU,SAAAvO,IACAiQ,EAAA9I,KAAA6I,EAEAC,GAAA9I,KAAAhN,KAAAoU,SAAAvO,IACA7F,KAAAoU,SAAA0B,EAEA,MAAA9V,OAUAa,EAAAc,UAAAoU,aAAA,SAAAC,EAAAC,GACA,GAAAC,GAAAlW,KAAAoU,SAAApU,KAAAoU,SAAAnQ,OAAA,EAUA,OATAiS,GAAA5B,GACA4B,EAAAH,aAAAC,EAAAC,GAEA,gBAAAC,GACAlW,KAAAoU,SAAApU,KAAAoU,SAAAnQ,OAAA,GAAAiS,EAAApL,QAAAkL,EAAAC,GAGAjW,KAAAoU,SAAApH,KAAA,GAAAlC,QAAAkL,EAAAC,IAEAjW,MAUAa,EAAAc,UAAA2B,iBACA,SAAAK,EAAAC,GACA5D,KAAAqU,eAAArT,EAAA+C,YAAAJ,IAAAC,GASA/C,EAAAc,UAAAwU,mBACA,SAAAP,GACA,OAAA/P,GAAA,EAAAC,EAAA9F,KAAAoU,SAAAnQ,OAA+C6B,EAAAD,EAASA,IACxD7F,KAAAoU,SAAAvO,GAAAyO,IACAtU,KAAAoU,SAAAvO,GAAAsQ,mBAAAP,EAKA,QADA3S,GAAAY,OAAAG,KAAAhE,KAAAqU,gBACAxO,EAAA,EAAAC,EAAA7C,EAAAgB,OAAyC6B,EAAAD,EAASA,IAClD+P,EAAA5U,EAAAwK,cAAAvI,EAAA4C,IAAA7F,KAAAqU,eAAApR,EAAA4C,MAQAhF,EAAAc,UAAAiF,SAAA,WACA,GAAA6J,GAAA,EAIA,OAHAzQ,MAAA2V,KAAA,SAAAH,GACA/E,GAAA+E,IAEA/E,GAOA5P,EAAAc,UAAAyU,sBAAA,SAAAtV,GACA,GAAAuB,IACAwS,KAAA,GACAvS,KAAA,EACAE,OAAA,GAEA6D,EAAA,GAAA1F,GAAAG,GACAuV,GAAA,EACAC,EAAA,KACAC,EAAA,KACAC,EAAA,KACAC,EAAA,IAqEA,OApEAzW,MAAA2V,KAAA,SAAAH,EAAA5S,GACAP,EAAAwS,MAAAW,EACA,OAAA5S,EAAAF,QACA,OAAAE,EAAAN,MACA,OAAAM,EAAAJ,SACA8T,IAAA1T,EAAAF,QACA6T,IAAA3T,EAAAN,MACAkU,IAAA5T,EAAAJ,QACAiU,IAAA7T,EAAAG,OACAsD,EAAArD,YACAN,OAAAE,EAAAF,OACAE,UACAN,KAAAM,EAAAN,KACAE,OAAAI,EAAAJ,QAEAH,WACAC,KAAAD,EAAAC,KACAE,OAAAH,EAAAG,QAEAO,KAAAH,EAAAG,OAGAuT,EAAA1T,EAAAF,OACA6T,EAAA3T,EAAAN,KACAkU,EAAA5T,EAAAJ,OACAiU,EAAA7T,EAAAG,KACAsT,GAAA,GACKA,IACLhQ,EAAArD,YACAX,WACAC,KAAAD,EAAAC,KACAE,OAAAH,EAAAG,UAGA8T,EAAA,KACAD,GAAA,EAEA,QAAAtJ,GAAA,EAAA9I,EAAAuR,EAAAvR,OAA4CA,EAAA8I,EAAcA,IAC1DyI,EAAAvN,WAAA8E,KAAAyH,GACAnS,EAAAC,OACAD,EAAAG,OAAA,EAEAuK,EAAA,IAAA9I,GACAqS,EAAA,KACAD,GAAA,GACSA,GACThQ,EAAArD,YACAN,OAAAE,EAAAF,OACAE,UACAN,KAAAM,EAAAN,KACAE,OAAAI,EAAAJ,QAEAH,WACAC,KAAAD,EAAAC,KACAE,OAAAH,EAAAG,QAEAO,KAAAH,EAAAG,QAIAV,EAAAG,WAIAxC,KAAAmW,mBAAA,SAAAhT,EAAAuT,GACArQ,EAAA/C,iBAAAH,EAAAuT,MAGU7B,KAAAxS,EAAAwS,KAAAxO,QAGVzG,EAAAiB","file":"source-map.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"sourceMap\"] = factory();\n\telse\n\t\troot[\"sourceMap\"] = factory();\n})(this, function() {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/","(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"sourceMap\"] = factory();\n\telse\n\t\troot[\"sourceMap\"] = factory();\n})(this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/*\n\t * Copyright 2009-2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE.txt or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\texports.SourceMapGenerator = __webpack_require__(1).SourceMapGenerator;\n\texports.SourceMapConsumer = __webpack_require__(7).SourceMapConsumer;\n\texports.SourceNode = __webpack_require__(10).SourceNode;\n\n\n/***/ },\n/* 1 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\t\n\tvar base64VLQ = __webpack_require__(2);\n\tvar util = __webpack_require__(4);\n\tvar ArraySet = __webpack_require__(5).ArraySet;\n\tvar MappingList = __webpack_require__(6).MappingList;\n\t\n\t/**\n\t * An instance of the SourceMapGenerator represents a source map which is\n\t * being built incrementally. You may pass an object with the following\n\t * properties:\n\t *\n\t * - file: The filename of the generated source.\n\t * - sourceRoot: A root for all relative URLs in this source map.\n\t */\n\tfunction SourceMapGenerator(aArgs) {\n\t if (!aArgs) {\n\t aArgs = {};\n\t }\n\t this._file = util.getArg(aArgs, 'file', null);\n\t this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);\n\t this._skipValidation = util.getArg(aArgs, 'skipValidation', false);\n\t this._sources = new ArraySet();\n\t this._names = new ArraySet();\n\t this._mappings = new MappingList();\n\t this._sourcesContents = null;\n\t}\n\t\n\tSourceMapGenerator.prototype._version = 3;\n\t\n\t/**\n\t * Creates a new SourceMapGenerator based on a SourceMapConsumer\n\t *\n\t * @param aSourceMapConsumer The SourceMap.\n\t */\n\tSourceMapGenerator.fromSourceMap =\n\t function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {\n\t var sourceRoot = aSourceMapConsumer.sourceRoot;\n\t var generator = new SourceMapGenerator({\n\t file: aSourceMapConsumer.file,\n\t sourceRoot: sourceRoot\n\t });\n\t aSourceMapConsumer.eachMapping(function (mapping) {\n\t var newMapping = {\n\t generated: {\n\t line: mapping.generatedLine,\n\t column: mapping.generatedColumn\n\t }\n\t };\n\t\n\t if (mapping.source != null) {\n\t newMapping.source = mapping.source;\n\t if (sourceRoot != null) {\n\t newMapping.source = util.relative(sourceRoot, newMapping.source);\n\t }\n\t\n\t newMapping.original = {\n\t line: mapping.originalLine,\n\t column: mapping.originalColumn\n\t };\n\t\n\t if (mapping.name != null) {\n\t newMapping.name = mapping.name;\n\t }\n\t }\n\t\n\t generator.addMapping(newMapping);\n\t });\n\t aSourceMapConsumer.sources.forEach(function (sourceFile) {\n\t var content = aSourceMapConsumer.sourceContentFor(sourceFile);\n\t if (content != null) {\n\t generator.setSourceContent(sourceFile, content);\n\t }\n\t });\n\t return generator;\n\t };\n\t\n\t/**\n\t * Add a single mapping from original source line and column to the generated\n\t * source's line and column for this source map being created. The mapping\n\t * object should have the following properties:\n\t *\n\t * - generated: An object with the generated line and column positions.\n\t * - original: An object with the original line and column positions.\n\t * - source: The original source file (relative to the sourceRoot).\n\t * - name: An optional original token name for this mapping.\n\t */\n\tSourceMapGenerator.prototype.addMapping =\n\t function SourceMapGenerator_addMapping(aArgs) {\n\t var generated = util.getArg(aArgs, 'generated');\n\t var original = util.getArg(aArgs, 'original', null);\n\t var source = util.getArg(aArgs, 'source', null);\n\t var name = util.getArg(aArgs, 'name', null);\n\t\n\t if (!this._skipValidation) {\n\t this._validateMapping(generated, original, source, name);\n\t }\n\t\n\t if (source != null) {\n\t source = String(source);\n\t if (!this._sources.has(source)) {\n\t this._sources.add(source);\n\t }\n\t }\n\t\n\t if (name != null) {\n\t name = String(name);\n\t if (!this._names.has(name)) {\n\t this._names.add(name);\n\t }\n\t }\n\t\n\t this._mappings.add({\n\t generatedLine: generated.line,\n\t generatedColumn: generated.column,\n\t originalLine: original != null && original.line,\n\t originalColumn: original != null && original.column,\n\t source: source,\n\t name: name\n\t });\n\t };\n\t\n\t/**\n\t * Set the source content for a source file.\n\t */\n\tSourceMapGenerator.prototype.setSourceContent =\n\t function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {\n\t var source = aSourceFile;\n\t if (this._sourceRoot != null) {\n\t source = util.relative(this._sourceRoot, source);\n\t }\n\t\n\t if (aSourceContent != null) {\n\t // Add the source content to the _sourcesContents map.\n\t // Create a new _sourcesContents map if the property is null.\n\t if (!this._sourcesContents) {\n\t this._sourcesContents = Object.create(null);\n\t }\n\t this._sourcesContents[util.toSetString(source)] = aSourceContent;\n\t } else if (this._sourcesContents) {\n\t // Remove the source file from the _sourcesContents map.\n\t // If the _sourcesContents map is empty, set the property to null.\n\t delete this._sourcesContents[util.toSetString(source)];\n\t if (Object.keys(this._sourcesContents).length === 0) {\n\t this._sourcesContents = null;\n\t }\n\t }\n\t };\n\t\n\t/**\n\t * Applies the mappings of a sub-source-map for a specific source file to the\n\t * source map being generated. Each mapping to the supplied source file is\n\t * rewritten using the supplied source map. Note: The resolution for the\n\t * resulting mappings is the minimium of this map and the supplied map.\n\t *\n\t * @param aSourceMapConsumer The source map to be applied.\n\t * @param aSourceFile Optional. The filename of the source file.\n\t * If omitted, SourceMapConsumer's file property will be used.\n\t * @param aSourceMapPath Optional. The dirname of the path to the source map\n\t * to be applied. If relative, it is relative to the SourceMapConsumer.\n\t * This parameter is needed when the two source maps aren't in the same\n\t * directory, and the source map to be applied contains relative source\n\t * paths. If so, those relative source paths need to be rewritten\n\t * relative to the SourceMapGenerator.\n\t */\n\tSourceMapGenerator.prototype.applySourceMap =\n\t function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {\n\t var sourceFile = aSourceFile;\n\t // If aSourceFile is omitted, we will use the file property of the SourceMap\n\t if (aSourceFile == null) {\n\t if (aSourceMapConsumer.file == null) {\n\t throw new Error(\n\t 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +\n\t 'or the source map\\'s \"file\" property. Both were omitted.'\n\t );\n\t }\n\t sourceFile = aSourceMapConsumer.file;\n\t }\n\t var sourceRoot = this._sourceRoot;\n\t // Make \"sourceFile\" relative if an absolute Url is passed.\n\t if (sourceRoot != null) {\n\t sourceFile = util.relative(sourceRoot, sourceFile);\n\t }\n\t // Applying the SourceMap can add and remove items from the sources and\n\t // the names array.\n\t var newSources = new ArraySet();\n\t var newNames = new ArraySet();\n\t\n\t // Find mappings for the \"sourceFile\"\n\t this._mappings.unsortedForEach(function (mapping) {\n\t if (mapping.source === sourceFile && mapping.originalLine != null) {\n\t // Check if it can be mapped by the source map, then update the mapping.\n\t var original = aSourceMapConsumer.originalPositionFor({\n\t line: mapping.originalLine,\n\t column: mapping.originalColumn\n\t });\n\t if (original.source != null) {\n\t // Copy mapping\n\t mapping.source = original.source;\n\t if (aSourceMapPath != null) {\n\t mapping.source = util.join(aSourceMapPath, mapping.source)\n\t }\n\t if (sourceRoot != null) {\n\t mapping.source = util.relative(sourceRoot, mapping.source);\n\t }\n\t mapping.originalLine = original.line;\n\t mapping.originalColumn = original.column;\n\t if (original.name != null) {\n\t mapping.name = original.name;\n\t }\n\t }\n\t }\n\t\n\t var source = mapping.source;\n\t if (source != null && !newSources.has(source)) {\n\t newSources.add(source);\n\t }\n\t\n\t var name = mapping.name;\n\t if (name != null && !newNames.has(name)) {\n\t newNames.add(name);\n\t }\n\t\n\t }, this);\n\t this._sources = newSources;\n\t this._names = newNames;\n\t\n\t // Copy sourcesContents of applied map.\n\t aSourceMapConsumer.sources.forEach(function (sourceFile) {\n\t var content = aSourceMapConsumer.sourceContentFor(sourceFile);\n\t if (content != null) {\n\t if (aSourceMapPath != null) {\n\t sourceFile = util.join(aSourceMapPath, sourceFile);\n\t }\n\t if (sourceRoot != null) {\n\t sourceFile = util.relative(sourceRoot, sourceFile);\n\t }\n\t this.setSourceContent(sourceFile, content);\n\t }\n\t }, this);\n\t };\n\t\n\t/**\n\t * A mapping can have one of the three levels of data:\n\t *\n\t * 1. Just the generated position.\n\t * 2. The Generated position, original position, and original source.\n\t * 3. Generated and original position, original source, as well as a name\n\t * token.\n\t *\n\t * To maintain consistency, we validate that any new mapping being added falls\n\t * in to one of these categories.\n\t */\n\tSourceMapGenerator.prototype._validateMapping =\n\t function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,\n\t aName) {\n\t if (aGenerated && 'line' in aGenerated && 'column' in aGenerated\n\t && aGenerated.line > 0 && aGenerated.column >= 0\n\t && !aOriginal && !aSource && !aName) {\n\t // Case 1.\n\t return;\n\t }\n\t else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated\n\t && aOriginal && 'line' in aOriginal && 'column' in aOriginal\n\t && aGenerated.line > 0 && aGenerated.column >= 0\n\t && aOriginal.line > 0 && aOriginal.column >= 0\n\t && aSource) {\n\t // Cases 2 and 3.\n\t return;\n\t }\n\t else {\n\t throw new Error('Invalid mapping: ' + JSON.stringify({\n\t generated: aGenerated,\n\t source: aSource,\n\t original: aOriginal,\n\t name: aName\n\t }));\n\t }\n\t };\n\t\n\t/**\n\t * Serialize the accumulated mappings in to the stream of base 64 VLQs\n\t * specified by the source map format.\n\t */\n\tSourceMapGenerator.prototype._serializeMappings =\n\t function SourceMapGenerator_serializeMappings() {\n\t var previousGeneratedColumn = 0;\n\t var previousGeneratedLine = 1;\n\t var previousOriginalColumn = 0;\n\t var previousOriginalLine = 0;\n\t var previousName = 0;\n\t var previousSource = 0;\n\t var result = '';\n\t var next;\n\t var mapping;\n\t var nameIdx;\n\t var sourceIdx;\n\t\n\t var mappings = this._mappings.toArray();\n\t for (var i = 0, len = mappings.length; i < len; i++) {\n\t mapping = mappings[i];\n\t next = ''\n\t\n\t if (mapping.generatedLine !== previousGeneratedLine) {\n\t previousGeneratedColumn = 0;\n\t while (mapping.generatedLine !== previousGeneratedLine) {\n\t next += ';';\n\t previousGeneratedLine++;\n\t }\n\t }\n\t else {\n\t if (i > 0) {\n\t if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {\n\t continue;\n\t }\n\t next += ',';\n\t }\n\t }\n\t\n\t next += base64VLQ.encode(mapping.generatedColumn\n\t - previousGeneratedColumn);\n\t previousGeneratedColumn = mapping.generatedColumn;\n\t\n\t if (mapping.source != null) {\n\t sourceIdx = this._sources.indexOf(mapping.source);\n\t next += base64VLQ.encode(sourceIdx - previousSource);\n\t previousSource = sourceIdx;\n\t\n\t // lines are stored 0-based in SourceMap spec version 3\n\t next += base64VLQ.encode(mapping.originalLine - 1\n\t - previousOriginalLine);\n\t previousOriginalLine = mapping.originalLine - 1;\n\t\n\t next += base64VLQ.encode(mapping.originalColumn\n\t - previousOriginalColumn);\n\t previousOriginalColumn = mapping.originalColumn;\n\t\n\t if (mapping.name != null) {\n\t nameIdx = this._names.indexOf(mapping.name);\n\t next += base64VLQ.encode(nameIdx - previousName);\n\t previousName = nameIdx;\n\t }\n\t }\n\t\n\t result += next;\n\t }\n\t\n\t return result;\n\t };\n\t\n\tSourceMapGenerator.prototype._generateSourcesContent =\n\t function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {\n\t return aSources.map(function (source) {\n\t if (!this._sourcesContents) {\n\t return null;\n\t }\n\t if (aSourceRoot != null) {\n\t source = util.relative(aSourceRoot, source);\n\t }\n\t var key = util.toSetString(source);\n\t return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)\n\t ? this._sourcesContents[key]\n\t : null;\n\t }, this);\n\t };\n\t\n\t/**\n\t * Externalize the source map.\n\t */\n\tSourceMapGenerator.prototype.toJSON =\n\t function SourceMapGenerator_toJSON() {\n\t var map = {\n\t version: this._version,\n\t sources: this._sources.toArray(),\n\t names: this._names.toArray(),\n\t mappings: this._serializeMappings()\n\t };\n\t if (this._file != null) {\n\t map.file = this._file;\n\t }\n\t if (this._sourceRoot != null) {\n\t map.sourceRoot = this._sourceRoot;\n\t }\n\t if (this._sourcesContents) {\n\t map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);\n\t }\n\t\n\t return map;\n\t };\n\t\n\t/**\n\t * Render the source map being generated to a string.\n\t */\n\tSourceMapGenerator.prototype.toString =\n\t function SourceMapGenerator_toString() {\n\t return JSON.stringify(this.toJSON());\n\t };\n\t\n\texports.SourceMapGenerator = SourceMapGenerator;\n\n\n/***/ },\n/* 2 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t *\n\t * Based on the Base 64 VLQ implementation in Closure Compiler:\n\t * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java\n\t *\n\t * Copyright 2011 The Closure Compiler Authors. All rights reserved.\n\t * Redistribution and use in source and binary forms, with or without\n\t * modification, are permitted provided that the following conditions are\n\t * met:\n\t *\n\t * * Redistributions of source code must retain the above copyright\n\t * notice, this list of conditions and the following disclaimer.\n\t * * Redistributions in binary form must reproduce the above\n\t * copyright notice, this list of conditions and the following\n\t * disclaimer in the documentation and/or other materials provided\n\t * with the distribution.\n\t * * Neither the name of Google Inc. nor the names of its\n\t * contributors may be used to endorse or promote products derived\n\t * from this software without specific prior written permission.\n\t *\n\t * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\t * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n\t * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n\t * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n\t * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n\t * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n\t * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n\t * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n\t * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\t * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\t * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\t */\n\t\n\tvar base64 = __webpack_require__(3);\n\t\n\t// A single base 64 digit can contain 6 bits of data. For the base 64 variable\n\t// length quantities we use in the source map spec, the first bit is the sign,\n\t// the next four bits are the actual value, and the 6th bit is the\n\t// continuation bit. The continuation bit tells us whether there are more\n\t// digits in this value following this digit.\n\t//\n\t// Continuation\n\t// | Sign\n\t// | |\n\t// V V\n\t// 101011\n\t\n\tvar VLQ_BASE_SHIFT = 5;\n\t\n\t// binary: 100000\n\tvar VLQ_BASE = 1 << VLQ_BASE_SHIFT;\n\t\n\t// binary: 011111\n\tvar VLQ_BASE_MASK = VLQ_BASE - 1;\n\t\n\t// binary: 100000\n\tvar VLQ_CONTINUATION_BIT = VLQ_BASE;\n\t\n\t/**\n\t * Converts from a two-complement value to a value where the sign bit is\n\t * placed in the least significant bit. For example, as decimals:\n\t * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)\n\t * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)\n\t */\n\tfunction toVLQSigned(aValue) {\n\t return aValue < 0\n\t ? ((-aValue) << 1) + 1\n\t : (aValue << 1) + 0;\n\t}\n\t\n\t/**\n\t * Converts to a two-complement value from a value where the sign bit is\n\t * placed in the least significant bit. For example, as decimals:\n\t * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1\n\t * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2\n\t */\n\tfunction fromVLQSigned(aValue) {\n\t var isNegative = (aValue & 1) === 1;\n\t var shifted = aValue >> 1;\n\t return isNegative\n\t ? -shifted\n\t : shifted;\n\t}\n\t\n\t/**\n\t * Returns the base 64 VLQ encoded value.\n\t */\n\texports.encode = function base64VLQ_encode(aValue) {\n\t var encoded = \"\";\n\t var digit;\n\t\n\t var vlq = toVLQSigned(aValue);\n\t\n\t do {\n\t digit = vlq & VLQ_BASE_MASK;\n\t vlq >>>= VLQ_BASE_SHIFT;\n\t if (vlq > 0) {\n\t // There are still more digits in this value, so we must make sure the\n\t // continuation bit is marked.\n\t digit |= VLQ_CONTINUATION_BIT;\n\t }\n\t encoded += base64.encode(digit);\n\t } while (vlq > 0);\n\t\n\t return encoded;\n\t};\n\t\n\t/**\n\t * Decodes the next base 64 VLQ value from the given string and returns the\n\t * value and the rest of the string via the out parameter.\n\t */\n\texports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {\n\t var strLen = aStr.length;\n\t var result = 0;\n\t var shift = 0;\n\t var continuation, digit;\n\t\n\t do {\n\t if (aIndex >= strLen) {\n\t throw new Error(\"Expected more digits in base 64 VLQ value.\");\n\t }\n\t\n\t digit = base64.decode(aStr.charCodeAt(aIndex++));\n\t if (digit === -1) {\n\t throw new Error(\"Invalid base64 digit: \" + aStr.charAt(aIndex - 1));\n\t }\n\t\n\t continuation = !!(digit & VLQ_CONTINUATION_BIT);\n\t digit &= VLQ_BASE_MASK;\n\t result = result + (digit << shift);\n\t shift += VLQ_BASE_SHIFT;\n\t } while (continuation);\n\t\n\t aOutParam.value = fromVLQSigned(result);\n\t aOutParam.rest = aIndex;\n\t};\n\n\n/***/ },\n/* 3 */\n/***/ function(module, exports) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\t\n\tvar intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');\n\t\n\t/**\n\t * Encode an integer in the range of 0 to 63 to a single base 64 digit.\n\t */\n\texports.encode = function (number) {\n\t if (0 <= number && number < intToCharMap.length) {\n\t return intToCharMap[number];\n\t }\n\t throw new TypeError(\"Must be between 0 and 63: \" + number);\n\t};\n\t\n\t/**\n\t * Decode a single base 64 character code digit to an integer. Returns -1 on\n\t * failure.\n\t */\n\texports.decode = function (charCode) {\n\t var bigA = 65; // 'A'\n\t var bigZ = 90; // 'Z'\n\t\n\t var littleA = 97; // 'a'\n\t var littleZ = 122; // 'z'\n\t\n\t var zero = 48; // '0'\n\t var nine = 57; // '9'\n\t\n\t var plus = 43; // '+'\n\t var slash = 47; // '/'\n\t\n\t var littleOffset = 26;\n\t var numberOffset = 52;\n\t\n\t // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ\n\t if (bigA <= charCode && charCode <= bigZ) {\n\t return (charCode - bigA);\n\t }\n\t\n\t // 26 - 51: abcdefghijklmnopqrstuvwxyz\n\t if (littleA <= charCode && charCode <= littleZ) {\n\t return (charCode - littleA + littleOffset);\n\t }\n\t\n\t // 52 - 61: 0123456789\n\t if (zero <= charCode && charCode <= nine) {\n\t return (charCode - zero + numberOffset);\n\t }\n\t\n\t // 62: +\n\t if (charCode == plus) {\n\t return 62;\n\t }\n\t\n\t // 63: /\n\t if (charCode == slash) {\n\t return 63;\n\t }\n\t\n\t // Invalid base64 digit.\n\t return -1;\n\t};\n\n\n/***/ },\n/* 4 */\n/***/ function(module, exports) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\t\n\t/**\n\t * This is a helper function for getting values from parameter/options\n\t * objects.\n\t *\n\t * @param args The object we are extracting values from\n\t * @param name The name of the property we are getting.\n\t * @param defaultValue An optional value to return if the property is missing\n\t * from the object. If this is not specified and the property is missing, an\n\t * error will be thrown.\n\t */\n\tfunction getArg(aArgs, aName, aDefaultValue) {\n\t if (aName in aArgs) {\n\t return aArgs[aName];\n\t } else if (arguments.length === 3) {\n\t return aDefaultValue;\n\t } else {\n\t throw new Error('\"' + aName + '\" is a required argument.');\n\t }\n\t}\n\texports.getArg = getArg;\n\t\n\tvar urlRegexp = /^(?:([\\w+\\-.]+):)?\\/\\/(?:(\\w+:\\w+)@)?([\\w.]*)(?::(\\d+))?(\\S*)$/;\n\tvar dataUrlRegexp = /^data:.+\\,.+$/;\n\t\n\tfunction urlParse(aUrl) {\n\t var match = aUrl.match(urlRegexp);\n\t if (!match) {\n\t return null;\n\t }\n\t return {\n\t scheme: match[1],\n\t auth: match[2],\n\t host: match[3],\n\t port: match[4],\n\t path: match[5]\n\t };\n\t}\n\texports.urlParse = urlParse;\n\t\n\tfunction urlGenerate(aParsedUrl) {\n\t var url = '';\n\t if (aParsedUrl.scheme) {\n\t url += aParsedUrl.scheme + ':';\n\t }\n\t url += '//';\n\t if (aParsedUrl.auth) {\n\t url += aParsedUrl.auth + '@';\n\t }\n\t if (aParsedUrl.host) {\n\t url += aParsedUrl.host;\n\t }\n\t if (aParsedUrl.port) {\n\t url += \":\" + aParsedUrl.port\n\t }\n\t if (aParsedUrl.path) {\n\t url += aParsedUrl.path;\n\t }\n\t return url;\n\t}\n\texports.urlGenerate = urlGenerate;\n\t\n\t/**\n\t * Normalizes a path, or the path portion of a URL:\n\t *\n\t * - Replaces consequtive slashes with one slash.\n\t * - Removes unnecessary '.' parts.\n\t * - Removes unnecessary '/..' parts.\n\t *\n\t * Based on code in the Node.js 'path' core module.\n\t *\n\t * @param aPath The path or url to normalize.\n\t */\n\tfunction normalize(aPath) {\n\t var path = aPath;\n\t var url = urlParse(aPath);\n\t if (url) {\n\t if (!url.path) {\n\t return aPath;\n\t }\n\t path = url.path;\n\t }\n\t var isAbsolute = exports.isAbsolute(path);\n\t\n\t var parts = path.split(/\\/+/);\n\t for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {\n\t part = parts[i];\n\t if (part === '.') {\n\t parts.splice(i, 1);\n\t } else if (part === '..') {\n\t up++;\n\t } else if (up > 0) {\n\t if (part === '') {\n\t // The first part is blank if the path is absolute. Trying to go\n\t // above the root is a no-op. Therefore we can remove all '..' parts\n\t // directly after the root.\n\t parts.splice(i + 1, up);\n\t up = 0;\n\t } else {\n\t parts.splice(i, 2);\n\t up--;\n\t }\n\t }\n\t }\n\t path = parts.join('/');\n\t\n\t if (path === '') {\n\t path = isAbsolute ? '/' : '.';\n\t }\n\t\n\t if (url) {\n\t url.path = path;\n\t return urlGenerate(url);\n\t }\n\t return path;\n\t}\n\texports.normalize = normalize;\n\t\n\t/**\n\t * Joins two paths/URLs.\n\t *\n\t * @param aRoot The root path or URL.\n\t * @param aPath The path or URL to be joined with the root.\n\t *\n\t * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a\n\t * scheme-relative URL: Then the scheme of aRoot, if any, is prepended\n\t * first.\n\t * - Otherwise aPath is a path. If aRoot is a URL, then its path portion\n\t * is updated with the result and aRoot is returned. Otherwise the result\n\t * is returned.\n\t * - If aPath is absolute, the result is aPath.\n\t * - Otherwise the two paths are joined with a slash.\n\t * - Joining for example 'http://' and 'www.example.com' is also supported.\n\t */\n\tfunction join(aRoot, aPath) {\n\t if (aRoot === \"\") {\n\t aRoot = \".\";\n\t }\n\t if (aPath === \"\") {\n\t aPath = \".\";\n\t }\n\t var aPathUrl = urlParse(aPath);\n\t var aRootUrl = urlParse(aRoot);\n\t if (aRootUrl) {\n\t aRoot = aRootUrl.path || '/';\n\t }\n\t\n\t // `join(foo, '//www.example.org')`\n\t if (aPathUrl && !aPathUrl.scheme) {\n\t if (aRootUrl) {\n\t aPathUrl.scheme = aRootUrl.scheme;\n\t }\n\t return urlGenerate(aPathUrl);\n\t }\n\t\n\t if (aPathUrl || aPath.match(dataUrlRegexp)) {\n\t return aPath;\n\t }\n\t\n\t // `join('http://', 'www.example.com')`\n\t if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {\n\t aRootUrl.host = aPath;\n\t return urlGenerate(aRootUrl);\n\t }\n\t\n\t var joined = aPath.charAt(0) === '/'\n\t ? aPath\n\t : normalize(aRoot.replace(/\\/+$/, '') + '/' + aPath);\n\t\n\t if (aRootUrl) {\n\t aRootUrl.path = joined;\n\t return urlGenerate(aRootUrl);\n\t }\n\t return joined;\n\t}\n\texports.join = join;\n\t\n\texports.isAbsolute = function (aPath) {\n\t return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp);\n\t};\n\t\n\t/**\n\t * Make a path relative to a URL or another path.\n\t *\n\t * @param aRoot The root path or URL.\n\t * @param aPath The path or URL to be made relative to aRoot.\n\t */\n\tfunction relative(aRoot, aPath) {\n\t if (aRoot === \"\") {\n\t aRoot = \".\";\n\t }\n\t\n\t aRoot = aRoot.replace(/\\/$/, '');\n\t\n\t // It is possible for the path to be above the root. In this case, simply\n\t // checking whether the root is a prefix of the path won't work. Instead, we\n\t // need to remove components from the root one by one, until either we find\n\t // a prefix that fits, or we run out of components to remove.\n\t var level = 0;\n\t while (aPath.indexOf(aRoot + '/') !== 0) {\n\t var index = aRoot.lastIndexOf(\"/\");\n\t if (index < 0) {\n\t return aPath;\n\t }\n\t\n\t // If the only part of the root that is left is the scheme (i.e. http://,\n\t // file:///, etc.), one or more slashes (/), or simply nothing at all, we\n\t // have exhausted all components, so the path is not relative to the root.\n\t aRoot = aRoot.slice(0, index);\n\t if (aRoot.match(/^([^\\/]+:\\/)?\\/*$/)) {\n\t return aPath;\n\t }\n\t\n\t ++level;\n\t }\n\t\n\t // Make sure we add a \"../\" for each component we removed from the root.\n\t return Array(level + 1).join(\"../\") + aPath.substr(aRoot.length + 1);\n\t}\n\texports.relative = relative;\n\t\n\tvar supportsNullProto = (function () {\n\t var obj = Object.create(null);\n\t return !('__proto__' in obj);\n\t}());\n\t\n\tfunction identity (s) {\n\t return s;\n\t}\n\t\n\t/**\n\t * Because behavior goes wacky when you set `__proto__` on objects, we\n\t * have to prefix all the strings in our set with an arbitrary character.\n\t *\n\t * See https://github.com/mozilla/source-map/pull/31 and\n\t * https://github.com/mozilla/source-map/issues/30\n\t *\n\t * @param String aStr\n\t */\n\tfunction toSetString(aStr) {\n\t if (isProtoString(aStr)) {\n\t return '$' + aStr;\n\t }\n\t\n\t return aStr;\n\t}\n\texports.toSetString = supportsNullProto ? identity : toSetString;\n\t\n\tfunction fromSetString(aStr) {\n\t if (isProtoString(aStr)) {\n\t return aStr.slice(1);\n\t }\n\t\n\t return aStr;\n\t}\n\texports.fromSetString = supportsNullProto ? identity : fromSetString;\n\t\n\tfunction isProtoString(s) {\n\t if (!s) {\n\t return false;\n\t }\n\t\n\t var length = s.length;\n\t\n\t if (length < 9 /* \"__proto__\".length */) {\n\t return false;\n\t }\n\t\n\t if (s.charCodeAt(length - 1) !== 95 /* '_' */ ||\n\t s.charCodeAt(length - 2) !== 95 /* '_' */ ||\n\t s.charCodeAt(length - 3) !== 111 /* 'o' */ ||\n\t s.charCodeAt(length - 4) !== 116 /* 't' */ ||\n\t s.charCodeAt(length - 5) !== 111 /* 'o' */ ||\n\t s.charCodeAt(length - 6) !== 114 /* 'r' */ ||\n\t s.charCodeAt(length - 7) !== 112 /* 'p' */ ||\n\t s.charCodeAt(length - 8) !== 95 /* '_' */ ||\n\t s.charCodeAt(length - 9) !== 95 /* '_' */) {\n\t return false;\n\t }\n\t\n\t for (var i = length - 10; i >= 0; i--) {\n\t if (s.charCodeAt(i) !== 36 /* '$' */) {\n\t return false;\n\t }\n\t }\n\t\n\t return true;\n\t}\n\t\n\t/**\n\t * Comparator between two mappings where the original positions are compared.\n\t *\n\t * Optionally pass in `true` as `onlyCompareGenerated` to consider two\n\t * mappings with the same original source/line/column, but different generated\n\t * line and column the same. Useful when searching for a mapping with a\n\t * stubbed out mapping.\n\t */\n\tfunction compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {\n\t var cmp = mappingA.source - mappingB.source;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.originalLine - mappingB.originalLine;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.originalColumn - mappingB.originalColumn;\n\t if (cmp !== 0 || onlyCompareOriginal) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.generatedLine - mappingB.generatedLine;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t return mappingA.name - mappingB.name;\n\t}\n\texports.compareByOriginalPositions = compareByOriginalPositions;\n\t\n\t/**\n\t * Comparator between two mappings with deflated source and name indices where\n\t * the generated positions are compared.\n\t *\n\t * Optionally pass in `true` as `onlyCompareGenerated` to consider two\n\t * mappings with the same generated line and column, but different\n\t * source/name/original line and column the same. Useful when searching for a\n\t * mapping with a stubbed out mapping.\n\t */\n\tfunction compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {\n\t var cmp = mappingA.generatedLine - mappingB.generatedLine;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n\t if (cmp !== 0 || onlyCompareGenerated) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.source - mappingB.source;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.originalLine - mappingB.originalLine;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.originalColumn - mappingB.originalColumn;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t return mappingA.name - mappingB.name;\n\t}\n\texports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;\n\t\n\tfunction strcmp(aStr1, aStr2) {\n\t if (aStr1 === aStr2) {\n\t return 0;\n\t }\n\t\n\t if (aStr1 > aStr2) {\n\t return 1;\n\t }\n\t\n\t return -1;\n\t}\n\t\n\t/**\n\t * Comparator between two mappings with inflated source and name strings where\n\t * the generated positions are compared.\n\t */\n\tfunction compareByGeneratedPositionsInflated(mappingA, mappingB) {\n\t var cmp = mappingA.generatedLine - mappingB.generatedLine;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = strcmp(mappingA.source, mappingB.source);\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.originalLine - mappingB.originalLine;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.originalColumn - mappingB.originalColumn;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t return strcmp(mappingA.name, mappingB.name);\n\t}\n\texports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;\n\n\n/***/ },\n/* 5 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\t\n\tvar util = __webpack_require__(4);\n\tvar has = Object.prototype.hasOwnProperty;\n\t\n\t/**\n\t * A data structure which is a combination of an array and a set. Adding a new\n\t * member is O(1), testing for membership is O(1), and finding the index of an\n\t * element is O(1). Removing elements from the set is not supported. Only\n\t * strings are supported for membership.\n\t */\n\tfunction ArraySet() {\n\t this._array = [];\n\t this._set = Object.create(null);\n\t}\n\t\n\t/**\n\t * Static method for creating ArraySet instances from an existing array.\n\t */\n\tArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {\n\t var set = new ArraySet();\n\t for (var i = 0, len = aArray.length; i < len; i++) {\n\t set.add(aArray[i], aAllowDuplicates);\n\t }\n\t return set;\n\t};\n\t\n\t/**\n\t * Return how many unique items are in this ArraySet. If duplicates have been\n\t * added, than those do not count towards the size.\n\t *\n\t * @returns Number\n\t */\n\tArraySet.prototype.size = function ArraySet_size() {\n\t return Object.getOwnPropertyNames(this._set).length;\n\t};\n\t\n\t/**\n\t * Add the given string to this set.\n\t *\n\t * @param String aStr\n\t */\n\tArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {\n\t var sStr = util.toSetString(aStr);\n\t var isDuplicate = has.call(this._set, sStr);\n\t var idx = this._array.length;\n\t if (!isDuplicate || aAllowDuplicates) {\n\t this._array.push(aStr);\n\t }\n\t if (!isDuplicate) {\n\t this._set[sStr] = idx;\n\t }\n\t};\n\t\n\t/**\n\t * Is the given string a member of this set?\n\t *\n\t * @param String aStr\n\t */\n\tArraySet.prototype.has = function ArraySet_has(aStr) {\n\t var sStr = util.toSetString(aStr);\n\t return has.call(this._set, sStr);\n\t};\n\t\n\t/**\n\t * What is the index of the given string in the array?\n\t *\n\t * @param String aStr\n\t */\n\tArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {\n\t var sStr = util.toSetString(aStr);\n\t if (has.call(this._set, sStr)) {\n\t return this._set[sStr];\n\t }\n\t throw new Error('\"' + aStr + '\" is not in the set.');\n\t};\n\t\n\t/**\n\t * What is the element at the given index?\n\t *\n\t * @param Number aIdx\n\t */\n\tArraySet.prototype.at = function ArraySet_at(aIdx) {\n\t if (aIdx >= 0 && aIdx < this._array.length) {\n\t return this._array[aIdx];\n\t }\n\t throw new Error('No element indexed by ' + aIdx);\n\t};\n\t\n\t/**\n\t * Returns the array representation of this set (which has the proper indices\n\t * indicated by indexOf). Note that this is a copy of the internal array used\n\t * for storing the members so that no one can mess with internal state.\n\t */\n\tArraySet.prototype.toArray = function ArraySet_toArray() {\n\t return this._array.slice();\n\t};\n\t\n\texports.ArraySet = ArraySet;\n\n\n/***/ },\n/* 6 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2014 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\t\n\tvar util = __webpack_require__(4);\n\t\n\t/**\n\t * Determine whether mappingB is after mappingA with respect to generated\n\t * position.\n\t */\n\tfunction generatedPositionAfter(mappingA, mappingB) {\n\t // Optimized for most common case\n\t var lineA = mappingA.generatedLine;\n\t var lineB = mappingB.generatedLine;\n\t var columnA = mappingA.generatedColumn;\n\t var columnB = mappingB.generatedColumn;\n\t return lineB > lineA || lineB == lineA && columnB >= columnA ||\n\t util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;\n\t}\n\t\n\t/**\n\t * A data structure to provide a sorted view of accumulated mappings in a\n\t * performance conscious manner. It trades a neglibable overhead in general\n\t * case for a large speedup in case of mappings being added in order.\n\t */\n\tfunction MappingList() {\n\t this._array = [];\n\t this._sorted = true;\n\t // Serves as infimum\n\t this._last = {generatedLine: -1, generatedColumn: 0};\n\t}\n\t\n\t/**\n\t * Iterate through internal items. This method takes the same arguments that\n\t * `Array.prototype.forEach` takes.\n\t *\n\t * NOTE: The order of the mappings is NOT guaranteed.\n\t */\n\tMappingList.prototype.unsortedForEach =\n\t function MappingList_forEach(aCallback, aThisArg) {\n\t this._array.forEach(aCallback, aThisArg);\n\t };\n\t\n\t/**\n\t * Add the given source mapping.\n\t *\n\t * @param Object aMapping\n\t */\n\tMappingList.prototype.add = function MappingList_add(aMapping) {\n\t if (generatedPositionAfter(this._last, aMapping)) {\n\t this._last = aMapping;\n\t this._array.push(aMapping);\n\t } else {\n\t this._sorted = false;\n\t this._array.push(aMapping);\n\t }\n\t};\n\t\n\t/**\n\t * Returns the flat, sorted array of mappings. The mappings are sorted by\n\t * generated position.\n\t *\n\t * WARNING: This method returns internal data without copying, for\n\t * performance. The return value must NOT be mutated, and should be treated as\n\t * an immutable borrow. If you want to take ownership, you must make your own\n\t * copy.\n\t */\n\tMappingList.prototype.toArray = function MappingList_toArray() {\n\t if (!this._sorted) {\n\t this._array.sort(util.compareByGeneratedPositionsInflated);\n\t this._sorted = true;\n\t }\n\t return this._array;\n\t};\n\t\n\texports.MappingList = MappingList;\n\n\n/***/ },\n/* 7 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\t\n\tvar util = __webpack_require__(4);\n\tvar binarySearch = __webpack_require__(8);\n\tvar ArraySet = __webpack_require__(5).ArraySet;\n\tvar base64VLQ = __webpack_require__(2);\n\tvar quickSort = __webpack_require__(9).quickSort;\n\t\n\tfunction SourceMapConsumer(aSourceMap) {\n\t var sourceMap = aSourceMap;\n\t if (typeof aSourceMap === 'string') {\n\t sourceMap = JSON.parse(aSourceMap.replace(/^\\)\\]\\}'/, ''));\n\t }\n\t\n\t return sourceMap.sections != null\n\t ? new IndexedSourceMapConsumer(sourceMap)\n\t : new BasicSourceMapConsumer(sourceMap);\n\t}\n\t\n\tSourceMapConsumer.fromSourceMap = function(aSourceMap) {\n\t return BasicSourceMapConsumer.fromSourceMap(aSourceMap);\n\t}\n\t\n\t/**\n\t * The version of the source mapping spec that we are consuming.\n\t */\n\tSourceMapConsumer.prototype._version = 3;\n\t\n\t// `__generatedMappings` and `__originalMappings` are arrays that hold the\n\t// parsed mapping coordinates from the source map's \"mappings\" attribute. They\n\t// are lazily instantiated, accessed via the `_generatedMappings` and\n\t// `_originalMappings` getters respectively, and we only parse the mappings\n\t// and create these arrays once queried for a source location. We jump through\n\t// these hoops because there can be many thousands of mappings, and parsing\n\t// them is expensive, so we only want to do it if we must.\n\t//\n\t// Each object in the arrays is of the form:\n\t//\n\t// {\n\t// generatedLine: The line number in the generated code,\n\t// generatedColumn: The column number in the generated code,\n\t// source: The path to the original source file that generated this\n\t// chunk of code,\n\t// originalLine: The line number in the original source that\n\t// corresponds to this chunk of generated code,\n\t// originalColumn: The column number in the original source that\n\t// corresponds to this chunk of generated code,\n\t// name: The name of the original symbol which generated this chunk of\n\t// code.\n\t// }\n\t//\n\t// All properties except for `generatedLine` and `generatedColumn` can be\n\t// `null`.\n\t//\n\t// `_generatedMappings` is ordered by the generated positions.\n\t//\n\t// `_originalMappings` is ordered by the original positions.\n\t\n\tSourceMapConsumer.prototype.__generatedMappings = null;\n\tObject.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {\n\t get: function () {\n\t if (!this.__generatedMappings) {\n\t this._parseMappings(this._mappings, this.sourceRoot);\n\t }\n\t\n\t return this.__generatedMappings;\n\t }\n\t});\n\t\n\tSourceMapConsumer.prototype.__originalMappings = null;\n\tObject.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {\n\t get: function () {\n\t if (!this.__originalMappings) {\n\t this._parseMappings(this._mappings, this.sourceRoot);\n\t }\n\t\n\t return this.__originalMappings;\n\t }\n\t});\n\t\n\tSourceMapConsumer.prototype._charIsMappingSeparator =\n\t function SourceMapConsumer_charIsMappingSeparator(aStr, index) {\n\t var c = aStr.charAt(index);\n\t return c === \";\" || c === \",\";\n\t };\n\t\n\t/**\n\t * Parse the mappings in a string in to a data structure which we can easily\n\t * query (the ordered arrays in the `this.__generatedMappings` and\n\t * `this.__originalMappings` properties).\n\t */\n\tSourceMapConsumer.prototype._parseMappings =\n\t function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {\n\t throw new Error(\"Subclasses must implement _parseMappings\");\n\t };\n\t\n\tSourceMapConsumer.GENERATED_ORDER = 1;\n\tSourceMapConsumer.ORIGINAL_ORDER = 2;\n\t\n\tSourceMapConsumer.GREATEST_LOWER_BOUND = 1;\n\tSourceMapConsumer.LEAST_UPPER_BOUND = 2;\n\t\n\t/**\n\t * Iterate over each mapping between an original source/line/column and a\n\t * generated line/column in this source map.\n\t *\n\t * @param Function aCallback\n\t * The function that is called with each mapping.\n\t * @param Object aContext\n\t * Optional. If specified, this object will be the value of `this` every\n\t * time that `aCallback` is called.\n\t * @param aOrder\n\t * Either `SourceMapConsumer.GENERATED_ORDER` or\n\t * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to\n\t * iterate over the mappings sorted by the generated file's line/column\n\t * order or the original's source/line/column order, respectively. Defaults to\n\t * `SourceMapConsumer.GENERATED_ORDER`.\n\t */\n\tSourceMapConsumer.prototype.eachMapping =\n\t function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {\n\t var context = aContext || null;\n\t var order = aOrder || SourceMapConsumer.GENERATED_ORDER;\n\t\n\t var mappings;\n\t switch (order) {\n\t case SourceMapConsumer.GENERATED_ORDER:\n\t mappings = this._generatedMappings;\n\t break;\n\t case SourceMapConsumer.ORIGINAL_ORDER:\n\t mappings = this._originalMappings;\n\t break;\n\t default:\n\t throw new Error(\"Unknown order of iteration.\");\n\t }\n\t\n\t var sourceRoot = this.sourceRoot;\n\t mappings.map(function (mapping) {\n\t var source = mapping.source === null ? null : this._sources.at(mapping.source);\n\t if (source != null && sourceRoot != null) {\n\t source = util.join(sourceRoot, source);\n\t }\n\t return {\n\t source: source,\n\t generatedLine: mapping.generatedLine,\n\t generatedColumn: mapping.generatedColumn,\n\t originalLine: mapping.originalLine,\n\t originalColumn: mapping.originalColumn,\n\t name: mapping.name === null ? null : this._names.at(mapping.name)\n\t };\n\t }, this).forEach(aCallback, context);\n\t };\n\t\n\t/**\n\t * Returns all generated line and column information for the original source,\n\t * line, and column provided. If no column is provided, returns all mappings\n\t * corresponding to a either the line we are searching for or the next\n\t * closest line that has any mappings. Otherwise, returns all mappings\n\t * corresponding to the given line and either the column we are searching for\n\t * or the next closest column that has any offsets.\n\t *\n\t * The only argument is an object with the following properties:\n\t *\n\t * - source: The filename of the original source.\n\t * - line: The line number in the original source.\n\t * - column: Optional. the column number in the original source.\n\t *\n\t * and an array of objects is returned, each with the following properties:\n\t *\n\t * - line: The line number in the generated source, or null.\n\t * - column: The column number in the generated source, or null.\n\t */\n\tSourceMapConsumer.prototype.allGeneratedPositionsFor =\n\t function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {\n\t var line = util.getArg(aArgs, 'line');\n\t\n\t // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping\n\t // returns the index of the closest mapping less than the needle. By\n\t // setting needle.originalColumn to 0, we thus find the last mapping for\n\t // the given line, provided such a mapping exists.\n\t var needle = {\n\t source: util.getArg(aArgs, 'source'),\n\t originalLine: line,\n\t originalColumn: util.getArg(aArgs, 'column', 0)\n\t };\n\t\n\t if (this.sourceRoot != null) {\n\t needle.source = util.relative(this.sourceRoot, needle.source);\n\t }\n\t if (!this._sources.has(needle.source)) {\n\t return [];\n\t }\n\t needle.source = this._sources.indexOf(needle.source);\n\t\n\t var mappings = [];\n\t\n\t var index = this._findMapping(needle,\n\t this._originalMappings,\n\t \"originalLine\",\n\t \"originalColumn\",\n\t util.compareByOriginalPositions,\n\t binarySearch.LEAST_UPPER_BOUND);\n\t if (index >= 0) {\n\t var mapping = this._originalMappings[index];\n\t\n\t if (aArgs.column === undefined) {\n\t var originalLine = mapping.originalLine;\n\t\n\t // Iterate until either we run out of mappings, or we run into\n\t // a mapping for a different line than the one we found. Since\n\t // mappings are sorted, this is guaranteed to find all mappings for\n\t // the line we found.\n\t while (mapping && mapping.originalLine === originalLine) {\n\t mappings.push({\n\t line: util.getArg(mapping, 'generatedLine', null),\n\t column: util.getArg(mapping, 'generatedColumn', null),\n\t lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)\n\t });\n\t\n\t mapping = this._originalMappings[++index];\n\t }\n\t } else {\n\t var originalColumn = mapping.originalColumn;\n\t\n\t // Iterate until either we run out of mappings, or we run into\n\t // a mapping for a different line than the one we were searching for.\n\t // Since mappings are sorted, this is guaranteed to find all mappings for\n\t // the line we are searching for.\n\t while (mapping &&\n\t mapping.originalLine === line &&\n\t mapping.originalColumn == originalColumn) {\n\t mappings.push({\n\t line: util.getArg(mapping, 'generatedLine', null),\n\t column: util.getArg(mapping, 'generatedColumn', null),\n\t lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)\n\t });\n\t\n\t mapping = this._originalMappings[++index];\n\t }\n\t }\n\t }\n\t\n\t return mappings;\n\t };\n\t\n\texports.SourceMapConsumer = SourceMapConsumer;\n\t\n\t/**\n\t * A BasicSourceMapConsumer instance represents a parsed source map which we can\n\t * query for information about the original file positions by giving it a file\n\t * position in the generated source.\n\t *\n\t * The only parameter is the raw source map (either as a JSON string, or\n\t * already parsed to an object). According to the spec, source maps have the\n\t * following attributes:\n\t *\n\t * - version: Which version of the source map spec this map is following.\n\t * - sources: An array of URLs to the original source files.\n\t * - names: An array of identifiers which can be referrenced by individual mappings.\n\t * - sourceRoot: Optional. The URL root from which all sources are relative.\n\t * - sourcesContent: Optional. An array of contents of the original source files.\n\t * - mappings: A string of base64 VLQs which contain the actual mappings.\n\t * - file: Optional. The generated file this source map is associated with.\n\t *\n\t * Here is an example source map, taken from the source map spec[0]:\n\t *\n\t * {\n\t * version : 3,\n\t * file: \"out.js\",\n\t * sourceRoot : \"\",\n\t * sources: [\"foo.js\", \"bar.js\"],\n\t * names: [\"src\", \"maps\", \"are\", \"fun\"],\n\t * mappings: \"AA,AB;;ABCDE;\"\n\t * }\n\t *\n\t * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#\n\t */\n\tfunction BasicSourceMapConsumer(aSourceMap) {\n\t var sourceMap = aSourceMap;\n\t if (typeof aSourceMap === 'string') {\n\t sourceMap = JSON.parse(aSourceMap.replace(/^\\)\\]\\}'/, ''));\n\t }\n\t\n\t var version = util.getArg(sourceMap, 'version');\n\t var sources = util.getArg(sourceMap, 'sources');\n\t // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which\n\t // requires the array) to play nice here.\n\t var names = util.getArg(sourceMap, 'names', []);\n\t var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);\n\t var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);\n\t var mappings = util.getArg(sourceMap, 'mappings');\n\t var file = util.getArg(sourceMap, 'file', null);\n\t\n\t // Once again, Sass deviates from the spec and supplies the version as a\n\t // string rather than a number, so we use loose equality checking here.\n\t if (version != this._version) {\n\t throw new Error('Unsupported version: ' + version);\n\t }\n\t\n\t sources = sources\n\t .map(String)\n\t // Some source maps produce relative source paths like \"./foo.js\" instead of\n\t // \"foo.js\". Normalize these first so that future comparisons will succeed.\n\t // See bugzil.la/1090768.\n\t .map(util.normalize)\n\t // Always ensure that absolute sources are internally stored relative to\n\t // the source root, if the source root is absolute. Not doing this would\n\t // be particularly problematic when the source root is a prefix of the\n\t // source (valid, but why??). See github issue #199 and bugzil.la/1188982.\n\t .map(function (source) {\n\t return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source)\n\t ? util.relative(sourceRoot, source)\n\t : source;\n\t });\n\t\n\t // Pass `true` below to allow duplicate names and sources. While source maps\n\t // are intended to be compressed and deduplicated, the TypeScript compiler\n\t // sometimes generates source maps with duplicates in them. See Github issue\n\t // #72 and bugzil.la/889492.\n\t this._names = ArraySet.fromArray(names.map(String), true);\n\t this._sources = ArraySet.fromArray(sources, true);\n\t\n\t this.sourceRoot = sourceRoot;\n\t this.sourcesContent = sourcesContent;\n\t this._mappings = mappings;\n\t this.file = file;\n\t}\n\t\n\tBasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);\n\tBasicSourceMapConsumer.prototype.consumer = SourceMapConsumer;\n\t\n\t/**\n\t * Create a BasicSourceMapConsumer from a SourceMapGenerator.\n\t *\n\t * @param SourceMapGenerator aSourceMap\n\t * The source map that will be consumed.\n\t * @returns BasicSourceMapConsumer\n\t */\n\tBasicSourceMapConsumer.fromSourceMap =\n\t function SourceMapConsumer_fromSourceMap(aSourceMap) {\n\t var smc = Object.create(BasicSourceMapConsumer.prototype);\n\t\n\t var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);\n\t var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);\n\t smc.sourceRoot = aSourceMap._sourceRoot;\n\t smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),\n\t smc.sourceRoot);\n\t smc.file = aSourceMap._file;\n\t\n\t // Because we are modifying the entries (by converting string sources and\n\t // names to indices into the sources and names ArraySets), we have to make\n\t // a copy of the entry or else bad things happen. Shared mutable state\n\t // strikes again! See github issue #191.\n\t\n\t var generatedMappings = aSourceMap._mappings.toArray().slice();\n\t var destGeneratedMappings = smc.__generatedMappings = [];\n\t var destOriginalMappings = smc.__originalMappings = [];\n\t\n\t for (var i = 0, length = generatedMappings.length; i < length; i++) {\n\t var srcMapping = generatedMappings[i];\n\t var destMapping = new Mapping;\n\t destMapping.generatedLine = srcMapping.generatedLine;\n\t destMapping.generatedColumn = srcMapping.generatedColumn;\n\t\n\t if (srcMapping.source) {\n\t destMapping.source = sources.indexOf(srcMapping.source);\n\t destMapping.originalLine = srcMapping.originalLine;\n\t destMapping.originalColumn = srcMapping.originalColumn;\n\t\n\t if (srcMapping.name) {\n\t destMapping.name = names.indexOf(srcMapping.name);\n\t }\n\t\n\t destOriginalMappings.push(destMapping);\n\t }\n\t\n\t destGeneratedMappings.push(destMapping);\n\t }\n\t\n\t quickSort(smc.__originalMappings, util.compareByOriginalPositions);\n\t\n\t return smc;\n\t };\n\t\n\t/**\n\t * The version of the source mapping spec that we are consuming.\n\t */\n\tBasicSourceMapConsumer.prototype._version = 3;\n\t\n\t/**\n\t * The list of original sources.\n\t */\n\tObject.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {\n\t get: function () {\n\t return this._sources.toArray().map(function (s) {\n\t return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s;\n\t }, this);\n\t }\n\t});\n\t\n\t/**\n\t * Provide the JIT with a nice shape / hidden class.\n\t */\n\tfunction Mapping() {\n\t this.generatedLine = 0;\n\t this.generatedColumn = 0;\n\t this.source = null;\n\t this.originalLine = null;\n\t this.originalColumn = null;\n\t this.name = null;\n\t}\n\t\n\t/**\n\t * Parse the mappings in a string in to a data structure which we can easily\n\t * query (the ordered arrays in the `this.__generatedMappings` and\n\t * `this.__originalMappings` properties).\n\t */\n\tBasicSourceMapConsumer.prototype._parseMappings =\n\t function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {\n\t var generatedLine = 1;\n\t var previousGeneratedColumn = 0;\n\t var previousOriginalLine = 0;\n\t var previousOriginalColumn = 0;\n\t var previousSource = 0;\n\t var previousName = 0;\n\t var length = aStr.length;\n\t var index = 0;\n\t var cachedSegments = {};\n\t var temp = {};\n\t var originalMappings = [];\n\t var generatedMappings = [];\n\t var mapping, str, segment, end, value;\n\t\n\t while (index < length) {\n\t if (aStr.charAt(index) === ';') {\n\t generatedLine++;\n\t index++;\n\t previousGeneratedColumn = 0;\n\t }\n\t else if (aStr.charAt(index) === ',') {\n\t index++;\n\t }\n\t else {\n\t mapping = new Mapping();\n\t mapping.generatedLine = generatedLine;\n\t\n\t // Because each offset is encoded relative to the previous one,\n\t // many segments often have the same encoding. We can exploit this\n\t // fact by caching the parsed variable length fields of each segment,\n\t // allowing us to avoid a second parse if we encounter the same\n\t // segment again.\n\t for (end = index; end < length; end++) {\n\t if (this._charIsMappingSeparator(aStr, end)) {\n\t break;\n\t }\n\t }\n\t str = aStr.slice(index, end);\n\t\n\t segment = cachedSegments[str];\n\t if (segment) {\n\t index += str.length;\n\t } else {\n\t segment = [];\n\t while (index < end) {\n\t base64VLQ.decode(aStr, index, temp);\n\t value = temp.value;\n\t index = temp.rest;\n\t segment.push(value);\n\t }\n\t\n\t if (segment.length === 2) {\n\t throw new Error('Found a source, but no line and column');\n\t }\n\t\n\t if (segment.length === 3) {\n\t throw new Error('Found a source and line, but no column');\n\t }\n\t\n\t cachedSegments[str] = segment;\n\t }\n\t\n\t // Generated column.\n\t mapping.generatedColumn = previousGeneratedColumn + segment[0];\n\t previousGeneratedColumn = mapping.generatedColumn;\n\t\n\t if (segment.length > 1) {\n\t // Original source.\n\t mapping.source = previousSource + segment[1];\n\t previousSource += segment[1];\n\t\n\t // Original line.\n\t mapping.originalLine = previousOriginalLine + segment[2];\n\t previousOriginalLine = mapping.originalLine;\n\t // Lines are stored 0-based\n\t mapping.originalLine += 1;\n\t\n\t // Original column.\n\t mapping.originalColumn = previousOriginalColumn + segment[3];\n\t previousOriginalColumn = mapping.originalColumn;\n\t\n\t if (segment.length > 4) {\n\t // Original name.\n\t mapping.name = previousName + segment[4];\n\t previousName += segment[4];\n\t }\n\t }\n\t\n\t generatedMappings.push(mapping);\n\t if (typeof mapping.originalLine === 'number') {\n\t originalMappings.push(mapping);\n\t }\n\t }\n\t }\n\t\n\t quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated);\n\t this.__generatedMappings = generatedMappings;\n\t\n\t quickSort(originalMappings, util.compareByOriginalPositions);\n\t this.__originalMappings = originalMappings;\n\t };\n\t\n\t/**\n\t * Find the mapping that best matches the hypothetical \"needle\" mapping that\n\t * we are searching for in the given \"haystack\" of mappings.\n\t */\n\tBasicSourceMapConsumer.prototype._findMapping =\n\t function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName,\n\t aColumnName, aComparator, aBias) {\n\t // To return the position we are searching for, we must first find the\n\t // mapping for the given position and then return the opposite position it\n\t // points to. Because the mappings are sorted, we can use binary search to\n\t // find the best mapping.\n\t\n\t if (aNeedle[aLineName] <= 0) {\n\t throw new TypeError('Line must be greater than or equal to 1, got '\n\t + aNeedle[aLineName]);\n\t }\n\t if (aNeedle[aColumnName] < 0) {\n\t throw new TypeError('Column must be greater than or equal to 0, got '\n\t + aNeedle[aColumnName]);\n\t }\n\t\n\t return binarySearch.search(aNeedle, aMappings, aComparator, aBias);\n\t };\n\t\n\t/**\n\t * Compute the last column for each generated mapping. The last column is\n\t * inclusive.\n\t */\n\tBasicSourceMapConsumer.prototype.computeColumnSpans =\n\t function SourceMapConsumer_computeColumnSpans() {\n\t for (var index = 0; index < this._generatedMappings.length; ++index) {\n\t var mapping = this._generatedMappings[index];\n\t\n\t // Mappings do not contain a field for the last generated columnt. We\n\t // can come up with an optimistic estimate, however, by assuming that\n\t // mappings are contiguous (i.e. given two consecutive mappings, the\n\t // first mapping ends where the second one starts).\n\t if (index + 1 < this._generatedMappings.length) {\n\t var nextMapping = this._generatedMappings[index + 1];\n\t\n\t if (mapping.generatedLine === nextMapping.generatedLine) {\n\t mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1;\n\t continue;\n\t }\n\t }\n\t\n\t // The last mapping for each line spans the entire line.\n\t mapping.lastGeneratedColumn = Infinity;\n\t }\n\t };\n\t\n\t/**\n\t * Returns the original source, line, and column information for the generated\n\t * source's line and column positions provided. The only argument is an object\n\t * with the following properties:\n\t *\n\t * - line: The line number in the generated source.\n\t * - column: The column number in the generated source.\n\t * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or\n\t * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the\n\t * closest element that is smaller than or greater than the one we are\n\t * searching for, respectively, if the exact element cannot be found.\n\t * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.\n\t *\n\t * and an object is returned with the following properties:\n\t *\n\t * - source: The original source file, or null.\n\t * - line: The line number in the original source, or null.\n\t * - column: The column number in the original source, or null.\n\t * - name: The original identifier, or null.\n\t */\n\tBasicSourceMapConsumer.prototype.originalPositionFor =\n\t function SourceMapConsumer_originalPositionFor(aArgs) {\n\t var needle = {\n\t generatedLine: util.getArg(aArgs, 'line'),\n\t generatedColumn: util.getArg(aArgs, 'column')\n\t };\n\t\n\t var index = this._findMapping(\n\t needle,\n\t this._generatedMappings,\n\t \"generatedLine\",\n\t \"generatedColumn\",\n\t util.compareByGeneratedPositionsDeflated,\n\t util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)\n\t );\n\t\n\t if (index >= 0) {\n\t var mapping = this._generatedMappings[index];\n\t\n\t if (mapping.generatedLine === needle.generatedLine) {\n\t var source = util.getArg(mapping, 'source', null);\n\t if (source !== null) {\n\t source = this._sources.at(source);\n\t if (this.sourceRoot != null) {\n\t source = util.join(this.sourceRoot, source);\n\t }\n\t }\n\t var name = util.getArg(mapping, 'name', null);\n\t if (name !== null) {\n\t name = this._names.at(name);\n\t }\n\t return {\n\t source: source,\n\t line: util.getArg(mapping, 'originalLine', null),\n\t column: util.getArg(mapping, 'originalColumn', null),\n\t name: name\n\t };\n\t }\n\t }\n\t\n\t return {\n\t source: null,\n\t line: null,\n\t column: null,\n\t name: null\n\t };\n\t };\n\t\n\t/**\n\t * Return true if we have the source content for every source in the source\n\t * map, false otherwise.\n\t */\n\tBasicSourceMapConsumer.prototype.hasContentsOfAllSources =\n\t function BasicSourceMapConsumer_hasContentsOfAllSources() {\n\t if (!this.sourcesContent) {\n\t return false;\n\t }\n\t return this.sourcesContent.length >= this._sources.size() &&\n\t !this.sourcesContent.some(function (sc) { return sc == null; });\n\t };\n\t\n\t/**\n\t * Returns the original source content. The only argument is the url of the\n\t * original source file. Returns null if no original source content is\n\t * available.\n\t */\n\tBasicSourceMapConsumer.prototype.sourceContentFor =\n\t function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {\n\t if (!this.sourcesContent) {\n\t return null;\n\t }\n\t\n\t if (this.sourceRoot != null) {\n\t aSource = util.relative(this.sourceRoot, aSource);\n\t }\n\t\n\t if (this._sources.has(aSource)) {\n\t return this.sourcesContent[this._sources.indexOf(aSource)];\n\t }\n\t\n\t var url;\n\t if (this.sourceRoot != null\n\t && (url = util.urlParse(this.sourceRoot))) {\n\t // XXX: file:// URIs and absolute paths lead to unexpected behavior for\n\t // many users. We can help them out when they expect file:// URIs to\n\t // behave like it would if they were running a local HTTP server. See\n\t // https://bugzilla.mozilla.org/show_bug.cgi?id=885597.\n\t var fileUriAbsPath = aSource.replace(/^file:\\/\\//, \"\");\n\t if (url.scheme == \"file\"\n\t && this._sources.has(fileUriAbsPath)) {\n\t return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]\n\t }\n\t\n\t if ((!url.path || url.path == \"/\")\n\t && this._sources.has(\"/\" + aSource)) {\n\t return this.sourcesContent[this._sources.indexOf(\"/\" + aSource)];\n\t }\n\t }\n\t\n\t // This function is used recursively from\n\t // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we\n\t // don't want to throw if we can't find the source - we just want to\n\t // return null, so we provide a flag to exit gracefully.\n\t if (nullOnMissing) {\n\t return null;\n\t }\n\t else {\n\t throw new Error('\"' + aSource + '\" is not in the SourceMap.');\n\t }\n\t };\n\t\n\t/**\n\t * Returns the generated line and column information for the original source,\n\t * line, and column positions provided. The only argument is an object with\n\t * the following properties:\n\t *\n\t * - source: The filename of the original source.\n\t * - line: The line number in the original source.\n\t * - column: The column number in the original source.\n\t * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or\n\t * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the\n\t * closest element that is smaller than or greater than the one we are\n\t * searching for, respectively, if the exact element cannot be found.\n\t * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.\n\t *\n\t * and an object is returned with the following properties:\n\t *\n\t * - line: The line number in the generated source, or null.\n\t * - column: The column number in the generated source, or null.\n\t */\n\tBasicSourceMapConsumer.prototype.generatedPositionFor =\n\t function SourceMapConsumer_generatedPositionFor(aArgs) {\n\t var source = util.getArg(aArgs, 'source');\n\t if (this.sourceRoot != null) {\n\t source = util.relative(this.sourceRoot, source);\n\t }\n\t if (!this._sources.has(source)) {\n\t return {\n\t line: null,\n\t column: null,\n\t lastColumn: null\n\t };\n\t }\n\t source = this._sources.indexOf(source);\n\t\n\t var needle = {\n\t source: source,\n\t originalLine: util.getArg(aArgs, 'line'),\n\t originalColumn: util.getArg(aArgs, 'column')\n\t };\n\t\n\t var index = this._findMapping(\n\t needle,\n\t this._originalMappings,\n\t \"originalLine\",\n\t \"originalColumn\",\n\t util.compareByOriginalPositions,\n\t util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)\n\t );\n\t\n\t if (index >= 0) {\n\t var mapping = this._originalMappings[index];\n\t\n\t if (mapping.source === needle.source) {\n\t return {\n\t line: util.getArg(mapping, 'generatedLine', null),\n\t column: util.getArg(mapping, 'generatedColumn', null),\n\t lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)\n\t };\n\t }\n\t }\n\t\n\t return {\n\t line: null,\n\t column: null,\n\t lastColumn: null\n\t };\n\t };\n\t\n\texports.BasicSourceMapConsumer = BasicSourceMapConsumer;\n\t\n\t/**\n\t * An IndexedSourceMapConsumer instance represents a parsed source map which\n\t * we can query for information. It differs from BasicSourceMapConsumer in\n\t * that it takes \"indexed\" source maps (i.e. ones with a \"sections\" field) as\n\t * input.\n\t *\n\t * The only parameter is a raw source map (either as a JSON string, or already\n\t * parsed to an object). According to the spec for indexed source maps, they\n\t * have the following attributes:\n\t *\n\t * - version: Which version of the source map spec this map is following.\n\t * - file: Optional. The generated file this source map is associated with.\n\t * - sections: A list of section definitions.\n\t *\n\t * Each value under the \"sections\" field has two fields:\n\t * - offset: The offset into the original specified at which this section\n\t * begins to apply, defined as an object with a \"line\" and \"column\"\n\t * field.\n\t * - map: A source map definition. This source map could also be indexed,\n\t * but doesn't have to be.\n\t *\n\t * Instead of the \"map\" field, it's also possible to have a \"url\" field\n\t * specifying a URL to retrieve a source map from, but that's currently\n\t * unsupported.\n\t *\n\t * Here's an example source map, taken from the source map spec[0], but\n\t * modified to omit a section which uses the \"url\" field.\n\t *\n\t * {\n\t * version : 3,\n\t * file: \"app.js\",\n\t * sections: [{\n\t * offset: {line:100, column:10},\n\t * map: {\n\t * version : 3,\n\t * file: \"section.js\",\n\t * sources: [\"foo.js\", \"bar.js\"],\n\t * names: [\"src\", \"maps\", \"are\", \"fun\"],\n\t * mappings: \"AAAA,E;;ABCDE;\"\n\t * }\n\t * }],\n\t * }\n\t *\n\t * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt\n\t */\n\tfunction IndexedSourceMapConsumer(aSourceMap) {\n\t var sourceMap = aSourceMap;\n\t if (typeof aSourceMap === 'string') {\n\t sourceMap = JSON.parse(aSourceMap.replace(/^\\)\\]\\}'/, ''));\n\t }\n\t\n\t var version = util.getArg(sourceMap, 'version');\n\t var sections = util.getArg(sourceMap, 'sections');\n\t\n\t if (version != this._version) {\n\t throw new Error('Unsupported version: ' + version);\n\t }\n\t\n\t this._sources = new ArraySet();\n\t this._names = new ArraySet();\n\t\n\t var lastOffset = {\n\t line: -1,\n\t column: 0\n\t };\n\t this._sections = sections.map(function (s) {\n\t if (s.url) {\n\t // The url field will require support for asynchronicity.\n\t // See https://github.com/mozilla/source-map/issues/16\n\t throw new Error('Support for url field in sections not implemented.');\n\t }\n\t var offset = util.getArg(s, 'offset');\n\t var offsetLine = util.getArg(offset, 'line');\n\t var offsetColumn = util.getArg(offset, 'column');\n\t\n\t if (offsetLine < lastOffset.line ||\n\t (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) {\n\t throw new Error('Section offsets must be ordered and non-overlapping.');\n\t }\n\t lastOffset = offset;\n\t\n\t return {\n\t generatedOffset: {\n\t // The offset fields are 0-based, but we use 1-based indices when\n\t // encoding/decoding from VLQ.\n\t generatedLine: offsetLine + 1,\n\t generatedColumn: offsetColumn + 1\n\t },\n\t consumer: new SourceMapConsumer(util.getArg(s, 'map'))\n\t }\n\t });\n\t}\n\t\n\tIndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);\n\tIndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer;\n\t\n\t/**\n\t * The version of the source mapping spec that we are consuming.\n\t */\n\tIndexedSourceMapConsumer.prototype._version = 3;\n\t\n\t/**\n\t * The list of original sources.\n\t */\n\tObject.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', {\n\t get: function () {\n\t var sources = [];\n\t for (var i = 0; i < this._sections.length; i++) {\n\t for (var j = 0; j < this._sections[i].consumer.sources.length; j++) {\n\t sources.push(this._sections[i].consumer.sources[j]);\n\t }\n\t }\n\t return sources;\n\t }\n\t});\n\t\n\t/**\n\t * Returns the original source, line, and column information for the generated\n\t * source's line and column positions provided. The only argument is an object\n\t * with the following properties:\n\t *\n\t * - line: The line number in the generated source.\n\t * - column: The column number in the generated source.\n\t *\n\t * and an object is returned with the following properties:\n\t *\n\t * - source: The original source file, or null.\n\t * - line: The line number in the original source, or null.\n\t * - column: The column number in the original source, or null.\n\t * - name: The original identifier, or null.\n\t */\n\tIndexedSourceMapConsumer.prototype.originalPositionFor =\n\t function IndexedSourceMapConsumer_originalPositionFor(aArgs) {\n\t var needle = {\n\t generatedLine: util.getArg(aArgs, 'line'),\n\t generatedColumn: util.getArg(aArgs, 'column')\n\t };\n\t\n\t // Find the section containing the generated position we're trying to map\n\t // to an original position.\n\t var sectionIndex = binarySearch.search(needle, this._sections,\n\t function(needle, section) {\n\t var cmp = needle.generatedLine - section.generatedOffset.generatedLine;\n\t if (cmp) {\n\t return cmp;\n\t }\n\t\n\t return (needle.generatedColumn -\n\t section.generatedOffset.generatedColumn);\n\t });\n\t var section = this._sections[sectionIndex];\n\t\n\t if (!section) {\n\t return {\n\t source: null,\n\t line: null,\n\t column: null,\n\t name: null\n\t };\n\t }\n\t\n\t return section.consumer.originalPositionFor({\n\t line: needle.generatedLine -\n\t (section.generatedOffset.generatedLine - 1),\n\t column: needle.generatedColumn -\n\t (section.generatedOffset.generatedLine === needle.generatedLine\n\t ? section.generatedOffset.generatedColumn - 1\n\t : 0),\n\t bias: aArgs.bias\n\t });\n\t };\n\t\n\t/**\n\t * Return true if we have the source content for every source in the source\n\t * map, false otherwise.\n\t */\n\tIndexedSourceMapConsumer.prototype.hasContentsOfAllSources =\n\t function IndexedSourceMapConsumer_hasContentsOfAllSources() {\n\t return this._sections.every(function (s) {\n\t return s.consumer.hasContentsOfAllSources();\n\t });\n\t };\n\t\n\t/**\n\t * Returns the original source content. The only argument is the url of the\n\t * original source file. Returns null if no original source content is\n\t * available.\n\t */\n\tIndexedSourceMapConsumer.prototype.sourceContentFor =\n\t function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {\n\t for (var i = 0; i < this._sections.length; i++) {\n\t var section = this._sections[i];\n\t\n\t var content = section.consumer.sourceContentFor(aSource, true);\n\t if (content) {\n\t return content;\n\t }\n\t }\n\t if (nullOnMissing) {\n\t return null;\n\t }\n\t else {\n\t throw new Error('\"' + aSource + '\" is not in the SourceMap.');\n\t }\n\t };\n\t\n\t/**\n\t * Returns the generated line and column information for the original source,\n\t * line, and column positions provided. The only argument is an object with\n\t * the following properties:\n\t *\n\t * - source: The filename of the original source.\n\t * - line: The line number in the original source.\n\t * - column: The column number in the original source.\n\t *\n\t * and an object is returned with the following properties:\n\t *\n\t * - line: The line number in the generated source, or null.\n\t * - column: The column number in the generated source, or null.\n\t */\n\tIndexedSourceMapConsumer.prototype.generatedPositionFor =\n\t function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {\n\t for (var i = 0; i < this._sections.length; i++) {\n\t var section = this._sections[i];\n\t\n\t // Only consider this section if the requested source is in the list of\n\t // sources of the consumer.\n\t if (section.consumer.sources.indexOf(util.getArg(aArgs, 'source')) === -1) {\n\t continue;\n\t }\n\t var generatedPosition = section.consumer.generatedPositionFor(aArgs);\n\t if (generatedPosition) {\n\t var ret = {\n\t line: generatedPosition.line +\n\t (section.generatedOffset.generatedLine - 1),\n\t column: generatedPosition.column +\n\t (section.generatedOffset.generatedLine === generatedPosition.line\n\t ? section.generatedOffset.generatedColumn - 1\n\t : 0)\n\t };\n\t return ret;\n\t }\n\t }\n\t\n\t return {\n\t line: null,\n\t column: null\n\t };\n\t };\n\t\n\t/**\n\t * Parse the mappings in a string in to a data structure which we can easily\n\t * query (the ordered arrays in the `this.__generatedMappings` and\n\t * `this.__originalMappings` properties).\n\t */\n\tIndexedSourceMapConsumer.prototype._parseMappings =\n\t function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) {\n\t this.__generatedMappings = [];\n\t this.__originalMappings = [];\n\t for (var i = 0; i < this._sections.length; i++) {\n\t var section = this._sections[i];\n\t var sectionMappings = section.consumer._generatedMappings;\n\t for (var j = 0; j < sectionMappings.length; j++) {\n\t var mapping = sectionMappings[j];\n\t\n\t var source = section.consumer._sources.at(mapping.source);\n\t if (section.consumer.sourceRoot !== null) {\n\t source = util.join(section.consumer.sourceRoot, source);\n\t }\n\t this._sources.add(source);\n\t source = this._sources.indexOf(source);\n\t\n\t var name = section.consumer._names.at(mapping.name);\n\t this._names.add(name);\n\t name = this._names.indexOf(name);\n\t\n\t // The mappings coming from the consumer for the section have\n\t // generated positions relative to the start of the section, so we\n\t // need to offset them to be relative to the start of the concatenated\n\t // generated file.\n\t var adjustedMapping = {\n\t source: source,\n\t generatedLine: mapping.generatedLine +\n\t (section.generatedOffset.generatedLine - 1),\n\t generatedColumn: mapping.generatedColumn +\n\t (section.generatedOffset.generatedLine === mapping.generatedLine\n\t ? section.generatedOffset.generatedColumn - 1\n\t : 0),\n\t originalLine: mapping.originalLine,\n\t originalColumn: mapping.originalColumn,\n\t name: name\n\t };\n\t\n\t this.__generatedMappings.push(adjustedMapping);\n\t if (typeof adjustedMapping.originalLine === 'number') {\n\t this.__originalMappings.push(adjustedMapping);\n\t }\n\t }\n\t }\n\t\n\t quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated);\n\t quickSort(this.__originalMappings, util.compareByOriginalPositions);\n\t };\n\t\n\texports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;\n\n\n/***/ },\n/* 8 */\n/***/ function(module, exports) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\t\n\texports.GREATEST_LOWER_BOUND = 1;\n\texports.LEAST_UPPER_BOUND = 2;\n\t\n\t/**\n\t * Recursive implementation of binary search.\n\t *\n\t * @param aLow Indices here and lower do not contain the needle.\n\t * @param aHigh Indices here and higher do not contain the needle.\n\t * @param aNeedle The element being searched for.\n\t * @param aHaystack The non-empty array being searched.\n\t * @param aCompare Function which takes two elements and returns -1, 0, or 1.\n\t * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or\n\t * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the\n\t * closest element that is smaller than or greater than the one we are\n\t * searching for, respectively, if the exact element cannot be found.\n\t */\n\tfunction recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) {\n\t // This function terminates when one of the following is true:\n\t //\n\t // 1. We find the exact element we are looking for.\n\t //\n\t // 2. We did not find the exact element, but we can return the index of\n\t // the next-closest element.\n\t //\n\t // 3. We did not find the exact element, and there is no next-closest\n\t // element than the one we are searching for, so we return -1.\n\t var mid = Math.floor((aHigh - aLow) / 2) + aLow;\n\t var cmp = aCompare(aNeedle, aHaystack[mid], true);\n\t if (cmp === 0) {\n\t // Found the element we are looking for.\n\t return mid;\n\t }\n\t else if (cmp > 0) {\n\t // Our needle is greater than aHaystack[mid].\n\t if (aHigh - mid > 1) {\n\t // The element is in the upper half.\n\t return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias);\n\t }\n\t\n\t // The exact needle element was not found in this haystack. Determine if\n\t // we are in termination case (3) or (2) and return the appropriate thing.\n\t if (aBias == exports.LEAST_UPPER_BOUND) {\n\t return aHigh < aHaystack.length ? aHigh : -1;\n\t } else {\n\t return mid;\n\t }\n\t }\n\t else {\n\t // Our needle is less than aHaystack[mid].\n\t if (mid - aLow > 1) {\n\t // The element is in the lower half.\n\t return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias);\n\t }\n\t\n\t // we are in termination case (3) or (2) and return the appropriate thing.\n\t if (aBias == exports.LEAST_UPPER_BOUND) {\n\t return mid;\n\t } else {\n\t return aLow < 0 ? -1 : aLow;\n\t }\n\t }\n\t}\n\t\n\t/**\n\t * This is an implementation of binary search which will always try and return\n\t * the index of the closest element if there is no exact hit. This is because\n\t * mappings between original and generated line/col pairs are single points,\n\t * and there is an implicit region between each of them, so a miss just means\n\t * that you aren't on the very start of a region.\n\t *\n\t * @param aNeedle The element you are looking for.\n\t * @param aHaystack The array that is being searched.\n\t * @param aCompare A function which takes the needle and an element in the\n\t * array and returns -1, 0, or 1 depending on whether the needle is less\n\t * than, equal to, or greater than the element, respectively.\n\t * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or\n\t * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the\n\t * closest element that is smaller than or greater than the one we are\n\t * searching for, respectively, if the exact element cannot be found.\n\t * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'.\n\t */\n\texports.search = function search(aNeedle, aHaystack, aCompare, aBias) {\n\t if (aHaystack.length === 0) {\n\t return -1;\n\t }\n\t\n\t var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack,\n\t aCompare, aBias || exports.GREATEST_LOWER_BOUND);\n\t if (index < 0) {\n\t return -1;\n\t }\n\t\n\t // We have found either the exact element, or the next-closest element than\n\t // the one we are searching for. However, there may be more than one such\n\t // element. Make sure we always return the smallest of these.\n\t while (index - 1 >= 0) {\n\t if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) {\n\t break;\n\t }\n\t --index;\n\t }\n\t\n\t return index;\n\t};\n\n\n/***/ },\n/* 9 */\n/***/ function(module, exports) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\t\n\t// It turns out that some (most?) JavaScript engines don't self-host\n\t// `Array.prototype.sort`. This makes sense because C++ will likely remain\n\t// faster than JS when doing raw CPU-intensive sorting. However, when using a\n\t// custom comparator function, calling back and forth between the VM's C++ and\n\t// JIT'd JS is rather slow *and* loses JIT type information, resulting in\n\t// worse generated code for the comparator function than would be optimal. In\n\t// fact, when sorting with a comparator, these costs outweigh the benefits of\n\t// sorting in C++. By using our own JS-implemented Quick Sort (below), we get\n\t// a ~3500ms mean speed-up in `bench/bench.html`.\n\t\n\t/**\n\t * Swap the elements indexed by `x` and `y` in the array `ary`.\n\t *\n\t * @param {Array} ary\n\t * The array.\n\t * @param {Number} x\n\t * The index of the first item.\n\t * @param {Number} y\n\t * The index of the second item.\n\t */\n\tfunction swap(ary, x, y) {\n\t var temp = ary[x];\n\t ary[x] = ary[y];\n\t ary[y] = temp;\n\t}\n\t\n\t/**\n\t * Returns a random integer within the range `low .. high` inclusive.\n\t *\n\t * @param {Number} low\n\t * The lower bound on the range.\n\t * @param {Number} high\n\t * The upper bound on the range.\n\t */\n\tfunction randomIntInRange(low, high) {\n\t return Math.round(low + (Math.random() * (high - low)));\n\t}\n\t\n\t/**\n\t * The Quick Sort algorithm.\n\t *\n\t * @param {Array} ary\n\t * An array to sort.\n\t * @param {function} comparator\n\t * Function to use to compare two items.\n\t * @param {Number} p\n\t * Start index of the array\n\t * @param {Number} r\n\t * End index of the array\n\t */\n\tfunction doQuickSort(ary, comparator, p, r) {\n\t // If our lower bound is less than our upper bound, we (1) partition the\n\t // array into two pieces and (2) recurse on each half. If it is not, this is\n\t // the empty array and our base case.\n\t\n\t if (p < r) {\n\t // (1) Partitioning.\n\t //\n\t // The partitioning chooses a pivot between `p` and `r` and moves all\n\t // elements that are less than or equal to the pivot to the before it, and\n\t // all the elements that are greater than it after it. The effect is that\n\t // once partition is done, the pivot is in the exact place it will be when\n\t // the array is put in sorted order, and it will not need to be moved\n\t // again. This runs in O(n) time.\n\t\n\t // Always choose a random pivot so that an input array which is reverse\n\t // sorted does not cause O(n^2) running time.\n\t var pivotIndex = randomIntInRange(p, r);\n\t var i = p - 1;\n\t\n\t swap(ary, pivotIndex, r);\n\t var pivot = ary[r];\n\t\n\t // Immediately after `j` is incremented in this loop, the following hold\n\t // true:\n\t //\n\t // * Every element in `ary[p .. i]` is less than or equal to the pivot.\n\t //\n\t // * Every element in `ary[i+1 .. j-1]` is greater than the pivot.\n\t for (var j = p; j < r; j++) {\n\t if (comparator(ary[j], pivot) <= 0) {\n\t i += 1;\n\t swap(ary, i, j);\n\t }\n\t }\n\t\n\t swap(ary, i + 1, j);\n\t var q = i + 1;\n\t\n\t // (2) Recurse on each half.\n\t\n\t doQuickSort(ary, comparator, p, q - 1);\n\t doQuickSort(ary, comparator, q + 1, r);\n\t }\n\t}\n\t\n\t/**\n\t * Sort the given array in-place with the given comparator function.\n\t *\n\t * @param {Array} ary\n\t * An array to sort.\n\t * @param {function} comparator\n\t * Function to use to compare two items.\n\t */\n\texports.quickSort = function (ary, comparator) {\n\t doQuickSort(ary, comparator, 0, ary.length - 1);\n\t};\n\n\n/***/ },\n/* 10 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\t\n\tvar SourceMapGenerator = __webpack_require__(1).SourceMapGenerator;\n\tvar util = __webpack_require__(4);\n\t\n\t// Matches a Windows-style `\\r\\n` newline or a `\\n` newline used by all other\n\t// operating systems these days (capturing the result).\n\tvar REGEX_NEWLINE = /(\\r?\\n)/;\n\t\n\t// Newline character code for charCodeAt() comparisons\n\tvar NEWLINE_CODE = 10;\n\t\n\t// Private symbol for identifying `SourceNode`s when multiple versions of\n\t// the source-map library are loaded. This MUST NOT CHANGE across\n\t// versions!\n\tvar isSourceNode = \"$$$isSourceNode$$$\";\n\t\n\t/**\n\t * SourceNodes provide a way to abstract over interpolating/concatenating\n\t * snippets of generated JavaScript source code while maintaining the line and\n\t * column information associated with the original source code.\n\t *\n\t * @param aLine The original line number.\n\t * @param aColumn The original column number.\n\t * @param aSource The original source's filename.\n\t * @param aChunks Optional. An array of strings which are snippets of\n\t * generated JS, or other SourceNodes.\n\t * @param aName The original identifier.\n\t */\n\tfunction SourceNode(aLine, aColumn, aSource, aChunks, aName) {\n\t this.children = [];\n\t this.sourceContents = {};\n\t this.line = aLine == null ? null : aLine;\n\t this.column = aColumn == null ? null : aColumn;\n\t this.source = aSource == null ? null : aSource;\n\t this.name = aName == null ? null : aName;\n\t this[isSourceNode] = true;\n\t if (aChunks != null) this.add(aChunks);\n\t}\n\t\n\t/**\n\t * Creates a SourceNode from generated code and a SourceMapConsumer.\n\t *\n\t * @param aGeneratedCode The generated code\n\t * @param aSourceMapConsumer The SourceMap for the generated code\n\t * @param aRelativePath Optional. The path that relative sources in the\n\t * SourceMapConsumer should be relative to.\n\t */\n\tSourceNode.fromStringWithSourceMap =\n\t function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) {\n\t // The SourceNode we want to fill with the generated code\n\t // and the SourceMap\n\t var node = new SourceNode();\n\t\n\t // All even indices of this array are one line of the generated code,\n\t // while all odd indices are the newlines between two adjacent lines\n\t // (since `REGEX_NEWLINE` captures its match).\n\t // Processed fragments are removed from this array, by calling `shiftNextLine`.\n\t var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);\n\t var shiftNextLine = function() {\n\t var lineContents = remainingLines.shift();\n\t // The last line of a file might not have a newline.\n\t var newLine = remainingLines.shift() || \"\";\n\t return lineContents + newLine;\n\t };\n\t\n\t // We need to remember the position of \"remainingLines\"\n\t var lastGeneratedLine = 1, lastGeneratedColumn = 0;\n\t\n\t // The generate SourceNodes we need a code range.\n\t // To extract it current and last mapping is used.\n\t // Here we store the last mapping.\n\t var lastMapping = null;\n\t\n\t aSourceMapConsumer.eachMapping(function (mapping) {\n\t if (lastMapping !== null) {\n\t // We add the code from \"lastMapping\" to \"mapping\":\n\t // First check if there is a new line in between.\n\t if (lastGeneratedLine < mapping.generatedLine) {\n\t // Associate first line with \"lastMapping\"\n\t addMappingWithCode(lastMapping, shiftNextLine());\n\t lastGeneratedLine++;\n\t lastGeneratedColumn = 0;\n\t // The remaining code is added without mapping\n\t } else {\n\t // There is no new line in between.\n\t // Associate the code between \"lastGeneratedColumn\" and\n\t // \"mapping.generatedColumn\" with \"lastMapping\"\n\t var nextLine = remainingLines[0];\n\t var code = nextLine.substr(0, mapping.generatedColumn -\n\t lastGeneratedColumn);\n\t remainingLines[0] = nextLine.substr(mapping.generatedColumn -\n\t lastGeneratedColumn);\n\t lastGeneratedColumn = mapping.generatedColumn;\n\t addMappingWithCode(lastMapping, code);\n\t // No more remaining code, continue\n\t lastMapping = mapping;\n\t return;\n\t }\n\t }\n\t // We add the generated code until the first mapping\n\t // to the SourceNode without any mapping.\n\t // Each line is added as separate string.\n\t while (lastGeneratedLine < mapping.generatedLine) {\n\t node.add(shiftNextLine());\n\t lastGeneratedLine++;\n\t }\n\t if (lastGeneratedColumn < mapping.generatedColumn) {\n\t var nextLine = remainingLines[0];\n\t node.add(nextLine.substr(0, mapping.generatedColumn));\n\t remainingLines[0] = nextLine.substr(mapping.generatedColumn);\n\t lastGeneratedColumn = mapping.generatedColumn;\n\t }\n\t lastMapping = mapping;\n\t }, this);\n\t // We have processed all mappings.\n\t if (remainingLines.length > 0) {\n\t if (lastMapping) {\n\t // Associate the remaining code in the current line with \"lastMapping\"\n\t addMappingWithCode(lastMapping, shiftNextLine());\n\t }\n\t // and add the remaining lines without any mapping\n\t node.add(remainingLines.join(\"\"));\n\t }\n\t\n\t // Copy sourcesContent into SourceNode\n\t aSourceMapConsumer.sources.forEach(function (sourceFile) {\n\t var content = aSourceMapConsumer.sourceContentFor(sourceFile);\n\t if (content != null) {\n\t if (aRelativePath != null) {\n\t sourceFile = util.join(aRelativePath, sourceFile);\n\t }\n\t node.setSourceContent(sourceFile, content);\n\t }\n\t });\n\t\n\t return node;\n\t\n\t function addMappingWithCode(mapping, code) {\n\t if (mapping === null || mapping.source === undefined) {\n\t node.add(code);\n\t } else {\n\t var source = aRelativePath\n\t ? util.join(aRelativePath, mapping.source)\n\t : mapping.source;\n\t node.add(new SourceNode(mapping.originalLine,\n\t mapping.originalColumn,\n\t source,\n\t code,\n\t mapping.name));\n\t }\n\t }\n\t };\n\t\n\t/**\n\t * Add a chunk of generated JS to this source node.\n\t *\n\t * @param aChunk A string snippet of generated JS code, another instance of\n\t * SourceNode, or an array where each member is one of those things.\n\t */\n\tSourceNode.prototype.add = function SourceNode_add(aChunk) {\n\t if (Array.isArray(aChunk)) {\n\t aChunk.forEach(function (chunk) {\n\t this.add(chunk);\n\t }, this);\n\t }\n\t else if (aChunk[isSourceNode] || typeof aChunk === \"string\") {\n\t if (aChunk) {\n\t this.children.push(aChunk);\n\t }\n\t }\n\t else {\n\t throw new TypeError(\n\t \"Expected a SourceNode, string, or an array of SourceNodes and strings. Got \" + aChunk\n\t );\n\t }\n\t return this;\n\t};\n\t\n\t/**\n\t * Add a chunk of generated JS to the beginning of this source node.\n\t *\n\t * @param aChunk A string snippet of generated JS code, another instance of\n\t * SourceNode, or an array where each member is one of those things.\n\t */\n\tSourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {\n\t if (Array.isArray(aChunk)) {\n\t for (var i = aChunk.length-1; i >= 0; i--) {\n\t this.prepend(aChunk[i]);\n\t }\n\t }\n\t else if (aChunk[isSourceNode] || typeof aChunk === \"string\") {\n\t this.children.unshift(aChunk);\n\t }\n\t else {\n\t throw new TypeError(\n\t \"Expected a SourceNode, string, or an array of SourceNodes and strings. Got \" + aChunk\n\t );\n\t }\n\t return this;\n\t};\n\t\n\t/**\n\t * Walk over the tree of JS snippets in this node and its children. The\n\t * walking function is called once for each snippet of JS and is passed that\n\t * snippet and the its original associated source's line/column location.\n\t *\n\t * @param aFn The traversal function.\n\t */\n\tSourceNode.prototype.walk = function SourceNode_walk(aFn) {\n\t var chunk;\n\t for (var i = 0, len = this.children.length; i < len; i++) {\n\t chunk = this.children[i];\n\t if (chunk[isSourceNode]) {\n\t chunk.walk(aFn);\n\t }\n\t else {\n\t if (chunk !== '') {\n\t aFn(chunk, { source: this.source,\n\t line: this.line,\n\t column: this.column,\n\t name: this.name });\n\t }\n\t }\n\t }\n\t};\n\t\n\t/**\n\t * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between\n\t * each of `this.children`.\n\t *\n\t * @param aSep The separator.\n\t */\n\tSourceNode.prototype.join = function SourceNode_join(aSep) {\n\t var newChildren;\n\t var i;\n\t var len = this.children.length;\n\t if (len > 0) {\n\t newChildren = [];\n\t for (i = 0; i < len-1; i++) {\n\t newChildren.push(this.children[i]);\n\t newChildren.push(aSep);\n\t }\n\t newChildren.push(this.children[i]);\n\t this.children = newChildren;\n\t }\n\t return this;\n\t};\n\t\n\t/**\n\t * Call String.prototype.replace on the very right-most source snippet. Useful\n\t * for trimming whitespace from the end of a source node, etc.\n\t *\n\t * @param aPattern The pattern to replace.\n\t * @param aReplacement The thing to replace the pattern with.\n\t */\n\tSourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {\n\t var lastChild = this.children[this.children.length - 1];\n\t if (lastChild[isSourceNode]) {\n\t lastChild.replaceRight(aPattern, aReplacement);\n\t }\n\t else if (typeof lastChild === 'string') {\n\t this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);\n\t }\n\t else {\n\t this.children.push(''.replace(aPattern, aReplacement));\n\t }\n\t return this;\n\t};\n\t\n\t/**\n\t * Set the source content for a source file. This will be added to the SourceMapGenerator\n\t * in the sourcesContent field.\n\t *\n\t * @param aSourceFile The filename of the source file\n\t * @param aSourceContent The content of the source file\n\t */\n\tSourceNode.prototype.setSourceContent =\n\t function SourceNode_setSourceContent(aSourceFile, aSourceContent) {\n\t this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;\n\t };\n\t\n\t/**\n\t * Walk over the tree of SourceNodes. The walking function is called for each\n\t * source file content and is passed the filename and source content.\n\t *\n\t * @param aFn The traversal function.\n\t */\n\tSourceNode.prototype.walkSourceContents =\n\t function SourceNode_walkSourceContents(aFn) {\n\t for (var i = 0, len = this.children.length; i < len; i++) {\n\t if (this.children[i][isSourceNode]) {\n\t this.children[i].walkSourceContents(aFn);\n\t }\n\t }\n\t\n\t var sources = Object.keys(this.sourceContents);\n\t for (var i = 0, len = sources.length; i < len; i++) {\n\t aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);\n\t }\n\t };\n\t\n\t/**\n\t * Return the string representation of this source node. Walks over the tree\n\t * and concatenates all the various snippets together to one string.\n\t */\n\tSourceNode.prototype.toString = function SourceNode_toString() {\n\t var str = \"\";\n\t this.walk(function (chunk) {\n\t str += chunk;\n\t });\n\t return str;\n\t};\n\t\n\t/**\n\t * Returns the string representation of this source node along with a source\n\t * map.\n\t */\n\tSourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {\n\t var generated = {\n\t code: \"\",\n\t line: 1,\n\t column: 0\n\t };\n\t var map = new SourceMapGenerator(aArgs);\n\t var sourceMappingActive = false;\n\t var lastOriginalSource = null;\n\t var lastOriginalLine = null;\n\t var lastOriginalColumn = null;\n\t var lastOriginalName = null;\n\t this.walk(function (chunk, original) {\n\t generated.code += chunk;\n\t if (original.source !== null\n\t && original.line !== null\n\t && original.column !== null) {\n\t if(lastOriginalSource !== original.source\n\t || lastOriginalLine !== original.line\n\t || lastOriginalColumn !== original.column\n\t || lastOriginalName !== original.name) {\n\t map.addMapping({\n\t source: original.source,\n\t original: {\n\t line: original.line,\n\t column: original.column\n\t },\n\t generated: {\n\t line: generated.line,\n\t column: generated.column\n\t },\n\t name: original.name\n\t });\n\t }\n\t lastOriginalSource = original.source;\n\t lastOriginalLine = original.line;\n\t lastOriginalColumn = original.column;\n\t lastOriginalName = original.name;\n\t sourceMappingActive = true;\n\t } else if (sourceMappingActive) {\n\t map.addMapping({\n\t generated: {\n\t line: generated.line,\n\t column: generated.column\n\t }\n\t });\n\t lastOriginalSource = null;\n\t sourceMappingActive = false;\n\t }\n\t for (var idx = 0, length = chunk.length; idx < length; idx++) {\n\t if (chunk.charCodeAt(idx) === NEWLINE_CODE) {\n\t generated.line++;\n\t generated.column = 0;\n\t // Mappings end at eol\n\t if (idx + 1 === length) {\n\t lastOriginalSource = null;\n\t sourceMappingActive = false;\n\t } else if (sourceMappingActive) {\n\t map.addMapping({\n\t source: original.source,\n\t original: {\n\t line: original.line,\n\t column: original.column\n\t },\n\t generated: {\n\t line: generated.line,\n\t column: generated.column\n\t },\n\t name: original.name\n\t });\n\t }\n\t } else {\n\t generated.column++;\n\t }\n\t }\n\t });\n\t this.walkSourceContents(function (sourceFile, sourceContent) {\n\t map.setSourceContent(sourceFile, sourceContent);\n\t });\n\t\n\t return { code: generated.code, map: map };\n\t};\n\t\n\texports.SourceNode = SourceNode;\n\n\n/***/ }\n/******/ ])\n});\n;\n\n\n/** WEBPACK FOOTER **\n ** source-map.min.js\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 5d9a9f4df3bd553ed2f9\n **/","/*\n * Copyright 2009-2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE.txt or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\nexports.SourceMapGenerator = require('./lib/source-map-generator').SourceMapGenerator;\nexports.SourceMapConsumer = require('./lib/source-map-consumer').SourceMapConsumer;\nexports.SourceNode = require('./lib/source-node').SourceNode;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./source-map.js\n ** module id = 0\n ** module chunks = 0\n **/","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\nvar base64VLQ = require('./base64-vlq');\nvar util = require('./util');\nvar ArraySet = require('./array-set').ArraySet;\nvar MappingList = require('./mapping-list').MappingList;\n\n/**\n * An instance of the SourceMapGenerator represents a source map which is\n * being built incrementally. You may pass an object with the following\n * properties:\n *\n * - file: The filename of the generated source.\n * - sourceRoot: A root for all relative URLs in this source map.\n */\nfunction SourceMapGenerator(aArgs) {\n if (!aArgs) {\n aArgs = {};\n }\n this._file = util.getArg(aArgs, 'file', null);\n this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);\n this._skipValidation = util.getArg(aArgs, 'skipValidation', false);\n this._sources = new ArraySet();\n this._names = new ArraySet();\n this._mappings = new MappingList();\n this._sourcesContents = null;\n}\n\nSourceMapGenerator.prototype._version = 3;\n\n/**\n * Creates a new SourceMapGenerator based on a SourceMapConsumer\n *\n * @param aSourceMapConsumer The SourceMap.\n */\nSourceMapGenerator.fromSourceMap =\n function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {\n var sourceRoot = aSourceMapConsumer.sourceRoot;\n var generator = new SourceMapGenerator({\n file: aSourceMapConsumer.file,\n sourceRoot: sourceRoot\n });\n aSourceMapConsumer.eachMapping(function (mapping) {\n var newMapping = {\n generated: {\n line: mapping.generatedLine,\n column: mapping.generatedColumn\n }\n };\n\n if (mapping.source != null) {\n newMapping.source = mapping.source;\n if (sourceRoot != null) {\n newMapping.source = util.relative(sourceRoot, newMapping.source);\n }\n\n newMapping.original = {\n line: mapping.originalLine,\n column: mapping.originalColumn\n };\n\n if (mapping.name != null) {\n newMapping.name = mapping.name;\n }\n }\n\n generator.addMapping(newMapping);\n });\n aSourceMapConsumer.sources.forEach(function (sourceFile) {\n var content = aSourceMapConsumer.sourceContentFor(sourceFile);\n if (content != null) {\n generator.setSourceContent(sourceFile, content);\n }\n });\n return generator;\n };\n\n/**\n * Add a single mapping from original source line and column to the generated\n * source's line and column for this source map being created. The mapping\n * object should have the following properties:\n *\n * - generated: An object with the generated line and column positions.\n * - original: An object with the original line and column positions.\n * - source: The original source file (relative to the sourceRoot).\n * - name: An optional original token name for this mapping.\n */\nSourceMapGenerator.prototype.addMapping =\n function SourceMapGenerator_addMapping(aArgs) {\n var generated = util.getArg(aArgs, 'generated');\n var original = util.getArg(aArgs, 'original', null);\n var source = util.getArg(aArgs, 'source', null);\n var name = util.getArg(aArgs, 'name', null);\n\n if (!this._skipValidation) {\n this._validateMapping(generated, original, source, name);\n }\n\n if (source != null) {\n source = String(source);\n if (!this._sources.has(source)) {\n this._sources.add(source);\n }\n }\n\n if (name != null) {\n name = String(name);\n if (!this._names.has(name)) {\n this._names.add(name);\n }\n }\n\n this._mappings.add({\n generatedLine: generated.line,\n generatedColumn: generated.column,\n originalLine: original != null && original.line,\n originalColumn: original != null && original.column,\n source: source,\n name: name\n });\n };\n\n/**\n * Set the source content for a source file.\n */\nSourceMapGenerator.prototype.setSourceContent =\n function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {\n var source = aSourceFile;\n if (this._sourceRoot != null) {\n source = util.relative(this._sourceRoot, source);\n }\n\n if (aSourceContent != null) {\n // Add the source content to the _sourcesContents map.\n // Create a new _sourcesContents map if the property is null.\n if (!this._sourcesContents) {\n this._sourcesContents = Object.create(null);\n }\n this._sourcesContents[util.toSetString(source)] = aSourceContent;\n } else if (this._sourcesContents) {\n // Remove the source file from the _sourcesContents map.\n // If the _sourcesContents map is empty, set the property to null.\n delete this._sourcesContents[util.toSetString(source)];\n if (Object.keys(this._sourcesContents).length === 0) {\n this._sourcesContents = null;\n }\n }\n };\n\n/**\n * Applies the mappings of a sub-source-map for a specific source file to the\n * source map being generated. Each mapping to the supplied source file is\n * rewritten using the supplied source map. Note: The resolution for the\n * resulting mappings is the minimium of this map and the supplied map.\n *\n * @param aSourceMapConsumer The source map to be applied.\n * @param aSourceFile Optional. The filename of the source file.\n * If omitted, SourceMapConsumer's file property will be used.\n * @param aSourceMapPath Optional. The dirname of the path to the source map\n * to be applied. If relative, it is relative to the SourceMapConsumer.\n * This parameter is needed when the two source maps aren't in the same\n * directory, and the source map to be applied contains relative source\n * paths. If so, those relative source paths need to be rewritten\n * relative to the SourceMapGenerator.\n */\nSourceMapGenerator.prototype.applySourceMap =\n function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {\n var sourceFile = aSourceFile;\n // If aSourceFile is omitted, we will use the file property of the SourceMap\n if (aSourceFile == null) {\n if (aSourceMapConsumer.file == null) {\n throw new Error(\n 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +\n 'or the source map\\'s \"file\" property. Both were omitted.'\n );\n }\n sourceFile = aSourceMapConsumer.file;\n }\n var sourceRoot = this._sourceRoot;\n // Make \"sourceFile\" relative if an absolute Url is passed.\n if (sourceRoot != null) {\n sourceFile = util.relative(sourceRoot, sourceFile);\n }\n // Applying the SourceMap can add and remove items from the sources and\n // the names array.\n var newSources = new ArraySet();\n var newNames = new ArraySet();\n\n // Find mappings for the \"sourceFile\"\n this._mappings.unsortedForEach(function (mapping) {\n if (mapping.source === sourceFile && mapping.originalLine != null) {\n // Check if it can be mapped by the source map, then update the mapping.\n var original = aSourceMapConsumer.originalPositionFor({\n line: mapping.originalLine,\n column: mapping.originalColumn\n });\n if (original.source != null) {\n // Copy mapping\n mapping.source = original.source;\n if (aSourceMapPath != null) {\n mapping.source = util.join(aSourceMapPath, mapping.source)\n }\n if (sourceRoot != null) {\n mapping.source = util.relative(sourceRoot, mapping.source);\n }\n mapping.originalLine = original.line;\n mapping.originalColumn = original.column;\n if (original.name != null) {\n mapping.name = original.name;\n }\n }\n }\n\n var source = mapping.source;\n if (source != null && !newSources.has(source)) {\n newSources.add(source);\n }\n\n var name = mapping.name;\n if (name != null && !newNames.has(name)) {\n newNames.add(name);\n }\n\n }, this);\n this._sources = newSources;\n this._names = newNames;\n\n // Copy sourcesContents of applied map.\n aSourceMapConsumer.sources.forEach(function (sourceFile) {\n var content = aSourceMapConsumer.sourceContentFor(sourceFile);\n if (content != null) {\n if (aSourceMapPath != null) {\n sourceFile = util.join(aSourceMapPath, sourceFile);\n }\n if (sourceRoot != null) {\n sourceFile = util.relative(sourceRoot, sourceFile);\n }\n this.setSourceContent(sourceFile, content);\n }\n }, this);\n };\n\n/**\n * A mapping can have one of the three levels of data:\n *\n * 1. Just the generated position.\n * 2. The Generated position, original position, and original source.\n * 3. Generated and original position, original source, as well as a name\n * token.\n *\n * To maintain consistency, we validate that any new mapping being added falls\n * in to one of these categories.\n */\nSourceMapGenerator.prototype._validateMapping =\n function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,\n aName) {\n if (aGenerated && 'line' in aGenerated && 'column' in aGenerated\n && aGenerated.line > 0 && aGenerated.column >= 0\n && !aOriginal && !aSource && !aName) {\n // Case 1.\n return;\n }\n else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated\n && aOriginal && 'line' in aOriginal && 'column' in aOriginal\n && aGenerated.line > 0 && aGenerated.column >= 0\n && aOriginal.line > 0 && aOriginal.column >= 0\n && aSource) {\n // Cases 2 and 3.\n return;\n }\n else {\n throw new Error('Invalid mapping: ' + JSON.stringify({\n generated: aGenerated,\n source: aSource,\n original: aOriginal,\n name: aName\n }));\n }\n };\n\n/**\n * Serialize the accumulated mappings in to the stream of base 64 VLQs\n * specified by the source map format.\n */\nSourceMapGenerator.prototype._serializeMappings =\n function SourceMapGenerator_serializeMappings() {\n var previousGeneratedColumn = 0;\n var previousGeneratedLine = 1;\n var previousOriginalColumn = 0;\n var previousOriginalLine = 0;\n var previousName = 0;\n var previousSource = 0;\n var result = '';\n var next;\n var mapping;\n var nameIdx;\n var sourceIdx;\n\n var mappings = this._mappings.toArray();\n for (var i = 0, len = mappings.length; i < len; i++) {\n mapping = mappings[i];\n next = ''\n\n if (mapping.generatedLine !== previousGeneratedLine) {\n previousGeneratedColumn = 0;\n while (mapping.generatedLine !== previousGeneratedLine) {\n next += ';';\n previousGeneratedLine++;\n }\n }\n else {\n if (i > 0) {\n if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {\n continue;\n }\n next += ',';\n }\n }\n\n next += base64VLQ.encode(mapping.generatedColumn\n - previousGeneratedColumn);\n previousGeneratedColumn = mapping.generatedColumn;\n\n if (mapping.source != null) {\n sourceIdx = this._sources.indexOf(mapping.source);\n next += base64VLQ.encode(sourceIdx - previousSource);\n previousSource = sourceIdx;\n\n // lines are stored 0-based in SourceMap spec version 3\n next += base64VLQ.encode(mapping.originalLine - 1\n - previousOriginalLine);\n previousOriginalLine = mapping.originalLine - 1;\n\n next += base64VLQ.encode(mapping.originalColumn\n - previousOriginalColumn);\n previousOriginalColumn = mapping.originalColumn;\n\n if (mapping.name != null) {\n nameIdx = this._names.indexOf(mapping.name);\n next += base64VLQ.encode(nameIdx - previousName);\n previousName = nameIdx;\n }\n }\n\n result += next;\n }\n\n return result;\n };\n\nSourceMapGenerator.prototype._generateSourcesContent =\n function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {\n return aSources.map(function (source) {\n if (!this._sourcesContents) {\n return null;\n }\n if (aSourceRoot != null) {\n source = util.relative(aSourceRoot, source);\n }\n var key = util.toSetString(source);\n return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)\n ? this._sourcesContents[key]\n : null;\n }, this);\n };\n\n/**\n * Externalize the source map.\n */\nSourceMapGenerator.prototype.toJSON =\n function SourceMapGenerator_toJSON() {\n var map = {\n version: this._version,\n sources: this._sources.toArray(),\n names: this._names.toArray(),\n mappings: this._serializeMappings()\n };\n if (this._file != null) {\n map.file = this._file;\n }\n if (this._sourceRoot != null) {\n map.sourceRoot = this._sourceRoot;\n }\n if (this._sourcesContents) {\n map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);\n }\n\n return map;\n };\n\n/**\n * Render the source map being generated to a string.\n */\nSourceMapGenerator.prototype.toString =\n function SourceMapGenerator_toString() {\n return JSON.stringify(this.toJSON());\n };\n\nexports.SourceMapGenerator = SourceMapGenerator;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./lib/source-map-generator.js\n ** module id = 1\n ** module chunks = 0\n **/","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n *\n * Based on the Base 64 VLQ implementation in Closure Compiler:\n * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java\n *\n * Copyright 2011 The Closure Compiler Authors. All rights reserved.\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following\n * disclaimer in the documentation and/or other materials provided\n * with the distribution.\n * * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nvar base64 = require('./base64');\n\n// A single base 64 digit can contain 6 bits of data. For the base 64 variable\n// length quantities we use in the source map spec, the first bit is the sign,\n// the next four bits are the actual value, and the 6th bit is the\n// continuation bit. The continuation bit tells us whether there are more\n// digits in this value following this digit.\n//\n// Continuation\n// | Sign\n// | |\n// V V\n// 101011\n\nvar VLQ_BASE_SHIFT = 5;\n\n// binary: 100000\nvar VLQ_BASE = 1 << VLQ_BASE_SHIFT;\n\n// binary: 011111\nvar VLQ_BASE_MASK = VLQ_BASE - 1;\n\n// binary: 100000\nvar VLQ_CONTINUATION_BIT = VLQ_BASE;\n\n/**\n * Converts from a two-complement value to a value where the sign bit is\n * placed in the least significant bit. For example, as decimals:\n * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)\n * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)\n */\nfunction toVLQSigned(aValue) {\n return aValue < 0\n ? ((-aValue) << 1) + 1\n : (aValue << 1) + 0;\n}\n\n/**\n * Converts to a two-complement value from a value where the sign bit is\n * placed in the least significant bit. For example, as decimals:\n * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1\n * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2\n */\nfunction fromVLQSigned(aValue) {\n var isNegative = (aValue & 1) === 1;\n var shifted = aValue >> 1;\n return isNegative\n ? -shifted\n : shifted;\n}\n\n/**\n * Returns the base 64 VLQ encoded value.\n */\nexports.encode = function base64VLQ_encode(aValue) {\n var encoded = \"\";\n var digit;\n\n var vlq = toVLQSigned(aValue);\n\n do {\n digit = vlq & VLQ_BASE_MASK;\n vlq >>>= VLQ_BASE_SHIFT;\n if (vlq > 0) {\n // There are still more digits in this value, so we must make sure the\n // continuation bit is marked.\n digit |= VLQ_CONTINUATION_BIT;\n }\n encoded += base64.encode(digit);\n } while (vlq > 0);\n\n return encoded;\n};\n\n/**\n * Decodes the next base 64 VLQ value from the given string and returns the\n * value and the rest of the string via the out parameter.\n */\nexports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {\n var strLen = aStr.length;\n var result = 0;\n var shift = 0;\n var continuation, digit;\n\n do {\n if (aIndex >= strLen) {\n throw new Error(\"Expected more digits in base 64 VLQ value.\");\n }\n\n digit = base64.decode(aStr.charCodeAt(aIndex++));\n if (digit === -1) {\n throw new Error(\"Invalid base64 digit: \" + aStr.charAt(aIndex - 1));\n }\n\n continuation = !!(digit & VLQ_CONTINUATION_BIT);\n digit &= VLQ_BASE_MASK;\n result = result + (digit << shift);\n shift += VLQ_BASE_SHIFT;\n } while (continuation);\n\n aOutParam.value = fromVLQSigned(result);\n aOutParam.rest = aIndex;\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./lib/base64-vlq.js\n ** module id = 2\n ** module chunks = 0\n **/","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\nvar intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');\n\n/**\n * Encode an integer in the range of 0 to 63 to a single base 64 digit.\n */\nexports.encode = function (number) {\n if (0 <= number && number < intToCharMap.length) {\n return intToCharMap[number];\n }\n throw new TypeError(\"Must be between 0 and 63: \" + number);\n};\n\n/**\n * Decode a single base 64 character code digit to an integer. Returns -1 on\n * failure.\n */\nexports.decode = function (charCode) {\n var bigA = 65; // 'A'\n var bigZ = 90; // 'Z'\n\n var littleA = 97; // 'a'\n var littleZ = 122; // 'z'\n\n var zero = 48; // '0'\n var nine = 57; // '9'\n\n var plus = 43; // '+'\n var slash = 47; // '/'\n\n var littleOffset = 26;\n var numberOffset = 52;\n\n // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ\n if (bigA <= charCode && charCode <= bigZ) {\n return (charCode - bigA);\n }\n\n // 26 - 51: abcdefghijklmnopqrstuvwxyz\n if (littleA <= charCode && charCode <= littleZ) {\n return (charCode - littleA + littleOffset);\n }\n\n // 52 - 61: 0123456789\n if (zero <= charCode && charCode <= nine) {\n return (charCode - zero + numberOffset);\n }\n\n // 62: +\n if (charCode == plus) {\n return 62;\n }\n\n // 63: /\n if (charCode == slash) {\n return 63;\n }\n\n // Invalid base64 digit.\n return -1;\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./lib/base64.js\n ** module id = 3\n ** module chunks = 0\n **/","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\n/**\n * This is a helper function for getting values from parameter/options\n * objects.\n *\n * @param args The object we are extracting values from\n * @param name The name of the property we are getting.\n * @param defaultValue An optional value to return if the property is missing\n * from the object. If this is not specified and the property is missing, an\n * error will be thrown.\n */\nfunction getArg(aArgs, aName, aDefaultValue) {\n if (aName in aArgs) {\n return aArgs[aName];\n } else if (arguments.length === 3) {\n return aDefaultValue;\n } else {\n throw new Error('\"' + aName + '\" is a required argument.');\n }\n}\nexports.getArg = getArg;\n\nvar urlRegexp = /^(?:([\\w+\\-.]+):)?\\/\\/(?:(\\w+:\\w+)@)?([\\w.]*)(?::(\\d+))?(\\S*)$/;\nvar dataUrlRegexp = /^data:.+\\,.+$/;\n\nfunction urlParse(aUrl) {\n var match = aUrl.match(urlRegexp);\n if (!match) {\n return null;\n }\n return {\n scheme: match[1],\n auth: match[2],\n host: match[3],\n port: match[4],\n path: match[5]\n };\n}\nexports.urlParse = urlParse;\n\nfunction urlGenerate(aParsedUrl) {\n var url = '';\n if (aParsedUrl.scheme) {\n url += aParsedUrl.scheme + ':';\n }\n url += '//';\n if (aParsedUrl.auth) {\n url += aParsedUrl.auth + '@';\n }\n if (aParsedUrl.host) {\n url += aParsedUrl.host;\n }\n if (aParsedUrl.port) {\n url += \":\" + aParsedUrl.port\n }\n if (aParsedUrl.path) {\n url += aParsedUrl.path;\n }\n return url;\n}\nexports.urlGenerate = urlGenerate;\n\n/**\n * Normalizes a path, or the path portion of a URL:\n *\n * - Replaces consequtive slashes with one slash.\n * - Removes unnecessary '.' parts.\n * - Removes unnecessary '/..' parts.\n *\n * Based on code in the Node.js 'path' core module.\n *\n * @param aPath The path or url to normalize.\n */\nfunction normalize(aPath) {\n var path = aPath;\n var url = urlParse(aPath);\n if (url) {\n if (!url.path) {\n return aPath;\n }\n path = url.path;\n }\n var isAbsolute = exports.isAbsolute(path);\n\n var parts = path.split(/\\/+/);\n for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {\n part = parts[i];\n if (part === '.') {\n parts.splice(i, 1);\n } else if (part === '..') {\n up++;\n } else if (up > 0) {\n if (part === '') {\n // The first part is blank if the path is absolute. Trying to go\n // above the root is a no-op. Therefore we can remove all '..' parts\n // directly after the root.\n parts.splice(i + 1, up);\n up = 0;\n } else {\n parts.splice(i, 2);\n up--;\n }\n }\n }\n path = parts.join('/');\n\n if (path === '') {\n path = isAbsolute ? '/' : '.';\n }\n\n if (url) {\n url.path = path;\n return urlGenerate(url);\n }\n return path;\n}\nexports.normalize = normalize;\n\n/**\n * Joins two paths/URLs.\n *\n * @param aRoot The root path or URL.\n * @param aPath The path or URL to be joined with the root.\n *\n * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a\n * scheme-relative URL: Then the scheme of aRoot, if any, is prepended\n * first.\n * - Otherwise aPath is a path. If aRoot is a URL, then its path portion\n * is updated with the result and aRoot is returned. Otherwise the result\n * is returned.\n * - If aPath is absolute, the result is aPath.\n * - Otherwise the two paths are joined with a slash.\n * - Joining for example 'http://' and 'www.example.com' is also supported.\n */\nfunction join(aRoot, aPath) {\n if (aRoot === \"\") {\n aRoot = \".\";\n }\n if (aPath === \"\") {\n aPath = \".\";\n }\n var aPathUrl = urlParse(aPath);\n var aRootUrl = urlParse(aRoot);\n if (aRootUrl) {\n aRoot = aRootUrl.path || '/';\n }\n\n // `join(foo, '//www.example.org')`\n if (aPathUrl && !aPathUrl.scheme) {\n if (aRootUrl) {\n aPathUrl.scheme = aRootUrl.scheme;\n }\n return urlGenerate(aPathUrl);\n }\n\n if (aPathUrl || aPath.match(dataUrlRegexp)) {\n return aPath;\n }\n\n // `join('http://', 'www.example.com')`\n if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {\n aRootUrl.host = aPath;\n return urlGenerate(aRootUrl);\n }\n\n var joined = aPath.charAt(0) === '/'\n ? aPath\n : normalize(aRoot.replace(/\\/+$/, '') + '/' + aPath);\n\n if (aRootUrl) {\n aRootUrl.path = joined;\n return urlGenerate(aRootUrl);\n }\n return joined;\n}\nexports.join = join;\n\nexports.isAbsolute = function (aPath) {\n return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp);\n};\n\n/**\n * Make a path relative to a URL or another path.\n *\n * @param aRoot The root path or URL.\n * @param aPath The path or URL to be made relative to aRoot.\n */\nfunction relative(aRoot, aPath) {\n if (aRoot === \"\") {\n aRoot = \".\";\n }\n\n aRoot = aRoot.replace(/\\/$/, '');\n\n // It is possible for the path to be above the root. In this case, simply\n // checking whether the root is a prefix of the path won't work. Instead, we\n // need to remove components from the root one by one, until either we find\n // a prefix that fits, or we run out of components to remove.\n var level = 0;\n while (aPath.indexOf(aRoot + '/') !== 0) {\n var index = aRoot.lastIndexOf(\"/\");\n if (index < 0) {\n return aPath;\n }\n\n // If the only part of the root that is left is the scheme (i.e. http://,\n // file:///, etc.), one or more slashes (/), or simply nothing at all, we\n // have exhausted all components, so the path is not relative to the root.\n aRoot = aRoot.slice(0, index);\n if (aRoot.match(/^([^\\/]+:\\/)?\\/*$/)) {\n return aPath;\n }\n\n ++level;\n }\n\n // Make sure we add a \"../\" for each component we removed from the root.\n return Array(level + 1).join(\"../\") + aPath.substr(aRoot.length + 1);\n}\nexports.relative = relative;\n\nvar supportsNullProto = (function () {\n var obj = Object.create(null);\n return !('__proto__' in obj);\n}());\n\nfunction identity (s) {\n return s;\n}\n\n/**\n * Because behavior goes wacky when you set `__proto__` on objects, we\n * have to prefix all the strings in our set with an arbitrary character.\n *\n * See https://github.com/mozilla/source-map/pull/31 and\n * https://github.com/mozilla/source-map/issues/30\n *\n * @param String aStr\n */\nfunction toSetString(aStr) {\n if (isProtoString(aStr)) {\n return '$' + aStr;\n }\n\n return aStr;\n}\nexports.toSetString = supportsNullProto ? identity : toSetString;\n\nfunction fromSetString(aStr) {\n if (isProtoString(aStr)) {\n return aStr.slice(1);\n }\n\n return aStr;\n}\nexports.fromSetString = supportsNullProto ? identity : fromSetString;\n\nfunction isProtoString(s) {\n if (!s) {\n return false;\n }\n\n var length = s.length;\n\n if (length < 9 /* \"__proto__\".length */) {\n return false;\n }\n\n if (s.charCodeAt(length - 1) !== 95 /* '_' */ ||\n s.charCodeAt(length - 2) !== 95 /* '_' */ ||\n s.charCodeAt(length - 3) !== 111 /* 'o' */ ||\n s.charCodeAt(length - 4) !== 116 /* 't' */ ||\n s.charCodeAt(length - 5) !== 111 /* 'o' */ ||\n s.charCodeAt(length - 6) !== 114 /* 'r' */ ||\n s.charCodeAt(length - 7) !== 112 /* 'p' */ ||\n s.charCodeAt(length - 8) !== 95 /* '_' */ ||\n s.charCodeAt(length - 9) !== 95 /* '_' */) {\n return false;\n }\n\n for (var i = length - 10; i >= 0; i--) {\n if (s.charCodeAt(i) !== 36 /* '$' */) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Comparator between two mappings where the original positions are compared.\n *\n * Optionally pass in `true` as `onlyCompareGenerated` to consider two\n * mappings with the same original source/line/column, but different generated\n * line and column the same. Useful when searching for a mapping with a\n * stubbed out mapping.\n */\nfunction compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {\n var cmp = mappingA.source - mappingB.source;\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.originalLine - mappingB.originalLine;\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.originalColumn - mappingB.originalColumn;\n if (cmp !== 0 || onlyCompareOriginal) {\n return cmp;\n }\n\n cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.generatedLine - mappingB.generatedLine;\n if (cmp !== 0) {\n return cmp;\n }\n\n return mappingA.name - mappingB.name;\n}\nexports.compareByOriginalPositions = compareByOriginalPositions;\n\n/**\n * Comparator between two mappings with deflated source and name indices where\n * the generated positions are compared.\n *\n * Optionally pass in `true` as `onlyCompareGenerated` to consider two\n * mappings with the same generated line and column, but different\n * source/name/original line and column the same. Useful when searching for a\n * mapping with a stubbed out mapping.\n */\nfunction compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {\n var cmp = mappingA.generatedLine - mappingB.generatedLine;\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n if (cmp !== 0 || onlyCompareGenerated) {\n return cmp;\n }\n\n cmp = mappingA.source - mappingB.source;\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.originalLine - mappingB.originalLine;\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.originalColumn - mappingB.originalColumn;\n if (cmp !== 0) {\n return cmp;\n }\n\n return mappingA.name - mappingB.name;\n}\nexports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;\n\nfunction strcmp(aStr1, aStr2) {\n if (aStr1 === aStr2) {\n return 0;\n }\n\n if (aStr1 > aStr2) {\n return 1;\n }\n\n return -1;\n}\n\n/**\n * Comparator between two mappings with inflated source and name strings where\n * the generated positions are compared.\n */\nfunction compareByGeneratedPositionsInflated(mappingA, mappingB) {\n var cmp = mappingA.generatedLine - mappingB.generatedLine;\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = strcmp(mappingA.source, mappingB.source);\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.originalLine - mappingB.originalLine;\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.originalColumn - mappingB.originalColumn;\n if (cmp !== 0) {\n return cmp;\n }\n\n return strcmp(mappingA.name, mappingB.name);\n}\nexports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./lib/util.js\n ** module id = 4\n ** module chunks = 0\n **/","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\nvar util = require('./util');\nvar has = Object.prototype.hasOwnProperty;\n\n/**\n * A data structure which is a combination of an array and a set. Adding a new\n * member is O(1), testing for membership is O(1), and finding the index of an\n * element is O(1). Removing elements from the set is not supported. Only\n * strings are supported for membership.\n */\nfunction ArraySet() {\n this._array = [];\n this._set = Object.create(null);\n}\n\n/**\n * Static method for creating ArraySet instances from an existing array.\n */\nArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {\n var set = new ArraySet();\n for (var i = 0, len = aArray.length; i < len; i++) {\n set.add(aArray[i], aAllowDuplicates);\n }\n return set;\n};\n\n/**\n * Return how many unique items are in this ArraySet. If duplicates have been\n * added, than those do not count towards the size.\n *\n * @returns Number\n */\nArraySet.prototype.size = function ArraySet_size() {\n return Object.getOwnPropertyNames(this._set).length;\n};\n\n/**\n * Add the given string to this set.\n *\n * @param String aStr\n */\nArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {\n var sStr = util.toSetString(aStr);\n var isDuplicate = has.call(this._set, sStr);\n var idx = this._array.length;\n if (!isDuplicate || aAllowDuplicates) {\n this._array.push(aStr);\n }\n if (!isDuplicate) {\n this._set[sStr] = idx;\n }\n};\n\n/**\n * Is the given string a member of this set?\n *\n * @param String aStr\n */\nArraySet.prototype.has = function ArraySet_has(aStr) {\n var sStr = util.toSetString(aStr);\n return has.call(this._set, sStr);\n};\n\n/**\n * What is the index of the given string in the array?\n *\n * @param String aStr\n */\nArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {\n var sStr = util.toSetString(aStr);\n if (has.call(this._set, sStr)) {\n return this._set[sStr];\n }\n throw new Error('\"' + aStr + '\" is not in the set.');\n};\n\n/**\n * What is the element at the given index?\n *\n * @param Number aIdx\n */\nArraySet.prototype.at = function ArraySet_at(aIdx) {\n if (aIdx >= 0 && aIdx < this._array.length) {\n return this._array[aIdx];\n }\n throw new Error('No element indexed by ' + aIdx);\n};\n\n/**\n * Returns the array representation of this set (which has the proper indices\n * indicated by indexOf). Note that this is a copy of the internal array used\n * for storing the members so that no one can mess with internal state.\n */\nArraySet.prototype.toArray = function ArraySet_toArray() {\n return this._array.slice();\n};\n\nexports.ArraySet = ArraySet;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./lib/array-set.js\n ** module id = 5\n ** module chunks = 0\n **/","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2014 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\nvar util = require('./util');\n\n/**\n * Determine whether mappingB is after mappingA with respect to generated\n * position.\n */\nfunction generatedPositionAfter(mappingA, mappingB) {\n // Optimized for most common case\n var lineA = mappingA.generatedLine;\n var lineB = mappingB.generatedLine;\n var columnA = mappingA.generatedColumn;\n var columnB = mappingB.generatedColumn;\n return lineB > lineA || lineB == lineA && columnB >= columnA ||\n util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;\n}\n\n/**\n * A data structure to provide a sorted view of accumulated mappings in a\n * performance conscious manner. It trades a neglibable overhead in general\n * case for a large speedup in case of mappings being added in order.\n */\nfunction MappingList() {\n this._array = [];\n this._sorted = true;\n // Serves as infimum\n this._last = {generatedLine: -1, generatedColumn: 0};\n}\n\n/**\n * Iterate through internal items. This method takes the same arguments that\n * `Array.prototype.forEach` takes.\n *\n * NOTE: The order of the mappings is NOT guaranteed.\n */\nMappingList.prototype.unsortedForEach =\n function MappingList_forEach(aCallback, aThisArg) {\n this._array.forEach(aCallback, aThisArg);\n };\n\n/**\n * Add the given source mapping.\n *\n * @param Object aMapping\n */\nMappingList.prototype.add = function MappingList_add(aMapping) {\n if (generatedPositionAfter(this._last, aMapping)) {\n this._last = aMapping;\n this._array.push(aMapping);\n } else {\n this._sorted = false;\n this._array.push(aMapping);\n }\n};\n\n/**\n * Returns the flat, sorted array of mappings. The mappings are sorted by\n * generated position.\n *\n * WARNING: This method returns internal data without copying, for\n * performance. The return value must NOT be mutated, and should be treated as\n * an immutable borrow. If you want to take ownership, you must make your own\n * copy.\n */\nMappingList.prototype.toArray = function MappingList_toArray() {\n if (!this._sorted) {\n this._array.sort(util.compareByGeneratedPositionsInflated);\n this._sorted = true;\n }\n return this._array;\n};\n\nexports.MappingList = MappingList;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./lib/mapping-list.js\n ** module id = 6\n ** module chunks = 0\n **/","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\nvar util = require('./util');\nvar binarySearch = require('./binary-search');\nvar ArraySet = require('./array-set').ArraySet;\nvar base64VLQ = require('./base64-vlq');\nvar quickSort = require('./quick-sort').quickSort;\n\nfunction SourceMapConsumer(aSourceMap) {\n var sourceMap = aSourceMap;\n if (typeof aSourceMap === 'string') {\n sourceMap = JSON.parse(aSourceMap.replace(/^\\)\\]\\}'/, ''));\n }\n\n return sourceMap.sections != null\n ? new IndexedSourceMapConsumer(sourceMap)\n : new BasicSourceMapConsumer(sourceMap);\n}\n\nSourceMapConsumer.fromSourceMap = function(aSourceMap) {\n return BasicSourceMapConsumer.fromSourceMap(aSourceMap);\n}\n\n/**\n * The version of the source mapping spec that we are consuming.\n */\nSourceMapConsumer.prototype._version = 3;\n\n// `__generatedMappings` and `__originalMappings` are arrays that hold the\n// parsed mapping coordinates from the source map's \"mappings\" attribute. They\n// are lazily instantiated, accessed via the `_generatedMappings` and\n// `_originalMappings` getters respectively, and we only parse the mappings\n// and create these arrays once queried for a source location. We jump through\n// these hoops because there can be many thousands of mappings, and parsing\n// them is expensive, so we only want to do it if we must.\n//\n// Each object in the arrays is of the form:\n//\n// {\n// generatedLine: The line number in the generated code,\n// generatedColumn: The column number in the generated code,\n// source: The path to the original source file that generated this\n// chunk of code,\n// originalLine: The line number in the original source that\n// corresponds to this chunk of generated code,\n// originalColumn: The column number in the original source that\n// corresponds to this chunk of generated code,\n// name: The name of the original symbol which generated this chunk of\n// code.\n// }\n//\n// All properties except for `generatedLine` and `generatedColumn` can be\n// `null`.\n//\n// `_generatedMappings` is ordered by the generated positions.\n//\n// `_originalMappings` is ordered by the original positions.\n\nSourceMapConsumer.prototype.__generatedMappings = null;\nObject.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {\n get: function () {\n if (!this.__generatedMappings) {\n this._parseMappings(this._mappings, this.sourceRoot);\n }\n\n return this.__generatedMappings;\n }\n});\n\nSourceMapConsumer.prototype.__originalMappings = null;\nObject.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {\n get: function () {\n if (!this.__originalMappings) {\n this._parseMappings(this._mappings, this.sourceRoot);\n }\n\n return this.__originalMappings;\n }\n});\n\nSourceMapConsumer.prototype._charIsMappingSeparator =\n function SourceMapConsumer_charIsMappingSeparator(aStr, index) {\n var c = aStr.charAt(index);\n return c === \";\" || c === \",\";\n };\n\n/**\n * Parse the mappings in a string in to a data structure which we can easily\n * query (the ordered arrays in the `this.__generatedMappings` and\n * `this.__originalMappings` properties).\n */\nSourceMapConsumer.prototype._parseMappings =\n function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {\n throw new Error(\"Subclasses must implement _parseMappings\");\n };\n\nSourceMapConsumer.GENERATED_ORDER = 1;\nSourceMapConsumer.ORIGINAL_ORDER = 2;\n\nSourceMapConsumer.GREATEST_LOWER_BOUND = 1;\nSourceMapConsumer.LEAST_UPPER_BOUND = 2;\n\n/**\n * Iterate over each mapping between an original source/line/column and a\n * generated line/column in this source map.\n *\n * @param Function aCallback\n * The function that is called with each mapping.\n * @param Object aContext\n * Optional. If specified, this object will be the value of `this` every\n * time that `aCallback` is called.\n * @param aOrder\n * Either `SourceMapConsumer.GENERATED_ORDER` or\n * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to\n * iterate over the mappings sorted by the generated file's line/column\n * order or the original's source/line/column order, respectively. Defaults to\n * `SourceMapConsumer.GENERATED_ORDER`.\n */\nSourceMapConsumer.prototype.eachMapping =\n function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {\n var context = aContext || null;\n var order = aOrder || SourceMapConsumer.GENERATED_ORDER;\n\n var mappings;\n switch (order) {\n case SourceMapConsumer.GENERATED_ORDER:\n mappings = this._generatedMappings;\n break;\n case SourceMapConsumer.ORIGINAL_ORDER:\n mappings = this._originalMappings;\n break;\n default:\n throw new Error(\"Unknown order of iteration.\");\n }\n\n var sourceRoot = this.sourceRoot;\n mappings.map(function (mapping) {\n var source = mapping.source === null ? null : this._sources.at(mapping.source);\n if (source != null && sourceRoot != null) {\n source = util.join(sourceRoot, source);\n }\n return {\n source: source,\n generatedLine: mapping.generatedLine,\n generatedColumn: mapping.generatedColumn,\n originalLine: mapping.originalLine,\n originalColumn: mapping.originalColumn,\n name: mapping.name === null ? null : this._names.at(mapping.name)\n };\n }, this).forEach(aCallback, context);\n };\n\n/**\n * Returns all generated line and column information for the original source,\n * line, and column provided. If no column is provided, returns all mappings\n * corresponding to a either the line we are searching for or the next\n * closest line that has any mappings. Otherwise, returns all mappings\n * corresponding to the given line and either the column we are searching for\n * or the next closest column that has any offsets.\n *\n * The only argument is an object with the following properties:\n *\n * - source: The filename of the original source.\n * - line: The line number in the original source.\n * - column: Optional. the column number in the original source.\n *\n * and an array of objects is returned, each with the following properties:\n *\n * - line: The line number in the generated source, or null.\n * - column: The column number in the generated source, or null.\n */\nSourceMapConsumer.prototype.allGeneratedPositionsFor =\n function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {\n var line = util.getArg(aArgs, 'line');\n\n // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping\n // returns the index of the closest mapping less than the needle. By\n // setting needle.originalColumn to 0, we thus find the last mapping for\n // the given line, provided such a mapping exists.\n var needle = {\n source: util.getArg(aArgs, 'source'),\n originalLine: line,\n originalColumn: util.getArg(aArgs, 'column', 0)\n };\n\n if (this.sourceRoot != null) {\n needle.source = util.relative(this.sourceRoot, needle.source);\n }\n if (!this._sources.has(needle.source)) {\n return [];\n }\n needle.source = this._sources.indexOf(needle.source);\n\n var mappings = [];\n\n var index = this._findMapping(needle,\n this._originalMappings,\n \"originalLine\",\n \"originalColumn\",\n util.compareByOriginalPositions,\n binarySearch.LEAST_UPPER_BOUND);\n if (index >= 0) {\n var mapping = this._originalMappings[index];\n\n if (aArgs.column === undefined) {\n var originalLine = mapping.originalLine;\n\n // Iterate until either we run out of mappings, or we run into\n // a mapping for a different line than the one we found. Since\n // mappings are sorted, this is guaranteed to find all mappings for\n // the line we found.\n while (mapping && mapping.originalLine === originalLine) {\n mappings.push({\n line: util.getArg(mapping, 'generatedLine', null),\n column: util.getArg(mapping, 'generatedColumn', null),\n lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)\n });\n\n mapping = this._originalMappings[++index];\n }\n } else {\n var originalColumn = mapping.originalColumn;\n\n // Iterate until either we run out of mappings, or we run into\n // a mapping for a different line than the one we were searching for.\n // Since mappings are sorted, this is guaranteed to find all mappings for\n // the line we are searching for.\n while (mapping &&\n mapping.originalLine === line &&\n mapping.originalColumn == originalColumn) {\n mappings.push({\n line: util.getArg(mapping, 'generatedLine', null),\n column: util.getArg(mapping, 'generatedColumn', null),\n lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)\n });\n\n mapping = this._originalMappings[++index];\n }\n }\n }\n\n return mappings;\n };\n\nexports.SourceMapConsumer = SourceMapConsumer;\n\n/**\n * A BasicSourceMapConsumer instance represents a parsed source map which we can\n * query for information about the original file positions by giving it a file\n * position in the generated source.\n *\n * The only parameter is the raw source map (either as a JSON string, or\n * already parsed to an object). According to the spec, source maps have the\n * following attributes:\n *\n * - version: Which version of the source map spec this map is following.\n * - sources: An array of URLs to the original source files.\n * - names: An array of identifiers which can be referrenced by individual mappings.\n * - sourceRoot: Optional. The URL root from which all sources are relative.\n * - sourcesContent: Optional. An array of contents of the original source files.\n * - mappings: A string of base64 VLQs which contain the actual mappings.\n * - file: Optional. The generated file this source map is associated with.\n *\n * Here is an example source map, taken from the source map spec[0]:\n *\n * {\n * version : 3,\n * file: \"out.js\",\n * sourceRoot : \"\",\n * sources: [\"foo.js\", \"bar.js\"],\n * names: [\"src\", \"maps\", \"are\", \"fun\"],\n * mappings: \"AA,AB;;ABCDE;\"\n * }\n *\n * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#\n */\nfunction BasicSourceMapConsumer(aSourceMap) {\n var sourceMap = aSourceMap;\n if (typeof aSourceMap === 'string') {\n sourceMap = JSON.parse(aSourceMap.replace(/^\\)\\]\\}'/, ''));\n }\n\n var version = util.getArg(sourceMap, 'version');\n var sources = util.getArg(sourceMap, 'sources');\n // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which\n // requires the array) to play nice here.\n var names = util.getArg(sourceMap, 'names', []);\n var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);\n var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);\n var mappings = util.getArg(sourceMap, 'mappings');\n var file = util.getArg(sourceMap, 'file', null);\n\n // Once again, Sass deviates from the spec and supplies the version as a\n // string rather than a number, so we use loose equality checking here.\n if (version != this._version) {\n throw new Error('Unsupported version: ' + version);\n }\n\n sources = sources\n .map(String)\n // Some source maps produce relative source paths like \"./foo.js\" instead of\n // \"foo.js\". Normalize these first so that future comparisons will succeed.\n // See bugzil.la/1090768.\n .map(util.normalize)\n // Always ensure that absolute sources are internally stored relative to\n // the source root, if the source root is absolute. Not doing this would\n // be particularly problematic when the source root is a prefix of the\n // source (valid, but why??). See github issue #199 and bugzil.la/1188982.\n .map(function (source) {\n return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source)\n ? util.relative(sourceRoot, source)\n : source;\n });\n\n // Pass `true` below to allow duplicate names and sources. While source maps\n // are intended to be compressed and deduplicated, the TypeScript compiler\n // sometimes generates source maps with duplicates in them. See Github issue\n // #72 and bugzil.la/889492.\n this._names = ArraySet.fromArray(names.map(String), true);\n this._sources = ArraySet.fromArray(sources, true);\n\n this.sourceRoot = sourceRoot;\n this.sourcesContent = sourcesContent;\n this._mappings = mappings;\n this.file = file;\n}\n\nBasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);\nBasicSourceMapConsumer.prototype.consumer = SourceMapConsumer;\n\n/**\n * Create a BasicSourceMapConsumer from a SourceMapGenerator.\n *\n * @param SourceMapGenerator aSourceMap\n * The source map that will be consumed.\n * @returns BasicSourceMapConsumer\n */\nBasicSourceMapConsumer.fromSourceMap =\n function SourceMapConsumer_fromSourceMap(aSourceMap) {\n var smc = Object.create(BasicSourceMapConsumer.prototype);\n\n var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);\n var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);\n smc.sourceRoot = aSourceMap._sourceRoot;\n smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),\n smc.sourceRoot);\n smc.file = aSourceMap._file;\n\n // Because we are modifying the entries (by converting string sources and\n // names to indices into the sources and names ArraySets), we have to make\n // a copy of the entry or else bad things happen. Shared mutable state\n // strikes again! See github issue #191.\n\n var generatedMappings = aSourceMap._mappings.toArray().slice();\n var destGeneratedMappings = smc.__generatedMappings = [];\n var destOriginalMappings = smc.__originalMappings = [];\n\n for (var i = 0, length = generatedMappings.length; i < length; i++) {\n var srcMapping = generatedMappings[i];\n var destMapping = new Mapping;\n destMapping.generatedLine = srcMapping.generatedLine;\n destMapping.generatedColumn = srcMapping.generatedColumn;\n\n if (srcMapping.source) {\n destMapping.source = sources.indexOf(srcMapping.source);\n destMapping.originalLine = srcMapping.originalLine;\n destMapping.originalColumn = srcMapping.originalColumn;\n\n if (srcMapping.name) {\n destMapping.name = names.indexOf(srcMapping.name);\n }\n\n destOriginalMappings.push(destMapping);\n }\n\n destGeneratedMappings.push(destMapping);\n }\n\n quickSort(smc.__originalMappings, util.compareByOriginalPositions);\n\n return smc;\n };\n\n/**\n * The version of the source mapping spec that we are consuming.\n */\nBasicSourceMapConsumer.prototype._version = 3;\n\n/**\n * The list of original sources.\n */\nObject.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {\n get: function () {\n return this._sources.toArray().map(function (s) {\n return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s;\n }, this);\n }\n});\n\n/**\n * Provide the JIT with a nice shape / hidden class.\n */\nfunction Mapping() {\n this.generatedLine = 0;\n this.generatedColumn = 0;\n this.source = null;\n this.originalLine = null;\n this.originalColumn = null;\n this.name = null;\n}\n\n/**\n * Parse the mappings in a string in to a data structure which we can easily\n * query (the ordered arrays in the `this.__generatedMappings` and\n * `this.__originalMappings` properties).\n */\nBasicSourceMapConsumer.prototype._parseMappings =\n function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {\n var generatedLine = 1;\n var previousGeneratedColumn = 0;\n var previousOriginalLine = 0;\n var previousOriginalColumn = 0;\n var previousSource = 0;\n var previousName = 0;\n var length = aStr.length;\n var index = 0;\n var cachedSegments = {};\n var temp = {};\n var originalMappings = [];\n var generatedMappings = [];\n var mapping, str, segment, end, value;\n\n while (index < length) {\n if (aStr.charAt(index) === ';') {\n generatedLine++;\n index++;\n previousGeneratedColumn = 0;\n }\n else if (aStr.charAt(index) === ',') {\n index++;\n }\n else {\n mapping = new Mapping();\n mapping.generatedLine = generatedLine;\n\n // Because each offset is encoded relative to the previous one,\n // many segments often have the same encoding. We can exploit this\n // fact by caching the parsed variable length fields of each segment,\n // allowing us to avoid a second parse if we encounter the same\n // segment again.\n for (end = index; end < length; end++) {\n if (this._charIsMappingSeparator(aStr, end)) {\n break;\n }\n }\n str = aStr.slice(index, end);\n\n segment = cachedSegments[str];\n if (segment) {\n index += str.length;\n } else {\n segment = [];\n while (index < end) {\n base64VLQ.decode(aStr, index, temp);\n value = temp.value;\n index = temp.rest;\n segment.push(value);\n }\n\n if (segment.length === 2) {\n throw new Error('Found a source, but no line and column');\n }\n\n if (segment.length === 3) {\n throw new Error('Found a source and line, but no column');\n }\n\n cachedSegments[str] = segment;\n }\n\n // Generated column.\n mapping.generatedColumn = previousGeneratedColumn + segment[0];\n previousGeneratedColumn = mapping.generatedColumn;\n\n if (segment.length > 1) {\n // Original source.\n mapping.source = previousSource + segment[1];\n previousSource += segment[1];\n\n // Original line.\n mapping.originalLine = previousOriginalLine + segment[2];\n previousOriginalLine = mapping.originalLine;\n // Lines are stored 0-based\n mapping.originalLine += 1;\n\n // Original column.\n mapping.originalColumn = previousOriginalColumn + segment[3];\n previousOriginalColumn = mapping.originalColumn;\n\n if (segment.length > 4) {\n // Original name.\n mapping.name = previousName + segment[4];\n previousName += segment[4];\n }\n }\n\n generatedMappings.push(mapping);\n if (typeof mapping.originalLine === 'number') {\n originalMappings.push(mapping);\n }\n }\n }\n\n quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated);\n this.__generatedMappings = generatedMappings;\n\n quickSort(originalMappings, util.compareByOriginalPositions);\n this.__originalMappings = originalMappings;\n };\n\n/**\n * Find the mapping that best matches the hypothetical \"needle\" mapping that\n * we are searching for in the given \"haystack\" of mappings.\n */\nBasicSourceMapConsumer.prototype._findMapping =\n function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName,\n aColumnName, aComparator, aBias) {\n // To return the position we are searching for, we must first find the\n // mapping for the given position and then return the opposite position it\n // points to. Because the mappings are sorted, we can use binary search to\n // find the best mapping.\n\n if (aNeedle[aLineName] <= 0) {\n throw new TypeError('Line must be greater than or equal to 1, got '\n + aNeedle[aLineName]);\n }\n if (aNeedle[aColumnName] < 0) {\n throw new TypeError('Column must be greater than or equal to 0, got '\n + aNeedle[aColumnName]);\n }\n\n return binarySearch.search(aNeedle, aMappings, aComparator, aBias);\n };\n\n/**\n * Compute the last column for each generated mapping. The last column is\n * inclusive.\n */\nBasicSourceMapConsumer.prototype.computeColumnSpans =\n function SourceMapConsumer_computeColumnSpans() {\n for (var index = 0; index < this._generatedMappings.length; ++index) {\n var mapping = this._generatedMappings[index];\n\n // Mappings do not contain a field for the last generated columnt. We\n // can come up with an optimistic estimate, however, by assuming that\n // mappings are contiguous (i.e. given two consecutive mappings, the\n // first mapping ends where the second one starts).\n if (index + 1 < this._generatedMappings.length) {\n var nextMapping = this._generatedMappings[index + 1];\n\n if (mapping.generatedLine === nextMapping.generatedLine) {\n mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1;\n continue;\n }\n }\n\n // The last mapping for each line spans the entire line.\n mapping.lastGeneratedColumn = Infinity;\n }\n };\n\n/**\n * Returns the original source, line, and column information for the generated\n * source's line and column positions provided. The only argument is an object\n * with the following properties:\n *\n * - line: The line number in the generated source.\n * - column: The column number in the generated source.\n * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or\n * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the\n * closest element that is smaller than or greater than the one we are\n * searching for, respectively, if the exact element cannot be found.\n * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.\n *\n * and an object is returned with the following properties:\n *\n * - source: The original source file, or null.\n * - line: The line number in the original source, or null.\n * - column: The column number in the original source, or null.\n * - name: The original identifier, or null.\n */\nBasicSourceMapConsumer.prototype.originalPositionFor =\n function SourceMapConsumer_originalPositionFor(aArgs) {\n var needle = {\n generatedLine: util.getArg(aArgs, 'line'),\n generatedColumn: util.getArg(aArgs, 'column')\n };\n\n var index = this._findMapping(\n needle,\n this._generatedMappings,\n \"generatedLine\",\n \"generatedColumn\",\n util.compareByGeneratedPositionsDeflated,\n util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)\n );\n\n if (index >= 0) {\n var mapping = this._generatedMappings[index];\n\n if (mapping.generatedLine === needle.generatedLine) {\n var source = util.getArg(mapping, 'source', null);\n if (source !== null) {\n source = this._sources.at(source);\n if (this.sourceRoot != null) {\n source = util.join(this.sourceRoot, source);\n }\n }\n var name = util.getArg(mapping, 'name', null);\n if (name !== null) {\n name = this._names.at(name);\n }\n return {\n source: source,\n line: util.getArg(mapping, 'originalLine', null),\n column: util.getArg(mapping, 'originalColumn', null),\n name: name\n };\n }\n }\n\n return {\n source: null,\n line: null,\n column: null,\n name: null\n };\n };\n\n/**\n * Return true if we have the source content for every source in the source\n * map, false otherwise.\n */\nBasicSourceMapConsumer.prototype.hasContentsOfAllSources =\n function BasicSourceMapConsumer_hasContentsOfAllSources() {\n if (!this.sourcesContent) {\n return false;\n }\n return this.sourcesContent.length >= this._sources.size() &&\n !this.sourcesContent.some(function (sc) { return sc == null; });\n };\n\n/**\n * Returns the original source content. The only argument is the url of the\n * original source file. Returns null if no original source content is\n * available.\n */\nBasicSourceMapConsumer.prototype.sourceContentFor =\n function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {\n if (!this.sourcesContent) {\n return null;\n }\n\n if (this.sourceRoot != null) {\n aSource = util.relative(this.sourceRoot, aSource);\n }\n\n if (this._sources.has(aSource)) {\n return this.sourcesContent[this._sources.indexOf(aSource)];\n }\n\n var url;\n if (this.sourceRoot != null\n && (url = util.urlParse(this.sourceRoot))) {\n // XXX: file:// URIs and absolute paths lead to unexpected behavior for\n // many users. We can help them out when they expect file:// URIs to\n // behave like it would if they were running a local HTTP server. See\n // https://bugzilla.mozilla.org/show_bug.cgi?id=885597.\n var fileUriAbsPath = aSource.replace(/^file:\\/\\//, \"\");\n if (url.scheme == \"file\"\n && this._sources.has(fileUriAbsPath)) {\n return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]\n }\n\n if ((!url.path || url.path == \"/\")\n && this._sources.has(\"/\" + aSource)) {\n return this.sourcesContent[this._sources.indexOf(\"/\" + aSource)];\n }\n }\n\n // This function is used recursively from\n // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we\n // don't want to throw if we can't find the source - we just want to\n // return null, so we provide a flag to exit gracefully.\n if (nullOnMissing) {\n return null;\n }\n else {\n throw new Error('\"' + aSource + '\" is not in the SourceMap.');\n }\n };\n\n/**\n * Returns the generated line and column information for the original source,\n * line, and column positions provided. The only argument is an object with\n * the following properties:\n *\n * - source: The filename of the original source.\n * - line: The line number in the original source.\n * - column: The column number in the original source.\n * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or\n * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the\n * closest element that is smaller than or greater than the one we are\n * searching for, respectively, if the exact element cannot be found.\n * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.\n *\n * and an object is returned with the following properties:\n *\n * - line: The line number in the generated source, or null.\n * - column: The column number in the generated source, or null.\n */\nBasicSourceMapConsumer.prototype.generatedPositionFor =\n function SourceMapConsumer_generatedPositionFor(aArgs) {\n var source = util.getArg(aArgs, 'source');\n if (this.sourceRoot != null) {\n source = util.relative(this.sourceRoot, source);\n }\n if (!this._sources.has(source)) {\n return {\n line: null,\n column: null,\n lastColumn: null\n };\n }\n source = this._sources.indexOf(source);\n\n var needle = {\n source: source,\n originalLine: util.getArg(aArgs, 'line'),\n originalColumn: util.getArg(aArgs, 'column')\n };\n\n var index = this._findMapping(\n needle,\n this._originalMappings,\n \"originalLine\",\n \"originalColumn\",\n util.compareByOriginalPositions,\n util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)\n );\n\n if (index >= 0) {\n var mapping = this._originalMappings[index];\n\n if (mapping.source === needle.source) {\n return {\n line: util.getArg(mapping, 'generatedLine', null),\n column: util.getArg(mapping, 'generatedColumn', null),\n lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)\n };\n }\n }\n\n return {\n line: null,\n column: null,\n lastColumn: null\n };\n };\n\nexports.BasicSourceMapConsumer = BasicSourceMapConsumer;\n\n/**\n * An IndexedSourceMapConsumer instance represents a parsed source map which\n * we can query for information. It differs from BasicSourceMapConsumer in\n * that it takes \"indexed\" source maps (i.e. ones with a \"sections\" field) as\n * input.\n *\n * The only parameter is a raw source map (either as a JSON string, or already\n * parsed to an object). According to the spec for indexed source maps, they\n * have the following attributes:\n *\n * - version: Which version of the source map spec this map is following.\n * - file: Optional. The generated file this source map is associated with.\n * - sections: A list of section definitions.\n *\n * Each value under the \"sections\" field has two fields:\n * - offset: The offset into the original specified at which this section\n * begins to apply, defined as an object with a \"line\" and \"column\"\n * field.\n * - map: A source map definition. This source map could also be indexed,\n * but doesn't have to be.\n *\n * Instead of the \"map\" field, it's also possible to have a \"url\" field\n * specifying a URL to retrieve a source map from, but that's currently\n * unsupported.\n *\n * Here's an example source map, taken from the source map spec[0], but\n * modified to omit a section which uses the \"url\" field.\n *\n * {\n * version : 3,\n * file: \"app.js\",\n * sections: [{\n * offset: {line:100, column:10},\n * map: {\n * version : 3,\n * file: \"section.js\",\n * sources: [\"foo.js\", \"bar.js\"],\n * names: [\"src\", \"maps\", \"are\", \"fun\"],\n * mappings: \"AAAA,E;;ABCDE;\"\n * }\n * }],\n * }\n *\n * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt\n */\nfunction IndexedSourceMapConsumer(aSourceMap) {\n var sourceMap = aSourceMap;\n if (typeof aSourceMap === 'string') {\n sourceMap = JSON.parse(aSourceMap.replace(/^\\)\\]\\}'/, ''));\n }\n\n var version = util.getArg(sourceMap, 'version');\n var sections = util.getArg(sourceMap, 'sections');\n\n if (version != this._version) {\n throw new Error('Unsupported version: ' + version);\n }\n\n this._sources = new ArraySet();\n this._names = new ArraySet();\n\n var lastOffset = {\n line: -1,\n column: 0\n };\n this._sections = sections.map(function (s) {\n if (s.url) {\n // The url field will require support for asynchronicity.\n // See https://github.com/mozilla/source-map/issues/16\n throw new Error('Support for url field in sections not implemented.');\n }\n var offset = util.getArg(s, 'offset');\n var offsetLine = util.getArg(offset, 'line');\n var offsetColumn = util.getArg(offset, 'column');\n\n if (offsetLine < lastOffset.line ||\n (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) {\n throw new Error('Section offsets must be ordered and non-overlapping.');\n }\n lastOffset = offset;\n\n return {\n generatedOffset: {\n // The offset fields are 0-based, but we use 1-based indices when\n // encoding/decoding from VLQ.\n generatedLine: offsetLine + 1,\n generatedColumn: offsetColumn + 1\n },\n consumer: new SourceMapConsumer(util.getArg(s, 'map'))\n }\n });\n}\n\nIndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);\nIndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer;\n\n/**\n * The version of the source mapping spec that we are consuming.\n */\nIndexedSourceMapConsumer.prototype._version = 3;\n\n/**\n * The list of original sources.\n */\nObject.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', {\n get: function () {\n var sources = [];\n for (var i = 0; i < this._sections.length; i++) {\n for (var j = 0; j < this._sections[i].consumer.sources.length; j++) {\n sources.push(this._sections[i].consumer.sources[j]);\n }\n }\n return sources;\n }\n});\n\n/**\n * Returns the original source, line, and column information for the generated\n * source's line and column positions provided. The only argument is an object\n * with the following properties:\n *\n * - line: The line number in the generated source.\n * - column: The column number in the generated source.\n *\n * and an object is returned with the following properties:\n *\n * - source: The original source file, or null.\n * - line: The line number in the original source, or null.\n * - column: The column number in the original source, or null.\n * - name: The original identifier, or null.\n */\nIndexedSourceMapConsumer.prototype.originalPositionFor =\n function IndexedSourceMapConsumer_originalPositionFor(aArgs) {\n var needle = {\n generatedLine: util.getArg(aArgs, 'line'),\n generatedColumn: util.getArg(aArgs, 'column')\n };\n\n // Find the section containing the generated position we're trying to map\n // to an original position.\n var sectionIndex = binarySearch.search(needle, this._sections,\n function(needle, section) {\n var cmp = needle.generatedLine - section.generatedOffset.generatedLine;\n if (cmp) {\n return cmp;\n }\n\n return (needle.generatedColumn -\n section.generatedOffset.generatedColumn);\n });\n var section = this._sections[sectionIndex];\n\n if (!section) {\n return {\n source: null,\n line: null,\n column: null,\n name: null\n };\n }\n\n return section.consumer.originalPositionFor({\n line: needle.generatedLine -\n (section.generatedOffset.generatedLine - 1),\n column: needle.generatedColumn -\n (section.generatedOffset.generatedLine === needle.generatedLine\n ? section.generatedOffset.generatedColumn - 1\n : 0),\n bias: aArgs.bias\n });\n };\n\n/**\n * Return true if we have the source content for every source in the source\n * map, false otherwise.\n */\nIndexedSourceMapConsumer.prototype.hasContentsOfAllSources =\n function IndexedSourceMapConsumer_hasContentsOfAllSources() {\n return this._sections.every(function (s) {\n return s.consumer.hasContentsOfAllSources();\n });\n };\n\n/**\n * Returns the original source content. The only argument is the url of the\n * original source file. Returns null if no original source content is\n * available.\n */\nIndexedSourceMapConsumer.prototype.sourceContentFor =\n function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {\n for (var i = 0; i < this._sections.length; i++) {\n var section = this._sections[i];\n\n var content = section.consumer.sourceContentFor(aSource, true);\n if (content) {\n return content;\n }\n }\n if (nullOnMissing) {\n return null;\n }\n else {\n throw new Error('\"' + aSource + '\" is not in the SourceMap.');\n }\n };\n\n/**\n * Returns the generated line and column information for the original source,\n * line, and column positions provided. The only argument is an object with\n * the following properties:\n *\n * - source: The filename of the original source.\n * - line: The line number in the original source.\n * - column: The column number in the original source.\n *\n * and an object is returned with the following properties:\n *\n * - line: The line number in the generated source, or null.\n * - column: The column number in the generated source, or null.\n */\nIndexedSourceMapConsumer.prototype.generatedPositionFor =\n function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {\n for (var i = 0; i < this._sections.length; i++) {\n var section = this._sections[i];\n\n // Only consider this section if the requested source is in the list of\n // sources of the consumer.\n if (section.consumer.sources.indexOf(util.getArg(aArgs, 'source')) === -1) {\n continue;\n }\n var generatedPosition = section.consumer.generatedPositionFor(aArgs);\n if (generatedPosition) {\n var ret = {\n line: generatedPosition.line +\n (section.generatedOffset.generatedLine - 1),\n column: generatedPosition.column +\n (section.generatedOffset.generatedLine === generatedPosition.line\n ? section.generatedOffset.generatedColumn - 1\n : 0)\n };\n return ret;\n }\n }\n\n return {\n line: null,\n column: null\n };\n };\n\n/**\n * Parse the mappings in a string in to a data structure which we can easily\n * query (the ordered arrays in the `this.__generatedMappings` and\n * `this.__originalMappings` properties).\n */\nIndexedSourceMapConsumer.prototype._parseMappings =\n function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) {\n this.__generatedMappings = [];\n this.__originalMappings = [];\n for (var i = 0; i < this._sections.length; i++) {\n var section = this._sections[i];\n var sectionMappings = section.consumer._generatedMappings;\n for (var j = 0; j < sectionMappings.length; j++) {\n var mapping = sectionMappings[j];\n\n var source = section.consumer._sources.at(mapping.source);\n if (section.consumer.sourceRoot !== null) {\n source = util.join(section.consumer.sourceRoot, source);\n }\n this._sources.add(source);\n source = this._sources.indexOf(source);\n\n var name = section.consumer._names.at(mapping.name);\n this._names.add(name);\n name = this._names.indexOf(name);\n\n // The mappings coming from the consumer for the section have\n // generated positions relative to the start of the section, so we\n // need to offset them to be relative to the start of the concatenated\n // generated file.\n var adjustedMapping = {\n source: source,\n generatedLine: mapping.generatedLine +\n (section.generatedOffset.generatedLine - 1),\n generatedColumn: mapping.generatedColumn +\n (section.generatedOffset.generatedLine === mapping.generatedLine\n ? section.generatedOffset.generatedColumn - 1\n : 0),\n originalLine: mapping.originalLine,\n originalColumn: mapping.originalColumn,\n name: name\n };\n\n this.__generatedMappings.push(adjustedMapping);\n if (typeof adjustedMapping.originalLine === 'number') {\n this.__originalMappings.push(adjustedMapping);\n }\n }\n }\n\n quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated);\n quickSort(this.__originalMappings, util.compareByOriginalPositions);\n };\n\nexports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./lib/source-map-consumer.js\n ** module id = 7\n ** module chunks = 0\n **/","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\nexports.GREATEST_LOWER_BOUND = 1;\nexports.LEAST_UPPER_BOUND = 2;\n\n/**\n * Recursive implementation of binary search.\n *\n * @param aLow Indices here and lower do not contain the needle.\n * @param aHigh Indices here and higher do not contain the needle.\n * @param aNeedle The element being searched for.\n * @param aHaystack The non-empty array being searched.\n * @param aCompare Function which takes two elements and returns -1, 0, or 1.\n * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or\n * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the\n * closest element that is smaller than or greater than the one we are\n * searching for, respectively, if the exact element cannot be found.\n */\nfunction recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) {\n // This function terminates when one of the following is true:\n //\n // 1. We find the exact element we are looking for.\n //\n // 2. We did not find the exact element, but we can return the index of\n // the next-closest element.\n //\n // 3. We did not find the exact element, and there is no next-closest\n // element than the one we are searching for, so we return -1.\n var mid = Math.floor((aHigh - aLow) / 2) + aLow;\n var cmp = aCompare(aNeedle, aHaystack[mid], true);\n if (cmp === 0) {\n // Found the element we are looking for.\n return mid;\n }\n else if (cmp > 0) {\n // Our needle is greater than aHaystack[mid].\n if (aHigh - mid > 1) {\n // The element is in the upper half.\n return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias);\n }\n\n // The exact needle element was not found in this haystack. Determine if\n // we are in termination case (3) or (2) and return the appropriate thing.\n if (aBias == exports.LEAST_UPPER_BOUND) {\n return aHigh < aHaystack.length ? aHigh : -1;\n } else {\n return mid;\n }\n }\n else {\n // Our needle is less than aHaystack[mid].\n if (mid - aLow > 1) {\n // The element is in the lower half.\n return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias);\n }\n\n // we are in termination case (3) or (2) and return the appropriate thing.\n if (aBias == exports.LEAST_UPPER_BOUND) {\n return mid;\n } else {\n return aLow < 0 ? -1 : aLow;\n }\n }\n}\n\n/**\n * This is an implementation of binary search which will always try and return\n * the index of the closest element if there is no exact hit. This is because\n * mappings between original and generated line/col pairs are single points,\n * and there is an implicit region between each of them, so a miss just means\n * that you aren't on the very start of a region.\n *\n * @param aNeedle The element you are looking for.\n * @param aHaystack The array that is being searched.\n * @param aCompare A function which takes the needle and an element in the\n * array and returns -1, 0, or 1 depending on whether the needle is less\n * than, equal to, or greater than the element, respectively.\n * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or\n * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the\n * closest element that is smaller than or greater than the one we are\n * searching for, respectively, if the exact element cannot be found.\n * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'.\n */\nexports.search = function search(aNeedle, aHaystack, aCompare, aBias) {\n if (aHaystack.length === 0) {\n return -1;\n }\n\n var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack,\n aCompare, aBias || exports.GREATEST_LOWER_BOUND);\n if (index < 0) {\n return -1;\n }\n\n // We have found either the exact element, or the next-closest element than\n // the one we are searching for. However, there may be more than one such\n // element. Make sure we always return the smallest of these.\n while (index - 1 >= 0) {\n if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) {\n break;\n }\n --index;\n }\n\n return index;\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./lib/binary-search.js\n ** module id = 8\n ** module chunks = 0\n **/","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\n// It turns out that some (most?) JavaScript engines don't self-host\n// `Array.prototype.sort`. This makes sense because C++ will likely remain\n// faster than JS when doing raw CPU-intensive sorting. However, when using a\n// custom comparator function, calling back and forth between the VM's C++ and\n// JIT'd JS is rather slow *and* loses JIT type information, resulting in\n// worse generated code for the comparator function than would be optimal. In\n// fact, when sorting with a comparator, these costs outweigh the benefits of\n// sorting in C++. By using our own JS-implemented Quick Sort (below), we get\n// a ~3500ms mean speed-up in `bench/bench.html`.\n\n/**\n * Swap the elements indexed by `x` and `y` in the array `ary`.\n *\n * @param {Array} ary\n * The array.\n * @param {Number} x\n * The index of the first item.\n * @param {Number} y\n * The index of the second item.\n */\nfunction swap(ary, x, y) {\n var temp = ary[x];\n ary[x] = ary[y];\n ary[y] = temp;\n}\n\n/**\n * Returns a random integer within the range `low .. high` inclusive.\n *\n * @param {Number} low\n * The lower bound on the range.\n * @param {Number} high\n * The upper bound on the range.\n */\nfunction randomIntInRange(low, high) {\n return Math.round(low + (Math.random() * (high - low)));\n}\n\n/**\n * The Quick Sort algorithm.\n *\n * @param {Array} ary\n * An array to sort.\n * @param {function} comparator\n * Function to use to compare two items.\n * @param {Number} p\n * Start index of the array\n * @param {Number} r\n * End index of the array\n */\nfunction doQuickSort(ary, comparator, p, r) {\n // If our lower bound is less than our upper bound, we (1) partition the\n // array into two pieces and (2) recurse on each half. If it is not, this is\n // the empty array and our base case.\n\n if (p < r) {\n // (1) Partitioning.\n //\n // The partitioning chooses a pivot between `p` and `r` and moves all\n // elements that are less than or equal to the pivot to the before it, and\n // all the elements that are greater than it after it. The effect is that\n // once partition is done, the pivot is in the exact place it will be when\n // the array is put in sorted order, and it will not need to be moved\n // again. This runs in O(n) time.\n\n // Always choose a random pivot so that an input array which is reverse\n // sorted does not cause O(n^2) running time.\n var pivotIndex = randomIntInRange(p, r);\n var i = p - 1;\n\n swap(ary, pivotIndex, r);\n var pivot = ary[r];\n\n // Immediately after `j` is incremented in this loop, the following hold\n // true:\n //\n // * Every element in `ary[p .. i]` is less than or equal to the pivot.\n //\n // * Every element in `ary[i+1 .. j-1]` is greater than the pivot.\n for (var j = p; j < r; j++) {\n if (comparator(ary[j], pivot) <= 0) {\n i += 1;\n swap(ary, i, j);\n }\n }\n\n swap(ary, i + 1, j);\n var q = i + 1;\n\n // (2) Recurse on each half.\n\n doQuickSort(ary, comparator, p, q - 1);\n doQuickSort(ary, comparator, q + 1, r);\n }\n}\n\n/**\n * Sort the given array in-place with the given comparator function.\n *\n * @param {Array} ary\n * An array to sort.\n * @param {function} comparator\n * Function to use to compare two items.\n */\nexports.quickSort = function (ary, comparator) {\n doQuickSort(ary, comparator, 0, ary.length - 1);\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./lib/quick-sort.js\n ** module id = 9\n ** module chunks = 0\n **/","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\nvar SourceMapGenerator = require('./source-map-generator').SourceMapGenerator;\nvar util = require('./util');\n\n// Matches a Windows-style `\\r\\n` newline or a `\\n` newline used by all other\n// operating systems these days (capturing the result).\nvar REGEX_NEWLINE = /(\\r?\\n)/;\n\n// Newline character code for charCodeAt() comparisons\nvar NEWLINE_CODE = 10;\n\n// Private symbol for identifying `SourceNode`s when multiple versions of\n// the source-map library are loaded. This MUST NOT CHANGE across\n// versions!\nvar isSourceNode = \"$$$isSourceNode$$$\";\n\n/**\n * SourceNodes provide a way to abstract over interpolating/concatenating\n * snippets of generated JavaScript source code while maintaining the line and\n * column information associated with the original source code.\n *\n * @param aLine The original line number.\n * @param aColumn The original column number.\n * @param aSource The original source's filename.\n * @param aChunks Optional. An array of strings which are snippets of\n * generated JS, or other SourceNodes.\n * @param aName The original identifier.\n */\nfunction SourceNode(aLine, aColumn, aSource, aChunks, aName) {\n this.children = [];\n this.sourceContents = {};\n this.line = aLine == null ? null : aLine;\n this.column = aColumn == null ? null : aColumn;\n this.source = aSource == null ? null : aSource;\n this.name = aName == null ? null : aName;\n this[isSourceNode] = true;\n if (aChunks != null) this.add(aChunks);\n}\n\n/**\n * Creates a SourceNode from generated code and a SourceMapConsumer.\n *\n * @param aGeneratedCode The generated code\n * @param aSourceMapConsumer The SourceMap for the generated code\n * @param aRelativePath Optional. The path that relative sources in the\n * SourceMapConsumer should be relative to.\n */\nSourceNode.fromStringWithSourceMap =\n function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) {\n // The SourceNode we want to fill with the generated code\n // and the SourceMap\n var node = new SourceNode();\n\n // All even indices of this array are one line of the generated code,\n // while all odd indices are the newlines between two adjacent lines\n // (since `REGEX_NEWLINE` captures its match).\n // Processed fragments are removed from this array, by calling `shiftNextLine`.\n var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);\n var shiftNextLine = function() {\n var lineContents = remainingLines.shift();\n // The last line of a file might not have a newline.\n var newLine = remainingLines.shift() || \"\";\n return lineContents + newLine;\n };\n\n // We need to remember the position of \"remainingLines\"\n var lastGeneratedLine = 1, lastGeneratedColumn = 0;\n\n // The generate SourceNodes we need a code range.\n // To extract it current and last mapping is used.\n // Here we store the last mapping.\n var lastMapping = null;\n\n aSourceMapConsumer.eachMapping(function (mapping) {\n if (lastMapping !== null) {\n // We add the code from \"lastMapping\" to \"mapping\":\n // First check if there is a new line in between.\n if (lastGeneratedLine < mapping.generatedLine) {\n // Associate first line with \"lastMapping\"\n addMappingWithCode(lastMapping, shiftNextLine());\n lastGeneratedLine++;\n lastGeneratedColumn = 0;\n // The remaining code is added without mapping\n } else {\n // There is no new line in between.\n // Associate the code between \"lastGeneratedColumn\" and\n // \"mapping.generatedColumn\" with \"lastMapping\"\n var nextLine = remainingLines[0];\n var code = nextLine.substr(0, mapping.generatedColumn -\n lastGeneratedColumn);\n remainingLines[0] = nextLine.substr(mapping.generatedColumn -\n lastGeneratedColumn);\n lastGeneratedColumn = mapping.generatedColumn;\n addMappingWithCode(lastMapping, code);\n // No more remaining code, continue\n lastMapping = mapping;\n return;\n }\n }\n // We add the generated code until the first mapping\n // to the SourceNode without any mapping.\n // Each line is added as separate string.\n while (lastGeneratedLine < mapping.generatedLine) {\n node.add(shiftNextLine());\n lastGeneratedLine++;\n }\n if (lastGeneratedColumn < mapping.generatedColumn) {\n var nextLine = remainingLines[0];\n node.add(nextLine.substr(0, mapping.generatedColumn));\n remainingLines[0] = nextLine.substr(mapping.generatedColumn);\n lastGeneratedColumn = mapping.generatedColumn;\n }\n lastMapping = mapping;\n }, this);\n // We have processed all mappings.\n if (remainingLines.length > 0) {\n if (lastMapping) {\n // Associate the remaining code in the current line with \"lastMapping\"\n addMappingWithCode(lastMapping, shiftNextLine());\n }\n // and add the remaining lines without any mapping\n node.add(remainingLines.join(\"\"));\n }\n\n // Copy sourcesContent into SourceNode\n aSourceMapConsumer.sources.forEach(function (sourceFile) {\n var content = aSourceMapConsumer.sourceContentFor(sourceFile);\n if (content != null) {\n if (aRelativePath != null) {\n sourceFile = util.join(aRelativePath, sourceFile);\n }\n node.setSourceContent(sourceFile, content);\n }\n });\n\n return node;\n\n function addMappingWithCode(mapping, code) {\n if (mapping === null || mapping.source === undefined) {\n node.add(code);\n } else {\n var source = aRelativePath\n ? util.join(aRelativePath, mapping.source)\n : mapping.source;\n node.add(new SourceNode(mapping.originalLine,\n mapping.originalColumn,\n source,\n code,\n mapping.name));\n }\n }\n };\n\n/**\n * Add a chunk of generated JS to this source node.\n *\n * @param aChunk A string snippet of generated JS code, another instance of\n * SourceNode, or an array where each member is one of those things.\n */\nSourceNode.prototype.add = function SourceNode_add(aChunk) {\n if (Array.isArray(aChunk)) {\n aChunk.forEach(function (chunk) {\n this.add(chunk);\n }, this);\n }\n else if (aChunk[isSourceNode] || typeof aChunk === \"string\") {\n if (aChunk) {\n this.children.push(aChunk);\n }\n }\n else {\n throw new TypeError(\n \"Expected a SourceNode, string, or an array of SourceNodes and strings. Got \" + aChunk\n );\n }\n return this;\n};\n\n/**\n * Add a chunk of generated JS to the beginning of this source node.\n *\n * @param aChunk A string snippet of generated JS code, another instance of\n * SourceNode, or an array where each member is one of those things.\n */\nSourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {\n if (Array.isArray(aChunk)) {\n for (var i = aChunk.length-1; i >= 0; i--) {\n this.prepend(aChunk[i]);\n }\n }\n else if (aChunk[isSourceNode] || typeof aChunk === \"string\") {\n this.children.unshift(aChunk);\n }\n else {\n throw new TypeError(\n \"Expected a SourceNode, string, or an array of SourceNodes and strings. Got \" + aChunk\n );\n }\n return this;\n};\n\n/**\n * Walk over the tree of JS snippets in this node and its children. The\n * walking function is called once for each snippet of JS and is passed that\n * snippet and the its original associated source's line/column location.\n *\n * @param aFn The traversal function.\n */\nSourceNode.prototype.walk = function SourceNode_walk(aFn) {\n var chunk;\n for (var i = 0, len = this.children.length; i < len; i++) {\n chunk = this.children[i];\n if (chunk[isSourceNode]) {\n chunk.walk(aFn);\n }\n else {\n if (chunk !== '') {\n aFn(chunk, { source: this.source,\n line: this.line,\n column: this.column,\n name: this.name });\n }\n }\n }\n};\n\n/**\n * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between\n * each of `this.children`.\n *\n * @param aSep The separator.\n */\nSourceNode.prototype.join = function SourceNode_join(aSep) {\n var newChildren;\n var i;\n var len = this.children.length;\n if (len > 0) {\n newChildren = [];\n for (i = 0; i < len-1; i++) {\n newChildren.push(this.children[i]);\n newChildren.push(aSep);\n }\n newChildren.push(this.children[i]);\n this.children = newChildren;\n }\n return this;\n};\n\n/**\n * Call String.prototype.replace on the very right-most source snippet. Useful\n * for trimming whitespace from the end of a source node, etc.\n *\n * @param aPattern The pattern to replace.\n * @param aReplacement The thing to replace the pattern with.\n */\nSourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {\n var lastChild = this.children[this.children.length - 1];\n if (lastChild[isSourceNode]) {\n lastChild.replaceRight(aPattern, aReplacement);\n }\n else if (typeof lastChild === 'string') {\n this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);\n }\n else {\n this.children.push(''.replace(aPattern, aReplacement));\n }\n return this;\n};\n\n/**\n * Set the source content for a source file. This will be added to the SourceMapGenerator\n * in the sourcesContent field.\n *\n * @param aSourceFile The filename of the source file\n * @param aSourceContent The content of the source file\n */\nSourceNode.prototype.setSourceContent =\n function SourceNode_setSourceContent(aSourceFile, aSourceContent) {\n this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;\n };\n\n/**\n * Walk over the tree of SourceNodes. The walking function is called for each\n * source file content and is passed the filename and source content.\n *\n * @param aFn The traversal function.\n */\nSourceNode.prototype.walkSourceContents =\n function SourceNode_walkSourceContents(aFn) {\n for (var i = 0, len = this.children.length; i < len; i++) {\n if (this.children[i][isSourceNode]) {\n this.children[i].walkSourceContents(aFn);\n }\n }\n\n var sources = Object.keys(this.sourceContents);\n for (var i = 0, len = sources.length; i < len; i++) {\n aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);\n }\n };\n\n/**\n * Return the string representation of this source node. Walks over the tree\n * and concatenates all the various snippets together to one string.\n */\nSourceNode.prototype.toString = function SourceNode_toString() {\n var str = \"\";\n this.walk(function (chunk) {\n str += chunk;\n });\n return str;\n};\n\n/**\n * Returns the string representation of this source node along with a source\n * map.\n */\nSourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {\n var generated = {\n code: \"\",\n line: 1,\n column: 0\n };\n var map = new SourceMapGenerator(aArgs);\n var sourceMappingActive = false;\n var lastOriginalSource = null;\n var lastOriginalLine = null;\n var lastOriginalColumn = null;\n var lastOriginalName = null;\n this.walk(function (chunk, original) {\n generated.code += chunk;\n if (original.source !== null\n && original.line !== null\n && original.column !== null) {\n if(lastOriginalSource !== original.source\n || lastOriginalLine !== original.line\n || lastOriginalColumn !== original.column\n || lastOriginalName !== original.name) {\n map.addMapping({\n source: original.source,\n original: {\n line: original.line,\n column: original.column\n },\n generated: {\n line: generated.line,\n column: generated.column\n },\n name: original.name\n });\n }\n lastOriginalSource = original.source;\n lastOriginalLine = original.line;\n lastOriginalColumn = original.column;\n lastOriginalName = original.name;\n sourceMappingActive = true;\n } else if (sourceMappingActive) {\n map.addMapping({\n generated: {\n line: generated.line,\n column: generated.column\n }\n });\n lastOriginalSource = null;\n sourceMappingActive = false;\n }\n for (var idx = 0, length = chunk.length; idx < length; idx++) {\n if (chunk.charCodeAt(idx) === NEWLINE_CODE) {\n generated.line++;\n generated.column = 0;\n // Mappings end at eol\n if (idx + 1 === length) {\n lastOriginalSource = null;\n sourceMappingActive = false;\n } else if (sourceMappingActive) {\n map.addMapping({\n source: original.source,\n original: {\n line: original.line,\n column: original.column\n },\n generated: {\n line: generated.line,\n column: generated.column\n },\n name: original.name\n });\n }\n } else {\n generated.column++;\n }\n }\n });\n this.walkSourceContents(function (sourceFile, sourceContent) {\n map.setSourceContent(sourceFile, sourceContent);\n });\n\n return { code: generated.code, map: map };\n};\n\nexports.SourceNode = SourceNode;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./lib/source-node.js\n ** module id = 10\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file diff --git a/node_modules/source-map/lib/array-set.js b/node_modules/source-map/lib/array-set.js new file mode 100644 index 0000000..51dffeb --- /dev/null +++ b/node_modules/source-map/lib/array-set.js @@ -0,0 +1,104 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var util = require('./util'); +var has = Object.prototype.hasOwnProperty; + +/** + * A data structure which is a combination of an array and a set. Adding a new + * member is O(1), testing for membership is O(1), and finding the index of an + * element is O(1). Removing elements from the set is not supported. Only + * strings are supported for membership. + */ +function ArraySet() { + this._array = []; + this._set = Object.create(null); +} + +/** + * Static method for creating ArraySet instances from an existing array. + */ +ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) { + var set = new ArraySet(); + for (var i = 0, len = aArray.length; i < len; i++) { + set.add(aArray[i], aAllowDuplicates); + } + return set; +}; + +/** + * Return how many unique items are in this ArraySet. If duplicates have been + * added, than those do not count towards the size. + * + * @returns Number + */ +ArraySet.prototype.size = function ArraySet_size() { + return Object.getOwnPropertyNames(this._set).length; +}; + +/** + * Add the given string to this set. + * + * @param String aStr + */ +ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) { + var sStr = util.toSetString(aStr); + var isDuplicate = has.call(this._set, sStr); + var idx = this._array.length; + if (!isDuplicate || aAllowDuplicates) { + this._array.push(aStr); + } + if (!isDuplicate) { + this._set[sStr] = idx; + } +}; + +/** + * Is the given string a member of this set? + * + * @param String aStr + */ +ArraySet.prototype.has = function ArraySet_has(aStr) { + var sStr = util.toSetString(aStr); + return has.call(this._set, sStr); +}; + +/** + * What is the index of the given string in the array? + * + * @param String aStr + */ +ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) { + var sStr = util.toSetString(aStr); + if (has.call(this._set, sStr)) { + return this._set[sStr]; + } + throw new Error('"' + aStr + '" is not in the set.'); +}; + +/** + * What is the element at the given index? + * + * @param Number aIdx + */ +ArraySet.prototype.at = function ArraySet_at(aIdx) { + if (aIdx >= 0 && aIdx < this._array.length) { + return this._array[aIdx]; + } + throw new Error('No element indexed by ' + aIdx); +}; + +/** + * Returns the array representation of this set (which has the proper indices + * indicated by indexOf). Note that this is a copy of the internal array used + * for storing the members so that no one can mess with internal state. + */ +ArraySet.prototype.toArray = function ArraySet_toArray() { + return this._array.slice(); +}; + +exports.ArraySet = ArraySet; diff --git a/node_modules/source-map/lib/base64-vlq.js b/node_modules/source-map/lib/base64-vlq.js new file mode 100644 index 0000000..612b404 --- /dev/null +++ b/node_modules/source-map/lib/base64-vlq.js @@ -0,0 +1,140 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + * + * Based on the Base 64 VLQ implementation in Closure Compiler: + * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java + * + * Copyright 2011 The Closure Compiler Authors. All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +var base64 = require('./base64'); + +// A single base 64 digit can contain 6 bits of data. For the base 64 variable +// length quantities we use in the source map spec, the first bit is the sign, +// the next four bits are the actual value, and the 6th bit is the +// continuation bit. The continuation bit tells us whether there are more +// digits in this value following this digit. +// +// Continuation +// | Sign +// | | +// V V +// 101011 + +var VLQ_BASE_SHIFT = 5; + +// binary: 100000 +var VLQ_BASE = 1 << VLQ_BASE_SHIFT; + +// binary: 011111 +var VLQ_BASE_MASK = VLQ_BASE - 1; + +// binary: 100000 +var VLQ_CONTINUATION_BIT = VLQ_BASE; + +/** + * Converts from a two-complement value to a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) + * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) + */ +function toVLQSigned(aValue) { + return aValue < 0 + ? ((-aValue) << 1) + 1 + : (aValue << 1) + 0; +} + +/** + * Converts to a two-complement value from a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 + * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 + */ +function fromVLQSigned(aValue) { + var isNegative = (aValue & 1) === 1; + var shifted = aValue >> 1; + return isNegative + ? -shifted + : shifted; +} + +/** + * Returns the base 64 VLQ encoded value. + */ +exports.encode = function base64VLQ_encode(aValue) { + var encoded = ""; + var digit; + + var vlq = toVLQSigned(aValue); + + do { + digit = vlq & VLQ_BASE_MASK; + vlq >>>= VLQ_BASE_SHIFT; + if (vlq > 0) { + // There are still more digits in this value, so we must make sure the + // continuation bit is marked. + digit |= VLQ_CONTINUATION_BIT; + } + encoded += base64.encode(digit); + } while (vlq > 0); + + return encoded; +}; + +/** + * Decodes the next base 64 VLQ value from the given string and returns the + * value and the rest of the string via the out parameter. + */ +exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { + var strLen = aStr.length; + var result = 0; + var shift = 0; + var continuation, digit; + + do { + if (aIndex >= strLen) { + throw new Error("Expected more digits in base 64 VLQ value."); + } + + digit = base64.decode(aStr.charCodeAt(aIndex++)); + if (digit === -1) { + throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1)); + } + + continuation = !!(digit & VLQ_CONTINUATION_BIT); + digit &= VLQ_BASE_MASK; + result = result + (digit << shift); + shift += VLQ_BASE_SHIFT; + } while (continuation); + + aOutParam.value = fromVLQSigned(result); + aOutParam.rest = aIndex; +}; diff --git a/node_modules/source-map/lib/base64.js b/node_modules/source-map/lib/base64.js new file mode 100644 index 0000000..8aa86b3 --- /dev/null +++ b/node_modules/source-map/lib/base64.js @@ -0,0 +1,67 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); + +/** + * Encode an integer in the range of 0 to 63 to a single base 64 digit. + */ +exports.encode = function (number) { + if (0 <= number && number < intToCharMap.length) { + return intToCharMap[number]; + } + throw new TypeError("Must be between 0 and 63: " + number); +}; + +/** + * Decode a single base 64 character code digit to an integer. Returns -1 on + * failure. + */ +exports.decode = function (charCode) { + var bigA = 65; // 'A' + var bigZ = 90; // 'Z' + + var littleA = 97; // 'a' + var littleZ = 122; // 'z' + + var zero = 48; // '0' + var nine = 57; // '9' + + var plus = 43; // '+' + var slash = 47; // '/' + + var littleOffset = 26; + var numberOffset = 52; + + // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ + if (bigA <= charCode && charCode <= bigZ) { + return (charCode - bigA); + } + + // 26 - 51: abcdefghijklmnopqrstuvwxyz + if (littleA <= charCode && charCode <= littleZ) { + return (charCode - littleA + littleOffset); + } + + // 52 - 61: 0123456789 + if (zero <= charCode && charCode <= nine) { + return (charCode - zero + numberOffset); + } + + // 62: + + if (charCode == plus) { + return 62; + } + + // 63: / + if (charCode == slash) { + return 63; + } + + // Invalid base64 digit. + return -1; +}; diff --git a/node_modules/source-map/lib/binary-search.js b/node_modules/source-map/lib/binary-search.js new file mode 100644 index 0000000..010ac94 --- /dev/null +++ b/node_modules/source-map/lib/binary-search.js @@ -0,0 +1,111 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +exports.GREATEST_LOWER_BOUND = 1; +exports.LEAST_UPPER_BOUND = 2; + +/** + * Recursive implementation of binary search. + * + * @param aLow Indices here and lower do not contain the needle. + * @param aHigh Indices here and higher do not contain the needle. + * @param aNeedle The element being searched for. + * @param aHaystack The non-empty array being searched. + * @param aCompare Function which takes two elements and returns -1, 0, or 1. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + */ +function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { + // This function terminates when one of the following is true: + // + // 1. We find the exact element we are looking for. + // + // 2. We did not find the exact element, but we can return the index of + // the next-closest element. + // + // 3. We did not find the exact element, and there is no next-closest + // element than the one we are searching for, so we return -1. + var mid = Math.floor((aHigh - aLow) / 2) + aLow; + var cmp = aCompare(aNeedle, aHaystack[mid], true); + if (cmp === 0) { + // Found the element we are looking for. + return mid; + } + else if (cmp > 0) { + // Our needle is greater than aHaystack[mid]. + if (aHigh - mid > 1) { + // The element is in the upper half. + return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias); + } + + // The exact needle element was not found in this haystack. Determine if + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return aHigh < aHaystack.length ? aHigh : -1; + } else { + return mid; + } + } + else { + // Our needle is less than aHaystack[mid]. + if (mid - aLow > 1) { + // The element is in the lower half. + return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias); + } + + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return mid; + } else { + return aLow < 0 ? -1 : aLow; + } + } +} + +/** + * This is an implementation of binary search which will always try and return + * the index of the closest element if there is no exact hit. This is because + * mappings between original and generated line/col pairs are single points, + * and there is an implicit region between each of them, so a miss just means + * that you aren't on the very start of a region. + * + * @param aNeedle The element you are looking for. + * @param aHaystack The array that is being searched. + * @param aCompare A function which takes the needle and an element in the + * array and returns -1, 0, or 1 depending on whether the needle is less + * than, equal to, or greater than the element, respectively. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'. + */ +exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { + if (aHaystack.length === 0) { + return -1; + } + + var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, + aCompare, aBias || exports.GREATEST_LOWER_BOUND); + if (index < 0) { + return -1; + } + + // We have found either the exact element, or the next-closest element than + // the one we are searching for. However, there may be more than one such + // element. Make sure we always return the smallest of these. + while (index - 1 >= 0) { + if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) { + break; + } + --index; + } + + return index; +}; diff --git a/node_modules/source-map/lib/mapping-list.js b/node_modules/source-map/lib/mapping-list.js new file mode 100644 index 0000000..06d1274 --- /dev/null +++ b/node_modules/source-map/lib/mapping-list.js @@ -0,0 +1,79 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2014 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var util = require('./util'); + +/** + * Determine whether mappingB is after mappingA with respect to generated + * position. + */ +function generatedPositionAfter(mappingA, mappingB) { + // Optimized for most common case + var lineA = mappingA.generatedLine; + var lineB = mappingB.generatedLine; + var columnA = mappingA.generatedColumn; + var columnB = mappingB.generatedColumn; + return lineB > lineA || lineB == lineA && columnB >= columnA || + util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0; +} + +/** + * A data structure to provide a sorted view of accumulated mappings in a + * performance conscious manner. It trades a neglibable overhead in general + * case for a large speedup in case of mappings being added in order. + */ +function MappingList() { + this._array = []; + this._sorted = true; + // Serves as infimum + this._last = {generatedLine: -1, generatedColumn: 0}; +} + +/** + * Iterate through internal items. This method takes the same arguments that + * `Array.prototype.forEach` takes. + * + * NOTE: The order of the mappings is NOT guaranteed. + */ +MappingList.prototype.unsortedForEach = + function MappingList_forEach(aCallback, aThisArg) { + this._array.forEach(aCallback, aThisArg); + }; + +/** + * Add the given source mapping. + * + * @param Object aMapping + */ +MappingList.prototype.add = function MappingList_add(aMapping) { + if (generatedPositionAfter(this._last, aMapping)) { + this._last = aMapping; + this._array.push(aMapping); + } else { + this._sorted = false; + this._array.push(aMapping); + } +}; + +/** + * Returns the flat, sorted array of mappings. The mappings are sorted by + * generated position. + * + * WARNING: This method returns internal data without copying, for + * performance. The return value must NOT be mutated, and should be treated as + * an immutable borrow. If you want to take ownership, you must make your own + * copy. + */ +MappingList.prototype.toArray = function MappingList_toArray() { + if (!this._sorted) { + this._array.sort(util.compareByGeneratedPositionsInflated); + this._sorted = true; + } + return this._array; +}; + +exports.MappingList = MappingList; diff --git a/node_modules/source-map/lib/quick-sort.js b/node_modules/source-map/lib/quick-sort.js new file mode 100644 index 0000000..6a7caad --- /dev/null +++ b/node_modules/source-map/lib/quick-sort.js @@ -0,0 +1,114 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +// It turns out that some (most?) JavaScript engines don't self-host +// `Array.prototype.sort`. This makes sense because C++ will likely remain +// faster than JS when doing raw CPU-intensive sorting. However, when using a +// custom comparator function, calling back and forth between the VM's C++ and +// JIT'd JS is rather slow *and* loses JIT type information, resulting in +// worse generated code for the comparator function than would be optimal. In +// fact, when sorting with a comparator, these costs outweigh the benefits of +// sorting in C++. By using our own JS-implemented Quick Sort (below), we get +// a ~3500ms mean speed-up in `bench/bench.html`. + +/** + * Swap the elements indexed by `x` and `y` in the array `ary`. + * + * @param {Array} ary + * The array. + * @param {Number} x + * The index of the first item. + * @param {Number} y + * The index of the second item. + */ +function swap(ary, x, y) { + var temp = ary[x]; + ary[x] = ary[y]; + ary[y] = temp; +} + +/** + * Returns a random integer within the range `low .. high` inclusive. + * + * @param {Number} low + * The lower bound on the range. + * @param {Number} high + * The upper bound on the range. + */ +function randomIntInRange(low, high) { + return Math.round(low + (Math.random() * (high - low))); +} + +/** + * The Quick Sort algorithm. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + * @param {Number} p + * Start index of the array + * @param {Number} r + * End index of the array + */ +function doQuickSort(ary, comparator, p, r) { + // If our lower bound is less than our upper bound, we (1) partition the + // array into two pieces and (2) recurse on each half. If it is not, this is + // the empty array and our base case. + + if (p < r) { + // (1) Partitioning. + // + // The partitioning chooses a pivot between `p` and `r` and moves all + // elements that are less than or equal to the pivot to the before it, and + // all the elements that are greater than it after it. The effect is that + // once partition is done, the pivot is in the exact place it will be when + // the array is put in sorted order, and it will not need to be moved + // again. This runs in O(n) time. + + // Always choose a random pivot so that an input array which is reverse + // sorted does not cause O(n^2) running time. + var pivotIndex = randomIntInRange(p, r); + var i = p - 1; + + swap(ary, pivotIndex, r); + var pivot = ary[r]; + + // Immediately after `j` is incremented in this loop, the following hold + // true: + // + // * Every element in `ary[p .. i]` is less than or equal to the pivot. + // + // * Every element in `ary[i+1 .. j-1]` is greater than the pivot. + for (var j = p; j < r; j++) { + if (comparator(ary[j], pivot) <= 0) { + i += 1; + swap(ary, i, j); + } + } + + swap(ary, i + 1, j); + var q = i + 1; + + // (2) Recurse on each half. + + doQuickSort(ary, comparator, p, q - 1); + doQuickSort(ary, comparator, q + 1, r); + } +} + +/** + * Sort the given array in-place with the given comparator function. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + */ +exports.quickSort = function (ary, comparator) { + doQuickSort(ary, comparator, 0, ary.length - 1); +}; diff --git a/node_modules/source-map/lib/source-map-consumer.js b/node_modules/source-map/lib/source-map-consumer.js new file mode 100644 index 0000000..6abcc28 --- /dev/null +++ b/node_modules/source-map/lib/source-map-consumer.js @@ -0,0 +1,1082 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var util = require('./util'); +var binarySearch = require('./binary-search'); +var ArraySet = require('./array-set').ArraySet; +var base64VLQ = require('./base64-vlq'); +var quickSort = require('./quick-sort').quickSort; + +function SourceMapConsumer(aSourceMap) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); + } + + return sourceMap.sections != null + ? new IndexedSourceMapConsumer(sourceMap) + : new BasicSourceMapConsumer(sourceMap); +} + +SourceMapConsumer.fromSourceMap = function(aSourceMap) { + return BasicSourceMapConsumer.fromSourceMap(aSourceMap); +} + +/** + * The version of the source mapping spec that we are consuming. + */ +SourceMapConsumer.prototype._version = 3; + +// `__generatedMappings` and `__originalMappings` are arrays that hold the +// parsed mapping coordinates from the source map's "mappings" attribute. They +// are lazily instantiated, accessed via the `_generatedMappings` and +// `_originalMappings` getters respectively, and we only parse the mappings +// and create these arrays once queried for a source location. We jump through +// these hoops because there can be many thousands of mappings, and parsing +// them is expensive, so we only want to do it if we must. +// +// Each object in the arrays is of the form: +// +// { +// generatedLine: The line number in the generated code, +// generatedColumn: The column number in the generated code, +// source: The path to the original source file that generated this +// chunk of code, +// originalLine: The line number in the original source that +// corresponds to this chunk of generated code, +// originalColumn: The column number in the original source that +// corresponds to this chunk of generated code, +// name: The name of the original symbol which generated this chunk of +// code. +// } +// +// All properties except for `generatedLine` and `generatedColumn` can be +// `null`. +// +// `_generatedMappings` is ordered by the generated positions. +// +// `_originalMappings` is ordered by the original positions. + +SourceMapConsumer.prototype.__generatedMappings = null; +Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', { + get: function () { + if (!this.__generatedMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__generatedMappings; + } +}); + +SourceMapConsumer.prototype.__originalMappings = null; +Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { + get: function () { + if (!this.__originalMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__originalMappings; + } +}); + +SourceMapConsumer.prototype._charIsMappingSeparator = + function SourceMapConsumer_charIsMappingSeparator(aStr, index) { + var c = aStr.charAt(index); + return c === ";" || c === ","; + }; + +/** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ +SourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + throw new Error("Subclasses must implement _parseMappings"); + }; + +SourceMapConsumer.GENERATED_ORDER = 1; +SourceMapConsumer.ORIGINAL_ORDER = 2; + +SourceMapConsumer.GREATEST_LOWER_BOUND = 1; +SourceMapConsumer.LEAST_UPPER_BOUND = 2; + +/** + * Iterate over each mapping between an original source/line/column and a + * generated line/column in this source map. + * + * @param Function aCallback + * The function that is called with each mapping. + * @param Object aContext + * Optional. If specified, this object will be the value of `this` every + * time that `aCallback` is called. + * @param aOrder + * Either `SourceMapConsumer.GENERATED_ORDER` or + * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to + * iterate over the mappings sorted by the generated file's line/column + * order or the original's source/line/column order, respectively. Defaults to + * `SourceMapConsumer.GENERATED_ORDER`. + */ +SourceMapConsumer.prototype.eachMapping = + function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { + var context = aContext || null; + var order = aOrder || SourceMapConsumer.GENERATED_ORDER; + + var mappings; + switch (order) { + case SourceMapConsumer.GENERATED_ORDER: + mappings = this._generatedMappings; + break; + case SourceMapConsumer.ORIGINAL_ORDER: + mappings = this._originalMappings; + break; + default: + throw new Error("Unknown order of iteration."); + } + + var sourceRoot = this.sourceRoot; + mappings.map(function (mapping) { + var source = mapping.source === null ? null : this._sources.at(mapping.source); + if (source != null && sourceRoot != null) { + source = util.join(sourceRoot, source); + } + return { + source: source, + generatedLine: mapping.generatedLine, + generatedColumn: mapping.generatedColumn, + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: mapping.name === null ? null : this._names.at(mapping.name) + }; + }, this).forEach(aCallback, context); + }; + +/** + * Returns all generated line and column information for the original source, + * line, and column provided. If no column is provided, returns all mappings + * corresponding to a either the line we are searching for or the next + * closest line that has any mappings. Otherwise, returns all mappings + * corresponding to the given line and either the column we are searching for + * or the next closest column that has any offsets. + * + * The only argument is an object with the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. + * - column: Optional. the column number in the original source. + * + * and an array of objects is returned, each with the following properties: + * + * - line: The line number in the generated source, or null. + * - column: The column number in the generated source, or null. + */ +SourceMapConsumer.prototype.allGeneratedPositionsFor = + function SourceMapConsumer_allGeneratedPositionsFor(aArgs) { + var line = util.getArg(aArgs, 'line'); + + // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping + // returns the index of the closest mapping less than the needle. By + // setting needle.originalColumn to 0, we thus find the last mapping for + // the given line, provided such a mapping exists. + var needle = { + source: util.getArg(aArgs, 'source'), + originalLine: line, + originalColumn: util.getArg(aArgs, 'column', 0) + }; + + if (this.sourceRoot != null) { + needle.source = util.relative(this.sourceRoot, needle.source); + } + if (!this._sources.has(needle.source)) { + return []; + } + needle.source = this._sources.indexOf(needle.source); + + var mappings = []; + + var index = this._findMapping(needle, + this._originalMappings, + "originalLine", + "originalColumn", + util.compareByOriginalPositions, + binarySearch.LEAST_UPPER_BOUND); + if (index >= 0) { + var mapping = this._originalMappings[index]; + + if (aArgs.column === undefined) { + var originalLine = mapping.originalLine; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we found. Since + // mappings are sorted, this is guaranteed to find all mappings for + // the line we found. + while (mapping && mapping.originalLine === originalLine) { + mappings.push({ + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } + } else { + var originalColumn = mapping.originalColumn; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we were searching for. + // Since mappings are sorted, this is guaranteed to find all mappings for + // the line we are searching for. + while (mapping && + mapping.originalLine === line && + mapping.originalColumn == originalColumn) { + mappings.push({ + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } + } + } + + return mappings; + }; + +exports.SourceMapConsumer = SourceMapConsumer; + +/** + * A BasicSourceMapConsumer instance represents a parsed source map which we can + * query for information about the original file positions by giving it a file + * position in the generated source. + * + * The only parameter is the raw source map (either as a JSON string, or + * already parsed to an object). According to the spec, source maps have the + * following attributes: + * + * - version: Which version of the source map spec this map is following. + * - sources: An array of URLs to the original source files. + * - names: An array of identifiers which can be referrenced by individual mappings. + * - sourceRoot: Optional. The URL root from which all sources are relative. + * - sourcesContent: Optional. An array of contents of the original source files. + * - mappings: A string of base64 VLQs which contain the actual mappings. + * - file: Optional. The generated file this source map is associated with. + * + * Here is an example source map, taken from the source map spec[0]: + * + * { + * version : 3, + * file: "out.js", + * sourceRoot : "", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AA,AB;;ABCDE;" + * } + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# + */ +function BasicSourceMapConsumer(aSourceMap) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); + } + + var version = util.getArg(sourceMap, 'version'); + var sources = util.getArg(sourceMap, 'sources'); + // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which + // requires the array) to play nice here. + var names = util.getArg(sourceMap, 'names', []); + var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null); + var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null); + var mappings = util.getArg(sourceMap, 'mappings'); + var file = util.getArg(sourceMap, 'file', null); + + // Once again, Sass deviates from the spec and supplies the version as a + // string rather than a number, so we use loose equality checking here. + if (version != this._version) { + throw new Error('Unsupported version: ' + version); + } + + sources = sources + .map(String) + // Some source maps produce relative source paths like "./foo.js" instead of + // "foo.js". Normalize these first so that future comparisons will succeed. + // See bugzil.la/1090768. + .map(util.normalize) + // Always ensure that absolute sources are internally stored relative to + // the source root, if the source root is absolute. Not doing this would + // be particularly problematic when the source root is a prefix of the + // source (valid, but why??). See github issue #199 and bugzil.la/1188982. + .map(function (source) { + return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source) + ? util.relative(sourceRoot, source) + : source; + }); + + // Pass `true` below to allow duplicate names and sources. While source maps + // are intended to be compressed and deduplicated, the TypeScript compiler + // sometimes generates source maps with duplicates in them. See Github issue + // #72 and bugzil.la/889492. + this._names = ArraySet.fromArray(names.map(String), true); + this._sources = ArraySet.fromArray(sources, true); + + this.sourceRoot = sourceRoot; + this.sourcesContent = sourcesContent; + this._mappings = mappings; + this.file = file; +} + +BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); +BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer; + +/** + * Create a BasicSourceMapConsumer from a SourceMapGenerator. + * + * @param SourceMapGenerator aSourceMap + * The source map that will be consumed. + * @returns BasicSourceMapConsumer + */ +BasicSourceMapConsumer.fromSourceMap = + function SourceMapConsumer_fromSourceMap(aSourceMap) { + var smc = Object.create(BasicSourceMapConsumer.prototype); + + var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true); + var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true); + smc.sourceRoot = aSourceMap._sourceRoot; + smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), + smc.sourceRoot); + smc.file = aSourceMap._file; + + // Because we are modifying the entries (by converting string sources and + // names to indices into the sources and names ArraySets), we have to make + // a copy of the entry or else bad things happen. Shared mutable state + // strikes again! See github issue #191. + + var generatedMappings = aSourceMap._mappings.toArray().slice(); + var destGeneratedMappings = smc.__generatedMappings = []; + var destOriginalMappings = smc.__originalMappings = []; + + for (var i = 0, length = generatedMappings.length; i < length; i++) { + var srcMapping = generatedMappings[i]; + var destMapping = new Mapping; + destMapping.generatedLine = srcMapping.generatedLine; + destMapping.generatedColumn = srcMapping.generatedColumn; + + if (srcMapping.source) { + destMapping.source = sources.indexOf(srcMapping.source); + destMapping.originalLine = srcMapping.originalLine; + destMapping.originalColumn = srcMapping.originalColumn; + + if (srcMapping.name) { + destMapping.name = names.indexOf(srcMapping.name); + } + + destOriginalMappings.push(destMapping); + } + + destGeneratedMappings.push(destMapping); + } + + quickSort(smc.__originalMappings, util.compareByOriginalPositions); + + return smc; + }; + +/** + * The version of the source mapping spec that we are consuming. + */ +BasicSourceMapConsumer.prototype._version = 3; + +/** + * The list of original sources. + */ +Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', { + get: function () { + return this._sources.toArray().map(function (s) { + return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s; + }, this); + } +}); + +/** + * Provide the JIT with a nice shape / hidden class. + */ +function Mapping() { + this.generatedLine = 0; + this.generatedColumn = 0; + this.source = null; + this.originalLine = null; + this.originalColumn = null; + this.name = null; +} + +/** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ +BasicSourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + var generatedLine = 1; + var previousGeneratedColumn = 0; + var previousOriginalLine = 0; + var previousOriginalColumn = 0; + var previousSource = 0; + var previousName = 0; + var length = aStr.length; + var index = 0; + var cachedSegments = {}; + var temp = {}; + var originalMappings = []; + var generatedMappings = []; + var mapping, str, segment, end, value; + + while (index < length) { + if (aStr.charAt(index) === ';') { + generatedLine++; + index++; + previousGeneratedColumn = 0; + } + else if (aStr.charAt(index) === ',') { + index++; + } + else { + mapping = new Mapping(); + mapping.generatedLine = generatedLine; + + // Because each offset is encoded relative to the previous one, + // many segments often have the same encoding. We can exploit this + // fact by caching the parsed variable length fields of each segment, + // allowing us to avoid a second parse if we encounter the same + // segment again. + for (end = index; end < length; end++) { + if (this._charIsMappingSeparator(aStr, end)) { + break; + } + } + str = aStr.slice(index, end); + + segment = cachedSegments[str]; + if (segment) { + index += str.length; + } else { + segment = []; + while (index < end) { + base64VLQ.decode(aStr, index, temp); + value = temp.value; + index = temp.rest; + segment.push(value); + } + + if (segment.length === 2) { + throw new Error('Found a source, but no line and column'); + } + + if (segment.length === 3) { + throw new Error('Found a source and line, but no column'); + } + + cachedSegments[str] = segment; + } + + // Generated column. + mapping.generatedColumn = previousGeneratedColumn + segment[0]; + previousGeneratedColumn = mapping.generatedColumn; + + if (segment.length > 1) { + // Original source. + mapping.source = previousSource + segment[1]; + previousSource += segment[1]; + + // Original line. + mapping.originalLine = previousOriginalLine + segment[2]; + previousOriginalLine = mapping.originalLine; + // Lines are stored 0-based + mapping.originalLine += 1; + + // Original column. + mapping.originalColumn = previousOriginalColumn + segment[3]; + previousOriginalColumn = mapping.originalColumn; + + if (segment.length > 4) { + // Original name. + mapping.name = previousName + segment[4]; + previousName += segment[4]; + } + } + + generatedMappings.push(mapping); + if (typeof mapping.originalLine === 'number') { + originalMappings.push(mapping); + } + } + } + + quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated); + this.__generatedMappings = generatedMappings; + + quickSort(originalMappings, util.compareByOriginalPositions); + this.__originalMappings = originalMappings; + }; + +/** + * Find the mapping that best matches the hypothetical "needle" mapping that + * we are searching for in the given "haystack" of mappings. + */ +BasicSourceMapConsumer.prototype._findMapping = + function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, + aColumnName, aComparator, aBias) { + // To return the position we are searching for, we must first find the + // mapping for the given position and then return the opposite position it + // points to. Because the mappings are sorted, we can use binary search to + // find the best mapping. + + if (aNeedle[aLineName] <= 0) { + throw new TypeError('Line must be greater than or equal to 1, got ' + + aNeedle[aLineName]); + } + if (aNeedle[aColumnName] < 0) { + throw new TypeError('Column must be greater than or equal to 0, got ' + + aNeedle[aColumnName]); + } + + return binarySearch.search(aNeedle, aMappings, aComparator, aBias); + }; + +/** + * Compute the last column for each generated mapping. The last column is + * inclusive. + */ +BasicSourceMapConsumer.prototype.computeColumnSpans = + function SourceMapConsumer_computeColumnSpans() { + for (var index = 0; index < this._generatedMappings.length; ++index) { + var mapping = this._generatedMappings[index]; + + // Mappings do not contain a field for the last generated columnt. We + // can come up with an optimistic estimate, however, by assuming that + // mappings are contiguous (i.e. given two consecutive mappings, the + // first mapping ends where the second one starts). + if (index + 1 < this._generatedMappings.length) { + var nextMapping = this._generatedMappings[index + 1]; + + if (mapping.generatedLine === nextMapping.generatedLine) { + mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1; + continue; + } + } + + // The last mapping for each line spans the entire line. + mapping.lastGeneratedColumn = Infinity; + } + }; + +/** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. + * - column: The column number in the generated source. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. + * - column: The column number in the original source, or null. + * - name: The original identifier, or null. + */ +BasicSourceMapConsumer.prototype.originalPositionFor = + function SourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util.getArg(aArgs, 'line'), + generatedColumn: util.getArg(aArgs, 'column') + }; + + var index = this._findMapping( + needle, + this._generatedMappings, + "generatedLine", + "generatedColumn", + util.compareByGeneratedPositionsDeflated, + util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); + + if (index >= 0) { + var mapping = this._generatedMappings[index]; + + if (mapping.generatedLine === needle.generatedLine) { + var source = util.getArg(mapping, 'source', null); + if (source !== null) { + source = this._sources.at(source); + if (this.sourceRoot != null) { + source = util.join(this.sourceRoot, source); + } + } + var name = util.getArg(mapping, 'name', null); + if (name !== null) { + name = this._names.at(name); + } + return { + source: source, + line: util.getArg(mapping, 'originalLine', null), + column: util.getArg(mapping, 'originalColumn', null), + name: name + }; + } + } + + return { + source: null, + line: null, + column: null, + name: null + }; + }; + +/** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ +BasicSourceMapConsumer.prototype.hasContentsOfAllSources = + function BasicSourceMapConsumer_hasContentsOfAllSources() { + if (!this.sourcesContent) { + return false; + } + return this.sourcesContent.length >= this._sources.size() && + !this.sourcesContent.some(function (sc) { return sc == null; }); + }; + +/** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ +BasicSourceMapConsumer.prototype.sourceContentFor = + function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + if (!this.sourcesContent) { + return null; + } + + if (this.sourceRoot != null) { + aSource = util.relative(this.sourceRoot, aSource); + } + + if (this._sources.has(aSource)) { + return this.sourcesContent[this._sources.indexOf(aSource)]; + } + + var url; + if (this.sourceRoot != null + && (url = util.urlParse(this.sourceRoot))) { + // XXX: file:// URIs and absolute paths lead to unexpected behavior for + // many users. We can help them out when they expect file:// URIs to + // behave like it would if they were running a local HTTP server. See + // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. + var fileUriAbsPath = aSource.replace(/^file:\/\//, ""); + if (url.scheme == "file" + && this._sources.has(fileUriAbsPath)) { + return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] + } + + if ((!url.path || url.path == "/") + && this._sources.has("/" + aSource)) { + return this.sourcesContent[this._sources.indexOf("/" + aSource)]; + } + } + + // This function is used recursively from + // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we + // don't want to throw if we can't find the source - we just want to + // return null, so we provide a flag to exit gracefully. + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + aSource + '" is not in the SourceMap.'); + } + }; + +/** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. + * - column: The column number in the original source. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. + * - column: The column number in the generated source, or null. + */ +BasicSourceMapConsumer.prototype.generatedPositionFor = + function SourceMapConsumer_generatedPositionFor(aArgs) { + var source = util.getArg(aArgs, 'source'); + if (this.sourceRoot != null) { + source = util.relative(this.sourceRoot, source); + } + if (!this._sources.has(source)) { + return { + line: null, + column: null, + lastColumn: null + }; + } + source = this._sources.indexOf(source); + + var needle = { + source: source, + originalLine: util.getArg(aArgs, 'line'), + originalColumn: util.getArg(aArgs, 'column') + }; + + var index = this._findMapping( + needle, + this._originalMappings, + "originalLine", + "originalColumn", + util.compareByOriginalPositions, + util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); + + if (index >= 0) { + var mapping = this._originalMappings[index]; + + if (mapping.source === needle.source) { + return { + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }; + } + } + + return { + line: null, + column: null, + lastColumn: null + }; + }; + +exports.BasicSourceMapConsumer = BasicSourceMapConsumer; + +/** + * An IndexedSourceMapConsumer instance represents a parsed source map which + * we can query for information. It differs from BasicSourceMapConsumer in + * that it takes "indexed" source maps (i.e. ones with a "sections" field) as + * input. + * + * The only parameter is a raw source map (either as a JSON string, or already + * parsed to an object). According to the spec for indexed source maps, they + * have the following attributes: + * + * - version: Which version of the source map spec this map is following. + * - file: Optional. The generated file this source map is associated with. + * - sections: A list of section definitions. + * + * Each value under the "sections" field has two fields: + * - offset: The offset into the original specified at which this section + * begins to apply, defined as an object with a "line" and "column" + * field. + * - map: A source map definition. This source map could also be indexed, + * but doesn't have to be. + * + * Instead of the "map" field, it's also possible to have a "url" field + * specifying a URL to retrieve a source map from, but that's currently + * unsupported. + * + * Here's an example source map, taken from the source map spec[0], but + * modified to omit a section which uses the "url" field. + * + * { + * version : 3, + * file: "app.js", + * sections: [{ + * offset: {line:100, column:10}, + * map: { + * version : 3, + * file: "section.js", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AAAA,E;;ABCDE;" + * } + * }], + * } + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt + */ +function IndexedSourceMapConsumer(aSourceMap) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); + } + + var version = util.getArg(sourceMap, 'version'); + var sections = util.getArg(sourceMap, 'sections'); + + if (version != this._version) { + throw new Error('Unsupported version: ' + version); + } + + this._sources = new ArraySet(); + this._names = new ArraySet(); + + var lastOffset = { + line: -1, + column: 0 + }; + this._sections = sections.map(function (s) { + if (s.url) { + // The url field will require support for asynchronicity. + // See https://github.com/mozilla/source-map/issues/16 + throw new Error('Support for url field in sections not implemented.'); + } + var offset = util.getArg(s, 'offset'); + var offsetLine = util.getArg(offset, 'line'); + var offsetColumn = util.getArg(offset, 'column'); + + if (offsetLine < lastOffset.line || + (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) { + throw new Error('Section offsets must be ordered and non-overlapping.'); + } + lastOffset = offset; + + return { + generatedOffset: { + // The offset fields are 0-based, but we use 1-based indices when + // encoding/decoding from VLQ. + generatedLine: offsetLine + 1, + generatedColumn: offsetColumn + 1 + }, + consumer: new SourceMapConsumer(util.getArg(s, 'map')) + } + }); +} + +IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); +IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer; + +/** + * The version of the source mapping spec that we are consuming. + */ +IndexedSourceMapConsumer.prototype._version = 3; + +/** + * The list of original sources. + */ +Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', { + get: function () { + var sources = []; + for (var i = 0; i < this._sections.length; i++) { + for (var j = 0; j < this._sections[i].consumer.sources.length; j++) { + sources.push(this._sections[i].consumer.sources[j]); + } + } + return sources; + } +}); + +/** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. + * - column: The column number in the generated source. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. + * - column: The column number in the original source, or null. + * - name: The original identifier, or null. + */ +IndexedSourceMapConsumer.prototype.originalPositionFor = + function IndexedSourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util.getArg(aArgs, 'line'), + generatedColumn: util.getArg(aArgs, 'column') + }; + + // Find the section containing the generated position we're trying to map + // to an original position. + var sectionIndex = binarySearch.search(needle, this._sections, + function(needle, section) { + var cmp = needle.generatedLine - section.generatedOffset.generatedLine; + if (cmp) { + return cmp; + } + + return (needle.generatedColumn - + section.generatedOffset.generatedColumn); + }); + var section = this._sections[sectionIndex]; + + if (!section) { + return { + source: null, + line: null, + column: null, + name: null + }; + } + + return section.consumer.originalPositionFor({ + line: needle.generatedLine - + (section.generatedOffset.generatedLine - 1), + column: needle.generatedColumn - + (section.generatedOffset.generatedLine === needle.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + bias: aArgs.bias + }); + }; + +/** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ +IndexedSourceMapConsumer.prototype.hasContentsOfAllSources = + function IndexedSourceMapConsumer_hasContentsOfAllSources() { + return this._sections.every(function (s) { + return s.consumer.hasContentsOfAllSources(); + }); + }; + +/** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ +IndexedSourceMapConsumer.prototype.sourceContentFor = + function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + + var content = section.consumer.sourceContentFor(aSource, true); + if (content) { + return content; + } + } + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + aSource + '" is not in the SourceMap.'); + } + }; + +/** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. + * - column: The column number in the original source. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. + * - column: The column number in the generated source, or null. + */ +IndexedSourceMapConsumer.prototype.generatedPositionFor = + function IndexedSourceMapConsumer_generatedPositionFor(aArgs) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + + // Only consider this section if the requested source is in the list of + // sources of the consumer. + if (section.consumer.sources.indexOf(util.getArg(aArgs, 'source')) === -1) { + continue; + } + var generatedPosition = section.consumer.generatedPositionFor(aArgs); + if (generatedPosition) { + var ret = { + line: generatedPosition.line + + (section.generatedOffset.generatedLine - 1), + column: generatedPosition.column + + (section.generatedOffset.generatedLine === generatedPosition.line + ? section.generatedOffset.generatedColumn - 1 + : 0) + }; + return ret; + } + } + + return { + line: null, + column: null + }; + }; + +/** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ +IndexedSourceMapConsumer.prototype._parseMappings = + function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) { + this.__generatedMappings = []; + this.__originalMappings = []; + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + var sectionMappings = section.consumer._generatedMappings; + for (var j = 0; j < sectionMappings.length; j++) { + var mapping = sectionMappings[j]; + + var source = section.consumer._sources.at(mapping.source); + if (section.consumer.sourceRoot !== null) { + source = util.join(section.consumer.sourceRoot, source); + } + this._sources.add(source); + source = this._sources.indexOf(source); + + var name = section.consumer._names.at(mapping.name); + this._names.add(name); + name = this._names.indexOf(name); + + // The mappings coming from the consumer for the section have + // generated positions relative to the start of the section, so we + // need to offset them to be relative to the start of the concatenated + // generated file. + var adjustedMapping = { + source: source, + generatedLine: mapping.generatedLine + + (section.generatedOffset.generatedLine - 1), + generatedColumn: mapping.generatedColumn + + (section.generatedOffset.generatedLine === mapping.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: name + }; + + this.__generatedMappings.push(adjustedMapping); + if (typeof adjustedMapping.originalLine === 'number') { + this.__originalMappings.push(adjustedMapping); + } + } + } + + quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated); + quickSort(this.__originalMappings, util.compareByOriginalPositions); + }; + +exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; diff --git a/node_modules/source-map/lib/source-map-generator.js b/node_modules/source-map/lib/source-map-generator.js new file mode 100644 index 0000000..8fbb8e8 --- /dev/null +++ b/node_modules/source-map/lib/source-map-generator.js @@ -0,0 +1,404 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var base64VLQ = require('./base64-vlq'); +var util = require('./util'); +var ArraySet = require('./array-set').ArraySet; +var MappingList = require('./mapping-list').MappingList; + +/** + * An instance of the SourceMapGenerator represents a source map which is + * being built incrementally. You may pass an object with the following + * properties: + * + * - file: The filename of the generated source. + * - sourceRoot: A root for all relative URLs in this source map. + */ +function SourceMapGenerator(aArgs) { + if (!aArgs) { + aArgs = {}; + } + this._file = util.getArg(aArgs, 'file', null); + this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null); + this._skipValidation = util.getArg(aArgs, 'skipValidation', false); + this._sources = new ArraySet(); + this._names = new ArraySet(); + this._mappings = new MappingList(); + this._sourcesContents = null; +} + +SourceMapGenerator.prototype._version = 3; + +/** + * Creates a new SourceMapGenerator based on a SourceMapConsumer + * + * @param aSourceMapConsumer The SourceMap. + */ +SourceMapGenerator.fromSourceMap = + function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) { + var sourceRoot = aSourceMapConsumer.sourceRoot; + var generator = new SourceMapGenerator({ + file: aSourceMapConsumer.file, + sourceRoot: sourceRoot + }); + aSourceMapConsumer.eachMapping(function (mapping) { + var newMapping = { + generated: { + line: mapping.generatedLine, + column: mapping.generatedColumn + } + }; + + if (mapping.source != null) { + newMapping.source = mapping.source; + if (sourceRoot != null) { + newMapping.source = util.relative(sourceRoot, newMapping.source); + } + + newMapping.original = { + line: mapping.originalLine, + column: mapping.originalColumn + }; + + if (mapping.name != null) { + newMapping.name = mapping.name; + } + } + + generator.addMapping(newMapping); + }); + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + generator.setSourceContent(sourceFile, content); + } + }); + return generator; + }; + +/** + * Add a single mapping from original source line and column to the generated + * source's line and column for this source map being created. The mapping + * object should have the following properties: + * + * - generated: An object with the generated line and column positions. + * - original: An object with the original line and column positions. + * - source: The original source file (relative to the sourceRoot). + * - name: An optional original token name for this mapping. + */ +SourceMapGenerator.prototype.addMapping = + function SourceMapGenerator_addMapping(aArgs) { + var generated = util.getArg(aArgs, 'generated'); + var original = util.getArg(aArgs, 'original', null); + var source = util.getArg(aArgs, 'source', null); + var name = util.getArg(aArgs, 'name', null); + + if (!this._skipValidation) { + this._validateMapping(generated, original, source, name); + } + + if (source != null) { + source = String(source); + if (!this._sources.has(source)) { + this._sources.add(source); + } + } + + if (name != null) { + name = String(name); + if (!this._names.has(name)) { + this._names.add(name); + } + } + + this._mappings.add({ + generatedLine: generated.line, + generatedColumn: generated.column, + originalLine: original != null && original.line, + originalColumn: original != null && original.column, + source: source, + name: name + }); + }; + +/** + * Set the source content for a source file. + */ +SourceMapGenerator.prototype.setSourceContent = + function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { + var source = aSourceFile; + if (this._sourceRoot != null) { + source = util.relative(this._sourceRoot, source); + } + + if (aSourceContent != null) { + // Add the source content to the _sourcesContents map. + // Create a new _sourcesContents map if the property is null. + if (!this._sourcesContents) { + this._sourcesContents = Object.create(null); + } + this._sourcesContents[util.toSetString(source)] = aSourceContent; + } else if (this._sourcesContents) { + // Remove the source file from the _sourcesContents map. + // If the _sourcesContents map is empty, set the property to null. + delete this._sourcesContents[util.toSetString(source)]; + if (Object.keys(this._sourcesContents).length === 0) { + this._sourcesContents = null; + } + } + }; + +/** + * Applies the mappings of a sub-source-map for a specific source file to the + * source map being generated. Each mapping to the supplied source file is + * rewritten using the supplied source map. Note: The resolution for the + * resulting mappings is the minimium of this map and the supplied map. + * + * @param aSourceMapConsumer The source map to be applied. + * @param aSourceFile Optional. The filename of the source file. + * If omitted, SourceMapConsumer's file property will be used. + * @param aSourceMapPath Optional. The dirname of the path to the source map + * to be applied. If relative, it is relative to the SourceMapConsumer. + * This parameter is needed when the two source maps aren't in the same + * directory, and the source map to be applied contains relative source + * paths. If so, those relative source paths need to be rewritten + * relative to the SourceMapGenerator. + */ +SourceMapGenerator.prototype.applySourceMap = + function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) { + var sourceFile = aSourceFile; + // If aSourceFile is omitted, we will use the file property of the SourceMap + if (aSourceFile == null) { + if (aSourceMapConsumer.file == null) { + throw new Error( + 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' + + 'or the source map\'s "file" property. Both were omitted.' + ); + } + sourceFile = aSourceMapConsumer.file; + } + var sourceRoot = this._sourceRoot; + // Make "sourceFile" relative if an absolute Url is passed. + if (sourceRoot != null) { + sourceFile = util.relative(sourceRoot, sourceFile); + } + // Applying the SourceMap can add and remove items from the sources and + // the names array. + var newSources = new ArraySet(); + var newNames = new ArraySet(); + + // Find mappings for the "sourceFile" + this._mappings.unsortedForEach(function (mapping) { + if (mapping.source === sourceFile && mapping.originalLine != null) { + // Check if it can be mapped by the source map, then update the mapping. + var original = aSourceMapConsumer.originalPositionFor({ + line: mapping.originalLine, + column: mapping.originalColumn + }); + if (original.source != null) { + // Copy mapping + mapping.source = original.source; + if (aSourceMapPath != null) { + mapping.source = util.join(aSourceMapPath, mapping.source) + } + if (sourceRoot != null) { + mapping.source = util.relative(sourceRoot, mapping.source); + } + mapping.originalLine = original.line; + mapping.originalColumn = original.column; + if (original.name != null) { + mapping.name = original.name; + } + } + } + + var source = mapping.source; + if (source != null && !newSources.has(source)) { + newSources.add(source); + } + + var name = mapping.name; + if (name != null && !newNames.has(name)) { + newNames.add(name); + } + + }, this); + this._sources = newSources; + this._names = newNames; + + // Copy sourcesContents of applied map. + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aSourceMapPath != null) { + sourceFile = util.join(aSourceMapPath, sourceFile); + } + if (sourceRoot != null) { + sourceFile = util.relative(sourceRoot, sourceFile); + } + this.setSourceContent(sourceFile, content); + } + }, this); + }; + +/** + * A mapping can have one of the three levels of data: + * + * 1. Just the generated position. + * 2. The Generated position, original position, and original source. + * 3. Generated and original position, original source, as well as a name + * token. + * + * To maintain consistency, we validate that any new mapping being added falls + * in to one of these categories. + */ +SourceMapGenerator.prototype._validateMapping = + function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, + aName) { + if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aGenerated.line > 0 && aGenerated.column >= 0 + && !aOriginal && !aSource && !aName) { + // Case 1. + return; + } + else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aOriginal && 'line' in aOriginal && 'column' in aOriginal + && aGenerated.line > 0 && aGenerated.column >= 0 + && aOriginal.line > 0 && aOriginal.column >= 0 + && aSource) { + // Cases 2 and 3. + return; + } + else { + throw new Error('Invalid mapping: ' + JSON.stringify({ + generated: aGenerated, + source: aSource, + original: aOriginal, + name: aName + })); + } + }; + +/** + * Serialize the accumulated mappings in to the stream of base 64 VLQs + * specified by the source map format. + */ +SourceMapGenerator.prototype._serializeMappings = + function SourceMapGenerator_serializeMappings() { + var previousGeneratedColumn = 0; + var previousGeneratedLine = 1; + var previousOriginalColumn = 0; + var previousOriginalLine = 0; + var previousName = 0; + var previousSource = 0; + var result = ''; + var next; + var mapping; + var nameIdx; + var sourceIdx; + + var mappings = this._mappings.toArray(); + for (var i = 0, len = mappings.length; i < len; i++) { + mapping = mappings[i]; + next = '' + + if (mapping.generatedLine !== previousGeneratedLine) { + previousGeneratedColumn = 0; + while (mapping.generatedLine !== previousGeneratedLine) { + next += ';'; + previousGeneratedLine++; + } + } + else { + if (i > 0) { + if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) { + continue; + } + next += ','; + } + } + + next += base64VLQ.encode(mapping.generatedColumn + - previousGeneratedColumn); + previousGeneratedColumn = mapping.generatedColumn; + + if (mapping.source != null) { + sourceIdx = this._sources.indexOf(mapping.source); + next += base64VLQ.encode(sourceIdx - previousSource); + previousSource = sourceIdx; + + // lines are stored 0-based in SourceMap spec version 3 + next += base64VLQ.encode(mapping.originalLine - 1 + - previousOriginalLine); + previousOriginalLine = mapping.originalLine - 1; + + next += base64VLQ.encode(mapping.originalColumn + - previousOriginalColumn); + previousOriginalColumn = mapping.originalColumn; + + if (mapping.name != null) { + nameIdx = this._names.indexOf(mapping.name); + next += base64VLQ.encode(nameIdx - previousName); + previousName = nameIdx; + } + } + + result += next; + } + + return result; + }; + +SourceMapGenerator.prototype._generateSourcesContent = + function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) { + return aSources.map(function (source) { + if (!this._sourcesContents) { + return null; + } + if (aSourceRoot != null) { + source = util.relative(aSourceRoot, source); + } + var key = util.toSetString(source); + return Object.prototype.hasOwnProperty.call(this._sourcesContents, key) + ? this._sourcesContents[key] + : null; + }, this); + }; + +/** + * Externalize the source map. + */ +SourceMapGenerator.prototype.toJSON = + function SourceMapGenerator_toJSON() { + var map = { + version: this._version, + sources: this._sources.toArray(), + names: this._names.toArray(), + mappings: this._serializeMappings() + }; + if (this._file != null) { + map.file = this._file; + } + if (this._sourceRoot != null) { + map.sourceRoot = this._sourceRoot; + } + if (this._sourcesContents) { + map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); + } + + return map; + }; + +/** + * Render the source map being generated to a string. + */ +SourceMapGenerator.prototype.toString = + function SourceMapGenerator_toString() { + return JSON.stringify(this.toJSON()); + }; + +exports.SourceMapGenerator = SourceMapGenerator; diff --git a/node_modules/source-map/lib/source-node.js b/node_modules/source-map/lib/source-node.js new file mode 100644 index 0000000..e927f66 --- /dev/null +++ b/node_modules/source-map/lib/source-node.js @@ -0,0 +1,407 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var SourceMapGenerator = require('./source-map-generator').SourceMapGenerator; +var util = require('./util'); + +// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other +// operating systems these days (capturing the result). +var REGEX_NEWLINE = /(\r?\n)/; + +// Newline character code for charCodeAt() comparisons +var NEWLINE_CODE = 10; + +// Private symbol for identifying `SourceNode`s when multiple versions of +// the source-map library are loaded. This MUST NOT CHANGE across +// versions! +var isSourceNode = "$$$isSourceNode$$$"; + +/** + * SourceNodes provide a way to abstract over interpolating/concatenating + * snippets of generated JavaScript source code while maintaining the line and + * column information associated with the original source code. + * + * @param aLine The original line number. + * @param aColumn The original column number. + * @param aSource The original source's filename. + * @param aChunks Optional. An array of strings which are snippets of + * generated JS, or other SourceNodes. + * @param aName The original identifier. + */ +function SourceNode(aLine, aColumn, aSource, aChunks, aName) { + this.children = []; + this.sourceContents = {}; + this.line = aLine == null ? null : aLine; + this.column = aColumn == null ? null : aColumn; + this.source = aSource == null ? null : aSource; + this.name = aName == null ? null : aName; + this[isSourceNode] = true; + if (aChunks != null) this.add(aChunks); +} + +/** + * Creates a SourceNode from generated code and a SourceMapConsumer. + * + * @param aGeneratedCode The generated code + * @param aSourceMapConsumer The SourceMap for the generated code + * @param aRelativePath Optional. The path that relative sources in the + * SourceMapConsumer should be relative to. + */ +SourceNode.fromStringWithSourceMap = + function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) { + // The SourceNode we want to fill with the generated code + // and the SourceMap + var node = new SourceNode(); + + // All even indices of this array are one line of the generated code, + // while all odd indices are the newlines between two adjacent lines + // (since `REGEX_NEWLINE` captures its match). + // Processed fragments are removed from this array, by calling `shiftNextLine`. + var remainingLines = aGeneratedCode.split(REGEX_NEWLINE); + var shiftNextLine = function() { + var lineContents = remainingLines.shift(); + // The last line of a file might not have a newline. + var newLine = remainingLines.shift() || ""; + return lineContents + newLine; + }; + + // We need to remember the position of "remainingLines" + var lastGeneratedLine = 1, lastGeneratedColumn = 0; + + // The generate SourceNodes we need a code range. + // To extract it current and last mapping is used. + // Here we store the last mapping. + var lastMapping = null; + + aSourceMapConsumer.eachMapping(function (mapping) { + if (lastMapping !== null) { + // We add the code from "lastMapping" to "mapping": + // First check if there is a new line in between. + if (lastGeneratedLine < mapping.generatedLine) { + // Associate first line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + lastGeneratedLine++; + lastGeneratedColumn = 0; + // The remaining code is added without mapping + } else { + // There is no new line in between. + // Associate the code between "lastGeneratedColumn" and + // "mapping.generatedColumn" with "lastMapping" + var nextLine = remainingLines[0]; + var code = nextLine.substr(0, mapping.generatedColumn - + lastGeneratedColumn); + remainingLines[0] = nextLine.substr(mapping.generatedColumn - + lastGeneratedColumn); + lastGeneratedColumn = mapping.generatedColumn; + addMappingWithCode(lastMapping, code); + // No more remaining code, continue + lastMapping = mapping; + return; + } + } + // We add the generated code until the first mapping + // to the SourceNode without any mapping. + // Each line is added as separate string. + while (lastGeneratedLine < mapping.generatedLine) { + node.add(shiftNextLine()); + lastGeneratedLine++; + } + if (lastGeneratedColumn < mapping.generatedColumn) { + var nextLine = remainingLines[0]; + node.add(nextLine.substr(0, mapping.generatedColumn)); + remainingLines[0] = nextLine.substr(mapping.generatedColumn); + lastGeneratedColumn = mapping.generatedColumn; + } + lastMapping = mapping; + }, this); + // We have processed all mappings. + if (remainingLines.length > 0) { + if (lastMapping) { + // Associate the remaining code in the current line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + } + // and add the remaining lines without any mapping + node.add(remainingLines.join("")); + } + + // Copy sourcesContent into SourceNode + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aRelativePath != null) { + sourceFile = util.join(aRelativePath, sourceFile); + } + node.setSourceContent(sourceFile, content); + } + }); + + return node; + + function addMappingWithCode(mapping, code) { + if (mapping === null || mapping.source === undefined) { + node.add(code); + } else { + var source = aRelativePath + ? util.join(aRelativePath, mapping.source) + : mapping.source; + node.add(new SourceNode(mapping.originalLine, + mapping.originalColumn, + source, + code, + mapping.name)); + } + } + }; + +/** + * Add a chunk of generated JS to this source node. + * + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. + */ +SourceNode.prototype.add = function SourceNode_add(aChunk) { + if (Array.isArray(aChunk)) { + aChunk.forEach(function (chunk) { + this.add(chunk); + }, this); + } + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + if (aChunk) { + this.children.push(aChunk); + } + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; +}; + +/** + * Add a chunk of generated JS to the beginning of this source node. + * + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. + */ +SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) { + if (Array.isArray(aChunk)) { + for (var i = aChunk.length-1; i >= 0; i--) { + this.prepend(aChunk[i]); + } + } + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + this.children.unshift(aChunk); + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; +}; + +/** + * Walk over the tree of JS snippets in this node and its children. The + * walking function is called once for each snippet of JS and is passed that + * snippet and the its original associated source's line/column location. + * + * @param aFn The traversal function. + */ +SourceNode.prototype.walk = function SourceNode_walk(aFn) { + var chunk; + for (var i = 0, len = this.children.length; i < len; i++) { + chunk = this.children[i]; + if (chunk[isSourceNode]) { + chunk.walk(aFn); + } + else { + if (chunk !== '') { + aFn(chunk, { source: this.source, + line: this.line, + column: this.column, + name: this.name }); + } + } + } +}; + +/** + * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between + * each of `this.children`. + * + * @param aSep The separator. + */ +SourceNode.prototype.join = function SourceNode_join(aSep) { + var newChildren; + var i; + var len = this.children.length; + if (len > 0) { + newChildren = []; + for (i = 0; i < len-1; i++) { + newChildren.push(this.children[i]); + newChildren.push(aSep); + } + newChildren.push(this.children[i]); + this.children = newChildren; + } + return this; +}; + +/** + * Call String.prototype.replace on the very right-most source snippet. Useful + * for trimming whitespace from the end of a source node, etc. + * + * @param aPattern The pattern to replace. + * @param aReplacement The thing to replace the pattern with. + */ +SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) { + var lastChild = this.children[this.children.length - 1]; + if (lastChild[isSourceNode]) { + lastChild.replaceRight(aPattern, aReplacement); + } + else if (typeof lastChild === 'string') { + this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); + } + else { + this.children.push(''.replace(aPattern, aReplacement)); + } + return this; +}; + +/** + * Set the source content for a source file. This will be added to the SourceMapGenerator + * in the sourcesContent field. + * + * @param aSourceFile The filename of the source file + * @param aSourceContent The content of the source file + */ +SourceNode.prototype.setSourceContent = + function SourceNode_setSourceContent(aSourceFile, aSourceContent) { + this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; + }; + +/** + * Walk over the tree of SourceNodes. The walking function is called for each + * source file content and is passed the filename and source content. + * + * @param aFn The traversal function. + */ +SourceNode.prototype.walkSourceContents = + function SourceNode_walkSourceContents(aFn) { + for (var i = 0, len = this.children.length; i < len; i++) { + if (this.children[i][isSourceNode]) { + this.children[i].walkSourceContents(aFn); + } + } + + var sources = Object.keys(this.sourceContents); + for (var i = 0, len = sources.length; i < len; i++) { + aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); + } + }; + +/** + * Return the string representation of this source node. Walks over the tree + * and concatenates all the various snippets together to one string. + */ +SourceNode.prototype.toString = function SourceNode_toString() { + var str = ""; + this.walk(function (chunk) { + str += chunk; + }); + return str; +}; + +/** + * Returns the string representation of this source node along with a source + * map. + */ +SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) { + var generated = { + code: "", + line: 1, + column: 0 + }; + var map = new SourceMapGenerator(aArgs); + var sourceMappingActive = false; + var lastOriginalSource = null; + var lastOriginalLine = null; + var lastOriginalColumn = null; + var lastOriginalName = null; + this.walk(function (chunk, original) { + generated.code += chunk; + if (original.source !== null + && original.line !== null + && original.column !== null) { + if(lastOriginalSource !== original.source + || lastOriginalLine !== original.line + || lastOriginalColumn !== original.column + || lastOriginalName !== original.name) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + lastOriginalSource = original.source; + lastOriginalLine = original.line; + lastOriginalColumn = original.column; + lastOriginalName = original.name; + sourceMappingActive = true; + } else if (sourceMappingActive) { + map.addMapping({ + generated: { + line: generated.line, + column: generated.column + } + }); + lastOriginalSource = null; + sourceMappingActive = false; + } + for (var idx = 0, length = chunk.length; idx < length; idx++) { + if (chunk.charCodeAt(idx) === NEWLINE_CODE) { + generated.line++; + generated.column = 0; + // Mappings end at eol + if (idx + 1 === length) { + lastOriginalSource = null; + sourceMappingActive = false; + } else if (sourceMappingActive) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + } else { + generated.column++; + } + } + }); + this.walkSourceContents(function (sourceFile, sourceContent) { + map.setSourceContent(sourceFile, sourceContent); + }); + + return { code: generated.code, map: map }; +}; + +exports.SourceNode = SourceNode; diff --git a/node_modules/source-map/lib/util.js b/node_modules/source-map/lib/util.js new file mode 100644 index 0000000..44e0e45 --- /dev/null +++ b/node_modules/source-map/lib/util.js @@ -0,0 +1,417 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +/** + * This is a helper function for getting values from parameter/options + * objects. + * + * @param args The object we are extracting values from + * @param name The name of the property we are getting. + * @param defaultValue An optional value to return if the property is missing + * from the object. If this is not specified and the property is missing, an + * error will be thrown. + */ +function getArg(aArgs, aName, aDefaultValue) { + if (aName in aArgs) { + return aArgs[aName]; + } else if (arguments.length === 3) { + return aDefaultValue; + } else { + throw new Error('"' + aName + '" is a required argument.'); + } +} +exports.getArg = getArg; + +var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/; +var dataUrlRegexp = /^data:.+\,.+$/; + +function urlParse(aUrl) { + var match = aUrl.match(urlRegexp); + if (!match) { + return null; + } + return { + scheme: match[1], + auth: match[2], + host: match[3], + port: match[4], + path: match[5] + }; +} +exports.urlParse = urlParse; + +function urlGenerate(aParsedUrl) { + var url = ''; + if (aParsedUrl.scheme) { + url += aParsedUrl.scheme + ':'; + } + url += '//'; + if (aParsedUrl.auth) { + url += aParsedUrl.auth + '@'; + } + if (aParsedUrl.host) { + url += aParsedUrl.host; + } + if (aParsedUrl.port) { + url += ":" + aParsedUrl.port + } + if (aParsedUrl.path) { + url += aParsedUrl.path; + } + return url; +} +exports.urlGenerate = urlGenerate; + +/** + * Normalizes a path, or the path portion of a URL: + * + * - Replaces consecutive slashes with one slash. + * - Removes unnecessary '.' parts. + * - Removes unnecessary '/..' parts. + * + * Based on code in the Node.js 'path' core module. + * + * @param aPath The path or url to normalize. + */ +function normalize(aPath) { + var path = aPath; + var url = urlParse(aPath); + if (url) { + if (!url.path) { + return aPath; + } + path = url.path; + } + var isAbsolute = exports.isAbsolute(path); + + var parts = path.split(/\/+/); + for (var part, up = 0, i = parts.length - 1; i >= 0; i--) { + part = parts[i]; + if (part === '.') { + parts.splice(i, 1); + } else if (part === '..') { + up++; + } else if (up > 0) { + if (part === '') { + // The first part is blank if the path is absolute. Trying to go + // above the root is a no-op. Therefore we can remove all '..' parts + // directly after the root. + parts.splice(i + 1, up); + up = 0; + } else { + parts.splice(i, 2); + up--; + } + } + } + path = parts.join('/'); + + if (path === '') { + path = isAbsolute ? '/' : '.'; + } + + if (url) { + url.path = path; + return urlGenerate(url); + } + return path; +} +exports.normalize = normalize; + +/** + * Joins two paths/URLs. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be joined with the root. + * + * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a + * scheme-relative URL: Then the scheme of aRoot, if any, is prepended + * first. + * - Otherwise aPath is a path. If aRoot is a URL, then its path portion + * is updated with the result and aRoot is returned. Otherwise the result + * is returned. + * - If aPath is absolute, the result is aPath. + * - Otherwise the two paths are joined with a slash. + * - Joining for example 'http://' and 'www.example.com' is also supported. + */ +function join(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + if (aPath === "") { + aPath = "."; + } + var aPathUrl = urlParse(aPath); + var aRootUrl = urlParse(aRoot); + if (aRootUrl) { + aRoot = aRootUrl.path || '/'; + } + + // `join(foo, '//www.example.org')` + if (aPathUrl && !aPathUrl.scheme) { + if (aRootUrl) { + aPathUrl.scheme = aRootUrl.scheme; + } + return urlGenerate(aPathUrl); + } + + if (aPathUrl || aPath.match(dataUrlRegexp)) { + return aPath; + } + + // `join('http://', 'www.example.com')` + if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { + aRootUrl.host = aPath; + return urlGenerate(aRootUrl); + } + + var joined = aPath.charAt(0) === '/' + ? aPath + : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); + + if (aRootUrl) { + aRootUrl.path = joined; + return urlGenerate(aRootUrl); + } + return joined; +} +exports.join = join; + +exports.isAbsolute = function (aPath) { + return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp); +}; + +/** + * Make a path relative to a URL or another path. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be made relative to aRoot. + */ +function relative(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + + aRoot = aRoot.replace(/\/$/, ''); + + // It is possible for the path to be above the root. In this case, simply + // checking whether the root is a prefix of the path won't work. Instead, we + // need to remove components from the root one by one, until either we find + // a prefix that fits, or we run out of components to remove. + var level = 0; + while (aPath.indexOf(aRoot + '/') !== 0) { + var index = aRoot.lastIndexOf("/"); + if (index < 0) { + return aPath; + } + + // If the only part of the root that is left is the scheme (i.e. http://, + // file:///, etc.), one or more slashes (/), or simply nothing at all, we + // have exhausted all components, so the path is not relative to the root. + aRoot = aRoot.slice(0, index); + if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { + return aPath; + } + + ++level; + } + + // Make sure we add a "../" for each component we removed from the root. + return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1); +} +exports.relative = relative; + +var supportsNullProto = (function () { + var obj = Object.create(null); + return !('__proto__' in obj); +}()); + +function identity (s) { + return s; +} + +/** + * Because behavior goes wacky when you set `__proto__` on objects, we + * have to prefix all the strings in our set with an arbitrary character. + * + * See https://github.com/mozilla/source-map/pull/31 and + * https://github.com/mozilla/source-map/issues/30 + * + * @param String aStr + */ +function toSetString(aStr) { + if (isProtoString(aStr)) { + return '$' + aStr; + } + + return aStr; +} +exports.toSetString = supportsNullProto ? identity : toSetString; + +function fromSetString(aStr) { + if (isProtoString(aStr)) { + return aStr.slice(1); + } + + return aStr; +} +exports.fromSetString = supportsNullProto ? identity : fromSetString; + +function isProtoString(s) { + if (!s) { + return false; + } + + var length = s.length; + + if (length < 9 /* "__proto__".length */) { + return false; + } + + if (s.charCodeAt(length - 1) !== 95 /* '_' */ || + s.charCodeAt(length - 2) !== 95 /* '_' */ || + s.charCodeAt(length - 3) !== 111 /* 'o' */ || + s.charCodeAt(length - 4) !== 116 /* 't' */ || + s.charCodeAt(length - 5) !== 111 /* 'o' */ || + s.charCodeAt(length - 6) !== 114 /* 'r' */ || + s.charCodeAt(length - 7) !== 112 /* 'p' */ || + s.charCodeAt(length - 8) !== 95 /* '_' */ || + s.charCodeAt(length - 9) !== 95 /* '_' */) { + return false; + } + + for (var i = length - 10; i >= 0; i--) { + if (s.charCodeAt(i) !== 36 /* '$' */) { + return false; + } + } + + return true; +} + +/** + * Comparator between two mappings where the original positions are compared. + * + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same original source/line/column, but different generated + * line and column the same. Useful when searching for a mapping with a + * stubbed out mapping. + */ +function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { + var cmp = mappingA.source - mappingB.source; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0 || onlyCompareOriginal) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + return mappingA.name - mappingB.name; +} +exports.compareByOriginalPositions = compareByOriginalPositions; + +/** + * Comparator between two mappings with deflated source and name indices where + * the generated positions are compared. + * + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same generated line and column, but different + * source/name/original line and column the same. Useful when searching for a + * mapping with a stubbed out mapping. + */ +function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0 || onlyCompareGenerated) { + return cmp; + } + + cmp = mappingA.source - mappingB.source; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } + + return mappingA.name - mappingB.name; +} +exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; + +function strcmp(aStr1, aStr2) { + if (aStr1 === aStr2) { + return 0; + } + + if (aStr1 > aStr2) { + return 1; + } + + return -1; +} + +/** + * Comparator between two mappings with inflated source and name strings where + * the generated positions are compared. + */ +function compareByGeneratedPositionsInflated(mappingA, mappingB) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } + + cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } + + return strcmp(mappingA.name, mappingB.name); +} +exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; diff --git a/node_modules/source-map/package.json b/node_modules/source-map/package.json new file mode 100644 index 0000000..4c93401 --- /dev/null +++ b/node_modules/source-map/package.json @@ -0,0 +1,255 @@ +{ + "_args": [ + [ + { + "raw": "source-map@^0.5.3", + "scope": null, + "escapedName": "source-map", + "name": "source-map", + "rawSpec": "^0.5.3", + "spec": ">=0.5.3 <0.6.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt-contrib-concat" + ] + ], + "_from": "source-map@>=0.5.3 <0.6.0", + "_id": "source-map@0.5.6", + "_inCache": true, + "_location": "/source-map", + "_nodeVersion": "5.3.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/source-map-0.5.6.tgz_1462209962516_0.9263619624543935" + }, + "_npmUser": { + "name": "nickfitzgerald", + "email": "fitzgen@gmail.com" + }, + "_npmVersion": "3.3.12", + "_phantomChildren": {}, + "_requested": { + "raw": "source-map@^0.5.3", + "scope": null, + "escapedName": "source-map", + "name": "source-map", + "rawSpec": "^0.5.3", + "spec": ">=0.5.3 <0.6.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt-contrib-concat", + "/uglify-js" + ], + "_resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "_shasum": "75ce38f52bf0733c5a7f0c118d81334a2bb5f412", + "_shrinkwrap": null, + "_spec": "source-map@^0.5.3", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt-contrib-concat", + "author": { + "name": "Nick Fitzgerald", + "email": "nfitzgerald@mozilla.com" + }, + "bugs": { + "url": "https://github.com/mozilla/source-map/issues" + }, + "contributors": [ + { + "name": "Tobias Koppers", + "email": "tobias.koppers@googlemail.com" + }, + { + "name": "Duncan Beevers", + "email": "duncan@dweebd.com" + }, + { + "name": "Stephen Crane", + "email": "scrane@mozilla.com" + }, + { + "name": "Ryan Seddon", + "email": "seddon.ryan@gmail.com" + }, + { + "name": "Miles Elam", + "email": "miles.elam@deem.com" + }, + { + "name": "Mihai Bazon", + "email": "mihai.bazon@gmail.com" + }, + { + "name": "Michael Ficarra", + "email": "github.public.email@michael.ficarra.me" + }, + { + "name": "Todd Wolfson", + "email": "todd@twolfson.com" + }, + { + "name": "Alexander Solovyov", + "email": "alexander@solovyov.net" + }, + { + "name": "Felix Gnass", + "email": "fgnass@gmail.com" + }, + { + "name": "Conrad Irwin", + "email": "conrad.irwin@gmail.com" + }, + { + "name": "usrbincc", + "email": "usrbincc@yahoo.com" + }, + { + "name": "David Glasser", + "email": "glasser@davidglasser.net" + }, + { + "name": "Chase Douglas", + "email": "chase@newrelic.com" + }, + { + "name": "Evan Wallace", + "email": "evan.exe@gmail.com" + }, + { + "name": "Heather Arthur", + "email": "fayearthur@gmail.com" + }, + { + "name": "Hugh Kennedy", + "email": "hughskennedy@gmail.com" + }, + { + "name": "David Glasser", + "email": "glasser@davidglasser.net" + }, + { + "name": "Simon Lydell", + "email": "simon.lydell@gmail.com" + }, + { + "name": "Jmeas Smith", + "email": "jellyes2@gmail.com" + }, + { + "name": "Michael Z Goddard", + "email": "mzgoddard@gmail.com" + }, + { + "name": "azu", + "email": "azu@users.noreply.github.com" + }, + { + "name": "John Gozde", + "email": "john@gozde.ca" + }, + { + "name": "Adam Kirkton", + "email": "akirkton@truefitinnovation.com" + }, + { + "name": "Chris Montgomery", + "email": "christopher.montgomery@dowjones.com" + }, + { + "name": "J. Ryan Stinnett", + "email": "jryans@gmail.com" + }, + { + "name": "Jack Herrington", + "email": "jherrington@walmartlabs.com" + }, + { + "name": "Chris Truter", + "email": "jeffpalentine@gmail.com" + }, + { + "name": "Daniel Espeset", + "email": "daniel@danielespeset.com" + }, + { + "name": "Jamie Wong", + "email": "jamie.lf.wong@gmail.com" + }, + { + "name": "Eddy Bruël", + "email": "ejpbruel@mozilla.com" + }, + { + "name": "Hawken Rives", + "email": "hawkrives@gmail.com" + }, + { + "name": "Gilad Peleg", + "email": "giladp007@gmail.com" + }, + { + "name": "djchie", + "email": "djchie.dev@gmail.com" + }, + { + "name": "Gary Ye", + "email": "garysye@gmail.com" + }, + { + "name": "Nicolas Lalevée", + "email": "nicolas.lalevee@hibnet.org" + } + ], + "dependencies": {}, + "description": "Generates and consumes source maps", + "devDependencies": { + "doctoc": "^0.15.0", + "webpack": "^1.12.0" + }, + "directories": {}, + "dist": { + "shasum": "75ce38f52bf0733c5a7f0c118d81334a2bb5f412", + "tarball": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "source-map.js", + "lib/", + "dist/source-map.debug.js", + "dist/source-map.js", + "dist/source-map.min.js", + "dist/source-map.min.js.map" + ], + "gitHead": "aa0398ced67beebea34f0d36f766505656c344f6", + "homepage": "https://github.com/mozilla/source-map", + "license": "BSD-3-Clause", + "main": "./source-map.js", + "maintainers": [ + { + "name": "mozilla-devtools", + "email": "mozilla-developer-tools@googlegroups.com" + }, + { + "name": "mozilla", + "email": "dherman@mozilla.com" + }, + { + "name": "nickfitzgerald", + "email": "fitzgen@gmail.com" + } + ], + "name": "source-map", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/mozilla/source-map.git" + }, + "scripts": { + "build": "webpack --color", + "test": "npm run build && node test/run-tests.js", + "toc": "doctoc --title '## Table of Contents' README.md && doctoc --title '## Table of Contents' CONTRIBUTING.md" + }, + "version": "0.5.6" +} diff --git a/node_modules/source-map/source-map.js b/node_modules/source-map/source-map.js new file mode 100644 index 0000000..bc88fe8 --- /dev/null +++ b/node_modules/source-map/source-map.js @@ -0,0 +1,8 @@ +/* + * Copyright 2009-2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE.txt or: + * http://opensource.org/licenses/BSD-3-Clause + */ +exports.SourceMapGenerator = require('./lib/source-map-generator').SourceMapGenerator; +exports.SourceMapConsumer = require('./lib/source-map-consumer').SourceMapConsumer; +exports.SourceNode = require('./lib/source-node').SourceNode; diff --git a/node_modules/spdx-correct/LICENSE b/node_modules/spdx-correct/LICENSE new file mode 100644 index 0000000..4b54239 --- /dev/null +++ b/node_modules/spdx-correct/LICENSE @@ -0,0 +1,57 @@ +SPDX:Apache-2.0 + +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and + +(b) You must cause any modified files to carry prominent notices stating that You changed the files; and + +(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + +(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. diff --git a/node_modules/spdx-correct/README.md b/node_modules/spdx-correct/README.md new file mode 100644 index 0000000..4289e5c --- /dev/null +++ b/node_modules/spdx-correct/README.md @@ -0,0 +1,10 @@ +```javascript +var correct = require('spdx-correct'); +var assert = require('assert'); + +assert.equal(correct('mit'), 'MIT') + +assert.equal(correct('Apache 2'), 'Apache-2.0') + +assert(correct('No idea what license') === null) +``` diff --git a/node_modules/spdx-correct/index.js b/node_modules/spdx-correct/index.js new file mode 100644 index 0000000..75b7a21 --- /dev/null +++ b/node_modules/spdx-correct/index.js @@ -0,0 +1,237 @@ +var licenseIDs = require('spdx-license-ids'); + +function valid(string) { + return licenseIDs.indexOf(string) > -1; +} + +// Common transpositions of license identifier acronyms +var transpositions = [ + ['APGL', 'AGPL'], + ['Gpl', 'GPL'], + ['GLP', 'GPL'], + ['APL', 'Apache'], + ['ISD', 'ISC'], + ['GLP', 'GPL'], + ['IST', 'ISC'], + ['Claude', 'Clause'], + [' or later', '+'], + [' International', ''], + ['GNU', 'GPL'], + ['GUN', 'GPL'], + ['+', ''], + ['GNU GPL', 'GPL'], + ['GNU/GPL', 'GPL'], + ['GNU GLP', 'GPL'], + ['GNU General Public License', 'GPL'], + ['Gnu public license', 'GPL'], + ['GNU Public License', 'GPL'], + ['GNU GENERAL PUBLIC LICENSE', 'GPL'], + ['MTI', 'MIT'], + ['Mozilla Public License', 'MPL'], + ['WTH', 'WTF'], + ['-License', ''] +]; + +var TRANSPOSED = 0; +var CORRECT = 1; + +// Simple corrections to nearly valid identifiers. +var transforms = [ + // e.g. 'mit' + function(argument) { + return argument.toUpperCase(); + }, + // e.g. 'MIT ' + function(argument) { + return argument.trim(); + }, + // e.g. 'M.I.T.' + function(argument) { + return argument.replace(/\./g, ''); + }, + // e.g. 'Apache- 2.0' + function(argument) { + return argument.replace(/\s+/g, ''); + }, + // e.g. 'CC BY 4.0'' + function(argument) { + return argument.replace(/\s+/g, '-'); + }, + // e.g. 'LGPLv2.1' + function(argument) { + return argument.replace('v', '-'); + }, + // e.g. 'Apache 2.0' + function(argument) { + return argument.replace(/,?\s*(\d)/, '-$1'); + }, + // e.g. 'GPL 2' + function(argument) { + return argument.replace(/,?\s*(\d)/, '-$1.0'); + }, + // e.g. 'Apache Version 2.0' + function(argument) { + return argument.replace(/,?\s*(V\.|v\.|V|v|Version|version)\s*(\d)/, '-$2'); + }, + // e.g. 'Apache Version 2' + function(argument) { + return argument.replace(/,?\s*(V\.|v\.|V|v|Version|version)\s*(\d)/, '-$2.0'); + }, + // e.g. 'ZLIB' + function(argument) { + return argument[0].toUpperCase() + argument.slice(1); + }, + // e.g. 'MPL/2.0' + function(argument) { + return argument.replace('/', '-'); + }, + // e.g. 'Apache 2' + function(argument) { + return argument + .replace(/\s*V\s*(\d)/, '-$1') + .replace(/(\d)$/, '$1.0'); + }, + // e.g. 'GPL-2.0-' + function(argument) { + return argument.slice(0, argument.length - 1); + }, + // e.g. 'GPL2' + function(argument) { + return argument.replace(/(\d)$/, '-$1.0'); + }, + // e.g. 'BSD 3' + function(argument) { + return argument.replace(/(-| )?(\d)$/, '-$2-Clause'); + }, + // e.g. 'BSD clause 3' + function(argument) { + return argument.replace(/(-| )clause(-| )(\d)/, '-$3-Clause'); + }, + // e.g. 'BY-NC-4.0' + function(argument) { + return 'CC-' + argument; + }, + // e.g. 'BY-NC' + function(argument) { + return 'CC-' + argument + '-4.0'; + }, + // e.g. 'Attribution-NonCommercial' + function(argument) { + return argument + .replace('Attribution', 'BY') + .replace('NonCommercial', 'NC') + .replace('NoDerivatives', 'ND') + .replace(/ (\d)/, '-$1') + .replace(/ ?International/, ''); + }, + // e.g. 'Attribution-NonCommercial' + function(argument) { + return 'CC-' + + argument + .replace('Attribution', 'BY') + .replace('NonCommercial', 'NC') + .replace('NoDerivatives', 'ND') + .replace(/ (\d)/, '-$1') + .replace(/ ?International/, '') + + '-4.0'; + } +]; + +// If all else fails, guess that strings containing certain substrings +// meant to identify certain licenses. +var lastResorts = [ + ['UNLI', 'Unlicense'], + ['WTF', 'WTFPL'], + ['2 CLAUSE', 'BSD-2-Clause'], + ['2-CLAUSE', 'BSD-2-Clause'], + ['3 CLAUSE', 'BSD-3-Clause'], + ['3-CLAUSE', 'BSD-3-Clause'], + ['AFFERO', 'AGPL-3.0'], + ['AGPL', 'AGPL-3.0'], + ['APACHE', 'Apache-2.0'], + ['ARTISTIC', 'Artistic-2.0'], + ['Affero', 'AGPL-3.0'], + ['BEER', 'Beerware'], + ['BOOST', 'BSL-1.0'], + ['BSD', 'BSD-2-Clause'], + ['ECLIPSE', 'EPL-1.0'], + ['FUCK', 'WTFPL'], + ['GNU', 'GPL-3.0'], + ['LGPL', 'LGPL-3.0'], + ['GPL', 'GPL-3.0'], + ['MIT', 'MIT'], + ['MPL', 'MPL-2.0'], + ['X11', 'X11'], + ['ZLIB', 'Zlib'] +]; + +var SUBSTRING = 0; +var IDENTIFIER = 1; + +var validTransformation = function(identifier) { + for (var i = 0; i < transforms.length; i++) { + var transformed = transforms[i](identifier); + if (transformed !== identifier && valid(transformed)) { + return transformed; + } + } + return null; +}; + +var validLastResort = function(identifier) { + var upperCased = identifier.toUpperCase(); + for (var i = 0; i < lastResorts.length; i++) { + var lastResort = lastResorts[i]; + if (upperCased.indexOf(lastResort[SUBSTRING]) > -1) { + return lastResort[IDENTIFIER]; + } + } + return null; +}; + +var anyCorrection = function(identifier, check) { + for (var i = 0; i < transpositions.length; i++) { + var transposition = transpositions[i]; + var transposed = transposition[TRANSPOSED]; + if (identifier.indexOf(transposed) > -1) { + var corrected = identifier.replace( + transposed, + transposition[CORRECT] + ); + var checked = check(corrected); + if (checked !== null) { + return checked; + } + } + } + return null; +}; + +module.exports = function(identifier) { + identifier = identifier.replace(/\+$/, ''); + if (valid(identifier)) { + return identifier; + } + var transformed = validTransformation(identifier); + if (transformed !== null) { + return transformed; + } + transformed = anyCorrection(identifier, function(argument) { + if (valid(argument)) { + return argument; + } + return validTransformation(argument); + }); + if (transformed !== null) { + return transformed; + } + transformed = validLastResort(identifier); + if (transformed !== null) { + return transformed; + } + transformed = anyCorrection(identifier, validLastResort); + if (transformed !== null) { + return transformed; + } + return null; +}; diff --git a/node_modules/spdx-correct/package.json b/node_modules/spdx-correct/package.json new file mode 100644 index 0000000..3c949ed --- /dev/null +++ b/node_modules/spdx-correct/package.json @@ -0,0 +1,98 @@ +{ + "_args": [ + [ + { + "raw": "spdx-correct@~1.0.0", + "scope": null, + "escapedName": "spdx-correct", + "name": "spdx-correct", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/validate-npm-package-license" + ] + ], + "_from": "spdx-correct@>=1.0.0 <1.1.0", + "_id": "spdx-correct@1.0.2", + "_inCache": true, + "_location": "/spdx-correct", + "_nodeVersion": "4.2.1", + "_npmUser": { + "name": "kemitchell", + "email": "kyle@kemitchell.com" + }, + "_npmVersion": "3.3.6", + "_phantomChildren": {}, + "_requested": { + "raw": "spdx-correct@~1.0.0", + "scope": null, + "escapedName": "spdx-correct", + "name": "spdx-correct", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/validate-npm-package-license" + ], + "_resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "_shasum": "4b3073d933ff51f3912f03ac5519498a4150db40", + "_shrinkwrap": null, + "_spec": "spdx-correct@~1.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/validate-npm-package-license", + "author": { + "name": "Kyle E. Mitchell", + "email": "kyle@kemitchell.com", + "url": "https://kemitchell.com" + }, + "bugs": { + "url": "https://github.com/kemitchell/spdx-correct.js/issues" + }, + "dependencies": { + "spdx-license-ids": "^1.0.2" + }, + "description": "correct invalid SPDX identifiers", + "devDependencies": { + "defence-cli": "^1.0.1", + "replace-require-self": "^1.0.0", + "spdx-expression-parse": "^1.0.0", + "tape": "~4.0.0" + }, + "directories": {}, + "dist": { + "shasum": "4b3073d933ff51f3912f03ac5519498a4150db40", + "tarball": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz" + }, + "gitHead": "8430a3ad521e1455208db33faafcb79c7b074236", + "homepage": "https://github.com/kemitchell/spdx-correct.js#readme", + "keywords": [ + "SPDX", + "law", + "legal", + "license", + "metadata" + ], + "license": "Apache-2.0", + "maintainers": [ + { + "name": "kemitchell", + "email": "kyle@kemitchell.com" + }, + { + "name": "othiym23", + "email": "ogd@aoaioxxysz.net" + } + ], + "name": "spdx-correct", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/kemitchell/spdx-correct.js.git" + }, + "scripts": { + "test": "defence README.md | replace-require-self | node && tape *.test.js" + }, + "version": "1.0.2" +} diff --git a/node_modules/spdx-expression-parse/AUTHORS b/node_modules/spdx-expression-parse/AUTHORS new file mode 100644 index 0000000..155f0f6 --- /dev/null +++ b/node_modules/spdx-expression-parse/AUTHORS @@ -0,0 +1,3 @@ +C. Scott Ananian (http://cscott.net) +Kyle E. Mitchell (https://kemitchell.com) +Shinnosuke Watanabe diff --git a/node_modules/spdx-expression-parse/LICENSE b/node_modules/spdx-expression-parse/LICENSE new file mode 100644 index 0000000..831618e --- /dev/null +++ b/node_modules/spdx-expression-parse/LICENSE @@ -0,0 +1,22 @@ +The MIT License + +Copyright (c) 2015 Kyle E. Mitchell & other authors listed in AUTHORS + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/spdx-expression-parse/README.md b/node_modules/spdx-expression-parse/README.md new file mode 100644 index 0000000..9928cdc --- /dev/null +++ b/node_modules/spdx-expression-parse/README.md @@ -0,0 +1,83 @@ +This package parses SPDX license expression strings describing license terms, like [package.json license strings](https://docs.npmjs.com/files/package.json#license), into consistently structured ECMAScript objects. The npm command-line interface depends on this package, as do many automatic license-audit tools. + +In a nutshell: + +```javascript +var parse = require('spdx-expression-parse') +var assert = require('assert') + +assert.deepEqual( + // Licensed under the terms of the Two-Clause BSD License. + parse('BSD-2-Clause'), + {license: 'BSD-2-Clause'} +) + +assert.throws(function () { + // An invalid SPDX license expression. + // Should be `Apache-2.0`. + parse('Apache 2') +}) + +assert.deepEqual( + // Dual licensed under LGPL 2.1 or a combination of the Three-Clause + // BSD License and the MIT License. + parse('(LGPL-2.1 OR BSD-3-Clause AND MIT)'), + { + left: {license: 'LGPL-2.1'}, + conjunction: 'or', + right: { + left: {license: 'BSD-3-Clause'}, + conjunction: 'and', + right: {license: 'MIT'} + } + } +) +``` + +The syntax comes from the [Software Package Data eXchange (SPDX)](https://spdx.org/), a standard from the [Linux Foundation](https://www.linuxfoundation.org) for shareable data about software package license terms. SPDX aims to make sharing and auditing license data easy, especially for users of open-source software. + +The bulk of the SPDX standard describes syntax and semantics of XML metadata files. This package implements two lightweight, plain-text components of that larger standard: + +1. The [license list](https://spdx.org/licenses), a mapping from specific string identifiers, like `Apache-2.0`, to standard form license texts and bolt-on license exceptions. The [spdx-license-ids](https://www.npmjs.com/package/spdx-exceptions) and [spdx-exceptions](https://www.npmjs.com/package/spdx-license-ids) packages implement the license list. They are development dependencies of this package. + + Any license identifier from the license list is a valid license expression: + + ```javascript + require('spdx-license-ids').forEach(function (id) { + assert.deepEqual(parse(id), {license: id}) + }) + ``` + + So is any license identifier `WITH` a standardized license exception: + + ```javascript + require('spdx-license-ids').forEach(function (id) { + require('spdx-exceptions').forEach(function (e) { + assert.deepEqual( + parse(id + ' WITH ' + e), + {license: id, exception: e} + ) + }) + }) + ``` + +2. The license expression language, for describing simple and complex license terms, like `MIT` for MIT-licensed and `(GPL-2.0 OR Apache-2.0)` for dual-licensing under GPL 2.0 and Apache 2.0. This package implements the license expression language. + + ```javascript + assert.deepEqual( + // Licensed under a combination of the MIT License and a combination + // of LGPL 2.1 (or a later version) and the Three-Clause BSD License. + parse('(MIT AND (LGPL-2.1+ AND BSD-3-Clause))'), + { + left: {license: 'MIT'}, + conjunction: 'and', + right: { + left: {license: 'LGPL-2.1', plus: true}, + conjunction: 'and', + right: {license: 'BSD-3-Clause'} + } + } + ) + ``` + +The Linux Foundation and its contributors license the SPDX standard under the terms of [the Creative Commons Attribution License 3.0 Unported (SPDX: "CC-BY-3.0")](http://spdx.org/licenses/CC-BY-3.0). "SPDX" is a United States federally registered trademark of the Linux Foundation. The authors of this package license their work under the terms of the MIT License. diff --git a/node_modules/spdx-expression-parse/index.js b/node_modules/spdx-expression-parse/index.js new file mode 100644 index 0000000..56a9b50 --- /dev/null +++ b/node_modules/spdx-expression-parse/index.js @@ -0,0 +1,5 @@ +var parser = require('./parser').parser + +module.exports = function (argument) { + return parser.parse(argument) +} diff --git a/node_modules/spdx-expression-parse/package.json b/node_modules/spdx-expression-parse/package.json new file mode 100644 index 0000000..498ed08 --- /dev/null +++ b/node_modules/spdx-expression-parse/package.json @@ -0,0 +1,125 @@ +{ + "_args": [ + [ + { + "raw": "spdx-expression-parse@~1.0.0", + "scope": null, + "escapedName": "spdx-expression-parse", + "name": "spdx-expression-parse", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/validate-npm-package-license" + ] + ], + "_from": "spdx-expression-parse@>=1.0.0 <1.1.0", + "_id": "spdx-expression-parse@1.0.4", + "_inCache": true, + "_location": "/spdx-expression-parse", + "_nodeVersion": "4.6.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/spdx-expression-parse-1.0.4.tgz_1475698361593_0.7478717286139727" + }, + "_npmUser": { + "name": "kemitchell", + "email": "kyle@kemitchell.com" + }, + "_npmVersion": "3.10.8", + "_phantomChildren": {}, + "_requested": { + "raw": "spdx-expression-parse@~1.0.0", + "scope": null, + "escapedName": "spdx-expression-parse", + "name": "spdx-expression-parse", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/validate-npm-package-license" + ], + "_resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "_shasum": "9bdf2f20e1f40ed447fbe273266191fced51626c", + "_shrinkwrap": null, + "_spec": "spdx-expression-parse@~1.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/validate-npm-package-license", + "author": { + "name": "Kyle E. Mitchell", + "email": "kyle@kemitchell.com", + "url": "http://kemitchell.com" + }, + "bugs": { + "url": "https://github.com/kemitchell/spdx-expression-parse.js/issues" + }, + "contributors": [ + { + "name": "C. Scott Ananian", + "email": "cscott@cscott.net", + "url": "http://cscott.net" + }, + { + "name": "Kyle E. Mitchell", + "email": "kyle@kemitchell.com", + "url": "https://kemitchell.com" + }, + { + "name": "Shinnosuke Watanabe", + "email": "snnskwtnb@gmail.com" + } + ], + "dependencies": {}, + "description": "parse SPDX license expressions", + "devDependencies": { + "defence-cli": "^1.0.1", + "jison": "^0.4.15", + "replace-require-self": "^1.0.0", + "spdx-exceptions": "^1.0.4", + "spdx-license-ids": "^1.0.0", + "standard": "^8.0.0" + }, + "directories": {}, + "dist": { + "shasum": "9bdf2f20e1f40ed447fbe273266191fced51626c", + "tarball": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz" + }, + "files": [ + "AUTHORS", + "index.js", + "parser.js" + ], + "gitHead": "326b222ed9e89e9ef472656e9970649b9ee4e8f3", + "homepage": "https://github.com/kemitchell/spdx-expression-parse.js#readme", + "keywords": [ + "SPDX", + "law", + "legal", + "license", + "metadata", + "package", + "package.json", + "standards" + ], + "license": "(MIT AND CC-BY-3.0)", + "maintainers": [ + { + "name": "kemitchell", + "email": "kyle@kemitchell.com" + } + ], + "name": "spdx-expression-parse", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/kemitchell/spdx-expression-parse.js.git" + }, + "scripts": { + "lint": "standard", + "prepublish": "node generate-parser.js > parser.js", + "pretest": "npm run prepublish", + "test": "defence -i javascript README.md | replace-require-self | node" + }, + "version": "1.0.4" +} diff --git a/node_modules/spdx-expression-parse/parser.js b/node_modules/spdx-expression-parse/parser.js new file mode 100644 index 0000000..a5e2edb --- /dev/null +++ b/node_modules/spdx-expression-parse/parser.js @@ -0,0 +1,1357 @@ +/* parser generated by jison 0.4.17 */ +/* + Returns a Parser object of the following structure: + + Parser: { + yy: {} + } + + Parser.prototype: { + yy: {}, + trace: function(), + symbols_: {associative list: name ==> number}, + terminals_: {associative list: number ==> name}, + productions_: [...], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$), + table: [...], + defaultActions: {...}, + parseError: function(str, hash), + parse: function(input), + + lexer: { + EOF: 1, + parseError: function(str, hash), + setInput: function(input), + input: function(), + unput: function(str), + more: function(), + less: function(n), + pastInput: function(), + upcomingInput: function(), + showPosition: function(), + test_match: function(regex_match_array, rule_index), + next: function(), + lex: function(), + begin: function(condition), + popState: function(), + _currentRules: function(), + topState: function(), + pushState: function(condition), + + options: { + ranges: boolean (optional: true ==> token location info will include a .range[] member) + flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match) + backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code) + }, + + performAction: function(yy, yy_, $avoiding_name_collisions, YY_START), + rules: [...], + conditions: {associative list: name ==> set}, + } + } + + + token location info (@$, _$, etc.): { + first_line: n, + last_line: n, + first_column: n, + last_column: n, + range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based) + } + + + the parseError function receives a 'hash' object with these members for lexer and parser errors: { + text: (matched text) + token: (the produced terminal token, if any) + line: (yylineno) + } + while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: { + loc: (yylloc) + expected: (string describing the set of expected tokens) + recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) + } +*/ +var spdxparse = (function(){ +var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,5],$V1=[1,6],$V2=[1,7],$V3=[1,4],$V4=[1,9],$V5=[1,10],$V6=[5,14,15,17],$V7=[5,12,14,15,17]; +var parser = {trace: function trace() { }, +yy: {}, +symbols_: {"error":2,"start":3,"expression":4,"EOS":5,"simpleExpression":6,"LICENSE":7,"PLUS":8,"LICENSEREF":9,"DOCUMENTREF":10,"COLON":11,"WITH":12,"EXCEPTION":13,"AND":14,"OR":15,"OPEN":16,"CLOSE":17,"$accept":0,"$end":1}, +terminals_: {2:"error",5:"EOS",7:"LICENSE",8:"PLUS",9:"LICENSEREF",10:"DOCUMENTREF",11:"COLON",12:"WITH",13:"EXCEPTION",14:"AND",15:"OR",16:"OPEN",17:"CLOSE"}, +productions_: [0,[3,2],[6,1],[6,2],[6,1],[6,3],[4,1],[4,3],[4,3],[4,3],[4,3]], +performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) { +/* this == yyval */ + +var $0 = $$.length - 1; +switch (yystate) { +case 1: +return this.$ = $$[$0-1] +break; +case 2: case 4: case 5: +this.$ = {license: yytext} +break; +case 3: +this.$ = {license: $$[$0-1], plus: true} +break; +case 6: +this.$ = $$[$0] +break; +case 7: +this.$ = {exception: $$[$0]} +this.$.license = $$[$0-2].license +if ($$[$0-2].hasOwnProperty('plus')) { + this.$.plus = $$[$0-2].plus +} +break; +case 8: +this.$ = {conjunction: 'and', left: $$[$0-2], right: $$[$0]} +break; +case 9: +this.$ = {conjunction: 'or', left: $$[$0-2], right: $$[$0]} +break; +case 10: +this.$ = $$[$0-1] +break; +} +}, +table: [{3:1,4:2,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{1:[3]},{5:[1,8],14:$V4,15:$V5},o($V6,[2,6],{12:[1,11]}),{4:12,6:3,7:$V0,9:$V1,10:$V2,16:$V3},o($V7,[2,2],{8:[1,13]}),o($V7,[2,4]),{11:[1,14]},{1:[2,1]},{4:15,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{4:16,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{13:[1,17]},{14:$V4,15:$V5,17:[1,18]},o($V7,[2,3]),{9:[1,19]},o($V6,[2,8]),o([5,15,17],[2,9],{14:$V4}),o($V6,[2,7]),o($V6,[2,10]),o($V7,[2,5])], +defaultActions: {8:[2,1]}, +parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + function _parseError (msg, hash) { + this.message = msg; + this.hash = hash; + } + _parseError.prototype = Error; + + throw new _parseError(str, hash); + } +}, +parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer; + sharedState.yy.parser = this; + if (typeof lexer.yylloc == 'undefined') { + lexer.yylloc = {}; + } + var yyloc = lexer.yylloc; + lstack.push(yyloc); + var ranges = lexer.options && lexer.options.ranges; + if (typeof sharedState.yy.parseError === 'function') { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function popStack(n) { + stack.length = stack.length - 2 * n; + vstack.length = vstack.length - n; + lstack.length = lstack.length - n; + } + _token_stack: + var lex = function () { + var token; + token = lexer.lex() || EOF; + if (typeof token !== 'number') { + token = self.symbols_[token] || token; + } + return token; + }; + var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == 'undefined') { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === 'undefined' || !action.length || !action[0]) { + var errStr = ''; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push('\'' + this.terminals_[p] + '\''); + } + } + if (lexer.showPosition) { + errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; + } else { + errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); + } + this.parseError(errStr, { + text: lexer.match, + token: this.terminals_[symbol] || symbol, + line: lexer.yylineno, + loc: yyloc, + expected: expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer.yytext); + lstack.push(lexer.yylloc); + stack.push(action[1]); + symbol = null; + if (!preErrorSymbol) { + yyleng = lexer.yyleng; + yytext = lexer.yytext; + yylineno = lexer.yylineno; + yyloc = lexer.yylloc; + if (recovering > 0) { + recovering--; + } + } else { + symbol = preErrorSymbol; + preErrorSymbol = null; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== 'undefined') { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; +}}; +/* generated by jison-lex 0.3.4 */ +var lexer = (function(){ +var lexer = ({ + +EOF:1, + +parseError:function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + +// resets the lexer, sets new input +setInput:function (input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ''; + this.conditionStack = ['INITIAL']; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0,0]; + } + this.offset = 0; + return this; + }, + +// consumes and returns one char from the input +input:function () { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + + this._input = this._input.slice(1); + return ch; + }, + +// unshifts one char (or a string) into the input +unput:function (ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + //this.yyleng -= len; + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? + (lines.length === oldLines.length ? this.yylloc.first_column : 0) + + oldLines[oldLines.length - lines.length].length - lines[0].length : + this.yylloc.first_column - len + }; + + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + +// When called from action, caches matched text and appends it on next action +more:function () { + this._more = true; + return this; + }, + +// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. +reject:function () { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + + } + return this; + }, + +// retain first n characters of the match +less:function (n) { + this.unput(this.match.slice(n)); + }, + +// displays already matched input, i.e. for error messages +pastInput:function () { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, ""); + }, + +// displays upcoming input, i.e. for error messages +upcomingInput:function () { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20-next.length); + } + return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ""); + }, + +// displays the character position where the lexing error occurred, i.e. for error messages +showPosition:function () { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + +// test the lexed token: return FALSE when not a match, otherwise return token +test_match:function (match, indexed_rule) { + var token, + lines, + backup; + + if (this.options.backtrack_lexer) { + // save context + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? + lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : + this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + // recover context + for (var k in backup) { + this[k] = backup[k]; + } + return false; // rule action called reject() implying the next rule should be tested instead. + } + return false; + }, + +// return next match in input +next:function () { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + + var token, + match, + tempMatch, + index; + if (!this._more) { + this.yytext = ''; + this.match = ''; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; // rule action called reject() implying a rule MISmatch. + } else { + // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + +// return next match that has a token +lex:function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + +// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) +begin:function begin(condition) { + this.conditionStack.push(condition); + }, + +// pop the previously active lexer condition state off the condition stack +popState:function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + +// produce the lexer rule set which is active for the currently active lexer condition state +_currentRules:function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + +// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available +topState:function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + +// alias for begin(condition) +pushState:function pushState(condition) { + this.begin(condition); + }, + +// return the number of states currently on the stack +stateStackSize:function stateStackSize() { + return this.conditionStack.length; + }, +options: {}, +performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { +var YYSTATE=YY_START; +switch($avoiding_name_collisions) { +case 0:return 5 +break; +case 1:/* skip whitespace */ +break; +case 2:return 8 +break; +case 3:return 16 +break; +case 4:return 17 +break; +case 5:return 11 +break; +case 6:return 10 +break; +case 7:return 9 +break; +case 8:return 14 +break; +case 9:return 15 +break; +case 10:return 12 +break; +case 11:return 7 +break; +case 12:return 7 +break; +case 13:return 7 +break; +case 14:return 7 +break; +case 15:return 7 +break; +case 16:return 7 +break; +case 17:return 7 +break; +case 18:return 7 +break; +case 19:return 7 +break; +case 20:return 7 +break; +case 21:return 7 +break; +case 22:return 7 +break; +case 23:return 7 +break; +case 24:return 13 +break; +case 25:return 13 +break; +case 26:return 13 +break; +case 27:return 13 +break; +case 28:return 13 +break; +case 29:return 13 +break; +case 30:return 13 +break; +case 31:return 13 +break; +case 32:return 7 +break; +case 33:return 13 +break; +case 34:return 7 +break; +case 35:return 13 +break; +case 36:return 7 +break; +case 37:return 13 +break; +case 38:return 13 +break; +case 39:return 7 +break; +case 40:return 13 +break; +case 41:return 13 +break; +case 42:return 13 +break; +case 43:return 13 +break; +case 44:return 13 +break; +case 45:return 7 +break; +case 46:return 13 +break; +case 47:return 7 +break; +case 48:return 7 +break; +case 49:return 7 +break; +case 50:return 7 +break; +case 51:return 7 +break; +case 52:return 7 +break; +case 53:return 7 +break; +case 54:return 7 +break; +case 55:return 7 +break; +case 56:return 7 +break; +case 57:return 7 +break; +case 58:return 7 +break; +case 59:return 7 +break; +case 60:return 7 +break; +case 61:return 7 +break; +case 62:return 7 +break; +case 63:return 13 +break; +case 64:return 7 +break; +case 65:return 7 +break; +case 66:return 13 +break; +case 67:return 7 +break; +case 68:return 7 +break; +case 69:return 7 +break; +case 70:return 7 +break; +case 71:return 7 +break; +case 72:return 7 +break; +case 73:return 13 +break; +case 74:return 7 +break; +case 75:return 13 +break; +case 76:return 7 +break; +case 77:return 7 +break; +case 78:return 7 +break; +case 79:return 7 +break; +case 80:return 7 +break; +case 81:return 7 +break; +case 82:return 7 +break; +case 83:return 7 +break; +case 84:return 7 +break; +case 85:return 7 +break; +case 86:return 7 +break; +case 87:return 7 +break; +case 88:return 7 +break; +case 89:return 7 +break; +case 90:return 7 +break; +case 91:return 7 +break; +case 92:return 7 +break; +case 93:return 7 +break; +case 94:return 7 +break; +case 95:return 7 +break; +case 96:return 7 +break; +case 97:return 7 +break; +case 98:return 7 +break; +case 99:return 7 +break; +case 100:return 7 +break; +case 101:return 7 +break; +case 102:return 7 +break; +case 103:return 7 +break; +case 104:return 7 +break; +case 105:return 7 +break; +case 106:return 7 +break; +case 107:return 7 +break; +case 108:return 7 +break; +case 109:return 7 +break; +case 110:return 7 +break; +case 111:return 7 +break; +case 112:return 7 +break; +case 113:return 7 +break; +case 114:return 7 +break; +case 115:return 7 +break; +case 116:return 7 +break; +case 117:return 7 +break; +case 118:return 7 +break; +case 119:return 7 +break; +case 120:return 7 +break; +case 121:return 7 +break; +case 122:return 7 +break; +case 123:return 7 +break; +case 124:return 7 +break; +case 125:return 7 +break; +case 126:return 7 +break; +case 127:return 7 +break; +case 128:return 7 +break; +case 129:return 7 +break; +case 130:return 7 +break; +case 131:return 7 +break; +case 132:return 7 +break; +case 133:return 7 +break; +case 134:return 7 +break; +case 135:return 7 +break; +case 136:return 7 +break; +case 137:return 7 +break; +case 138:return 7 +break; +case 139:return 7 +break; +case 140:return 7 +break; +case 141:return 7 +break; +case 142:return 7 +break; +case 143:return 7 +break; +case 144:return 7 +break; +case 145:return 7 +break; +case 146:return 7 +break; +case 147:return 7 +break; +case 148:return 7 +break; +case 149:return 7 +break; +case 150:return 7 +break; +case 151:return 7 +break; +case 152:return 7 +break; +case 153:return 7 +break; +case 154:return 7 +break; +case 155:return 7 +break; +case 156:return 7 +break; +case 157:return 7 +break; +case 158:return 7 +break; +case 159:return 7 +break; +case 160:return 7 +break; +case 161:return 7 +break; +case 162:return 7 +break; +case 163:return 7 +break; +case 164:return 7 +break; +case 165:return 7 +break; +case 166:return 7 +break; +case 167:return 7 +break; +case 168:return 7 +break; +case 169:return 7 +break; +case 170:return 7 +break; +case 171:return 7 +break; +case 172:return 7 +break; +case 173:return 7 +break; +case 174:return 7 +break; +case 175:return 7 +break; +case 176:return 7 +break; +case 177:return 7 +break; +case 178:return 7 +break; +case 179:return 7 +break; +case 180:return 7 +break; +case 181:return 7 +break; +case 182:return 7 +break; +case 183:return 7 +break; +case 184:return 7 +break; +case 185:return 7 +break; +case 186:return 7 +break; +case 187:return 7 +break; +case 188:return 7 +break; +case 189:return 7 +break; +case 190:return 7 +break; +case 191:return 7 +break; +case 192:return 7 +break; +case 193:return 7 +break; +case 194:return 7 +break; +case 195:return 7 +break; +case 196:return 7 +break; +case 197:return 7 +break; +case 198:return 7 +break; +case 199:return 7 +break; +case 200:return 7 +break; +case 201:return 7 +break; +case 202:return 7 +break; +case 203:return 7 +break; +case 204:return 7 +break; +case 205:return 7 +break; +case 206:return 7 +break; +case 207:return 7 +break; +case 208:return 7 +break; +case 209:return 7 +break; +case 210:return 7 +break; +case 211:return 7 +break; +case 212:return 7 +break; +case 213:return 7 +break; +case 214:return 7 +break; +case 215:return 7 +break; +case 216:return 7 +break; +case 217:return 7 +break; +case 218:return 7 +break; +case 219:return 7 +break; +case 220:return 7 +break; +case 221:return 7 +break; +case 222:return 7 +break; +case 223:return 7 +break; +case 224:return 7 +break; +case 225:return 7 +break; +case 226:return 7 +break; +case 227:return 7 +break; +case 228:return 7 +break; +case 229:return 7 +break; +case 230:return 7 +break; +case 231:return 7 +break; +case 232:return 7 +break; +case 233:return 7 +break; +case 234:return 7 +break; +case 235:return 7 +break; +case 236:return 7 +break; +case 237:return 7 +break; +case 238:return 7 +break; +case 239:return 7 +break; +case 240:return 7 +break; +case 241:return 7 +break; +case 242:return 7 +break; +case 243:return 7 +break; +case 244:return 7 +break; +case 245:return 7 +break; +case 246:return 7 +break; +case 247:return 7 +break; +case 248:return 7 +break; +case 249:return 7 +break; +case 250:return 7 +break; +case 251:return 7 +break; +case 252:return 7 +break; +case 253:return 7 +break; +case 254:return 7 +break; +case 255:return 7 +break; +case 256:return 7 +break; +case 257:return 7 +break; +case 258:return 7 +break; +case 259:return 7 +break; +case 260:return 7 +break; +case 261:return 7 +break; +case 262:return 7 +break; +case 263:return 7 +break; +case 264:return 7 +break; +case 265:return 7 +break; +case 266:return 7 +break; +case 267:return 7 +break; +case 268:return 7 +break; +case 269:return 7 +break; +case 270:return 7 +break; +case 271:return 7 +break; +case 272:return 7 +break; +case 273:return 7 +break; +case 274:return 7 +break; +case 275:return 7 +break; +case 276:return 7 +break; +case 277:return 7 +break; +case 278:return 7 +break; +case 279:return 7 +break; +case 280:return 7 +break; +case 281:return 7 +break; +case 282:return 7 +break; +case 283:return 7 +break; +case 284:return 7 +break; +case 285:return 7 +break; +case 286:return 7 +break; +case 287:return 7 +break; +case 288:return 7 +break; +case 289:return 7 +break; +case 290:return 7 +break; +case 291:return 7 +break; +case 292:return 7 +break; +case 293:return 7 +break; +case 294:return 7 +break; +case 295:return 7 +break; +case 296:return 7 +break; +case 297:return 7 +break; +case 298:return 7 +break; +case 299:return 7 +break; +case 300:return 7 +break; +case 301:return 7 +break; +case 302:return 7 +break; +case 303:return 7 +break; +case 304:return 7 +break; +case 305:return 7 +break; +case 306:return 7 +break; +case 307:return 7 +break; +case 308:return 7 +break; +case 309:return 7 +break; +case 310:return 7 +break; +case 311:return 7 +break; +case 312:return 7 +break; +case 313:return 7 +break; +case 314:return 7 +break; +case 315:return 7 +break; +case 316:return 7 +break; +case 317:return 7 +break; +case 318:return 7 +break; +case 319:return 7 +break; +case 320:return 7 +break; +case 321:return 7 +break; +case 322:return 7 +break; +case 323:return 7 +break; +case 324:return 7 +break; +case 325:return 7 +break; +case 326:return 7 +break; +case 327:return 7 +break; +case 328:return 7 +break; +case 329:return 7 +break; +case 330:return 7 +break; +case 331:return 7 +break; +case 332:return 7 +break; +case 333:return 7 +break; +case 334:return 7 +break; +case 335:return 7 +break; +case 336:return 7 +break; +case 337:return 7 +break; +case 338:return 7 +break; +case 339:return 7 +break; +case 340:return 7 +break; +case 341:return 7 +break; +case 342:return 7 +break; +case 343:return 7 +break; +case 344:return 7 +break; +case 345:return 7 +break; +case 346:return 7 +break; +case 347:return 7 +break; +case 348:return 7 +break; +case 349:return 7 +break; +case 350:return 7 +break; +case 351:return 7 +break; +case 352:return 7 +break; +case 353:return 7 +break; +case 354:return 7 +break; +case 355:return 7 +break; +case 356:return 7 +break; +case 357:return 7 +break; +case 358:return 7 +break; +case 359:return 7 +break; +case 360:return 7 +break; +case 361:return 7 +break; +case 362:return 7 +break; +case 363:return 7 +break; +case 364:return 7 +break; +} +}, +rules: [/^(?:$)/,/^(?:\s+)/,/^(?:\+)/,/^(?:\()/,/^(?:\))/,/^(?::)/,/^(?:DocumentRef-([0-9A-Za-z-+.]+))/,/^(?:LicenseRef-([0-9A-Za-z-+.]+))/,/^(?:AND)/,/^(?:OR)/,/^(?:WITH)/,/^(?:BSD-3-Clause-No-Nuclear-License-2014)/,/^(?:BSD-3-Clause-No-Nuclear-Warranty)/,/^(?:GPL-2\.0-with-classpath-exception)/,/^(?:GPL-3\.0-with-autoconf-exception)/,/^(?:GPL-2\.0-with-autoconf-exception)/,/^(?:BSD-3-Clause-No-Nuclear-License)/,/^(?:MPL-2\.0-no-copyleft-exception)/,/^(?:GPL-2\.0-with-bison-exception)/,/^(?:GPL-2\.0-with-font-exception)/,/^(?:GPL-2\.0-with-GCC-exception)/,/^(?:CNRI-Python-GPL-Compatible)/,/^(?:GPL-3\.0-with-GCC-exception)/,/^(?:BSD-3-Clause-Attribution)/,/^(?:Classpath-exception-2\.0)/,/^(?:WxWindows-exception-3\.1)/,/^(?:freertos-exception-2\.0)/,/^(?:Autoconf-exception-3\.0)/,/^(?:i2p-gpl-java-exception)/,/^(?:gnu-javamail-exception)/,/^(?:Nokia-Qt-exception-1\.1)/,/^(?:Autoconf-exception-2\.0)/,/^(?:BSD-2-Clause-FreeBSD)/,/^(?:u-boot-exception-2\.0)/,/^(?:zlib-acknowledgement)/,/^(?:Bison-exception-2\.2)/,/^(?:BSD-2-Clause-NetBSD)/,/^(?:CLISP-exception-2\.0)/,/^(?:eCos-exception-2\.0)/,/^(?:BSD-3-Clause-Clear)/,/^(?:Font-exception-2\.0)/,/^(?:FLTK-exception-2\.0)/,/^(?:GCC-exception-2\.0)/,/^(?:Qwt-exception-1\.0)/,/^(?:Libtool-exception)/,/^(?:BSD-3-Clause-LBNL)/,/^(?:GCC-exception-3\.1)/,/^(?:Artistic-1\.0-Perl)/,/^(?:Artistic-1\.0-cl8)/,/^(?:CC-BY-NC-SA-2\.5)/,/^(?:MIT-advertising)/,/^(?:BSD-Source-Code)/,/^(?:CC-BY-NC-SA-4\.0)/,/^(?:LiLiQ-Rplus-1\.1)/,/^(?:CC-BY-NC-SA-3\.0)/,/^(?:BSD-4-Clause-UC)/,/^(?:CC-BY-NC-SA-2\.0)/,/^(?:CC-BY-NC-SA-1\.0)/,/^(?:CC-BY-NC-ND-4\.0)/,/^(?:CC-BY-NC-ND-3\.0)/,/^(?:CC-BY-NC-ND-2\.5)/,/^(?:CC-BY-NC-ND-2\.0)/,/^(?:CC-BY-NC-ND-1\.0)/,/^(?:LZMA-exception)/,/^(?:BitTorrent-1\.1)/,/^(?:CrystalStacker)/,/^(?:FLTK-exception)/,/^(?:SugarCRM-1\.1\.3)/,/^(?:BSD-Protection)/,/^(?:BitTorrent-1\.0)/,/^(?:HaskellReport)/,/^(?:Interbase-1\.0)/,/^(?:StandardML-NJ)/,/^(?:mif-exception)/,/^(?:Frameworx-1\.0)/,/^(?:389-exception)/,/^(?:CC-BY-NC-2\.0)/,/^(?:CC-BY-NC-2\.5)/,/^(?:CC-BY-NC-3\.0)/,/^(?:CC-BY-NC-4\.0)/,/^(?:W3C-19980720)/,/^(?:CC-BY-SA-1\.0)/,/^(?:CC-BY-SA-2\.0)/,/^(?:CC-BY-SA-2\.5)/,/^(?:CC-BY-ND-2\.0)/,/^(?:CC-BY-SA-4\.0)/,/^(?:CC-BY-SA-3\.0)/,/^(?:Artistic-1\.0)/,/^(?:Artistic-2\.0)/,/^(?:CC-BY-ND-2\.5)/,/^(?:CC-BY-ND-3\.0)/,/^(?:CC-BY-ND-4\.0)/,/^(?:CC-BY-ND-1\.0)/,/^(?:BSD-4-Clause)/,/^(?:BSD-3-Clause)/,/^(?:BSD-2-Clause)/,/^(?:CC-BY-NC-1\.0)/,/^(?:bzip2-1\.0\.6)/,/^(?:Unicode-TOU)/,/^(?:CNRI-Jython)/,/^(?:ImageMagick)/,/^(?:Adobe-Glyph)/,/^(?:CUA-OPL-1\.0)/,/^(?:OLDAP-2\.2\.2)/,/^(?:LiLiQ-R-1\.1)/,/^(?:bzip2-1\.0\.5)/,/^(?:LiLiQ-P-1\.1)/,/^(?:OLDAP-2\.0\.1)/,/^(?:OLDAP-2\.2\.1)/,/^(?:CNRI-Python)/,/^(?:XFree86-1\.1)/,/^(?:OSET-PL-2\.1)/,/^(?:Apache-2\.0)/,/^(?:Watcom-1\.0)/,/^(?:PostgreSQL)/,/^(?:Python-2\.0)/,/^(?:RHeCos-1\.1)/,/^(?:EUDatagrid)/,/^(?:Spencer-99)/,/^(?:Intel-ACPI)/,/^(?:CECILL-1\.0)/,/^(?:CECILL-1\.1)/,/^(?:JasPer-2\.0)/,/^(?:CECILL-2\.0)/,/^(?:CECILL-2\.1)/,/^(?:gSOAP-1\.3b)/,/^(?:Spencer-94)/,/^(?:Apache-1\.1)/,/^(?:Spencer-86)/,/^(?:Apache-1\.0)/,/^(?:ClArtistic)/,/^(?:TORQUE-1\.1)/,/^(?:CATOSL-1\.1)/,/^(?:Adobe-2006)/,/^(?:Zimbra-1\.4)/,/^(?:Zimbra-1\.3)/,/^(?:Condor-1\.1)/,/^(?:CC-BY-3\.0)/,/^(?:CC-BY-2\.5)/,/^(?:OLDAP-2\.4)/,/^(?:SGI-B-1\.1)/,/^(?:SISSL-1\.2)/,/^(?:SGI-B-1\.0)/,/^(?:OLDAP-2\.3)/,/^(?:CC-BY-4\.0)/,/^(?:Crossword)/,/^(?:SimPL-2\.0)/,/^(?:OLDAP-2\.2)/,/^(?:OLDAP-2\.1)/,/^(?:ErlPL-1\.1)/,/^(?:LPPL-1\.3a)/,/^(?:LPPL-1\.3c)/,/^(?:OLDAP-2\.0)/,/^(?:Leptonica)/,/^(?:CPOL-1\.02)/,/^(?:OLDAP-1\.4)/,/^(?:OLDAP-1\.3)/,/^(?:CC-BY-2\.0)/,/^(?:Unlicense)/,/^(?:OLDAP-2\.8)/,/^(?:OLDAP-1\.2)/,/^(?:MakeIndex)/,/^(?:OLDAP-2\.7)/,/^(?:OLDAP-1\.1)/,/^(?:Sleepycat)/,/^(?:D-FSL-1\.0)/,/^(?:CC-BY-1\.0)/,/^(?:OLDAP-2\.6)/,/^(?:WXwindows)/,/^(?:NPOSL-3\.0)/,/^(?:FreeImage)/,/^(?:SGI-B-2\.0)/,/^(?:OLDAP-2\.5)/,/^(?:Beerware)/,/^(?:Newsletr)/,/^(?:NBPL-1\.0)/,/^(?:NASA-1\.3)/,/^(?:NLOD-1\.0)/,/^(?:AGPL-1\.0)/,/^(?:OCLC-2\.0)/,/^(?:ODbL-1\.0)/,/^(?:PDDL-1\.0)/,/^(?:Motosoto)/,/^(?:Afmparse)/,/^(?:ANTLR-PD)/,/^(?:LPL-1\.02)/,/^(?:Abstyles)/,/^(?:eCos-2\.0)/,/^(?:APSL-1\.0)/,/^(?:LPPL-1\.2)/,/^(?:LPPL-1\.1)/,/^(?:LPPL-1\.0)/,/^(?:APSL-1\.1)/,/^(?:APSL-2\.0)/,/^(?:Info-ZIP)/,/^(?:Zend-2\.0)/,/^(?:IBM-pibs)/,/^(?:LGPL-2\.0)/,/^(?:LGPL-3\.0)/,/^(?:LGPL-2\.1)/,/^(?:GFDL-1\.3)/,/^(?:PHP-3\.01)/,/^(?:GFDL-1\.2)/,/^(?:GFDL-1\.1)/,/^(?:AGPL-3\.0)/,/^(?:Giftware)/,/^(?:EUPL-1\.1)/,/^(?:RPSL-1\.0)/,/^(?:EUPL-1\.0)/,/^(?:MIT-enna)/,/^(?:CECILL-B)/,/^(?:diffmark)/,/^(?:CECILL-C)/,/^(?:CDDL-1\.0)/,/^(?:Sendmail)/,/^(?:CDDL-1\.1)/,/^(?:CPAL-1\.0)/,/^(?:APSL-1\.2)/,/^(?:NPL-1\.1)/,/^(?:AFL-1\.2)/,/^(?:Caldera)/,/^(?:AFL-2\.0)/,/^(?:FSFULLR)/,/^(?:AFL-2\.1)/,/^(?:VSL-1\.0)/,/^(?:VOSTROM)/,/^(?:UPL-1\.0)/,/^(?:Dotseqn)/,/^(?:CPL-1\.0)/,/^(?:dvipdfm)/,/^(?:EPL-1\.0)/,/^(?:OCCT-PL)/,/^(?:ECL-1\.0)/,/^(?:Latex2e)/,/^(?:ECL-2\.0)/,/^(?:GPL-1\.0)/,/^(?:GPL-2\.0)/,/^(?:GPL-3\.0)/,/^(?:AFL-3\.0)/,/^(?:LAL-1\.2)/,/^(?:LAL-1\.3)/,/^(?:EFL-1\.0)/,/^(?:EFL-2\.0)/,/^(?:gnuplot)/,/^(?:Aladdin)/,/^(?:LPL-1\.0)/,/^(?:libtiff)/,/^(?:Entessa)/,/^(?:AMDPLPA)/,/^(?:IPL-1\.0)/,/^(?:OPL-1\.0)/,/^(?:OSL-1\.0)/,/^(?:OSL-1\.1)/,/^(?:OSL-2\.0)/,/^(?:OSL-2\.1)/,/^(?:OSL-3\.0)/,/^(?:OpenSSL)/,/^(?:ZPL-2\.1)/,/^(?:PHP-3\.0)/,/^(?:ZPL-2\.0)/,/^(?:ZPL-1\.1)/,/^(?:CC0-1\.0)/,/^(?:SPL-1\.0)/,/^(?:psutils)/,/^(?:MPL-1\.0)/,/^(?:QPL-1\.0)/,/^(?:MPL-1\.1)/,/^(?:MPL-2\.0)/,/^(?:APL-1\.0)/,/^(?:RPL-1\.1)/,/^(?:RPL-1\.5)/,/^(?:MIT-CMU)/,/^(?:Multics)/,/^(?:Eurosym)/,/^(?:BSL-1\.0)/,/^(?:MIT-feh)/,/^(?:Saxpath)/,/^(?:Borceux)/,/^(?:OFL-1\.1)/,/^(?:OFL-1\.0)/,/^(?:AFL-1\.1)/,/^(?:YPL-1\.1)/,/^(?:YPL-1\.0)/,/^(?:NPL-1\.0)/,/^(?:iMatix)/,/^(?:mpich2)/,/^(?:APAFML)/,/^(?:Bahyph)/,/^(?:RSA-MD)/,/^(?:psfrag)/,/^(?:Plexus)/,/^(?:eGenix)/,/^(?:Glulxe)/,/^(?:SAX-PD)/,/^(?:Imlib2)/,/^(?:Wsuipa)/,/^(?:LGPLLR)/,/^(?:Libpng)/,/^(?:xinetd)/,/^(?:MITNFA)/,/^(?:NetCDF)/,/^(?:Naumen)/,/^(?:SMPPL)/,/^(?:Nunit)/,/^(?:FSFUL)/,/^(?:GL2PS)/,/^(?:SMLNJ)/,/^(?:Rdisc)/,/^(?:Noweb)/,/^(?:Nokia)/,/^(?:SISSL)/,/^(?:Qhull)/,/^(?:Intel)/,/^(?:Glide)/,/^(?:Xerox)/,/^(?:AMPAS)/,/^(?:WTFPL)/,/^(?:MS-PL)/,/^(?:XSkat)/,/^(?:MS-RL)/,/^(?:MirOS)/,/^(?:RSCPL)/,/^(?:TMate)/,/^(?:OGTSL)/,/^(?:FSFAP)/,/^(?:NCSA)/,/^(?:Zlib)/,/^(?:SCEA)/,/^(?:SNIA)/,/^(?:NGPL)/,/^(?:NOSL)/,/^(?:ADSL)/,/^(?:MTLL)/,/^(?:NLPL)/,/^(?:Ruby)/,/^(?:JSON)/,/^(?:Barr)/,/^(?:0BSD)/,/^(?:Xnet)/,/^(?:Cube)/,/^(?:curl)/,/^(?:DSDP)/,/^(?:Fair)/,/^(?:HPND)/,/^(?:TOSL)/,/^(?:IJG)/,/^(?:SWL)/,/^(?:Vim)/,/^(?:FTL)/,/^(?:ICU)/,/^(?:OML)/,/^(?:NRL)/,/^(?:DOC)/,/^(?:TCL)/,/^(?:W3C)/,/^(?:NTP)/,/^(?:IPA)/,/^(?:ISC)/,/^(?:X11)/,/^(?:AAL)/,/^(?:AML)/,/^(?:xpp)/,/^(?:Zed)/,/^(?:MIT)/,/^(?:Mup)/], +conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364],"inclusive":true}} +}); +return lexer; +})(); +parser.lexer = lexer; +function Parser () { + this.yy = {}; +} +Parser.prototype = parser;parser.Parser = Parser; +return new Parser; +})(); + + +if (typeof require !== 'undefined' && typeof exports !== 'undefined') { +exports.parser = spdxparse; +exports.Parser = spdxparse.Parser; +exports.parse = function () { return spdxparse.parse.apply(spdxparse, arguments); }; +exports.main = function commonjsMain(args) { + if (!args[1]) { + console.log('Usage: '+args[0]+' FILE'); + process.exit(1); + } + var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8"); + return exports.parser.parse(source); +}; +if (typeof module !== 'undefined' && require.main === module) { + exports.main(process.argv.slice(1)); +} +} diff --git a/node_modules/spdx-license-ids/LICENSE b/node_modules/spdx-license-ids/LICENSE new file mode 100644 index 0000000..68a49da --- /dev/null +++ b/node_modules/spdx-license-ids/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/node_modules/spdx-license-ids/README.md b/node_modules/spdx-license-ids/README.md new file mode 100644 index 0000000..9252353 --- /dev/null +++ b/node_modules/spdx-license-ids/README.md @@ -0,0 +1,55 @@ +# spdx-license-ids + +A list of [SPDX license](https://spdx.org/licenses/) identifiers + +[**Download JSON**](https://raw.githubusercontent.com/shinnn/spdx-license-ids/master/spdx-license-ids.json) + +## Use as a JavaScript Library + +[![NPM version](https://img.shields.io/npm/v/spdx-license-ids.svg)](https://www.npmjs.org/package/spdx-license-ids) +[![Bower version](https://img.shields.io/bower/v/spdx-license-ids.svg)](https://github.com/shinnn/spdx-license-ids/releases) +[![Build Status](https://travis-ci.org/shinnn/spdx-license-ids.svg?branch=master)](https://travis-ci.org/shinnn/spdx-license-ids) +[![Coverage Status](https://img.shields.io/coveralls/shinnn/spdx-license-ids.svg)](https://coveralls.io/r/shinnn/spdx-license-ids) +[![devDependency Status](https://david-dm.org/shinnn/spdx-license-ids/dev-status.svg)](https://david-dm.org/shinnn/spdx-license-ids#info=devDependencies) + +### Installation + +#### Package managers + +##### [npm](https://www.npmjs.com/) + +```sh +npm install spdx-license-ids +``` + +##### [bower](http://bower.io/) + +```sh +bower install spdx-license-ids +``` + +##### [Duo](http://duojs.org/) + +```javascript +const spdxLicenseIds = require('shinnn/spdx-license-ids'); +``` + +#### Standalone + +[Download the script file directly.](https://raw.githubusercontent.com/shinnn/spdx-license-ids/master/spdx-license-ids-browser.js) + +### API + +#### spdxLicenseIds + +Type: `Array` of `String` + +It returns an array of SPDX license identifiers. + +```javascript +const spdxLicenseIds = require('spdx-license-ids'); //=> ['Glide', 'Abstyles', 'AFL-1.1', ... ] +``` + +## License + +[The Unlicense](./LICENSE). diff --git a/node_modules/spdx-license-ids/package.json b/node_modules/spdx-license-ids/package.json new file mode 100644 index 0000000..0cff3a2 --- /dev/null +++ b/node_modules/spdx-license-ids/package.json @@ -0,0 +1,116 @@ +{ + "_args": [ + [ + { + "raw": "spdx-license-ids@^1.0.2", + "scope": null, + "escapedName": "spdx-license-ids", + "name": "spdx-license-ids", + "rawSpec": "^1.0.2", + "spec": ">=1.0.2 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/spdx-correct" + ] + ], + "_from": "spdx-license-ids@>=1.0.2 <2.0.0", + "_id": "spdx-license-ids@1.2.2", + "_inCache": true, + "_location": "/spdx-license-ids", + "_nodeVersion": "6.3.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/spdx-license-ids-1.2.2.tgz_1469529975605_0.35518706892617047" + }, + "_npmUser": { + "name": "shinnn", + "email": "snnskwtnb@gmail.com" + }, + "_npmVersion": "3.10.5", + "_phantomChildren": {}, + "_requested": { + "raw": "spdx-license-ids@^1.0.2", + "scope": null, + "escapedName": "spdx-license-ids", + "name": "spdx-license-ids", + "rawSpec": "^1.0.2", + "spec": ">=1.0.2 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/spdx-correct" + ], + "_resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "_shasum": "c9df7a3424594ade6bd11900d596696dc06bac57", + "_shrinkwrap": null, + "_spec": "spdx-license-ids@^1.0.2", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/spdx-correct", + "author": { + "name": "Shinnosuke Watanabe", + "url": "https://github.com/shinnn" + }, + "bugs": { + "url": "https://github.com/shinnn/spdx-license-ids/issues" + }, + "dependencies": {}, + "description": "A list of SPDX license identifiers", + "devDependencies": { + "@shinnn/eslint-config-node": "^3.0.0", + "chalk": "^1.1.3", + "eslint": "^3.1.1", + "get-spdx-license-ids": "^1.0.0", + "istanbul": "^0.4.4", + "loud-rejection": "^1.6.0", + "rimraf-promise": "^2.0.0", + "stringify-object": "^2.4.0", + "tap-spec": "^4.1.1", + "tape": "^4.6.0", + "write-file-atomically": "1.0.0" + }, + "directories": {}, + "dist": { + "shasum": "c9df7a3424594ade6bd11900d596696dc06bac57", + "tarball": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz" + }, + "files": [ + "spdx-license-ids.json" + ], + "gitHead": "70e2541bf04b4fbef4c5df52c581a1861fd355b2", + "homepage": "https://github.com/shinnn/spdx-license-ids#readme", + "keywords": [ + "spdx", + "license", + "licenses", + "id", + "identifier", + "identifiers", + "json", + "array", + "oss", + "browser", + "client-side" + ], + "license": "Unlicense", + "main": "spdx-license-ids.json", + "maintainers": [ + { + "name": "shinnn", + "email": "snnskwtnb@gmail.com" + } + ], + "name": "spdx-license-ids", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/shinnn/spdx-license-ids.git" + }, + "scripts": { + "build": "node --strong_mode build.js", + "coverage": "node --strong_mode node_modules/.bin/istanbul cover test.js", + "lint": "eslint --config @shinnn/node --env browser --ignore-path .gitignore .", + "pretest": "${npm_package_scripts_build} && ${npm_package_scripts_lint}", + "test": "node --strong_mode test.js | tap-spec" + }, + "version": "1.2.2" +} diff --git a/node_modules/spdx-license-ids/spdx-license-ids.json b/node_modules/spdx-license-ids/spdx-license-ids.json new file mode 100644 index 0000000..1c60d6e --- /dev/null +++ b/node_modules/spdx-license-ids/spdx-license-ids.json @@ -0,0 +1,334 @@ +[ + "Glide", + "Abstyles", + "AFL-1.1", + "AFL-1.2", + "AFL-2.0", + "AFL-2.1", + "AFL-3.0", + "AMPAS", + "APL-1.0", + "Adobe-Glyph", + "APAFML", + "Adobe-2006", + "AGPL-1.0", + "Afmparse", + "Aladdin", + "ADSL", + "AMDPLPA", + "ANTLR-PD", + "Apache-1.0", + "Apache-1.1", + "Apache-2.0", + "AML", + "APSL-1.0", + "APSL-1.1", + "APSL-1.2", + "APSL-2.0", + "Artistic-1.0", + "Artistic-1.0-Perl", + "Artistic-1.0-cl8", + "Artistic-2.0", + "AAL", + "Bahyph", + "Barr", + "Beerware", + "BitTorrent-1.0", + "BitTorrent-1.1", + "BSL-1.0", + "Borceux", + "BSD-2-Clause", + "BSD-2-Clause-FreeBSD", + "BSD-2-Clause-NetBSD", + "BSD-3-Clause", + "BSD-3-Clause-Clear", + "BSD-4-Clause", + "BSD-Protection", + "BSD-Source-Code", + "BSD-3-Clause-Attribution", + "0BSD", + "BSD-4-Clause-UC", + "bzip2-1.0.5", + "bzip2-1.0.6", + "Caldera", + "CECILL-1.0", + "CECILL-1.1", + "CECILL-2.0", + "CECILL-2.1", + "CECILL-B", + "CECILL-C", + "ClArtistic", + "MIT-CMU", + "CNRI-Jython", + "CNRI-Python", + "CNRI-Python-GPL-Compatible", + "CPOL-1.02", + "CDDL-1.0", + "CDDL-1.1", + "CPAL-1.0", + "CPL-1.0", + "CATOSL-1.1", + "Condor-1.1", + "CC-BY-1.0", + "CC-BY-2.0", + "CC-BY-2.5", + "CC-BY-3.0", + "CC-BY-4.0", + "CC-BY-ND-1.0", + "CC-BY-ND-2.0", + "CC-BY-ND-2.5", + "CC-BY-ND-3.0", + "CC-BY-ND-4.0", + "CC-BY-NC-1.0", + "CC-BY-NC-2.0", + "CC-BY-NC-2.5", + "CC-BY-NC-3.0", + "CC-BY-NC-4.0", + "CC-BY-NC-ND-1.0", + "CC-BY-NC-ND-2.0", + "CC-BY-NC-ND-2.5", + "CC-BY-NC-ND-3.0", + "CC-BY-NC-ND-4.0", + "CC-BY-NC-SA-1.0", + "CC-BY-NC-SA-2.0", + "CC-BY-NC-SA-2.5", + "CC-BY-NC-SA-3.0", + "CC-BY-NC-SA-4.0", + "CC-BY-SA-1.0", + "CC-BY-SA-2.0", + "CC-BY-SA-2.5", + "CC-BY-SA-3.0", + "CC-BY-SA-4.0", + "CC0-1.0", + "Crossword", + "CrystalStacker", + "CUA-OPL-1.0", + "Cube", + "curl", + "D-FSL-1.0", + "diffmark", + "WTFPL", + "DOC", + "Dotseqn", + "DSDP", + "dvipdfm", + "EPL-1.0", + "ECL-1.0", + "ECL-2.0", + "eGenix", + "EFL-1.0", + "EFL-2.0", + "MIT-advertising", + "MIT-enna", + "Entessa", + "ErlPL-1.1", + "EUDatagrid", + "EUPL-1.0", + "EUPL-1.1", + "Eurosym", + "Fair", + "MIT-feh", + "Frameworx-1.0", + "FreeImage", + "FTL", + "FSFAP", + "FSFUL", + "FSFULLR", + "Giftware", + "GL2PS", + "Glulxe", + "AGPL-3.0", + "GFDL-1.1", + "GFDL-1.2", + "GFDL-1.3", + "GPL-1.0", + "GPL-2.0", + "GPL-3.0", + "LGPL-2.1", + "LGPL-3.0", + "LGPL-2.0", + "gnuplot", + "gSOAP-1.3b", + "HaskellReport", + "HPND", + "IBM-pibs", + "IPL-1.0", + "ICU", + "ImageMagick", + "iMatix", + "Imlib2", + "IJG", + "Info-ZIP", + "Intel-ACPI", + "Intel", + "Interbase-1.0", + "IPA", + "ISC", + "JasPer-2.0", + "JSON", + "LPPL-1.0", + "LPPL-1.1", + "LPPL-1.2", + "LPPL-1.3a", + "LPPL-1.3c", + "Latex2e", + "BSD-3-Clause-LBNL", + "Leptonica", + "LGPLLR", + "Libpng", + "libtiff", + "LAL-1.2", + "LAL-1.3", + "LiLiQ-P-1.1", + "LiLiQ-Rplus-1.1", + "LiLiQ-R-1.1", + "LPL-1.02", + "LPL-1.0", + "MakeIndex", + "MTLL", + "MS-PL", + "MS-RL", + "MirOS", + "MITNFA", + "MIT", + "Motosoto", + "MPL-1.0", + "MPL-1.1", + "MPL-2.0", + "MPL-2.0-no-copyleft-exception", + "mpich2", + "Multics", + "Mup", + "NASA-1.3", + "Naumen", + "NBPL-1.0", + "NetCDF", + "NGPL", + "NOSL", + "NPL-1.0", + "NPL-1.1", + "Newsletr", + "NLPL", + "Nokia", + "NPOSL-3.0", + "NLOD-1.0", + "Noweb", + "NRL", + "NTP", + "Nunit", + "OCLC-2.0", + "ODbL-1.0", + "PDDL-1.0", + "OCCT-PL", + "OGTSL", + "OLDAP-2.2.2", + "OLDAP-1.1", + "OLDAP-1.2", + "OLDAP-1.3", + "OLDAP-1.4", + "OLDAP-2.0", + "OLDAP-2.0.1", + "OLDAP-2.1", + "OLDAP-2.2", + "OLDAP-2.2.1", + "OLDAP-2.3", + "OLDAP-2.4", + "OLDAP-2.5", + "OLDAP-2.6", + "OLDAP-2.7", + "OLDAP-2.8", + "OML", + "OPL-1.0", + "OSL-1.0", + "OSL-1.1", + "OSL-2.0", + "OSL-2.1", + "OSL-3.0", + "OpenSSL", + "OSET-PL-2.1", + "PHP-3.0", + "PHP-3.01", + "Plexus", + "PostgreSQL", + "psfrag", + "psutils", + "Python-2.0", + "QPL-1.0", + "Qhull", + "Rdisc", + "RPSL-1.0", + "RPL-1.1", + "RPL-1.5", + "RHeCos-1.1", + "RSCPL", + "RSA-MD", + "Ruby", + "SAX-PD", + "Saxpath", + "SCEA", + "SWL", + "SMPPL", + "Sendmail", + "SGI-B-1.0", + "SGI-B-1.1", + "SGI-B-2.0", + "OFL-1.0", + "OFL-1.1", + "SimPL-2.0", + "Sleepycat", + "SNIA", + "Spencer-86", + "Spencer-94", + "Spencer-99", + "SMLNJ", + "SugarCRM-1.1.3", + "SISSL", + "SISSL-1.2", + "SPL-1.0", + "Watcom-1.0", + "TCL", + "Unlicense", + "TMate", + "TORQUE-1.1", + "TOSL", + "Unicode-TOU", + "UPL-1.0", + "NCSA", + "Vim", + "VOSTROM", + "VSL-1.0", + "W3C-19980720", + "W3C", + "Wsuipa", + "Xnet", + "X11", + "Xerox", + "XFree86-1.1", + "xinetd", + "xpp", + "XSkat", + "YPL-1.0", + "YPL-1.1", + "Zed", + "Zend-2.0", + "Zimbra-1.3", + "Zimbra-1.4", + "Zlib", + "zlib-acknowledgement", + "ZPL-1.1", + "ZPL-2.0", + "ZPL-2.1", + "BSD-3-Clause-No-Nuclear-License", + "BSD-3-Clause-No-Nuclear-Warranty", + "BSD-3-Clause-No-Nuclear-License-2014", + "eCos-2.0", + "GPL-2.0-with-autoconf-exception", + "GPL-2.0-with-bison-exception", + "GPL-2.0-with-classpath-exception", + "GPL-2.0-with-font-exception", + "GPL-2.0-with-GCC-exception", + "GPL-3.0-with-autoconf-exception", + "GPL-3.0-with-GCC-exception", + "StandardML-NJ", + "WXwindows" +] diff --git a/node_modules/sprintf-js/.npmignore b/node_modules/sprintf-js/.npmignore new file mode 100644 index 0000000..096746c --- /dev/null +++ b/node_modules/sprintf-js/.npmignore @@ -0,0 +1 @@ +/node_modules/ \ No newline at end of file diff --git a/node_modules/sprintf-js/LICENSE b/node_modules/sprintf-js/LICENSE new file mode 100644 index 0000000..663ac52 --- /dev/null +++ b/node_modules/sprintf-js/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2007-2014, Alexandru Marasteanu +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of this software nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/node_modules/sprintf-js/README.md b/node_modules/sprintf-js/README.md new file mode 100644 index 0000000..8386356 --- /dev/null +++ b/node_modules/sprintf-js/README.md @@ -0,0 +1,88 @@ +# sprintf.js +**sprintf.js** is a complete open source JavaScript sprintf implementation for the *browser* and *node.js*. + +Its prototype is simple: + + string sprintf(string format , [mixed arg1 [, mixed arg2 [ ,...]]]) + +The placeholders in the format string are marked by `%` and are followed by one or more of these elements, in this order: + +* An optional number followed by a `$` sign that selects which argument index to use for the value. If not specified, arguments will be placed in the same order as the placeholders in the input string. +* An optional `+` sign that forces to preceed the result with a plus or minus sign on numeric values. By default, only the `-` sign is used on negative numbers. +* An optional padding specifier that says what character to use for padding (if specified). Possible values are `0` or any other character precedeed by a `'` (single quote). The default is to pad with *spaces*. +* An optional `-` sign, that causes sprintf to left-align the result of this placeholder. The default is to right-align the result. +* An optional number, that says how many characters the result should have. If the value to be returned is shorter than this number, the result will be padded. When used with the `j` (JSON) type specifier, the padding length specifies the tab size used for indentation. +* An optional precision modifier, consisting of a `.` (dot) followed by a number, that says how many digits should be displayed for floating point numbers. When used with the `g` type specifier, it specifies the number of significant digits. When used on a string, it causes the result to be truncated. +* A type specifier that can be any of: + * `%` — yields a literal `%` character + * `b` — yields an integer as a binary number + * `c` — yields an integer as the character with that ASCII value + * `d` or `i` — yields an integer as a signed decimal number + * `e` — yields a float using scientific notation + * `u` — yields an integer as an unsigned decimal number + * `f` — yields a float as is; see notes on precision above + * `g` — yields a float as is; see notes on precision above + * `o` — yields an integer as an octal number + * `s` — yields a string as is + * `x` — yields an integer as a hexadecimal number (lower-case) + * `X` — yields an integer as a hexadecimal number (upper-case) + * `j` — yields a JavaScript object or array as a JSON encoded string + +## JavaScript `vsprintf` +`vsprintf` is the same as `sprintf` except that it accepts an array of arguments, rather than a variable number of arguments: + + vsprintf("The first 4 letters of the english alphabet are: %s, %s, %s and %s", ["a", "b", "c", "d"]) + +## Argument swapping +You can also swap the arguments. That is, the order of the placeholders doesn't have to match the order of the arguments. You can do that by simply indicating in the format string which arguments the placeholders refer to: + + sprintf("%2$s %3$s a %1$s", "cracker", "Polly", "wants") +And, of course, you can repeat the placeholders without having to increase the number of arguments. + +## Named arguments +Format strings may contain replacement fields rather than positional placeholders. Instead of referring to a certain argument, you can now refer to a certain key within an object. Replacement fields are surrounded by rounded parentheses - `(` and `)` - and begin with a keyword that refers to a key: + + var user = { + name: "Dolly" + } + sprintf("Hello %(name)s", user) // Hello Dolly +Keywords in replacement fields can be optionally followed by any number of keywords or indexes: + + var users = [ + {name: "Dolly"}, + {name: "Molly"}, + {name: "Polly"} + ] + sprintf("Hello %(users[0].name)s, %(users[1].name)s and %(users[2].name)s", {users: users}) // Hello Dolly, Molly and Polly +Note: mixing positional and named placeholders is not (yet) supported + +## Computed values +You can pass in a function as a dynamic value and it will be invoked (with no arguments) in order to compute the value on-the-fly. + + sprintf("Current timestamp: %d", Date.now) // Current timestamp: 1398005382890 + sprintf("Current date and time: %s", function() { return new Date().toString() }) + +# AngularJS +You can now use `sprintf` and `vsprintf` (also aliased as `fmt` and `vfmt` respectively) in your AngularJS projects. See `demo/`. + +# Installation + +## Via Bower + + bower install sprintf + +## Or as a node.js module + + npm install sprintf-js + +### Usage + + var sprintf = require("sprintf-js").sprintf, + vsprintf = require("sprintf-js").vsprintf + + sprintf("%2$s %3$s a %1$s", "cracker", "Polly", "wants") + vsprintf("The first 4 letters of the english alphabet are: %s, %s, %s and %s", ["a", "b", "c", "d"]) + +# License + +**sprintf.js** is licensed under the terms of the 3-clause BSD license. diff --git a/node_modules/sprintf-js/bower.json b/node_modules/sprintf-js/bower.json new file mode 100644 index 0000000..d90a759 --- /dev/null +++ b/node_modules/sprintf-js/bower.json @@ -0,0 +1,14 @@ +{ + "name": "sprintf", + "description": "JavaScript sprintf implementation", + "version": "1.0.3", + "main": "src/sprintf.js", + "license": "BSD-3-Clause-Clear", + "keywords": ["sprintf", "string", "formatting"], + "authors": ["Alexandru Marasteanu (http://alexei.ro/)"], + "homepage": "https://github.com/alexei/sprintf.js", + "repository": { + "type": "git", + "url": "git://github.com/alexei/sprintf.js.git" + } +} diff --git a/node_modules/sprintf-js/demo/angular.html b/node_modules/sprintf-js/demo/angular.html new file mode 100644 index 0000000..3559efd --- /dev/null +++ b/node_modules/sprintf-js/demo/angular.html @@ -0,0 +1,20 @@ + + + + + + + + +
          {{ "%+010d"|sprintf:-123 }}
          +
          {{ "%+010d"|vsprintf:[-123] }}
          +
          {{ "%+010d"|fmt:-123 }}
          +
          {{ "%+010d"|vfmt:[-123] }}
          +
          {{ "I've got %2$d apples and %1$d oranges."|fmt:4:2 }}
          +
          {{ "I've got %(apples)d apples and %(oranges)d oranges."|fmt:{apples: 2, oranges: 4} }}
          + + + + diff --git a/node_modules/sprintf-js/dist/angular-sprintf.min.js b/node_modules/sprintf-js/dist/angular-sprintf.min.js new file mode 100644 index 0000000..dbaf744 --- /dev/null +++ b/node_modules/sprintf-js/dist/angular-sprintf.min.js @@ -0,0 +1,4 @@ +/*! sprintf-js | Alexandru Marasteanu (http://alexei.ro/) | BSD-3-Clause */ + +angular.module("sprintf",[]).filter("sprintf",function(){return function(){return sprintf.apply(null,arguments)}}).filter("fmt",["$filter",function(a){return a("sprintf")}]).filter("vsprintf",function(){return function(a,b){return vsprintf(a,b)}}).filter("vfmt",["$filter",function(a){return a("vsprintf")}]); +//# sourceMappingURL=angular-sprintf.min.map \ No newline at end of file diff --git a/node_modules/sprintf-js/dist/angular-sprintf.min.js.map b/node_modules/sprintf-js/dist/angular-sprintf.min.js.map new file mode 100644 index 0000000..055964c --- /dev/null +++ b/node_modules/sprintf-js/dist/angular-sprintf.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"angular-sprintf.min.js","sources":["../src/angular-sprintf.js"],"names":["angular","module","filter","sprintf","apply","arguments","$filter","format","argv","vsprintf"],"mappings":";;AAAAA,QACIC,OAAO,cACPC,OAAO,UAAW,WACd,MAAO,YACH,MAAOC,SAAQC,MAAM,KAAMC,cAGnCH,OAAO,OAAQ,UAAW,SAASI,GAC/B,MAAOA,GAAQ,cAEnBJ,OAAO,WAAY,WACf,MAAO,UAASK,EAAQC,GACpB,MAAOC,UAASF,EAAQC,MAGhCN,OAAO,QAAS,UAAW,SAASI,GAChC,MAAOA,GAAQ"} \ No newline at end of file diff --git a/node_modules/sprintf-js/dist/angular-sprintf.min.map b/node_modules/sprintf-js/dist/angular-sprintf.min.map new file mode 100644 index 0000000..055964c --- /dev/null +++ b/node_modules/sprintf-js/dist/angular-sprintf.min.map @@ -0,0 +1 @@ +{"version":3,"file":"angular-sprintf.min.js","sources":["../src/angular-sprintf.js"],"names":["angular","module","filter","sprintf","apply","arguments","$filter","format","argv","vsprintf"],"mappings":";;AAAAA,QACIC,OAAO,cACPC,OAAO,UAAW,WACd,MAAO,YACH,MAAOC,SAAQC,MAAM,KAAMC,cAGnCH,OAAO,OAAQ,UAAW,SAASI,GAC/B,MAAOA,GAAQ,cAEnBJ,OAAO,WAAY,WACf,MAAO,UAASK,EAAQC,GACpB,MAAOC,UAASF,EAAQC,MAGhCN,OAAO,QAAS,UAAW,SAASI,GAChC,MAAOA,GAAQ"} \ No newline at end of file diff --git a/node_modules/sprintf-js/dist/sprintf.min.js b/node_modules/sprintf-js/dist/sprintf.min.js new file mode 100644 index 0000000..dc61e51 --- /dev/null +++ b/node_modules/sprintf-js/dist/sprintf.min.js @@ -0,0 +1,4 @@ +/*! sprintf-js | Alexandru Marasteanu (http://alexei.ro/) | BSD-3-Clause */ + +!function(a){function b(){var a=arguments[0],c=b.cache;return c[a]&&c.hasOwnProperty(a)||(c[a]=b.parse(a)),b.format.call(null,c[a],arguments)}function c(a){return Object.prototype.toString.call(a).slice(8,-1).toLowerCase()}function d(a,b){return Array(b+1).join(a)}var e={not_string:/[^s]/,number:/[diefg]/,json:/[j]/,not_json:/[^j]/,text:/^[^\x25]+/,modulo:/^\x25{2}/,placeholder:/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijosuxX])/,key:/^([a-z_][a-z_\d]*)/i,key_access:/^\.([a-z_][a-z_\d]*)/i,index_access:/^\[(\d+)\]/,sign:/^[\+\-]/};b.format=function(a,f){var g,h,i,j,k,l,m,n=1,o=a.length,p="",q=[],r=!0,s="";for(h=0;o>h;h++)if(p=c(a[h]),"string"===p)q[q.length]=a[h];else if("array"===p){if(j=a[h],j[2])for(g=f[n],i=0;i=0),j[8]){case"b":g=g.toString(2);break;case"c":g=String.fromCharCode(g);break;case"d":case"i":g=parseInt(g,10);break;case"j":g=JSON.stringify(g,null,j[6]?parseInt(j[6]):0);break;case"e":g=j[7]?g.toExponential(j[7]):g.toExponential();break;case"f":g=j[7]?parseFloat(g).toFixed(j[7]):parseFloat(g);break;case"g":g=j[7]?parseFloat(g).toPrecision(j[7]):parseFloat(g);break;case"o":g=g.toString(8);break;case"s":g=(g=String(g))&&j[7]?g.substring(0,j[7]):g;break;case"u":g>>>=0;break;case"x":g=g.toString(16);break;case"X":g=g.toString(16).toUpperCase()}e.json.test(j[8])?q[q.length]=g:(!e.number.test(j[8])||r&&!j[3]?s="":(s=r?"+":"-",g=g.toString().replace(e.sign,"")),l=j[4]?"0"===j[4]?"0":j[4].charAt(1):" ",m=j[6]-(s+g).length,k=j[6]&&m>0?d(l,m):"",q[q.length]=j[5]?s+g+k:"0"===l?s+k+g:k+s+g)}return q.join("")},b.cache={},b.parse=function(a){for(var b=a,c=[],d=[],f=0;b;){if(null!==(c=e.text.exec(b)))d[d.length]=c[0];else if(null!==(c=e.modulo.exec(b)))d[d.length]="%";else{if(null===(c=e.placeholder.exec(b)))throw new SyntaxError("[sprintf] unexpected placeholder");if(c[2]){f|=1;var g=[],h=c[2],i=[];if(null===(i=e.key.exec(h)))throw new SyntaxError("[sprintf] failed to parse named argument key");for(g[g.length]=i[1];""!==(h=h.substring(i[0].length));)if(null!==(i=e.key_access.exec(h)))g[g.length]=i[1];else{if(null===(i=e.index_access.exec(h)))throw new SyntaxError("[sprintf] failed to parse named argument key");g[g.length]=i[1]}c[2]=g}else f|=2;if(3===f)throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported");d[d.length]=c}b=b.substring(c[0].length)}return d};var f=function(a,c,d){return d=(c||[]).slice(0),d.splice(0,0,a),b.apply(null,d)};"undefined"!=typeof exports?(exports.sprintf=b,exports.vsprintf=f):(a.sprintf=b,a.vsprintf=f,"function"==typeof define&&define.amd&&define(function(){return{sprintf:b,vsprintf:f}}))}("undefined"==typeof window?this:window); +//# sourceMappingURL=sprintf.min.map \ No newline at end of file diff --git a/node_modules/sprintf-js/dist/sprintf.min.js.map b/node_modules/sprintf-js/dist/sprintf.min.js.map new file mode 100644 index 0000000..369dbaf --- /dev/null +++ b/node_modules/sprintf-js/dist/sprintf.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"sprintf.min.js","sources":["../src/sprintf.js"],"names":["window","sprintf","key","arguments","cache","hasOwnProperty","parse","format","call","get_type","variable","Object","prototype","toString","slice","toLowerCase","str_repeat","input","multiplier","Array","join","re","not_string","number","json","not_json","text","modulo","placeholder","key_access","index_access","sign","parse_tree","argv","arg","i","k","match","pad","pad_character","pad_length","cursor","tree_length","length","node_type","output","is_positive","Error","test","isNaN","TypeError","String","fromCharCode","parseInt","JSON","stringify","toExponential","parseFloat","toFixed","substring","toUpperCase","replace","charAt","fmt","_fmt","arg_names","exec","SyntaxError","field_list","replacement_field","field_match","vsprintf","_argv","splice","apply","exports","define","amd","this"],"mappings":";;CAAA,SAAUA,GAeN,QAASC,KACL,GAAIC,GAAMC,UAAU,GAAIC,EAAQH,EAAQG,KAIxC,OAHMA,GAAMF,IAAQE,EAAMC,eAAeH,KACrCE,EAAMF,GAAOD,EAAQK,MAAMJ,IAExBD,EAAQM,OAAOC,KAAK,KAAMJ,EAAMF,GAAMC,WA4JjD,QAASM,GAASC,GACd,MAAOC,QAAOC,UAAUC,SAASL,KAAKE,GAAUI,MAAM,EAAG,IAAIC,cAGjE,QAASC,GAAWC,EAAOC,GACvB,MAAOC,OAAMD,EAAa,GAAGE,KAAKH,GApLtC,GAAII,IACAC,WAAY,OACZC,OAAQ,SACRC,KAAM,MACNC,SAAU,OACVC,KAAM,YACNC,OAAQ,WACRC,YAAa,yFACb1B,IAAK,sBACL2B,WAAY,wBACZC,aAAc,aACdC,KAAM,UAWV9B,GAAQM,OAAS,SAASyB,EAAYC,GAClC,GAAiEC,GAAkBC,EAAGC,EAAGC,EAAOC,EAAKC,EAAeC,EAAhHC,EAAS,EAAGC,EAAcV,EAAWW,OAAQC,EAAY,GAASC,KAA0DC,GAAc,EAAMf,EAAO,EAC3J,KAAKI,EAAI,EAAOO,EAAJP,EAAiBA,IAEzB,GADAS,EAAYnC,EAASuB,EAAWG,IACd,WAAdS,EACAC,EAAOA,EAAOF,QAAUX,EAAWG,OAElC,IAAkB,UAAdS,EAAuB,CAE5B,GADAP,EAAQL,EAAWG,GACfE,EAAM,GAEN,IADAH,EAAMD,EAAKQ,GACNL,EAAI,EAAGA,EAAIC,EAAM,GAAGM,OAAQP,IAAK,CAClC,IAAKF,EAAI7B,eAAegC,EAAM,GAAGD,IAC7B,KAAM,IAAIW,OAAM9C,EAAQ,yCAA0CoC,EAAM,GAAGD,IAE/EF,GAAMA,EAAIG,EAAM,GAAGD,QAIvBF,GADKG,EAAM,GACLJ,EAAKI,EAAM,IAGXJ,EAAKQ,IAOf,IAJqB,YAAjBhC,EAASyB,KACTA,EAAMA,KAGNb,EAAGC,WAAW0B,KAAKX,EAAM,KAAOhB,EAAGI,SAASuB,KAAKX,EAAM,KAAyB,UAAjB5B,EAASyB,IAAoBe,MAAMf,GAClG,KAAM,IAAIgB,WAAUjD,EAAQ,0CAA2CQ,EAASyB,IAOpF,QAJIb,EAAGE,OAAOyB,KAAKX,EAAM,MACrBS,EAAcZ,GAAO,GAGjBG,EAAM,IACV,IAAK,IACDH,EAAMA,EAAIrB,SAAS,EACvB,MACA,KAAK,IACDqB,EAAMiB,OAAOC,aAAalB,EAC9B,MACA,KAAK,IACL,IAAK,IACDA,EAAMmB,SAASnB,EAAK,GACxB,MACA,KAAK,IACDA,EAAMoB,KAAKC,UAAUrB,EAAK,KAAMG,EAAM,GAAKgB,SAAShB,EAAM,IAAM,EACpE,MACA,KAAK,IACDH,EAAMG,EAAM,GAAKH,EAAIsB,cAAcnB,EAAM,IAAMH,EAAIsB,eACvD,MACA,KAAK,IACDtB,EAAMG,EAAM,GAAKoB,WAAWvB,GAAKwB,QAAQrB,EAAM,IAAMoB,WAAWvB,EACpE,MACA,KAAK,IACDA,EAAMA,EAAIrB,SAAS,EACvB,MACA,KAAK,IACDqB,GAAQA,EAAMiB,OAAOjB,KAASG,EAAM,GAAKH,EAAIyB,UAAU,EAAGtB,EAAM,IAAMH,CAC1E,MACA,KAAK,IACDA,KAAc,CAClB,MACA,KAAK,IACDA,EAAMA,EAAIrB,SAAS,GACvB,MACA,KAAK,IACDqB,EAAMA,EAAIrB,SAAS,IAAI+C,cAG3BvC,EAAGG,KAAKwB,KAAKX,EAAM,IACnBQ,EAAOA,EAAOF,QAAUT,IAGpBb,EAAGE,OAAOyB,KAAKX,EAAM,KAASS,IAAeT,EAAM,GAKnDN,EAAO,IAJPA,EAAOe,EAAc,IAAM,IAC3BZ,EAAMA,EAAIrB,WAAWgD,QAAQxC,EAAGU,KAAM,KAK1CQ,EAAgBF,EAAM,GAAkB,MAAbA,EAAM,GAAa,IAAMA,EAAM,GAAGyB,OAAO,GAAK,IACzEtB,EAAaH,EAAM,IAAMN,EAAOG,GAAKS,OACrCL,EAAMD,EAAM,IAAMG,EAAa,EAAIxB,EAAWuB,EAAeC,GAAoB,GACjFK,EAAOA,EAAOF,QAAUN,EAAM,GAAKN,EAAOG,EAAMI,EAAyB,MAAlBC,EAAwBR,EAAOO,EAAMJ,EAAMI,EAAMP,EAAOG,GAI3H,MAAOW,GAAOzB,KAAK,KAGvBnB,EAAQG,SAERH,EAAQK,MAAQ,SAASyD,GAErB,IADA,GAAIC,GAAOD,EAAK1B,KAAYL,KAAiBiC,EAAY,EAClDD,GAAM,CACT,GAAqC,QAAhC3B,EAAQhB,EAAGK,KAAKwC,KAAKF,IACtBhC,EAAWA,EAAWW,QAAUN,EAAM,OAErC,IAAuC,QAAlCA,EAAQhB,EAAGM,OAAOuC,KAAKF,IAC7BhC,EAAWA,EAAWW,QAAU,QAE/B,CAAA,GAA4C,QAAvCN,EAAQhB,EAAGO,YAAYsC,KAAKF,IAgClC,KAAM,IAAIG,aAAY,mCA/BtB,IAAI9B,EAAM,GAAI,CACV4B,GAAa,CACb,IAAIG,MAAiBC,EAAoBhC,EAAM,GAAIiC,IACnD,IAAuD,QAAlDA,EAAcjD,EAAGnB,IAAIgE,KAAKG,IAe3B,KAAM,IAAIF,aAAY,+CAbtB,KADAC,EAAWA,EAAWzB,QAAU2B,EAAY,GACwC,MAA5ED,EAAoBA,EAAkBV,UAAUW,EAAY,GAAG3B,UACnE,GAA8D,QAAzD2B,EAAcjD,EAAGQ,WAAWqC,KAAKG,IAClCD,EAAWA,EAAWzB,QAAU2B,EAAY,OAE3C,CAAA,GAAgE,QAA3DA,EAAcjD,EAAGS,aAAaoC,KAAKG,IAIzC,KAAM,IAAIF,aAAY,+CAHtBC,GAAWA,EAAWzB,QAAU2B,EAAY,GAUxDjC,EAAM,GAAK+B,MAGXH,IAAa,CAEjB,IAAkB,IAAdA,EACA,KAAM,IAAIlB,OAAM,4EAEpBf,GAAWA,EAAWW,QAAUN,EAKpC2B,EAAOA,EAAKL,UAAUtB,EAAM,GAAGM,QAEnC,MAAOX,GAGX,IAAIuC,GAAW,SAASR,EAAK9B,EAAMuC,GAG/B,MAFAA,IAASvC,OAAYnB,MAAM,GAC3B0D,EAAMC,OAAO,EAAG,EAAGV,GACZ9D,EAAQyE,MAAM,KAAMF,GAiBR,oBAAZG,UACPA,QAAQ1E,QAAUA,EAClB0E,QAAQJ,SAAWA,IAGnBvE,EAAOC,QAAUA,EACjBD,EAAOuE,SAAWA,EAEI,kBAAXK,SAAyBA,OAAOC,KACvCD,OAAO,WACH,OACI3E,QAASA,EACTsE,SAAUA,OAKT,mBAAXvE,QAAyB8E,KAAO9E"} \ No newline at end of file diff --git a/node_modules/sprintf-js/dist/sprintf.min.map b/node_modules/sprintf-js/dist/sprintf.min.map new file mode 100644 index 0000000..ee011aa --- /dev/null +++ b/node_modules/sprintf-js/dist/sprintf.min.map @@ -0,0 +1 @@ +{"version":3,"file":"sprintf.min.js","sources":["../src/sprintf.js"],"names":["window","sprintf","key","arguments","cache","hasOwnProperty","parse","format","call","get_type","variable","Object","prototype","toString","slice","toLowerCase","str_repeat","input","multiplier","Array","join","re","not_string","number","json","not_json","text","modulo","placeholder","key_access","index_access","sign","parse_tree","argv","arg","i","k","match","pad","pad_character","pad_length","cursor","tree_length","length","node_type","output","is_positive","Error","test","isNaN","TypeError","String","fromCharCode","parseInt","JSON","stringify","toExponential","parseFloat","toFixed","toPrecision","substring","toUpperCase","replace","charAt","fmt","_fmt","arg_names","exec","SyntaxError","field_list","replacement_field","field_match","vsprintf","_argv","splice","apply","exports","define","amd","this"],"mappings":";;CAAA,SAAUA,GAeN,QAASC,KACL,GAAIC,GAAMC,UAAU,GAAIC,EAAQH,EAAQG,KAIxC,OAHMA,GAAMF,IAAQE,EAAMC,eAAeH,KACrCE,EAAMF,GAAOD,EAAQK,MAAMJ,IAExBD,EAAQM,OAAOC,KAAK,KAAMJ,EAAMF,GAAMC,WA+JjD,QAASM,GAASC,GACd,MAAOC,QAAOC,UAAUC,SAASL,KAAKE,GAAUI,MAAM,EAAG,IAAIC,cAGjE,QAASC,GAAWC,EAAOC,GACvB,MAAOC,OAAMD,EAAa,GAAGE,KAAKH,GAvLtC,GAAII,IACAC,WAAY,OACZC,OAAQ,UACRC,KAAM,MACNC,SAAU,OACVC,KAAM,YACNC,OAAQ,WACRC,YAAa,yFACb1B,IAAK,sBACL2B,WAAY,wBACZC,aAAc,aACdC,KAAM,UAWV9B,GAAQM,OAAS,SAASyB,EAAYC,GAClC,GAAiEC,GAAkBC,EAAGC,EAAGC,EAAOC,EAAKC,EAAeC,EAAhHC,EAAS,EAAGC,EAAcV,EAAWW,OAAQC,EAAY,GAASC,KAA0DC,GAAc,EAAMf,EAAO,EAC3J,KAAKI,EAAI,EAAOO,EAAJP,EAAiBA,IAEzB,GADAS,EAAYnC,EAASuB,EAAWG,IACd,WAAdS,EACAC,EAAOA,EAAOF,QAAUX,EAAWG,OAElC,IAAkB,UAAdS,EAAuB,CAE5B,GADAP,EAAQL,EAAWG,GACfE,EAAM,GAEN,IADAH,EAAMD,EAAKQ,GACNL,EAAI,EAAGA,EAAIC,EAAM,GAAGM,OAAQP,IAAK,CAClC,IAAKF,EAAI7B,eAAegC,EAAM,GAAGD,IAC7B,KAAM,IAAIW,OAAM9C,EAAQ,yCAA0CoC,EAAM,GAAGD,IAE/EF,GAAMA,EAAIG,EAAM,GAAGD,QAIvBF,GADKG,EAAM,GACLJ,EAAKI,EAAM,IAGXJ,EAAKQ,IAOf,IAJqB,YAAjBhC,EAASyB,KACTA,EAAMA,KAGNb,EAAGC,WAAW0B,KAAKX,EAAM,KAAOhB,EAAGI,SAASuB,KAAKX,EAAM,KAAyB,UAAjB5B,EAASyB,IAAoBe,MAAMf,GAClG,KAAM,IAAIgB,WAAUjD,EAAQ,0CAA2CQ,EAASyB,IAOpF,QAJIb,EAAGE,OAAOyB,KAAKX,EAAM,MACrBS,EAAcZ,GAAO,GAGjBG,EAAM,IACV,IAAK,IACDH,EAAMA,EAAIrB,SAAS,EACvB,MACA,KAAK,IACDqB,EAAMiB,OAAOC,aAAalB,EAC9B,MACA,KAAK,IACL,IAAK,IACDA,EAAMmB,SAASnB,EAAK,GACxB,MACA,KAAK,IACDA,EAAMoB,KAAKC,UAAUrB,EAAK,KAAMG,EAAM,GAAKgB,SAAShB,EAAM,IAAM,EACpE,MACA,KAAK,IACDH,EAAMG,EAAM,GAAKH,EAAIsB,cAAcnB,EAAM,IAAMH,EAAIsB,eACvD,MACA,KAAK,IACDtB,EAAMG,EAAM,GAAKoB,WAAWvB,GAAKwB,QAAQrB,EAAM,IAAMoB,WAAWvB,EACpE,MACA,KAAK,IACDA,EAAMG,EAAM,GAAKoB,WAAWvB,GAAKyB,YAAYtB,EAAM,IAAMoB,WAAWvB,EACxE,MACA,KAAK,IACDA,EAAMA,EAAIrB,SAAS,EACvB,MACA,KAAK,IACDqB,GAAQA,EAAMiB,OAAOjB,KAASG,EAAM,GAAKH,EAAI0B,UAAU,EAAGvB,EAAM,IAAMH,CAC1E,MACA,KAAK,IACDA,KAAc,CAClB,MACA,KAAK,IACDA,EAAMA,EAAIrB,SAAS,GACvB,MACA,KAAK,IACDqB,EAAMA,EAAIrB,SAAS,IAAIgD,cAG3BxC,EAAGG,KAAKwB,KAAKX,EAAM,IACnBQ,EAAOA,EAAOF,QAAUT,IAGpBb,EAAGE,OAAOyB,KAAKX,EAAM,KAASS,IAAeT,EAAM,GAKnDN,EAAO,IAJPA,EAAOe,EAAc,IAAM,IAC3BZ,EAAMA,EAAIrB,WAAWiD,QAAQzC,EAAGU,KAAM,KAK1CQ,EAAgBF,EAAM,GAAkB,MAAbA,EAAM,GAAa,IAAMA,EAAM,GAAG0B,OAAO,GAAK,IACzEvB,EAAaH,EAAM,IAAMN,EAAOG,GAAKS,OACrCL,EAAMD,EAAM,IAAMG,EAAa,EAAIxB,EAAWuB,EAAeC,GAAoB,GACjFK,EAAOA,EAAOF,QAAUN,EAAM,GAAKN,EAAOG,EAAMI,EAAyB,MAAlBC,EAAwBR,EAAOO,EAAMJ,EAAMI,EAAMP,EAAOG,GAI3H,MAAOW,GAAOzB,KAAK,KAGvBnB,EAAQG,SAERH,EAAQK,MAAQ,SAAS0D,GAErB,IADA,GAAIC,GAAOD,EAAK3B,KAAYL,KAAiBkC,EAAY,EAClDD,GAAM,CACT,GAAqC,QAAhC5B,EAAQhB,EAAGK,KAAKyC,KAAKF,IACtBjC,EAAWA,EAAWW,QAAUN,EAAM,OAErC,IAAuC,QAAlCA,EAAQhB,EAAGM,OAAOwC,KAAKF,IAC7BjC,EAAWA,EAAWW,QAAU,QAE/B,CAAA,GAA4C,QAAvCN,EAAQhB,EAAGO,YAAYuC,KAAKF,IAgClC,KAAM,IAAIG,aAAY,mCA/BtB,IAAI/B,EAAM,GAAI,CACV6B,GAAa,CACb,IAAIG,MAAiBC,EAAoBjC,EAAM,GAAIkC,IACnD,IAAuD,QAAlDA,EAAclD,EAAGnB,IAAIiE,KAAKG,IAe3B,KAAM,IAAIF,aAAY,+CAbtB,KADAC,EAAWA,EAAW1B,QAAU4B,EAAY,GACwC,MAA5ED,EAAoBA,EAAkBV,UAAUW,EAAY,GAAG5B,UACnE,GAA8D,QAAzD4B,EAAclD,EAAGQ,WAAWsC,KAAKG,IAClCD,EAAWA,EAAW1B,QAAU4B,EAAY,OAE3C,CAAA,GAAgE,QAA3DA,EAAclD,EAAGS,aAAaqC,KAAKG,IAIzC,KAAM,IAAIF,aAAY,+CAHtBC,GAAWA,EAAW1B,QAAU4B,EAAY,GAUxDlC,EAAM,GAAKgC,MAGXH,IAAa,CAEjB,IAAkB,IAAdA,EACA,KAAM,IAAInB,OAAM,4EAEpBf,GAAWA,EAAWW,QAAUN,EAKpC4B,EAAOA,EAAKL,UAAUvB,EAAM,GAAGM,QAEnC,MAAOX,GAGX,IAAIwC,GAAW,SAASR,EAAK/B,EAAMwC,GAG/B,MAFAA,IAASxC,OAAYnB,MAAM,GAC3B2D,EAAMC,OAAO,EAAG,EAAGV,GACZ/D,EAAQ0E,MAAM,KAAMF,GAiBR,oBAAZG,UACPA,QAAQ3E,QAAUA,EAClB2E,QAAQJ,SAAWA,IAGnBxE,EAAOC,QAAUA,EACjBD,EAAOwE,SAAWA,EAEI,kBAAXK,SAAyBA,OAAOC,KACvCD,OAAO,WACH,OACI5E,QAASA,EACTuE,SAAUA,OAKT,mBAAXxE,QAAyB+E,KAAO/E"} \ No newline at end of file diff --git a/node_modules/sprintf-js/gruntfile.js b/node_modules/sprintf-js/gruntfile.js new file mode 100644 index 0000000..246e1c3 --- /dev/null +++ b/node_modules/sprintf-js/gruntfile.js @@ -0,0 +1,36 @@ +module.exports = function(grunt) { + grunt.initConfig({ + pkg: grunt.file.readJSON("package.json"), + + uglify: { + options: { + banner: "/*! <%= pkg.name %> | <%= pkg.author %> | <%= pkg.license %> */\n", + sourceMap: true + }, + build: { + files: [ + { + src: "src/sprintf.js", + dest: "dist/sprintf.min.js" + }, + { + src: "src/angular-sprintf.js", + dest: "dist/angular-sprintf.min.js" + } + ] + } + }, + + watch: { + js: { + files: "src/*.js", + tasks: ["uglify"] + } + } + }) + + grunt.loadNpmTasks("grunt-contrib-uglify") + grunt.loadNpmTasks("grunt-contrib-watch") + + grunt.registerTask("default", ["uglify", "watch"]) +} diff --git a/node_modules/sprintf-js/package.json b/node_modules/sprintf-js/package.json new file mode 100644 index 0000000..b2095b0 --- /dev/null +++ b/node_modules/sprintf-js/package.json @@ -0,0 +1,86 @@ +{ + "_args": [ + [ + { + "raw": "sprintf-js@~1.0.2", + "scope": null, + "escapedName": "sprintf-js", + "name": "sprintf-js", + "rawSpec": "~1.0.2", + "spec": ">=1.0.2 <1.1.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt-sftp-deploy/node_modules/argparse" + ] + ], + "_from": "sprintf-js@>=1.0.2 <1.1.0", + "_id": "sprintf-js@1.0.3", + "_inCache": true, + "_location": "/sprintf-js", + "_nodeVersion": "0.12.4", + "_npmUser": { + "name": "alexei", + "email": "hello@alexei.ro" + }, + "_npmVersion": "2.10.1", + "_phantomChildren": {}, + "_requested": { + "raw": "sprintf-js@~1.0.2", + "scope": null, + "escapedName": "sprintf-js", + "name": "sprintf-js", + "rawSpec": "~1.0.2", + "spec": ">=1.0.2 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt-sftp-deploy/argparse" + ], + "_resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "_shasum": "04e6926f662895354f3dd015203633b857297e2c", + "_shrinkwrap": null, + "_spec": "sprintf-js@~1.0.2", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt-sftp-deploy/node_modules/argparse", + "author": { + "name": "Alexandru Marasteanu", + "email": "hello@alexei.ro", + "url": "http://alexei.ro/" + }, + "bugs": { + "url": "https://github.com/alexei/sprintf.js/issues" + }, + "dependencies": {}, + "description": "JavaScript sprintf implementation", + "devDependencies": { + "grunt": "*", + "grunt-contrib-uglify": "*", + "grunt-contrib-watch": "*", + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "04e6926f662895354f3dd015203633b857297e2c", + "tarball": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + }, + "gitHead": "747b806c2dab5b64d5c9958c42884946a187c3b1", + "homepage": "https://github.com/alexei/sprintf.js#readme", + "license": "BSD-3-Clause", + "main": "src/sprintf.js", + "maintainers": [ + { + "name": "alexei", + "email": "hello@alexei.ro" + } + ], + "name": "sprintf-js", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/alexei/sprintf.js.git" + }, + "scripts": { + "test": "mocha test/test.js" + }, + "version": "1.0.3" +} diff --git a/node_modules/sprintf-js/src/angular-sprintf.js b/node_modules/sprintf-js/src/angular-sprintf.js new file mode 100644 index 0000000..9c69123 --- /dev/null +++ b/node_modules/sprintf-js/src/angular-sprintf.js @@ -0,0 +1,18 @@ +angular. + module("sprintf", []). + filter("sprintf", function() { + return function() { + return sprintf.apply(null, arguments) + } + }). + filter("fmt", ["$filter", function($filter) { + return $filter("sprintf") + }]). + filter("vsprintf", function() { + return function(format, argv) { + return vsprintf(format, argv) + } + }). + filter("vfmt", ["$filter", function($filter) { + return $filter("vsprintf") + }]) diff --git a/node_modules/sprintf-js/src/sprintf.js b/node_modules/sprintf-js/src/sprintf.js new file mode 100644 index 0000000..c0fc7c0 --- /dev/null +++ b/node_modules/sprintf-js/src/sprintf.js @@ -0,0 +1,208 @@ +(function(window) { + var re = { + not_string: /[^s]/, + number: /[diefg]/, + json: /[j]/, + not_json: /[^j]/, + text: /^[^\x25]+/, + modulo: /^\x25{2}/, + placeholder: /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijosuxX])/, + key: /^([a-z_][a-z_\d]*)/i, + key_access: /^\.([a-z_][a-z_\d]*)/i, + index_access: /^\[(\d+)\]/, + sign: /^[\+\-]/ + } + + function sprintf() { + var key = arguments[0], cache = sprintf.cache + if (!(cache[key] && cache.hasOwnProperty(key))) { + cache[key] = sprintf.parse(key) + } + return sprintf.format.call(null, cache[key], arguments) + } + + sprintf.format = function(parse_tree, argv) { + var cursor = 1, tree_length = parse_tree.length, node_type = "", arg, output = [], i, k, match, pad, pad_character, pad_length, is_positive = true, sign = "" + for (i = 0; i < tree_length; i++) { + node_type = get_type(parse_tree[i]) + if (node_type === "string") { + output[output.length] = parse_tree[i] + } + else if (node_type === "array") { + match = parse_tree[i] // convenience purposes only + if (match[2]) { // keyword argument + arg = argv[cursor] + for (k = 0; k < match[2].length; k++) { + if (!arg.hasOwnProperty(match[2][k])) { + throw new Error(sprintf("[sprintf] property '%s' does not exist", match[2][k])) + } + arg = arg[match[2][k]] + } + } + else if (match[1]) { // positional argument (explicit) + arg = argv[match[1]] + } + else { // positional argument (implicit) + arg = argv[cursor++] + } + + if (get_type(arg) == "function") { + arg = arg() + } + + if (re.not_string.test(match[8]) && re.not_json.test(match[8]) && (get_type(arg) != "number" && isNaN(arg))) { + throw new TypeError(sprintf("[sprintf] expecting number but found %s", get_type(arg))) + } + + if (re.number.test(match[8])) { + is_positive = arg >= 0 + } + + switch (match[8]) { + case "b": + arg = arg.toString(2) + break + case "c": + arg = String.fromCharCode(arg) + break + case "d": + case "i": + arg = parseInt(arg, 10) + break + case "j": + arg = JSON.stringify(arg, null, match[6] ? parseInt(match[6]) : 0) + break + case "e": + arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential() + break + case "f": + arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg) + break + case "g": + arg = match[7] ? parseFloat(arg).toPrecision(match[7]) : parseFloat(arg) + break + case "o": + arg = arg.toString(8) + break + case "s": + arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg) + break + case "u": + arg = arg >>> 0 + break + case "x": + arg = arg.toString(16) + break + case "X": + arg = arg.toString(16).toUpperCase() + break + } + if (re.json.test(match[8])) { + output[output.length] = arg + } + else { + if (re.number.test(match[8]) && (!is_positive || match[3])) { + sign = is_positive ? "+" : "-" + arg = arg.toString().replace(re.sign, "") + } + else { + sign = "" + } + pad_character = match[4] ? match[4] === "0" ? "0" : match[4].charAt(1) : " " + pad_length = match[6] - (sign + arg).length + pad = match[6] ? (pad_length > 0 ? str_repeat(pad_character, pad_length) : "") : "" + output[output.length] = match[5] ? sign + arg + pad : (pad_character === "0" ? sign + pad + arg : pad + sign + arg) + } + } + } + return output.join("") + } + + sprintf.cache = {} + + sprintf.parse = function(fmt) { + var _fmt = fmt, match = [], parse_tree = [], arg_names = 0 + while (_fmt) { + if ((match = re.text.exec(_fmt)) !== null) { + parse_tree[parse_tree.length] = match[0] + } + else if ((match = re.modulo.exec(_fmt)) !== null) { + parse_tree[parse_tree.length] = "%" + } + else if ((match = re.placeholder.exec(_fmt)) !== null) { + if (match[2]) { + arg_names |= 1 + var field_list = [], replacement_field = match[2], field_match = [] + if ((field_match = re.key.exec(replacement_field)) !== null) { + field_list[field_list.length] = field_match[1] + while ((replacement_field = replacement_field.substring(field_match[0].length)) !== "") { + if ((field_match = re.key_access.exec(replacement_field)) !== null) { + field_list[field_list.length] = field_match[1] + } + else if ((field_match = re.index_access.exec(replacement_field)) !== null) { + field_list[field_list.length] = field_match[1] + } + else { + throw new SyntaxError("[sprintf] failed to parse named argument key") + } + } + } + else { + throw new SyntaxError("[sprintf] failed to parse named argument key") + } + match[2] = field_list + } + else { + arg_names |= 2 + } + if (arg_names === 3) { + throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported") + } + parse_tree[parse_tree.length] = match + } + else { + throw new SyntaxError("[sprintf] unexpected placeholder") + } + _fmt = _fmt.substring(match[0].length) + } + return parse_tree + } + + var vsprintf = function(fmt, argv, _argv) { + _argv = (argv || []).slice(0) + _argv.splice(0, 0, fmt) + return sprintf.apply(null, _argv) + } + + /** + * helpers + */ + function get_type(variable) { + return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase() + } + + function str_repeat(input, multiplier) { + return Array(multiplier + 1).join(input) + } + + /** + * export to either browser or node.js + */ + if (typeof exports !== "undefined") { + exports.sprintf = sprintf + exports.vsprintf = vsprintf + } + else { + window.sprintf = sprintf + window.vsprintf = vsprintf + + if (typeof define === "function" && define.amd) { + define(function() { + return { + sprintf: sprintf, + vsprintf: vsprintf + } + }) + } + } +})(typeof window === "undefined" ? this : window); diff --git a/node_modules/sprintf-js/test/test.js b/node_modules/sprintf-js/test/test.js new file mode 100644 index 0000000..6f57b25 --- /dev/null +++ b/node_modules/sprintf-js/test/test.js @@ -0,0 +1,82 @@ +var assert = require("assert"), + sprintfjs = require("../src/sprintf.js"), + sprintf = sprintfjs.sprintf, + vsprintf = sprintfjs.vsprintf + +describe("sprintfjs", function() { + var pi = 3.141592653589793 + + it("should return formated strings for simple placeholders", function() { + assert.equal("%", sprintf("%%")) + assert.equal("10", sprintf("%b", 2)) + assert.equal("A", sprintf("%c", 65)) + assert.equal("2", sprintf("%d", 2)) + assert.equal("2", sprintf("%i", 2)) + assert.equal("2", sprintf("%d", "2")) + assert.equal("2", sprintf("%i", "2")) + assert.equal('{"foo":"bar"}', sprintf("%j", {foo: "bar"})) + assert.equal('["foo","bar"]', sprintf("%j", ["foo", "bar"])) + assert.equal("2e+0", sprintf("%e", 2)) + assert.equal("2", sprintf("%u", 2)) + assert.equal("4294967294", sprintf("%u", -2)) + assert.equal("2.2", sprintf("%f", 2.2)) + assert.equal("3.141592653589793", sprintf("%g", pi)) + assert.equal("10", sprintf("%o", 8)) + assert.equal("%s", sprintf("%s", "%s")) + assert.equal("ff", sprintf("%x", 255)) + assert.equal("FF", sprintf("%X", 255)) + assert.equal("Polly wants a cracker", sprintf("%2$s %3$s a %1$s", "cracker", "Polly", "wants")) + assert.equal("Hello world!", sprintf("Hello %(who)s!", {"who": "world"})) + }) + + it("should return formated strings for complex placeholders", function() { + // sign + assert.equal("2", sprintf("%d", 2)) + assert.equal("-2", sprintf("%d", -2)) + assert.equal("+2", sprintf("%+d", 2)) + assert.equal("-2", sprintf("%+d", -2)) + assert.equal("2", sprintf("%i", 2)) + assert.equal("-2", sprintf("%i", -2)) + assert.equal("+2", sprintf("%+i", 2)) + assert.equal("-2", sprintf("%+i", -2)) + assert.equal("2.2", sprintf("%f", 2.2)) + assert.equal("-2.2", sprintf("%f", -2.2)) + assert.equal("+2.2", sprintf("%+f", 2.2)) + assert.equal("-2.2", sprintf("%+f", -2.2)) + assert.equal("-2.3", sprintf("%+.1f", -2.34)) + assert.equal("-0.0", sprintf("%+.1f", -0.01)) + assert.equal("3.14159", sprintf("%.6g", pi)) + assert.equal("3.14", sprintf("%.3g", pi)) + assert.equal("3", sprintf("%.1g", pi)) + assert.equal("-000000123", sprintf("%+010d", -123)) + assert.equal("______-123", sprintf("%+'_10d", -123)) + assert.equal("-234.34 123.2", sprintf("%f %f", -234.34, 123.2)) + + // padding + assert.equal("-0002", sprintf("%05d", -2)) + assert.equal("-0002", sprintf("%05i", -2)) + assert.equal(" <", sprintf("%5s", "<")) + assert.equal("0000<", sprintf("%05s", "<")) + assert.equal("____<", sprintf("%'_5s", "<")) + assert.equal("> ", sprintf("%-5s", ">")) + assert.equal(">0000", sprintf("%0-5s", ">")) + assert.equal(">____", sprintf("%'_-5s", ">")) + assert.equal("xxxxxx", sprintf("%5s", "xxxxxx")) + assert.equal("1234", sprintf("%02u", 1234)) + assert.equal(" -10.235", sprintf("%8.3f", -10.23456)) + assert.equal("-12.34 xxx", sprintf("%f %s", -12.34, "xxx")) + assert.equal('{\n "foo": "bar"\n}', sprintf("%2j", {foo: "bar"})) + assert.equal('[\n "foo",\n "bar"\n]', sprintf("%2j", ["foo", "bar"])) + + // precision + assert.equal("2.3", sprintf("%.1f", 2.345)) + assert.equal("xxxxx", sprintf("%5.5s", "xxxxxx")) + assert.equal(" x", sprintf("%5.1s", "xxxxxx")) + + }) + + it("should return formated strings for callbacks", function() { + assert.equal("foobar", sprintf("%s", function() { return "foobar" })) + assert.equal(Date.now(), sprintf("%s", Date.now)) // should pass... + }) +}) diff --git a/node_modules/ssh2-streams/.travis.yml b/node_modules/ssh2-streams/.travis.yml new file mode 100644 index 0000000..4cec49d --- /dev/null +++ b/node_modules/ssh2-streams/.travis.yml @@ -0,0 +1,17 @@ +sudo: false +language: cpp +notifications: + email: false +env: + matrix: + - TRAVIS_NODE_VERSION="0.10" + - TRAVIS_NODE_VERSION="0.12" + - TRAVIS_NODE_VERSION="4" + - TRAVIS_NODE_VERSION="6" + - TRAVIS_NODE_VERSION="7" +install: + - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION + - node --version + - npm --version + - npm install +script: npm test diff --git a/node_modules/ssh2-streams/LICENSE b/node_modules/ssh2-streams/LICENSE new file mode 100644 index 0000000..3d983a8 --- /dev/null +++ b/node_modules/ssh2-streams/LICENSE @@ -0,0 +1,19 @@ +Copyright 2014 Brian White. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/ssh2-streams/README.md b/node_modules/ssh2-streams/README.md new file mode 100644 index 0000000..9070928 --- /dev/null +++ b/node_modules/ssh2-streams/README.md @@ -0,0 +1,569 @@ +Description +=========== + +SSH2 and SFTP(v3) client/server protocol streams for [node.js](http://nodejs.org/). + +[![Build Status](https://travis-ci.org/mscdex/ssh2-streams.svg?branch=master)](https://travis-ci.org/mscdex/ssh2-streams) + + +Requirements +============ + +* [node.js](http://nodejs.org/) -- v0.10 or newer + + +Install +======= + + npm install ssh2-streams + + +API +=== + +`require('ssh2').SSH2Stream` returns an **_SSH2Stream_** constructor. + +`require('ssh2').SFTPStream` returns an [**_SFTPStream_**](SFTPStream.md) constructor. + +`require('ssh2').utils` returns an _object_ of useful utility functions. + +`require('ssh2').constants` returns an _object_ containing useful SSH protocol constants. + + +SSH2Stream events +----------------- + +**Client/Server events** + +* **header**(< _object_ >headerInfo) - Emitted when the protocol header is seen. `headerInfo` contains: + + * **greeting** - _string_ - (Client-only) An optional greeting message presented by the server. + + * **identRaw** - _string_ - The raw identification string sent by the remote party. + + * **versions** - _object_ - Contains various information parsed from `identRaw`: + + * **protocol** - _string_ - The protocol version (always `1.99` or `2.0`) supported by the remote party. + + * **software** - _string_ - The software name used by the remote party. + + * **comments** - _string_ - Any additional text that comes after the software name. + +* **GLOBAL_REQUEST**(< _string_ >reqName, < _boolean_ >wantReply, < _mixed_ >reqData) + +* **CHANNEL_DATA:\**(< _Buffer_ >data) + +* **CHANNEL_EXTENDED_DATA:\**(< _integer_ >type, < _Buffer_ >data) + +* **CHANNEL_WINDOW_ADJUST:\**(< _integer_ >bytesToAdd) + +* **CHANNEL_SUCCESS:\**() + +* **CHANNEL_FAILURE:\**() + +* **CHANNEL_EOF:\**() + +* **CHANNEL_CLOSE:\**() + +* **CHANNEL_OPEN_CONFIRMATION:\**(< _object_ >channelInfo) - `channelInfo` contains: + + * **recipient** - _integer_ - The local channel number. + + * **sender** - _integer_ - The remote party's channel number. + + * **window** - _integer_ - The initial window size for the channel. + + * **packetSize** - _integer_ - The maximum packet size for the channel. + +* **CHANNEL_OPEN_FAILURE:\**(< _object_ >failInfo) - `failInfo` contains: + + * **recipient** - _integer_ - The local channel number. + + * **reasonCode** - _integer_ - The reason code of the failure. + + * **reason** - _string_ - A text representation of the `reasonCode`. + + * **description** - _string_ - An optional description of the failure. + +* **DISCONNECT**(< _string_ >reason, < _integer_ >reasonCode, < _string_ >description) + +* **DEBUG**(< _string_ >message) + +* **NEWKEYS**() + +* **REQUEST_SUCCESS**([< _Buffer_ >resData]) + +* **REQUEST_FAILURE**() + + + +**Client-only events** + +* **fingerprint**(< _Buffer_ >hostKey, < _function_ >callback) - This event allows you to verify a host's key. If `callback` is called with `true`, the handshake continues. Otherwise a disconnection will occur if `callback` is called with `false`. The default behavior is to auto-allow any host key if there are no handlers for this event. + +* **SERVICE_ACCEPT**(< _string_ >serviceName) + +* **USERAUTH_PASSWD_CHANGEREQ**(< _string_ >message) + +* **USERAUTH_INFO_REQUEST**(< _string_ >name, < _string_ >instructions, < _string_ >lang, < _array_ >prompts) + +* **USERAUTH_PK_OK**() + +* **USERAUTH_SUCCESS**() + +* **USERAUTH_FAILURE**(< _array_ >methodsContinue, < _boolean_ >partialSuccess) + +* **USERAUTH_BANNER**(< _string_ >message) + +* **CHANNEL_OPEN**(< _object_ >channelInfo) - `channelInfo` contains: + + * **type** - _string_ - The channel type (e.g. `x11`, `forwarded-tcpip`). + + * **sender** - _integer_ - The remote party's channel number. + + * **window** - _integer_ - The initial window size for the channel. + + * **packetSize** - _integer_ - The maximum packet size for the channel. + + * **data** - _object_ - The properties available depend on `type`: + + * `x11`: + + * **srcIP** - _string_ - Source IP address of X11 connection request. + + * **srcPort** - _string_ - Source port of X11 connection request. + + * `forwarded-tcpip`: + + * **srcIP** - _string_ - Source IP address of incoming connection. + + * **srcPort** - _string_ - Source port of incoming connection. + + * **destIP** - _string_ - Destination IP address of incoming connection. + + * **destPort** - _string_ - Destination port of incoming connection. + + * `forwarded-streamlocal@openssh.com`: + + * **socketPath** - _string_ - Source socket path of incoming connection. + + * `auth-agent@openssh.com` has no extra data. + +* **CHANNEL_REQUEST:\**(< _object_ >reqInfo) - `reqInfo` properties depend on `reqInfo.request`: + + * `exit-status`: + + * **code** - _integer_ - The exit status code of the remote process. + + * `exit-signal`: + + * **signal** - _string_ - The signal name. + + * **coredump** - _boolean_ - Was the exit the result of a core dump? + + * **description** - _string_ - An optional error message. + + + +**Server-only events** + +* **SERVICE_REQUEST**(< _string_ >serviceName) + +* **USERAUTH_REQUEST**(< _string_ >username, < _string_ >serviceName, < _string_ >authMethod, < _mixed_ >authMethodData) - `authMethodData` depends on `authMethod`: + + * For `password`, it's a _string_ containing the password. + + * For `publickey`, it's an _object_ containing: + + * **keyAlgo** - _string_ - The public key algorithm. + + * **key** - _Buffer_ - The public key data. + + * **signature** - _mixed_ - If set, it is a _Buffer_ containing the signature to be verified. + + * **blob** - _mixed_ - If set, it is a _Buffer_ containing the data to sign. The resulting signature is what is compared to `signature`. + + * For `hostbased`, it's an _object_ including the properties from `publickey` but also: + + * **localHostname** - _string_ - The client's hostname to be verified. + + * **localUsername** - _string_ - The client's (local) username to be verified. + +* **USERAUTH_INFO_RESPONSE**(< _array_ >responses) + +* **GLOBAL_REQUEST**(< _string_ >reqName, < _boolean_ >wantReply, < _mixed_ >reqData) - `reqData` depends on `reqName`: + + * For `tcpip-forward`/`cancel-tcpip-forward`, it's an _object_ containing: + + * **bindAddr** - _string_ - The IP address to start/stop binding to. + + * **bindPort** - _string_ - The port to start/stop binding to. + + * For `streamlocal-forward@openssh.com`/`cancel-streamlocal-forward@openssh.com`, it's an _object_ containing: + + * **socketPath** - _string_ - The socket path to start/stop listening on. + + * For `no-more-sessions@openssh.com`, there is no `reqData`. + + * For any other requests, it's a _Buffer_ containing raw request-specific data *if* there is any extra data. + +* **CHANNEL_OPEN**(< _object_ >channelInfo) - `channelInfo` contains: + + * **type** - _string_ - The channel type (e.g. `session`, `direct-tcpip`). + + * **sender** - _integer_ - The remote party's channel number. + + * **window** - _integer_ - The initial window size for the channel. + + * **packetSize** - _integer_ - The maximum packet size for the channel. + + * **data** - _object_ - The properties available depend on `type`: + + * `direct-tcpip`: + + * **srcIP** - _string_ - Source IP address of outgoing connection. + + * **srcPort** - _string_ - Source port of outgoing connection. + + * **destIP** - _string_ - Destination IP address of outgoing connection. + + * **destPort** - _string_ - Destination port of outgoing connection. + + * `direct-streamlocal@openssh.com`: + + * **socketPath** - _string_ - Destination socket path of outgoing connection. + + * `session` has no extra data. + +* **CHANNEL_REQUEST:\**(< _object_ >reqInfo) - `reqInfo` properties depend on `reqInfo.request`: + + * `pty-req`: + + * **wantReply** - _boolean_ - The client is requesting a response to this request. + + * **term** - _string_ - The terminal type name. + + * **cols** - _integer_ - The number of columns. + + * **rows** - _integer_ - The number of rows. + + * **width** - _integer_ - The width in pixels. + + * **height** - _integer_ - The height in pixels. + + * **modes** - _object_ - The terminal modes. + + * `window-change`: + + * **cols** - _integer_ - The number of columns. + + * **rows** - _integer_ - The number of rows. + + * **width** - _integer_ - The width in pixels. + + * **height** - _integer_ - The height in pixels. + + * `x11-req`: + + * **wantReply** - _boolean_ - The client is requesting a response to this request. + + * **single** - _boolean_ - Whether only a single X11 connection should be allowed. + + * **protocol** - _string_ - The X11 authentication protocol to be used. + + * **cookie** - _string_ - The hex-encoded X11 authentication cookie. + + * **screen** - _integer_ - The screen number for incoming X11 connections. + + * `env`: + + * **wantReply** - _boolean_ - The client is requesting a response to this request. + + * **key** - _string_ - The environment variable name. + + * **val** - _string_ - The environment variable value. + + * `shell`: + + * **wantReply** - _boolean_ - The client is requesting a response to this request. + + * `exec`: + + * **wantReply** - _boolean_ - The client is requesting a response to this request. + + * **command** - _string_ - The command to be executed. + + * `subsystem`: + + * **wantReply** - _boolean_ - The client is requesting a response to this request. + + * **subsystem** - _string_ - The name of the subsystem. + + * `signal`: + + * **signal** - _string_ - The signal name (prefixed with `SIG`). + + * `xon-xoff`: + + * **clientControl** - _boolean_ - Client can/can't perform flow control (control-S/control-Q processing). + + * `auth-agent-req@openssh.com` has no `reqInfo`. + +SSH2Stream properties +--------------------- + +* **bytesSent** - _integer_ - The number of bytes sent since the last keying. This metric can be useful in determining when to call `rekey()`. + +* **bytesReceived** - _integer_ - The number of bytes received since the last keying. This metric can be useful in determining when to call `rekey()`. + + +SSH2Stream methods +------------------ + +* **(constructor)**(< _object_ >config) - Creates and returns a new SSH2Stream instance. SSH2Stream instances are Duplex streams. `config` can contain: + + * **server** - _boolean_ - Set to `true` to create an instance in server mode. **Default:** `false` + + * **hostKeys** - _object_ - If in server mode, an object keyed on host key format (see supported `serverHostKey` values in `algorithms` option below) with values being (decrypted) _Buffer_s or _string_s that contain PEM-encoded (OpenSSH format) host private key(s). **Default:** (none) + + * **greeting** - _string_ - If in server mode, an optional message to send to the user immediately upon connection, before the handshake. **Note:** Most clients usually ignore this. **Default:** (none) + + * **banner** - _string_ - If in server mode, an optional message to send to the user once, right before authentication begins. **Default:** (none) + + * **ident** - _string_ - A custom software name/version identifier. **Default:** `'ssh2js' + moduleVersion + 'srv'` (server mode) `'ssh2js' + moduleVersion` (client mode) + + * **maxPacketSize** - _string_ - This is the maximum packet size that will be accepted. It should be 35000 bytes or larger to be compatible with other SSH2 implementations. **Default:** `35000` + + * **highWaterMark** - _integer_ - This is the `highWaterMark` to use for the stream. **Default:** `32 * 1024` + + * **algorithms** - _object_ - This option allows you to explicitly override the default transport layer algorithms used for the connection. Each value must be an array of valid algorithms for that category. The order of the algorithms in the arrays are important, with the most favorable being first. Valid keys: + + * **kex** - _array_ - Key exchange algorithms. + + * Default values: + + 1. ecdh-sha2-nistp256 **(node v0.11.14 or newer)** + 2. ecdh-sha2-nistp384 **(node v0.11.14 or newer)** + 3. ecdh-sha2-nistp521 **(node v0.11.14 or newer)** + 4. diffie-hellman-group-exchange-sha256 **(node v0.11.12 or newer)** + 5. diffie-hellman-group14-sha1 + + * Supported values: + + * ecdh-sha2-nistp256 **(node v0.11.14 or newer)** + * ecdh-sha2-nistp384 **(node v0.11.14 or newer)** + * ecdh-sha2-nistp521 **(node v0.11.14 or newer)** + * diffie-hellman-group-exchange-sha256 **(node v0.11.12 or newer)** + * diffie-hellman-group14-sha1 + * diffie-hellman-group-exchange-sha1 **(node v0.11.12 or newer)** + * diffie-hellman-group1-sha1 + + * **cipher** - _array_ - Ciphers. + + * Default values: + + 1. aes128-ctr + 2. aes192-ctr + 3. aes256-ctr + 4. aes128-gcm **(node v0.11.12 or newer)** + 5. aes128-gcm@openssh.com **(node v0.11.12 or newer)** + 6. aes256-gcm **(node v0.11.12 or newer)** + 7. aes256-gcm@openssh.com **(node v0.11.12 or newer)** + + * Supported values: + + * aes128-ctr + * aes192-ctr + * aes256-ctr + * aes128-gcm **(node v0.11.12 or newer)** + * aes128-gcm@openssh.com **(node v0.11.12 or newer)** + * aes256-gcm **(node v0.11.12 or newer)** + * aes256-gcm@openssh.com **(node v0.11.12 or newer)** + * aes256-cbc + * aes192-cbc + * aes128-cbc + * blowfish-cbc + * 3des-cbc + * arcfour256 + * arcfour128 + * cast128-cbc + * arcfour + + * **serverHostKey** - _array_ - Server host key formats. In server mode, this list must agree with the host private keys set in the `hostKeys` config setting. + + * Default values: + + 1. ssh-rsa + 2. ecdsa-sha2-nistp256 **(node v5.2.0 or newer)** + 3. ecdsa-sha2-nistp384 **(node v5.2.0 or newer)** + 4. ecdsa-sha2-nistp521 **(node v5.2.0 or newer)** + + * Supported values: + + * ssh-rsa + * ecdsa-sha2-nistp256 **(node v5.2.0 or newer)** + * ecdsa-sha2-nistp384 **(node v5.2.0 or newer)** + * ecdsa-sha2-nistp521 **(node v5.2.0 or newer)** + * ssh-dss + + * **hmac** - _array_ - (H)MAC algorithms. + + * Default values: + + 1. hmac-sha2-256 + 2. hmac-sha2-512 + 3. hmac-sha1 + + * Supported values: + + * hmac-sha2-256 + * hmac-sha2-512 + * hmac-sha1 + * hmac-md5 + * hmac-sha2-256-96 + * hmac-sha2-512-96 + * hmac-ripemd160 + * hmac-sha1-96 + * hmac-md5-96 + + * **compress** - _array_ - Compression algorithms. + + * Default values: + + 1. none + 2. zlib@openssh.com + 3. zlib + + * Supported values: + + * none + * zlib@openssh.com + * zlib + + * **debug** - _function_ - Set this to a function that receives a single string argument to get detailed (local) debug information. **Default:** (none) + + + +**Client/Server methods** + +* **ping**() - _boolean_ - Writes a dummy GLOBAL_REQUEST packet (specifically "keepalive@openssh.com") that requests a reply. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **disconnect**([< _integer_ >reasonCode]) - _boolean_ - Writes a disconnect packet and closes the stream. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **rekey**() - _boolean_ - Starts the re-keying process. Incoming/Outgoing packets are buffered until the re-keying process has finished. Returns `false` to indicate that no more packets should be written until the `NEWKEYS` event is seen. + +* **requestSuccess**([< _Buffer_ >data]) - _boolean_ - Writes a request success packet. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **requestFailure**() - _boolean_ - Writes a request failure packet. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **channelSuccess**() - _boolean_ - Writes a channel success packet. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **channelFailure**() - _boolean_ - Writes a channel failure packet. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **channelEOF**(< _integer_ >channel) - _boolean_ - Writes a channel EOF packet for the given `channel`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **channelClose**(< _integer_ >channel) - _boolean_ - Writes a channel close packet for the given `channel`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **channelWindowAdjust**(< _integer_ >channel, < _integer_ >amount) - _boolean_ - Writes a channel window adjust packet for the given `channel` where `amount` is the number of bytes to add to the channel window. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **channelData**(< _integer_ >channel, < _mixed_ >data) - _boolean_ - Writes a channel data packet for the given `channel` where `data` is a _Buffer_ or _string_. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **channelExtData**(< _integer_ >channel, < _mixed_ >data, < _integer_ >type) - _boolean_ - Writes a channel extended data packet for the given `channel` where `data is a _Buffer_ or _string_. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **channelOpenConfirm**(< _integer_ >remoteChannel, < _integer_ >localChannel, < _integer_ >initWindow, < _integer_ >maxPacket) - _boolean_ - Writes a channel open confirmation packet. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **channelOpenFail**(< _integer_ >remoteChannel, < _integer_ >reasonCode[, < _string_ >description]) - _boolean_ - Writes a channel open failure packet. Returns `false` if you should wait for the `continue` event before sending any more traffic. + + + +**Client-only methods** + +* **service**(< _string_ >serviceName) - _boolean_ - Writes a service request packet for `serviceName`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **tcpipForward**(< _string_ >bindAddr, < _integer_ >bindPort[, < _boolean_ >wantReply]) - _boolean_ - Writes a tcpip forward global request packet. `wantReply` defaults to `true`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **cancelTcpipForward**(< _string_ >bindAddr, < _integer_ >bindPort[, < _boolean_ >wantReply]) - _boolean_ - Writes a cancel tcpip forward global request packet. `wantReply` defaults to `true`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **authPassword**(< _string_ >username, < _string_ >password) - _boolean_ - Writes a password userauth request packet. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **authPK**(< _string_ >username, < _object_ >pubKey[, < _function_ >cbSign]) - _boolean_ - Writes a publickey userauth request packet. `pubKey` is the object returned from using `utils.parseKey()` on a private or public key. If `cbSign` is not present, a pubkey check userauth packet is written. Otherwise `cbSign` is called with `(blob, callback)`, where `blob` is the data to sign with the private key and the resulting signature _Buffer_ is passed to `callback` as the first argument. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **authHostbased**(< _string_ >username, < _object_ >pubKey, < _string_ >localHostname, < _string_ >localUsername, < _function_ >cbSign) - _boolean_ - Writes a hostbased userauth request packet. `pubKey` is the object returned from using `utils.parseKey()` on a private or public key. `cbSign` is called with `(blob, callback)`, where `blob` is the data to sign with the private key and the resulting signature _Buffer_ is passed to `callback` as the first argument. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **authKeyboard**(< _string_ >username) - _boolean_ - Writes a keyboard-interactive userauth request packet. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **authNone**(< _string_ >username) - _boolean_ - Writes a "none" userauth request packet. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **authInfoRes**(< _array_ >responses) - _boolean_ - Writes a userauth info response packet. `responses` is an _array_ of zero or more strings corresponding to responses to prompts previously sent by the server. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **directTcpip**(< _integer_ >channel, < _integer_ >initWindow, < _integer_ >maxPacket, < _object_ >config) - _boolean_ - Writes a direct tcpip channel open packet. `config` must contain `srcIP`, `srcPort`, `dstIP`, and `dstPort`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **session**(< _integer_ >channel, < _integer_ >initWindow, < _integer_ >maxPacket) - _boolean_ - Writes a session channel open packet. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **openssh_agentForward**(< _integer_ >channel[, < _boolean_ >wantReply]) - _boolean_ - Writes an `auth-agent-req@openssh.com` channel request packet. `wantReply` defaults to `true`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **windowChange**(< _integer_ >channel, < _integer_ >rows, < _integer_ >cols, < _integer_ >height, < _integer_ >width) - _boolean_ - Writes a window change channel request packet. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **pty**(< _integer_ >channel, < _integer_ >rows, < _integer_ >cols, < _integer_ >height, < _integer_ >width, < _string_ >terminalType, < _mixed_ >terminalModes[, < _boolean_ >wantReply]) - _boolean_ - Writes a pty channel request packet. If `terminalType` is falsey, `vt100` is used. `terminalModes` can be the raw bytes, an _object_ of the terminal modes to set, or a falsey value for no modes. `wantReply` defaults to `true`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **env**(< _integer_ >channel, < _string_ >key, < _mixed_ >value[, < _boolean_ >wantReply]) - _boolean_ - Writes an env channel request packet. `value` can be a _string_ or _Buffer_. `wantReply` defaults to `true`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **shell**(< _integer_ >channel[, < _boolean_ >wantReply]) - _boolean_ - Writes a shell channel request packet. `wantReply` defaults to `true`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **exec**(< _integer_ >channel, < _string_ >command[, < _boolean_ >wantReply]) - _boolean_ - Writes an exec channel request packet. `wantReply` defaults to `true`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **signal**(< _integer_ >channel, < _string_ >signalName) - _boolean_ - Writes a signal channel request packet. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **x11Forward**(< _integer_ >channel, < _object_ >config[, < _boolean_ >wantReply]) - _boolean_ - Writes an X11 forward channel request packet. `wantReply` defaults to `true`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `config` can contain: + + * **single** - _boolean_ - `true` if only a single connection should be forwarded. + + * **protocol** - _string_ - The name of the X11 authentication method used (e.g. `MIT-MAGIC-COOKIE-1`). + + * **cookie** - _string_ - The X11 authentication cookie encoded in hexadecimal. + + * **screen** - _integer_ - The screen number to forward X11 connections for. + +* **subsystem**(< _integer_ >channel, < _string_ >name[, < _boolean_ >wantReply]) - _boolean_ - Writes a subsystem channel request packet. `name` is the name of the subsystem (e.g. `sftp` or `netconf`). `wantReply` defaults to `true`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **openssh_noMoreSessions**([< _boolean_ >wantReply]) - _boolean_ - Writes a no-more-sessions@openssh.com request packet. `wantReply` defaults to `true`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **openssh_streamLocalForward**(< _string_ >socketPath[, < _boolean_ >wantReply]) - _boolean_ - Writes a streamlocal-forward@openssh.com request packet. `wantReply` defaults to `true`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **openssh_cancelStreamLocalForward**(< _string_ >socketPath[, < _boolean_ >wantReply]) - _boolean_ - Writes a cancel-streamlocal-forward@openssh.com request packet. `wantReply` defaults to `true`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **openssh_directStreamLocal**(< _integer_ >channel, < _integer_ >initWindow, < _integer_ >maxPacket, < _object_ >config) - _boolean_ - Writes a direct-streamlocal@openssh.com channel open packet. `config` must contain `socketPath`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + + + +**Server-only methods** + +* **serviceAccept**(< _string_ >serviceName) - _boolean_ - Writes a service accept packet. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **authFailure**([< _array_ >authMethods[, < _boolean_ >partialSuccess]]) - _boolean_ - Writes a userauth failure packet. `authMethods` is an _array_ of authentication methods that can continue. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **authSuccess**() - _boolean_ - Writes a userauth success packet. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **authPKOK**(< _string_ >keyAlgorithm, < _Buffer_ >keyData) - _boolean_ - Writes a userauth PK OK packet. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **authInfoReq**(< _string_ >name, < _string_ >instructions, < _array_ >prompts) - _boolean_ - Writes a userauth info request packet. `prompts` is an array of `{ prompt: 'Prompt text', echo: true }` objects (`prompt` being the prompt text and `echo` indicating whether the client's response to the prompt should be echoed to their display). Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **forwardedTcpip**(< _integer_ >channel, < _integer_ >initWindow, < _integer_ >maxPacket, < _object_ >info) - _boolean_ - Writes a forwarded tcpip channel open packet. `info` must contain `boundAddr`, `boundPort`, `remoteAddr`, and `remotePort`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **x11**(< _integer_ >channel, < _integer_ >initWindow, < _integer_ >maxPacket, < _object_ >info) - _boolean_ - Writes an X11 channel open packet. `info` must contain `originAddr` and `originPort`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **openssh_forwardedStreamLocal**(< _integer_ >channel, < _integer_ >initWindow, < _integer_ >maxPacket, < _object_ >info) - _boolean_ - Writes an forwarded-streamlocal@openssh.com channel open packet. `info` must contain `socketPath`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **exitStatus**(< _integer_ >channel, < _integer_ >exitCode) - _boolean_ - Writes an exit status channel request packet. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **exitSignal**(< _integer_ >channel, < _string_ >signalName, < _boolean_ >coreDumped, < _string_ >errorMessage) - _boolean_ - Writes an exit signal channel request packet. Returns `false` if you should wait for the `continue` event before sending any more traffic. + + +Utility methods +--------------- + +* **parseKey**(< _mixed_ >keyData) - _object_ - Parses a private/public key in OpenSSH and RFC4716 formats. + +* **decryptKey**(< _object_ >privKeyInfo, < _string_ >passphrase) - _(void)_ - Takes a private key parsed with `parseKey()` and decrypts it with `passphrase`. The decrypted key data overwrites the original encrypted copy. + +* **genPublicKey**(< _object_ >privKeyInfo) - _object_ - Takes a private key parsed with `parseKey()` and generates the associated public key and returns the public key information in the same format as `parseKey()`. diff --git a/node_modules/ssh2-streams/SFTPStream.md b/node_modules/ssh2-streams/SFTPStream.md new file mode 100644 index 0000000..f44e5bd --- /dev/null +++ b/node_modules/ssh2-streams/SFTPStream.md @@ -0,0 +1,405 @@ +SFTPStream events +----------------- + +**Client/Server events** + +* **ready**() - Emitted after initial protocol version check has passed. + +**Server-only events** + +_Responses to these client requests are sent using one of the methods listed further in this document under `Server-only methods`. The valid response(s) for each request are documented below._ + +* **OPEN**(< _integer_ >reqID, < _string_ >filename, < _integer_ >flags, < _ATTRS_ >attrs) + + `flags` is a bitfield containing any of the flags defined in + `SFTPStream.OPEN_MODE`. Use the static method `SFTPStream.flagsToString()` + to convert the value to a mode string to be used by `fs.open()` (e.g. `'r'`). + + Respond using one of the following: + + * `handle()` - This indicates a successful opening of the file and passes + the given handle back to the client to use to refer to this open file for + future operations (e.g. reading, writing, closing). + + * `status()` - Use this to indicate a failure to open the requested file. + +* **READ**(< _integer_ >reqID, < _Buffer_ >handle, < _integer_ >offset, < _integer_ >length) + + Respond using one of the following: + + * `data()` - Use this to send the requested chunk of data back to the client. + The amount of data sent is allowed to be less than the `length` requested, + for example if the file ends between `offset` and `offset + length`. + + * `status()` - Use this to indicate either end of file (`STATUS_CODE.EOF`) + has been reached (`offset` is past the end of the file) or if an error + occurred while reading the requested part of the file. + +* **WRITE**(< _integer_ >reqID, < _Buffer_ >handle, < _integer_ >offset, < _Buffer_ >data) + + Respond using: + + * `status()` - Use this to indicate success/failure of the write to the file. + +* **FSTAT**(< _integer_ >reqID, < _Buffer_ >handle) + + Respond using one of the following: + + * `attrs()` - Use this to send the attributes for the requested + file/directory back to the client. + + * `status()` - Use this to indicate an error occurred while accessing the + file/directory. + +* **FSETSTAT**(< _integer_ >reqID, < _Buffer_ >handle, < _ATTRS_ >attrs) + + Respond using: + + * `status()` - Use this to indicates success/failure of the setting of the + given file/directory attributes. + +* **CLOSE**(< _integer_ >reqID, < _Buffer_ >handle) + + Respond using: + + * `status()` - Use this to indicate success (`STATUS_CODE.OK`) or failure of + the closing of the file identified by `handle`. + +* **OPENDIR**(< _integer_ >reqID, < _string_ >path) + + Respond using one of the following: + + * `handle()` - This indicates a successful opening of the directory and + passes the given handle back to the client to use to refer to this open + directory for future operations (e.g. reading directory contents, closing). + + * `status()` - Use this to indicate a failure to open the requested + directory. + +* **READDIR**(< _integer_ >reqID, < _Buffer_ >handle) + + Respond using one of the following: + + * `name()` - Use this to send one or more directory listings for the open + directory back to the client. + + * `status()` - Use this to indicate either end of directory contents + (`STATUS_CODE.EOF`) or if an error occurred while reading the directory + contents. + +* **LSTAT**(< _integer_ >reqID, < _string_ >path) + + Respond using one of the following: + + * `attrs()` - Use this to send the attributes for the requested + file/directory back to the client. + + * `status()` - Use this to indicate an error occurred while accessing the + file/directory. + +* **STAT**(< _integer_ >reqID, < _string_ >path) + + Respond using one of the following: + + * `attrs()` - Use this to send the attributes for the requested + file/directory back to the client. + + * `status()` - Use this to indicate an error occurred while accessing the + file/directory. + +* **REMOVE**(< _integer_ >reqID, < _string_ >path) + + Respond using: + + * `status()` - Use this to indicate success/failure of the removal of the + file at `path`. + +* **RMDIR**(< _integer_ >reqID, < _string_ >path) + + Respond using: + + * `status()` - Use this to indicate success/failure of the removal of the + directory at `path`. + +* **REALPATH**(< _integer_ >reqID, < _string_ >path) + + Respond using one of the following: + + * `name()` - Use this to respond with a normalized version of `path`. + No file/directory attributes are required to be sent in this response. + + * `status()` - Use this to indicate a failure in normalizing `path`. + +* **READLINK**(< _integer_ >reqID, < _string_ >path) + + Respond using one of the following: + + * `name()` - Use this to respond with the target of the symlink at `path`. + No file/directory attributes are required to be sent in this response. + + * `status()` - Use this to indicate a failure in reading the symlink at + `path`. + +* **SETSTAT**(< _integer_ >reqID, < _string_ >path, < _ATTRS_ >attrs) + + Respond using: + + * `status()` - Use this to indicates success/failure of the setting of the + given file/directory attributes. + +* **MKDIR**(< _integer_ >reqID, < _string_ >path, < _ATTRS_ >attrs) + + Respond using: + + * `status()` - Use this to indicate success/failure of the creation of the + directory at `path`. + +* **RENAME**(< _integer_ >reqID, < _string_ >oldPath, < _string_ >newPath) + + Respond using: + + * `status()` - Use this to indicate success/failure of the renaming of the + file/directory at `oldPath` to `newPath`. + +* **SYMLINK**(< _integer_ >reqID, < _string_ >linkPath, < _string_ >targetPath) + + Respond using: + + * `status()` - Use this to indicate success/failure of the symlink creation. + + +SFTPStream static constants +--------------------------- + +* **SFTPStream.STATUS_CODE** - _object_ - Contains the various status codes (for use especially with `status()`): + + * `OK` + + * `EOF` + + * `NO_SUCH_FILE` + + * `PERMISSION_DENIED` + + * `FAILURE` + + * `BAD_MESSAGE` + + * `OP_UNSUPPORTED` + +* **SFTPStream.OPEN_MODE** - _object_ - Contains the various open file flags: + + * `READ` + + * `WRITE` + + * `APPEND` + + * `CREAT` + + * `TRUNC` + + * `EXCL` + + +SFTPStream static methods +------------------------- + +* **SFTPStream.stringToFlags**(< _string_ >flagsStr) - _integer_ - Converts string flags (e.g. `'r'`, `'a+'`, etc.) to the appropriate `SFTPStream.OPEN_MODE` flag mask. Returns `null` if conversion failed. + +* **SFTPStream.flagsToString**(< _integer_ >flagsMask) - _string_ - Converts flag mask (e.g. number containing `SFTPStream.OPEN_MODE` values) to the appropriate string value. Returns `null` if conversion failed. + + +SFTPStream methods +------------------ + +* **(constructor)**(< _object_ >config[, < _string_ >remoteIdentRaw]) - Creates and returns a new SFTPStream instance. SFTPStream instances are Duplex streams. `remoteIdentRaw` can be the raw SSH identification string of the remote party. This is used to change internal behavior based on particular SFTP implementations. `config` can contain: + + * **server** - _boolean_ - Set to `true` to create an instance in server mode. **Default:** `false` + + * **highWaterMark** - _integer_ - This is the `highWaterMark` to use for the stream. **Default:** `32 * 1024` + + * **debug** - _function_ - Set this to a function that receives a single string argument to get detailed (local) debug information. **Default:** (none) + + + +**Client-only methods** + +* **fastGet**(< _string_ >remotePath, < _string_ >localPath[, < _object_ >options], < _function_ >callback) - _(void)_ - Downloads a file at `remotePath` to `localPath` using parallel reads for faster throughput. `options` can have the following properties: + + * **concurrency** - _integer_ - Number of concurrent reads **Default:** `64` + + * **chunkSize** - _integer_ - Size of each read in bytes **Default:** `32768` + + * **step** - _function_(< _integer_ >total_transferred, < _integer_ >chunk, < _integer_ >total) - Called every time a part of a file was transferred + + `callback` has 1 parameter: < _Error_ >err. + +* **fastPut**(< _string_ >localPath, < _string_ >remotePath[, < _object_ >options], < _function_ >callback) - _(void)_ - Uploads a file from `localPath` to `remotePath` using parallel reads for faster throughput. `options` can have the following properties: + + * **concurrency** - _integer_ - Number of concurrent reads **Default:** `64` + + * **chunkSize** - _integer_ - Size of each read in bytes **Default:** `32768` + + * **step** - _function_(< _integer_ >total_transferred, < _integer_ >chunk, < _integer_ >total) - Called every time a part of a file was transferred + + * **mode** - _mixed_ - Integer or string representing the file mode to set for the uploaded file. + + `callback` has 1 parameter: < _Error_ >err. + +* **createReadStream**(< _string_ >path[, < _object_ >options]) - _ReadStream_ - Returns a new readable stream for `path`. `options` has the following defaults: + + ```javascript + { flags: 'r', + encoding: null, + handle: null, + mode: 0o666, + autoClose: true + } + ``` + + `options` can include `start` and `end` values to read a range of bytes from the file instead of the entire file. Both `start` and `end` are inclusive and start at 0. The `encoding` can be `'utf8'`, `'ascii'`, or `'base64'`. + + If `autoClose` is false, then the file handle won't be closed, even if there's an error. It is your responsiblity to close it and make sure there's no file handle leak. If `autoClose` is set to true (default behavior), on `error` or `end` the file handle will be closed automatically. + + An example to read the last 10 bytes of a file which is 100 bytes long: + + ```javascript + sftp.createReadStream('sample.txt', {start: 90, end: 99}); + ``` + +* **createWriteStream**(< _string_ >path[, < _object_ >options]) - _WriteStream_ - Returns a new writable stream for `path`. `options` has the following defaults: + + ```javascript + { + flags: 'w', + encoding: null, + mode: 0o666, + autoClose: true + } + ``` + + `options` may also include a `start` option to allow writing data at some position past the beginning of the file. Modifying a file rather than replacing it may require a flags mode of 'r+' rather than the default mode 'w'. + + If 'autoClose' is set to false and you pipe to this stream, this stream will not automatically close after there is no more data upstream -- allowing future pipes and/or manual writes. + +* **open**(< _string_ >filename, < _string_ >flags, [< _mixed_ >attrs_mode, ]< _function_ >callback) - _boolean_ - Opens a file `filename` with `flags` with optional _ATTRS_ object or file mode `attrs_mode`. `flags` is any of the flags supported by `fs.open` (except sync flag). Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 2 parameters: < _Error_ >err, < _Buffer_ >handle. + +* **close**(< _Buffer_ >handle, < _function_ >callback) - _boolean_ - Closes the resource associated with `handle` given by open() or opendir(). Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + +* **readData**(< _Buffer_ >handle, < _Buffer_ >buffer, < _integer_ >offset, < _integer_ >length, < _integer_ >position, < _function_ >callback) - _boolean_ - Reads `length` bytes from the resource associated with `handle` starting at `position` and stores the bytes in `buffer` starting at `offset`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 4 parameters: < _Error_ >err, < _integer_ >bytesRead, < _Buffer_ >buffer (offset adjusted), < _integer_ >position. + +* **writeData**(< _Buffer_ >handle, < _Buffer_ >buffer, < _integer_ >offset, < _integer_ >length, < _integer_ >position, < _function_ >callback) - _boolean_ - Writes `length` bytes from `buffer` starting at `offset` to the resource associated with `handle` starting at `position`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + +* **fstat**(< _Buffer_ >handle, < _function_ >callback) - _boolean_ - Retrieves attributes for the resource associated with `handle`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 2 parameters: < _Error_ >err, < _Stats_ >stats. + +* **fsetstat**(< _Buffer_ >handle, < _ATTRS_ >attributes, < _function_ >callback) - _boolean_ - Sets the attributes defined in `attributes` for the resource associated with `handle`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + +* **futimes**(< _Buffer_ >handle, < _mixed_ >atime, < _mixed_ >mtime, < _function_ >callback) - _boolean_ - Sets the access time and modified time for the resource associated with `handle`. `atime` and `mtime` can be Date instances or UNIX timestamps. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + +* **fchown**(< _Buffer_ >handle, < _integer_ >uid, < _integer_ >gid, < _function_ >callback) - _boolean_ - Sets the owner for the resource associated with `handle`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + +* **fchmod**(< _Buffer_ >handle, < _mixed_ >mode, < _function_ >callback) - _boolean_ - Sets the mode for the resource associated with `handle`. `mode` can be an integer or a string containing an octal number. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + +* **opendir**(< _string_ >path, < _function_ >callback) - _boolean_ - Opens a directory `path`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 2 parameters: < _Error_ >err, < _Buffer_ >handle. + +* **readdir**(< _mixed_ >location, < _function_ >callback) - _boolean_ - Retrieves a directory listing. `location` can either be a _Buffer_ containing a valid directory handle from opendir() or a _string_ containing the path to a directory. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 2 parameters: < _Error_ >err, < _mixed_ >list. `list` is an _Array_ of `{ filename: 'foo', longname: '....', attrs: {...} }` style objects (attrs is of type _ATTR_). If `location` is a directory handle, this function may need to be called multiple times until `list` is boolean false, which indicates that no more directory entries are available for that directory handle. + +* **unlink**(< _string_ >path, < _function_ >callback) - _boolean_ - Removes the file/symlink at `path`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + +* **rename**(< _string_ >srcPath, < _string_ >destPath, < _function_ >callback) - _boolean_ - Renames/moves `srcPath` to `destPath`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + +* **mkdir**(< _string_ >path, [< _ATTRS_ >attributes, ]< _function_ >callback) - _boolean_ - Creates a new directory `path`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + +* **rmdir**(< _string_ >path, < _function_ >callback) - _boolean_ - Removes the directory at `path`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + +* **stat**(< _string_ >path, < _function_ >callback) - _boolean_ - Retrieves attributes for `path`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 2 parameter: < _Error_ >err, < _Stats_ >stats. + +* **lstat**(< _string_ >path, < _function_ >callback) - _boolean_ - Retrieves attributes for `path`. If `path` is a symlink, the link itself is stat'ed instead of the resource it refers to. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 2 parameters: < _Error_ >err, < _Stats_ >stats. + +* **setstat**(< _string_ >path, < _ATTRS_ >attributes, < _function_ >callback) - _boolean_ - Sets the attributes defined in `attributes` for `path`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + +* **utimes**(< _string_ >path, < _mixed_ >atime, < _mixed_ >mtime, < _function_ >callback) - _boolean_ - Sets the access time and modified time for `path`. `atime` and `mtime` can be Date instances or UNIX timestamps. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + +* **chown**(< _string_ >path, < _integer_ >uid, < _integer_ >gid, < _function_ >callback) - _boolean_ - Sets the owner for `path`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + +* **chmod**(< _string_ >path, < _mixed_ >mode, < _function_ >callback) - _boolean_ - Sets the mode for `path`. `mode` can be an integer or a string containing an octal number. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + +* **readlink**(< _string_ >path, < _function_ >callback) - _boolean_ - Retrieves the target for a symlink at `path`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 2 parameters: < _Error_ >err, < _string_ >target. + +* **symlink**(< _string_ >targetPath, < _string_ >linkPath, < _function_ >callback) - _boolean_ - Creates a symlink at `linkPath` to `targetPath`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + +* **realpath**(< _string_ >path, < _function_ >callback) - _boolean_ - Resolves `path` to an absolute path. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 2 parameters: < _Error_ >err, < _string_ >absPath. + +* **ext_openssh_rename**(< _string_ >srcPath, < _string_ >destPath, < _function_ >callback) - _boolean_ - **OpenSSH extension** Performs POSIX rename(3) from `srcPath` to `destPath`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + +* **ext_openssh_statvfs**(< _string_ >path, < _function_ >callback) - _boolean_ - **OpenSSH extension** Performs POSIX statvfs(2) on `path`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 2 parameters: < _Error_ >err, < _object_ >fsInfo. `fsInfo` contains the information as found in the [statvfs struct](http://linux.die.net/man/2/statvfs). + +* **ext_openssh_fstatvfs**(< _Buffer_ >handle, < _function_ >callback) - _boolean_ - **OpenSSH extension** Performs POSIX fstatvfs(2) on open handle `handle`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 2 parameters: < _Error_ >err, < _object_ >fsInfo. `fsInfo` contains the information as found in the [statvfs struct](http://linux.die.net/man/2/statvfs). + +* **ext_openssh_hardlink**(< _string_ >targetPath, < _string_ >linkPath, < _function_ >callback) - _boolean_ - **OpenSSH extension** Performs POSIX link(2) to create a hard link to `targetPath` at `linkPath`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + +* **ext_openssh_fsync**(< _Buffer_ >handle, < _function_ >callback) - _boolean_ - **OpenSSH extension** Performs POSIX fsync(3) on the open handle `handle`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err. + + +**Server-only methods** + +* **status**(< _integer_ >reqID, < _integer_ >statusCode[, < _string_ >message]) - _boolean_ - Sends a status response for the request identified by `id`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **handle**(< _integer_ >reqID, < _Buffer_ >handle) - _boolean_ - Sends a handle response for the request identified by `id`. `handle` must be less than 256 bytes and is an opaque value that could merely contain the value of a backing file descriptor or some other unique, custom value. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **data**(< _integer_ >reqID, < _mixed_ >data[, < _string_ >encoding]) - _boolean_ - Sends a data response for the request identified by `id`. `data` can be a _Buffer_ or _string_. If `data` is a string, `encoding` is the encoding of `data`. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **name**(< _integer_ >reqID, < _array_ >names) - _boolean_ - Sends a name response for the request identified by `id`. Returns `false` if you should wait for the `continue` event before sending any more traffic. `names` must be an _array_ of _object_ where each _object_ can contain: + + * **filename** - _string_ - The entry's name. + + * **longname** - _string_ - This is the `ls -l`-style format for the entry (e.g. `-rwxr--r-- 1 bar bar 718 Dec 8 2009 foo`) + + * **attrs** - _ATTRS_ - This is an optional _ATTRS_ object that contains requested/available attributes for the entry. + +* **attrs**(< _integer_ >reqID, < _ATTRS_ >attrs) - _boolean_ - Sends an attrs response for the request identified by `id`. `attrs` contains the requested/available attributes. + + +ATTRS +----- + +An object with the following valid properties: + +* **mode** - _integer_ - Mode/permissions for the resource. + +* **uid** - _integer_ - User ID of the resource. + +* **gid** - _integer_ - Group ID of the resource. + +* **size** - _integer_ - Resource size in bytes. + +* **atime** - _integer_ - UNIX timestamp of the access time of the resource. + +* **mtime** - _integer_ - UNIX timestamp of the modified time of the resource. + +When supplying an ATTRS object to one of the SFTP methods: + +* `atime` and `mtime` can be either a Date instance or a UNIX timestamp. + +* `mode` can either be an integer or a string containing an octal number. + + +Stats +----- + +An object with the same attributes as an ATTRS object with the addition of the following methods: + +* `stats.isDirectory()` + +* `stats.isFile()` + +* `stats.isBlockDevice()` + +* `stats.isCharacterDevice()` + +* `stats.isSymbolicLink()` + +* `stats.isFIFO()` + +* `stats.isSocket()` diff --git a/node_modules/ssh2-streams/index.js b/node_modules/ssh2-streams/index.js new file mode 100644 index 0000000..ac17b72 --- /dev/null +++ b/node_modules/ssh2-streams/index.js @@ -0,0 +1,6 @@ +module.exports = { + SFTPStream: require('./lib/sftp'), + SSH2Stream: require('./lib/ssh'), + utils: require('./lib/utils'), + constants: require('./lib/constants') +}; \ No newline at end of file diff --git a/node_modules/ssh2-streams/lib/constants.js b/node_modules/ssh2-streams/lib/constants.js new file mode 100644 index 0000000..5feedb0 --- /dev/null +++ b/node_modules/ssh2-streams/lib/constants.js @@ -0,0 +1,386 @@ +var semver = require('semver'); + +var i; +var keys; +var len; + +var MESSAGE = exports.MESSAGE = { + // Transport layer protocol -- generic (1-19) + DISCONNECT: 1, + IGNORE: 2, + UNIMPLEMENTED: 3, + DEBUG: 4, + SERVICE_REQUEST: 5, + SERVICE_ACCEPT: 6, + + // Transport layer protocol -- algorithm negotiation (20-29) + KEXINIT: 20, + NEWKEYS: 21, + + // Transport layer protocol -- key exchange method-specific (30-49) + + // User auth protocol -- generic (50-59) + USERAUTH_REQUEST: 50, + USERAUTH_FAILURE: 51, + USERAUTH_SUCCESS: 52, + USERAUTH_BANNER: 53, + + // User auth protocol -- user auth method-specific (60-79) + + // Connection protocol -- generic (80-89) + GLOBAL_REQUEST: 80, + REQUEST_SUCCESS: 81, + REQUEST_FAILURE: 82, + + // Connection protocol -- channel-related (90-127) + CHANNEL_OPEN: 90, + CHANNEL_OPEN_CONFIRMATION: 91, + CHANNEL_OPEN_FAILURE: 92, + CHANNEL_WINDOW_ADJUST: 93, + CHANNEL_DATA: 94, + CHANNEL_EXTENDED_DATA: 95, + CHANNEL_EOF: 96, + CHANNEL_CLOSE: 97, + CHANNEL_REQUEST: 98, + CHANNEL_SUCCESS: 99, + CHANNEL_FAILURE: 100 + + // Reserved for client protocols (128-191) + + // Local extensions (192-155) +}; +for (i = 0, keys = Object.keys(MESSAGE), len = keys.length; i < len; ++i) + MESSAGE[MESSAGE[keys[i]]] = keys[i]; +// context-specific message codes: +MESSAGE.KEXDH_INIT = 30; +MESSAGE.KEXDH_REPLY = 31; +MESSAGE.KEXDH_GEX_REQUEST = 34; +MESSAGE.KEXDH_GEX_GROUP = 31; +MESSAGE.KEXDH_GEX_INIT = 32; +MESSAGE.KEXDH_GEX_REPLY = 33; +MESSAGE.KEXECDH_INIT = 30; // included here for completeness +MESSAGE.KEXECDH_REPLY = 31; // included here for completeness +MESSAGE.USERAUTH_PASSWD_CHANGEREQ = 60; +MESSAGE.USERAUTH_PK_OK = 60; +MESSAGE.USERAUTH_INFO_REQUEST = 60; +MESSAGE.USERAUTH_INFO_RESPONSE = 61; + +var DYNAMIC_KEXDH_MESSAGE = exports.DYNAMIC_KEXDH_MESSAGE = {}; +DYNAMIC_KEXDH_MESSAGE[MESSAGE.KEXDH_GEX_GROUP] = 'KEXDH_GEX_GROUP'; +DYNAMIC_KEXDH_MESSAGE[MESSAGE.KEXDH_GEX_REPLY] = 'KEXDH_GEX_REPLY'; + +var KEXDH_MESSAGE = exports.KEXDH_MESSAGE = {}; +KEXDH_MESSAGE[MESSAGE.KEXDH_INIT] = 'KEXDH_INIT'; +KEXDH_MESSAGE[MESSAGE.KEXDH_REPLY] = 'KEXDH_REPLY'; + +var DISCONNECT_REASON = exports.DISCONNECT_REASON = { + HOST_NOT_ALLOWED_TO_CONNECT: 1, + PROTOCOL_ERROR: 2, + KEY_EXCHANGE_FAILED: 3, + RESERVED: 4, + MAC_ERROR: 5, + COMPRESSION_ERROR: 6, + SERVICE_NOT_AVAILABLE: 7, + PROTOCOL_VERSION_NOT_SUPPORTED: 8, + HOST_KEY_NOT_VERIFIABLE: 9, + CONNECTION_LOST: 10, + BY_APPLICATION: 11, + TOO_MANY_CONNECTIONS: 12, + AUTH_CANCELED_BY_USER: 13, + NO_MORE_AUTH_METHODS_AVAILABLE: 14, + ILLEGAL_USER_NAME: 15 +}; +for (i = 0, keys = Object.keys(DISCONNECT_REASON), len = keys.length; + i < len; + ++i) { + DISCONNECT_REASON[DISCONNECT_REASON[keys[i]]] = keys[i]; +} + +var CHANNEL_OPEN_FAILURE = exports.CHANNEL_OPEN_FAILURE = { + ADMINISTRATIVELY_PROHIBITED: 1, + CONNECT_FAILED: 2, + UNKNOWN_CHANNEL_TYPE: 3, + RESOURCE_SHORTAGE: 4 +}; +for (i = 0, keys = Object.keys(CHANNEL_OPEN_FAILURE), len = keys.length; + i < len; + ++i) { + CHANNEL_OPEN_FAILURE[CHANNEL_OPEN_FAILURE[keys[i]]] = keys[i]; +} + +var TERMINAL_MODE = exports.TERMINAL_MODE = { + TTY_OP_END: 0, // Indicates end of options. + VINTR: 1, // Interrupt character; 255 if none. Similarly for the + // other characters. Not all of these characters are + // supported on all systems. + VQUIT: 2, // The quit character (sends SIGQUIT signal on POSIX + // systems). + VERASE: 3, // Erase the character to left of the cursor. + VKILL: 4, // Kill the current input line. + VEOF: 5, // End-of-file character (sends EOF from the terminal). + VEOL: 6, // End-of-line character in addition to carriage return + // and/or linefeed. + VEOL2: 7, // Additional end-of-line character. + VSTART: 8, // Continues paused output (normally control-Q). + VSTOP: 9, // Pauses output (normally control-S). + VSUSP: 10, // Suspends the current program. + VDSUSP: 11, // Another suspend character. + VREPRINT: 12, // Reprints the current input line. + VWERASE: 13, // Erases a word left of cursor. + VLNEXT: 14, // Enter the next character typed literally, even if it + // is a special character + VFLUSH: 15, // Character to flush output. + VSWTCH: 16, // Switch to a different shell layer. + VSTATUS: 17, // Prints system status line (load, command, pid, etc). + VDISCARD: 18, // Toggles the flushing of terminal output. + IGNPAR: 30, // The ignore parity flag. The parameter SHOULD be 0 + // if this flag is FALSE, and 1 if it is TRUE. + PARMRK: 31, // Mark parity and framing errors. + INPCK: 32, // Enable checking of parity errors. + ISTRIP: 33, // Strip 8th bit off characters. + INLCR: 34, // Map NL into CR on input. + IGNCR: 35, // Ignore CR on input. + ICRNL: 36, // Map CR to NL on input. + IUCLC: 37, // Translate uppercase characters to lowercase. + IXON: 38, // Enable output flow control. + IXANY: 39, // Any char will restart after stop. + IXOFF: 40, // Enable input flow control. + IMAXBEL: 41, // Ring bell on input queue full. + ISIG: 50, // Enable signals INTR, QUIT, [D]SUSP. + ICANON: 51, // Canonicalize input lines. + XCASE: 52, // Enable input and output of uppercase characters by + // preceding their lowercase equivalents with "\". + ECHO: 53, // Enable echoing. + ECHOE: 54, // Visually erase chars. + ECHOK: 55, // Kill character discards current line. + ECHONL: 56, // Echo NL even if ECHO is off. + NOFLSH: 57, // Don't flush after interrupt. + TOSTOP: 58, // Stop background jobs from output. + IEXTEN: 59, // Enable extensions. + ECHOCTL: 60, // Echo control characters as ^(Char). + ECHOKE: 61, // Visual erase for line kill. + PENDIN: 62, // Retype pending input. + OPOST: 70, // Enable output processing. + OLCUC: 71, // Convert lowercase to uppercase. + ONLCR: 72, // Map NL to CR-NL. + OCRNL: 73, // Translate carriage return to newline (output). + ONOCR: 74, // Translate newline to carriage return-newline + // (output). + ONLRET: 75, // Newline performs a carriage return (output). + CS7: 90, // 7 bit mode. + CS8: 91, // 8 bit mode. + PARENB: 92, // Parity enable. + PARODD: 93, // Odd parity, else even. + TTY_OP_ISPEED: 128, // Specifies the input baud rate in bits per second. + TTY_OP_OSPEED: 129 // Specifies the output baud rate in bits per second. +}; +for (i = 0, keys = Object.keys(TERMINAL_MODE), len = keys.length; i < len; ++i) + TERMINAL_MODE[TERMINAL_MODE[keys[i]]] = keys[i]; + +var CHANNEL_EXTENDED_DATATYPE = exports.CHANNEL_EXTENDED_DATATYPE = { + STDERR: 1 +}; +for (i = 0, keys = Object.keys(CHANNEL_EXTENDED_DATATYPE), len = keys.length; + i < len; + ++i) { + CHANNEL_EXTENDED_DATATYPE[CHANNEL_EXTENDED_DATATYPE[keys[i]]] = keys[i]; +} + +exports.SIGNALS = ['ABRT', 'ALRM', 'FPE', 'HUP', 'ILL', 'INT', + 'QUIT', 'SEGV', 'TERM', 'USR1', 'USR2', 'KILL', + 'PIPE']; + +var DEFAULT_KEX = [ + 'diffie-hellman-group14-sha1' // REQUIRED +]; +var SUPPORTED_KEX = [ + 'diffie-hellman-group1-sha1' // REQUIRED +]; +if (semver.gte(process.version, '0.11.12')) { + // https://tools.ietf.org/html/rfc4419#section-4 + DEFAULT_KEX = [ + 'diffie-hellman-group-exchange-sha256' + ].concat(DEFAULT_KEX); + SUPPORTED_KEX = [ + 'diffie-hellman-group-exchange-sha1' + ].concat(SUPPORTED_KEX); +} +if (semver.gte(process.version, '0.11.14')) { + // https://tools.ietf.org/html/rfc5656#section-10.1 + DEFAULT_KEX = [ + 'ecdh-sha2-nistp256', + 'ecdh-sha2-nistp384', + 'ecdh-sha2-nistp521' + ].concat(DEFAULT_KEX); +} +var KEX_BUF = new Buffer(DEFAULT_KEX.join(','), 'ascii'); +SUPPORTED_KEX = DEFAULT_KEX.concat(SUPPORTED_KEX); + +var DEFAULT_SERVER_HOST_KEY = [ + 'ssh-rsa' +]; +var SUPPORTED_SERVER_HOST_KEY = [ + 'ssh-dss' +]; +if (semver.gte(process.version, '5.2.0')) { + // ECDSA keys are only supported in v5.2.0+ because of a crypto change that + // made it possible to (efficiently) generate an ECDSA public key from a + // private key (commit nodejs/node#da5ac55c83eb2c09cfb3baf7875529e8f1113529) + DEFAULT_SERVER_HOST_KEY.push( + 'ecdsa-sha2-nistp256', + 'ecdsa-sha2-nistp384', + 'ecdsa-sha2-nistp521' + ); +} +var SERVER_HOST_KEY_BUF = new Buffer(DEFAULT_SERVER_HOST_KEY.join(','), + 'ascii'); +SUPPORTED_SERVER_HOST_KEY = DEFAULT_SERVER_HOST_KEY.concat( + SUPPORTED_SERVER_HOST_KEY +); + +var DEFAULT_CIPHER = []; +var SUPPORTED_CIPHER = [ + 'aes256-cbc', + 'aes192-cbc', + 'aes128-cbc', + 'blowfish-cbc', + '3des-cbc', + + // http://tools.ietf.org/html/rfc4345#section-4: + 'arcfour256', + 'arcfour128', + + 'cast128-cbc', + 'arcfour' +]; +if (semver.gte(process.version, '0.11.12')) { + // node v0.11.12 introduced support for setting AAD, which is needed for + // AES-GCM in SSH2 + DEFAULT_CIPHER = [ + // http://tools.ietf.org/html/rfc5647 + 'aes128-gcm', + 'aes128-gcm@openssh.com', + 'aes256-gcm', + 'aes256-gcm@openssh.com' + ].concat(DEFAULT_CIPHER); +} +DEFAULT_CIPHER = [ + // http://tools.ietf.org/html/rfc4344#section-4 + 'aes128-ctr', + 'aes192-ctr', + 'aes256-ctr' +].concat(DEFAULT_CIPHER); +var CIPHER_BUF = new Buffer(DEFAULT_CIPHER.join(','), 'ascii'); +SUPPORTED_CIPHER = DEFAULT_CIPHER.concat(SUPPORTED_CIPHER); + +var DEFAULT_HMAC = [ + 'hmac-sha2-256', + 'hmac-sha2-512', + 'hmac-sha1', +]; +var SUPPORTED_HMAC = [ + 'hmac-md5', + 'hmac-sha2-256-96', // first 96 bits of HMAC-SHA256 + 'hmac-sha2-512-96', // first 96 bits of HMAC-SHA512 + 'hmac-ripemd160', + 'hmac-sha1-96', // first 96 bits of HMAC-SHA1 + 'hmac-md5-96' // first 96 bits of HMAC-MD5 +]; +var HMAC_BUF = new Buffer(DEFAULT_HMAC.join(','), 'ascii'); +SUPPORTED_HMAC = DEFAULT_HMAC.concat(SUPPORTED_HMAC); + +var DEFAULT_COMPRESS = [ + 'none', + 'zlib@openssh.com', // ZLIB (LZ77) compression, except + // compression/decompression does not start until after + // successful user authentication + 'zlib' // ZLIB (LZ77) compression +]; +var SUPPORTED_COMPRESS = []; +var COMPRESS_BUF = new Buffer(DEFAULT_COMPRESS.join(','), 'ascii'); +SUPPORTED_COMPRESS = DEFAULT_COMPRESS.concat(SUPPORTED_COMPRESS); + +exports.ALGORITHMS = { + KEX: DEFAULT_KEX, + KEX_BUF: KEX_BUF, + SUPPORTED_KEX: SUPPORTED_KEX, + + SERVER_HOST_KEY: DEFAULT_SERVER_HOST_KEY, + SERVER_HOST_KEY_BUF: SERVER_HOST_KEY_BUF, + SUPPORTED_SERVER_HOST_KEY: SUPPORTED_SERVER_HOST_KEY, + + CIPHER: DEFAULT_CIPHER, + CIPHER_BUF: CIPHER_BUF, + SUPPORTED_CIPHER: SUPPORTED_CIPHER, + + HMAC: DEFAULT_HMAC, + HMAC_BUF: HMAC_BUF, + SUPPORTED_HMAC: SUPPORTED_HMAC, + + COMPRESS: DEFAULT_COMPRESS, + COMPRESS_BUF: COMPRESS_BUF, + SUPPORTED_COMPRESS: SUPPORTED_COMPRESS +}; +exports.SSH_TO_OPENSSL = { + // ECDH key exchange + 'ecdh-sha2-nistp256': 'prime256v1', // OpenSSL's name for 'secp256r1' + 'ecdh-sha2-nistp384': 'secp384r1', + 'ecdh-sha2-nistp521': 'secp521r1', + // Ciphers + 'aes128-gcm': 'aes-128-gcm', + 'aes256-gcm': 'aes-256-gcm', + 'aes128-gcm@openssh.com': 'aes-128-gcm', + 'aes256-gcm@openssh.com': 'aes-256-gcm', + '3des-cbc': 'des-ede3-cbc', + 'blowfish-cbc': 'bf-cbc', + 'aes256-cbc': 'aes-256-cbc', + 'aes192-cbc': 'aes-192-cbc', + 'aes128-cbc': 'aes-128-cbc', + 'idea-cbc': 'idea-cbc', + 'cast128-cbc': 'cast-cbc', + 'rijndael-cbc@lysator.liu.se': 'aes-256-cbc', + 'arcfour128': 'rc4', + 'arcfour256': 'rc4', + 'arcfour512': 'rc4', + 'arcfour': 'rc4', + 'camellia128-cbc': 'camellia-128-cbc', + 'camellia192-cbc': 'camellia-192-cbc', + 'camellia256-cbc': 'camellia-256-cbc', + 'camellia128-cbc@openssh.com': 'camellia-128-cbc', + 'camellia192-cbc@openssh.com': 'camellia-192-cbc', + 'camellia256-cbc@openssh.com': 'camellia-256-cbc', + '3des-ctr': 'des-ede3', + 'blowfish-ctr': 'bf-ecb', + 'aes256-ctr': 'aes-256-ctr', + 'aes192-ctr': 'aes-192-ctr', + 'aes128-ctr': 'aes-128-ctr', + 'cast128-ctr': 'cast5-ecb', + 'camellia128-ctr': 'camellia-128-ecb', + 'camellia192-ctr': 'camellia-192-ecb', + 'camellia256-ctr': 'camellia-256-ecb', + 'camellia128-ctr@openssh.com': 'camellia-128-ecb', + 'camellia192-ctr@openssh.com': 'camellia-192-ecb', + 'camellia256-ctr@openssh.com': 'camellia-256-ecb', + // HMAC + 'hmac-sha1-96': 'sha1', + 'hmac-sha1': 'sha1', + 'hmac-sha2-256': 'sha256', + 'hmac-sha2-256-96': 'sha256', + 'hmac-sha2-512': 'sha512', + 'hmac-sha2-512-96': 'sha512', + 'hmac-md5-96': 'md5', + 'hmac-md5': 'md5', + 'hmac-ripemd160': 'ripemd160' +}; + +var BUGS = exports.BUGS = { + BAD_DHGEX: 1, + OLD_EXIT: 2, + DYN_RPORT_BUG: 4 +}; + +exports.BUGGY_IMPLS = [ + [ 'Cisco-1.25', BUGS.BAD_DHGEX ], + [ /^[0-9.]+$/, BUGS.OLD_EXIT ], // old SSH.com implementations + [ /^OpenSSH_5\.\d+/, BUGS.DYN_RPORT_BUG ] +]; diff --git a/node_modules/ssh2-streams/lib/jsbn.js b/node_modules/ssh2-streams/lib/jsbn.js new file mode 100644 index 0000000..309fe0d --- /dev/null +++ b/node_modules/ssh2-streams/lib/jsbn.js @@ -0,0 +1,1186 @@ +// Copyright (c) 2005 Tom Wu +// All Rights Reserved. +// See "LICENSE" for details. + +// Basic JavaScript BN library - subset useful for RSA encryption. + +// Bits per digit +var dbits; + +// JavaScript engine analysis +var canary = 0xdeadbeefcafe; +var j_lm = ((canary&0xffffff)==0xefcafe); + +// (public) Constructor +function BigInteger(a,b,c) { + if(a != null) + if("number" == typeof a) this.fromNumber(a,b,c); + else if(b == null && "string" != typeof a) this.fromString(a,256); + else this.fromString(a,b); +} + +// return new, unset BigInteger +function nbi() { return new BigInteger(null); } + +// am: Compute w_j += (x*this_i), propagate carries, +// c is initial carry, returns final carry. +// c < 3*dvalue, x < 2*dvalue, this_i < dvalue +// We need to select the fastest one that works in this environment. + +// Set max digit bits to 28 since some +// browsers slow down when dealing with 32-bit numbers. +function am3(i,x,w,j,c,n) { + var xl = x&0x3fff, xh = x>>14; + while(--n >= 0) { + var l = this[i]&0x3fff; + var h = this[i++]>>14; + var m = xh*l+h*xl; + l = xl*l+((m&0x3fff)<<14)+w[j]+c; + c = (l>>28)+(m>>14)+xh*h; + w[j++] = l&0xfffffff; + } + return c; +} +BigInteger.prototype.am = am3; +dbits = 28; + +BigInteger.prototype.DB = dbits; +BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; +} + +// (protected) set from integer value x, -DV <= x < DV +function bnpFromInt(x) { + this.t = 1; + this.s = (x<0)?-1:0; + if(x > 0) this[0] = x; + else if(x < -1) this[0] = x+this.DV; + else this.t = 0; +} + +// return bigint initialized to value +function nbv(i) { var r = nbi(); r.fromInt(i); return r; } + +// (protected) set from string and radix +function bnpFromString(s,b) { + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 256) k = 8; // byte array + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else { this.fromRadix(s,b); return; } + this.t = 0; + this.s = 0; + var i = s.length, mi = false, sh = 0; + while(--i >= 0) { + var x = (k==8)?s[i]&0xff:intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if(sh == 0) + this[this.t++] = x; + else if(sh+k > this.DB) { + this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); + } + else + this[this.t-1] |= x<= this.DB) sh -= this.DB; + } + if(k == 8 && (s[0]&0x80) != 0) { + this.s = -1; + if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; +} + +// (public) return string representation in given radix +function bnToString(b) { + if(this.s < 0) return "-"+this.negate().toString(b); + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else return this.toRadix(b); + var km = (1< 0) { + if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } + while(i >= 0) { + if(p < k) { + d = (this[i]&((1<>(p+=this.DB-k); + } + else { + d = (this[i]>>(p-=k))&km; + if(p <= 0) { p += this.DB; --i; } + } + if(d > 0) m = true; + if(m) r += int2char(d); + } + } + return m?r:"0"; +} + +// (public) -this +function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } + +// (public) |this| +function bnAbs() { return (this.s<0)?this.negate():this; } + +// (public) return + if this > a, - if this < a, 0 if equal +function bnCompareTo(a) { + var r = this.s-a.s; + if(r != 0) return r; + var i = this.t; + r = i-a.t; + if(r != 0) return (this.s<0)?-r:r; + while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; + return 0; +} + +// returns bit length of the integer x +function nbits(x) { + var r = 1, t; + if((t=x>>>16) != 0) { x = t; r += 16; } + if((t=x>>8) != 0) { x = t; r += 8; } + if((t=x>>4) != 0) { x = t; r += 4; } + if((t=x>>2) != 0) { x = t; r += 2; } + if((t=x>>1) != 0) { x = t; r += 1; } + return r; +} + +// (public) return the number of bits in "this" +function bnBitLength() { + if(this.t <= 0) return 0; + return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); +} + +// (protected) r = this << n*DB +function bnpDLShiftTo(n,r) { + var i; + for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; + for(i = n-1; i >= 0; --i) r[i] = 0; + r.t = this.t+n; + r.s = this.s; +} + +// (protected) r = this >> n*DB +function bnpDRShiftTo(n,r) { + for(var i = n; i < this.t; ++i) r[i-n] = this[i]; + r.t = Math.max(this.t-n,0); + r.s = this.s; +} + +// (protected) r = this << n +function bnpLShiftTo(n,r) { + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<= 0; --i) { + r[i+ds+1] = (this[i]>>cbs)|c; + c = (this[i]&bm)<= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t+ds+1; + r.s = this.s; + r.clamp(); +} + +// (protected) r = this >> n +function bnpRShiftTo(n,r) { + r.s = this.s; + var ds = Math.floor(n/this.DB); + if(ds >= this.t) { r.t = 0; return; } + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<>bs; + for(var i = ds+1; i < this.t; ++i) { + r[i-ds-1] |= (this[i]&bm)<>bs; + } + if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; + } + if(a.t < this.t) { + c -= a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c -= a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c<0)?-1:0; + if(c < -1) r[i++] = this.DV+c; + else if(c > 0) r[i++] = c; + r.t = i; + r.clamp(); +} + +// (protected) r = this * a, r != this,a (HAC 14.12) +// "this" should be the larger one if appropriate. +function bnpMultiplyTo(a,r) { + var x = this.abs(), y = a.abs(); + var i = x.t; + r.t = i+y.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); + r.s = 0; + r.clamp(); + if(this.s != a.s) BigInteger.ZERO.subTo(r,r); +} + +// (protected) r = this^2, r != this (HAC 14.16) +function bnpSquareTo(r) { + var x = this.abs(); + var i = r.t = 2*x.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < x.t-1; ++i) { + var c = x.am(i,x[i],r,2*i,0,1); + if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { + r[i+x.t] -= x.DV; + r[i+x.t+1] = 1; + } + } + if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); + r.s = 0; + r.clamp(); +} + +// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) +// r != q, this != m. q or r may be null. +function bnpDivRemTo(m,q,r) { + var pm = m.abs(); + if(pm.t <= 0) return; + var pt = this.abs(); + if(pt.t < pm.t) { + if(q != null) q.fromInt(0); + if(r != null) this.copyTo(r); + return; + } + if(r == null) r = nbi(); + var y = nbi(), ts = this.s, ms = m.s; + var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus + if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } + else { pm.copyTo(y); pt.copyTo(r); } + var ys = y.t; + var y0 = y[ys-1]; + if(y0 == 0) return; + var yt = y0*(1<1)?y[ys-2]>>this.F2:0); + var d1 = this.FV/yt, d2 = (1<= 0) { + r[r.t++] = 1; + r.subTo(t,r); + } + BigInteger.ONE.dlShiftTo(ys,t); + t.subTo(y,y); // "negative" y so we can replace sub with am later + while(y.t < ys) y[y.t++] = 0; + while(--j >= 0) { + // Estimate quotient digit + var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); + if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out + y.dlShiftTo(j,t); + r.subTo(t,r); + while(r[i] < --qd) r.subTo(t,r); + } + } + if(q != null) { + r.drShiftTo(ys,q); + if(ts != ms) BigInteger.ZERO.subTo(q,q); + } + r.t = ys; + r.clamp(); + if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder + if(ts < 0) BigInteger.ZERO.subTo(r,r); +} + +// (public) this mod a +function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a,null,r); + if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); + return r; +} + +// Modular reduction using "classic" algorithm +function Classic(m) { this.m = m; } +function cConvert(x) { + if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; +} +function cRevert(x) { return x; } +function cReduce(x) { x.divRemTo(this.m,null,x); } +function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } +function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +Classic.prototype.convert = cConvert; +Classic.prototype.revert = cRevert; +Classic.prototype.reduce = cReduce; +Classic.prototype.mulTo = cMulTo; +Classic.prototype.sqrTo = cSqrTo; + +// (protected) return "-1/this % 2^DB"; useful for Mont. reduction +// justification: +// xy == 1 (mod m) +// xy = 1+km +// xy(2-xy) = (1+km)(1-km) +// x[y(2-xy)] = 1-k^2m^2 +// x[y(2-xy)] == 1 (mod m^2) +// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 +// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. +// JS multiply "overflows" differently from C/C++, so care is needed here. +function bnpInvDigit() { + if(this.t < 1) return 0; + var x = this[0]; + if((x&1) == 0) return 0; + var y = x&3; // y == 1/x mod 2^2 + y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 + y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 + y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y>0)?this.DV-y:-y; +} + +// Montgomery reduction +function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp&0x7fff; + this.mph = this.mp>>15; + this.um = (1<<(m.DB-15))-1; + this.mt2 = 2*m.t; +} + +// xR mod m +function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t,r); + r.divRemTo(this.m,null,r); + if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); + return r; +} + +// x/R mod m +function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; +} + +// x = x/R mod m (HAC 14.32) +function montReduce(x) { + while(x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for(var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i]&0x7fff; + var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; + // use am to combine the multiply-shift-add into one call + j = i+this.m.t; + x[j] += this.m.am(0,u0,x,i,0,this.m.t); + // propagate carry + while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } + } + x.clamp(); + x.drShiftTo(this.m.t,x); + if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = "x^2/R mod m"; x != r +function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = "xy/R mod m"; x,y != r +function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Montgomery.prototype.convert = montConvert; +Montgomery.prototype.revert = montRevert; +Montgomery.prototype.reduce = montReduce; +Montgomery.prototype.mulTo = montMulTo; +Montgomery.prototype.sqrTo = montSqrTo; + +// (protected) true iff this is even +function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } + +// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) +function bnpExp(e,z) { + if(e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; + g.copyTo(r); + while(--i >= 0) { + z.sqrTo(r,r2); + if((e&(1< 0) z.mulTo(r2,g,r); + else { var t = r; r = r2; r2 = t; } + } + return z.revert(r); +} + +// (public) this^e % m, 0 <= e < 2^32 +function bnModPowInt(e,m) { + var z; + if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e,z); +} + +// protected +BigInteger.prototype.copyTo = bnpCopyTo; +BigInteger.prototype.fromInt = bnpFromInt; +BigInteger.prototype.fromString = bnpFromString; +BigInteger.prototype.clamp = bnpClamp; +BigInteger.prototype.dlShiftTo = bnpDLShiftTo; +BigInteger.prototype.drShiftTo = bnpDRShiftTo; +BigInteger.prototype.lShiftTo = bnpLShiftTo; +BigInteger.prototype.rShiftTo = bnpRShiftTo; +BigInteger.prototype.subTo = bnpSubTo; +BigInteger.prototype.multiplyTo = bnpMultiplyTo; +BigInteger.prototype.squareTo = bnpSquareTo; +BigInteger.prototype.divRemTo = bnpDivRemTo; +BigInteger.prototype.invDigit = bnpInvDigit; +BigInteger.prototype.isEven = bnpIsEven; +BigInteger.prototype.exp = bnpExp; + +// public +BigInteger.prototype.toString = bnToString; +BigInteger.prototype.negate = bnNegate; +BigInteger.prototype.abs = bnAbs; +BigInteger.prototype.compareTo = bnCompareTo; +BigInteger.prototype.bitLength = bnBitLength; +BigInteger.prototype.mod = bnMod; +BigInteger.prototype.modPowInt = bnModPowInt; + +// "constants" +BigInteger.ZERO = nbv(0); +BigInteger.ONE = nbv(1); + +// Copyright (c) 2005-2009 Tom Wu +// All Rights Reserved. +// See "LICENSE" for details. + +// Extended JavaScript BN functions, required for RSA private ops. + +// Version 1.1: new BigInteger("0", 10) returns "proper" zero +// Version 1.2: square() API, isProbablePrime fix + +// (public) +function bnClone() { var r = nbi(); this.copyTo(r); return r; } + +// (public) return value as integer +function bnIntValue() { + if(this.s < 0) { + if(this.t == 1) return this[0]-this.DV; + else if(this.t == 0) return -1; + } + else if(this.t == 1) return this[0]; + else if(this.t == 0) return 0; + // assumes 16 < DB < 32 + return ((this[1]&((1<<(32-this.DB))-1))<>24; } + +// (public) return value as short (assumes DB>=16) +function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } + +// (protected) return x s.t. r^x < DV +function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } + +// (public) 0 if this == 0, 1 if this > 0 +function bnSigNum() { + if(this.s < 0) return -1; + else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else return 1; +} + +// (protected) convert to radix string +function bnpToRadix(b) { + if(b == null) b = 10; + if(this.signum() == 0 || b < 2 || b > 36) return "0"; + var cs = this.chunkSize(b); + var a = Math.pow(b,cs); + var d = nbv(a), y = nbi(), z = nbi(), r = ""; + this.divRemTo(d,y,z); + while(y.signum() > 0) { + r = (a+z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d,y,z); + } + return z.intValue().toString(b) + r; +} + +// (protected) convert from radix string +function bnpFromRadix(s,b) { + this.fromInt(0); + if(b == null) b = 10; + var cs = this.chunkSize(b); + var d = Math.pow(b,cs), mi = false, j = 0, w = 0; + for(var i = 0; i < s.length; ++i) { + var x = intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-" && this.signum() == 0) mi = true; + continue; + } + w = b*w+x; + if(++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w,0); + j = 0; + w = 0; + } + } + if(j > 0) { + this.dMultiply(Math.pow(b,j)); + this.dAddOffset(w,0); + } + if(mi) BigInteger.ZERO.subTo(this,this); +} + +// (protected) alternate constructor +function bnpFromNumber(a,b,c) { + if("number" == typeof b) { + // new BigInteger(int,int,RNG) + if(a < 2) this.fromInt(1); + else { + this.fromNumber(a,c); + if(!this.testBit(a-1)) // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); + if(this.isEven()) this.dAddOffset(1,0); // force odd + while(!this.isProbablePrime(b)) { + this.dAddOffset(2,0); + if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); + } + } + } + else { + // new BigInteger(int,RNG) + var x = new Array(), t = a&7; + x.length = (a>>3)+1; + b.nextBytes(x); + if(t > 0) x[0] &= ((1< 0) { + if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) + r[k++] = d|(this.s<<(this.DB-p)); + while(i >= 0) { + if(p < 8) { + d = (this[i]&((1<>(p+=this.DB-8); + } + else { + d = (this[i]>>(p-=8))&0xff; + if(p <= 0) { p += this.DB; --i; } + } + if((d&0x80) != 0) d |= -256; + if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; + if(k > 0 || d != this.s) r[k++] = d; + } + } + return r; +} + +function bnEquals(a) { return(this.compareTo(a)==0); } +function bnMin(a) { return(this.compareTo(a)<0)?this:a; } +function bnMax(a) { return(this.compareTo(a)>0)?this:a; } + +// (protected) r = this op a (bitwise) +function bnpBitwiseTo(a,op,r) { + var i, f, m = Math.min(a.t,this.t); + for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); + if(a.t < this.t) { + f = a.s&this.DM; + for(i = m; i < this.t; ++i) r[i] = op(this[i],f); + r.t = this.t; + } + else { + f = this.s&this.DM; + for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); + r.t = a.t; + } + r.s = op(this.s,a.s); + r.clamp(); +} + +// (public) this & a +function op_and(x,y) { return x&y; } +function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } + +// (public) this | a +function op_or(x,y) { return x|y; } +function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } + +// (public) this ^ a +function op_xor(x,y) { return x^y; } +function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } + +// (public) this & ~a +function op_andnot(x,y) { return x&~y; } +function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } + +// (public) ~this +function bnNot() { + var r = nbi(); + for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; + r.t = this.t; + r.s = ~this.s; + return r; +} + +// (public) this << n +function bnShiftLeft(n) { + var r = nbi(); + if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); + return r; +} + +// (public) this >> n +function bnShiftRight(n) { + var r = nbi(); + if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); + return r; +} + +// return index of lowest 1-bit in x, x < 2^31 +function lbit(x) { + if(x == 0) return -1; + var r = 0; + if((x&0xffff) == 0) { x >>= 16; r += 16; } + if((x&0xff) == 0) { x >>= 8; r += 8; } + if((x&0xf) == 0) { x >>= 4; r += 4; } + if((x&3) == 0) { x >>= 2; r += 2; } + if((x&1) == 0) ++r; + return r; +} + +// (public) returns index of lowest 1-bit (or -1 if none) +function bnGetLowestSetBit() { + for(var i = 0; i < this.t; ++i) + if(this[i] != 0) return i*this.DB+lbit(this[i]); + if(this.s < 0) return this.t*this.DB; + return -1; +} + +// return number of 1 bits in x +function cbit(x) { + var r = 0; + while(x != 0) { x &= x-1; ++r; } + return r; +} + +// (public) return number of set bits +function bnBitCount() { + var r = 0, x = this.s&this.DM; + for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); + return r; +} + +// (public) true iff nth bit is set +function bnTestBit(n) { + var j = Math.floor(n/this.DB); + if(j >= this.t) return(this.s!=0); + return((this[j]&(1<<(n%this.DB)))!=0); +} + +// (protected) this op (1<>= this.DB; + } + if(a.t < this.t) { + c += a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c += a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = (c<0)?-1:0; + if(c > 0) r[i++] = c; + else if(c < -1) r[i++] = this.DV+c; + r.t = i; + r.clamp(); +} + +// (public) this + a +function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } + +// (public) this - a +function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } + +// (public) this * a +function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } + +// (public) this^2 +function bnSquare() { var r = nbi(); this.squareTo(r); return r; } + +// (public) this / a +function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } + +// (public) this % a +function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } + +// (public) [this/a,this%a] +function bnDivideAndRemainder(a) { + var q = nbi(), r = nbi(); + this.divRemTo(a,q,r); + return new Array(q,r); +} + +// (protected) this *= n, this >= 0, 1 < n < DV +function bnpDMultiply(n) { + this[this.t] = this.am(0,n-1,this,0,0,this.t); + ++this.t; + this.clamp(); +} + +// (protected) this += n << w words, this >= 0 +function bnpDAddOffset(n,w) { + if(n == 0) return; + while(this.t <= w) this[this.t++] = 0; + this[w] += n; + while(this[w] >= this.DV) { + this[w] -= this.DV; + if(++w >= this.t) this[this.t++] = 0; + ++this[w]; + } +} + +// A "null" reducer +function NullExp() {} +function nNop(x) { return x; } +function nMulTo(x,y,r) { x.multiplyTo(y,r); } +function nSqrTo(x,r) { x.squareTo(r); } + +NullExp.prototype.convert = nNop; +NullExp.prototype.revert = nNop; +NullExp.prototype.mulTo = nMulTo; +NullExp.prototype.sqrTo = nSqrTo; + +// (public) this^e +function bnPow(e) { return this.exp(e,new NullExp()); } + +// (protected) r = lower n words of "this * a", a.t <= n +// "this" should be the larger one if appropriate. +function bnpMultiplyLowerTo(a,n,r) { + var i = Math.min(this.t+a.t,n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while(i > 0) r[--i] = 0; + var j; + for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); + for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); + r.clamp(); +} + +// (protected) r = "this * a" without lower n words, n > 0 +// "this" should be the larger one if appropriate. +function bnpMultiplyUpperTo(a,n,r) { + --n; + var i = r.t = this.t+a.t-n; + r.s = 0; // assumes a,this >= 0 + while(--i >= 0) r[i] = 0; + for(i = Math.max(n-this.t,0); i < a.t; ++i) + r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); + r.clamp(); + r.drShiftTo(1,r); +} + +// Barrett modular reduction +function Barrett(m) { + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2*m.t,this.r2); + this.mu = this.r2.divide(m); + this.m = m; +} + +function barrettConvert(x) { + if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); + else if(x.compareTo(this.m) < 0) return x; + else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } +} + +function barrettRevert(x) { return x; } + +// x = x mod m (HAC 14.42) +function barrettReduce(x) { + x.drShiftTo(this.m.t-1,this.r2); + if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } + this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); + this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); + while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); + x.subTo(this.r2,x); + while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = x^2 mod m; x != r +function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = x*y mod m; x,y != r +function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Barrett.prototype.convert = barrettConvert; +Barrett.prototype.revert = barrettRevert; +Barrett.prototype.reduce = barrettReduce; +Barrett.prototype.mulTo = barrettMulTo; +Barrett.prototype.sqrTo = barrettSqrTo; + +// (public) this^e % m (HAC 14.85) +function bnModPow(e,m) { + var i = e.bitLength(), k, r = nbv(1), z; + if(i <= 0) return r; + else if(i < 18) k = 1; + else if(i < 48) k = 3; + else if(i < 144) k = 4; + else if(i < 768) k = 5; + else k = 6; + if(i < 8) + z = new Classic(m); + else if(m.isEven()) + z = new Barrett(m); + else + z = new Montgomery(m); + + // precomputation + var g = new Array(), n = 3, k1 = k-1, km = (1< 1) { + var g2 = nbi(); + z.sqrTo(g[1],g2); + while(n <= km) { + g[n] = nbi(); + z.mulTo(g2,g[n-2],g[n]); + n += 2; + } + } + + var j = e.t-1, w, is1 = true, r2 = nbi(), t; + i = nbits(e[j])-1; + while(j >= 0) { + if(i >= k1) w = (e[j]>>(i-k1))&km; + else { + w = (e[j]&((1<<(i+1))-1))<<(k1-i); + if(j > 0) w |= e[j-1]>>(this.DB+i-k1); + } + + n = k; + while((w&1) == 0) { w >>= 1; --n; } + if((i -= n) < 0) { i += this.DB; --j; } + if(is1) { // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } + else { + while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } + if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } + z.mulTo(r2,g[w],r); + } + + while(j >= 0 && (e[j]&(1< 0) { + x.rShiftTo(g,x); + y.rShiftTo(g,y); + } + while(x.signum() > 0) { + if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); + if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); + if(x.compareTo(y) >= 0) { + x.subTo(y,x); + x.rShiftTo(1,x); + } + else { + y.subTo(x,y); + y.rShiftTo(1,y); + } + } + if(g > 0) y.lShiftTo(g,y); + return y; +} + +// (protected) this % n, n < 2^26 +function bnpModInt(n) { + if(n <= 0) return 0; + var d = this.DV%n, r = (this.s<0)?n-1:0; + if(this.t > 0) + if(d == 0) r = this[0]%n; + else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; + return r; +} + +// (public) 1/this % m (HAC 14.61) +function bnModInverse(m) { + var ac = m.isEven(); + if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + var u = m.clone(), v = this.clone(); + var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); + while(u.signum() != 0) { + while(u.isEven()) { + u.rShiftTo(1,u); + if(ac) { + if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } + a.rShiftTo(1,a); + } + else if(!b.isEven()) b.subTo(m,b); + b.rShiftTo(1,b); + } + while(v.isEven()) { + v.rShiftTo(1,v); + if(ac) { + if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } + c.rShiftTo(1,c); + } + else if(!d.isEven()) d.subTo(m,d); + d.rShiftTo(1,d); + } + if(u.compareTo(v) >= 0) { + u.subTo(v,u); + if(ac) a.subTo(c,a); + b.subTo(d,b); + } + else { + v.subTo(u,v); + if(ac) c.subTo(a,c); + d.subTo(b,d); + } + } + if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; + if(d.compareTo(m) >= 0) return d.subtract(m); + if(d.signum() < 0) d.addTo(m,d); else return d; + if(d.signum() < 0) return d.add(m); else return d; +} + +var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; +var lplim = (1<<26)/lowprimes[lowprimes.length-1]; + +// (public) test primality with certainty >= 1-.5^t +function bnIsProbablePrime(t) { + var i, x = this.abs(); + if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { + for(i = 0; i < lowprimes.length; ++i) + if(x[0] == lowprimes[i]) return true; + return false; + } + if(x.isEven()) return false; + i = 1; + while(i < lowprimes.length) { + var m = lowprimes[i], j = i+1; + while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + m = x.modInt(m); + while(i < j) if(m%lowprimes[i++] == 0) return false; + } + return x.millerRabin(t); +} + +// (protected) true if probably prime (HAC 4.24, Miller-Rabin) +function bnpMillerRabin(t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if(k <= 0) return false; + var r = n1.shiftRight(k); + t = (t+1)>>1; + if(t > lowprimes.length) t = lowprimes.length; + var a = nbi(); + for(var i = 0; i < t; ++i) { + //Pick bases at random, instead of starting at 2 + a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]); + var y = a.modPow(r,this); + if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while(j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2,this); + if(y.compareTo(BigInteger.ONE) == 0) return false; + } + if(y.compareTo(n1) != 0) return false; + } + } + return true; +} + +// protected +BigInteger.prototype.chunkSize = bnpChunkSize; +BigInteger.prototype.toRadix = bnpToRadix; +BigInteger.prototype.fromRadix = bnpFromRadix; +BigInteger.prototype.fromNumber = bnpFromNumber; +BigInteger.prototype.bitwiseTo = bnpBitwiseTo; +BigInteger.prototype.changeBit = bnpChangeBit; +BigInteger.prototype.addTo = bnpAddTo; +BigInteger.prototype.dMultiply = bnpDMultiply; +BigInteger.prototype.dAddOffset = bnpDAddOffset; +BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; +BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; +BigInteger.prototype.modInt = bnpModInt; +BigInteger.prototype.millerRabin = bnpMillerRabin; + +// public +BigInteger.prototype.clone = bnClone; +BigInteger.prototype.intValue = bnIntValue; +BigInteger.prototype.byteValue = bnByteValue; +BigInteger.prototype.shortValue = bnShortValue; +BigInteger.prototype.signum = bnSigNum; +BigInteger.prototype.toByteArray = bnToByteArray; +BigInteger.prototype.equals = bnEquals; +BigInteger.prototype.min = bnMin; +BigInteger.prototype.max = bnMax; +BigInteger.prototype.and = bnAnd; +BigInteger.prototype.or = bnOr; +BigInteger.prototype.xor = bnXor; +BigInteger.prototype.andNot = bnAndNot; +BigInteger.prototype.not = bnNot; +BigInteger.prototype.shiftLeft = bnShiftLeft; +BigInteger.prototype.shiftRight = bnShiftRight; +BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; +BigInteger.prototype.bitCount = bnBitCount; +BigInteger.prototype.testBit = bnTestBit; +BigInteger.prototype.setBit = bnSetBit; +BigInteger.prototype.clearBit = bnClearBit; +BigInteger.prototype.flipBit = bnFlipBit; +BigInteger.prototype.add = bnAdd; +BigInteger.prototype.subtract = bnSubtract; +BigInteger.prototype.multiply = bnMultiply; +BigInteger.prototype.divide = bnDivide; +BigInteger.prototype.remainder = bnRemainder; +BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; +BigInteger.prototype.modPow = bnModPow; +BigInteger.prototype.modInverse = bnModInverse; +BigInteger.prototype.pow = bnPow; +BigInteger.prototype.gcd = bnGCD; +BigInteger.prototype.isProbablePrime = bnIsProbablePrime; + +// JSBN-specific extension +BigInteger.prototype.square = bnSquare; + +// Expose the Barrett function +BigInteger.prototype.Barrett = Barrett + +// BigInteger interfaces not implemented in jsbn: + +// BigInteger(int signum, byte[] magnitude) +// double doubleValue() +// float floatValue() +// int hashCode() +// long longValue() +// static BigInteger valueOf(long val) + +module.exports = BigInteger; + diff --git a/node_modules/ssh2-streams/lib/keyParser.js b/node_modules/ssh2-streams/lib/keyParser.js new file mode 100644 index 0000000..937f08d --- /dev/null +++ b/node_modules/ssh2-streams/lib/keyParser.js @@ -0,0 +1,239 @@ +// TODO: +// * handle multi-line header values (OpenSSH)? +// * more thorough validation? + +var utils; +var Ber = require('asn1').Ber; +var semver = require('semver'); + +var RE_PPK = /^PuTTY-User-Key-File-2: ssh-(rsa|dss)\r?\nEncryption: (aes256-cbc|none)\r?\nComment: ([^\r\n]*)\r?\nPublic-Lines: \d+\r?\n([\s\S]+?)\r?\nPrivate-Lines: \d+\r?\n([\s\S]+?)\r?\nPrivate-MAC: ([^\r\n]+)/; +var RE_HEADER_OPENSSH_PRIV = /^-----BEGIN (RSA|DSA|EC) PRIVATE KEY-----$/i; +var RE_FOOTER_OPENSSH_PRIV = /^-----END (?:RSA|DSA|EC) PRIVATE KEY-----$/i; +var RE_HEADER_OPENSSH_PUB = /^((?:(?:ssh-(rsa|dss))|ecdsa-sha2-nistp(256|384|521))(?:-cert-v0[01]@openssh.com)?) ([A-Z0-9a-z\/+=]+)(?:$|\s+([\S].*)?)$/i; +var RE_HEADER_RFC4716_PUB = /^---- BEGIN SSH2 PUBLIC KEY ----$/i; +var RE_FOOTER_RFC4716_PUB = /^---- END SSH2 PUBLIC KEY ----$/i; +var RE_HEADER_OPENSSH = /^([^:]+):\s*([\S].*)?$/i; +var RE_HEADER_RFC4716 = /^([^:]+): (.*)?$/i; + +module.exports = function(data) { + if (Buffer.isBuffer(data)) + data = data.toString('utf8'); + else if (typeof data !== 'string') + return new Error('Key data must be a Buffer or string'); + + var ret = { + fulltype: undefined, + type: undefined, + curve: undefined, + extra: undefined, + comment: undefined, + encryption: undefined, + private: undefined, + privateOrig: undefined, + public: undefined, + publicOrig: undefined + }; + var m; + var i; + var len; + + data = data.trim().split(/\r\n|\n/); + + while (!data[0].length) + data.shift(); + while (!data.slice(-1)[0].length) + data.pop(); + + var orig = data.join('\n'); + + if ((m = RE_HEADER_OPENSSH_PRIV.exec(data[0])) + && RE_FOOTER_OPENSSH_PRIV.test(data.slice(-1))) { + // OpenSSH private key + var keyType = m[1].toLowerCase(); + if (keyType === 'dsa') + keyType = 'dss'; + + if (keyType === 'ec' && semver.lt(process.version, '5.2.0')) { + return new Error( + 'EC private keys are not supported in this version of node' + ); + } + + if (!RE_HEADER_OPENSSH.test(data[1])) { + // unencrypted, no headers + var privData = new Buffer(data.slice(1, -1).join(''), 'base64'); + if (keyType !== 'ec') { + ret.fulltype = 'ssh-' + keyType; + } else { + // ECDSA + var asnReader = new Ber.Reader(privData); + asnReader.readSequence(); + asnReader.readInt(); + asnReader.readString(Ber.OctetString, true); + asnReader.readByte(); // Skip "complex" context type byte + var offset = asnReader.readLength(); // Skip context length + if (offset !== null) { + asnReader._offset = offset; + switch (asnReader.readOID()) { + case '1.2.840.10045.3.1.7': + // prime256v1/secp256r1 + ret.fulltype = 'ecdsa-sha2-nistp256'; + break; + case '1.3.132.0.34': + // secp384r1 + ret.fulltype = 'ecdsa-sha2-nistp384'; + break; + case '1.3.132.0.35': + // secp521r1 + ret.fulltype = 'ecdsa-sha2-nistp521'; + break; + } + } + if (ret.fulltype === undefined) + return new Error('Unsupported EC private key type'); + } + ret.private = privData; + } else { + // possibly encrypted, headers + for (i = 1, len = data.length; i < len; ++i) { + m = RE_HEADER_OPENSSH.exec(data[i]); + if (m) { + m[1] = m[1].toLowerCase(); + if (m[1] === 'dek-info') { + m[2] = m[2].split(','); + ret.encryption = m[2][0].toLowerCase(); + if (m[2].length > 1) + ret.extra = m[2].slice(1); + } + } else if (data[i].length) + break; + } + ret.private = new Buffer(data.slice(i, -1).join(''), 'base64'); + } + ret.type = keyType; + ret.privateOrig = new Buffer(orig); + } else if (m = RE_HEADER_OPENSSH_PUB.exec(data[0])) { + // OpenSSH public key + ret.fulltype = m[1]; + ret.type = (m[2] || 'ec').toLowerCase(); + ret.public = new Buffer(m[4], 'base64'); + ret.publicOrig = new Buffer(orig); + ret.comment = m[5]; + if (m[3]) // ECDSA only + ret.curve = 'nistp' + m[3]; + } else if (RE_HEADER_RFC4716_PUB.test(data[0]) + && RE_FOOTER_RFC4716_PUB.test(data.slice(-1))) { + if (data[1].indexOf(': ') === -1) { + // no headers + ret.public = new Buffer(data.slice(1, -1).join(''), 'base64'); + } else { + // headers + for (i = 1, len = data.length; i < len; ++i) { + if (data[i].indexOf(': ') === -1) { + if (data[i].length) + break; // start of key data + else + continue; // empty line + } + while (data[i].substr(-1) === '\\') { + if (i + 1 < len) { + data[i] = data[i].slice(0, -1) + data[i + 1]; + data.splice(i + 1, 1); + --len; + } else + return new Error('RFC4716 public key missing header continuation line'); + } + m = RE_HEADER_RFC4716.exec(data[i]); + if (m) { + m[1] = m[1].toLowerCase(); + if (m[1] === 'comment') { + ret.comment = m[2] || ''; + if (ret.comment[0] === '"' && ret.comment.substr(-1) === '"') + ret.comment = ret.comment.slice(1, -1); + } + } else + return new Error('RFC4716 public key invalid header line'); + } + ret.public = new Buffer(data.slice(i, -1).join(''), 'base64'); + } + len = ret.public.readUInt32BE(0, true); + var fulltype = ret.public.toString('ascii', 4, 4 + len); + ret.fulltype = fulltype; + if (fulltype === 'ssh-dss') + ret.type = 'dss'; + else if (fulltype === 'ssh-rsa') + ret.type = 'rsa'; + else + return new Error('Unsupported RFC4716 public key type: ' + fulltype); + ret.public = ret.public.slice(11); + ret.publicOrig = new Buffer(orig); + } else if (m = RE_PPK.exec(orig)) { + // m[1] = short type + // m[2] = encryption type + // m[3] = comment + // m[4] = base64-encoded public key data: + // for "ssh-rsa": + // string "ssh-rsa" + // mpint e (public exponent) + // mpint n (modulus) + // for "ssh-dss": + // string "ssh-dss" + // mpint p (modulus) + // mpint q (prime) + // mpint g (base number) + // mpint y (public key parameter: g^x mod p) + // m[5] = base64-encoded private key data: + // for "ssh-rsa": + // mpint d (private exponent) + // mpint p (prime 1) + // mpint q (prime 2) + // mpint iqmp ([inverse of q] mod p) + // for "ssh-dss": + // mpint x (private key parameter) + // m[6] = SHA1 HMAC over: + // string name of algorithm ("ssh-dss", "ssh-rsa") + // string encryption type + // string comment + // string public key data + // string private-plaintext (including the final padding) + + // avoid cyclic require by requiring on first use + if (!utils) + utils = require('./utils'); + + ret.ppk = true; + ret.type = m[1]; + ret.fulltype = 'ssh-' + m[1]; + if (m[2] !== 'none') + ret.encryption = m[2]; + ret.comment = m[3]; + + ret.public = new Buffer(m[4].replace(/\r?\n/g, ''), 'base64'); + var privateKey = new Buffer(m[5].replace(/\r?\n/g, ''), 'base64'); + + ret.privateMAC = m[6].replace(/\r?\n/g, ''); + + // automatically verify private key MAC if we don't need to wait for + // decryption + if (!ret.encryption) { + var valid = utils.verifyPPKMAC(ret, undefined, privateKey); + if (!valid) + throw new Error('PPK MAC mismatch'); + } + + // generate a PEM encoded version of the public key + var pubkey = utils.genPublicKey(ret); + ret.public = pubkey.public; + ret.publicOrig = pubkey.publicOrig; + + ret.private = privateKey; + + // automatically convert private key data to OpenSSL format (including PEM) + // if we don't need to wait for decryption + if (!ret.encryption) + utils.convertPPKPrivate(ret); + } else + return new Error('Unsupported key format'); + + return ret; +}; diff --git a/node_modules/ssh2-streams/lib/sftp.js b/node_modules/ssh2-streams/lib/sftp.js new file mode 100644 index 0000000..270ab84 --- /dev/null +++ b/node_modules/ssh2-streams/lib/sftp.js @@ -0,0 +1,2962 @@ +// TODO: support EXTENDED request packets + +var TransformStream = require('stream').Transform; +var ReadableStream = require('stream').Readable; +var WritableStream = require('stream').Writable; +var constants = require('fs').constants || process.binding('constants'); +var util = require('util'); +var inherits = util.inherits; +var isDate = util.isDate; +var listenerCount = require('events').EventEmitter.listenerCount; +var fs = require('fs'); + +var readString = require('./utils').readString; +var readInt = require('./utils').readInt; + +var ATTR = { + SIZE: 0x00000001, + UIDGID: 0x00000002, + PERMISSIONS: 0x00000004, + ACMODTIME: 0x00000008, + EXTENDED: 0x80000000 +}; + +var STATUS_CODE = { + OK: 0, + EOF: 1, + NO_SUCH_FILE: 2, + PERMISSION_DENIED: 3, + FAILURE: 4, + BAD_MESSAGE: 5, + NO_CONNECTION: 6, + CONNECTION_LOST: 7, + OP_UNSUPPORTED: 8 +}; +Object.keys(STATUS_CODE).forEach(function(key) { + STATUS_CODE[STATUS_CODE[key]] = key; +}); +var STATUS_CODE_STR = { + 0: 'No error', + 1: 'End of file', + 2: 'No such file or directory', + 3: 'Permission denied', + 4: 'Failure', + 5: 'Bad message', + 6: 'No connection', + 7: 'Connection lost', + 8: 'Operation unsupported' +}; +SFTPStream.STATUS_CODE = STATUS_CODE; + +var REQUEST = { + INIT: 1, + OPEN: 3, + CLOSE: 4, + READ: 5, + WRITE: 6, + LSTAT: 7, + FSTAT: 8, + SETSTAT: 9, + FSETSTAT: 10, + OPENDIR: 11, + READDIR: 12, + REMOVE: 13, + MKDIR: 14, + RMDIR: 15, + REALPATH: 16, + STAT: 17, + RENAME: 18, + READLINK: 19, + SYMLINK: 20, + EXTENDED: 200 +}; +Object.keys(REQUEST).forEach(function(key) { + REQUEST[REQUEST[key]] = key; +}); + +var RESPONSE = { + VERSION: 2, + STATUS: 101, + HANDLE: 102, + DATA: 103, + NAME: 104, + ATTRS: 105, + EXTENDED: 201 +}; +Object.keys(RESPONSE).forEach(function(key) { + RESPONSE[RESPONSE[key]] = key; +}); + +var OPEN_MODE = { + READ: 0x00000001, + WRITE: 0x00000002, + APPEND: 0x00000004, + CREAT: 0x00000008, + TRUNC: 0x00000010, + EXCL: 0x00000020 +}; +SFTPStream.OPEN_MODE = OPEN_MODE; + +var MAX_PKT_LEN = 34000; +var MAX_REQID = Math.pow(2, 32) - 1; +var CLIENT_VERSION_BUFFER = new Buffer([0, 0, 0, 5 /* length */, + REQUEST.INIT, + 0, 0, 0, 3 /* version */]); +var SERVER_VERSION_BUFFER = new Buffer([0, 0, 0, 5 /* length */, + RESPONSE.VERSION, + 0, 0, 0, 3 /* version */]); +/* + http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02: + + The maximum size of a packet is in practice determined by the client + (the maximum size of read or write requests that it sends, plus a few + bytes of packet overhead). All servers SHOULD support packets of at + least 34000 bytes (where the packet size refers to the full length, + including the header above). This should allow for reads and writes + of at most 32768 bytes. + + OpenSSH caps this to 256kb instead of the ~34kb as mentioned in the sftpv3 + spec. +*/ +var RE_OPENSSH = /^SSH-2.0-(?:OpenSSH|dropbear)/; +var OPENSSH_MAX_DATA_LEN = (256 * 1024) - (2 * 1024)/*account for header data*/; + +function DEBUG_NOOP(msg) {} + +function SFTPStream(cfg, remoteIdentRaw) { + if (typeof cfg === 'string' && !remoteIdentRaw) { + remoteIdentRaw = cfg; + cfg = undefined; + } + if (typeof cfg !== 'object' || !cfg) + cfg = {}; + + TransformStream.call(this, { + highWaterMark: (typeof cfg.highWaterMark === 'number' + ? cfg.highWaterMark + : 32 * 1024) + }); + + this.debug = (typeof cfg.debug === 'function' ? cfg.debug : DEBUG_NOOP); + this.server = (cfg.server ? true : false); + this._isOpenSSH = (remoteIdentRaw && RE_OPENSSH.test(remoteIdentRaw)); + this._needContinue = false; + this._state = { + // common + status: 'packet_header', + writeReqid: -1, + pktLeft: undefined, + pktHdrBuf: new Buffer(9), // room for pktLen + pktType + req id + pktBuf: undefined, + pktType: undefined, + version: undefined, + extensions: {}, + + // client + maxDataLen: (this._isOpenSSH ? OPENSSH_MAX_DATA_LEN : 32768), + requests: {} + }; + + var self = this; + this.on('end', function() { + self.readable = false; + }).on('finish', onFinish) + .on('prefinish', onFinish); + function onFinish() { + self.writable = false; + self._cleanup(false); + } + + if (!this.server) + this.push(CLIENT_VERSION_BUFFER); +} +inherits(SFTPStream, TransformStream); + +SFTPStream.prototype.__read = TransformStream.prototype._read; +SFTPStream.prototype._read = function(n) { + if (this._needContinue) { + this._needContinue = false; + this.emit('continue'); + } + return this.__read(n); +}; +SFTPStream.prototype.__push = TransformStream.prototype.push; +SFTPStream.prototype.push = function(chunk, encoding) { + if (!this.readable) + return false; + if (chunk === null) + this.readable = false; + var ret = this.__push(chunk, encoding); + this._needContinue = (ret === false); + return ret; +}; + +SFTPStream.prototype._cleanup = function(callback) { + var state = this._state; + + state.pktBuf = undefined; // give GC something to do + + var requests = state.requests; + var keys = Object.keys(requests); + var len = keys.length; + if (len) { + if (this.readable) { + var err = new Error('SFTP session ended early'); + for (var i = 0, cb; i < len; ++i) + (cb = requests[keys[i]].cb) && cb(err); + } + state.requests = {}; + } + + if (this.readable) + this.push(null); + else if (!this._readableState.endEmitted && !this._readableState.flowing) { + // Ugh! + this.resume(); + } + if (callback !== false) { + this.debug('DEBUG[SFTP]: Parser: Malformed packet'); + callback && callback(new Error('Malformed packet')); + } +}; + +SFTPStream.prototype._transform = function(chunk, encoding, callback) { + var state = this._state; + var server = this.server; + var status = state.status; + var pktType = state.pktType; + var pktBuf = state.pktBuf; + var pktLeft = state.pktLeft; + var version = state.version; + var pktHdrBuf = state.pktHdrBuf; + var requests = state.requests; + var debug = this.debug; + var chunkLen = chunk.length; + var chunkPos = 0; + var buffer; + var chunkLeft; + var id; + + while (true) { + if (status === 'discard') { + chunkLeft = (chunkLen - chunkPos); + if (pktLeft <= chunkLeft) { + chunkPos += pktLeft; + pktLeft = 0; + status = 'packet_header'; + buffer = pktBuf = undefined; + } else { + pktLeft -= chunkLeft; + break; + } + } else if (pktBuf !== undefined) { + chunkLeft = (chunkLen - chunkPos); + if (pktLeft <= chunkLeft) { + chunk.copy(pktBuf, + pktBuf.length - pktLeft, + chunkPos, + chunkPos + pktLeft); + chunkPos += pktLeft; + pktLeft = 0; + buffer = pktBuf; + pktBuf = undefined; + continue; + } else { + chunk.copy(pktBuf, pktBuf.length - pktLeft, chunkPos); + pktLeft -= chunkLeft; + break; + } + } else if (status === 'packet_header') { + if (!buffer) { + pktLeft = 5; + pktBuf = pktHdrBuf; + } else { + // here we read the right-most 5 bytes from buffer (pktHdrBuf) + pktLeft = buffer.readUInt32BE(4, true) - 1; // account for type byte + pktType = buffer[8]; + + if (server) { + if (version === undefined && pktType !== REQUEST.INIT) { + debug('DEBUG[SFTP]: Parser: Unexpected packet before init'); + status = 'bad_pkt'; + } else if (version !== undefined && pktType === REQUEST.INIT) { + debug('DEBUG[SFTP]: Parser: Unexpected duplicate init'); + status = 'bad_pkt'; + } else if (pktLeft > MAX_PKT_LEN) { + debug('DEBUG[SFTP]: Parser: Packet length (' + + pktLeft + + ') exceeds max length (' + + MAX_PKT_LEN + + ')'); + status = 'bad_pkt'; + } else if (pktType === REQUEST.EXTENDED) + status = 'bad_pkt'; + else if (REQUEST[pktType] === undefined) { + debug('DEBUG[SFTP]: Parser: Unsupported packet type: ' + pktType); + status = 'discard'; + } + } else if (version === undefined && pktType !== RESPONSE.VERSION) { + debug('DEBUG[SFTP]: Parser: Unexpected packet before version'); + status = 'bad_pkt'; + } else if (version !== undefined && pktType === RESPONSE.VERSION) { + debug('DEBUG[SFTP]: Parser: Unexpected duplicate version'); + status = 'bad_pkt'; + } else if (RESPONSE[pktType] === undefined) + status = 'discard'; + + if (status === 'bad_pkt') { + // copy original packet info + pktHdrBuf.writeUInt32BE(pktLeft, 0, true); + pktHdrBuf[4] = pktType; + + pktLeft = 4; + pktBuf = pktHdrBuf; + } else { + pktBuf = new Buffer(pktLeft); + status = 'payload'; + } + } + } else if (status === 'payload') { + if (pktType === RESPONSE.VERSION || pktType === REQUEST.INIT) { + /* + uint32 version + + */ + version = state.version = readInt(buffer, 0, this, callback); + if (version === false) + return; + if (version < 3) { + this._cleanup(); + return callback(new Error('Incompatible SFTP version: ' + version)); + } else if (server) + this.push(SERVER_VERSION_BUFFER); + + var buflen = buffer.length; + var extname; + var extdata; + buffer._pos = 4; + while (buffer._pos < buflen) { + extname = readString(buffer, buffer._pos, 'ascii', this, callback); + if (extname === false) + return; + extdata = readString(buffer, buffer._pos, 'ascii', this, callback); + if (extdata === false) + return; + if (state.extensions[extname]) + state.extensions[extname].push(extdata); + else + state.extensions[extname] = [ extdata ]; + } + + this.emit('ready'); + } else { + /* + All other packets (client and server) begin with a (client) request + id: + uint32 id + */ + id = readInt(buffer, 0, this, callback); + if (id === false) + return; + + var filename; + var attrs; + var handle; + var data; + + if (!server) { + var req = requests[id]; + var cb = req && req.cb; + debug('DEBUG[SFTP]: Parser: Response: ' + RESPONSE[pktType]); + if (req && cb) { + if (pktType === RESPONSE.STATUS) { + /* + uint32 error/status code + string error message (ISO-10646 UTF-8) + string language tag + */ + var code = readInt(buffer, 4, this, callback); + if (code === false) + return; + if (code === STATUS_CODE.OK) { + cb(); + } else { + // We borrow OpenSSH behavior here, specifically we make the + // message and language fields optional, despite the + // specification requiring them (even if they are empty). This + // helps to avoid problems with buggy implementations that do + // not fully conform to the SFTP(v3) specification. + var msg; + var lang = ''; + if (buffer.length >= 12) { + msg = readString(buffer, 8, 'utf8', this, callback); + if (msg === false) + return; + if ((buffer._pos + 4) < buffer.length) { + lang = readString(buffer, + buffer._pos, + 'ascii', + this, + callback); + if (lang === false) + return; + } + } + var err = new Error(msg + || STATUS_CODE_STR[code] + || 'Unknown status'); + err.code = code; + err.lang = lang; + cb(err); + } + } else if (pktType === RESPONSE.HANDLE) { + /* + string handle + */ + handle = readString(buffer, 4, this, callback); + if (handle === false) + return; + cb(undefined, handle); + } else if (pktType === RESPONSE.DATA) { + /* + string data + */ + if (req.buffer) { + // we have already pre-allocated space to store the data + var dataLen = readInt(buffer, 4, this, callback); + if (dataLen === false) + return; + var reqBufLen = req.buffer.length; + if (dataLen > reqBufLen) { + // truncate response data to fit expected size + buffer.writeUInt32BE(reqBufLen, 4, true); + } + data = readString(buffer, 4, req.buffer, this, callback); + if (data === false) + return; + cb(undefined, data, dataLen); + } else { + data = readString(buffer, 4, this, callback); + if (data === false) + return; + cb(undefined, data); + } + } else if (pktType === RESPONSE.NAME) { + /* + uint32 count + repeats count times: + string filename + string longname + ATTRS attrs + */ + var namesLen = readInt(buffer, 4, this, callback); + if (namesLen === false) + return; + var names = [], + longname; + buffer._pos = 8; + for (var i = 0; i < namesLen; ++i) { + // we are going to assume UTF-8 for filenames despite the SFTPv3 + // spec not specifying an encoding because the specs for newer + // versions of the protocol all explicitly specify UTF-8 for + // filenames + filename = readString(buffer, + buffer._pos, + 'utf8', + this, + callback); + if (filename === false) + return; + // `longname` only exists in SFTPv3 and since it typically will + // contain the filename, we assume it is also UTF-8 + longname = readString(buffer, + buffer._pos, + 'utf8', + this, + callback); + if (longname === false) + return; + attrs = readAttrs(buffer, buffer._pos, this, callback); + if (attrs === false) + return; + names.push({ + filename: filename, + longname: longname, + attrs: attrs + }); + } + cb(undefined, names); + } else if (pktType === RESPONSE.ATTRS) { + /* + ATTRS attrs + */ + attrs = readAttrs(buffer, 4, this, callback); + if (attrs === false) + return; + cb(undefined, attrs); + } else if (pktType === RESPONSE.EXTENDED) { + if (req.extended) { + switch (req.extended) { + case 'statvfs@openssh.com': + case 'fstatvfs@openssh.com': + /* + uint64 f_bsize // file system block size + uint64 f_frsize // fundamental fs block size + uint64 f_blocks // number of blocks (unit f_frsize) + uint64 f_bfree // free blocks in file system + uint64 f_bavail // free blocks for non-root + uint64 f_files // total file inodes + uint64 f_ffree // free file inodes + uint64 f_favail // free file inodes for to non-root + uint64 f_fsid // file system id + uint64 f_flag // bit mask of f_flag values + uint64 f_namemax // maximum filename length + */ + var stats = { + f_bsize: undefined, + f_frsize: undefined, + f_blocks: undefined, + f_bfree: undefined, + f_bavail: undefined, + f_files: undefined, + f_ffree: undefined, + f_favail: undefined, + f_sid: undefined, + f_flag: undefined, + f_namemax: undefined + }; + stats.f_bsize = readUInt64BE(buffer, 4, this, callback); + if (stats.f_bsize === false) + return; + stats.f_frsize = readUInt64BE(buffer, 12, this, callback); + if (stats.f_frsize === false) + return; + stats.f_blocks = readUInt64BE(buffer, 20, this, callback); + if (stats.f_blocks === false) + return; + stats.f_bfree = readUInt64BE(buffer, 28, this, callback); + if (stats.f_bfree === false) + return; + stats.f_bavail = readUInt64BE(buffer, 36, this, callback); + if (stats.f_bavail === false) + return; + stats.f_files = readUInt64BE(buffer, 44, this, callback); + if (stats.f_files === false) + return; + stats.f_ffree = readUInt64BE(buffer, 52, this, callback); + if (stats.f_ffree === false) + return; + stats.f_favail = readUInt64BE(buffer, 60, this, callback); + if (stats.f_favail === false) + return; + stats.f_sid = readUInt64BE(buffer, 68, this, callback); + if (stats.f_sid === false) + return; + stats.f_flag = readUInt64BE(buffer, 76, this, callback); + if (stats.f_flag === false) + return; + stats.f_namemax = readUInt64BE(buffer, 84, this, callback); + if (stats.f_namemax === false) + return; + cb(undefined, stats); + break; + } + } + // XXX: at least provide the raw buffer data to the callback in + // case of unexpected extended response? + cb(); + } + } + if (req) + delete requests[id]; + } else { + // server + var evName = REQUEST[pktType]; + var offset; + var path; + + debug('DEBUG[SFTP]: Parser: Request: ' + evName); + if (listenerCount(this, evName)) { + if (pktType === REQUEST.OPEN) { + /* + string filename + uint32 pflags + ATTRS attrs + */ + filename = readString(buffer, 4, 'utf8', this, callback); + if (filename === false) + return; + var pflags = readInt(buffer, buffer._pos, this, callback); + if (pflags === false) + return; + attrs = readAttrs(buffer, buffer._pos + 4, this, callback); + if (attrs === false) + return; + this.emit(evName, id, filename, pflags, attrs); + } else if (pktType === REQUEST.CLOSE + || pktType === REQUEST.FSTAT + || pktType === REQUEST.READDIR) { + /* + string handle + */ + handle = readString(buffer, 4, this, callback); + if (handle === false) + return; + this.emit(evName, id, handle); + } else if (pktType === REQUEST.READ) { + /* + string handle + uint64 offset + uint32 len + */ + handle = readString(buffer, 4, this, callback); + if (handle === false) + return; + offset = readUInt64BE(buffer, buffer._pos, this, callback); + if (offset === false) + return; + var len = readInt(buffer, buffer._pos, this, callback); + if (len === false) + return; + this.emit(evName, id, handle, offset, len); + } else if (pktType === REQUEST.WRITE) { + /* + string handle + uint64 offset + string data + */ + handle = readString(buffer, 4, this, callback); + if (handle === false) + return; + offset = readUInt64BE(buffer, buffer._pos, this, callback); + if (offset === false) + return; + data = readString(buffer, buffer._pos, this, callback); + if (data === false) + return; + this.emit(evName, id, handle, offset, data); + } else if (pktType === REQUEST.LSTAT + || pktType === REQUEST.STAT + || pktType === REQUEST.OPENDIR + || pktType === REQUEST.REMOVE + || pktType === REQUEST.RMDIR + || pktType === REQUEST.REALPATH + || pktType === REQUEST.READLINK) { + /* + string path + */ + path = readString(buffer, 4, 'utf8', this, callback); + if (path === false) + return; + this.emit(evName, id, path); + } else if (pktType === REQUEST.SETSTAT + || pktType === REQUEST.MKDIR) { + /* + string path + ATTRS attrs + */ + path = readString(buffer, 4, 'utf8', this, callback); + if (path === false) + return; + attrs = readAttrs(buffer, buffer._pos, this, callback); + if (attrs === false) + return; + this.emit(evName, id, path, attrs); + } else if (pktType === REQUEST.FSETSTAT) { + /* + string handle + ATTRS attrs + */ + handle = readString(buffer, 4, this, callback); + if (handle === false) + return; + attrs = readAttrs(buffer, buffer._pos, this, callback); + if (attrs === false) + return; + this.emit(evName, id, handle, attrs); + } else if (pktType === REQUEST.RENAME + || pktType === REQUEST.SYMLINK) { + /* + RENAME: + string oldpath + string newpath + SYMLINK: + string linkpath + string targetpath + */ + var str1; + var str2; + str1 = readString(buffer, 4, 'utf8', this, callback); + if (str1 === false) + return; + str2 = readString(buffer, buffer._pos, 'utf8', this, callback); + if (str2 === false) + return; + if (pktType === REQUEST.SYMLINK && this._isOpenSSH) { + // OpenSSH has linkpath and targetpath positions switched + this.emit(evName, id, str2, str1); + } else + this.emit(evName, id, str1, str2); + } + } else { + // automatically reject request if no handler for request type + this.status(id, STATUS_CODE.OP_UNSUPPORTED); + } + } + } + + // prepare for next packet + status = 'packet_header'; + buffer = pktBuf = undefined; + } else if (status === 'bad_pkt') { + if (server && buffer[4] !== REQUEST.INIT) { + var errCode = (buffer[4] === REQUEST.EXTENDED + ? STATUS_CODE.OP_UNSUPPORTED + : STATUS_CODE.FAILURE); + + // no request id for init/version packets, so we have no way to send a + // status response, so we just close up shop ... + if (buffer[4] === REQUEST.INIT || buffer[4] === RESPONSE.VERSION) + return this._cleanup(callback); + + id = readInt(buffer, 5, this, callback); + if (id === false) + return; + this.status(id, errCode); + } + + // by this point we have already read the type byte and the id bytes, so + // we subtract those from the number of bytes to skip + pktLeft = buffer.readUInt32BE(0, true) - 5; + + status = 'discard'; + } + + if (chunkPos >= chunkLen) + break; + } + + state.status = status; + state.pktType = pktType; + state.pktBuf = pktBuf; + state.pktLeft = pktLeft; + state.version = version; + + callback(); +}; + +// client +SFTPStream.prototype.createReadStream = function(path, options) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + return new ReadStream(this, path, options); +}; +SFTPStream.prototype.createWriteStream = function(path, options) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + return new WriteStream(this, path, options); +}; +SFTPStream.prototype.open = function(path, flags_, attrs, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var state = this._state; + + if (typeof attrs === 'function') { + cb = attrs; + attrs = undefined; + } + + var flags = stringToFlags(flags_); + if (flags === null) + throw new Error('Unknown flags string: ' + flags_); + + var attrFlags = 0; + var attrBytes = 0; + if (typeof attrs === 'string' || typeof attrs === 'number') { + attrs = { mode: attrs }; + } + if (typeof attrs === 'object') { + attrs = attrsToBytes(attrs); + attrFlags = attrs.flags; + attrBytes = attrs.nbytes; + attrs = attrs.bytes; + } + + /* + uint32 id + string filename + uint32 pflags + ATTRS attrs + */ + var pathlen = Buffer.byteLength(path); + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + pathlen + 4 + 4 + attrBytes); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.OPEN; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + + buf.writeUInt32BE(pathlen, p, true); + buf.write(path, p += 4, pathlen, 'utf8'); + buf.writeUInt32BE(flags, p += pathlen, true); + buf.writeUInt32BE(attrFlags, p += 4, true); + if (attrs && attrFlags) { + p += 4; + for (var i = 0, len = attrs.length; i < len; ++i) + for (var j = 0, len2 = attrs[i].length; j < len2; ++j) + buf[p++] = attrs[i][j]; + } + state.requests[reqid] = { cb: cb }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing OPEN'); + return this.push(buf); +}; +SFTPStream.prototype.close = function(handle, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + else if (!Buffer.isBuffer(handle)) + throw new Error('handle is not a Buffer'); + + var state = this._state; + + /* + uint32 id + string handle + */ + var handlelen = handle.length; + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + handlelen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.CLOSE; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + + buf.writeUInt32BE(handlelen, p, true); + handle.copy(buf, p += 4); + + state.requests[reqid] = { cb: cb }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing CLOSE'); + return this.push(buf); +}; +SFTPStream.prototype.readData = function(handle, buf, off, len, position, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + else if (!Buffer.isBuffer(handle)) + throw new Error('handle is not a Buffer'); + else if (!Buffer.isBuffer(buf)) + throw new Error('buffer is not a Buffer'); + else if (off >= buf.length) + throw new Error('offset is out of bounds'); + else if (off + len > buf.length) + throw new Error('length extends beyond buffer'); + else if (position === null) + throw new Error('null position currently unsupported'); + + var state = this._state; + + /* + uint32 id + string handle + uint64 offset + uint32 len + */ + var handlelen = handle.length; + var p = 9; + var pos = position; + var out = new Buffer(4 + 1 + 4 + 4 + handlelen + 8 + 4); + + out.writeUInt32BE(out.length - 4, 0, true); + out[4] = REQUEST.READ; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + out.writeUInt32BE(reqid, 5, true); + + out.writeUInt32BE(handlelen, p, true); + handle.copy(out, p += 4); + p += handlelen; + for (var i = 7; i >= 0; --i) { + out[p + i] = pos & 0xFF; + pos /= 256; + } + out.writeUInt32BE(len, p += 8, true); + + state.requests[reqid] = { + cb: function(err, data, nb) { + if (err && err.code !== STATUS_CODE.EOF) + return cb(err); + cb(undefined, nb || 0, data, position); + }, + buffer: buf.slice(off, off + len) + }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing READ'); + return this.push(out); +}; +SFTPStream.prototype.writeData = function(handle, buf, off, len, position, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + else if (!Buffer.isBuffer(handle)) + throw new Error('handle is not a Buffer'); + else if (!Buffer.isBuffer(buf)) + throw new Error('buffer is not a Buffer'); + else if (off > buf.length) + throw new Error('offset is out of bounds'); + else if (off + len > buf.length) + throw new Error('length extends beyond buffer'); + else if (position === null) + throw new Error('null position currently unsupported'); + + var self = this; + var state = this._state; + + if (!len) { + cb && process.nextTick(function() { cb(undefined, 0); }); + return; + } + + var overflow = (len > state.maxDataLen + ? len - state.maxDataLen + : 0); + var origPosition = position; + + if (overflow) + len = state.maxDataLen; + + /* + uint32 id + string handle + uint64 offset + string data + */ + var handlelen = handle.length; + var p = 9; + var out = new Buffer(4 + 1 + 4 + 4 + handlelen + 8 + 4 + len); + + out.writeUInt32BE(out.length - 4, 0, true); + out[4] = REQUEST.WRITE; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + out.writeUInt32BE(reqid, 5, true); + + out.writeUInt32BE(handlelen, p, true); + handle.copy(out, p += 4); + p += handlelen; + for (var i = 7; i >= 0; --i) { + out[p + i] = position & 0xFF; + position /= 256; + } + out.writeUInt32BE(len, p += 8, true); + buf.copy(out, p += 4, off, off + len); + + state.requests[reqid] = { + cb: function(err) { + if (err) + cb && cb(err); + else if (overflow) { + self.writeData(handle, + buf, + off + len, + overflow, + origPosition + len, + cb); + } else + cb && cb(undefined, off + len); + } + }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing WRITE'); + return this.push(out); +}; +function tryCreateBuffer(size) { + try { + return new Buffer(size); + } catch (ex) { + return ex; + } +} +function fastXfer(src, dst, srcPath, dstPath, opts, cb) { + var concurrency = 64; + var chunkSize = 32768; + //var preserve = false; + var onstep; + var mode; + + if (typeof opts === 'function') { + cb = opts; + } else if (typeof opts === 'object') { + if (typeof opts.concurrency === 'number' + && opts.concurrency > 0 + && !isNaN(opts.concurrency)) + concurrency = opts.concurrency; + if (typeof opts.chunkSize === 'number' + && opts.chunkSize > 0 + && !isNaN(opts.chunkSize)) + chunkSize = opts.chunkSize; + if (typeof opts.step === 'function') + onstep = opts.step; + //preserve = (opts.preserve ? true : false); + if (typeof opts.mode === 'string' || typeof opts.mode === 'number') + mode = modeNum(opts.mode); + } + + // internal state variables + var fsize; + var chunk; + var psrc = 0; + var pdst = 0; + var reads = 0; + var total = 0; + var hadError = false; + var srcHandle; + var dstHandle; + var readbuf; + var bufsize = chunkSize * concurrency; + + function onerror(err) { + if (hadError) + return; + + hadError = true; + + var left = 0; + var cbfinal; + + if (srcHandle || dstHandle) { + cbfinal = function() { + if (--left === 0) + cb(err); + }; + if (srcHandle && (src === fs || src.writable)) + ++left; + if (dstHandle && (dst === fs || dst.writable)) + ++left; + if (srcHandle && (src === fs || src.writable)) + src.close(srcHandle, cbfinal); + if (dstHandle && (dst === fs || dst.writable)) + dst.close(dstHandle, cbfinal); + } else + cb(err); + } + + src.open(srcPath, 'r', function(err, sourceHandle) { + if (err) + return onerror(err); + + srcHandle = sourceHandle; + + src.fstat(srcHandle, function tryStat(err, attrs) { + if (err) { + if (src !== fs) { + // Try stat() for sftp servers that may not support fstat() for + // whatever reason + src.stat(srcPath, function(err_, attrs_) { + if (err_) + return onerror(err); + tryStat(null, attrs_); + }); + return; + } + return onerror(err); + } + fsize = attrs.size; + + dst.open(dstPath, 'w', function(err, destHandle) { + if (err) + return onerror(err); + + dstHandle = destHandle; + + if (fsize <= 0) + return onerror(); + + // Use less memory where possible + while (bufsize > fsize) { + if (concurrency === 1) { + bufsize = fsize; + break; + } + bufsize -= chunkSize; + --concurrency; + } + + readbuf = tryCreateBuffer(bufsize); + if (readbuf instanceof Error) + return onerror(readbuf); + + if (mode !== undefined) { + dst.fchmod(dstHandle, mode, function tryAgain(err) { + if (err) { + // Try chmod() for sftp servers that may not support fchmod() for + // whatever reason + dst.chmod(dstPath, mode, function(err_) { + tryAgain(); + }); + return; + } + read(); + }); + } else { + read(); + } + + function onread(err, nb, data, dstpos, datapos) { + if (err) + return onerror(err); + + if (src === fs) + dst.writeData(dstHandle, data, datapos || 0, nb, dstpos, writeCb); + else + dst.write(dstHandle, data, datapos || 0, nb, dstpos, writeCb); + + function writeCb(err) { + if (err) + return onerror(err); + + total += nb; + onstep && onstep(total, nb, fsize); + + if (--reads === 0) { + if (total === fsize) { + dst.close(dstHandle, function(err) { + dstHandle = undefined; + if (err) + return onerror(err); + src.close(srcHandle, function(err) { + srcHandle = undefined; + if (err) + return onerror(err); + cb(); + }); + }); + } else + read(); + } + } + } + + function makeCb(psrc, pdst) { + return function(err, nb, data) { + onread(err, nb, data, pdst, psrc); + }; + } + + function read() { + while (pdst < fsize && reads < concurrency) { + chunk = (pdst + chunkSize > fsize ? fsize - pdst : chunkSize); + if (src === fs) { + src.read(srcHandle, + readbuf, + psrc, + chunk, + pdst, + makeCb(psrc, pdst)); + } else + src.readData(srcHandle, readbuf, psrc, chunk, pdst, onread); + psrc += chunk; + pdst += chunk; + ++reads; + } + psrc = 0; + } + }); + }); + }); +} +SFTPStream.prototype.fastGet = function(remotePath, localPath, opts, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + fastXfer(this, fs, remotePath, localPath, opts, cb); +}; +SFTPStream.prototype.fastPut = function(localPath, remotePath, opts, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + fastXfer(fs, this, localPath, remotePath, opts, cb); +}; +SFTPStream.prototype.readFile = function(path, options, callback_) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var callback; + if (typeof callback_ === 'function') { + callback = callback_; + } else if (typeof options === 'function') { + callback = options; + options = undefined; + } + + var self = this; + + if (typeof options === 'string') + options = { encoding: options, flag: 'r' }; + else if (!options) + options = { encoding: null, flag: 'r' }; + else if (typeof options !== 'object') + throw new TypeError('Bad arguments'); + + var encoding = options.encoding; + if (encoding && !Buffer.isEncoding(encoding)) + throw new Error('Unknown encoding: ' + encoding); + + // first, stat the file, so we know the size. + var size; + var buffer; // single buffer with file data + var buffers; // list for when size is unknown + var pos = 0; + var handle; + + // SFTPv3 does not support using -1 for read position, so we have to track + // read position manually + var bytesRead = 0; + + var flag = options.flag || 'r'; + this.open(path, flag, 438 /*=0666*/, function(er, handle_) { + if (er) + return callback && callback(er); + handle = handle_; + + self.fstat(handle, function tryStat(er, st) { + if (er) { + // Try stat() for sftp servers that may not support fstat() for + // whatever reason + self.stat(path, function(er_, st_) { + if (er_) { + return self.close(handle, function() { + callback && callback(er); + }); + } + tryStat(null, st_); + }); + return; + } + + size = st.size; + if (size === 0) { + // the kernel lies about many files. + // Go ahead and try to read some bytes. + buffers = []; + return read(); + } + + buffer = new Buffer(size); + read(); + }); + }); + + function read() { + if (size === 0) { + buffer = new Buffer(8192); + self.readData(handle, buffer, 0, 8192, bytesRead, afterRead); + } else + self.readData(handle, buffer, pos, size - pos, bytesRead, afterRead); + } + + function afterRead(er, nbytes) { + if (er) { + return self.close(handle, function() { + return callback && callback(er); + }); + } + + if (nbytes === 0) + return close(); + + bytesRead += nbytes; + pos += nbytes; + if (size !== 0) { + if (pos === size) + close(); + else + read(); + } else { + // unknown size, just read until we don't get bytes. + buffers.push(buffer.slice(0, nbytes)); + read(); + } + } + + function close() { + self.close(handle, function(er) { + if (size === 0) { + // collected the data into the buffers list. + buffer = Buffer.concat(buffers, pos); + } else if (pos < size) + buffer = buffer.slice(0, pos); + + if (encoding) + buffer = buffer.toString(encoding); + return callback && callback(er, buffer); + }); + } +}; +function writeAll(self, handle, buffer, offset, length, position, callback_) { + var callback = (typeof callback_ === 'function' ? callback_ : undefined); + + self.writeData(handle, + buffer, + offset, + length, + position, + function(writeErr, written) { + if (writeErr) { + return self.close(handle, function() { + callback && callback(writeErr); + }); + } + if (written === length) + self.close(handle, callback); + else { + offset += written; + length -= written; + position += written; + writeAll(self, handle, buffer, offset, length, position, callback); + } + }); +} +SFTPStream.prototype.writeFile = function(path, data, options, callback_) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var callback; + if (typeof callback_ === 'function') { + callback = callback_; + } else if (typeof options === 'function') { + callback = options; + options = undefined; + } + var self = this; + + if (typeof options === 'string') + options = { encoding: options, mode: 438, flag: 'w' }; + else if (!options) + options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'w' }; + else if (typeof options !== 'object') + throw new TypeError('Bad arguments'); + + if (options.encoding && !Buffer.isEncoding(options.encoding)) + throw new Error('Unknown encoding: ' + options.encoding); + + var flag = options.flag || 'w'; + this.open(path, flag, options.mode, function(openErr, handle) { + if (openErr) + callback && callback(openErr); + else { + var buffer = (Buffer.isBuffer(data) + ? data + : new Buffer('' + data, options.encoding || 'utf8')); + var position = (/a/.test(flag) ? null : 0); + + // SFTPv3 does not support the notion of 'current position' + // (null position), so we just attempt to append to the end of the file + // instead + if (position === null) { + self.fstat(handle, function tryStat(er, st) { + if (er) { + // Try stat() for sftp servers that may not support fstat() for + // whatever reason + self.stat(path, function(er_, st_) { + if (er_) { + return self.close(handle, function() { + callback && callback(er); + }); + } + tryStat(null, st_); + }); + return; + } + writeAll(self, handle, buffer, 0, buffer.length, st.size, callback); + }); + return; + } + writeAll(self, handle, buffer, 0, buffer.length, position, callback); + } + }); +}; +SFTPStream.prototype.appendFile = function(path, data, options, callback_) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var callback; + if (typeof callback_ === 'function') { + callback = callback_; + } else if (typeof options === 'function') { + callback = options; + options = undefined; + } + + if (typeof options === 'string') + options = { encoding: options, mode: 438, flag: 'a' }; + else if (!options) + options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'a' }; + else if (typeof options !== 'object') + throw new TypeError('Bad arguments'); + + if (!options.flag) + options = util._extend({ flag: 'a' }, options); + this.writeFile(path, data, options, callback); +}; +SFTPStream.prototype.exists = function(path, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + this.stat(path, function(err) { + cb && cb(err ? false : true); + }); +}; +SFTPStream.prototype.unlink = function(filename, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var state = this._state; + + /* + uint32 id + string filename + */ + var fnamelen = Buffer.byteLength(filename); + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + fnamelen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.REMOVE; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + + buf.writeUInt32BE(fnamelen, p, true); + buf.write(filename, p += 4, fnamelen, 'utf8'); + + state.requests[reqid] = { cb: cb }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing REMOVE'); + return this.push(buf); +}; +SFTPStream.prototype.rename = function(oldPath, newPath, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var state = this._state; + + /* + uint32 id + string oldpath + string newpath + */ + var oldlen = Buffer.byteLength(oldPath); + var newlen = Buffer.byteLength(newPath); + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + oldlen + 4 + newlen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.RENAME; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + + buf.writeUInt32BE(oldlen, p, true); + buf.write(oldPath, p += 4, oldlen, 'utf8'); + buf.writeUInt32BE(newlen, p += oldlen, true); + buf.write(newPath, p += 4, newlen, 'utf8'); + + state.requests[reqid] = { cb: cb }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing RENAME'); + return this.push(buf); +}; +SFTPStream.prototype.mkdir = function(path, attrs, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var flags = 0; + var attrBytes = 0; + var state = this._state; + + if (typeof attrs === 'function') { + cb = attrs; + attrs = undefined; + } + if (typeof attrs === 'object') { + attrs = attrsToBytes(attrs); + flags = attrs.flags; + attrBytes = attrs.nbytes; + attrs = attrs.bytes; + } + + /* + uint32 id + string path + ATTRS attrs + */ + var pathlen = Buffer.byteLength(path); + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + pathlen + 4 + attrBytes); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.MKDIR; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + + buf.writeUInt32BE(pathlen, p, true); + buf.write(path, p += 4, pathlen, 'utf8'); + buf.writeUInt32BE(flags, p += pathlen); + if (flags) { + p += 4; + for (var i = 0, len = attrs.length; i < len; ++i) + for (var j = 0, len2 = attrs[i].length; j < len2; ++j) + buf[p++] = attrs[i][j]; + } + + state.requests[reqid] = { cb: cb }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing MKDIR'); + return this.push(buf); +}; +SFTPStream.prototype.rmdir = function(path, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var state = this._state; + + /* + uint32 id + string path + */ + var pathlen = Buffer.byteLength(path); + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + pathlen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.RMDIR; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + + buf.writeUInt32BE(pathlen, p, true); + buf.write(path, p += 4, pathlen, 'utf8'); + + state.requests[reqid] = { cb: cb }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing RMDIR'); + return this.push(buf); +}; +SFTPStream.prototype.readdir = function(where, opts, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var state = this._state; + var doFilter; + + if (typeof opts === 'function') { + cb = opts; + opts = {}; + } + if (typeof opts !== 'object') + opts = {}; + + doFilter = (opts && opts.full ? false : true); + + if (!Buffer.isBuffer(where) && typeof where !== 'string') + throw new Error('missing directory handle or path'); + + if (typeof where === 'string') { + var self = this; + var entries = []; + var e = 0; + + return this.opendir(where, function reread(err, handle) { + if (err) + return cb(err); + + self.readdir(handle, opts, function(err, list) { + var eof = (err && err.code === STATUS_CODE.EOF); + + if (err && !eof) { + return self.close(handle, function() { + cb(err); + }); + } else if (eof) { + return self.close(handle, function(err) { + if (err) + return cb(err); + cb(undefined, entries); + }); + } + + for (var i = 0, len = list.length; i < len; ++i, ++e) + entries[e] = list[i]; + + reread(undefined, handle); + }); + }); + } + + /* + uint32 id + string handle + */ + var handlelen = where.length; + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + handlelen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.READDIR; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + + buf.writeUInt32BE(handlelen, p, true); + where.copy(buf, p += 4); + + state.requests[reqid] = { + cb: (doFilter + ? function(err, list) { + if (err) + return cb(err); + + for (var i = list.length - 1; i >= 0; --i) { + if (list[i].filename === '.' || list[i].filename === '..') + list.splice(i, 1); + } + + cb(undefined, list); + } + : cb) + }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing READDIR'); + return this.push(buf); +}; +SFTPStream.prototype.fstat = function(handle, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + else if (!Buffer.isBuffer(handle)) + throw new Error('handle is not a Buffer'); + + var state = this._state; + + /* + uint32 id + string handle + */ + var handlelen = handle.length; + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + handlelen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.FSTAT; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + + buf.writeUInt32BE(handlelen, p, true); + handle.copy(buf, p += 4); + + state.requests[reqid] = { cb: cb }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing FSTAT'); + return this.push(buf); +}; +SFTPStream.prototype.stat = function(path, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var state = this._state; + + /* + uint32 id + string path + */ + var pathlen = Buffer.byteLength(path); + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + pathlen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.STAT; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + + buf.writeUInt32BE(pathlen, p, true); + buf.write(path, p += 4, pathlen, 'utf8'); + + state.requests[reqid] = { cb: cb }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing STAT'); + return this.push(buf); +}; +SFTPStream.prototype.lstat = function(path, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var state = this._state; + + /* + uint32 id + string path + */ + var pathlen = Buffer.byteLength(path); + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + pathlen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.LSTAT; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + + buf.writeUInt32BE(pathlen, p, true); + buf.write(path, p += 4, pathlen, 'utf8'); + + state.requests[reqid] = { cb: cb }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing LSTAT'); + return this.push(buf); +}; +SFTPStream.prototype.opendir = function(path, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var state = this._state; + + /* + uint32 id + string path + */ + var pathlen = Buffer.byteLength(path); + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + pathlen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.OPENDIR; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + + buf.writeUInt32BE(pathlen, p, true); + buf.write(path, p += 4, pathlen, 'utf8'); + + state.requests[reqid] = { cb: cb }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing OPENDIR'); + return this.push(buf); +}; +SFTPStream.prototype.setstat = function(path, attrs, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var flags = 0; + var attrBytes = 0; + var state = this._state; + + if (typeof attrs === 'object') { + attrs = attrsToBytes(attrs); + flags = attrs.flags; + attrBytes = attrs.nbytes; + attrs = attrs.bytes; + } else if (typeof attrs === 'function') + cb = attrs; + + /* + uint32 id + string path + ATTRS attrs + */ + var pathlen = Buffer.byteLength(path); + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + pathlen + 4 + attrBytes); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.SETSTAT; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + + buf.writeUInt32BE(pathlen, p, true); + buf.write(path, p += 4, pathlen, 'utf8'); + buf.writeUInt32BE(flags, p += pathlen); + if (flags) { + p += 4; + for (var i = 0, len = attrs.length; i < len; ++i) + for (var j = 0, len2 = attrs[i].length; j < len2; ++j) + buf[p++] = attrs[i][j]; + } + + state.requests[reqid] = { cb: cb }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing SETSTAT'); + return this.push(buf); +}; +SFTPStream.prototype.fsetstat = function(handle, attrs, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + else if (!Buffer.isBuffer(handle)) + throw new Error('handle is not a Buffer'); + + var flags = 0; + var attrBytes = 0; + var state = this._state; + + if (typeof attrs === 'object') { + attrs = attrsToBytes(attrs); + flags = attrs.flags; + attrBytes = attrs.nbytes; + attrs = attrs.bytes; + } else if (typeof attrs === 'function') + cb = attrs; + + /* + uint32 id + string handle + ATTRS attrs + */ + var handlelen = handle.length; + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + handlelen + 4 + attrBytes); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.FSETSTAT; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + + buf.writeUInt32BE(handlelen, p, true); + handle.copy(buf, p += 4); + buf.writeUInt32BE(flags, p += handlelen); + if (flags) { + p += 4; + for (var i = 0, len = attrs.length; i < len; ++i) + for (var j = 0, len2 = attrs[i].length; j < len2; ++j) + buf[p++] = attrs[i][j]; + } + + state.requests[reqid] = { cb: cb }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing FSETSTAT'); + return this.push(buf); +}; +SFTPStream.prototype.futimes = function(handle, atime, mtime, cb) { + return this.fsetstat(handle, { + atime: toUnixTimestamp(atime), + mtime: toUnixTimestamp(mtime) + }, cb); +}; +SFTPStream.prototype.utimes = function(path, atime, mtime, cb) { + return this.setstat(path, { + atime: toUnixTimestamp(atime), + mtime: toUnixTimestamp(mtime) + }, cb); +}; +SFTPStream.prototype.fchown = function(handle, uid, gid, cb) { + return this.fsetstat(handle, { + uid: uid, + gid: gid + }, cb); +}; +SFTPStream.prototype.chown = function(path, uid, gid, cb) { + return this.setstat(path, { + uid: uid, + gid: gid + }, cb); +}; +SFTPStream.prototype.fchmod = function(handle, mode, cb) { + return this.fsetstat(handle, { + mode: mode + }, cb); +}; +SFTPStream.prototype.chmod = function(path, mode, cb) { + return this.setstat(path, { + mode: mode + }, cb); +}; +SFTPStream.prototype.readlink = function(path, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var state = this._state; + + /* + uint32 id + string path + */ + var pathlen = Buffer.byteLength(path); + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + pathlen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.READLINK; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + + buf.writeUInt32BE(pathlen, p, true); + buf.write(path, p += 4, pathlen, 'utf8'); + + state.requests[reqid] = { + cb: function(err, names) { + if (err) + return cb(err); + else if (!names || !names.length) + return cb(new Error('Response missing link info')); + cb(undefined, names[0].filename); + } + }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing READLINK'); + return this.push(buf); +}; +SFTPStream.prototype.symlink = function(targetPath, linkPath, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var state = this._state; + + /* + uint32 id + string linkpath + string targetpath + */ + var linklen = Buffer.byteLength(linkPath); + var targetlen = Buffer.byteLength(targetPath); + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + linklen + 4 + targetlen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.SYMLINK; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + + if (this._isOpenSSH) { + // OpenSSH has linkpath and targetpath positions switched + buf.writeUInt32BE(targetlen, p, true); + buf.write(targetPath, p += 4, targetlen, 'utf8'); + buf.writeUInt32BE(linklen, p += targetlen, true); + buf.write(linkPath, p += 4, linklen, 'utf8'); + } else { + buf.writeUInt32BE(linklen, p, true); + buf.write(linkPath, p += 4, linklen, 'utf8'); + buf.writeUInt32BE(targetlen, p += linklen, true); + buf.write(targetPath, p += 4, targetlen, 'utf8'); + } + + state.requests[reqid] = { cb: cb }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing SYMLINK'); + return this.push(buf); +}; +SFTPStream.prototype.realpath = function(path, cb) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var state = this._state; + + /* + uint32 id + string path + */ + var pathlen = Buffer.byteLength(path); + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + pathlen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.REALPATH; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + + buf.writeUInt32BE(pathlen, p, true); + buf.write(path, p += 4, pathlen, 'utf8'); + + state.requests[reqid] = { + cb: function(err, names) { + if (err) + return cb(err); + else if (!names || !names.length) + return cb(new Error('Response missing path info')); + cb(undefined, names[0].filename); + } + }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing REALPATH'); + return this.push(buf); +}; +// extended requests +SFTPStream.prototype.ext_openssh_rename = function(oldPath, newPath, cb) { + var state = this._state; + + if (this.server) + throw new Error('Client-only method called in server mode'); + else if (!state.extensions['posix-rename@openssh.com'] + || state.extensions['posix-rename@openssh.com'].indexOf('1') === -1) + throw new Error('Server does not support this extended request'); + + /* + uint32 id + string "posix-rename@openssh.com" + string oldpath + string newpath + */ + var oldlen = Buffer.byteLength(oldPath); + var newlen = Buffer.byteLength(newPath); + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + 24 + 4 + oldlen + 4 + newlen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.EXTENDED; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + buf.writeUInt32BE(24, p, true); + buf.write('posix-rename@openssh.com', p += 4, 24, 'ascii'); + + buf.writeUInt32BE(oldlen, p += 24, true); + buf.write(oldPath, p += 4, oldlen, 'utf8'); + buf.writeUInt32BE(newlen, p += oldlen, true); + buf.write(newPath, p += 4, newlen, 'utf8'); + + state.requests[reqid] = { cb: cb }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing posix-rename@openssh.com'); + return this.push(buf); +}; +SFTPStream.prototype.ext_openssh_statvfs = function(path, cb) { + var state = this._state; + + if (this.server) + throw new Error('Client-only method called in server mode'); + else if (!state.extensions['statvfs@openssh.com'] + || state.extensions['statvfs@openssh.com'].indexOf('2') === -1) + throw new Error('Server does not support this extended request'); + + /* + uint32 id + string "statvfs@openssh.com" + string path + */ + var pathlen = Buffer.byteLength(path); + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + 19 + 4 + pathlen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.EXTENDED; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + buf.writeUInt32BE(19, p, true); + buf.write('statvfs@openssh.com', p += 4, 19, 'ascii'); + + buf.writeUInt32BE(pathlen, p += 19, true); + buf.write(path, p += 4, pathlen, 'utf8'); + + state.requests[reqid] = { + extended: 'statvfs@openssh.com', + cb: cb + }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing statvfs@openssh.com'); + return this.push(buf); +}; +SFTPStream.prototype.ext_openssh_fstatvfs = function(handle, cb) { + var state = this._state; + + if (this.server) + throw new Error('Client-only method called in server mode'); + else if (!state.extensions['fstatvfs@openssh.com'] + || state.extensions['fstatvfs@openssh.com'].indexOf('2') === -1) + throw new Error('Server does not support this extended request'); + else if (!Buffer.isBuffer(handle)) + throw new Error('handle is not a Buffer'); + + /* + uint32 id + string "fstatvfs@openssh.com" + string handle + */ + var handlelen = handle.length; + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + 20 + 4 + handlelen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.EXTENDED; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + buf.writeUInt32BE(20, p, true); + buf.write('fstatvfs@openssh.com', p += 4, 20, 'ascii'); + + buf.writeUInt32BE(handlelen, p += 20, true); + buf.write(handle, p += 4, handlelen, 'utf8'); + + state.requests[reqid] = { + extended: 'fstatvfs@openssh.com', + cb: cb + }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing fstatvfs@openssh.com'); + return this.push(buf); +}; +SFTPStream.prototype.ext_openssh_hardlink = function(oldPath, newPath, cb) { + var state = this._state; + + if (this.server) + throw new Error('Client-only method called in server mode'); + else if (!state.extensions['hardlink@openssh.com'] + || state.extensions['hardlink@openssh.com'].indexOf('1') === -1) + throw new Error('Server does not support this extended request'); + + /* + uint32 id + string "hardlink@openssh.com" + string oldpath + string newpath + */ + var oldlen = Buffer.byteLength(oldPath); + var newlen = Buffer.byteLength(newPath); + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + 20 + 4 + oldlen + 4 + newlen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.EXTENDED; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + buf.writeUInt32BE(20, p, true); + buf.write('hardlink@openssh.com', p += 4, 20, 'ascii'); + + buf.writeUInt32BE(oldlen, p += 20, true); + buf.write(oldPath, p += 4, oldlen, 'utf8'); + buf.writeUInt32BE(newlen, p += oldlen, true); + buf.write(newPath, p += 4, newlen, 'utf8'); + + state.requests[reqid] = { cb: cb }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing hardlink@openssh.com'); + return this.push(buf); +}; +SFTPStream.prototype.ext_openssh_fsync = function(handle, cb) { + var state = this._state; + + if (this.server) + throw new Error('Client-only method called in server mode'); + else if (!state.extensions['fsync@openssh.com'] + || state.extensions['fsync@openssh.com'].indexOf('1') === -1) + throw new Error('Server does not support this extended request'); + else if (!Buffer.isBuffer(handle)) + throw new Error('handle is not a Buffer'); + + /* + uint32 id + string "fsync@openssh.com" + string handle + */ + var handlelen = handle.length; + var p = 9; + var buf = new Buffer(4 + 1 + 4 + 4 + 17 + 4 + handlelen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = REQUEST.EXTENDED; + var reqid = state.writeReqid = (state.writeReqid + 1) % MAX_REQID; + buf.writeUInt32BE(reqid, 5, true); + buf.writeUInt32BE(17, p, true); + buf.write('fsync@openssh.com', p += 4, 17, 'ascii'); + + buf.writeUInt32BE(handlelen, p += 17, true); + buf.write(handle, p += 4, handlelen, 'utf8'); + + state.requests[reqid] = { cb: cb }; + + this.debug('DEBUG[SFTP]: Outgoing: Writing fsync@openssh.com'); + return this.push(buf); +}; + +// server +SFTPStream.prototype.status = function(id, code, message, lang) { + if (!this.server) + throw new Error('Server-only method called in client mode'); + + if (!STATUS_CODE[code] || typeof code !== 'number') + throw new Error('Bad status code: ' + code); + + message || (message = ''); + lang || (lang = ''); + + var msgLen = Buffer.byteLength(message); + var langLen = Buffer.byteLength(lang); + var buf = new Buffer(4 + 1 + 4 + 4 + 4 + msgLen + 4 + langLen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = RESPONSE.STATUS; + buf.writeUInt32BE(id, 5, true); + + buf.writeUInt32BE(code, 9, true); + + buf.writeUInt32BE(msgLen, 13, true); + if (msgLen) + buf.write(message, 17, msgLen, 'utf8'); + + buf.writeUInt32BE(langLen, 17 + msgLen, true); + if (langLen) + buf.write(lang, 17 + msgLen + 4, langLen, 'ascii'); + + this.debug('DEBUG[SFTP]: Outgoing: Writing STATUS'); + return this.push(buf); +}; +SFTPStream.prototype.handle = function(id, handle) { + if (!this.server) + throw new Error('Server-only method called in client mode'); + + if (!Buffer.isBuffer(handle)) + throw new Error('handle is not a Buffer'); + + var handleLen = handle.length; + + if (handleLen > 256) + throw new Error('handle too large (> 256 bytes)'); + + var buf = new Buffer(4 + 1 + 4 + 4 + handleLen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = RESPONSE.HANDLE; + buf.writeUInt32BE(id, 5, true); + + buf.writeUInt32BE(handleLen, 9, true); + if (handleLen) + handle.copy(buf, 13); + + this.debug('DEBUG[SFTP]: Outgoing: Writing HANDLE'); + return this.push(buf); +}; +SFTPStream.prototype.data = function(id, data, encoding) { + if (!this.server) + throw new Error('Server-only method called in client mode'); + + var isBuffer = Buffer.isBuffer(data); + + if (!isBuffer && typeof data !== 'string') + throw new Error('data is not a Buffer or string'); + + if (!isBuffer) + encoding || (encoding = 'utf8'); + + var dataLen = (isBuffer ? data.length : Buffer.byteLength(data, encoding)); + var buf = new Buffer(4 + 1 + 4 + 4 + dataLen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = RESPONSE.DATA; + buf.writeUInt32BE(id, 5, true); + + buf.writeUInt32BE(dataLen, 9, true); + if (dataLen) { + if (isBuffer) + data.copy(buf, 13); + else + buf.write(data, 13, dataLen, encoding); + } + + this.debug('DEBUG[SFTP]: Outgoing: Writing DATA'); + return this.push(buf); +}; +SFTPStream.prototype.name = function(id, names) { + if (!this.server) + throw new Error('Server-only method called in client mode'); + + if (!Array.isArray(names) && typeof names === 'object') + names = [ names ]; + else if (!Array.isArray(names)) + throw new Error('names is not an object or array'); + + var count = names.length; + var namesLen = 0; + var nameAttrs; + var attrs = []; + var name; + var filename; + var longname; + var attr; + var len; + var len2; + var buf; + var p; + var i; + var j; + var k; + + for (i = 0; i < count; ++i) { + name = names[i]; + filename = (!name || !name.filename || typeof name.filename !== 'string' + ? '' + : name.filename); + namesLen += 4 + Buffer.byteLength(filename); + longname = (!name || !name.longname || typeof name.longname !== 'string' + ? '' + : name.longname); + namesLen += 4 + Buffer.byteLength(longname); + + if (typeof name.attrs === 'object') { + nameAttrs = attrsToBytes(name.attrs); + namesLen += 4 + nameAttrs.nbytes; + attrs.push(nameAttrs); + } else { + namesLen += 4; + attrs.push(null); + } + } + + buf = new Buffer(4 + 1 + 4 + 4 + namesLen); + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = RESPONSE.NAME; + buf.writeUInt32BE(id, 5, true); + + buf.writeUInt32BE(count, 9, true); + + p = 13; + + for (i = 0; i < count; ++i) { + name = names[i]; + + filename = (!name || !name.filename || typeof name.filename !== 'string' + ? '' + : name.filename); + len = Buffer.byteLength(filename); + buf.writeUInt32BE(len, p, true); + p += 4; + if (len) { + buf.write(filename, p, len, 'utf8'); + p += len; + } + + longname = (!name || !name.longname || typeof name.longname !== 'string' + ? '' + : name.longname); + len = Buffer.byteLength(longname); + buf.writeUInt32BE(len, p, true); + p += 4; + if (len) { + buf.write(longname, p, len, 'utf8'); + p += len; + } + + attr = attrs[i]; + if (attr) { + buf.writeUInt32BE(attr.flags, p, true); + p += 4; + if (attr.flags && attr.bytes) { + var bytes = attr.bytes; + for (j = 0, len = bytes.length; j < len; ++j) + for (k = 0, len2 = bytes[j].length; k < len2; ++k) + buf[p++] = bytes[j][k]; + } + } else { + buf.writeUInt32BE(0, p, true); + p += 4; + } + } + + this.debug('DEBUG[SFTP]: Outgoing: Writing NAME'); + return this.push(buf); +}; +SFTPStream.prototype.attrs = function(id, attrs) { + if (!this.server) + throw new Error('Server-only method called in client mode'); + + if (typeof attrs !== 'object') + throw new Error('attrs is not an object'); + + var info = attrsToBytes(attrs); + var buf = new Buffer(4 + 1 + 4 + 4 + info.nbytes); + var p = 13; + + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = RESPONSE.ATTRS; + buf.writeUInt32BE(id, 5, true); + + buf.writeUInt32BE(info.flags, 9, true); + + if (info.flags && info.bytes) { + var bytes = info.bytes; + for (var j = 0, len = bytes.length; j < len; ++j) + for (var k = 0, len2 = bytes[j].length; k < len2; ++k) + buf[p++] = bytes[j][k]; + } + + this.debug('DEBUG[SFTP]: Outgoing: Writing ATTRS'); + return this.push(buf); +}; + +function readAttrs(buf, p, stream, callback) { + /* + uint32 flags + uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE + uint32 uid present only if flag SSH_FILEXFER_ATTR_UIDGID + uint32 gid present only if flag SSH_FILEXFER_ATTR_UIDGID + uint32 permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS + uint32 atime present only if flag SSH_FILEXFER_ACMODTIME + uint32 mtime present only if flag SSH_FILEXFER_ACMODTIME + uint32 extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED + string extended_type + string extended_data + ... more extended data (extended_type - extended_data pairs), + so that number of pairs equals extended_count + */ + var flags = buf.readUInt32BE(p, true); + var attrs = new Stats(); + + p += 4; + + if (flags & ATTR.SIZE) { + var size = readUInt64BE(buf, p, stream, callback); + if (size === false) + return false; + attrs.size = size; + p += 8; + } + if (flags & ATTR.UIDGID) { + var uid; + var gid; + uid = readInt(buf, p, this, callback); + if (uid === false) + return false; + attrs.uid = uid; + p += 4; + gid = readInt(buf, p, this, callback); + if (gid === false) + return false; + attrs.gid = gid; + p += 4; + } + if (flags & ATTR.PERMISSIONS) { + var mode = readInt(buf, p, this, callback); + if (mode === false) + return false; + attrs.mode = mode; + // backwards compatibility + attrs.permissions = mode; + p += 4; + } + if (flags & ATTR.ACMODTIME) { + var atime; + var mtime; + atime = readInt(buf, p, this, callback); + if (atime === false) + return false; + attrs.atime = atime; + p += 4; + mtime = readInt(buf, p, this, callback); + if (mtime === false) + return false; + attrs.mtime = mtime; + p += 4; + } + if (flags & ATTR.EXTENDED) { + // TODO: read/parse extended data + var extcount = readInt(buf, p, this, callback); + if (extcount === false) + return false; + p += 4; + for (var i = 0, len; i < extcount; ++i) { + len = readInt(buf, p, this, callback); + if (len === false) + return false; + p += 4 + len; + } + } + + buf._pos = p; + + return attrs; +} + +function readUInt64BE(buffer, p, stream, callback) { + if ((buffer.length - p) < 8) { + stream && stream._cleanup(callback); + return false; + } + + var val = 0; + + for (var len = p + 8; p < len; ++p) { + val *= 256; + val += buffer[p]; + } + + buffer._pos = p; + + return val; +} + +function attrsToBytes(attrs) { + var flags = 0; + var attrBytes = 0; + var ret = []; + var i = 0; + + if (typeof attrs.size === 'number') { + flags |= ATTR.SIZE; + attrBytes += 8; + var sizeBytes = new Array(8); + var val = attrs.size; + for (i = 7; i >= 0; --i) { + sizeBytes[i] = val & 0xFF; + val /= 256; + } + ret.push(sizeBytes); + } + if (typeof attrs.uid === 'number' && typeof attrs.gid === 'number') { + flags |= ATTR.UIDGID; + attrBytes += 8; + ret.push([(attrs.uid >> 24) & 0xFF, (attrs.uid >> 16) & 0xFF, + (attrs.uid >> 8) & 0xFF, attrs.uid & 0xFF]); + ret.push([(attrs.gid >> 24) & 0xFF, (attrs.gid >> 16) & 0xFF, + (attrs.gid >> 8) & 0xFF, attrs.gid & 0xFF]); + } + if (typeof attrs.permissions === 'number' + || typeof attrs.permissions === 'string' + || typeof attrs.mode === 'number' + || typeof attrs.mode === 'string') { + var mode = modeNum(attrs.mode || attrs.permissions); + flags |= ATTR.PERMISSIONS; + attrBytes += 4; + ret.push([(mode >> 24) & 0xFF, + (mode >> 16) & 0xFF, + (mode >> 8) & 0xFF, + mode & 0xFF]); + } + if ((typeof attrs.atime === 'number' || isDate(attrs.atime)) + && (typeof attrs.mtime === 'number' || isDate(attrs.mtime))) { + var atime = toUnixTimestamp(attrs.atime); + var mtime = toUnixTimestamp(attrs.mtime); + + flags |= ATTR.ACMODTIME; + attrBytes += 8; + ret.push([(atime >> 24) & 0xFF, (atime >> 16) & 0xFF, + (atime >> 8) & 0xFF, atime & 0xFF]); + ret.push([(mtime >> 24) & 0xFF, (mtime >> 16) & 0xFF, + (mtime >> 8) & 0xFF, mtime & 0xFF]); + } + // TODO: extended attributes + + return { flags: flags, nbytes: attrBytes, bytes: ret }; +} + +function toUnixTimestamp(time) { + if (typeof time === 'number' && !isNaN(time)) + return time; + else if (isDate(time)) + return parseInt(time.getTime() / 1000, 10); + throw new Error('Cannot parse time: ' + time); +} + +function modeNum(mode) { + if (typeof mode === 'number' && !isNaN(mode)) + return mode; + else if (typeof mode === 'string') + return modeNum(parseInt(mode, 8)); + throw new Error('Cannot parse mode: ' + mode); +} + +var stringFlagMap = { + 'r': OPEN_MODE.READ, + 'r+': OPEN_MODE.READ | OPEN_MODE.WRITE, + 'w': OPEN_MODE.TRUNC | OPEN_MODE.CREAT | OPEN_MODE.WRITE, + 'wx': OPEN_MODE.TRUNC | OPEN_MODE.CREAT | OPEN_MODE.WRITE | OPEN_MODE.EXCL, + 'xw': OPEN_MODE.TRUNC | OPEN_MODE.CREAT | OPEN_MODE.WRITE | OPEN_MODE.EXCL, + 'w+': OPEN_MODE.TRUNC | OPEN_MODE.CREAT | OPEN_MODE.READ | OPEN_MODE.WRITE, + 'wx+': OPEN_MODE.TRUNC | OPEN_MODE.CREAT | OPEN_MODE.READ | OPEN_MODE.WRITE + | OPEN_MODE.EXCL, + 'xw+': OPEN_MODE.TRUNC | OPEN_MODE.CREAT | OPEN_MODE.READ | OPEN_MODE.WRITE + | OPEN_MODE.EXCL, + 'a': OPEN_MODE.APPEND | OPEN_MODE.CREAT | OPEN_MODE.WRITE, + 'ax': OPEN_MODE.APPEND | OPEN_MODE.CREAT | OPEN_MODE.WRITE | OPEN_MODE.EXCL, + 'xa': OPEN_MODE.APPEND | OPEN_MODE.CREAT | OPEN_MODE.WRITE | OPEN_MODE.EXCL, + 'a+': OPEN_MODE.APPEND | OPEN_MODE.CREAT | OPEN_MODE.READ | OPEN_MODE.WRITE, + 'ax+': OPEN_MODE.APPEND | OPEN_MODE.CREAT | OPEN_MODE.READ | OPEN_MODE.WRITE + | OPEN_MODE.EXCL, + 'xa+': OPEN_MODE.APPEND | OPEN_MODE.CREAT | OPEN_MODE.READ | OPEN_MODE.WRITE + | OPEN_MODE.EXCL +}; +var stringFlagMapKeys = Object.keys(stringFlagMap); + +function stringToFlags(str) { + var flags = stringFlagMap[str]; + if (flags !== undefined) + return flags; + return null; +} +SFTPStream.stringToFlags = stringToFlags; + +function flagsToString(flags) { + for (var i = 0; i < stringFlagMapKeys.length; ++i) { + var key = stringFlagMapKeys[i]; + if (stringFlagMap[key] === flags) + return key; + } + return null; +} +SFTPStream.flagsToString = flagsToString; + +function Stats(initial) { + this.mode = (initial && initial.mode); + this.permissions = this.mode; // backwards compatiblity + this.uid = (initial && initial.uid); + this.gid = (initial && initial.gid); + this.size = (initial && initial.size); + this.atime = (initial && initial.atime); + this.mtime = (initial && initial.mtime); +} +Stats.prototype._checkModeProperty = function(property) { + return ((this.mode & constants.S_IFMT) === property); +}; +Stats.prototype.isDirectory = function() { + return this._checkModeProperty(constants.S_IFDIR); +}; +Stats.prototype.isFile = function() { + return this._checkModeProperty(constants.S_IFREG); +}; +Stats.prototype.isBlockDevice = function() { + return this._checkModeProperty(constants.S_IFBLK); +}; +Stats.prototype.isCharacterDevice = function() { + return this._checkModeProperty(constants.S_IFCHR); +}; +Stats.prototype.isSymbolicLink = function() { + return this._checkModeProperty(constants.S_IFLNK); +}; +Stats.prototype.isFIFO = function() { + return this._checkModeProperty(constants.S_IFIFO); +}; +Stats.prototype.isSocket = function() { + return this._checkModeProperty(constants.S_IFSOCK); +}; +SFTPStream.Stats = Stats; + + +// ReadStream-related +var kMinPoolSpace = 128; +var pool; +function allocNewPool(poolSize) { + pool = new Buffer(poolSize); + pool.used = 0; +} + +function ReadStream(sftp, path, options) { + if (!(this instanceof ReadStream)) + return new ReadStream(sftp, path, options); + + var self = this; + + if (options === undefined) + options = {}; + else if (typeof options === 'string') + options = { encoding: options }; + else if (options === null || typeof options !== 'object') + throw new TypeError('"options" argument must be a string or an object'); + else + options = Object.create(options); + + // a little bit bigger buffer and water marks by default + if (options.highWaterMark === undefined) + options.highWaterMark = 64 * 1024; + + ReadableStream.call(this, options); + + this.path = path; + this.handle = options.handle === undefined ? null : options.handle; + this.flags = options.flags === undefined ? 'r' : options.flags; + this.mode = options.mode === undefined ? 438/*0666*/ : options.mode; + + this.start = options.start === undefined ? undefined : options.start; + this.end = options.end === undefined ? undefined : options.end; + this.autoClose = options.autoClose === undefined ? true : options.autoClose; + this.pos = 0; + this.sftp = sftp; + + if (this.start !== undefined) { + if (typeof this.start !== 'number') + throw new TypeError('start must be a Number'); + if (this.end === undefined) + this.end = Infinity; + else if (typeof this.end !== 'number') + throw new TypeError('end must be a Number'); + + if (this.start > this.end) + throw new Error('start must be <= end'); + else if (this.start < 0) + throw new Error('start must be >= zero'); + + this.pos = this.start; + } + + this.on('end', function() { + if (self.autoClose) { + self.destroy(); + } + }); + + if (!Buffer.isBuffer(this.handle)) + this.open(); +} +inherits(ReadStream, ReadableStream); + +ReadStream.prototype.open = function() { + var self = this; + this.sftp.open(this.path, this.flags, this.mode, function(er, handle) { + if (er) { + self.emit('error', er); + this.destroyed = this.closed = true; + self.emit('close'); + return; + } + + self.handle = handle; + self.emit('open', handle); + // start the flow of data. + self.read(); + }); +}; + +ReadStream.prototype._read = function(n) { + if (!Buffer.isBuffer(this.handle)) { + return this.once('open', function() { + this._read(n); + }); + } + + if (this.destroyed) + return; + + if (!pool || pool.length - pool.used < kMinPoolSpace) { + // discard the old pool. + pool = null; + allocNewPool(this._readableState.highWaterMark); + } + + // Grab another reference to the pool in the case that while we're + // in the thread pool another read() finishes up the pool, and + // allocates a new one. + var thisPool = pool; + var toRead = Math.min(pool.length - pool.used, n); + var start = pool.used; + + if (this.end !== undefined) + toRead = Math.min(this.end - this.pos + 1, toRead); + + // already read everything we were supposed to read! + // treat as EOF. + if (toRead <= 0) + return this.push(null); + + // the actual read. + var self = this; + this.sftp.readData(this.handle, pool, pool.used, toRead, this.pos, onread); + + // move the pool positions, and internal position for reading. + this.pos += toRead; + pool.used += toRead; + + function onread(er, bytesRead) { + if (er) { + if (self.autoClose) + self.destroy(); + self.emit('error', er); + } else { + var b = null; + if (bytesRead > 0) + b = thisPool.slice(start, start + bytesRead); + + self.push(b); + } + } +}; + +ReadStream.prototype.destroy = function() { + if (this.destroyed) + return; + this.destroyed = true; + if (Buffer.isBuffer(this.handle)) + this.close(); +}; + + +ReadStream.prototype.close = function(cb) { + var self = this; + if (cb) + this.once('close', cb); + if (this.closed || !Buffer.isBuffer(this.handle)) { + if (!Buffer.isBuffer(this.handle)) { + this.once('open', close); + return; + } + return process.nextTick(this.emit.bind(this, 'close')); + } + this.closed = true; + close(); + + function close(handle) { + self.sftp.close(handle || self.handle, function(er) { + if (er) + self.emit('error', er); + else + self.emit('close'); + }); + self.handle = null; + } +}; + + +function WriteStream(sftp, path, options) { + if (!(this instanceof WriteStream)) + return new WriteStream(sftp, path, options); + + if (options === undefined) + options = {}; + else if (typeof options === 'string') + options = { encoding: options }; + else if (options === null || typeof options !== 'object') + throw new TypeError('"options" argument must be a string or an object'); + else + options = Object.create(options); + + WritableStream.call(this, options); + + this.path = path; + this.handle = options.handle === undefined ? null : options.handle; + this.flags = options.flags === undefined ? 'w' : options.flags; + this.mode = options.mode === undefined ? 438/*0666*/ : options.mode; + + this.start = options.start === undefined ? undefined : options.start; + this.autoClose = options.autoClose === undefined ? true : options.autoClose; + this.pos = 0; + this.bytesWritten = 0; + this.sftp = sftp; + + if (this.start !== undefined) { + if (typeof this.start !== 'number') + throw new TypeError('start must be a Number'); + if (this.start < 0) + throw new Error('start must be >= zero'); + + this.pos = this.start; + } + + if (options.encoding) + this.setDefaultEncoding(options.encoding); + + if (!Buffer.isBuffer(this.handle)) + this.open(); + + // dispose on finish. + this.once('finish', function onclose() { + if (this.autoClose) + this.close(); + }); +} +inherits(WriteStream, WritableStream); + +WriteStream.prototype.open = function() { + var self = this; + this.sftp.open(this.path, this.flags, this.mode, function(er, handle) { + if (er) { + self.emit('error', er); + if (this.autoClose) { + this.destroyed = this.closed = true; + self.emit('close'); + } + return; + } + + self.handle = handle; + + self.sftp.fchmod(handle, self.mode, function tryAgain(err) { + if (err) { + // Try chmod() for sftp servers that may not support fchmod() for + // whatever reason + self.sftp.chmod(self.path, self.mode, function(err_) { + tryAgain(); + }); + return; + } + + // SFTPv3 requires absolute offsets, no matter the open flag used + if (self.flags[0] === 'a') { + self.sftp.fstat(handle, function tryStat(err, st) { + if (err) { + // Try stat() for sftp servers that may not support fstat() for + // whatever reason + self.sftp.stat(self.path, function(err_, st_) { + if (err_) { + self.destroy(); + self.emit('error', err); + return; + } + tryStat(null, st_); + }); + return; + } + + self.pos = st.size; + self.emit('open', handle); + }); + return; + } + self.emit('open', handle); + }); + }); +}; + +WriteStream.prototype._write = function(data, encoding, cb) { + if (!Buffer.isBuffer(data)) + return this.emit('error', new Error('Invalid data')); + + if (!Buffer.isBuffer(this.handle)) { + return this.once('open', function() { + this._write(data, encoding, cb); + }); + } + + var self = this; + this.sftp.writeData(this.handle, + data, + 0, + data.length, + this.pos, + function(er, bytes) { + if (er) { + if (self.autoClose) + self.destroy(); + return cb(er); + } + self.bytesWritten += bytes; + cb(); + }); + + this.pos += data.length; +}; + +WriteStream.prototype._writev = function(data, cb) { + if (!Buffer.isBuffer(this.handle)) { + return this.once('open', function() { + this._writev(data, cb); + }); + } + + var sftp = this.sftp; + var handle = this.handle; + var writesLeft = data.length; + var self = this; + + for (var i = 0; i < data.length; ++i) { + var chunk = data[i].chunk; + + sftp.writeData(handle, chunk, 0, chunk.length, this.pos, onwrite); + this.pos += chunk.length; + } + + function onwrite(er, bytes) { + if (er) { + self.destroy(); + return cb(er); + } + self.bytesWritten += bytes; + if (--writesLeft === 0) + cb(); + } +}; + +WriteStream.prototype.destroy = ReadStream.prototype.destroy; +WriteStream.prototype.close = ReadStream.prototype.close; + +// There is no shutdown() for files. +WriteStream.prototype.destroySoon = WriteStream.prototype.end; + + +module.exports = SFTPStream; + diff --git a/node_modules/ssh2-streams/lib/ssh.js b/node_modules/ssh2-streams/lib/ssh.js new file mode 100644 index 0000000..dea9da8 --- /dev/null +++ b/node_modules/ssh2-streams/lib/ssh.js @@ -0,0 +1,5391 @@ +// TODO: * Automatic re-key every (configurable) n bytes or length of time +// - RFC suggests every 1GB of transmitted data or 1 hour, whichever +// comes sooner +// * Filter control codes from strings +// (as per http://tools.ietf.org/html/rfc4251#section-9.2) + +var crypto = require('crypto'); +var zlib = require('zlib'); +var TransformStream = require('stream').Transform; +var inherits = require('util').inherits; +var inspect = require('util').inspect; +var BUFFER_MAX_LEN = require('buffer').kMaxLength; + +var StreamSearch = require('streamsearch'); + +var consts = require('./constants'); +var utils = require('./utils'); +var isStreamCipher = utils.isStreamCipher; +var iv_inc = utils.iv_inc; +var readString = utils.readString; +var readInt = utils.readInt; +var DSASigBERToBare = utils.DSASigBERToBare; +var DSASigBareToBER = utils.DSASigBareToBER; +var ECDSASigSSHToASN1 = utils.ECDSASigSSHToASN1; +var ECDSASigASN1ToSSH = utils.ECDSASigASN1ToSSH; +var RSAKeySSHToASN1 = utils.RSAKeySSHToASN1; +var DSAKeySSHToASN1 = utils.DSAKeySSHToASN1; +var ECDSAKeySSHToASN1 = utils.ECDSAKeySSHToASN1; + +var MESSAGE = consts.MESSAGE; +var DYNAMIC_KEXDH_MESSAGE = consts.DYNAMIC_KEXDH_MESSAGE; +var KEXDH_MESSAGE = consts.KEXDH_MESSAGE; +var ALGORITHMS = consts.ALGORITHMS; +var DISCONNECT_REASON = consts.DISCONNECT_REASON; +var CHANNEL_OPEN_FAILURE = consts.CHANNEL_OPEN_FAILURE; +var SSH_TO_OPENSSL = consts.SSH_TO_OPENSSL; +var TERMINAL_MODE = consts.TERMINAL_MODE; +var SIGNALS = consts.SIGNALS; +var BUGS = consts.BUGS; +var BUGGY_IMPLS = consts.BUGGY_IMPLS; +var BUGGY_IMPLS_LEN = BUGGY_IMPLS.length; +var MODULE_VER = require('../package.json').version; +var I = 0; +var IN_INIT = I++; +var IN_GREETING = I++; +var IN_HEADER = I++; +var IN_PACKETBEFORE = I++; +var IN_PACKET = I++; +var IN_PACKETDATA = I++; +var IN_PACKETDATAVERIFY = I++; +var IN_PACKETDATAAFTER = I++; +var OUT_INIT = I++; +var OUT_READY = I++; +var OUT_REKEYING = I++; +var MAX_SEQNO = 4294967295; +var MAX_PACKET_SIZE = 35000; +var MAX_PACKETS_REKEYING = 50; +var EXP_TYPE_HEADER = 0; +var EXP_TYPE_LF = 1; +var EXP_TYPE_BYTES = 2; // Waits until n bytes have been seen +var Z_PARTIAL_FLUSH = zlib.Z_PARTIAL_FLUSH; +var ZLIB_OPTS = { flush: Z_PARTIAL_FLUSH }; + +var RE_KEX_HASH = /-(.+)$/; +var RE_GEX = /^gex-/; +var RE_NULL = /\x00/g; +var RE_GCM = /^aes\d+-gcm/i; + +var IDENT_PREFIX_BUFFER = new Buffer('SSH-'); +var EMPTY_BUFFER = new Buffer(0); +var PING_PACKET = new Buffer([ + MESSAGE.GLOBAL_REQUEST, + // "keepalive@openssh.com" + 0, 0, 0, 21, + 107, 101, 101, 112, 97, 108, 105, 118, 101, 64, 111, 112, 101, 110, 115, + 115, 104, 46, 99, 111, 109, + // Request a reply + 1 +]); +var NEWKEYS_PACKET = new Buffer([MESSAGE.NEWKEYS]); +var USERAUTH_SUCCESS_PACKET = new Buffer([MESSAGE.USERAUTH_SUCCESS]); +var REQUEST_SUCCESS_PACKET = new Buffer([MESSAGE.REQUEST_SUCCESS]); +var REQUEST_FAILURE_PACKET = new Buffer([MESSAGE.REQUEST_FAILURE]); +var NO_TERMINAL_MODES_BUFFER = new Buffer([TERMINAL_MODE.TTY_OP_END]); +var KEXDH_GEX_REQ_PACKET = new Buffer([ + MESSAGE.KEXDH_GEX_REQUEST, + // Minimal size in bits of an acceptable group + 0, 0, 4, 0, // 1024, modp2 + // Preferred size in bits of the group the server will send + 0, 0, 10, 0, // 4096, modp16 + // Maximal size in bits of an acceptable group + 0, 0, 20, 0 // 8192, modp18 +]); + +function DEBUG_NOOP(msg) {} + +function SSH2Stream(cfg) { + if (typeof cfg !== 'object' || cfg === null) + cfg = {}; + + TransformStream.call(this, { + highWaterMark: (typeof cfg.highWaterMark === 'number' + ? cfg.highWaterMark + : 32 * 1024) + }); + + this._needContinue = false; + this.bytesSent = this.bytesReceived = 0; + this.debug = (typeof cfg.debug === 'function' ? cfg.debug : DEBUG_NOOP); + this.server = (cfg.server === true); + this.maxPacketSize = (typeof cfg.maxPacketSize === 'number' + ? cfg.maxPacketSize + : MAX_PACKET_SIZE); + // Bitmap that indicates any bugs the remote side has. This is determined + // by the reported software version. + this.remoteBugs = 0; + + if (this.server) { + // TODO: Remove when we support group exchange for server implementation + this.remoteBugs = BUGS.BAD_DHGEX; + } + + var self = this; + + var hostKeys = cfg.hostKeys; + if (this.server && (typeof hostKeys !== 'object' || hostKeys === null)) + throw new Error('hostKeys must be an object keyed on host key type'); + + this.config = { + // Server + hostKeys: hostKeys, // All keys supported by server + + // Client/Server + ident: 'SSH-2.0-' + + (cfg.ident + || ('ssh2js' + MODULE_VER + (this.server ? 'srv' : ''))), + algorithms: { + kex: ALGORITHMS.KEX, + kexBuf: ALGORITHMS.KEX_BUF, + serverHostKey: ALGORITHMS.SERVER_HOST_KEY, + serverHostKeyBuf: ALGORITHMS.SERVER_HOST_KEY_BUF, + cipher: ALGORITHMS.CIPHER, + cipherBuf: ALGORITHMS.CIPHER_BUF, + hmac: ALGORITHMS.HMAC, + hmacBuf: ALGORITHMS.HMAC_BUF, + compress: ALGORITHMS.COMPRESS, + compressBuf: ALGORITHMS.COMPRESS_BUF + } + }; + // RFC 4253 states the identification string must not contain NULL + this.config.ident.replace(RE_NULL, ''); + + if (this.config.ident.length + 2 /* Account for "\r\n" */ > 255) + throw new Error('ident too long'); + + if (typeof cfg.algorithms === 'object' && cfg.algorithms !== null) { + var algos = cfg.algorithms; + if (Array.isArray(algos.kex) && algos.kex.length > 0) { + this.config.algorithms.kex = algos.kex; + if (!Buffer.isBuffer(algos.kexBuf)) + algos.kexBuf = new Buffer(algos.kex.join(','), 'ascii'); + this.config.algorithms.kexBuf = algos.kexBuf; + } + if (Array.isArray(algos.serverHostKey) && algos.serverHostKey.length > 0) { + this.config.algorithms.serverHostKey = algos.serverHostKey; + if (!Buffer.isBuffer(algos.serverHostKeyBuf)) { + algos.serverHostKeyBuf = new Buffer(algos.serverHostKey.join(','), + 'ascii'); + } + this.config.algorithms.serverHostKeyBuf = algos.serverHostKeyBuf; + } + if (Array.isArray(algos.cipher) && algos.cipher.length > 0) { + this.config.algorithms.cipher = algos.cipher; + if (!Buffer.isBuffer(algos.cipherBuf)) + algos.cipherBuf = new Buffer(algos.cipher.join(','), 'ascii'); + this.config.algorithms.cipherBuf = algos.cipherBuf; + } + if (Array.isArray(algos.hmac) && algos.hmac.length > 0) { + this.config.algorithms.hmac = algos.hmac; + if (!Buffer.isBuffer(algos.hmacBuf)) + algos.hmacBuf = new Buffer(algos.hmac.join(','), 'ascii'); + this.config.algorithms.hmacBuf = algos.hmacBuf; + } + if (Array.isArray(algos.compress) && algos.compress.length > 0) { + this.config.algorithms.compress = algos.compress; + if (!Buffer.isBuffer(algos.compressBuf)) + algos.compressBuf = new Buffer(algos.compress.join(','), 'ascii'); + this.config.algorithms.compressBuf = algos.compressBuf; + } + } + + this.reset(true); + + // Common events + this.on('end', function() { + // Let GC collect any Buffers we were previously storing + self._state = undefined; + self.reset(); + self._state.incoming.hmac.bufCompute = undefined; + self._state.outgoing.bufSeqno = undefined; + }); + this.on('DISCONNECT', function(reason, code, desc, lang) { + onDISCONNECT(self, reason, code, desc, lang); + }); + this.on('KEXINIT', function(init, firstFollows) { + onKEXINIT(self, init, firstFollows); + }); + this.on('NEWKEYS', function() { onNEWKEYS(self); }); + + if (this.server) { + // Server-specific events + this.on('KEXDH_INIT', function(e) { onKEXDH_INIT(self, e); }); + } else { + // Client-specific events + this.on('KEXDH_REPLY', function(info) { onKEXDH_REPLY(self, info); }) + .on('KEXDH_GEX_GROUP', + function(prime, gen) { onKEXDH_GEX_GROUP(self, prime, gen); }); + } + + if (this.server) { + // Greeting displayed before the ssh identification string is sent, this is + // usually ignored by most clients + if (typeof cfg.greeting === 'string' && cfg.greeting.length) { + if (cfg.greeting.slice(-2) === '\r\n') + this.push(cfg.greeting); + else + this.push(cfg.greeting + '\r\n'); + } + // Banner shown after the handshake completes, but before user + // authentication begins + if (typeof cfg.banner === 'string' && cfg.banner.length) { + if (cfg.banner.slice(-2) === '\r\n') + this.banner = cfg.banner; + else + this.banner = cfg.banner + '\r\n'; + } + } + this.debug('DEBUG: Local ident: ' + inspect(this.config.ident)); + this.push(this.config.ident + '\r\n'); + + this._state.incoming.expectedPacket = 'KEXINIT'; +} +inherits(SSH2Stream, TransformStream); + +SSH2Stream.prototype.__read = TransformStream.prototype._read; +SSH2Stream.prototype._read = function(n) { + if (this._needContinue) { + this._needContinue = false; + this.emit('continue'); + } + return this.__read(n); +}; +SSH2Stream.prototype.__push = TransformStream.prototype.push; +SSH2Stream.prototype.push = function(chunk, encoding) { + var ret = this.__push(chunk, encoding); + this._needContinue = (ret === false); + return ret; +}; + +SSH2Stream.prototype._cleanup = function(callback) { + this.reset(); + this.debug('DEBUG: Parser: Malformed packet'); + callback && callback(new Error('Malformed packet')); +}; + +SSH2Stream.prototype._transform = function(chunk, encoding, callback, decomp) { + var skipDecrypt = false; + var doDecryptGCM = false; + var state = this._state; + var instate = state.incoming; + var outstate = state.outgoing; + var expect = instate.expect; + var decrypt = instate.decrypt; + var decompress = instate.decompress; + var chlen = chunk.length; + var chleft = 0; + var debug = this.debug; + var self = this; + var i = 0; + var p = i; + var buffer; + var buf; + var r; + + this.bytesReceived += chlen; + + while (true) { + if (expect.type !== undefined) { + if (i >= chlen) + break; + if (expect.type === EXP_TYPE_BYTES) { + chleft = (chlen - i); + var pktLeft = (expect.buf.length - expect.ptr); + if (pktLeft <= chleft) { + chunk.copy(expect.buf, expect.ptr, i, i + pktLeft); + i += pktLeft; + buffer = expect.buf; + expect.buf = undefined; + expect.ptr = 0; + expect.type = undefined; + } else { + chunk.copy(expect.buf, expect.ptr, i); + expect.ptr += chleft; + i += chleft; + } + continue; + } else if (expect.type === EXP_TYPE_HEADER) { + i += instate.search.push(chunk); + if (expect.type !== undefined) + continue; + } else if (expect.type === EXP_TYPE_LF) { + if (++expect.ptr + 4 /* Account for "SSH-" */ > 255) { + this.reset(); + debug('DEBUG: Parser: Identification string exceeded 255 characters'); + return callback(new Error('Max identification string size exceeded')); + } + if (chunk[i] === 0x0A) { + expect.type = undefined; + if (p < i) { + if (expect.buf === undefined) + expect.buf = chunk.toString('ascii', p, i); + else + expect.buf += chunk.toString('ascii', p, i); + } + buffer = expect.buf; + expect.buf = undefined; + ++i; + } else { + if (++i === chlen && p < i) { + if (expect.buf === undefined) + expect.buf = chunk.toString('ascii', p, i); + else + expect.buf += chunk.toString('ascii', p, i); + } + continue; + } + } + } + + if (instate.status === IN_INIT) { + if (this.server) { + // Retrieve what should be the start of the protocol version exchange + if (!buffer) { + debug('DEBUG: Parser: IN_INIT (waiting for identification begin)'); + expectData(this, EXP_TYPE_BYTES, 4); + } else { + if (buffer[0] === 0x53 // S + && buffer[1] === 0x53 // S + && buffer[2] === 0x48 // H + && buffer[3] === 0x2D) { // - + instate.status = IN_GREETING; + debug('DEBUG: Parser: IN_INIT (waiting for rest of identification)'); + } else { + this.reset(); + debug('DEBUG: Parser: Bad identification start'); + return callback(new Error('Bad identification start')); + } + } + } else { + debug('DEBUG: Parser: IN_INIT'); + // Retrieve any bytes that may come before the protocol version exchange + var ss = instate.search = new StreamSearch(IDENT_PREFIX_BUFFER); + ss.on('info', function onInfo(matched, data, start, end) { + if (data) { + if (instate.greeting === undefined) + instate.greeting = data.toString('binary', start, end); + else + instate.greeting += data.toString('binary', start, end); + } + if (matched) { + expect.type = undefined; + instate.search.removeListener('info', onInfo); + } + }); + ss.maxMatches = 1; + expectData(this, EXP_TYPE_HEADER); + instate.status = IN_GREETING; + } + } else if (instate.status === IN_GREETING) { + debug('DEBUG: Parser: IN_GREETING'); + instate.search = undefined; + // Retrieve the identification bytes after the "SSH-" header + p = i; + expectData(this, EXP_TYPE_LF); + instate.status = IN_HEADER; + } else if (instate.status === IN_HEADER) { + debug('DEBUG: Parser: IN_HEADER'); + buffer = buffer.trim(); + var idxDash = buffer.indexOf('-'); + var idxSpace = buffer.indexOf(' '); + var header = { + // RFC says greeting SHOULD be utf8 + greeting: instate.greeting, + identRaw: 'SSH-' + buffer, + versions: { + protocol: buffer.substr(0, idxDash), + software: (idxSpace === -1 + ? buffer.substring(idxDash + 1) + : buffer.substring(idxDash + 1, idxSpace)) + }, + comments: (idxSpace > -1 ? buffer.substring(idxSpace + 1) : undefined) + }; + instate.greeting = undefined; + + if (header.versions.protocol !== '1.99' + && header.versions.protocol !== '2.0') { + this.reset(); + debug('DEBUG: Parser: protocol version not supported: ' + + header.versions.protocol); + return callback(new Error('Protocol version not supported')); + } else + this.emit('header', header); + + if (instate.status === IN_INIT) { + // We reset from an event handler, possibly due to an unsupported SSH + // protocol version? + return; + } + + var identRaw = header.identRaw; + var software = header.versions.software; + this.debug('DEBUG: Remote ident: ' + inspect(identRaw)); + for (var j = 0, rule; j < BUGGY_IMPLS_LEN; ++j) { + rule = BUGGY_IMPLS[j]; + if (typeof rule[0] === 'string') { + if (software === rule[0]) + this.remoteBugs |= rule[1]; + } else if (rule[0].test(software)) + this.remoteBugs |= rule[1]; + } + instate.identRaw = identRaw; + // Adjust bytesReceived first otherwise it will have an incorrectly larger + // total when we call back into this function after completing KEXINIT + this.bytesReceived -= (chlen - i); + KEXINIT(this, function() { + if (i === chlen) + callback(); + else + self._transform(chunk.slice(i), encoding, callback); + }); + instate.status = IN_PACKETBEFORE; + return; + } else if (instate.status === IN_PACKETBEFORE) { + debug('DEBUG: Parser: IN_PACKETBEFORE (expecting ' + decrypt.size + ')'); + // Wait for the right number of bytes so we can determine the incoming + // packet length + expectData(this, EXP_TYPE_BYTES, decrypt.size, decrypt.buf); + instate.status = IN_PACKET; + } else if (instate.status === IN_PACKET) { + debug('DEBUG: Parser: IN_PACKET'); + doDecryptGCM = (decrypt.instance && decrypt.isGCM); + if (decrypt.instance && !decrypt.isGCM) + buffer = decryptData(this, buffer); + + r = readInt(buffer, 0, this, callback); + if (r === false) + return; + var macSize = (instate.hmac.size || 0); + var fullPacketLen = r + 4 + macSize; + var maxPayloadLen = this.maxPacketSize; + if (decompress.instance) { + // Account for compressed payloads + // This formula is taken from dropbear which derives it from zlib's + // documentation. Explanation from dropbear: + /* For exact details see http://www.zlib.net/zlib_tech.html + * 5 bytes per 16kB block, plus 6 bytes for the stream. + * We might allocate 5 unnecessary bytes here if it's an + * exact multiple. */ + maxPayloadLen += (((this.maxPacketSize / 16384) + 1) * 5 + 6); + } + if (r > maxPayloadLen + // TODO: Change 16 to "MAX(16, decrypt.size)" when/if SSH2 adopts + // 512-bit ciphers + || fullPacketLen < (16 + macSize) + || ((r + (doDecryptGCM ? 0 : 4)) % decrypt.size) !== 0) { + this.disconnect(DISCONNECT_REASON.PROTOCOL_ERROR); + debug('DEBUG: Parser: Bad packet length (' + fullPacketLen + ')'); + return callback(new Error('Bad packet length')); + } + + instate.pktLen = r; + var remainLen = instate.pktLen + 4 - decrypt.size; + if (doDecryptGCM) { + decrypt.instance.setAAD(buffer.slice(0, 4)); + debug('DEBUG: Parser: pktLen:' + + instate.pktLen + + ',remainLen:' + + remainLen); + } else { + instate.padLen = buffer[4]; + debug('DEBUG: Parser: pktLen:' + + instate.pktLen + + ',padLen:' + + instate.padLen + + ',remainLen:' + + remainLen); + } + if (remainLen > 0) { + if (doDecryptGCM) + instate.pktExtra = buffer.slice(4); + else + instate.pktExtra = buffer.slice(5); + // Grab the rest of the packet + expectData(this, EXP_TYPE_BYTES, remainLen); + instate.status = IN_PACKETDATA; + } else if (remainLen < 0) + instate.status = IN_PACKETBEFORE; + else { + // Entire message fit into one block + skipDecrypt = true; + instate.status = IN_PACKETDATA; + continue; + } + } else if (instate.status === IN_PACKETDATA) { + debug('DEBUG: Parser: IN_PACKETDATA'); + doDecryptGCM = (decrypt.instance && decrypt.isGCM); + if (decrypt.instance && !skipDecrypt && !doDecryptGCM) + buffer = decryptData(this, buffer); + else if (skipDecrypt) + skipDecrypt = false; + var padStart = instate.pktLen - instate.padLen - 1; + // TODO: Allocate a Buffer once that is slightly larger than maxPacketSize + // (to accommodate for packet length field and MAC) and re-use that + // instead + if (instate.pktExtra) { + buf = new Buffer(instate.pktExtra.length + buffer.length); + instate.pktExtra.copy(buf); + buffer.copy(buf, instate.pktExtra.length); + instate.payload = buf.slice(0, padStart); + } else { + // Entire message fit into one block + if (doDecryptGCM) + buf = buffer.slice(4); + else + buf = buffer.slice(5); + instate.payload = buffer.slice(5, 5 + padStart); + } + if (instate.hmac.size !== undefined) { + // Wait for hmac hash + debug('DEBUG: Parser: HMAC size:' + instate.hmac.size); + expectData(this, EXP_TYPE_BYTES, instate.hmac.size, instate.hmac.buf); + instate.status = IN_PACKETDATAVERIFY; + instate.packet = buf; + } else + instate.status = IN_PACKETDATAAFTER; + instate.pktExtra = undefined; + buf = undefined; + } else if (instate.status === IN_PACKETDATAVERIFY) { + debug('DEBUG: Parser: IN_PACKETDATAVERIFY'); + // Verify packet data integrity + if (hmacVerify(this, buffer)) { + debug('DEBUG: Parser: IN_PACKETDATAVERIFY (Valid HMAC)'); + instate.status = IN_PACKETDATAAFTER; + instate.packet = undefined; + } else { + this.reset(); + debug('DEBUG: Parser: IN_PACKETDATAVERIFY (Invalid HMAC)'); + return callback(new Error('Invalid HMAC')); + } + } else if (instate.status === IN_PACKETDATAAFTER) { + if (decompress.instance) { + if (!decomp) { + debug('DEBUG: Parser: Decompressing'); + decompress.instance.write(instate.payload); + var decompBuf = []; + var decompBufLen = 0; + decompress.instance.on('readable', function() { + var buf; + while (buf = this.read()) { + decompBuf.push(buf); + decompBufLen += buf.length; + } + }).flush(Z_PARTIAL_FLUSH, function() { + decompress.instance.removeAllListeners('readable'); + if (decompBuf.length === 1) + instate.payload = decompBuf[0]; + else + instate.payload = Buffer.concat(decompBuf, decompBufLen); + decompBuf = null; + var nextSlice; + if (i === chlen) + nextSlice = EMPTY_BUFFER; // Avoid slicing a zero-length buffer + else + nextSlice = chunk.slice(i); + self._transform(nextSlice, encoding, callback, true); + }); + return; + } else { + // Make sure we reset this after this first time in the loop, + // otherwise we could end up trying to interpret as-is another + // compressed packet that is within the same chunk + decomp = false; + } + } + + this.emit('packet'); + + var ptype = instate.payload[0]; + + if (debug !== DEBUG_NOOP) { + var msgPacket = 'DEBUG: Parser: IN_PACKETDATAAFTER, packet: '; + var kexdh = state.kexdh; + var authMethod = state.authsQueue[0]; + var msgPktType = null; + + if (outstate.status === OUT_REKEYING + && !(ptype <= 4 || (ptype >= 20 && ptype <= 49))) + msgPacket += '(enqueued) '; + + if (ptype === MESSAGE.KEXDH_INIT) { + if (kexdh === 'group') + msgPktType = 'KEXDH_INIT'; + else if (kexdh[0] === 'e') + msgPktType = 'KEXECDH_INIT'; + else + msgPktType = 'KEXDH_GEX_REQUEST'; + } else if (ptype === MESSAGE.KEXDH_REPLY) { + if (kexdh === 'group') + msgPktType = 'KEXDH_REPLY'; + else if (kexdh[0] === 'e') + msgPktType = 'KEXECDH_REPLY'; + else + msgPktType = 'KEXDH_GEX_GROUP'; + } else if (ptype === MESSAGE.KEXDH_GEX_GROUP) + msgPktType = 'KEXDH_GEX_GROUP'; + else if (ptype === MESSAGE.KEXDH_GEX_REPLY) + msgPktType = 'KEXDH_GEX_REPLY'; + else if (ptype === 60) { + if (authMethod === 'password') + msgPktType = 'USERAUTH_PASSWD_CHANGEREQ'; + else if (authMethod === 'keyboard-interactive') + msgPktType = 'USERAUTH_INFO_REQUEST'; + else if (authMethod === 'publickey') + msgPktType = 'USERAUTH_PK_OK'; + else + msgPktType = 'UNKNOWN PACKET 60'; + } else if (ptype === 61) { + if (authMethod === 'keyboard-interactive') + msgPktType = 'USERAUTH_INFO_RESPONSE'; + else + msgPktType = 'UNKNOWN PACKET 61'; + } + + if (msgPktType === null) + msgPktType = MESSAGE[ptype]; + + // Don't write debug output for messages we custom make in parsePacket() + if (ptype !== MESSAGE.CHANNEL_OPEN + && ptype !== MESSAGE.CHANNEL_REQUEST + && ptype !== MESSAGE.CHANNEL_SUCCESS + && ptype !== MESSAGE.CHANNEL_FAILURE + && ptype !== MESSAGE.CHANNEL_EOF + && ptype !== MESSAGE.CHANNEL_CLOSE + && ptype !== MESSAGE.CHANNEL_DATA + && ptype !== MESSAGE.CHANNEL_EXTENDED_DATA + && ptype !== MESSAGE.CHANNEL_WINDOW_ADJUST + && ptype !== MESSAGE.DISCONNECT + && ptype !== MESSAGE.USERAUTH_REQUEST) + debug(msgPacket + msgPktType); + } + + // Only parse packet if we are not re-keying or the packet is not a + // transport layer packet needed for re-keying + if (outstate.status === OUT_READY + || ptype <= 4 + || (ptype >= 20 && ptype <= 49)) { + if (parsePacket(this, callback) === false) + return; + + if (instate.status === IN_INIT) { + // We were reset due to some error/disagreement ? + return; + } + } else if (outstate.status === OUT_REKEYING) { + if (instate.rekeyQueue.length === MAX_PACKETS_REKEYING) { + debug('DEBUG: Parser: Max incoming re-key queue length reached'); + this.disconnect(DISCONNECT_REASON.PROTOCOL_ERROR); + return callback( + new Error('Incoming re-key queue length limit reached') + ); + } + + // Make sure to record the sequence number in case we need it later on + // when we drain the queue (e.g. unknown packet) + var seqno = instate.seqno; + if (++instate.seqno > MAX_SEQNO) + instate.seqno = 0; + + instate.rekeyQueue.push(seqno, instate.payload); + } + + instate.status = IN_PACKETBEFORE; + instate.payload = undefined; + } + if (buffer !== undefined) + buffer = undefined; + } + + callback(); +}; + +SSH2Stream.prototype.reset = function(noend) { + if (this._state) { + var state = this._state; + state.incoming.status = IN_INIT; + state.outgoing.status = OUT_INIT; + } else { + this._state = { + authsQueue: [], + hostkeyFormat: undefined, + kex: undefined, + kexdh: undefined, + + incoming: { + status: IN_INIT, + expectedPacket: undefined, + search: undefined, + greeting: undefined, + seqno: 0, + pktLen: undefined, + padLen: undefined, + pktExtra: undefined, + payload: undefined, + packet: undefined, + kexinit: undefined, + identRaw: undefined, + rekeyQueue: [], + ignoreNext: false, + + expect: { + amount: undefined, + type: undefined, + ptr: 0, + buf: undefined + }, + + decrypt: { + instance: false, + size: 8, + isGCM: false, + iv: undefined, // GCM + key: undefined, // GCM + buf: undefined, + type: undefined + }, + + hmac: { + size: undefined, + key: undefined, + buf: undefined, + bufCompute: new Buffer(9), + type: false + }, + + decompress: { + instance: false, + type: false + } + }, + + outgoing: { + status: OUT_INIT, + seqno: 0, + bufSeqno: new Buffer(4), + rekeyQueue: [], + kexinit: undefined, + kexsecret: undefined, + pubkey: undefined, + exchangeHash: undefined, + sessionId: undefined, + sentNEWKEYS: false, + + encrypt: { + instance: false, + size: 8, + isGCM: false, + iv: undefined, // GCM + key: undefined, // GCM + type: undefined + }, + + hmac: { + size: undefined, + key: undefined, + buf: undefined, + type: false + }, + + compress: { + instance: false, + type: false + } + } + }; + } + if (!noend) { + if (this.readable) + this.push(null); + } +}; + +// Common methods +// Global +SSH2Stream.prototype.disconnect = function(reason) { + /* + byte SSH_MSG_DISCONNECT + uint32 reason code + string description in ISO-10646 UTF-8 encoding + string language tag + */ + var buf = new Buffer(1 + 4 + 4 + 4); + + buf.fill(0); + buf[0] = MESSAGE.DISCONNECT; + + if (DISCONNECT_REASON[reason] === undefined) + reason = DISCONNECT_REASON.BY_APPLICATION; + buf.writeUInt32BE(reason, 1, true); + + this.debug('DEBUG: Outgoing: Writing DISCONNECT (' + + DISCONNECT_REASON[reason] + + ')'); + send(this, buf); + this.reset(); + + return false; +}; +SSH2Stream.prototype.ping = function() { + this.debug('DEBUG: Outgoing: Writing ping (GLOBAL_REQUEST: keepalive@openssh.com)'); + return send(this, PING_PACKET); +}; +SSH2Stream.prototype.rekey = function() { + var status = this._state.outgoing.status; + if (status === OUT_REKEYING) + throw new Error('A re-key is already in progress'); + else if (status !== OUT_READY) + throw new Error('Cannot re-key yet'); + + this.debug('DEBUG: Outgoing: Starting re-key'); + return KEXINIT(this); +}; + +// 'ssh-connection' service-specific +SSH2Stream.prototype.requestSuccess = function(data) { + var buf; + if (Buffer.isBuffer(data)) { + buf = new Buffer(1 + data.length); + + buf[0] = MESSAGE.REQUEST_SUCCESS; + + data.copy(buf, 1); + } else + buf = REQUEST_SUCCESS_PACKET; + + this.debug('DEBUG: Outgoing: Writing REQUEST_SUCCESS'); + return send(this, buf); +}; +SSH2Stream.prototype.requestFailure = function() { + this.debug('DEBUG: Outgoing: Writing REQUEST_FAILURE'); + return send(this, REQUEST_FAILURE_PACKET); +}; +SSH2Stream.prototype.channelSuccess = function(chan) { + // Does not consume window space + var buf = new Buffer(1 + 4); + + buf[0] = MESSAGE.CHANNEL_SUCCESS; + + buf.writeUInt32BE(chan, 1, true); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_SUCCESS (' + chan + ')'); + return send(this, buf); +}; +SSH2Stream.prototype.channelFailure = function(chan) { + // Does not consume window space + var buf = new Buffer(1 + 4); + + buf[0] = MESSAGE.CHANNEL_FAILURE; + + buf.writeUInt32BE(chan, 1, true); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_FAILURE (' + chan + ')'); + return send(this, buf); +}; +SSH2Stream.prototype.channelEOF = function(chan) { + // Does not consume window space + var buf = new Buffer(1 + 4); + + buf[0] = MESSAGE.CHANNEL_EOF; + + buf.writeUInt32BE(chan, 1, true); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_EOF (' + chan + ')'); + return send(this, buf); +}; +SSH2Stream.prototype.channelClose = function(chan) { + // Does not consume window space + var buf = new Buffer(1 + 4); + + buf[0] = MESSAGE.CHANNEL_CLOSE; + + buf.writeUInt32BE(chan, 1, true); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_CLOSE (' + chan + ')'); + return send(this, buf); +}; +SSH2Stream.prototype.channelWindowAdjust = function(chan, amount) { + // Does not consume window space + var buf = new Buffer(1 + 4 + 4); + + buf[0] = MESSAGE.CHANNEL_WINDOW_ADJUST; + + buf.writeUInt32BE(chan, 1, true); + + buf.writeUInt32BE(amount, 5, true); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_WINDOW_ADJUST (' + + chan + + ', ' + + amount + + ')'); + return send(this, buf); +}; +SSH2Stream.prototype.channelData = function(chan, data) { + var dataIsBuffer = Buffer.isBuffer(data); + var dataLen = (dataIsBuffer ? data.length : Buffer.byteLength(data)); + var buf = new Buffer(1 + 4 + 4 + dataLen); + + buf[0] = MESSAGE.CHANNEL_DATA; + + buf.writeUInt32BE(chan, 1, true); + + buf.writeUInt32BE(dataLen, 5, true); + if (dataIsBuffer) + data.copy(buf, 9); + else + buf.write(data, 9, dataLen, 'utf8'); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_DATA (' + chan + ')'); + return send(this, buf); +}; +SSH2Stream.prototype.channelExtData = function(chan, data, type) { + var dataIsBuffer = Buffer.isBuffer(data); + var dataLen = (dataIsBuffer ? data.length : Buffer.byteLength(data)); + var buf = new Buffer(1 + 4 + 4 + 4 + dataLen); + + buf[0] = MESSAGE.CHANNEL_EXTENDED_DATA; + + buf.writeUInt32BE(chan, 1, true); + + buf.writeUInt32BE(type, 5, true); + + buf.writeUInt32BE(dataLen, 9, true); + if (dataIsBuffer) + data.copy(buf, 13); + else + buf.write(data, 13, dataLen, 'utf8'); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_EXTENDED_DATA (' + chan + ')'); + return send(this, buf); +}; +SSH2Stream.prototype.channelOpenConfirm = function(remoteChan, localChan, + initWindow, maxPacket) { + var buf = new Buffer(1 + 4 + 4 + 4 + 4); + + buf[0] = MESSAGE.CHANNEL_OPEN_CONFIRMATION; + + buf.writeUInt32BE(remoteChan, 1, true); + + buf.writeUInt32BE(localChan, 5, true); + + buf.writeUInt32BE(initWindow, 9, true); + + buf.writeUInt32BE(maxPacket, 13, true); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_OPEN_CONFIRMATION (r:' + + remoteChan + + ', l:' + + localChan + + ')'); + return send(this, buf); +}; +SSH2Stream.prototype.channelOpenFail = function(remoteChan, reason, desc, + lang) { + if (typeof desc !== 'string') + desc = ''; + if (typeof lang !== 'string') + lang = ''; + + var descLen = Buffer.byteLength(desc); + var langLen = Buffer.byteLength(lang); + var p = 9; + var buf = new Buffer(1 + 4 + 4 + 4 + descLen + 4 + langLen); + + buf[0] = MESSAGE.CHANNEL_OPEN_FAILURE; + + buf.writeUInt32BE(remoteChan, 1, true); + + buf.writeUInt32BE(reason, 5, true); + + buf.writeUInt32BE(descLen, p, true); + p += 4; + if (descLen) { + buf.write(desc, p, descLen, 'utf8'); + p += descLen; + } + + buf.writeUInt32BE(langLen, p, true); + if (langLen) + buf.write(lang, p += 4, langLen, 'ascii'); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_OPEN_FAILURE (' + + remoteChan + + ')'); + return send(this, buf); +}; + +// Client-specific methods +// Global +SSH2Stream.prototype.service = function(svcName) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var svcNameLen = Buffer.byteLength(svcName); + var buf = new Buffer(1 + 4 + svcNameLen); + + buf[0] = MESSAGE.SERVICE_REQUEST; + + buf.writeUInt32BE(svcNameLen, 1, true); + buf.write(svcName, 5, svcNameLen, 'ascii'); + + this.debug('DEBUG: Outgoing: Writing SERVICE_REQUEST (' + svcName + ')'); + return send(this, buf); +}; +// 'ssh-connection' service-specific +SSH2Stream.prototype.tcpipForward = function(bindAddr, bindPort, wantReply) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var addrlen = Buffer.byteLength(bindAddr); + var buf = new Buffer(1 + 4 + 13 + 1 + 4 + addrlen + 4); + + buf[0] = MESSAGE.GLOBAL_REQUEST; + + buf.writeUInt32BE(13, 1, true); + buf.write('tcpip-forward', 5, 13, 'ascii'); + + buf[18] = (wantReply === undefined || wantReply === true ? 1 : 0); + + buf.writeUInt32BE(addrlen, 19, true); + buf.write(bindAddr, 23, addrlen, 'ascii'); + + buf.writeUInt32BE(bindPort, 23 + addrlen, true); + + this.debug('DEBUG: Outgoing: Writing GLOBAL_REQUEST (tcpip-forward)'); + return send(this, buf); +}; +SSH2Stream.prototype.cancelTcpipForward = function(bindAddr, bindPort, + wantReply) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var addrlen = Buffer.byteLength(bindAddr); + var buf = new Buffer(1 + 4 + 20 + 1 + 4 + addrlen + 4); + + buf[0] = MESSAGE.GLOBAL_REQUEST; + + buf.writeUInt32BE(20, 1, true); + buf.write('cancel-tcpip-forward', 5, 20, 'ascii'); + + buf[25] = (wantReply === undefined || wantReply === true ? 1 : 0); + + buf.writeUInt32BE(addrlen, 26, true); + buf.write(bindAddr, 30, addrlen, 'ascii'); + + buf.writeUInt32BE(bindPort, 30 + addrlen, true); + + this.debug('DEBUG: Outgoing: Writing GLOBAL_REQUEST (cancel-tcpip-forward)'); + return send(this, buf); +}; +SSH2Stream.prototype.openssh_streamLocalForward = function(socketPath, + wantReply) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var pathlen = Buffer.byteLength(pathlen); + var buf = new Buffer(1 + 4 + 31 + 1 + 4 + pathlen); + + buf[0] = MESSAGE.GLOBAL_REQUEST; + + buf.writeUInt32BE(31, 1, true); + buf.write('streamlocal-forward@openssh.com', 5, 31, 'ascii'); + + buf[36] = (wantReply === undefined || wantReply === true ? 1 : 0); + + buf.writeUInt32BE(pathlen, 37, true); + buf.write(socketPath, 41, pathlen, 'utf8'); + + this.debug('DEBUG: Outgoing: Writing GLOBAL_REQUEST (streamlocal-forward@openssh.com)'); + return send(this, buf); +}; +SSH2Stream.prototype.openssh_cancelStreamLocalForward = function(socketPath, + wantReply) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var pathlen = Buffer.byteLength(pathlen); + var buf = new Buffer(1 + 4 + 38 + 1 + 4 + pathlen); + + buf[0] = MESSAGE.GLOBAL_REQUEST; + + buf.writeUInt32BE(38, 1, true); + buf.write('cancel-streamlocal-forward@openssh.com', 5, 38, 'ascii'); + + buf[43] = (wantReply === undefined || wantReply === true ? 1 : 0); + + buf.writeUInt32BE(pathlen, 44, true); + buf.write(socketPath, 48, pathlen, 'utf8'); + + this.debug('DEBUG: Outgoing: Writing GLOBAL_REQUEST (cancel-streamlocal-forward@openssh.com)'); + return send(this, buf); +}; +SSH2Stream.prototype.directTcpip = function(chan, initWindow, maxPacket, cfg) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var srclen = Buffer.byteLength(cfg.srcIP); + var dstlen = Buffer.byteLength(cfg.dstIP); + var p = 29; + var buf = new Buffer(1 + 4 + 12 + 4 + 4 + 4 + 4 + srclen + 4 + 4 + dstlen + + 4); + + buf[0] = MESSAGE.CHANNEL_OPEN; + + buf.writeUInt32BE(12, 1, true); + buf.write('direct-tcpip', 5, 12, 'ascii'); + + buf.writeUInt32BE(chan, 17, true); + + buf.writeUInt32BE(initWindow, 21, true); + + buf.writeUInt32BE(maxPacket, 25, true); + + buf.writeUInt32BE(dstlen, p, true); + buf.write(cfg.dstIP, p += 4, dstlen, 'ascii'); + + buf.writeUInt32BE(cfg.dstPort, p += dstlen, true); + + buf.writeUInt32BE(srclen, p += 4, true); + buf.write(cfg.srcIP, p += 4, srclen, 'ascii'); + + buf.writeUInt32BE(cfg.srcPort, p += srclen, true); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_OPEN (' + + chan + + ', direct-tcpip)'); + return send(this, buf); +}; +SSH2Stream.prototype.openssh_directStreamLocal = function(chan, initWindow, + maxPacket, cfg) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var pathlen = Buffer.byteLength(cfg.socketPath); + var p = 47; + var buf = new Buffer(1 + 4 + 30 + 4 + 4 + 4 + 4 + pathlen + 4); + + buf[0] = MESSAGE.CHANNEL_OPEN; + + buf.writeUInt32BE(30, 1, true); + buf.write('direct-streamlocal@openssh.com', 5, 30, 'ascii'); + + buf.writeUInt32BE(chan, 35, true); + + buf.writeUInt32BE(initWindow, 39, true); + + buf.writeUInt32BE(maxPacket, 43, true); + + buf.writeUInt32BE(pathlen, p, true); + buf.write(cfg.socketPath, p += 4, pathlen, 'utf8'); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_OPEN (' + + chan + + ', direct-streamlocal@openssh.com)'); + return send(this, buf); +}; +SSH2Stream.prototype.openssh_noMoreSessions = function(wantReply) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var buf = new Buffer(1 + 4 + 28 + 1); + + buf[0] = MESSAGE.GLOBAL_REQUEST; + + buf.writeUInt32BE(28, 1, true); + buf.write('no-more-sessions@openssh.com', 5, 28, 'ascii'); + + buf[33] = (wantReply === undefined || wantReply === true ? 1 : 0); + + this.debug('DEBUG: Outgoing: Writing GLOBAL_REQUEST (no-more-sessions@openssh.com)'); + return send(this, buf); +}; +SSH2Stream.prototype.session = function(chan, initWindow, maxPacket) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + // Does not consume window space + var buf = new Buffer(1 + 4 + 7 + 4 + 4 + 4); + + buf[0] = MESSAGE.CHANNEL_OPEN; + + buf.writeUInt32BE(7, 1, true); + buf.write('session', 5, 7, 'ascii'); + + buf.writeUInt32BE(chan, 12, true); + + buf.writeUInt32BE(initWindow, 16, true); + + buf.writeUInt32BE(maxPacket, 20, true); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_OPEN (' + + chan + + ', session)'); + return send(this, buf); +}; +SSH2Stream.prototype.windowChange = function(chan, rows, cols, height, width) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + // Does not consume window space + var buf = new Buffer(1 + 4 + 4 + 13 + 1 + 4 + 4 + 4 + 4); + + buf[0] = MESSAGE.CHANNEL_REQUEST; + + buf.writeUInt32BE(chan, 1, true); + + buf.writeUInt32BE(13, 5, true); + buf.write('window-change', 9, 13, 'ascii'); + + buf[22] = 0; + + buf.writeUInt32BE(cols, 23, true); + + buf.writeUInt32BE(rows, 27, true); + + buf.writeUInt32BE(width, 31, true); + + buf.writeUInt32BE(height, 35, true); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_REQUEST (' + + chan + + ', window-change)'); + return send(this, buf); +}; +SSH2Stream.prototype.pty = function(chan, rows, cols, height, + width, term, modes, wantReply) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + // Does not consume window space + if (!term || !term.length) + term = 'vt100'; + if (modes + && !Buffer.isBuffer(modes) + && !Array.isArray(modes) + && typeof modes === 'object') + modes = modesToBytes(modes); + if (!modes || !modes.length) + modes = NO_TERMINAL_MODES_BUFFER; + + var termLen = term.length; + var modesLen = modes.length; + var p = 21; + var buf = new Buffer(1 + 4 + 4 + 7 + 1 + 4 + termLen + 4 + 4 + 4 + 4 + 4 + + modesLen); + + buf[0] = MESSAGE.CHANNEL_REQUEST; + + buf.writeUInt32BE(chan, 1, true); + + buf.writeUInt32BE(7, 5, true); + buf.write('pty-req', 9, 7, 'ascii'); + + buf[16] = (wantReply === undefined || wantReply === true ? 1 : 0); + + buf.writeUInt32BE(termLen, 17, true); + buf.write(term, 21, termLen, 'utf8'); + + buf.writeUInt32BE(cols, p += termLen, true); + + buf.writeUInt32BE(rows, p += 4, true); + + buf.writeUInt32BE(width, p += 4, true); + + buf.writeUInt32BE(height, p += 4, true); + + buf.writeUInt32BE(modesLen, p += 4, true); + p += 4; + if (Array.isArray(modes)) { + for (var i = 0; i < modesLen; ++i) + buf[p++] = modes[i]; + } else if (Buffer.isBuffer(modes)) { + modes.copy(buf, p); + } + + this.debug('DEBUG: Outgoing: Writing CHANNEL_REQUEST (' + + chan + + ', pty-req)'); + return send(this, buf); +}; +SSH2Stream.prototype.shell = function(chan, wantReply) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + // Does not consume window space + var buf = new Buffer(1 + 4 + 4 + 5 + 1); + + buf[0] = MESSAGE.CHANNEL_REQUEST; + + buf.writeUInt32BE(chan, 1, true); + + buf.writeUInt32BE(5, 5, true); + buf.write('shell', 9, 5, 'ascii'); + + buf[14] = (wantReply === undefined || wantReply === true ? 1 : 0); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_REQUEST (' + + chan + + ', shell)'); + return send(this, buf); +}; +SSH2Stream.prototype.exec = function(chan, cmd, wantReply) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + // Does not consume window space + var cmdlen = (Buffer.isBuffer(cmd) ? cmd.length : Buffer.byteLength(cmd)); + var buf = new Buffer(1 + 4 + 4 + 4 + 1 + 4 + cmdlen); + + buf[0] = MESSAGE.CHANNEL_REQUEST; + + buf.writeUInt32BE(chan, 1, true); + + buf.writeUInt32BE(4, 5, true); + buf.write('exec', 9, 4, 'ascii'); + + buf[13] = (wantReply === undefined || wantReply === true ? 1 : 0); + + buf.writeUInt32BE(cmdlen, 14, true); + if (Buffer.isBuffer(cmd)) + cmd.copy(buf, 18); + else + buf.write(cmd, 18, cmdlen, 'utf8'); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_REQUEST (' + + chan + + ', exec)'); + return send(this, buf); +}; +SSH2Stream.prototype.signal = function(chan, signal) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + // Does not consume window space + signal = signal.toUpperCase(); + if (signal.slice(0, 3) === 'SIG') + signal = signal.substring(3); + + if (SIGNALS.indexOf(signal) === -1) + throw new Error('Invalid signal: ' + signal); + + var signalLen = signal.length; + var buf = new Buffer(1 + 4 + 4 + 6 + 1 + 4 + signalLen); + + buf[0] = MESSAGE.CHANNEL_REQUEST; + + buf.writeUInt32BE(chan, 1, true); + + buf.writeUInt32BE(6, 5, true); + buf.write('signal', 9, 6, 'ascii'); + + buf[15] = 0; + + buf.writeUInt32BE(signalLen, 16, true); + buf.write(signal, 20, signalLen, 'ascii'); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_REQUEST (' + + chan + + ', signal)'); + return send(this, buf); +}; +SSH2Stream.prototype.env = function(chan, key, val, wantReply) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + // Does not consume window space + var keyLen = Buffer.byteLength(key); + var valLen = (Buffer.isBuffer(val) ? val.length : Buffer.byteLength(val)); + var buf = new Buffer(1 + 4 + 4 + 3 + 1 + 4 + keyLen + 4 + valLen); + + buf[0] = MESSAGE.CHANNEL_REQUEST; + + buf.writeUInt32BE(chan, 1, true); + + buf.writeUInt32BE(3, 5, true); + buf.write('env', 9, 3, 'ascii'); + + buf[12] = (wantReply === undefined || wantReply === true ? 1 : 0); + + buf.writeUInt32BE(keyLen, 13, true); + buf.write(key, 17, keyLen, 'ascii'); + + buf.writeUInt32BE(valLen, 17 + keyLen, true); + if (Buffer.isBuffer(val)) + val.copy(buf, 17 + keyLen + 4); + else + buf.write(val, 17 + keyLen + 4, valLen, 'utf8'); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_REQUEST (' + + chan + + ', env)'); + return send(this, buf); +}; +SSH2Stream.prototype.x11Forward = function(chan, cfg, wantReply) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + // Does not consume window space + var protolen = Buffer.byteLength(cfg.protocol); + var cookielen = Buffer.byteLength(cfg.cookie); + var buf = new Buffer(1 + 4 + 4 + 7 + 1 + 1 + 4 + protolen + 4 + cookielen + + 4); + + buf[0] = MESSAGE.CHANNEL_REQUEST; + + buf.writeUInt32BE(chan, 1, true); + + buf.writeUInt32BE(7, 5, true); + buf.write('x11-req', 9, 7, 'ascii'); + + buf[16] = (wantReply === undefined || wantReply === true ? 1 : 0); + + buf[17] = (cfg.single ? 1 : 0); + + buf.writeUInt32BE(protolen, 18, true); + var bp = 22; + if (Buffer.isBuffer(cfg.protocol)) + cfg.protocol.copy(buf, bp); + else + buf.write(cfg.protocol, bp, protolen, 'utf8'); + bp += protolen; + + buf.writeUInt32BE(cookielen, bp, true); + bp += 4; + if (Buffer.isBuffer(cfg.cookie)) + cfg.cookie.copy(buf, bp); + else + buf.write(cfg.cookie, bp, cookielen, 'utf8'); + bp += cookielen; + + buf.writeUInt32BE((cfg.screen || 0), bp, true); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_REQUEST (' + + chan + + ', x11-req)'); + return send(this, buf); +}; +SSH2Stream.prototype.subsystem = function(chan, name, wantReply) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + // Does not consume window space + var nameLen = Buffer.byteLength(name); + var buf = new Buffer(1 + 4 + 4 + 9 + 1 + 4 + nameLen); + + buf[0] = MESSAGE.CHANNEL_REQUEST; + + buf.writeUInt32BE(chan, 1, true); + + buf.writeUInt32BE(9, 5, true); + buf.write('subsystem', 9, 9, 'ascii'); + + buf[18] = (wantReply === undefined || wantReply === true ? 1 : 0); + + buf.writeUInt32BE(nameLen, 19, true); + buf.write(name, 23, nameLen, 'ascii'); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_REQUEST (' + + chan + + ', subsystem: ' + + name + + ')'); + return send(this, buf); +}; +SSH2Stream.prototype.openssh_agentForward = function(chan, wantReply) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + // Does not consume window space + var buf = new Buffer(1 + 4 + 4 + 26 + 1); + + buf[0] = MESSAGE.CHANNEL_REQUEST; + + buf.writeUInt32BE(chan, 1, true); + + buf.writeUInt32BE(26, 5, true); + buf.write('auth-agent-req@openssh.com', 9, 26, 'ascii'); + + buf[35] = (wantReply === undefined || wantReply === true ? 1 : 0); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_REQUEST (' + + chan + + ', auth-agent-req@openssh.com)'); + return send(this, buf); +}; +// 'ssh-userauth' service-specific +SSH2Stream.prototype.authPassword = function(username, password) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var userLen = Buffer.byteLength(username); + var passLen = Buffer.byteLength(password); + var p = 0; + var buf = new Buffer(1 + + 4 + userLen + + 4 + 14 // "ssh-connection" + + 4 + 8 // "password" + + 1 + + 4 + passLen); + + buf[p] = MESSAGE.USERAUTH_REQUEST; + + buf.writeUInt32BE(userLen, ++p, true); + buf.write(username, p += 4, userLen, 'utf8'); + + buf.writeUInt32BE(14, p += userLen, true); + buf.write('ssh-connection', p += 4, 14, 'ascii'); + + buf.writeUInt32BE(8, p += 14, true); + buf.write('password', p += 4, 8, 'ascii'); + + buf[p += 8] = 0; + + buf.writeUInt32BE(passLen, ++p, true); + buf.write(password, p += 4, passLen, 'utf8'); + + this._state.authsQueue.push('password'); + this.debug('DEBUG: Outgoing: Writing USERAUTH_REQUEST (password)'); + return send(this, buf); +}; +SSH2Stream.prototype.authPK = function(username, pubKey, cbSign) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var self = this; + var outstate = this._state.outgoing; + var pubKeyFullType; + + if (pubKey.public) { + pubKeyFullType = pubKey.fulltype; + pubKey = pubKey.public; + } else { + pubKeyFullType = pubKey.toString('ascii', + 4, + 4 + pubKey.readUInt32BE(0, true)); + } + + var userLen = Buffer.byteLength(username); + var algoLen = Buffer.byteLength(pubKeyFullType); + var pubKeyLen = pubKey.length; + var sesLen = outstate.sessionId.length; + var p = 0; + var buf = new Buffer((cbSign ? 4 + sesLen : 0) + + 1 + + 4 + userLen + + 4 + 14 // "ssh-connection" + + 4 + 9 // "publickey" + + 1 + + 4 + algoLen + + 4 + pubKeyLen + ); + + if (cbSign) { + buf.writeUInt32BE(sesLen, p, true); + outstate.sessionId.copy(buf, p += 4); + buf[p += sesLen] = MESSAGE.USERAUTH_REQUEST; + } else + buf[p] = MESSAGE.USERAUTH_REQUEST; + + buf.writeUInt32BE(userLen, ++p, true); + buf.write(username, p += 4, userLen, 'utf8'); + + buf.writeUInt32BE(14, p += userLen, true); + buf.write('ssh-connection', p += 4, 14, 'ascii'); + + buf.writeUInt32BE(9, p += 14, true); + buf.write('publickey', p += 4, 9, 'ascii'); + + buf[p += 9] = (cbSign ? 1 : 0); + + buf.writeUInt32BE(algoLen, ++p, true); + buf.write(pubKeyFullType, p += 4, algoLen, 'ascii'); + + buf.writeUInt32BE(pubKeyLen, p += algoLen, true); + pubKey.copy(buf, p += 4); + + if (!cbSign) { + this._state.authsQueue.push('publickey'); + this.debug('DEBUG: Outgoing: Writing USERAUTH_REQUEST (publickey -- check)'); + return send(this, buf); + } + + cbSign(buf, function(signature) { + if (pubKeyFullType === 'ssh-dss') { + signature = DSASigBERToBare(signature); + } else if (pubKeyFullType !== 'ssh-rsa') { + // ECDSA + signature = ECDSASigASN1ToSSH(signature); + } + + var sigLen = signature.length; + var sigbuf = new Buffer(1 + + 4 + userLen + + 4 + 14 // "ssh-connection" + + 4 + 9 // "publickey" + + 1 + + 4 + algoLen + + 4 + pubKeyLen + + 4 // 4 + algoLen + 4 + sigLen + + 4 + algoLen + + 4 + sigLen); + + p = 0; + + sigbuf[p] = MESSAGE.USERAUTH_REQUEST; + + sigbuf.writeUInt32BE(userLen, ++p, true); + sigbuf.write(username, p += 4, userLen, 'utf8'); + + sigbuf.writeUInt32BE(14, p += userLen, true); + sigbuf.write('ssh-connection', p += 4, 14, 'ascii'); + + sigbuf.writeUInt32BE(9, p += 14, true); + sigbuf.write('publickey', p += 4, 9, 'ascii'); + + sigbuf[p += 9] = 1; + + sigbuf.writeUInt32BE(algoLen, ++p, true); + sigbuf.write(pubKeyFullType, p += 4, algoLen, 'ascii'); + + sigbuf.writeUInt32BE(pubKeyLen, p += algoLen, true); + pubKey.copy(sigbuf, p += 4); + sigbuf.writeUInt32BE(4 + algoLen + 4 + sigLen, p += pubKeyLen, true); + sigbuf.writeUInt32BE(algoLen, p += 4, true); + sigbuf.write(pubKeyFullType, p += 4, algoLen, 'ascii'); + sigbuf.writeUInt32BE(sigLen, p += algoLen, true); + signature.copy(sigbuf, p += 4); + + // Servers shouldn't send packet type 60 in response to signed publickey + // attempts, but if they do, interpret as type 60. + self._state.authsQueue.push('publickey'); + self.debug('DEBUG: Outgoing: Writing USERAUTH_REQUEST (publickey)'); + return send(self, sigbuf); + }); + return true; +}; +SSH2Stream.prototype.authHostbased = function(username, pubKey, hostname, + userlocal, cbSign) { + // TODO: Make DRY by sharing similar code with authPK() + + if (this.server) + throw new Error('Client-only method called in server mode'); + + var self = this; + var outstate = this._state.outgoing; + var pubKeyFullType; + + if (pubKey.public) { + pubKeyFullType = pubKey.fulltype; + pubKey = pubKey.public; + } else { + pubKeyFullType = pubKey.toString('ascii', + 4, + 4 + pubKey.readUInt32BE(0, true)); + } + + var userLen = Buffer.byteLength(username); + var algoLen = Buffer.byteLength(pubKeyFullType); + var pubKeyLen = pubKey.length; + var sesLen = outstate.sessionId.length; + var hostnameLen = Buffer.byteLength(hostname); + var userlocalLen = Buffer.byteLength(userlocal); + var p = 0; + var buf = new Buffer(4 + sesLen + + 1 + + 4 + userLen + + 4 + 14 // "ssh-connection" + + 4 + 9 // "hostbased" + + 4 + algoLen + + 4 + pubKeyLen + + 4 + hostnameLen + + 4 + userlocalLen + ); + + buf.writeUInt32BE(sesLen, p, true); + outstate.sessionId.copy(buf, p += 4); + + buf[p += sesLen] = MESSAGE.USERAUTH_REQUEST; + + buf.writeUInt32BE(userLen, ++p, true); + buf.write(username, p += 4, userLen, 'utf8'); + + buf.writeUInt32BE(14, p += userLen, true); + buf.write('ssh-connection', p += 4, 14, 'ascii'); + + buf.writeUInt32BE(9, p += 14, true); + buf.write('hostbased', p += 4, 9, 'ascii'); + + buf.writeUInt32BE(algoLen, p += 9, true); + buf.write(pubKeyFullType, p += 4, algoLen, 'ascii'); + + buf.writeUInt32BE(pubKeyLen, p += algoLen, true); + pubKey.copy(buf, p += 4); + + buf.writeUInt32BE(hostnameLen, p += pubKeyLen, true); + buf.write(hostname, p += 4, hostnameLen, 'ascii'); + + buf.writeUInt32BE(userlocalLen, p += hostnameLen, true); + buf.write(userlocal, p += 4, userlocalLen, 'utf8'); + + cbSign(buf, function(signature) { + if (pubKeyFullType === 'ssh-dss') { + signature = DSASigBERToBare(signature); + } else if (pubKeyFullType !== 'ssh-rsa') { + // ECDSA + signature = ECDSASigASN1ToSSH(signature); + } + var sigLen = signature.length; + var sigbuf = new Buffer((buf.length - sesLen) + sigLen); + + buf.copy(sigbuf, 0, 4 + sesLen); + sigbuf.writeUInt32BE(sigLen, sigbuf.length - sigLen - 4, true); + signature.copy(sigbuf, sigbuf.length - sigLen); + + self._state.authsQueue.push('hostbased'); + self.debug('DEBUG: Outgoing: Writing USERAUTH_REQUEST (hostbased)'); + return send(self, sigbuf); + }); + return true; +}; +SSH2Stream.prototype.authKeyboard = function(username) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var userLen = Buffer.byteLength(username); + var p = 0; + var buf = new Buffer(1 + + 4 + userLen + + 4 + 14 // "ssh-connection" + + 4 + 20 // "keyboard-interactive" + + 4 // no language set + + 4 // no submethods + ); + + buf[p] = MESSAGE.USERAUTH_REQUEST; + + buf.writeUInt32BE(userLen, ++p, true); + buf.write(username, p += 4, userLen, 'utf8'); + + buf.writeUInt32BE(14, p += userLen, true); + buf.write('ssh-connection', p += 4, 14, 'ascii'); + + buf.writeUInt32BE(20, p += 14, true); + buf.write('keyboard-interactive', p += 4, 20, 'ascii'); + + buf.writeUInt32BE(0, p += 20, true); + + buf.writeUInt32BE(0, p += 4, true); + + this._state.authsQueue.push('keyboard-interactive'); + this.debug('DEBUG: Outgoing: Writing USERAUTH_REQUEST (keyboard-interactive)'); + return send(this, buf); +}; +SSH2Stream.prototype.authNone = function(username) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var userLen = Buffer.byteLength(username); + var p = 0; + var buf = new Buffer(1 + + 4 + userLen + + 4 + 14 // "ssh-connection" + + 4 + 4 // "none" + ); + + buf[p] = MESSAGE.USERAUTH_REQUEST; + + buf.writeUInt32BE(userLen, ++p, true); + buf.write(username, p += 4, userLen, 'utf8'); + + buf.writeUInt32BE(14, p += userLen, true); + buf.write('ssh-connection', p += 4, 14, 'ascii'); + + buf.writeUInt32BE(4, p += 14, true); + buf.write('none', p += 4, 4, 'ascii'); + + this._state.authsQueue.push('none'); + this.debug('DEBUG: Outgoing: Writing USERAUTH_REQUEST (none)'); + return send(this, buf); +}; +SSH2Stream.prototype.authInfoRes = function(responses) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + var responsesLen = 0; + var p = 0; + var resLen; + var len; + var i; + + if (responses) { + for (i = 0, len = responses.length; i < len; ++i) + responsesLen += 4 + Buffer.byteLength(responses[i]); + } + var buf = new Buffer(1 + 4 + responsesLen); + + buf[p++] = MESSAGE.USERAUTH_INFO_RESPONSE; + + buf.writeUInt32BE(responses ? responses.length : 0, p, true); + if (responses) { + p += 4; + for (i = 0, len = responses.length; i < len; ++i) { + resLen = Buffer.byteLength(responses[i]); + buf.writeUInt32BE(resLen, p, true); + p += 4; + if (resLen) { + buf.write(responses[i], p, resLen, 'utf8'); + p += resLen; + } + } + } + + this.debug('DEBUG: Outgoing: Writing USERAUTH_INFO_RESPONSE'); + return send(this, buf); +}; + +// Server-specific methods +// Global +SSH2Stream.prototype.serviceAccept = function(svcName) { + if (!this.server) + throw new Error('Server-only method called in client mode'); + + var svcNameLen = svcName.length; + var buf = new Buffer(1 + 4 + svcNameLen); + + buf[0] = MESSAGE.SERVICE_ACCEPT; + + buf.writeUInt32BE(svcNameLen, 1, true); + buf.write(svcName, 5, svcNameLen, 'ascii'); + + this.debug('DEBUG: Outgoing: Writing SERVICE_ACCEPT (' + svcName + ')'); + send(this, buf); + + if (this.server && this.banner && svcName === 'ssh-userauth') { + /* + byte SSH_MSG_USERAUTH_BANNER + string message in ISO-10646 UTF-8 encoding + string language tag + */ + var bannerLen = Buffer.byteLength(this.banner); + var packetLen = 1 + 4 + bannerLen + 4; + if (packetLen > BUFFER_MAX_LEN) { + bannerLen -= 1 + 4 + 4; + packetLen -= 1 + 4 + 4; + } + var packet = new Buffer(packetLen); + packet[0] = MESSAGE.USERAUTH_BANNER; + packet.writeUInt32BE(bannerLen, 1, true); + packet.write(this.banner, 5, bannerLen, 'utf8'); + packet.fill(0, packetLen - 4); // Empty language tag + this.debug('DEBUG: Outgoing: Writing USERAUTH_BANNER'); + send(this, packet); + this.banner = undefined; // Prevent banner from being displayed again + } +}; +// 'ssh-connection' service-specific +SSH2Stream.prototype.forwardedTcpip = function(chan, initWindow, maxPacket, + cfg) { + if (!this.server) + throw new Error('Server-only method called in client mode'); + + var boundAddrLen = Buffer.byteLength(cfg.boundAddr); + var remoteAddrLen = Buffer.byteLength(cfg.remoteAddr); + var p = 36 + boundAddrLen; + var buf = new Buffer(1 + 4 + 15 + 4 + 4 + 4 + 4 + boundAddrLen + 4 + 4 + + remoteAddrLen + 4); + + buf[0] = MESSAGE.CHANNEL_OPEN; + + buf.writeUInt32BE(15, 1, true); + buf.write('forwarded-tcpip', 5, 15, 'ascii'); + + buf.writeUInt32BE(chan, 20, true); + + buf.writeUInt32BE(initWindow, 24, true); + + buf.writeUInt32BE(maxPacket, 28, true); + + buf.writeUInt32BE(boundAddrLen, 32, true); + buf.write(cfg.boundAddr, 36, boundAddrLen, 'ascii'); + + buf.writeUInt32BE(cfg.boundPort, p, true); + + buf.writeUInt32BE(remoteAddrLen, p += 4, true); + buf.write(cfg.remoteAddr, p += 4, remoteAddrLen, 'ascii'); + + buf.writeUInt32BE(cfg.remotePort, p += remoteAddrLen, true); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_OPEN (' + + chan + + ', forwarded-tcpip)'); + return send(this, buf); +}; +SSH2Stream.prototype.x11 = function(chan, initWindow, maxPacket, cfg) { + if (!this.server) + throw new Error('Server-only method called in client mode'); + + var addrLen = Buffer.byteLength(cfg.originAddr); + var p = 24 + addrLen; + var buf = new Buffer(1 + 4 + 3 + 4 + 4 + 4 + 4 + addrLen + 4); + + buf[0] = MESSAGE.CHANNEL_OPEN; + + buf.writeUInt32BE(3, 1, true); + buf.write('x11', 5, 3, 'ascii'); + + buf.writeUInt32BE(chan, 8, true); + + buf.writeUInt32BE(initWindow, 12, true); + + buf.writeUInt32BE(maxPacket, 16, true); + + buf.writeUInt32BE(addrLen, 20, true); + buf.write(cfg.originAddr, 24, addrLen, 'ascii'); + + buf.writeUInt32BE(cfg.originPort, p, true); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_OPEN (' + + chan + + ', x11)'); + return send(this, buf); +}; +SSH2Stream.prototype.openssh_forwardedStreamLocal = function(chan, initWindow, + maxPacket, cfg) { + if (!this.server) + throw new Error('Server-only method called in client mode'); + + var pathlen = Buffer.byteLength(cfg.socketPath); + var buf = new Buffer(1 + 4 + 33 + 4 + 4 + 4 + 4 + pathlen + 4); + + buf[0] = MESSAGE.CHANNEL_OPEN; + + buf.writeUInt32BE(33, 1, true); + buf.write('forwarded-streamlocal@openssh.com', 5, 33, 'ascii'); + + buf.writeUInt32BE(chan, 38, true); + + buf.writeUInt32BE(initWindow, 42, true); + + buf.writeUInt32BE(maxPacket, 46, true); + + buf.writeUInt32BE(pathlen, 50, true); + buf.write(cfg.socketPath, 54, pathlen, 'utf8'); + + buf.writeUInt32BE(0, 54 + pathlen, true); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_OPEN (' + + chan + + ', forwarded-streamlocal@openssh.com)'); + return send(this, buf); +}; +SSH2Stream.prototype.exitStatus = function(chan, status) { + if (!this.server) + throw new Error('Server-only method called in client mode'); + + // Does not consume window space + var buf = new Buffer(1 + 4 + 4 + 11 + 1 + 4); + + buf[0] = MESSAGE.CHANNEL_REQUEST; + + buf.writeUInt32BE(chan, 1, true); + + buf.writeUInt32BE(11, 5, true); + buf.write('exit-status', 9, 11, 'ascii'); + + buf[20] = 0; + + buf.writeUInt32BE(status, 21, true); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_REQUEST (' + + chan + + ', exit-status)'); + return send(this, buf); +}; +SSH2Stream.prototype.exitSignal = function(chan, name, coreDumped, msg) { + if (!this.server) + throw new Error('Server-only method called in client mode'); + + // Does not consume window space + var nameLen = Buffer.byteLength(name); + var msgLen = (msg ? Buffer.byteLength(msg) : 0); + var p = 25 + nameLen; + var buf = new Buffer(1 + 4 + 4 + 11 + 1 + 4 + nameLen + 1 + 4 + msgLen + 4); + + buf[0] = MESSAGE.CHANNEL_REQUEST; + + buf.writeUInt32BE(chan, 1, true); + + buf.writeUInt32BE(11, 5, true); + buf.write('exit-signal', 9, 11, 'ascii'); + + buf[20] = 0; + + buf.writeUInt32BE(nameLen, 21, true); + buf.write(name, 25, nameLen, 'utf8'); + + buf[p++] = (coreDumped ? 1 : 0); + + buf.writeUInt32BE(msgLen, p, true); + p += 4; + if (msgLen) { + buf.write(msg, p, msgLen, 'utf8'); + p += msgLen; + } + + buf.writeUInt32BE(0, p, true); + + this.debug('DEBUG: Outgoing: Writing CHANNEL_REQUEST (' + + chan + + ', exit-signal)'); + return send(this, buf); +}; +// 'ssh-userauth' service-specific +SSH2Stream.prototype.authFailure = function(authMethods, isPartial) { + if (!this.server) + throw new Error('Server-only method called in client mode'); + + var authsQueue = this._state.authsQueue; + if (!authsQueue.length) + throw new Error('No auth in progress'); + + var methods; + + if (typeof authMethods === 'boolean') { + isPartial = authMethods; + authMethods = undefined; + } + + if (authMethods) { + methods = []; + for (var i = 0, len = authMethods.length; i < len; ++i) { + if (authMethods[i].toLowerCase() === 'none') + continue; + methods.push(authMethods[i]); + } + methods = methods.join(','); + } else + methods = ''; + + var methodsLen = methods.length; + var buf = new Buffer(1 + 4 + methodsLen + 1); + + buf[0] = MESSAGE.USERAUTH_FAILURE; + + buf.writeUInt32BE(methodsLen, 1, true); + buf.write(methods, 5, methodsLen, 'ascii'); + + buf[5 + methodsLen] = (isPartial === true ? 1 : 0); + + this._state.authsQueue.shift(); + this.debug('DEBUG: Outgoing: Writing USERAUTH_FAILURE'); + return send(this, buf); +}; +SSH2Stream.prototype.authSuccess = function() { + if (!this.server) + throw new Error('Server-only method called in client mode'); + + var authsQueue = this._state.authsQueue; + if (!authsQueue.length) + throw new Error('No auth in progress'); + + this._state.authsQueue.shift(); + this.debug('DEBUG: Outgoing: Writing USERAUTH_SUCCESS'); + return send(this, USERAUTH_SUCCESS_PACKET); +}; +SSH2Stream.prototype.authPKOK = function(keyAlgo, key) { + if (!this.server) + throw new Error('Server-only method called in client mode'); + + var authsQueue = this._state.authsQueue; + if (!authsQueue.length || authsQueue[0] !== 'publickey') + throw new Error('"publickey" auth not in progress'); + + var keyAlgoLen = keyAlgo.length; + var keyLen = key.length; + var buf = new Buffer(1 + 4 + keyAlgoLen + 4 + keyLen); + + buf[0] = MESSAGE.USERAUTH_PK_OK; + + buf.writeUInt32BE(keyAlgoLen, 1, true); + buf.write(keyAlgo, 5, keyAlgoLen, 'ascii'); + + buf.writeUInt32BE(keyLen, 5 + keyAlgoLen, true); + key.copy(buf, 5 + keyAlgoLen + 4); + + this._state.authsQueue.shift(); + this.debug('DEBUG: Outgoing: Writing USERAUTH_PK_OK'); + return send(this, buf); +}; +SSH2Stream.prototype.authPasswdChg = function(prompt, lang) { + if (!this.server) + throw new Error('Server-only method called in client mode'); + + var promptLen = Buffer.byteLength(prompt); + var langLen = lang ? lang.length : 0; + var p = 0; + var buf = new Buffer(1 + 4 + promptLen + 4 + langLen); + + buf[p] = MESSAGE.USERAUTH_PASSWD_CHANGEREQ; + + buf.writeUInt32BE(promptLen, ++p, true); + buf.write(prompt, p += 4, promptLen, 'utf8'); + + buf.writeUInt32BE(langLen, p += promptLen, true); + if (langLen) + buf.write(lang, p += 4, langLen, 'ascii'); + + this.debug('DEBUG: Outgoing: Writing USERAUTH_PASSWD_CHANGEREQ'); + return send(this, buf); +}; +SSH2Stream.prototype.authInfoReq = function(name, instructions, prompts) { + if (!this.server) + throw new Error('Server-only method called in client mode'); + + var promptsLen = 0; + var nameLen = name ? Buffer.byteLength(name) : 0; + var instrLen = instructions ? Buffer.byteLength(instructions) : 0; + var p = 0; + var promptLen; + var prompt; + var len; + var i; + + for (i = 0, len = prompts.length; i < len; ++i) + promptsLen += 4 + Buffer.byteLength(prompts[i].prompt) + 1; + var buf = new Buffer(1 + 4 + nameLen + 4 + instrLen + 4 + 4 + promptsLen); + + buf[p++] = MESSAGE.USERAUTH_INFO_REQUEST; + + buf.writeUInt32BE(nameLen, p, true); + p += 4; + if (name) { + buf.write(name, p, nameLen, 'utf8'); + p += nameLen; + } + + buf.writeUInt32BE(instrLen, p, true); + p += 4; + if (instructions) { + buf.write(instructions, p, instrLen, 'utf8'); + p += instrLen; + } + + buf.writeUInt32BE(0, p, true); + p += 4; + + buf.writeUInt32BE(prompts.length, p, true); + p += 4; + for (i = 0, len = prompts.length; i < len; ++i) { + prompt = prompts[i]; + promptLen = Buffer.byteLength(prompt.prompt); + buf.writeUInt32BE(promptLen, p, true); + p += 4; + if (promptLen) { + buf.write(prompt.prompt, p, promptLen, 'utf8'); + p += promptLen; + } + buf[p++] = (prompt.echo ? 1 : 0); + } + + this.debug('DEBUG: Outgoing: Writing USERAUTH_INFO_REQUEST'); + return send(this, buf); +}; + +// Shared incoming/parser functions +function onDISCONNECT(self, reason, code, desc, lang) { // Client/Server + if (code !== DISCONNECT_REASON.BY_APPLICATION) { + var err = new Error(desc || reason); + err.code = code; + self.emit('error', err); + } + self.reset(); +} + +function onKEXINIT(self, init, firstFollows) { // Client/Server + var state = self._state; + var outstate = state.outgoing; + + if (outstate.status === OUT_READY) { + self.debug('DEBUG: Received re-key request'); + outstate.status = OUT_REKEYING; + outstate.kexinit = undefined; + KEXINIT(self, check); + } else + check(); + + function check() { + if (check_KEXINIT(self, init, firstFollows) === true) { + var isGEX = RE_GEX.test(state.kexdh); + if (!self.server) { + if (isGEX) + KEXDH_GEX_REQ(self); + else + KEXDH_INIT(self); + } else { + if (isGEX) + state.incoming.expectedPacket = 'KEXDH_GEX_REQ'; + else + state.incoming.expectedPacket = 'KEXDH_INIT'; + } + } + } +} + +function check_KEXINIT(self, init, firstFollows) { + var state = self._state; + var instate = state.incoming; + var outstate = state.outgoing; + var debug = self.debug; + var serverList; + var clientList; + var val; + var len; + var i; + + debug('DEBUG: Comparing KEXINITs ...'); + + var algos = self.config.algorithms; + + var kexList = algos.kex; + if (self.remoteBugs & BUGS.BAD_DHGEX) { + var copied = false; + for (var j = kexList.length - 1; j >= 0; --j) { + if (kexList[j].indexOf('group-exchange') !== -1) { + if (!copied) { + kexList = kexList.slice(); + copied = true; + } + kexList.splice(j, 1); + } + } + } + + debug('DEBUG: (local) KEX algorithms: ' + kexList); + debug('DEBUG: (remote) KEX algorithms: ' + init.algorithms.kex); + if (self.server) { + serverList = kexList; + clientList = init.algorithms.kex; + } else { + serverList = init.algorithms.kex; + clientList = kexList; + } + // Check for agreeable key exchange algorithm + for (i = 0, len = clientList.length; + i < len && serverList.indexOf(clientList[i]) === -1; + ++i); + if (i === len) { + // No suitable match found! + debug('DEBUG: No matching key exchange algorithm'); + var err = new Error('Handshake failed: no matching key exchange algorithm'); + err.level = 'handshake'; + self.emit('error', err); + self.disconnect(DISCONNECT_REASON.KEY_EXCHANGE_FAILED); + return false; + } + + var kex_algorithm = clientList[i]; + debug('DEBUG: KEX algorithm: ' + kex_algorithm); + if (firstFollows + && (!init.algorithms.kex.length + || kex_algorithm !== init.algorithms.kex[0])) { + // Ignore next incoming packet, it was a wrong first guess at KEX algorithm + instate.ignoreNext = true; + } + + debug('DEBUG: (local) Host key formats: ' + algos.serverHostKey); + debug('DEBUG: (remote) Host key formats: ' + init.algorithms.srvHostKey); + if (self.server) { + serverList = algos.serverHostKey; + clientList = init.algorithms.srvHostKey; + } else { + serverList = init.algorithms.srvHostKey; + clientList = algos.serverHostKey; + } + // Check for agreeable server host key format + for (i = 0, len = clientList.length; + i < len && serverList.indexOf(clientList[i]) === -1; + ++i); + if (i === len) { + // No suitable match found! + debug('DEBUG: No matching host key format'); + var err = new Error('Handshake failed: no matching host key format'); + err.level = 'handshake'; + self.emit('error', err); + self.disconnect(DISCONNECT_REASON.KEY_EXCHANGE_FAILED); + return false; + } + + state.hostkeyFormat = clientList[i]; + debug('DEBUG: Host key format: ' + state.hostkeyFormat); + + debug('DEBUG: (local) Client->Server ciphers: ' + algos.cipher); + debug('DEBUG: (remote) Client->Server ciphers: ' + + init.algorithms.cs.encrypt); + if (self.server) { + serverList = algos.cipher; + clientList = init.algorithms.cs.encrypt; + } else { + serverList = init.algorithms.cs.encrypt; + clientList = algos.cipher; + } + // Check for agreeable client->server cipher + for (i = 0, len = clientList.length; + i < len && serverList.indexOf(clientList[i]) === -1; + ++i); + if (i === len) { + // No suitable match found! + debug('DEBUG: No matching Client->Server cipher'); + var err = new Error('Handshake failed: no matching client->server cipher'); + err.level = 'handshake'; + self.emit('error', err); + self.disconnect(DISCONNECT_REASON.KEY_EXCHANGE_FAILED); + return false; + } + + if (self.server) { + val = instate.decrypt.type = clientList[i]; + instate.decrypt.isGCM = RE_GCM.test(val); + } else { + val = outstate.encrypt.type = clientList[i]; + outstate.encrypt.isGCM = RE_GCM.test(val); + } + debug('DEBUG: Client->Server Cipher: ' + val); + + debug('DEBUG: (local) Server->Client ciphers: ' + algos.cipher); + debug('DEBUG: (remote) Server->Client ciphers: ' + + (init.algorithms.sc.encrypt)); + if (self.server) { + serverList = algos.cipher; + clientList = init.algorithms.sc.encrypt; + } else { + serverList = init.algorithms.sc.encrypt; + clientList = algos.cipher; + } + // Check for agreeable server->client cipher + for (i = 0, len = clientList.length; + i < len && serverList.indexOf(clientList[i]) === -1; + ++i); + if (i === len) { + // No suitable match found! + debug('DEBUG: No matching Server->Client cipher'); + var err = new Error('Handshake failed: no matching server->client cipher'); + err.level = 'handshake'; + self.emit('error', err); + self.disconnect(DISCONNECT_REASON.KEY_EXCHANGE_FAILED); + return false; + } + + if (self.server) { + val = outstate.encrypt.type = clientList[i]; + outstate.encrypt.isGCM = RE_GCM.test(val); + } else { + val = instate.decrypt.type = clientList[i]; + instate.decrypt.isGCM = RE_GCM.test(val); + } + debug('DEBUG: Server->Client Cipher: ' + val); + + debug('DEBUG: (local) Client->Server HMAC algorithms: ' + algos.hmac); + debug('DEBUG: (remote) Client->Server HMAC algorithms: ' + + init.algorithms.cs.mac); + if (self.server) { + serverList = algos.hmac; + clientList = init.algorithms.cs.mac; + } else { + serverList = init.algorithms.cs.mac; + clientList = algos.hmac; + } + // Check for agreeable client->server hmac algorithm + for (i = 0, len = clientList.length; + i < len && serverList.indexOf(clientList[i]) === -1; + ++i); + if (i === len) { + // No suitable match found! + debug('DEBUG: No matching Client->Server HMAC algorithm'); + var err = new Error('Handshake failed: no matching client->server HMAC'); + err.level = 'handshake'; + self.emit('error', err); + self.disconnect(DISCONNECT_REASON.KEY_EXCHANGE_FAILED); + return false; + } + + if (self.server) + val = instate.hmac.type = clientList[i]; + else + val = outstate.hmac.type = clientList[i]; + debug('DEBUG: Client->Server HMAC algorithm: ' + val); + + debug('DEBUG: (local) Server->Client HMAC algorithms: ' + algos.hmac); + debug('DEBUG: (remote) Server->Client HMAC algorithms: ' + + init.algorithms.sc.mac); + if (self.server) { + serverList = algos.hmac; + clientList = init.algorithms.sc.mac; + } else { + serverList = init.algorithms.sc.mac; + clientList = algos.hmac; + } + // Check for agreeable server->client hmac algorithm + for (i = 0, len = clientList.length; + i < len && serverList.indexOf(clientList[i]) === -1; + ++i); + if (i === len) { + // No suitable match found! + debug('DEBUG: No matching Server->Client HMAC algorithm'); + var err = new Error('Handshake failed: no matching server->client HMAC'); + err.level = 'handshake'; + self.emit('error', err); + self.disconnect(DISCONNECT_REASON.KEY_EXCHANGE_FAILED); + return false; + } + + if (self.server) + val = outstate.hmac.type = clientList[i]; + else + val = instate.hmac.type = clientList[i]; + debug('DEBUG: Server->Client HMAC algorithm: ' + val); + + debug('DEBUG: (local) Client->Server compression algorithms: ' + + algos.compress); + debug('DEBUG: (remote) Client->Server compression algorithms: ' + + init.algorithms.cs.compress); + if (self.server) { + serverList = algos.compress; + clientList = init.algorithms.cs.compress; + } else { + serverList = init.algorithms.cs.compress; + clientList = algos.compress; + } + // Check for agreeable client->server compression algorithm + for (i = 0, len = clientList.length; + i < len && serverList.indexOf(clientList[i]) === -1; + ++i); + if (i === len) { + // No suitable match found! + debug('DEBUG: No matching Client->Server compression algorithm'); + var err = new Error('Handshake failed: no matching client->server ' + + 'compression algorithm'); + err.level = 'handshake'; + self.emit('error', err); + self.disconnect(DISCONNECT_REASON.KEY_EXCHANGE_FAILED); + return false; + } + + if (self.server) + val = instate.decompress.type = clientList[i]; + else + val = outstate.compress.type = clientList[i]; + debug('DEBUG: Client->Server compression algorithm: ' + val); + + debug('DEBUG: (local) Server->Client compression algorithms: ' + + algos.compress); + debug('DEBUG: (remote) Server->Client compression algorithms: ' + + init.algorithms.sc.compress); + if (self.server) { + serverList = algos.compress; + clientList = init.algorithms.sc.compress; + } else { + serverList = init.algorithms.sc.compress; + clientList = algos.compress; + } + // Check for agreeable server->client compression algorithm + for (i = 0, len = clientList.length; + i < len && serverList.indexOf(clientList[i]) === -1; + ++i); + if (i === len) { + // No suitable match found! + debug('DEBUG: No matching Server->Client compression algorithm'); + var err = new Error('Handshake failed: no matching server->client ' + + 'compression algorithm'); + err.level = 'handshake'; + self.emit('error', err); + self.disconnect(DISCONNECT_REASON.KEY_EXCHANGE_FAILED); + return false; + } + + if (self.server) + val = outstate.compress.type = clientList[i]; + else + val = instate.decompress.type = clientList[i]; + debug('DEBUG: Server->Client compression algorithm: ' + val); + + switch (kex_algorithm) { + case 'diffie-hellman-group1-sha1': + state.kexdh = 'group'; + state.kex = crypto.getDiffieHellman('modp2'); + break; + case 'diffie-hellman-group14-sha1': + state.kexdh = 'group'; + state.kex = crypto.getDiffieHellman('modp14'); + break; + case 'ecdh-sha2-nistp256': + state.kexdh = 'ec-sha256'; + state.kex = crypto.createECDH(SSH_TO_OPENSSL[kex_algorithm]); + break; + case 'ecdh-sha2-nistp384': + state.kexdh = 'ec-sha384'; + state.kex = crypto.createECDH(SSH_TO_OPENSSL[kex_algorithm]); + break; + case 'ecdh-sha2-nistp521': + state.kexdh = 'ec-sha512'; + state.kex = crypto.createECDH(SSH_TO_OPENSSL[kex_algorithm]); + break; + default: + if (kex_algorithm === 'diffie-hellman-group-exchange-sha1') + state.kexdh = 'gex-sha1'; + else if (kex_algorithm === 'diffie-hellman-group-exchange-sha256') + state.kexdh = 'gex-sha256'; + // Reset kex object if DH group exchange is selected on re-key and DH + // group exchange was used before the re-key. This ensures that we send + // the right DH packet after the KEXINIT exchange + state.kex = undefined; + } + + if (state.kex) { + outstate.pubkey = state.kex.generateKeys(); + var idx = 0; + len = outstate.pubkey.length; + while (outstate.pubkey[idx] === 0x00) { + ++idx; + --len; + } + if (outstate.pubkey[idx] & 0x80) { + var key = new Buffer(len + 1); + key[0] = 0; + outstate.pubkey.copy(key, 1, idx); + outstate.pubkey = key; + } + } + + return true; +} + +function onKEXDH_GEX_GROUP(self, prime, gen) { + var state = self._state; + var outstate = state.outgoing; + + state.kex = crypto.createDiffieHellman(prime, gen); + outstate.pubkey = state.kex.generateKeys(); + var idx = 0; + var len = outstate.pubkey.length; + while (outstate.pubkey[idx] === 0x00) { + ++idx; + --len; + } + if (outstate.pubkey[idx] & 0x80) { + var key = new Buffer(len + 1); + key[0] = 0; + outstate.pubkey.copy(key, 1, idx); + outstate.pubkey = key; + } + KEXDH_INIT(self); +} + +function onKEXDH_INIT(self, e) { // Server + KEXDH_REPLY(self, e); +} + +function onKEXDH_REPLY(self, info, verifiedHost) { // Client + var state = self._state; + var instate = state.incoming; + var outstate = state.outgoing; + var debug = self.debug; + var len; + var i; + + if (verifiedHost === undefined) { + instate.expectedPacket = 'NEWKEYS'; + outstate.sentNEWKEYS = false; + + debug('DEBUG: Checking host key format'); + // Ensure all host key formats agree + var hostkey_format = readString(info.hostkey, 0, 'ascii', self); + if (hostkey_format === false) + return false; + if (info.hostkey_format !== state.hostkeyFormat + || info.hostkey_format !== hostkey_format) { + // Expected and actual server host key format do not match! + debug('DEBUG: Host key format mismatch'); + self.disconnect(DISCONNECT_REASON.KEY_EXCHANGE_FAILED); + self.reset(); + var err = new Error('Handshake failed: host key format mismatch'); + err.level = 'handshake'; + self.emit('error', err); + return false; + } + + debug('DEBUG: Checking signature format'); + // Ensure signature formats agree + var sig_format = readString(info.sig, 0, 'ascii', self); + if (sig_format === false) + return false; + if (info.sig_format !== sig_format) { + debug('DEBUG: Signature format mismatch'); + self.disconnect(DISCONNECT_REASON.KEY_EXCHANGE_FAILED); + self.reset(); + var err = new Error('Handshake failed: signature format mismatch'); + err.level = 'handshake'; + self.emit('error', err); + return false; + } + } + + // Verify the host fingerprint first if needed + if (outstate.status === OUT_INIT) { + if (verifiedHost === undefined) { + debug('DEBUG: Verifying host fingerprint'); + var sync = true; + var emitted = self.emit('fingerprint', info.hostkey, function(permitted) { + // Prevent multiple calls to this callback + if (verifiedHost !== undefined) + return; + verifiedHost = !!permitted; + if (!sync) { + // Continue execution by re-entry + onKEXDH_REPLY(self, info, verifiedHost); + } + }); + sync = false; + // Support async calling of verification callback + if (emitted && verifiedHost === undefined) + return; + } + if (verifiedHost === undefined) + debug('DEBUG: Host accepted by default (no verification)'); + else if (verifiedHost === true) + debug('DEBUG: Host accepted (verified)'); + else { + debug('DEBUG: Host denied via fingerprint verification'); + self.disconnect(DISCONNECT_REASON.KEY_EXCHANGE_FAILED); + self.reset(); + var err = new Error('Handshake failed: ' + + 'host fingerprint verification failed'); + err.level = 'handshake'; + self.emit('error', err); + return false; + } + } + + var slicepos = -1; + for (i = 0, len = info.pubkey.length; i < len; ++i) { + if (info.pubkey[i] === 0) + ++slicepos; + else + break; + } + if (slicepos > -1) + info.pubkey = info.pubkey.slice(slicepos + 1); + info.secret = tryComputeSecret(state.kex, info.pubkey); + if (info.secret instanceof Error) { + info.secret.message = 'Error while computing DH secret (' + + state.kexdh + '): ' + + info.secret.message; + info.secret.level = 'handshake'; + self.emit('error', info.secret); + self.disconnect(DISCONNECT_REASON.KEY_EXCHANGE_FAILED); + return false; + } + + var hashAlgo; + if (state.kexdh === 'group') + hashAlgo = 'sha1'; + else + hashAlgo = RE_KEX_HASH.exec(state.kexdh)[1]; + var hash = crypto.createHash(hashAlgo); + + var len_ident = Buffer.byteLength(self.config.ident); + var len_sident = Buffer.byteLength(instate.identRaw); + var len_init = outstate.kexinit.length; + var len_sinit = instate.kexinit.length; + var len_hostkey = info.hostkey.length; + var len_pubkey = outstate.pubkey.length; + var len_spubkey = info.pubkey.length; + var len_secret = info.secret.length; + + var idx_pubkey = 0; + var idx_spubkey = 0; + var idx_secret = 0; + + while (outstate.pubkey[idx_pubkey] === 0x00) { + ++idx_pubkey; + --len_pubkey; + } + while (info.pubkey[idx_spubkey] === 0x00) { + ++idx_spubkey; + --len_spubkey; + } + while (info.secret[idx_secret] === 0x00) { + ++idx_secret; + --len_secret; + } + if (outstate.pubkey[idx_pubkey] & 0x80) + ++len_pubkey; + if (info.pubkey[idx_spubkey] & 0x80) + ++len_spubkey; + if (info.secret[idx_secret] & 0x80) + ++len_secret; + + var exchangeBufLen = len_ident + + len_sident + + len_init + + len_sinit + + len_hostkey + + len_pubkey + + len_spubkey + + len_secret + + (4 * 8); // Length fields for above values + + // Group exchange-related + var isGEX = RE_GEX.test(state.kexdh); + var len_gex_prime = 0; + var len_gex_gen = 0; + var idx_gex_prime = 0; + var idx_gex_gen = 0; + var gex_prime; + var gex_gen; + if (isGEX) { + gex_prime = state.kex.getPrime(); + gex_gen = state.kex.getGenerator(); + len_gex_prime = gex_prime.length; + len_gex_gen = gex_gen.length; + while (gex_prime[idx_gex_prime] === 0x00) { + ++idx_gex_prime; + --len_gex_prime; + } + while (gex_gen[idx_gex_gen] === 0x00) { + ++idx_gex_gen; + --len_gex_gen; + } + if (gex_prime[idx_gex_prime] & 0x80) + ++len_gex_prime; + if (gex_gen[idx_gex_gen] & 0x80) + ++len_gex_gen; + exchangeBufLen += (4 * 3); // min, n, max values + exchangeBufLen += (4 * 2); // prime, generator length fields + exchangeBufLen += len_gex_prime; + exchangeBufLen += len_gex_gen; + } + + + var bp = 0; + var exchangeBuf = new Buffer(exchangeBufLen); + + exchangeBuf.writeUInt32BE(len_ident, bp, true); + bp += 4; + exchangeBuf.write(self.config.ident, bp, 'utf8'); // V_C + bp += len_ident; + + exchangeBuf.writeUInt32BE(len_sident, bp, true); + bp += 4; + exchangeBuf.write(instate.identRaw, bp, 'utf8'); // V_S + bp += len_sident; + + exchangeBuf.writeUInt32BE(len_init, bp, true); + bp += 4; + outstate.kexinit.copy(exchangeBuf, bp); // I_C + bp += len_init; + outstate.kexinit = undefined; + + exchangeBuf.writeUInt32BE(len_sinit, bp, true); + bp += 4; + instate.kexinit.copy(exchangeBuf, bp); // I_S + bp += len_sinit; + instate.kexinit = undefined; + + exchangeBuf.writeUInt32BE(len_hostkey, bp, true); + bp += 4; + info.hostkey.copy(exchangeBuf, bp); // K_S + bp += len_hostkey; + + if (isGEX) { + KEXDH_GEX_REQ_PACKET.slice(1).copy(exchangeBuf, bp); // min, n, max + bp += (4 * 3); // Skip over bytes just copied + + exchangeBuf.writeUInt32BE(len_gex_prime, bp, true); + bp += 4; + if (gex_prime[idx_gex_prime] & 0x80) + exchangeBuf[bp++] = 0; + gex_prime.copy(exchangeBuf, bp, idx_gex_prime); // p + bp += len_gex_prime - (gex_prime[idx_gex_prime] & 0x80 ? 1 : 0); + + exchangeBuf.writeUInt32BE(len_gex_gen, bp, true); + bp += 4; + if (gex_gen[idx_gex_gen] & 0x80) + exchangeBuf[bp++] = 0; + gex_gen.copy(exchangeBuf, bp, idx_gex_gen); // g + bp += len_gex_gen - (gex_gen[idx_gex_gen] & 0x80 ? 1 : 0); + } + + exchangeBuf.writeUInt32BE(len_pubkey, bp, true); + bp += 4; + if (outstate.pubkey[idx_pubkey] & 0x80) + exchangeBuf[bp++] = 0; + outstate.pubkey.copy(exchangeBuf, bp, idx_pubkey); // e + bp += len_pubkey - (outstate.pubkey[idx_pubkey] & 0x80 ? 1 : 0); + + exchangeBuf.writeUInt32BE(len_spubkey, bp, true); + bp += 4; + if (info.pubkey[idx_spubkey] & 0x80) + exchangeBuf[bp++] = 0; + info.pubkey.copy(exchangeBuf, bp, idx_spubkey); // f + bp += len_spubkey - (info.pubkey[idx_spubkey] & 0x80 ? 1 : 0); + + exchangeBuf.writeUInt32BE(len_secret, bp, true); + bp += 4; + if (info.secret[idx_secret] & 0x80) + exchangeBuf[bp++] = 0; + info.secret.copy(exchangeBuf, bp, idx_secret); // K + + outstate.exchangeHash = hash.update(exchangeBuf).digest(); // H + + var rawsig = readString(info.sig, info.sig._pos, self); // s + if (rawsig === false) + return false; + + var keyAlgo; + switch (info.sig_format) { + case 'ssh-rsa': + keyAlgo = 'RSA-SHA1'; + break; + case 'ssh-dss': + keyAlgo = 'DSA-SHA1'; + break; + case 'ecdsa-sha2-nistp256': + keyAlgo = 'sha256'; + break; + case 'ecdsa-sha2-nistp384': + keyAlgo = 'sha384'; + break; + case 'ecdsa-sha2-nistp521': + keyAlgo = 'sha512'; + break; + default: + debug('DEBUG: Signature format unsupported: ' + info.sig_format); + self.disconnect(DISCONNECT_REASON.KEY_EXCHANGE_FAILED); + self.reset(); + var err = new Error('Handshake failed: signature format unsupported: ' + + info.sig_format); + err.level = 'handshake'; + self.emit('error', err); + return false; + } + var verifier = crypto.createVerify(keyAlgo); + verifier.update(outstate.exchangeHash); + + var asn1KeyBuf; + if (keyAlgo === 'RSA-SHA1') { + asn1KeyBuf = RSAKeySSHToASN1(info.hostkey, self); + } else if (keyAlgo === 'DSA-SHA1') { + asn1KeyBuf = DSAKeySSHToASN1(info.hostkey, self); + rawsig = DSASigBareToBER(rawsig); + } else { + // ECDSA + asn1KeyBuf = ECDSAKeySSHToASN1(info.hostkey, self); + rawsig = ECDSASigSSHToASN1(rawsig, self); + } + + if (!asn1KeyBuf || !rawsig) + return false; + + debug('DEBUG: Verifying signature'); + + var b64key = asn1KeyBuf.toString('base64').replace(/(.{64})/g, '$1\n'); + var fullkey = '-----BEGIN PUBLIC KEY-----\n' + + b64key + + (b64key[b64key.length - 1] === '\n' ? '' : '\n') + + '-----END PUBLIC KEY-----'; + + var verified = verifier.verify(fullkey, rawsig); + + if (!verified) { + debug('DEBUG: Signature verification failed'); + self.disconnect(DISCONNECT_REASON.KEY_EXCHANGE_FAILED); + self.reset(); + var err = new Error('Handshake failed: signature verification failed'); + err.level = 'handshake'; + self.emit('error', err); + return false; + } + + if (outstate.sessionId === undefined) + outstate.sessionId = outstate.exchangeHash; + outstate.kexsecret = info.secret; + + debug('DEBUG: Outgoing: Writing NEWKEYS'); + if (outstate.status === OUT_REKEYING) + send(self, NEWKEYS_PACKET, undefined, true); + else + send(self, NEWKEYS_PACKET); + outstate.sentNEWKEYS = true; + + if (verifiedHost !== undefined && instate.expectedPacket === undefined) { + // We received NEWKEYS while we were waiting for the fingerprint + // verification callback to be called. In this case we have to re-execute + // onNEWKEYS to finish the handshake. + onNEWKEYS(self); + } +} + +function onNEWKEYS(self) { // Client/Server + var state = self._state; + var outstate = state.outgoing; + var instate = state.incoming; + + instate.expectedPacket = undefined; + + if (!outstate.sentNEWKEYS) + return; + + var idx_secret = 0; + var len = outstate.kexsecret.length; + while (outstate.kexsecret[idx_secret] === 0x00) { + ++idx_secret; + --len; + } + + var blocklen = 8; + var keylen = 0; + var p = 0; + + var dhHashAlgo; + if (state.kexdh === 'group') + dhHashAlgo = 'sha1'; + else + dhHashAlgo = RE_KEX_HASH.exec(state.kexdh)[1]; + + var len_secret = (outstate.kexsecret[idx_secret] & 0x80 ? 1 : 0) + len; + var secret = new Buffer(4 + len_secret); + var iv; + var key; + + // Whenever the client sends a new authentication request, it is enqueued + // here. Once the request is resolved (success, fail, or PK_OK), + // dequeue. Whatever is at the front of the queue determines how we + // interpret packet type 60. + state.authsQueue = []; + + secret.writeUInt32BE(len_secret, p, true); + p += 4; + if (outstate.kexsecret[idx_secret] & 0x80) + secret[p++] = 0; + outstate.kexsecret.copy(secret, p, idx_secret); + outstate.kexsecret = undefined; + if (!isStreamCipher(outstate.encrypt.type)) { + iv = crypto.createHash(dhHashAlgo) + .update(secret) + .update(outstate.exchangeHash) + .update(!self.server ? 'A' : 'B', 'ascii') + .update(outstate.sessionId) + .digest(); + switch (outstate.encrypt.type) { + case 'aes128-gcm': + case 'aes256-gcm': + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + blocklen = 12; + break; + case 'aes256-cbc': + case 'aes192-cbc': + case 'aes128-cbc': + case 'aes256-ctr': + case 'aes192-ctr': + case 'aes128-ctr': + blocklen = 16; + } + outstate.encrypt.size = blocklen; + while (blocklen > iv.length) { + iv = Buffer.concat([iv, + crypto.createHash(dhHashAlgo) + .update(secret) + .update(outstate.exchangeHash) + .update(iv) + .digest()]); + } + iv = iv.slice(0, blocklen); + } else { + outstate.encrypt.size = blocklen; + iv = EMPTY_BUFFER; // Streaming ciphers don't use an IV upfront + } + switch (outstate.encrypt.type) { + case 'aes256-gcm': + case 'aes256-gcm@openssh.com': + case 'aes256-cbc': + case 'aes256-ctr': + case 'arcfour256': + keylen = 32; + break; + case '3des-cbc': + case '3des-ctr': + case 'aes192-cbc': + case 'aes192-ctr': + keylen = 24; + break; + case 'aes128-gcm': + case 'aes128-gcm@openssh.com': + case 'aes128-cbc': + case 'aes128-ctr': + case 'cast128-cbc': + case 'blowfish-cbc': + case 'arcfour': + case 'arcfour128': + keylen = 16; + break; + } + + key = crypto.createHash(dhHashAlgo) + .update(secret) + .update(outstate.exchangeHash) + .update(!self.server ? 'C' : 'D', 'ascii') + .update(outstate.sessionId) + .digest(); + while (keylen > key.length) { + key = Buffer.concat([key, + crypto.createHash(dhHashAlgo) + .update(secret) + .update(outstate.exchangeHash) + .update(key) + .digest()]); + } + key = key.slice(0, keylen); + + if (outstate.encrypt.isGCM) { + outstate.encrypt.size = 16; + outstate.encrypt.iv = iv; + outstate.encrypt.key = key; + outstate.encrypt.instance = true; + } else { + var cipherAlgo = SSH_TO_OPENSSL[outstate.encrypt.type]; + outstate.encrypt.instance = crypto.createCipheriv(cipherAlgo, key, iv); + outstate.encrypt.instance.setAutoPadding(false); + } + + // And now for decrypting ... + + blocklen = 8; + keylen = 0; + if (!isStreamCipher(instate.decrypt.type)) { + iv = crypto.createHash(dhHashAlgo) + .update(secret) + .update(outstate.exchangeHash) + .update(!self.server ? 'B' : 'A', 'ascii') + .update(outstate.sessionId) + .digest(); + switch (instate.decrypt.type) { + case 'aes128-gcm': + case 'aes256-gcm': + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + blocklen = 12; + break; + case 'aes256-cbc': + case 'aes192-cbc': + case 'aes128-cbc': + case 'aes256-ctr': + case 'aes192-ctr': + case 'aes128-ctr': + blocklen = 16; + } + if (instate.decrypt.isGCM) + instate.decrypt.size = 16; + else + instate.decrypt.size = blocklen; + while (blocklen > iv.length) { + iv = Buffer.concat([iv, + crypto.createHash(dhHashAlgo) + .update(secret) + .update(outstate.exchangeHash) + .update(iv) + .digest()]); + } + iv = iv.slice(0, blocklen); + } else { + instate.decrypt.size = blocklen; + iv = EMPTY_BUFFER; // Streaming ciphers don't use an IV upfront + } + + // Create a reusable buffer for decryption purposes + instate.decrypt.buf = new Buffer(instate.decrypt.size); + + switch (instate.decrypt.type) { + case 'aes256-gcm': + case 'aes256-gcm@openssh.com': + case 'aes256-cbc': + case 'aes256-ctr': + case 'arcfour256': + keylen = 32; + break; + case '3des-cbc': + case '3des-ctr': + case 'aes192-cbc': + case 'aes192-ctr': + keylen = 24; + break; + case 'aes128-gcm': + case 'aes128-gcm@openssh.com': + case 'aes128-cbc': + case 'aes128-ctr': + case 'cast128-cbc': + case 'blowfish-cbc': + case 'arcfour': + case 'arcfour128': + keylen = 16; + break; + } + key = crypto.createHash(dhHashAlgo) + .update(secret) + .update(outstate.exchangeHash) + .update(!self.server ? 'D' : 'C', 'ascii') + .update(outstate.sessionId) + .digest(); + while (keylen > key.length) { + key = Buffer.concat([key, + crypto.createHash(dhHashAlgo) + .update(secret) + .update(outstate.exchangeHash) + .update(key) + .digest()]); + } + key = key.slice(0, keylen); + + var decipherAlgo = SSH_TO_OPENSSL[instate.decrypt.type]; + instate.decrypt.instance = crypto.createDecipheriv(decipherAlgo, key, iv); + instate.decrypt.instance.setAutoPadding(false); + instate.decrypt.iv = iv; + instate.decrypt.key = key; + + /* The "arcfour128" algorithm is the RC4 cipher, as described in + [SCHNEIER], using a 128-bit key. The first 1536 bytes of keystream + generated by the cipher MUST be discarded, and the first byte of the + first encrypted packet MUST be encrypted using the 1537th byte of + keystream. + + -- http://tools.ietf.org/html/rfc4345#section-4 */ + var emptyBuf; + if (outstate.encrypt.type.substr(0, 7) === 'arcfour') { + emptyBuf = new Buffer(1536); + emptyBuf.fill(0); + outstate.encrypt.instance.update(emptyBuf); + } + if (instate.decrypt.type.substr(0, 7) === 'arcfour') { + emptyBuf = new Buffer(1536); + emptyBuf.fill(0); + instate.decrypt.instance.update(emptyBuf); + } + + var createKeyLen = 0; + var checkKeyLen = 0; + switch (outstate.hmac.type) { + case 'hmac-ripemd160': + case 'hmac-sha1': + createKeyLen = 20; + outstate.hmac.size = 20; + break; + case 'hmac-sha1-96': + createKeyLen = 20; + outstate.hmac.size = 12; + break; + case 'hmac-sha2-256': + createKeyLen = 32; + outstate.hmac.size = 32; + break; + case 'hmac-sha2-256-96': + createKeyLen = 32; + outstate.hmac.size = 12; + break; + case 'hmac-sha2-512': + createKeyLen = 64; + outstate.hmac.size = 64; + break; + case 'hmac-sha2-512-96': + createKeyLen = 64; + outstate.hmac.size = 12; + break; + case 'hmac-md5': + createKeyLen = 16; + outstate.hmac.size = 16; + break; + case 'hmac-md5-96': + createKeyLen = 16; + outstate.hmac.size = 12; + break; + } + switch (instate.hmac.type) { + case 'hmac-ripemd160': + case 'hmac-sha1': + checkKeyLen = 20; + instate.hmac.size = 20; + break; + case 'hmac-sha1-96': + checkKeyLen = 20; + instate.hmac.size = 12; + break; + case 'hmac-sha2-256': + checkKeyLen = 32; + instate.hmac.size = 32; + break; + case 'hmac-sha2-256-96': + checkKeyLen = 32; + instate.hmac.size = 12; + break; + case 'hmac-sha2-512': + checkKeyLen = 64; + instate.hmac.size = 64; + break; + case 'hmac-sha2-512-96': + checkKeyLen = 64; + instate.hmac.size = 12; + break; + case 'hmac-md5': + checkKeyLen = 16; + instate.hmac.size = 16; + break; + case 'hmac-md5-96': + checkKeyLen = 16; + instate.hmac.size = 12; + break; + } + + if (!outstate.encrypt.isGCM) { + key = crypto.createHash(dhHashAlgo) + .update(secret) + .update(outstate.exchangeHash) + .update(!self.server ? 'E' : 'F', 'ascii') + .update(outstate.sessionId) + .digest(); + while (createKeyLen > key.length) { + key = Buffer.concat([key, + crypto.createHash(dhHashAlgo) + .update(secret) + .update(outstate.exchangeHash) + .update(key) + .digest()]); + } + outstate.hmac.key = key.slice(0, createKeyLen); + } else + outstate.hmac.key = undefined; + if (!instate.decrypt.isGCM) { + key = crypto.createHash(dhHashAlgo) + .update(secret) + .update(outstate.exchangeHash) + .update(!self.server ? 'F' : 'E', 'ascii') + .update(outstate.sessionId) + .digest(); + while (checkKeyLen > key.length) { + key = Buffer.concat([key, + crypto.createHash(dhHashAlgo) + .update(secret) + .update(outstate.exchangeHash) + .update(key) + .digest()]); + } + instate.hmac.key = key.slice(0, checkKeyLen); + } else { + instate.hmac.key = undefined; + instate.hmac.size = 16; + } + + outstate.exchangeHash = undefined; + + // Create a reusable buffer for message verification purposes + if (!instate.hmac.buf + || instate.hmac.buf.length !== instate.hmac.size) + instate.hmac.buf = new Buffer(instate.hmac.size); + + if (outstate.compress.type === 'zlib') + outstate.compress.instance = zlib.createDeflate(ZLIB_OPTS); + else if (outstate.compress.type === 'none') + outstate.compress.instance = false; + if (instate.decompress.type === 'zlib') + instate.decompress.instance = zlib.createInflate(ZLIB_OPTS); + else if (instate.decompress.type === 'none') + instate.decompress.instance = false; + + self.bytesSent = self.bytesReceived = 0; + + if (outstate.status === OUT_REKEYING) { + outstate.status = OUT_READY; + + // Empty our outbound buffer of any data we tried to send during the + // re-keying process + var queue = outstate.rekeyQueue; + var qlen = queue.length; + var q = 0; + + outstate.rekeyQueue = []; + + for (; q < qlen; ++q) { + if (Buffer.isBuffer(queue[q])) + send(self, queue[q]); + else + send(self, queue[q][0], queue[q][1]); + } + + // Now empty our inbound buffer of any non-transport layer packets we + // received during the re-keying process + queue = instate.rekeyQueue; + qlen = queue.length; + q = 0; + + instate.rekeyQueue = []; + + var curSeqno = instate.seqno; + for (; q < qlen; ++q) { + instate.seqno = queue[q][0]; + instate.payload = queue[q][1]; + if (parsePacket(self) === false) + return; + + if (instate.status === IN_INIT) { + // We were reset due to some error/disagreement ? + return; + } + } + instate.seqno = curSeqno; + } else { + outstate.status = OUT_READY; + if (instate.status === IN_PACKET) { + // Explicitly update incoming packet parser status in order to get the + // correct decipher, hmac, etc. states. + + // We only get here if the host fingerprint callback was called + // asynchronously and the incoming packet parser is still expecting an + // unencrypted packet, etc. + + self.debug('DEBUG: Parser: IN_PACKETBEFORE (update) (expecting ' + + instate.decrypt.size + ')'); + // Wait for the right number of bytes so we can determine the incoming + // packet length + expectData(self, + EXP_TYPE_BYTES, + instate.decrypt.size, + instate.decrypt.buf); + } + self.emit('ready'); + } +} + +function parsePacket(self, callback) { + var instate = self._state.incoming; + var outstate = self._state.outgoing; + var payload = instate.payload; + var seqno = instate.seqno; + var serviceName; + var lang; + var message; + var info; + var chan; + var data; + var srcIP; + var srcPort; + var sender; + var window; + var packetSize; + var recipient; + var description; + var socketPath; + + if (++instate.seqno > MAX_SEQNO) + instate.seqno = 0; + + if (instate.ignoreNext) { + self.debug('DEBUG: Parser: Packet ignored'); + instate.ignoreNext = false; + return; + } + + var type = payload[0]; + if (type === undefined) + return false; + + // If we receive a packet during handshake that is not the expected packet + // and it is not one of: DISCONNECT, IGNORE, UNIMPLEMENTED, or DEBUG, then we + // close the stream + if (outstate.status !== OUT_READY + && MESSAGE[type] !== instate.expectedPacket + && type < 1 + && type > 4) { + self.debug('DEBUG: Parser: IN_PACKETDATAAFTER, expected: ' + + instate.expectedPacket + + ' but got: ' + + MESSAGE[type]); + // XXX: Potential issue where the module user decides to initiate a rekey + // via KEXINIT() (which sets `expectedPacket`) after receiving a packet + // and there is still another packet already waiting to be parsed at the + // time the KEXINIT is written. this will cause an unexpected disconnect... + self.disconnect(DISCONNECT_REASON.PROTOCOL_ERROR); + var err = new Error('Received unexpected packet'); + err.level = 'protocol'; + self.emit('error', err); + return false; + } + + if (type === MESSAGE.CHANNEL_DATA) { + /* + byte SSH_MSG_CHANNEL_DATA + uint32 recipient channel + string data + */ + chan = readInt(payload, 1, self, callback); + if (chan === false) + return false; + // TODO: MAX_CHAN_DATA_LEN here should really be dependent upon the + // channel's packet size. The ssh2 module uses 32KB, so we'll hard + // code this for now ... + data = readString(payload, 5, self, callback, 32768); + if (data === false) + return false; + self.debug('DEBUG: Parser: IN_PACKETDATAAFTER, packet: CHANNEL_DATA (' + + chan + + ')'); + self.emit('CHANNEL_DATA:' + chan, data); + } else if (type === MESSAGE.CHANNEL_EXTENDED_DATA) { + /* + byte SSH_MSG_CHANNEL_EXTENDED_DATA + uint32 recipient channel + uint32 data_type_code + string data + */ + chan = readInt(payload, 1, self, callback); + if (chan === false) + return false; + var dataType = readInt(payload, 5, self, callback); + if (dataType === false) + return false; + data = readString(payload, 9, self, callback); + if (data === false) + return false; + self.debug('DEBUG: Parser: IN_PACKETDATAAFTER, packet: ' + + 'CHANNEL_EXTENDED_DATA (' + + chan + + ')'); + self.emit('CHANNEL_EXTENDED_DATA:' + chan, dataType, data); + } else if (type === MESSAGE.CHANNEL_WINDOW_ADJUST) { + /* + byte SSH_MSG_CHANNEL_WINDOW_ADJUST + uint32 recipient channel + uint32 bytes to add + */ + chan = readInt(payload, 1, self, callback); + if (chan === false) + return false; + var bytesToAdd = readInt(payload, 5, self, callback); + if (bytesToAdd === false) + return false; + self.debug('DEBUG: Parser: IN_PACKETDATAAFTER, packet: ' + + 'CHANNEL_WINDOW_ADJUST (' + + chan + + ', ' + + bytesToAdd + + ')'); + self.emit('CHANNEL_WINDOW_ADJUST:' + chan, bytesToAdd); + } else if (type === MESSAGE.CHANNEL_SUCCESS) { + /* + byte SSH_MSG_CHANNEL_SUCCESS + uint32 recipient channel + */ + chan = readInt(payload, 1, self, callback); + if (chan === false) + return false; + self.debug('DEBUG: Parser: IN_PACKETDATAAFTER, packet: CHANNEL_SUCCESS (' + + chan + + ')'); + self.emit('CHANNEL_SUCCESS:' + chan); + } else if (type === MESSAGE.CHANNEL_FAILURE) { + /* + byte SSH_MSG_CHANNEL_FAILURE + uint32 recipient channel + */ + chan = readInt(payload, 1, self, callback); + if (chan === false) + return false; + self.debug('DEBUG: Parser: IN_PACKETDATAAFTER, packet: CHANNEL_FAILURE (' + + chan + + ')'); + self.emit('CHANNEL_FAILURE:' + chan); + } else if (type === MESSAGE.CHANNEL_EOF) { + /* + byte SSH_MSG_CHANNEL_EOF + uint32 recipient channel + */ + chan = readInt(payload, 1, self, callback); + if (chan === false) + return false; + self.debug('DEBUG: Parser: IN_PACKETDATAAFTER, packet: CHANNEL_EOF (' + + chan + + ')'); + self.emit('CHANNEL_EOF:' + chan); + } else if (type === MESSAGE.CHANNEL_OPEN) { + /* + byte SSH_MSG_CHANNEL_OPEN + string channel type in US-ASCII only + uint32 sender channel + uint32 initial window size + uint32 maximum packet size + .... channel type specific data follows + */ + var chanType = readString(payload, 1, 'ascii', self, callback); + if (chanType === false) + return false; + sender = readInt(payload, payload._pos, self, callback); + if (sender === false) + return false; + window = readInt(payload, payload._pos += 4, self, callback); + if (window === false) + return false; + packetSize = readInt(payload, payload._pos += 4, self, callback); + if (packetSize === false) + return false; + var channel; + + self.debug('DEBUG: Parser: IN_PACKETDATAAFTER, packet: CHANNEL_OPEN (' + + sender + + ', ' + + chanType + + ')'); + + if (chanType === 'forwarded-tcpip' // Server->Client + || chanType === 'direct-tcpip') { // Client->Server + /* + string address that was connected / host to connect + uint32 port that was connected / port to connect + string originator IP address + uint32 originator port + */ + var destIP = readString(payload, + payload._pos += 4, + 'ascii', + self, + callback); + if (destIP === false) + return false; + var destPort = readInt(payload, payload._pos, self, callback); + if (destPort === false) + return false; + srcIP = readString(payload, payload._pos += 4, 'ascii', self, callback); + if (srcIP === false) + return false; + srcPort = readInt(payload, payload._pos, self, callback); + if (srcPort === false) + return false; + channel = { + type: chanType, + sender: sender, + window: window, + packetSize: packetSize, + data: { + destIP: destIP, + destPort: destPort, + srcIP: srcIP, + srcPort: srcPort + } + }; + } else if (// Server->Client + chanType === 'forwarded-streamlocal@openssh.com' + // Client->Server + || chanType === 'direct-streamlocal@openssh.com') { + /* + string socket path + string reserved for future use + */ + socketPath = readString(payload, + payload._pos += 4, + 'utf8', + self, + callback); + if (socketPath === false) + return false; + channel = { + type: chanType, + sender: sender, + window: window, + packetSize: packetSize, + data: { + socketPath: socketPath, + } + }; + } else if (chanType === 'x11') { // Server->Client + /* + string originator address (e.g., "192.168.7.38") + uint32 originator port + */ + srcIP = readString(payload, payload._pos += 4, 'ascii', self, callback); + if (srcIP === false) + return false; + srcPort = readInt(payload, payload._pos, self, callback); + if (srcPort === false) + return false; + channel = { + type: chanType, + sender: sender, + window: window, + packetSize: packetSize, + data: { + srcIP: srcIP, + srcPort: srcPort + } + }; + } else { + // 'session' (Client->Server), 'auth-agent@openssh.com' (Server->Client) + channel = { + type: chanType, + sender: sender, + window: window, + packetSize: packetSize, + data: {} + }; + } + + self.emit('CHANNEL_OPEN', channel); + } else if (type === MESSAGE.CHANNEL_OPEN_CONFIRMATION) { + /* + byte SSH_MSG_CHANNEL_OPEN_CONFIRMATION + uint32 recipient channel + uint32 sender channel + uint32 initial window size + uint32 maximum packet size + .... channel type specific data follows + */ + // "The 'recipient channel' is the channel number given in the + // original open request, and 'sender channel' is the channel number + // allocated by the other side." + recipient = readInt(payload, 1, self, callback); + if (recipient === false) + return false; + sender = readInt(payload, 5, self, callback); + if (sender === false) + return false; + window = readInt(payload, 9, self, callback); + if (window === false) + return false; + packetSize = readInt(payload, 13, self, callback); + if (packetSize === false) + return false; + + info = { + recipient: recipient, + sender: sender, + window: window, + packetSize: packetSize + }; + + if (payload.length > 17) + info.data = payload.slice(17); + + self.emit('CHANNEL_OPEN_CONFIRMATION:' + info.recipient, info); + } else if (type === MESSAGE.CHANNEL_OPEN_FAILURE) { + /* + byte SSH_MSG_CHANNEL_OPEN_FAILURE + uint32 recipient channel + uint32 reason code + string description in ISO-10646 UTF-8 encoding + string language tag + */ + recipient = readInt(payload, 1, self, callback); + if (recipient === false) + return false; + var reasonCode = readInt(payload, 5, self, callback); + if (reasonCode === false) + return false; + description = readString(payload, 9, 'utf8', self, callback); + if (description === false) + return false; + lang = readString(payload, payload._pos, 'utf8', self, callback); + if (lang === false) + return false; + payload._pos = 9; + info = { + recipient: recipient, + reasonCode: reasonCode, + reason: CHANNEL_OPEN_FAILURE[reasonCode], + description: description, + lang: lang + }; + + self.emit('CHANNEL_OPEN_FAILURE:' + info.recipient, info); + } else if (type === MESSAGE.CHANNEL_CLOSE) { + /* + byte SSH_MSG_CHANNEL_CLOSE + uint32 recipient channel + */ + chan = readInt(payload, 1, self, callback); + if (chan === false) + return false; + self.debug('DEBUG: Parser: IN_PACKETDATAAFTER, packet: CHANNEL_CLOSE (' + + chan + + ')'); + self.emit('CHANNEL_CLOSE:' + chan); + } else if (type === MESSAGE.IGNORE) { + /* + byte SSH_MSG_IGNORE + string data + */ + } else if (type === MESSAGE.DISCONNECT) { + /* + byte SSH_MSG_DISCONNECT + uint32 reason code + string description in ISO-10646 UTF-8 encoding + string language tag + */ + var reason = readInt(payload, 1, self, callback); + if (reason === false) + return false; + var reasonText = DISCONNECT_REASON[reason]; + description = readString(payload, 5, 'utf8', self, callback); + if (description === false) + return false; + + lang = readString(payload, payload._pos, 'ascii', self, callback); + + self.debug('DEBUG: Parser: IN_PACKETDATAAFTER, packet: DISCONNECT (' + + reasonText + + ')'); + + self.emit('DISCONNECT', reasonText, reason, description, lang); + } else if (type === MESSAGE.DEBUG) { + /* + byte SSH_MSG_DEBUG + boolean always_display + string message in ISO-10646 UTF-8 encoding + string language tag + */ + message = readString(payload, 2, 'utf8', self, callback); + if (message === false) + return false; + lang = readString(payload, payload._pos, 'ascii', self, callback); + if (lang === false) + return false; + + self.emit('DEBUG', message, lang); + } else if (type === MESSAGE.NEWKEYS) { + /* + byte SSH_MSG_NEW_KEYS + */ + self.emit('NEWKEYS'); + } else if (type === MESSAGE.SERVICE_REQUEST) { + /* + byte SSH_MSG_SERVICE_REQUEST + string service name + */ + serviceName = readString(payload, 1, 'ascii', self, callback); + if (serviceName === false) + return false; + + self.emit('SERVICE_REQUEST', serviceName); + } else if (type === MESSAGE.SERVICE_ACCEPT) { + /* + byte SSH_MSG_SERVICE_ACCEPT + string service name + */ + serviceName = readString(payload, 1, 'ascii', self, callback); + if (serviceName === false) + return false; + + self.emit('SERVICE_ACCEPT', serviceName); + } else if (type === MESSAGE.USERAUTH_REQUEST) { + /* + byte SSH_MSG_USERAUTH_REQUEST + string user name in ISO-10646 UTF-8 encoding [RFC3629] + string service name in US-ASCII + string method name in US-ASCII + .... method specific fields + */ + var username = readString(payload, 1, 'utf8', self, callback); + if (username === false) + return false; + var svcName = readString(payload, payload._pos, 'ascii', self, callback); + if (svcName === false) + return false; + var method = readString(payload, payload._pos, 'ascii', self, callback); + if (method === false) + return false; + var methodData; + + if (method === 'password') { + methodData = readString(payload, + payload._pos + 1, + 'utf8', + self, + callback); + if (methodData === false) + return false; + } else if (method === 'publickey' || method === 'hostbased') { + var pkSigned; + var keyAlgo; + var key; + var signature; + var blob; + var hostname; + var userlocal; + if (method === 'publickey') { + pkSigned = payload[payload._pos++]; + if (pkSigned === undefined) + return false; + pkSigned = (pkSigned !== 0); + } + keyAlgo = readString(payload, payload._pos, 'ascii', self, callback); + if (keyAlgo === false) + return false; + key = readString(payload, payload._pos, self, callback); + if (key === false) + return false; + + if (pkSigned || method === 'hostbased') { + if (method === 'hostbased') { + hostname = readString(payload, payload._pos, 'ascii', self, callback); + if (hostname === false) + return false; + userlocal = readString(payload, payload._pos, 'utf8', self, callback); + if (userlocal === false) + return false; + } + + var blobEnd = payload._pos; + signature = readString(payload, blobEnd, self, callback); + if (signature === false) + return false; + + if (signature.length > (4 + keyAlgo.length + 4) + && signature.toString('ascii', 4, 4 + keyAlgo.length) === keyAlgo) { + // Skip algoLen + algo + sigLen + signature = signature.slice(4 + keyAlgo.length + 4); + } + + if (keyAlgo === 'ssh-dss') { + signature = DSASigBareToBER(signature); + } else if (keyAlgo !== 'ssh-rsa' && keyAlgo !== 'ssh-dss') { + // ECDSA + signature = ECDSASigSSHToASN1(signature, self, callback); + if (signature === false) + return false; + } + + blob = new Buffer(4 + outstate.sessionId.length + blobEnd); + blob.writeUInt32BE(outstate.sessionId.length, 0, true); + outstate.sessionId.copy(blob, 4); + payload.copy(blob, 4 + outstate.sessionId.length, 0, blobEnd); + } + + methodData = { + keyAlgo: keyAlgo, + key: key, + signature: signature, + blob: blob, + localHostname: hostname, + localUsername: userlocal + }; + } else if (method === 'keyboard-interactive') { + // Skip language, it's deprecated + var skipLen = readInt(payload, payload._pos, self, callback); + if (skipLen === false) + return false; + methodData = readString(payload, + payload._pos + 4 + skipLen, + 'utf8', + self, + callback); + if (methodData === false) + return false; + } else if (method !== 'none') + methodData = payload.slice(payload._pos); + + self.debug('DEBUG: Parser: IN_PACKETDATAAFTER, packet: USERAUTH_REQUEST (' + + method + + ')'); + + self._state.authsQueue.push(method); + self.emit('USERAUTH_REQUEST', username, svcName, method, methodData); + } else if (type === MESSAGE.USERAUTH_SUCCESS) { + /* + byte SSH_MSG_USERAUTH_SUCCESS + */ + if (outstate.compress.type === 'zlib@openssh.com') + outstate.compress.instance = zlib.createDeflate(ZLIB_OPTS); + if (instate.decompress.type === 'zlib@openssh.com') + instate.decompress.instance = zlib.createInflate(ZLIB_OPTS); + self._state.authsQueue.shift(); + self.emit('USERAUTH_SUCCESS'); + } else if (type === MESSAGE.USERAUTH_FAILURE) { + /* + byte SSH_MSG_USERAUTH_FAILURE + name-list authentications that can continue + boolean partial success + */ + var auths = readString(payload, 1, 'ascii', self, callback); + if (auths === false) + return false; + var partSuccess = payload[payload._pos]; + if (partSuccess === undefined) + return false; + + partSuccess = (partSuccess !== 0); + auths = auths.split(','); + + self._state.authsQueue.shift(); + self.emit('USERAUTH_FAILURE', auths, partSuccess); + } else if (type === MESSAGE.USERAUTH_BANNER) { + /* + byte SSH_MSG_USERAUTH_BANNER + string message in ISO-10646 UTF-8 encoding + string language tag + */ + message = readString(payload, 1, 'utf8', self, callback); + if (message === false) + return false; + lang = readString(payload, payload._pos, 'utf8', self, callback); + if (lang === false) + return false; + + self.emit('USERAUTH_BANNER', message, lang); + } else if (type === MESSAGE.GLOBAL_REQUEST) { + /* + byte SSH_MSG_GLOBAL_REQUEST + string request name in US-ASCII only + boolean want reply + .... request-specific data follows + */ + var request = readString(payload, 1, 'ascii', self, callback); + if (request === false) + return false; + var wantReply = payload[payload._pos++]; + if (wantReply === undefined) + return false; + var reqData; + + wantReply = (wantReply !== 0); + + if (request === 'tcpip-forward' || request === 'cancel-tcpip-forward') { + var bindAddr = readString(payload, payload._pos, 'ascii', self, callback); + if (bindAddr === false) + return false; + var bindPort = readInt(payload, payload._pos, self, callback); + if (bindPort === false) + return false; + reqData = { + bindAddr: bindAddr, + bindPort: bindPort + }; + } else if (request === 'streamlocal-forward@openssh.com' + || request === 'cancel-streamlocal-forward@openssh.com') { + socketPath = readString(payload, payload._pos, 'utf8', self, callback); + if (socketPath === false) + return false; + reqData = { + socketPath: socketPath + }; + } else if (request === 'no-more-sessions@openssh.com') { + // No data + } else + reqData = payload.slice(payload._pos); + + self.emit('GLOBAL_REQUEST', request, wantReply, reqData); + } else if (type === MESSAGE.REQUEST_SUCCESS) { + /* + byte SSH_MSG_REQUEST_SUCCESS + .... response specific data + */ + if (payload.length > 1) + self.emit('REQUEST_SUCCESS', payload.slice(1)); + else + self.emit('REQUEST_SUCCESS'); + } else if (type === MESSAGE.REQUEST_FAILURE) { + /* + byte SSH_MSG_REQUEST_FAILURE + */ + self.emit('REQUEST_FAILURE'); + } else if (type === MESSAGE.UNIMPLEMENTED) { + /* + byte SSH_MSG_UNIMPLEMENTED + uint32 packet sequence number of rejected message + */ + // TODO + } else if (type === MESSAGE.KEXINIT) + return parse_KEXINIT(self, callback); + else if (type === MESSAGE.CHANNEL_REQUEST) + return parse_CHANNEL_REQUEST(self, callback); + else if (type >= 30 && type <= 49) // Key exchange method-specific messages + return parse_KEX(self, type, callback); + else if (type >= 60 && type <= 70) // User auth context-specific messages + return parse_USERAUTH(self, type, callback); + else { + // Unknown packet type + var unimpl = new Buffer(1 + 4); + unimpl[0] = MESSAGE.UNIMPLEMENTED; + unimpl.writeUInt32BE(seqno, 1, true); + send(self, unimpl); + } +} + +function parse_KEXINIT(self, callback) { + var instate = self._state.incoming; + var payload = instate.payload; + + /* + byte SSH_MSG_KEXINIT + byte[16] cookie (random bytes) + name-list kex_algorithms + name-list server_host_key_algorithms + name-list encryption_algorithms_client_to_server + name-list encryption_algorithms_server_to_client + name-list mac_algorithms_client_to_server + name-list mac_algorithms_server_to_client + name-list compression_algorithms_client_to_server + name-list compression_algorithms_server_to_client + name-list languages_client_to_server + name-list languages_server_to_client + boolean first_kex_packet_follows + uint32 0 (reserved for future extension) + */ + var init = { + algorithms: { + kex: undefined, + srvHostKey: undefined, + cs: { + encrypt: undefined, + mac: undefined, + compress: undefined + }, + sc: { + encrypt: undefined, + mac: undefined, + compress: undefined + } + }, + languages: { + cs: undefined, + sc: undefined + } + }; + var val; + + val = readList(payload, 17, self, callback); + if (val === false) + return false; + init.algorithms.kex = val; + val = readList(payload, payload._pos, self, callback); + if (val === false) + return false; + init.algorithms.srvHostKey = val; + val = readList(payload, payload._pos, self, callback); + if (val === false) + return false; + init.algorithms.cs.encrypt = val; + val = readList(payload, payload._pos, self, callback); + if (val === false) + return false; + init.algorithms.sc.encrypt = val; + val = readList(payload, payload._pos, self, callback); + if (val === false) + return false; + init.algorithms.cs.mac = val; + val = readList(payload, payload._pos, self, callback); + if (val === false) + return false; + init.algorithms.sc.mac = val; + val = readList(payload, payload._pos, self, callback); + if (val === false) + return false; + init.algorithms.cs.compress = val; + val = readList(payload, payload._pos, self, callback); + if (val === false) + return false; + init.algorithms.sc.compress = val; + val = readList(payload, payload._pos, self, callback); + if (val === false) + return false; + init.languages.cs = val; + val = readList(payload, payload._pos, self, callback); + if (val === false) + return false; + init.languages.sc = val; + + var firstFollows = (payload._pos < payload.length + && payload[payload._pos] === 1); + + instate.kexinit = payload; + + self.emit('KEXINIT', init, firstFollows); +} + +function parse_KEX(self, type, callback) { + var state = self._state; + var instate = state.incoming; + var payload = instate.payload; + var pktType = (RE_GEX.test(state.kexdh) + ? DYNAMIC_KEXDH_MESSAGE[type] + : KEXDH_MESSAGE[type]); + + if (state.outgoing.status === OUT_READY + || instate.expectedPacket !== pktType) { + self.debug('DEBUG: Parser: IN_PACKETDATAAFTER, expected: ' + + instate.expectedPacket + + ' but got: ' + + pktType); + self.disconnect(DISCONNECT_REASON.PROTOCOL_ERROR); + var err = new Error('Received unexpected packet'); + err.level = 'protocol'; + self.emit('error', err); + return false; + } + + if (RE_GEX.test(state.kexdh)) { + // Dynamic group exchange-related + + if (self.server) { + // TODO: Support group exchange server-side + self.disconnect(DISCONNECT_REASON.PROTOCOL_ERROR); + var err = new Error('DH group exchange not supported by server'); + err.level = 'handshake'; + self.emit('error', err); + return false; + } else { + if (type === MESSAGE.KEXDH_GEX_GROUP) { + /* + byte SSH_MSG_KEX_DH_GEX_GROUP + mpint p, safe prime + mpint g, generator for subgroup in GF(p) + */ + var prime = readString(payload, 1, self, callback); + if (prime === false) + return false; + var gen = readString(payload, payload._pos, self, callback); + if (gen === false) + return false; + self.emit('KEXDH_GEX_GROUP', prime, gen); + } else if (type === MESSAGE.KEXDH_GEX_REPLY) + return parse_KEXDH_REPLY(self, callback); + } + } else { + // Static group or ECDH-related + + if (type === MESSAGE.KEXDH_INIT) { + /* + byte SSH_MSG_KEXDH_INIT + mpint e + */ + var e = readString(payload, 1, self, callback); + if (e === false) + return false; + + self.emit('KEXDH_INIT', e); + } else if (type === MESSAGE.KEXDH_REPLY) + return parse_KEXDH_REPLY(self, callback); + } +} + +function parse_KEXDH_REPLY(self, callback) { + var payload = self._state.incoming.payload; + /* + byte SSH_MSG_KEXDH_REPLY + / SSH_MSG_KEX_DH_GEX_REPLY + / SSH_MSG_KEX_ECDH_REPLY + string server public host key and certificates (K_S) + mpint f + string signature of H + */ + var hostkey = readString(payload, 1, self, callback); + if (hostkey === false) + return false; + var pubkey = readString(payload, payload._pos, self, callback); + if (pubkey === false) + return false; + var sig = readString(payload, payload._pos, self, callback); + if (sig === false) + return false; + var info = { + hostkey: hostkey, + hostkey_format: undefined, + pubkey: pubkey, + sig: sig, + sig_format: undefined + }; + var hostkey_format = readString(hostkey, 0, 'ascii', self, callback); + if (hostkey_format === false) + return false; + info.hostkey_format = hostkey_format; + var sig_format = readString(sig, 0, 'ascii', self, callback); + if (sig_format === false) + return false; + info.sig_format = sig_format; + self.emit('KEXDH_REPLY', info); +} + +function parse_USERAUTH(self, type, callback) { + var state = self._state; + var authMethod = state.authsQueue[0]; + var payload = state.incoming.payload; + var message; + var lang; + var text; + + if (authMethod === 'password') { + if (type === MESSAGE.USERAUTH_PASSWD_CHANGEREQ) { + /* + byte SSH_MSG_USERAUTH_PASSWD_CHANGEREQ + string prompt in ISO-10646 UTF-8 encoding + string language tag + */ + message = readString(payload, 1, 'utf8', self, callback); + if (message === false) + return false; + lang = readString(payload, payload._pos, 'utf8', self, callback); + if (lang === false) + return false; + self.emit('USERAUTH_PASSWD_CHANGEREQ', message, lang); + } + } else if (authMethod === 'keyboard-interactive') { + if (type === MESSAGE.USERAUTH_INFO_REQUEST) { + /* + byte SSH_MSG_USERAUTH_INFO_REQUEST + string name (ISO-10646 UTF-8) + string instruction (ISO-10646 UTF-8) + string language tag -- MAY be empty + int num-prompts + string prompt[1] (ISO-10646 UTF-8) + boolean echo[1] + ... + string prompt[num-prompts] (ISO-10646 UTF-8) + boolean echo[num-prompts] + */ + var name; + var instr; + var nprompts; + + name = readString(payload, 1, 'utf8', self, callback); + if (name === false) + return false; + instr = readString(payload, payload._pos, 'utf8', self, callback); + if (instr === false) + return false; + lang = readString(payload, payload._pos, 'utf8', self, callback); + if (lang === false) + return false; + nprompts = readInt(payload, payload._pos, self, callback); + if (nprompts === false) + return false; + + payload._pos += 4; + + var prompts = []; + for (var prompt = 0; prompt < nprompts; ++prompt) { + text = readString(payload, payload._pos, 'utf8', self, callback); + if (text === false) + return false; + var echo = payload[payload._pos++]; + if (echo === undefined) + return false; + echo = (echo !== 0); + prompts.push({ + prompt: text, + echo: echo + }); + } + self.emit('USERAUTH_INFO_REQUEST', name, instr, lang, prompts); + } else if (type === MESSAGE.USERAUTH_INFO_RESPONSE) { + /* + byte SSH_MSG_USERAUTH_INFO_RESPONSE + int num-responses + string response[1] (ISO-10646 UTF-8) + ... + string response[num-responses] (ISO-10646 UTF-8) + */ + var nresponses = readInt(payload, 1, self, callback); + if (nresponses === false) + return false; + + payload._pos = 5; + + var responses = []; + for (var response = 0; response < nresponses; ++response) { + text = readString(payload, payload._pos, 'utf8', self, callback); + if (text === false) + return false; + responses.push(text); + } + self.emit('USERAUTH_INFO_RESPONSE', responses); + } + } else if (authMethod === 'publickey') { + if (type === MESSAGE.USERAUTH_PK_OK) { + /* + byte SSH_MSG_USERAUTH_PK_OK + string public key algorithm name from the request + string public key blob from the request + */ + var authsQueue = self._state.authsQueue; + if (!authsQueue.length || authsQueue[0] !== 'publickey') + return; + authsQueue.shift(); + self.emit('USERAUTH_PK_OK'); + // XXX: Parse public key info? client currently can ignore it because + // there is only one outstanding auth request at any given time, so it + // knows which key was OK'd + } + } else if (authMethod !== undefined) { + // Invalid packet for this auth type + self.disconnect(DISCONNECT_REASON.PROTOCOL_ERROR); + var err = new Error('Invalid authentication method: ' + authMethod); + err.level = 'protocol'; + self.emit('error', err); + } +} + +function parse_CHANNEL_REQUEST(self, callback) { + var payload = self._state.incoming.payload; + var info; + var cols; + var rows; + var width; + var height; + var wantReply; + var signal; + + var recipient = readInt(payload, 1, self, callback); + if (recipient === false) + return false; + var request = readString(payload, 5, 'ascii', self, callback); + if (request === false) + return false; + + if (request === 'exit-status') { // Server->Client + /* + byte SSH_MSG_CHANNEL_REQUEST + uint32 recipient channel + string "exit-status" + boolean FALSE + uint32 exit_status + */ + var code = readInt(payload, ++payload._pos, self, callback); + if (code === false) + return false; + info = { + recipient: recipient, + request: request, + wantReply: false, + code: code + }; + } else if (request === 'exit-signal') { // Server->Client + /* + byte SSH_MSG_CHANNEL_REQUEST + uint32 recipient channel + string "exit-signal" + boolean FALSE + string signal name (without the "SIG" prefix) + boolean core dumped + string error message in ISO-10646 UTF-8 encoding + string language tag + */ + var coredump; + if (!(self.remoteBugs & BUGS.OLD_EXIT)) { + signal = readString(payload, ++payload._pos, 'ascii', self, callback); + if (signal === false) + return false; + coredump = payload[payload._pos++]; + if (coredump === undefined) + return false; + coredump = (coredump !== 0); + } else { + /* + Instead of `signal name` and `core dumped`, we have just: + + uint32 signal number + */ + signal = readInt(payload, ++payload._pos, self, callback); + if (signal === false) + return false; + switch (signal) { + case 1: + signal = 'HUP'; + break; + case 2: + signal = 'INT'; + break; + case 3: + signal = 'QUIT'; + break; + case 6: + signal = 'ABRT'; + break; + case 9: + signal = 'KILL'; + break; + case 14: + signal = 'ALRM'; + break; + case 15: + signal = 'TERM'; + break; + default: + // Unknown or OS-specific + signal = 'UNKNOWN (' + signal + ')'; + } + coredump = false; + } + var description = readString(payload, payload._pos, 'utf8', self, + callback); + if (description === false) + return false; + var lang = readString(payload, payload._pos, 'utf8', self, callback); + if (lang === false) + return false; + info = { + recipient: recipient, + request: request, + wantReply: false, + signal: signal, + coredump: coredump, + description: description, + lang: lang + }; + } else if (request === 'pty-req') { // Client->Server + /* + byte SSH_MSG_CHANNEL_REQUEST + uint32 recipient channel + string "pty-req" + boolean want_reply + string TERM environment variable value (e.g., vt100) + uint32 terminal width, characters (e.g., 80) + uint32 terminal height, rows (e.g., 24) + uint32 terminal width, pixels (e.g., 640) + uint32 terminal height, pixels (e.g., 480) + string encoded terminal modes + */ + wantReply = payload[payload._pos++]; + if (wantReply === undefined) + return false; + wantReply = (wantReply !== 0); + var term = readString(payload, payload._pos, 'ascii', self, callback); + if (term === false) + return false; + cols = readInt(payload, payload._pos, self, callback); + if (cols === false) + return false; + rows = readInt(payload, payload._pos += 4, self, callback); + if (rows === false) + return false; + width = readInt(payload, payload._pos += 4, self, callback); + if (width === false) + return false; + height = readInt(payload, payload._pos += 4, self, callback); + if (height === false) + return false; + var modes = readString(payload, payload._pos += 4, self, callback); + if (modes === false) + return false; + modes = bytesToModes(modes); + info = { + recipient: recipient, + request: request, + wantReply: wantReply, + term: term, + cols: cols, + rows: rows, + width: width, + height: height, + modes: modes + }; + } else if (request === 'window-change') { // Client->Server + /* + byte SSH_MSG_CHANNEL_REQUEST + uint32 recipient channel + string "window-change" + boolean FALSE + uint32 terminal width, columns + uint32 terminal height, rows + uint32 terminal width, pixels + uint32 terminal height, pixels + */ + cols = readInt(payload, ++payload._pos, self, callback); + if (cols === false) + return false; + rows = readInt(payload, payload._pos += 4, self, callback); + if (rows === false) + return false; + width = readInt(payload, payload._pos += 4, self, callback); + if (width === false) + return false; + height = readInt(payload, payload._pos += 4, self, callback); + if (height === false) + return false; + info = { + recipient: recipient, + request: request, + wantReply: false, + cols: cols, + rows: rows, + width: width, + height: height + }; + } else if (request === 'x11-req') { // Client->Server + /* + byte SSH_MSG_CHANNEL_REQUEST + uint32 recipient channel + string "x11-req" + boolean want reply + boolean single connection + string x11 authentication protocol + string x11 authentication cookie + uint32 x11 screen number + */ + wantReply = payload[payload._pos++]; + if (wantReply === undefined) + return false; + wantReply = (wantReply !== 0); + var single = payload[payload._pos++]; + if (single === undefined) + return false; + single = (single !== 0); + var protocol = readString(payload, payload._pos, 'ascii', self, callback); + if (protocol === false) + return false; + var cookie = readString(payload, payload._pos, 'hex', self, callback); + if (cookie === false) + return false; + var screen = readInt(payload, payload._pos, self, callback); + if (screen === false) + return false; + info = { + recipient: recipient, + request: request, + wantReply: wantReply, + single: single, + protocol: protocol, + cookie: cookie, + screen: screen + }; + } else if (request === 'env') { // Client->Server + /* + byte SSH_MSG_CHANNEL_REQUEST + uint32 recipient channel + string "env" + boolean want reply + string variable name + string variable value + */ + wantReply = payload[payload._pos++]; + if (wantReply === undefined) + return false; + wantReply = (wantReply !== 0); + var key = readString(payload, payload._pos, 'utf8', self, callback); + if (key === false) + return false; + var val = readString(payload, payload._pos, 'utf8', self, callback); + if (val === false) + return false; + info = { + recipient: recipient, + request: request, + wantReply: wantReply, + key: key, + val: val + }; + } else if (request === 'shell') { // Client->Server + /* + byte SSH_MSG_CHANNEL_REQUEST + uint32 recipient channel + string "shell" + boolean want reply + */ + wantReply = payload[payload._pos]; + if (wantReply === undefined) + return false; + wantReply = (wantReply !== 0); + info = { + recipient: recipient, + request: request, + wantReply: wantReply + }; + } else if (request === 'exec') { // Client->Server + /* + byte SSH_MSG_CHANNEL_REQUEST + uint32 recipient channel + string "exec" + boolean want reply + string command + */ + wantReply = payload[payload._pos++]; + if (wantReply === undefined) + return false; + wantReply = (wantReply !== 0); + var command = readString(payload, payload._pos, 'utf8', self, callback); + if (command === false) + return false; + info = { + recipient: recipient, + request: request, + wantReply: wantReply, + command: command + }; + } else if (request === 'subsystem') { // Client->Server + /* + byte SSH_MSG_CHANNEL_REQUEST + uint32 recipient channel + string "subsystem" + boolean want reply + string subsystem name + */ + wantReply = payload[payload._pos++]; + if (wantReply === undefined) + return false; + wantReply = (wantReply !== 0); + var subsystem = readString(payload, payload._pos, 'utf8', self, callback); + if (subsystem === false) + return false; + info = { + recipient: recipient, + request: request, + wantReply: wantReply, + subsystem: subsystem + }; + } else if (request === 'signal') { // Client->Server + /* + byte SSH_MSG_CHANNEL_REQUEST + uint32 recipient channel + string "signal" + boolean FALSE + string signal name (without the "SIG" prefix) + */ + signal = readString(payload, ++payload._pos, 'ascii', self, callback); + if (signal === false) + return false; + info = { + recipient: recipient, + request: request, + wantReply: false, + signal: 'SIG' + signal + }; + } else if (request === 'xon-xoff') { // Client->Server + /* + byte SSH_MSG_CHANNEL_REQUEST + uint32 recipient channel + string "xon-xoff" + boolean FALSE + boolean client can do + */ + var clientControl = payload[++payload._pos]; + if (clientControl === undefined) + return false; + clientControl = (clientControl !== 0); + info = { + recipient: recipient, + request: request, + wantReply: false, + clientControl: clientControl + }; + } else if (request === 'auth-agent-req@openssh.com') { // Client->Server + /* + byte SSH_MSG_CHANNEL_REQUEST + uint32 recipient channel + string "auth-agent-req@openssh.com" + boolean want reply + */ + wantReply = payload[payload._pos]; + if (wantReply === undefined) + return false; + wantReply = (wantReply !== 0); + info = { + recipient: recipient, + request: request, + wantReply: wantReply + }; + } else { + // Unknown request type + wantReply = payload[payload._pos]; + if (wantReply === undefined) + return false; + wantReply = (wantReply !== 0); + info = { + recipient: recipient, + request: request, + wantReply: wantReply + }; + } + self.debug('DEBUG: Parser: IN_PACKETDATAAFTER, packet: CHANNEL_REQUEST (' + + recipient + + ', ' + + request + + ')'); + self.emit('CHANNEL_REQUEST:' + recipient, info); +} + +function hmacVerify(self, data) { + var instate = self._state.incoming; + var hmac = instate.hmac; + + self.debug('DEBUG: Parser: Verifying MAC'); + + if (instate.decrypt.isGCM) { + var decrypt = instate.decrypt; + var instance = decrypt.instance; + + instance.setAuthTag(data); + + var payload = instance.update(instate.packet); + instate.payload = payload.slice(1, instate.packet.length + 4 - payload[0]); + //instance.final(); + iv_inc(decrypt.iv); + + decrypt.instance = crypto.createDecipheriv( + SSH_TO_OPENSSL[decrypt.type], + decrypt.key, + decrypt.iv + ); + decrypt.instance.setAutoPadding(false); + return true; + } else { + var calcHmac = crypto.createHmac(SSH_TO_OPENSSL[hmac.type], hmac.key); + + hmac.bufCompute.writeUInt32BE(instate.seqno, 0, true); + hmac.bufCompute.writeUInt32BE(instate.pktLen, 4, true); + hmac.bufCompute[8] = instate.padLen; + + calcHmac.update(hmac.bufCompute); + calcHmac.update(instate.packet); + + var mac = calcHmac.digest('binary'); + if (mac.length > instate.hmac.size) + mac = mac.slice(0, instate.hmac.size); + return (mac === data.toString('binary')); + } +} + +function decryptData(self, data) { + var instance = self._state.incoming.decrypt.instance; + self.debug('DEBUG: Parser: Decrypting'); + return instance.update(data); +} + +function expectData(self, type, amount, bufferKey) { + var expect = self._state.incoming.expect; + expect.amount = amount; + expect.type = type; + expect.ptr = 0; + if (bufferKey && self[bufferKey]) + expect.buf = self[bufferKey]; + else if (amount) + expect.buf = new Buffer(amount); +} + +function readList(buffer, start, stream, callback) { + var list = readString(buffer, start, 'ascii', stream, callback); + return (list !== false ? (list.length ? list.split(',') : []) : false); +} + +function bytesToModes(buffer) { + var modes = {}; + + for (var i = 0, len = buffer.length, opcode; i < len; i += 5) { + opcode = buffer[i]; + if (opcode === TERMINAL_MODE.TTY_OP_END + || TERMINAL_MODE[opcode] === undefined + || i + 5 > len) + break; + modes[TERMINAL_MODE[opcode]] = buffer.readUInt32BE(i + 1, true); + } + + return modes; +} + +function modesToBytes(modes) { + var RE_IS_NUM = /^\d+$/; + var keys = Object.keys(modes); + var b = 0; + var bytes = []; + + for (var i = 0, len = keys.length, key, opcode, val; i < len; ++i) { + key = keys[i]; + opcode = TERMINAL_MODE[key]; + if (opcode + && !RE_IS_NUM.test(key) + && typeof modes[key] === 'number' + && key !== 'TTY_OP_END') { + val = modes[key]; + bytes[b++] = opcode; + bytes[b++] = (val >>> 24) & 0xFF; + bytes[b++] = (val >>> 16) & 0xFF; + bytes[b++] = (val >>> 8) & 0xFF; + bytes[b++] = val & 0xFF; + } + } + + bytes[b] = TERMINAL_MODE.TTY_OP_END; + + return bytes; +} + +// Shared outgoing functions +function KEXINIT(self, cb) { // Client/Server + randBytes(16, function(myCookie) { + /* + byte SSH_MSG_KEXINIT + byte[16] cookie (random bytes) + name-list kex_algorithms + name-list server_host_key_algorithms + name-list encryption_algorithms_client_to_server + name-list encryption_algorithms_server_to_client + name-list mac_algorithms_client_to_server + name-list mac_algorithms_server_to_client + name-list compression_algorithms_client_to_server + name-list compression_algorithms_server_to_client + name-list languages_client_to_server + name-list languages_server_to_client + boolean first_kex_packet_follows + uint32 0 (reserved for future extension) + */ + var algos = self.config.algorithms; + + var kexBuf = algos.kexBuf; + if (self.remoteBugs & BUGS.BAD_DHGEX) { + var copied = false; + var kexList = algos.kex; + for (var j = kexList.length - 1; j >= 0; --j) { + if (kexList[j].indexOf('group-exchange') !== -1) { + if (!copied) { + kexList = kexList.slice(); + copied = true; + } + kexList.splice(j, 1); + } + } + if (copied) + kexBuf = new Buffer(kexList.join(',')); + } + + var hostKeyBuf = algos.serverHostKeyBuf; + + var kexInitSize = 1 + 16 + + 4 + kexBuf.length + + 4 + hostKeyBuf.length + + (2 * (4 + algos.cipherBuf.length)) + + (2 * (4 + algos.hmacBuf.length)) + + (2 * (4 + algos.compressBuf.length)) + + (2 * (4 /* languages skipped */)) + + 1 + 4; + var buf = new Buffer(kexInitSize); + var p = 17; + + buf.fill(0); + + buf[0] = MESSAGE.KEXINIT; + + if (myCookie !== false) + myCookie.copy(buf, 1); + + buf.writeUInt32BE(kexBuf.length, p, true); + p += 4; + kexBuf.copy(buf, p); + p += kexBuf.length; + + buf.writeUInt32BE(hostKeyBuf.length, p, true); + p += 4; + hostKeyBuf.copy(buf, p); + p += hostKeyBuf.length; + + buf.writeUInt32BE(algos.cipherBuf.length, p, true); + p += 4; + algos.cipherBuf.copy(buf, p); + p += algos.cipherBuf.length; + + buf.writeUInt32BE(algos.cipherBuf.length, p, true); + p += 4; + algos.cipherBuf.copy(buf, p); + p += algos.cipherBuf.length; + + buf.writeUInt32BE(algos.hmacBuf.length, p, true); + p += 4; + algos.hmacBuf.copy(buf, p); + p += algos.hmacBuf.length; + + buf.writeUInt32BE(algos.hmacBuf.length, p, true); + p += 4; + algos.hmacBuf.copy(buf, p); + p += algos.hmacBuf.length; + + buf.writeUInt32BE(algos.compressBuf.length, p, true); + p += 4; + algos.compressBuf.copy(buf, p); + p += algos.compressBuf.length; + + buf.writeUInt32BE(algos.compressBuf.length, p, true); + p += 4; + algos.compressBuf.copy(buf, p); + p += algos.compressBuf.length; + + // Skip language lists, first_kex_packet_follows, and reserved bytes + + self.debug('DEBUG: Outgoing: Writing KEXINIT'); + + self._state.incoming.expectedPacket = 'KEXINIT'; + + var outstate = self._state.outgoing; + + outstate.kexinit = buf; + + if (outstate.status === OUT_READY) { + // We are the one starting the rekeying process ... + outstate.status = OUT_REKEYING; + } + + send(self, buf, cb, true); + }); + return true; +} + +function KEXDH_INIT(self) { // Client + var state = self._state; + var outstate = state.outgoing; + var buf = new Buffer(1 + 4 + outstate.pubkey.length); + + if (RE_GEX.test(state.kexdh)) { + state.incoming.expectedPacket = 'KEXDH_GEX_REPLY'; + buf[0] = MESSAGE.KEXDH_GEX_INIT; + self.debug('DEBUG: Outgoing: Writing KEXDH_GEX_INIT'); + } else { + state.incoming.expectedPacket = 'KEXDH_REPLY'; + buf[0] = MESSAGE.KEXDH_INIT; + if (state.kexdh !== 'group') + self.debug('DEBUG: Outgoing: Writing KEXECDH_INIT'); + else + self.debug('DEBUG: Outgoing: Writing KEXDH_INIT'); + } + + buf.writeUInt32BE(outstate.pubkey.length, 1, true); + outstate.pubkey.copy(buf, 5); + + return send(self, buf, undefined, true); +} + +function KEXDH_REPLY(self, e) { // Server + var state = self._state; + var outstate = state.outgoing; + var instate = state.incoming; + var curHostKey = self.config.hostKeys[state.hostkeyFormat]; + var hostkey = curHostKey.publicKey.public; + var hostkeyAlgo = curHostKey.publicKey.fulltype; + var privateKey = curHostKey.privateKey.privateOrig; + + // e === client DH public key + + var slicepos = -1; + for (var i = 0, len = e.length; i < len; ++i) { + if (e[i] === 0) + ++slicepos; + else + break; + } + if (slicepos > -1) + e = e.slice(slicepos + 1); + + var secret = tryComputeSecret(state.kex, e); + if (secret instanceof Error) { + secret.message = 'Error while computing DH secret (' + + state.kexdh + '): ' + + secret.message; + secret.level = 'handshake'; + self.emit('error', secret); + self.disconnect(DISCONNECT_REASON.KEY_EXCHANGE_FAILED); + return false; + } + + var hashAlgo; + if (state.kexdh === 'group') + hashAlgo = 'sha1'; + else + hashAlgo = RE_KEX_HASH.exec(state.kexdh)[1]; + + var hash = crypto.createHash(hashAlgo); + + var len_ident = Buffer.byteLength(instate.identRaw); + var len_sident = Buffer.byteLength(self.config.ident); + var len_init = instate.kexinit.length; + var len_sinit = outstate.kexinit.length; + var len_hostkey = hostkey.length; + var len_pubkey = e.length; + var len_spubkey = outstate.pubkey.length; + var len_secret = secret.length; + + var idx_spubkey = 0; + var idx_secret = 0; + + while (outstate.pubkey[idx_spubkey] === 0x00) { + ++idx_spubkey; + --len_spubkey; + } + while (secret[idx_secret] === 0x00) { + ++idx_secret; + --len_secret; + } + if (e[0] & 0x80) + ++len_pubkey; + if (outstate.pubkey[idx_spubkey] & 0x80) + ++len_spubkey; + if (secret[idx_secret] & 0x80) + ++len_secret; + + var exchangeBufLen = len_ident + + len_sident + + len_init + + len_sinit + + len_hostkey + + len_pubkey + + len_spubkey + + len_secret + + (4 * 8); // Length fields for above values + + // Group exchange-related + var isGEX = RE_GEX.test(state.kexdh); + var len_gex_prime = 0; + var len_gex_gen = 0; + var idx_gex_prime = 0; + var idx_gex_gen = 0; + var gex_prime; + var gex_gen; + if (isGEX) { + gex_prime = state.kex.getPrime(); + gex_gen = state.kex.getGenerator(); + len_gex_prime = gex_prime.length; + len_gex_gen = gex_gen.length; + while (gex_prime[idx_gex_prime] === 0x00) { + ++idx_gex_prime; + --len_gex_prime; + } + while (gex_gen[idx_gex_gen] === 0x00) { + ++idx_gex_gen; + --len_gex_gen; + } + if (gex_prime[idx_gex_prime] & 0x80) + ++len_gex_prime; + if (gex_gen[idx_gex_gen] & 0x80) + ++len_gex_gen; + exchangeBufLen += (4 * 3); // min, n, max values + exchangeBufLen += (4 * 2); // prime, generator length fields + exchangeBufLen += len_gex_prime; + exchangeBufLen += len_gex_gen; + } + + var bp = 0; + var exchangeBuf = new Buffer(exchangeBufLen); + + exchangeBuf.writeUInt32BE(len_ident, bp, true); + bp += 4; + exchangeBuf.write(instate.identRaw, bp, 'utf8'); // V_C + bp += len_ident; + + exchangeBuf.writeUInt32BE(len_sident, bp, true); + bp += 4; + exchangeBuf.write(self.config.ident, bp, 'utf8'); // V_S + bp += len_sident; + + exchangeBuf.writeUInt32BE(len_init, bp, true); + bp += 4; + instate.kexinit.copy(exchangeBuf, bp); // I_C + bp += len_init; + instate.kexinit = undefined; + + exchangeBuf.writeUInt32BE(len_sinit, bp, true); + bp += 4; + outstate.kexinit.copy(exchangeBuf, bp); // I_S + bp += len_sinit; + outstate.kexinit = undefined; + + exchangeBuf.writeUInt32BE(len_hostkey, bp, true); + bp += 4; + hostkey.copy(exchangeBuf, bp); // K_S + bp += len_hostkey; + + if (isGEX) { + KEXDH_GEX_REQ_PACKET.slice(1).copy(exchangeBuf, bp); // min, n, max + bp += (4 * 3); // Skip over bytes just copied + + exchangeBuf.writeUInt32BE(len_gex_prime, bp, true); + bp += 4; + if (gex_prime[idx_gex_prime] & 0x80) + exchangeBuf[bp++] = 0; + gex_prime.copy(exchangeBuf, bp, idx_gex_prime); // p + bp += len_gex_prime - (gex_prime[idx_gex_prime] & 0x80 ? 1 : 0); + + exchangeBuf.writeUInt32BE(len_gex_gen, bp, true); + bp += 4; + if (gex_gen[idx_gex_gen] & 0x80) + exchangeBuf[bp++] = 0; + gex_gen.copy(exchangeBuf, bp, idx_gex_gen); // g + bp += len_gex_gen - (gex_gen[idx_gex_gen] & 0x80 ? 1 : 0); + } + + exchangeBuf.writeUInt32BE(len_pubkey, bp, true); + bp += 4; + if (e[0] & 0x80) + exchangeBuf[bp++] = 0; + e.copy(exchangeBuf, bp); // e + bp += len_pubkey - (e[0] & 0x80 ? 1 : 0); + + exchangeBuf.writeUInt32BE(len_spubkey, bp, true); + bp += 4; + if (outstate.pubkey[idx_spubkey] & 0x80) + exchangeBuf[bp++] = 0; + outstate.pubkey.copy(exchangeBuf, bp, idx_spubkey); // f + bp += len_spubkey - (outstate.pubkey[idx_spubkey] & 0x80 ? 1 : 0); + + exchangeBuf.writeUInt32BE(len_secret, bp, true); + bp += 4; + if (secret[idx_secret] & 0x80) + exchangeBuf[bp++] = 0; + secret.copy(exchangeBuf, bp, idx_secret); // K + + outstate.exchangeHash = hash.update(exchangeBuf).digest(); // H + + if (outstate.sessionId === undefined) + outstate.sessionId = outstate.exchangeHash; + outstate.kexsecret = secret; + + var signAlgo; + switch (hostkeyAlgo) { + case 'ssh-rsa': + signAlgo = 'RSA-SHA1'; + break; + case 'ssh-dss': + signAlgo = 'DSA-SHA1'; + break; + case 'ecdsa-sha2-nistp256': + signAlgo = 'sha256'; + break; + case 'ecdsa-sha2-nistp384': + signAlgo = 'sha384'; + break; + case 'ecdsa-sha2-nistp521': + signAlgo = 'sha512'; + break; + } + var signer = crypto.createSign(signAlgo); + var signature; + signer.update(outstate.exchangeHash); + signature = trySign(signer, privateKey); + if (signature instanceof Error) { + signature.message = 'Error while signing data with host key (' + + hostkeyAlgo + '): ' + + signature.message; + signature.level = 'handshake'; + self.emit('error', signature); + self.disconnect(DISCONNECT_REASON.KEY_EXCHANGE_FAILED); + return false; + } + + if (signAlgo === 'DSA-SHA1') { + signature = DSASigBERToBare(signature); + } else if (signAlgo !== 'RSA-SHA1') { + // ECDSA + signature = ECDSASigASN1ToSSH(signature); + } + + /* + byte SSH_MSG_KEXDH_REPLY + string server public host key and certificates (K_S) + mpint f + string signature of H + */ + + var siglen = 4 + hostkeyAlgo.length + 4 + signature.length; + var buf = new Buffer(1 + + 4 + len_hostkey + + 4 + len_spubkey + + 4 + siglen); + + bp = 0; + buf[bp] = (!isGEX ? MESSAGE.KEXDH_REPLY : MESSAGE.KEXDH_GEX_REPLY); + ++bp; + + buf.writeUInt32BE(len_hostkey, bp, true); + bp += 4; + hostkey.copy(buf, bp); // K_S + bp += len_hostkey; + + buf.writeUInt32BE(len_spubkey, bp, true); + bp += 4; + if (outstate.pubkey[idx_spubkey] & 0x80) + buf[bp++] = 0; + outstate.pubkey.copy(buf, bp, idx_spubkey); // f + bp += len_spubkey - (outstate.pubkey[idx_spubkey] & 0x80 ? 1 : 0); + + buf.writeUInt32BE(siglen, bp, true); + bp += 4; + buf.writeUInt32BE(hostkeyAlgo.length, bp, true); + bp += 4; + buf.write(hostkeyAlgo, bp, hostkeyAlgo.length, 'ascii'); + bp += hostkeyAlgo.length; + buf.writeUInt32BE(signature.length, bp, true); + bp += 4; + signature.copy(buf, bp); + + state.incoming.expectedPacket = 'NEWKEYS'; + + if (isGEX) + self.debug('DEBUG: Outgoing: Writing KEXDH_GEX_REPLY'); + else if (state.kexdh !== 'group') + self.debug('DEBUG: Outgoing: Writing KEXECDH_REPLY'); + else + self.debug('DEBUG: Outgoing: Writing KEXDH_REPLY'); + send(self, buf, undefined, true); + + outstate.sentNEWKEYS = true; + self.debug('DEBUG: Outgoing: Writing NEWKEYS'); + return send(self, NEWKEYS_PACKET, undefined, true); +} + +function KEXDH_GEX_REQ(self) { // Client + self._state.incoming.expectedPacket = 'KEXDH_GEX_GROUP'; + + self.debug('DEBUG: Outgoing: Writing KEXDH_GEX_REQUEST'); + return send(self, KEXDH_GEX_REQ_PACKET, undefined, true); +} + +function send(self, payload, cb, bypass) { + var state = self._state; + + if (!state) + return false; + + var outstate = state.outgoing; + if (outstate.status === OUT_REKEYING && !bypass) { + if (typeof cb === 'function') + outstate.rekeyQueue.push([payload, cb]); + else + outstate.rekeyQueue.push(payload); + return false; + } else if (self._readableState.ended || self._writableState.ended) + return false; + + var compress = outstate.compress.instance; + if (compress) { + compress.write(payload); + compress.flush(Z_PARTIAL_FLUSH, function() { + if (self._readableState.ended || self._writableState.ended) + return; + send_(self, compress.read(), cb); + }); + return true; + } else + return send_(self, payload, cb); +} + +function send_(self, payload, cb) { + // TODO: Implement length checks + + var state = self._state; + var outstate = state.outgoing; + var encrypt = outstate.encrypt; + var hmac = outstate.hmac; + var pktLen; + var padLen; + var buf; + var mac; + var ret; + + pktLen = payload.length + 9; + + if (encrypt.instance !== false && encrypt.isGCM) { + var ptlen = 1 + payload.length + 4 /* Must have at least 4 bytes padding*/; + while ((ptlen % encrypt.size) !== 0) + ++ptlen; + padLen = ptlen - 1 - payload.length; + pktLen = 4 + ptlen; + } else { + pktLen += ((encrypt.size - 1) * pktLen) % encrypt.size; + padLen = pktLen - payload.length - 5; + } + + buf = new Buffer(pktLen); + + buf.writeUInt32BE(pktLen - 4, 0, true); + buf[4] = padLen; + payload.copy(buf, 5); + + var padBytes = crypto.randomBytes(padLen); + padBytes.copy(buf, 5 + payload.length); + + if (hmac.type !== false && hmac.key) { + mac = crypto.createHmac(SSH_TO_OPENSSL[hmac.type], hmac.key); + outstate.bufSeqno.writeUInt32BE(outstate.seqno, 0, true); + mac.update(outstate.bufSeqno); + mac.update(buf); + mac = mac.digest(); + if (mac.length > outstate.hmac.size) + mac = mac.slice(0, outstate.hmac.size); + } + + var nb = 0; + var encData; + + if (encrypt.instance !== false) { + if (encrypt.isGCM) { + var encrypter = crypto.createCipheriv(SSH_TO_OPENSSL[encrypt.type], + encrypt.key, + encrypt.iv); + encrypter.setAutoPadding(false); + + var lenbuf = buf.slice(0, 4); + + encrypter.setAAD(lenbuf); + self.push(lenbuf); + nb += lenbuf; + + encData = encrypter.update(buf.slice(4)); + self.push(encData); + nb += encData.length; + + var final = encrypter.final(); + if (final.length) { + self.push(final); + nb += final.length; + } + + var authTag = encrypter.getAuthTag(); + ret = self.push(authTag); + nb += authTag.length; + + iv_inc(encrypt.iv); + } else { + encData = encrypt.instance.update(buf); + self.push(encData); + nb += encData.length; + + ret = self.push(mac); + nb += mac.length; + } + } else { + ret = self.push(buf); + nb = buf.length; + } + + self.bytesSent += nb; + + if (++outstate.seqno > MAX_SEQNO) + outstate.seqno = 0; + + cb && cb(); + + return ret; +} + +function randBytes(n, cb) { + crypto.randomBytes(n, function retry(err, buf) { + if (err) + return crypto.randomBytes(n, retry); + cb && cb(buf); + }); +} + +function trySign(sig, key) { + try { + return sig.sign(key); + } catch (err) { + return err; + } +} + +function tryComputeSecret(dh, e) { + try { + return dh.computeSecret(e); + } catch (err) { + return err; + } +} + +module.exports = SSH2Stream; +module.exports._send = send; diff --git a/node_modules/ssh2-streams/lib/utils.js b/node_modules/ssh2-streams/lib/utils.js new file mode 100644 index 0000000..fdb945e --- /dev/null +++ b/node_modules/ssh2-streams/lib/utils.js @@ -0,0 +1,817 @@ +var crypto = require('crypto'); + +var Ber = require('asn1').Ber; +var BigInteger = require('./jsbn'); // only for converting PPK -> OpenSSL format + +var SSH_TO_OPENSSL = require('./constants').SSH_TO_OPENSSL; + +var RE_STREAM = /^arcfour/i; +var RE_KEY_LEN = /(.{64})/g; +// XXX the value of 2400 from dropbear is only for certain strings, not all +// strings. for example the list strings used during handshakes +var MAX_STRING_LEN = Infinity;//2400; // taken from dropbear +var PPK_IV = new Buffer([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + +module.exports = { + iv_inc: iv_inc, + isStreamCipher: isStreamCipher, + readInt: readInt, + readString: readString, + parseKey: require('./keyParser'), + genPublicKey: genPublicKey, + convertPPKPrivate: convertPPKPrivate, + verifyPPKMAC: verifyPPKMAC, + decryptKey: decryptKey, + DSASigBERToBare: DSASigBERToBare, + DSASigBareToBER: DSASigBareToBER, + ECDSASigASN1ToSSH: ECDSASigASN1ToSSH, + ECDSASigSSHToASN1: ECDSASigSSHToASN1, + RSAKeySSHToASN1: RSAKeySSHToASN1, + DSAKeySSHToASN1: DSAKeySSHToASN1, + ECDSAKeySSHToASN1: ECDSAKeySSHToASN1 +}; + +function iv_inc(iv) { + var n = 12; + var c = 0; + do { + --n; + c = iv[n]; + if (c === 255) + iv[n] = 0; + else { + iv[n] = ++c; + return; + } + } while (n > 4); +} + +function isStreamCipher(name) { + return RE_STREAM.test(name); +} + +function readInt(buffer, start, stream, cb) { + var bufferLen = buffer.length; + if (start < 0 || start >= bufferLen || (bufferLen - start) < 4) { + stream && stream._cleanup(cb); + return false; + } + + return buffer.readUInt32BE(start, true); +} + +function DSASigBERToBare(signature) { + if (signature.length <= 40) + return signature; + // This is a quick and dirty way to get from BER encoded r and s that + // OpenSSL gives us, to just the bare values back to back (40 bytes + // total) like OpenSSH (and possibly others) are expecting + var asnReader = new Ber.Reader(signature); + asnReader.readSequence(); + var r = asnReader.readString(Ber.Integer, true); + var s = asnReader.readString(Ber.Integer, true); + var rOffset = 0; + var sOffset = 0; + if (r.length < 20) { + var rNew = new Buffer(20); + r.copy(rNew, 1); + r = rNew; + r[0] = 0; + } + if (s.length < 20) { + var sNew = new Buffer(20); + s.copy(sNew, 1); + s = sNew; + s[0] = 0; + } + if (r.length > 20 && r[0] === 0x00) + rOffset = 1; + if (s.length > 20 && s[0] === 0x00) + sOffset = 1; + var newSig = new Buffer((r.length - rOffset) + (s.length - sOffset)); + r.copy(newSig, 0, rOffset); + s.copy(newSig, r.length - rOffset, sOffset); + return newSig; +} + +function DSASigBareToBER(signature) { + if (signature.length > 40) + return signature; + // Change bare signature r and s values to ASN.1 BER values for OpenSSL + var asnWriter = new Ber.Writer(); + asnWriter.startSequence(); + var r = signature.slice(0, 20); + var s = signature.slice(20); + if (r[0] & 0x80) { + var rNew = new Buffer(21); + rNew[0] = 0x00; + r.copy(rNew, 1); + r = rNew; + } else if (r[0] === 0x00 && !(r[1] & 0x80)) { + r = r.slice(1); + } + if (s[0] & 0x80) { + var sNew = new Buffer(21); + sNew[0] = 0x00; + s.copy(sNew, 1); + s = sNew; + } else if (s[0] === 0x00 && !(s[1] & 0x80)) { + s = s.slice(1); + } + asnWriter.writeBuffer(r, Ber.Integer); + asnWriter.writeBuffer(s, Ber.Integer); + asnWriter.endSequence(); + return asnWriter.buffer; +} + +function ECDSASigASN1ToSSH(signature) { + if (signature[0] === 0x00) + return signature; + // Convert SSH signature parameters to ASN.1 BER values for OpenSSL + var asnReader = new Ber.Reader(signature); + asnReader.readSequence(); + var r = asnReader.readString(Ber.Integer, true); + var s = asnReader.readString(Ber.Integer, true); + if (r === null || s === null) + throw new Error('Invalid signature'); + var newSig = new Buffer(4 + r.length + 4 + s.length); + newSig.writeUInt32BE(r.length, 0, true); + r.copy(newSig, 4); + newSig.writeUInt32BE(s.length, 4 + r.length, true); + s.copy(newSig, 4 + 4 + r.length); + return newSig; +} + +function ECDSASigSSHToASN1(signature, self, callback) { + // Convert SSH signature parameters to ASN.1 BER values for OpenSSL + var r = readString(signature, 0, self, callback); + if (r === false) + return false; + var s = readString(signature, signature._pos, self, callback); + if (s === false) + return false; + + var asnWriter = new Ber.Writer(); + asnWriter.startSequence(); + asnWriter.writeBuffer(r, Ber.Integer); + asnWriter.writeBuffer(s, Ber.Integer); + asnWriter.endSequence(); + return asnWriter.buffer; +} + +function RSAKeySSHToASN1(key, self, callback) { + // Convert SSH key parameters to ASN.1 BER values for OpenSSL + var e = readString(key, key._pos, self, callback); + if (e === false) + return false; + var n = readString(key, key._pos, self, callback); + if (n === false) + return false; + + var asnWriter = new Ber.Writer(); + asnWriter.startSequence(); + // algorithm + asnWriter.startSequence(); + asnWriter.writeOID('1.2.840.113549.1.1.1'); // rsaEncryption + // algorithm parameters (RSA has none) + asnWriter.writeNull(); + asnWriter.endSequence(); + + // subjectPublicKey + asnWriter.startSequence(Ber.BitString); + asnWriter.writeByte(0x00); + asnWriter.startSequence(); + asnWriter.writeBuffer(n, Ber.Integer); + asnWriter.writeBuffer(e, Ber.Integer); + asnWriter.endSequence(); + asnWriter.endSequence(); + asnWriter.endSequence(); + return asnWriter.buffer; +} + +function DSAKeySSHToASN1(key, self, callback) { + // Convert SSH key parameters to ASN.1 BER values for OpenSSL + var p = readString(key, key._pos, self, callback); + if (p === false) + return false; + var q = readString(key, key._pos, self, callback); + if (q === false) + return false; + var g = readString(key, key._pos, self, callback); + if (g === false) + return false; + var y = readString(key, key._pos, self, callback); + if (y === false) + return false; + + var asnWriter = new Ber.Writer(); + asnWriter.startSequence(); + // algorithm + asnWriter.startSequence(); + asnWriter.writeOID('1.2.840.10040.4.1'); // id-dsa + // algorithm parameters + asnWriter.startSequence(); + asnWriter.writeBuffer(p, Ber.Integer); + asnWriter.writeBuffer(q, Ber.Integer); + asnWriter.writeBuffer(g, Ber.Integer); + asnWriter.endSequence(); + asnWriter.endSequence(); + + // subjectPublicKey + asnWriter.startSequence(Ber.BitString); + asnWriter.writeByte(0x00); + asnWriter.writeBuffer(y, Ber.Integer); + asnWriter.endSequence(); + asnWriter.endSequence(); + return asnWriter.buffer; +} + +function ECDSAKeySSHToASN1(key, self, callback) { + // Convert SSH key parameters to ASN.1 BER values for OpenSSL + var curve = readString(key, key._pos, self, callback); + if (curve === false) + return false; + var Q = readString(key, key._pos, self, callback); + if (Q === false) + return false; + + var ecCurveOID; + switch (curve.toString('ascii')) { + case 'nistp256': + // prime256v1/secp256r1 + ecCurveOID = '1.2.840.10045.3.1.7'; + break; + case 'nistp384': + // secp384r1 + ecCurveOID = '1.3.132.0.34'; + break; + case 'nistp521': + // secp521r1 + ecCurveOID = '1.3.132.0.35'; + break; + default: + return false; + } + var asnWriter = new Ber.Writer(); + asnWriter.startSequence(); + // algorithm + asnWriter.startSequence(); + asnWriter.writeOID('1.2.840.10045.2.1'); // id-ecPublicKey + // algorithm parameters (namedCurve) + asnWriter.writeOID(ecCurveOID); + asnWriter.endSequence(); + + // subjectPublicKey + asnWriter.startSequence(Ber.BitString); + asnWriter.writeByte(0x00); + // XXX: hack to write a raw buffer without a tag -- yuck + asnWriter._ensure(Q.length); + Q.copy(asnWriter._buf, asnWriter._offset, 0, Q.length); + asnWriter._offset += Q.length; + // end hack + asnWriter.endSequence(); + asnWriter.endSequence(); + return asnWriter.buffer; +} + +function decryptKey(keyInfo, passphrase) { + if (keyInfo._decrypted || !keyInfo.encryption) + return; + + var keylen = 0; + var key; + var iv; + var dc; + + keyInfo.encryption = (SSH_TO_OPENSSL[keyInfo.encryption] + || keyInfo.encryption); + switch (keyInfo.encryption) { + case 'aes-256-cbc': + case 'aes-256-ctr': + keylen = 32; + break; + case 'des-ede3-cbc': + case 'des-ede3': + case 'aes-192-cbc': + case 'aes-192-ctr': + keylen = 24; + break; + case 'aes-128-cbc': + case 'aes-128-ctr': + case 'cast-cbc': + case 'bf-cbc': + keylen = 16; + break; + default: + throw new Error('Unsupported cipher for encrypted key: ' + + keyInfo.encryption); + } + + if (keyInfo.ppk) { + iv = PPK_IV; + + key = Buffer.concat([ + crypto.createHash('sha1') + .update('\x00\x00\x00\x00' + passphrase, 'utf8') + .digest(), + crypto.createHash('sha1') + .update('\x00\x00\x00\x01' + passphrase, 'utf8') + .digest() + ]); + key = key.slice(0, keylen); + } else { + iv = new Buffer(keyInfo.extra[0], 'hex'); + + key = crypto.createHash('md5') + .update(passphrase, 'utf8') + .update(iv.slice(0, 8)) + .digest(); + + while (keylen > key.length) { + key = Buffer.concat([ + key, + (crypto.createHash('md5') + .update(key) + .update(passphrase, 'utf8') + .update(iv) + .digest()).slice(0, 8) + ]); + } + if (key.length > keylen) + key = key.slice(0, keylen); + } + + dc = crypto.createDecipheriv(keyInfo.encryption, key, iv); + dc.setAutoPadding(false); + keyInfo.private = Buffer.concat([ dc.update(keyInfo.private), dc.final() ]); + + keyInfo._decrypted = true; + + if (keyInfo.privateOrig) { + // Update our original base64-encoded version of the private key + var orig = keyInfo.privateOrig.toString('utf8'); + var newOrig = /^(.+(?:\r\n|\n))/.exec(orig)[1]; + var b64key = keyInfo.private.toString('base64'); + + newOrig += b64key.match(/.{1,70}/g).join('\n'); + newOrig += /((?:\r\n|\n).+)$/.exec(orig)[1]; + + keyInfo.privateOrig = newOrig; + } else if (keyInfo.ppk) { + var valid = verifyPPKMAC(keyInfo, passphrase, keyInfo.private); + if (!valid) + throw new Error('PPK MAC mismatch'); + // Automatically convert private key data to OpenSSL format + // (including PEM) + convertPPKPrivate(keyInfo); + } + + // Fill in full key type + // TODO: make DRY, we do this also in keyParser + if (keyInfo.type !== 'ec') { + keyInfo.fulltype = 'ssh-' + keyInfo.type; + } else { + // ECDSA + var asnReader = new Ber.Reader(keyInfo.private); + asnReader.readSequence(); + asnReader.readInt(); + asnReader.readString(Ber.OctetString, true); + asnReader.readByte(); // Skip "complex" context type byte + var offset = asnReader.readLength(); // Skip context length + if (offset !== null) { + asnReader._offset = offset; + switch (asnReader.readOID()) { + case '1.2.840.10045.3.1.7': + // prime256v1/secp256r1 + keyInfo.fulltype = 'ecdsa-sha2-nistp256'; + break; + case '1.3.132.0.34': + // secp384r1 + keyInfo.fulltype = 'ecdsa-sha2-nistp384'; + break; + case '1.3.132.0.35': + // secp521r1 + keyInfo.fulltype = 'ecdsa-sha2-nistp521'; + break; + } + } + if (keyInfo.fulltype === undefined) + return new Error('Unsupported EC private key type'); + } +} + +function genPublicKey(keyInfo) { + var publicKey; + var i; + + // RSA + var n; + var e; + + // DSA + var p; + var q; + var g; + var y; + + // ECDSA + var d; + var Q; + var ecCurveOID; + var ecCurveName; + + if (keyInfo.private) { + // parsing private key in ASN.1 format in order to generate a public key + var privKey = keyInfo.private; + var asnReader = new Ber.Reader(privKey); + var errMsg; + + if (asnReader.readSequence() === null) { + errMsg = 'Malformed private key (expected sequence)'; + if (keyInfo._decrypted) + errMsg += '. Bad passphrase?'; + throw new Error(errMsg); + } + + // version (ignored) + if (asnReader.readInt() === null) { + errMsg = 'Malformed private key (expected version)'; + if (keyInfo._decrypted) + errMsg += '. Bad passphrase?'; + throw new Error(errMsg); + } + + if (keyInfo.type === 'rsa') { + // modulus (n) -- integer + n = asnReader.readString(Ber.Integer, true); + if (n === null) { + errMsg = 'Malformed private key (expected RSA n value)'; + if (keyInfo._decrypted) + errMsg += '. Bad passphrase?'; + throw new Error(errMsg); + } + + // public exponent (e) -- integer + e = asnReader.readString(Ber.Integer, true); + if (e === null) { + errMsg = 'Malformed private key (expected RSA e value)'; + if (keyInfo._decrypted) + errMsg += '. Bad passphrase?'; + throw new Error(errMsg); + } + + publicKey = new Buffer(4 + 7 // ssh-rsa + + 4 + n.length + + 4 + e.length); + + publicKey.writeUInt32BE(7, 0, true); + publicKey.write('ssh-rsa', 4, 7, 'ascii'); + + i = 4 + 7; + publicKey.writeUInt32BE(e.length, i, true); + e.copy(publicKey, i += 4); + + publicKey.writeUInt32BE(n.length, i += e.length, true); + n.copy(publicKey, i += 4); + } else if (keyInfo.type === 'dss') { // DSA + // prime (p) -- integer + p = asnReader.readString(Ber.Integer, true); + if (p === null) { + errMsg = 'Malformed private key (expected DSA p value)'; + if (keyInfo._decrypted) + errMsg += '. Bad passphrase?'; + throw new Error(errMsg); + } + + // group order (q) -- integer + q = asnReader.readString(Ber.Integer, true); + if (q === null) { + errMsg = 'Malformed private key (expected DSA q value)'; + if (keyInfo._decrypted) + errMsg += '. Bad passphrase?'; + throw new Error(errMsg); + } + + // group generator (g) -- integer + g = asnReader.readString(Ber.Integer, true); + if (g === null) { + errMsg = 'Malformed private key (expected DSA g value)'; + if (keyInfo._decrypted) + errMsg += '. Bad passphrase?'; + throw new Error(errMsg); + } + + // public key value (y) -- integer + y = asnReader.readString(Ber.Integer, true); + if (y === null) { + errMsg = 'Malformed private key (expected DSA y value)'; + if (keyInfo._decrypted) + errMsg += '. Bad passphrase?'; + throw new Error(errMsg); + } + + publicKey = new Buffer(4 + 7 // ssh-dss + + 4 + p.length + + 4 + q.length + + 4 + g.length + + 4 + y.length); + + publicKey.writeUInt32BE(7, 0, true); + publicKey.write('ssh-dss', 4, 7, 'ascii'); + + i = 4 + 7; + publicKey.writeUInt32BE(p.length, i, true); + p.copy(publicKey, i += 4); + + publicKey.writeUInt32BE(q.length, i += p.length, true); + q.copy(publicKey, i += 4); + + publicKey.writeUInt32BE(g.length, i += q.length, true); + g.copy(publicKey, i += 4); + + publicKey.writeUInt32BE(y.length, i += g.length, true); + y.copy(publicKey, i += 4); + } else { // ECDSA + d = asnReader.readString(Ber.OctetString, true); + if (d === null) + throw new Error('Malformed private key (expected ECDSA private key)'); + asnReader.readByte(); // Skip "complex" context type byte + var offset = asnReader.readLength(); // Skip context length + if (offset === null) + throw new Error('Malformed private key (expected ECDSA context value)'); + asnReader._offset = offset; + ecCurveOID = asnReader.readOID(); + if (ecCurveOID === null) + throw new Error('Malformed private key (expected ECDSA curve)'); + var tempECDH; + switch (ecCurveOID) { + case '1.2.840.10045.3.1.7': + // prime256v1/secp256r1 + keyInfo.curve = ecCurveName = 'nistp256'; + tempECDH = crypto.createECDH('prime256v1'); + break; + case '1.3.132.0.34': + // secp384r1 + keyInfo.curve = ecCurveName = 'nistp384'; + tempECDH = crypto.createECDH('secp384r1'); + break; + case '1.3.132.0.35': + // secp521r1 + keyInfo.curve = ecCurveName = 'nistp521'; + tempECDH = crypto.createECDH('secp521r1'); + break; + default: + throw new Error('Malformed private key (unsupported EC curve)'); + } + tempECDH.setPrivateKey(d); + Q = tempECDH.getPublicKey(); + + publicKey = new Buffer(4 + 19 // ecdsa-sha2- + + 4 + 8 // + + 4 + Q.length); + + publicKey.writeUInt32BE(19, 0, true); + publicKey.write('ecdsa-sha2-' + ecCurveName, 4, 19, 'ascii'); + + publicKey.writeUInt32BE(8, 23, true); + publicKey.write(ecCurveName, 27, 8, 'ascii'); + + publicKey.writeUInt32BE(Q.length, 35, true); + Q.copy(publicKey, 39); + } + } else if (keyInfo.public) { + publicKey = keyInfo.public; + if (keyInfo.type === 'ec') { + // TODO: support adding ecdsa-* prefix + ecCurveName = keyInfo.curve; + } else if (publicKey[0] !== 0 + // check for missing ssh-{dsa,rsa} prefix + || publicKey[1] !== 0 + || publicKey[2] !== 0 + || publicKey[3] !== 7 + || publicKey[4] !== 115 + || publicKey[5] !== 115 + || publicKey[6] !== 104 + || publicKey[7] !== 45 + || ((publicKey[8] !== 114 + || publicKey[9] !== 115 + || publicKey[10] !== 97) + && + ((publicKey[8] !== 100 + || publicKey[9] !== 115 + || publicKey[10] !== 115)))) { + var newPK = new Buffer(4 + 7 + publicKey.length); + publicKey.copy(newPK, 11); + newPK.writeUInt32BE(7, 0, true); + if (keyInfo.type === 'rsa') + newPK.write('ssh-rsa', 4, 7, 'ascii'); + else + newPK.write('ssh-dss', 4, 7, 'ascii'); + publicKey = newPK; + } + } else + throw new Error('Missing data generated by parseKey()'); + + // generate a public key format for use with OpenSSL + + i = 4 + 7; + + var fulltype; + var asn1KeyBuf; + if (keyInfo.type === 'rsa') { + fulltype = 'ssh-rsa'; + asn1KeyBuf = RSAKeySSHToASN1(publicKey.slice(4 + 7)); + } else if (keyInfo.type === 'dss') { + fulltype = 'ssh-dss'; + asn1KeyBuf = DSAKeySSHToASN1(publicKey.slice(4 + 7)); + } else { // ECDSA + fulltype = 'ecdsa-sha2-' + ecCurveName; + asn1KeyBuf = ECDSAKeySSHToASN1(publicKey.slice(4 + 19)); + } + + if (!asn1KeyBuf) + throw new Error('Invalid SSH-formatted public key'); + + var b64key = asn1KeyBuf.toString('base64').replace(RE_KEY_LEN, '$1\n'); + var fullkey = '-----BEGIN PUBLIC KEY-----\n' + + b64key + + (b64key[b64key.length - 1] === '\n' ? '' : '\n') + + '-----END PUBLIC KEY-----'; + + return { + type: keyInfo.type, + fulltype: fulltype, + curve: ecCurveName, + public: publicKey, + publicOrig: new Buffer(fullkey) + }; +} + +function verifyPPKMAC(keyInfo, passphrase, privateKey) { + if (keyInfo._macresult !== undefined) + return keyInfo._macresult; + else if (!keyInfo.ppk) + throw new Error("Key isn't a PPK"); + else if (!keyInfo.privateMAC) + throw new Error('Missing MAC'); + else if (!privateKey) + throw new Error('Missing raw private key data'); + else if (keyInfo.encryption && typeof passphrase !== 'string') + throw new Error('Missing passphrase for encrypted PPK'); + else if (keyInfo.encryption && !keyInfo._decrypted) + throw new Error('PPK must be decrypted before verifying MAC'); + + var mac = keyInfo.privateMAC; + var typelen = keyInfo.fulltype.length; + // encryption algorithm is converted at this point for use with OpenSSL, + // so we need to use the original value so that the MAC is calculated + // correctly + var enc = (keyInfo.encryption ? 'aes256-cbc' : 'none'); + var enclen = enc.length; + var commlen = Buffer.byteLength(keyInfo.comment); + var pub = keyInfo.public; + var publen = pub.length; + var privlen = privateKey.length; + var macdata = new Buffer(4 + typelen + + 4 + enclen + + 4 + commlen + + 4 + publen + + 4 + privlen); + var p = 0; + + macdata.writeUInt32BE(typelen, p, true); + macdata.write(keyInfo.fulltype, p += 4, typelen, 'ascii'); + macdata.writeUInt32BE(enclen, p += typelen, true); + macdata.write(enc, p += 4, enclen, 'ascii'); + macdata.writeUInt32BE(commlen, p += enclen, true); + macdata.write(keyInfo.comment, p += 4, commlen, 'utf8'); + macdata.writeUInt32BE(publen, p += commlen, true); + pub.copy(macdata, p += 4); + macdata.writeUInt32BE(privlen, p += publen, true); + privateKey.copy(macdata, p += 4); + + if (typeof passphrase !== 'string') + passphrase = ''; + + var mackey = crypto.createHash('sha1') + .update('putty-private-key-file-mac-key', 'ascii') + .update(passphrase, 'utf8') + .digest(); + + var calcMAC = crypto.createHmac('sha1', mackey) + .update(macdata) + .digest('hex'); + + return (keyInfo._macresult = (calcMAC === mac)); +} + +function convertPPKPrivate(keyInfo) { + if (!keyInfo.ppk || !keyInfo.public || !keyInfo.private) + throw new Error("Key isn't a PPK"); + else if (keyInfo._converted) + return false; + + var pub = keyInfo.public; + var priv = keyInfo.private; + var asnWriter = new Ber.Writer(); + var p; + var q; + + if (keyInfo.type === 'rsa') { + var e = readString(pub, 4 + 7); + var n = readString(pub, pub._pos); + var d = readString(priv, 0); + p = readString(priv, priv._pos); + q = readString(priv, priv._pos); + var iqmp = readString(priv, priv._pos); + var p1 = new BigInteger(p, 256); + var q1 = new BigInteger(q, 256); + var dmp1 = new BigInteger(d, 256); + var dmq1 = new BigInteger(d, 256); + + dmp1 = new Buffer(dmp1.mod(p1.subtract(BigInteger.ONE)).toByteArray()); + dmq1 = new Buffer(dmq1.mod(q1.subtract(BigInteger.ONE)).toByteArray()); + + asnWriter.startSequence(); + asnWriter.writeInt(0x00, Ber.Integer); + asnWriter.writeBuffer(n, Ber.Integer); + asnWriter.writeBuffer(e, Ber.Integer); + asnWriter.writeBuffer(d, Ber.Integer); + asnWriter.writeBuffer(p, Ber.Integer); + asnWriter.writeBuffer(q, Ber.Integer); + asnWriter.writeBuffer(dmp1, Ber.Integer); + asnWriter.writeBuffer(dmq1, Ber.Integer); + asnWriter.writeBuffer(iqmp, Ber.Integer); + asnWriter.endSequence(); + } else { + p = readString(pub, 4 + 7); + q = readString(pub, pub._pos); + var g = readString(pub, pub._pos); + var y = readString(pub, pub._pos); + var x = readString(priv, 0); + + asnWriter.startSequence(); + asnWriter.writeInt(0x00, Ber.Integer); + asnWriter.writeBuffer(p, Ber.Integer); + asnWriter.writeBuffer(q, Ber.Integer); + asnWriter.writeBuffer(g, Ber.Integer); + asnWriter.writeBuffer(y, Ber.Integer); + asnWriter.writeBuffer(x, Ber.Integer); + asnWriter.endSequence(); + } + + var b64key = asnWriter.buffer.toString('base64').replace(RE_KEY_LEN, '$1\n'); + var fullkey = '-----BEGIN ' + + (keyInfo.type === 'rsa' ? 'RSA' : 'DSA') + + ' PRIVATE KEY-----\n' + + b64key + + (b64key[b64key.length - 1] === '\n' ? '' : '\n') + + '-----END ' + + (keyInfo.type === 'rsa' ? 'RSA' : 'DSA') + + ' PRIVATE KEY-----'; + + keyInfo.private = asnWriter.buffer; + keyInfo.privateOrig = new Buffer(fullkey); + keyInfo._converted = true; + return true; +} + +function readString(buffer, start, encoding, stream, cb, maxLen) { + if (encoding && !Buffer.isBuffer(encoding) && typeof encoding !== 'string') { + if (typeof cb === 'number') + maxLen = cb; + cb = stream; + stream = encoding; + encoding = undefined; + } + + start || (start = 0); + var bufferLen = buffer.length; + var left = (bufferLen - start); + var len; + var end; + if (start < 0 || start >= bufferLen || left < 4) { + stream && stream._cleanup(cb); + return false; + } + + len = buffer.readUInt32BE(start, true); + if (len > (maxLen || MAX_STRING_LEN) || left < (4 + len)) { + stream && stream._cleanup(cb); + return false; + } + + start += 4; + end = start + len; + buffer._pos = end; + + if (encoding) { + if (Buffer.isBuffer(encoding)) { + buffer.copy(encoding, 0, start, end); + return encoding; + } else + return buffer.toString(encoding, start, end); + } else + return buffer.slice(start, end); +} + diff --git a/node_modules/ssh2-streams/package.json b/node_modules/ssh2-streams/package.json new file mode 100644 index 0000000..6792c19 --- /dev/null +++ b/node_modules/ssh2-streams/package.json @@ -0,0 +1,105 @@ +{ + "_args": [ + [ + { + "raw": "ssh2-streams@~0.1.15", + "scope": null, + "escapedName": "ssh2-streams", + "name": "ssh2-streams", + "rawSpec": "~0.1.15", + "spec": ">=0.1.15 <0.2.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/ssh2" + ] + ], + "_from": "ssh2-streams@>=0.1.15 <0.2.0", + "_id": "ssh2-streams@0.1.16", + "_inCache": true, + "_location": "/ssh2-streams", + "_nodeVersion": "6.9.1", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/ssh2-streams-0.1.16.tgz_1479405852590_0.7305608857423067" + }, + "_npmUser": { + "name": "mscdex", + "email": "mscdex@mscdex.net" + }, + "_npmVersion": "3.10.8", + "_phantomChildren": {}, + "_requested": { + "raw": "ssh2-streams@~0.1.15", + "scope": null, + "escapedName": "ssh2-streams", + "name": "ssh2-streams", + "rawSpec": "~0.1.15", + "spec": ">=0.1.15 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/ssh2" + ], + "_resolved": "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.1.16.tgz", + "_shasum": "ac9d3ce9e062f8cf08fcce5b3a274b6d5cecdc54", + "_shrinkwrap": null, + "_spec": "ssh2-streams@~0.1.15", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/ssh2", + "author": { + "name": "Brian White", + "email": "mscdex@mscdex.net" + }, + "bugs": { + "url": "https://github.com/mscdex/ssh2-streams/issues" + }, + "dependencies": { + "asn1": "~0.2.0", + "semver": "^5.1.0", + "streamsearch": "~0.1.2" + }, + "description": "SSH2 and SFTP(v3) client/server protocol streams for node.js", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "ac9d3ce9e062f8cf08fcce5b3a274b6d5cecdc54", + "tarball": "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.1.16.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "homepage": "https://github.com/mscdex/ssh2-streams#readme", + "keywords": [ + "ssh", + "ssh2", + "sftp", + "secure", + "protocol", + "streams", + "client", + "server" + ], + "licenses": [ + { + "type": "MIT", + "url": "http://github.com/mscdex/ssh2-streams/raw/master/LICENSE" + } + ], + "main": "./index", + "maintainers": [ + { + "name": "mscdex", + "email": "mscdex@mscdex.net" + } + ], + "name": "ssh2-streams", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/mscdex/ssh2-streams.git" + }, + "scripts": { + "test": "node test/test.js" + }, + "version": "0.1.16" +} diff --git a/node_modules/ssh2-streams/test/fixtures/encrypted-dsa.ppk b/node_modules/ssh2-streams/test/fixtures/encrypted-dsa.ppk new file mode 100644 index 0000000..915508b --- /dev/null +++ b/node_modules/ssh2-streams/test/fixtures/encrypted-dsa.ppk @@ -0,0 +1,17 @@ +PuTTY-User-Key-File-2: ssh-dss +Encryption: aes256-cbc +Comment: dsa-key-20141202 +Public-Lines: 10 +AAAAB3NzaC1kc3MAAACBAJn2I8YefRo3BsEeinQt8KQ4cEyArAs7Y/W733oRSYOI +zWF1Ju124ysKrmg2okv+05CYcjV3Yp4AzQeomYAlgmB/7xCEnWaEnxCwAxmrrJMm +PrkwNjHOIi7yM5QOE90IM/Q+IJA4EPBfSb+Xr8fYhrp53KNHVSnc2KkOqpo2FsIj +AAAAFQC4NlP50GqyUqq2B82Vh/w5j3TzwQAAAIAeSGom9LLNdzcwCHnGfxKNnEz3 +55KITADTxiIpBvnQW+eDHwQvIw6V2Oc73bKCu5ZirZmIMW5w6KjQVwkuQBoF9Koq +/2u6VeevtL9pD6TBzSLMVw5pV3PmE4/C/eLiaUxZLIHdbzpqPkAvAUBrXKkj0ijz +cNzCp1fuF8H0pvR8yQAAAIAmvV+kqWhUgDYwNNz1qDaoS8XdsOponutZ/0stRQ66 +mKAy8kNVNNQ6oUx1XFl1WUt4iyFY/2Rz2fZhLz5/TbZRK5ygo666WgnxB/Ud4GAx +/BPQTghOJJOL00vJk+8jVCGNDc942V6nFXznDMXwqxhRCW6dm+2lTh7ntrli8mCk +5g== +Private-Lines: 1 +BytvbK+jNyMjiVxCO5lcE4YbW7q293oC+LZjkZ8Ajlw= +Private-MAC: c3da536ea28851fc32d5d1ff01498c8fcebc1170 diff --git a/node_modules/ssh2-streams/test/fixtures/encrypted-rsa.ppk b/node_modules/ssh2-streams/test/fixtures/encrypted-rsa.ppk new file mode 100644 index 0000000..6f2f7f7 --- /dev/null +++ b/node_modules/ssh2-streams/test/fixtures/encrypted-rsa.ppk @@ -0,0 +1,18 @@ +PuTTY-User-Key-File-2: ssh-rsa +Encryption: aes256-cbc +Comment: rsa-key-20141119 +Public-Lines: 4 +AAAAB3NzaC1yc2EAAAABJQAAAIBrBWETAVAyJmuNG53jwTNDlbIcH5lrEvcx6lx5 +bM6EKg0XmOIH96VqUjS7eRRTTD9lpBA8hYhkrOjOx93/JWB/pcVN8/B3DYHshT9O +BW1DCkrNwut2pbJ2oZOBirhhAr+xqWFr3551FqbzaCIXpOKubr4EcIwCipBl6PxL +USfHgw== +Private-Lines: 8 +8O3NrBePR4+4RHHys8wrRKCmgx3Gsdz1cKoRJJDgnnrQxuAxBTVUlVTC2vzSOXrP +jlKdRP9DbtrL5YF8g9HkMPpzzTdgpiEAGikpIc+L0sJhN+S9VvMoXRRKqyuB7o1C +xZhAeRaZ68izdUUbFd7ajUwBNpGoFppOznGXyf/3/Ao9FfoTKReZzeBd/e2/JFhc +nsYkSbtWfKQBVXF1Fhr10UwRWSMaVJSDkcSuk8ghICoKBBCgRBnZFap0SR77oIJh +DKgmNFktoKzEqh111vYPhQyEEyGNxpD0aEPaGUJEjPEd3C5a46n7mIiqrNX7QJoo +xxZtkueGdXWaoe5mBf1tFc+nCA1l72nUlghJZooQhnO9NPpieu6NNZ8X+tFQ1Rq/ +xvOZHzpDOOeOgWdV7oAmRDbDjYPh0H67z2OKCFaP0Z9kgmnwqV2IJvTDrexj1VwY +6kFaPldnK+ohXl37oVIlWA== +Private-MAC: 9d09a15a122e48955682ba969d33c75ba8e4be2c diff --git a/node_modules/ssh2-streams/test/fixtures/id_rsa b/node_modules/ssh2-streams/test/fixtures/id_rsa new file mode 100644 index 0000000..c7c09e1 --- /dev/null +++ b/node_modules/ssh2-streams/test/fixtures/id_rsa @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEAysX9gGx5CsLW3xHqOgnrbfCuXy1Y0OFpZBxWs6FNHxtqpxRD +Ii8vnWQw9Ltul5NhBb1QrS/3XlODu5rv8VWZy+ciXDaeaVYvzCR3fHmQyDXA+WLR +x8kkR4ZxHTQREj1yifGyHdZTMsMbSaW9Eh2+sgWIjZaBkLjF2NDT52HX0y+zr2WL +TYVCcYf9ugCJIfwXN4/SpR+cV3MSak+4HfFDRo7EwFbYL8QRpNZLVVas5SUpN3CR +e6u26zPNgcqSRmC81lA/e2t7qG1qvjFy9RgJpUJJsZan5yMYAob9p83Fo61ajLX1 +DeqpZPauEfe9e/4bkjVbU8gW/cgb9Ct6v+59fQIDAQABAoIBAQCUH6GZKKQbKk1Q +UoPptclXXFPkjvmsTJ1yVgk32wK9UIfOWUzZMeL0dHYWsLyO2Ugsqyi9+qYXL6ax +avMQNlnMy6Eb/4IkrKLp21G1ihArUKkRBBD+gn6QCTOkA57c1ipPflGA3kmUcVYD +rKC7FSNyY/xmgaVQFMniIlpJUf4Y9BjIKC2FSTGxtKx2AI7eBDjmiZ7Mkcinaf62 +5jl0AfV0/PgBb7AqhPWcmJp+/jWyZ3IrlPvMspEg6PfLnNzACKrh/Qorkhf3cLcn +aFJmnyRn4Zhx+scqoWq1NcYOfNyU+eAEofTu8TwvGVh0nx9C2vxwPftjDQlfh0kf +wGscN72BAoGBAOZs4u5ObnFf4pNbGfjhLhSf2vXATb9TYjr8vPc4xbviukYGPaNR +tP5d9oXHecFP37IeV6I0SmMmd0Sth56/RfRFD8Rirq3MjjKWvwwbJ1sd34n9cqN3 +goSWERfqPOzVMjxEPqq0wm/7Y61EU5Gt1ou8MOOS+lPx3LmpapSjSNutAoGBAOFH +bLZQUpLaUf7ijCU/yykRdpzBpwDDEgRqf7RLqS8p+tzI9z39KfNSxrVEqhWe7uuZ +3dl8EjrXhBK8FoCDAD6yrx35aUUeUJHZp/kFoXBdlHpGk8VvveTJMSqPS6KxKglB +JqINECpwHzasQSun2vhLsH6ikUUqnB8qkJYMNGMRAoGBAJ5wio1/4pMUclAOWUp3 +U18dF8rZItyGskmLFUgMgnIRkTGrAuD0wrYQ1/zez0pr6I2qLWm7+NY6UdIoW9N9 +A9XVUuUfUarxt2jznIPve908KkPQwO3DtDwEj9ZY2vGiGruz1T89sWCcg8pU6/2E +gbxtd1RT8MqdyL7kzgNMT0G1AoGBAMc1otOBKdPEjVeIPAfAZsXVNH8f268X0Lno +9y6W7W/Qfo54g/HkChGqNB8dLg5accoTURO93Fz+MUNj4b4YmcHXvnUSFV3Slcqz +nw7dRMoZZm/OM2QXEOPcacbJ2kduxM5UN3Z7eL0eUuvE3QhesYp5XARPe4ifSllh +CWQ2PKkRAoGBAMFANW/IxEH6H60yfJbY9t/0ggu4DoVI62rmv43n2dYsdNeaF1Fl +SbGoK16+6ERyjyJtqe0642LpgenrEcpJbXxr1qtG6gGRCJIcZ8gJDiVj4XW1d1cZ +eCNZLVlVOrBNRkKmXDD5Sd10m52tlBMfarvskgbJVvkRO6pSz3o8Q0B1 +-----END RSA PRIVATE KEY----- diff --git a/node_modules/ssh2-streams/test/fixtures/id_rsa_enc b/node_modules/ssh2-streams/test/fixtures/id_rsa_enc new file mode 100644 index 0000000..ec0646c --- /dev/null +++ b/node_modules/ssh2-streams/test/fixtures/id_rsa_enc @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,3E36D2FEB814842942EC58DA9722DB75 + +MBCl5tVBiTjZywjXSMPNnVcBzuAhZzLsvb/pPofnVNnx96CqBMAzaKxGu6Ls9UBu +ejGGOik+8EJHV7p7dj6GAf5srgBnFXVYQy69eoL4xl1IuKoSKOXicS70/QXuApzY +tBdwnqMz1y1tuWZ0q4iOZYQHqvNTvhH4s/rfm8/As7GwPi4NQ4FipsbOifKVIlJN +0+XQAZLBjD6D2BFbVBas2RyI/zT5NyFtFxEPlQwWjuajnDrdVFf59mkzHzQc8Jo1 +qjCv6bDHTW9EeoZeloqpAaYegmOYGynb8HQzmbEBoarXsOkwtaI38jXT3WOljaVJ +xuWV7xl181CsV4dgbyd948YKcHg3riRQiQwXXlKe4MTGwcQ3sybR4oFLzFIa6Ct2 +qbsyqvc+3tiBhOZtiAXgDdbzvXR+60aSTjduVp+52lF/m4l658Sleyx2hxQ3LEcc +lbuG27WIbLEATeqV9gaJ1jDtEyEtGNALAdIZF6YdND5tiTSqHd0n3yUMbZVdiQ5i +s5lSfWD38c3Is4hOdZlG9nMFoAGe7wnFmV+N5Cv3vnlFPFogoO4eVZS5S+ReAmas +syOelwKvVNNy0FzCoQ3URZWLQTKsZ7Wkl1ve9jJ5ZPox0p09A0gcykIB5oya9/OL +oTKDhoenoh0p3ttyQ7WbkUc9VwHNn+rX7N3v/Ui+NF8mnCfD/1UOzBhRY0LjDCfO +qT70wd63c4cSr0HCTDNrGtShztJD9gdzwIH6q/eNDjFk1S8KOrV/K6wQwWzULs+c +Ld/7xkELz+d60Ll5dVUHcSxOhYwBVY+GGC5ybOmSqr5+t1MDfLN0Q4d3x0X6LU2q +sL94x93XFY342x5NpjOusKISCaCx9eBXxCpi132IAfmB7kDZXpbe02aed0bNChUP +IM6eXFYVfPb5YZ3oXlWJ+e/E01dGPK2rHnAzOLH2DSmDZ7MWZW5hkRKQ4zU6/ECo +0K7uGLAdpCoC8FKWcE2Gm7fol5fmHes06SNC1wLyVHtv4g7kFfnfmNIVVy3lSP1f +WoHRL52lNOCR+E1N03djvyKoK46cKiJ9TcBrJXcMHSSjPvqLafS/AUK+FYjxlqyM +qXgATtt/n0h+VxjPm2+xZNVHC5fD5GHhoo3PhmapLpLNyDlhzJTy/iFtrmX6uht1 +4XDYmzzQyoRu6+1DQ7HPpwXZf84+QFGGfb/LTiLUF+pgCHOt41HdHEaU6eIHGEk0 +wfTfWG2pP/2wDUtX8KVAnikfIaa5KrC/ZuDV5pfp0Tk+Rjt2iv9+YuB7fPrvKF3Z +B7zgMuBG8FQZMFHvWsaDHE/vo8fivgeM0zVL0shigLuwL+p6EeanRdm5bRavF8M8 +XDtOjZt/id4UMQDuobawUVadTZhtGfFNfO9Wt16EAa6jhRBJ1A+FRGqFbJXV36ZV +zzx7edCzyCd0rcsZoi6Kz4NeDxm1lcGspBBhstUT5cbgQo91wAZCU1hpj/qsqygr +KK4NcNpDjYFc1azb/zRGe+zx1WzWhKAZR6HfMEoJwzyzTcwRmApbTEYqv+oYxC0+ +f/HNQaCH/UGDy4QEvMVaJRnjFv7oW6GpS7ob6POvi2esgYglwNJR1hN86W7kfOrF +-----END RSA PRIVATE KEY----- diff --git a/node_modules/ssh2-streams/test/fixtures/ssh_host_rsa_key b/node_modules/ssh2-streams/test/fixtures/ssh_host_rsa_key new file mode 100644 index 0000000..9c2cc6f --- /dev/null +++ b/node_modules/ssh2-streams/test/fixtures/ssh_host_rsa_key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQC57UB/5H0M+t+mopksrltCCIXghryzofJjau+8tuMT9CG6ta3S +O9aKApJUUG/xtc88giVhB7HFABX/oob+jrkSthR8s/whULC8E+GhvOBjHydRUZIs +aPYOMBb42HcbOsgq3li/hwOcDk0vY00hZDKCum9BgvRAb7dPEkw2dmiCQQIDAQAB +AoGAMG+HOwoaLbR5aR64yrQNYBF6Vvii1iUdURr9o2r9kygpVUuZIcim5kMvPbnK +v+w+NaQt+q4XeJvCH1uG0W/69FwnphfaOVmCCUtsoJ6sU3fWr9x59MtKL2Llh8xR +50lz6R+eDXoYRDq245hG9BFn/bu0vtqQqx06mlZJcjaRocECQQDjdYFmr+DSww3x +VNx0G0DUkaQZZ+iqZiT3Zund2pcBB4aLiewOrqj0GFct4+YNzgxIXPejmS0eSokN +N2lC3NxZAkEA0UGjN5TG5/LEK3zcYtx2kpXryenrYORo1n2L/WPMZ0mjLQyd4LJr +ibfgVUfwX/kV3vgGYLwjpgcaTiMsecv4KQJAYMmMgZSPdz+WvD1e/WznXkyG5mSn +xXJngnrhQw0TulVodBIBR5IcxJli510VdIRcB6K/oXa5ky0mOmB8wv3WKQJBAKEF +PxE//KbzWhyUogm4180IbD4dMDCI0ltqlFRRfTJlqZi6wqnq4XFB+u/kwYU4aKoA +dPfvDgduI8HIsyqt17ECQDI/HC8PiYsDIOyVpQuQdIAsbGmoavK7X1MVEWR2nj9t +7BbUVFSnVKynL4TWIJZ6xP8WQwkDBQc5WjognHDaUTQ= +-----END RSA PRIVATE KEY----- diff --git a/node_modules/ssh2-streams/test/test-durability-ssh.js b/node_modules/ssh2-streams/test/test-durability-ssh.js new file mode 100644 index 0000000..853656b --- /dev/null +++ b/node_modules/ssh2-streams/test/test-durability-ssh.js @@ -0,0 +1,169 @@ +var SSH2Stream = require('../lib/ssh'); + +var fs = require('fs'); +var path = require('path'); +var inspect = require('util').inspect; +var inherits = require('util').inherits; +var TransformStream = require('stream').Transform; +var assert = require('assert'); + +var t = -1; +var group = path.basename(__filename, '.js') + '/'; +var fixturesdir = path.join(__dirname, 'fixtures'); + +var HOST_KEY_RSA = fs.readFileSync(path.join(fixturesdir, 'ssh_host_rsa_key')); +var SERVER_CONFIG = { + server: true, + hostKeys: { 'ssh-rsa': HOST_KEY_RSA } +}; + +function SimpleStream() { + TransformStream.call(this); + this.buffer = ''; +} +inherits(SimpleStream, TransformStream); +SimpleStream.prototype._transform = function(chunk, encoding, cb) { + this.buffer += chunk.toString('binary'); + cb(); +}; + +var tests = [ + { run: function() { + var what = this.what; + var serverError = false; + var server = new SSH2Stream(SERVER_CONFIG); + var client = new SimpleStream(); + + client.pipe(server).pipe(client); + + server.on('error', function(err) { + serverError = err; + assert(err.message === 'Protocol version not supported', + makeMsg(what, 'Wrong error message')); + }).on('end', function() { + assert(client.buffer === server.config.ident + '\r\n', + makeMsg(what, 'Wrong server ident: ' + inspect(client.buffer))); + assert(serverError, makeMsg(what, 'Expected server error')); + next(); + }); + + client.push('SSH-1.0-aaa\r\n'); + }, + what: 'Incompatible client SSH protocol version' + }, + { run: function() { + var what = this.what; + var serverError = false; + var server = new SSH2Stream(SERVER_CONFIG); + var client = new SimpleStream(); + + client.pipe(server).pipe(client); + + server.on('error', function(err) { + serverError = err; + assert(err.message === 'Bad identification start', + makeMsg(what, 'Wrong error message')); + }).on('end', function() { + assert(client.buffer === server.config.ident + '\r\n', + makeMsg(what, 'Wrong server ident: ' + inspect(client.buffer))); + assert(serverError, makeMsg(what, 'Expected server error')); + next(); + }); + client.push('LOL-2.0-asdf\r\n'); + }, + what: 'Malformed client protocol identification' + }, + { run: function() { + var what = this.what; + var serverError = false; + var server = new SSH2Stream(SERVER_CONFIG); + var client = new SimpleStream(); + + client.pipe(server).pipe(client); + + server.on('error', function(err) { + serverError = err; + assert(err.message === 'Max identification string size exceeded', + makeMsg(what, 'Wrong error message')); + }).on('end', function() { + assert(client.buffer === server.config.ident + '\r\n', + makeMsg(what, 'Wrong server ident: ' + inspect(client.buffer))); + assert(serverError, makeMsg(what, 'Expected server error')); + next(); + }); + var ident = 'SSH-2.0-'; + for (var i = 0; i < 30; ++i) + ident += 'foobarbaz'; + ident += '\r\n'; + client.push(ident); + }, + what: 'SSH client protocol identification too long (> 255 characters)' + }, + { run: function() { + var what = this.what; + var serverError = false; + var server = new SSH2Stream(SERVER_CONFIG); + var client = new SimpleStream(); + + client.pipe(server).pipe(client); + + server.on('error', function(err) { + serverError = err; + assert(err.message === 'Bad packet length', + makeMsg(what, 'Wrong error message')); + }).on('end', function() { + assert(client.buffer.length, makeMsg(what, 'Expected server data')); + assert(serverError, makeMsg(what, 'Expected server error')); + next(); + }); + client.push('SSH-2.0-asdf\r\n'); + // 500,000 byte packet_length + client.push(new Buffer([0x00, 0x07, 0xA1, 0x20, 0x00, 0x00, 0x00, 0x00])); + }, + what: 'Bad packet length (max)' + }, + { run: function() { + var what = this.what; + var serverError = false; + var server = new SSH2Stream(SERVER_CONFIG); + var client = new SimpleStream(); + + client.pipe(server).pipe(client); + + server.on('error', function(err) { + serverError = err; + assert(err.message === 'Bad packet length', + makeMsg(what, 'Wrong error message')); + }).on('end', function() { + assert(client.buffer.length, makeMsg(what, 'Expected server data')); + assert(serverError, makeMsg(what, 'Expected server error')); + next(); + }); + client.push('SSH-2.0-asdf\r\n'); + client.push(new Buffer([0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00])); + }, + what: 'Bad packet length (min)' + }, +]; + +function next() { + if (Array.isArray(process._events.exit)) + process._events.exit = process._events.exit[1]; + if (++t === tests.length) + return; + + var v = tests[t]; + v.run.call(v); +} + +function makeMsg(what, msg) { + return '[' + group + what + ']: ' + msg; +} + +process.once('exit', function() { + assert(t === tests.length, + makeMsg('_exit', + 'Only finished ' + t + '/' + tests.length + ' tests')); +}); + +next(); diff --git a/node_modules/ssh2-streams/test/test-kexdh.js b/node_modules/ssh2-streams/test/test-kexdh.js new file mode 100644 index 0000000..5544168 --- /dev/null +++ b/node_modules/ssh2-streams/test/test-kexdh.js @@ -0,0 +1,66 @@ +var SSH2Stream = require('../lib/ssh'); +var parseKey = require('../lib/utils').parseKey; +var genPubKey = require('../lib/utils').genPublicKey; +var MESSAGE = require('../lib/constants').MESSAGE; + +var assert = require('assert'); +var fs = require('fs'); + +var SERVER_KEY = fs.readFileSync(__dirname + '/fixtures/ssh_host_rsa_key'); +var SERVER_KEY_PRV = parseKey(SERVER_KEY); +var SERVER_KEY_PUB = genPubKey(SERVER_KEY_PRV); + +var server = new SSH2Stream({ + server: true, + hostKeys: { + 'ssh-rsa': { + privateKey: SERVER_KEY_PRV, + publicKey: SERVER_KEY_PUB, + } + } +}); +var client = new SSH2Stream(); +var cliError; +var srvError; + +server.on('error', function(err) { + assert(err); + assert(/unexpected/.test(err.message)); + assert(!srvError); + srvError = err; +}); + +// Removed 'KEXDH_REPLY' listeners as it causes client to send 'NEWKEYS' which +// changes server's state. +client.removeAllListeners('KEXDH_REPLY'); +// Removed 'NEWKEYS' listeners as server sends 'NEWKEYS' after receiving +// 'KEXDH_INIT' which causes errors on client if 'NEWKEYS' is processed +// without processing 'KEXDH_REPLY' +client.removeAllListeners('NEWKEYS'); +// Added 'KEXDH_REPLY' which violates protocol and re-sends 'KEXDH_INIT' +// packet +client.on('KEXDH_REPLY', function(info) { + var state = client._state; + var outstate = state.outgoing; + var buf = new Buffer(1 + 4 + outstate.pubkey.length); + buf[0] = MESSAGE.KEXDH_INIT; + buf.writeUInt32BE(outstate.pubkey.length, 1, true); + outstate.pubkey.copy(buf, 5); + SSH2Stream._send(client, buf, undefined, true); +}); +client.on('error', function(err) { + assert(!cliError); + assert(err); + assert.equal( + err.message, + 'PROTOCOL_ERROR', + 'Expected Error: PROTOCOL_ERROR Got Error: ' + err.message + ); + cliError = err; +}); +client.pipe(server).pipe(client); + +process.on('exit', function() { + assert(cliError, 'Expected client error'); + //assert(srvError, 'Expected server error'); +}); diff --git a/node_modules/ssh2-streams/test/test-keyparser.js b/node_modules/ssh2-streams/test/test-keyparser.js new file mode 100644 index 0000000..d634dc3 --- /dev/null +++ b/node_modules/ssh2-streams/test/test-keyparser.js @@ -0,0 +1,2301 @@ +var parser = require('../lib/keyParser'); + +var path = require('path'); +var assert = require('assert'); +var inspect = require('util').inspect; + +var group = path.basename(__filename, '.js') + '/'; + +[ + { source: [ + '-----BEGIN RSA PRIVATE KEY-----', + 'MIIBywIBAAJhANXy0sLFQFgcY6sfyqlrBBNAcow7MWjQS0flUEj8HmrdTX+denZ5', + 'sArVEBWIoIcCWt0DWGz/mZDS2XPqyy9IbEnhwtZ3bpHmw11J1k61odAwy5sE3P4S', + 'kS/Svl7Wxjcr5wIDAQABAmEAx50pG2QiZpMGQvEEixE32iZ1OXU44kwFEO1Y/N+O', + 'GbKkzf5F9igPIewsd4rkC1MbcVPYTN6a7WlFh2dP1kC5wdPAdVjBf1p7Ii4t4HZt', + 'OokidduJzCmC+TulDCNLFmlBAjEA/6SUxcxRXJV7GHBmu+FIbnR6/drHaBvMkNKZ', + '/tGIq1KfrHIWrhGl2vYqot6hRgoXAjEA1j9VAyuDK2NhQG/WMmf8WV+OMeJQ7vpn', + '3KmtPc/CsWfPNYeQagfwlj0SLGwz8J6xAjEA4qIRkllUN/P9MOlU6nMKN4HkF3EB', + 'HvamIC3Uf+dadifFjqeGG8NhegCKQ+GCsAj5AjAecs3AL5Tqu6r8n2hPrZudkAkD', + 'aeiarhfIsoyedkJzOA+oyeVqTEqS74b/rTkMf2ECMBrts0oFmVJYo77riKQBYbR7', + '/8feisYSPHSg7hwaoXSwU+jU4g39w7rgvO+WkGuzyQ==', + '-----END RSA PRIVATE KEY-----' + ].join('\n'), + expected: { + fulltype: 'ssh-rsa', + type: 'rsa', + curve: undefined, + extra: undefined, + comment: undefined, + encryption: undefined, + private: new Buffer([ + 0x30, 0x82, 0x01, 0xcb, 0x02, 0x01, 0x00, 0x02, 0x61, 0x00, 0xd5, 0xf2, + 0xd2, 0xc2, 0xc5, 0x40, 0x58, 0x1c, 0x63, 0xab, 0x1f, 0xca, 0xa9, 0x6b, + 0x04, 0x13, 0x40, 0x72, 0x8c, 0x3b, 0x31, 0x68, 0xd0, 0x4b, 0x47, 0xe5, + 0x50, 0x48, 0xfc, 0x1e, 0x6a, 0xdd, 0x4d, 0x7f, 0x9d, 0x7a, 0x76, 0x79, + 0xb0, 0x0a, 0xd5, 0x10, 0x15, 0x88, 0xa0, 0x87, 0x02, 0x5a, 0xdd, 0x03, + 0x58, 0x6c, 0xff, 0x99, 0x90, 0xd2, 0xd9, 0x73, 0xea, 0xcb, 0x2f, 0x48, + 0x6c, 0x49, 0xe1, 0xc2, 0xd6, 0x77, 0x6e, 0x91, 0xe6, 0xc3, 0x5d, 0x49, + 0xd6, 0x4e, 0xb5, 0xa1, 0xd0, 0x30, 0xcb, 0x9b, 0x04, 0xdc, 0xfe, 0x12, + 0x91, 0x2f, 0xd2, 0xbe, 0x5e, 0xd6, 0xc6, 0x37, 0x2b, 0xe7, 0x02, 0x03, + 0x01, 0x00, 0x01, 0x02, 0x61, 0x00, 0xc7, 0x9d, 0x29, 0x1b, 0x64, 0x22, + 0x66, 0x93, 0x06, 0x42, 0xf1, 0x04, 0x8b, 0x11, 0x37, 0xda, 0x26, 0x75, + 0x39, 0x75, 0x38, 0xe2, 0x4c, 0x05, 0x10, 0xed, 0x58, 0xfc, 0xdf, 0x8e, + 0x19, 0xb2, 0xa4, 0xcd, 0xfe, 0x45, 0xf6, 0x28, 0x0f, 0x21, 0xec, 0x2c, + 0x77, 0x8a, 0xe4, 0x0b, 0x53, 0x1b, 0x71, 0x53, 0xd8, 0x4c, 0xde, 0x9a, + 0xed, 0x69, 0x45, 0x87, 0x67, 0x4f, 0xd6, 0x40, 0xb9, 0xc1, 0xd3, 0xc0, + 0x75, 0x58, 0xc1, 0x7f, 0x5a, 0x7b, 0x22, 0x2e, 0x2d, 0xe0, 0x76, 0x6d, + 0x3a, 0x89, 0x22, 0x75, 0xdb, 0x89, 0xcc, 0x29, 0x82, 0xf9, 0x3b, 0xa5, + 0x0c, 0x23, 0x4b, 0x16, 0x69, 0x41, 0x02, 0x31, 0x00, 0xff, 0xa4, 0x94, + 0xc5, 0xcc, 0x51, 0x5c, 0x95, 0x7b, 0x18, 0x70, 0x66, 0xbb, 0xe1, 0x48, + 0x6e, 0x74, 0x7a, 0xfd, 0xda, 0xc7, 0x68, 0x1b, 0xcc, 0x90, 0xd2, 0x99, + 0xfe, 0xd1, 0x88, 0xab, 0x52, 0x9f, 0xac, 0x72, 0x16, 0xae, 0x11, 0xa5, + 0xda, 0xf6, 0x2a, 0xa2, 0xde, 0xa1, 0x46, 0x0a, 0x17, 0x02, 0x31, 0x00, + 0xd6, 0x3f, 0x55, 0x03, 0x2b, 0x83, 0x2b, 0x63, 0x61, 0x40, 0x6f, 0xd6, + 0x32, 0x67, 0xfc, 0x59, 0x5f, 0x8e, 0x31, 0xe2, 0x50, 0xee, 0xfa, 0x67, + 0xdc, 0xa9, 0xad, 0x3d, 0xcf, 0xc2, 0xb1, 0x67, 0xcf, 0x35, 0x87, 0x90, + 0x6a, 0x07, 0xf0, 0x96, 0x3d, 0x12, 0x2c, 0x6c, 0x33, 0xf0, 0x9e, 0xb1, + 0x02, 0x31, 0x00, 0xe2, 0xa2, 0x11, 0x92, 0x59, 0x54, 0x37, 0xf3, 0xfd, + 0x30, 0xe9, 0x54, 0xea, 0x73, 0x0a, 0x37, 0x81, 0xe4, 0x17, 0x71, 0x01, + 0x1e, 0xf6, 0xa6, 0x20, 0x2d, 0xd4, 0x7f, 0xe7, 0x5a, 0x76, 0x27, 0xc5, + 0x8e, 0xa7, 0x86, 0x1b, 0xc3, 0x61, 0x7a, 0x00, 0x8a, 0x43, 0xe1, 0x82, + 0xb0, 0x08, 0xf9, 0x02, 0x30, 0x1e, 0x72, 0xcd, 0xc0, 0x2f, 0x94, 0xea, + 0xbb, 0xaa, 0xfc, 0x9f, 0x68, 0x4f, 0xad, 0x9b, 0x9d, 0x90, 0x09, 0x03, + 0x69, 0xe8, 0x9a, 0xae, 0x17, 0xc8, 0xb2, 0x8c, 0x9e, 0x76, 0x42, 0x73, + 0x38, 0x0f, 0xa8, 0xc9, 0xe5, 0x6a, 0x4c, 0x4a, 0x92, 0xef, 0x86, 0xff, + 0xad, 0x39, 0x0c, 0x7f, 0x61, 0x02, 0x30, 0x1a, 0xed, 0xb3, 0x4a, 0x05, + 0x99, 0x52, 0x58, 0xa3, 0xbe, 0xeb, 0x88, 0xa4, 0x01, 0x61, 0xb4, 0x7b, + 0xff, 0xc7, 0xde, 0x8a, 0xc6, 0x12, 0x3c, 0x74, 0xa0, 0xee, 0x1c, 0x1a, + 0xa1, 0x74, 0xb0, 0x53, 0xe8, 0xd4, 0xe2, 0x0d, 0xfd, 0xc3, 0xba, 0xe0, + 0xbc, 0xef, 0x96, 0x90, 0x6b, 0xb3, 0xc9, + ]), + privateOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x52, + 0x53, 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, + 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x42, + 0x79, 0x77, 0x49, 0x42, 0x41, 0x41, 0x4a, 0x68, 0x41, 0x4e, 0x58, 0x79, + 0x30, 0x73, 0x4c, 0x46, 0x51, 0x46, 0x67, 0x63, 0x59, 0x36, 0x73, 0x66, + 0x79, 0x71, 0x6c, 0x72, 0x42, 0x42, 0x4e, 0x41, 0x63, 0x6f, 0x77, 0x37, + 0x4d, 0x57, 0x6a, 0x51, 0x53, 0x30, 0x66, 0x6c, 0x55, 0x45, 0x6a, 0x38, + 0x48, 0x6d, 0x72, 0x64, 0x54, 0x58, 0x2b, 0x64, 0x65, 0x6e, 0x5a, 0x35, + 0x0a, 0x73, 0x41, 0x72, 0x56, 0x45, 0x42, 0x57, 0x49, 0x6f, 0x49, 0x63, + 0x43, 0x57, 0x74, 0x30, 0x44, 0x57, 0x47, 0x7a, 0x2f, 0x6d, 0x5a, 0x44, + 0x53, 0x32, 0x58, 0x50, 0x71, 0x79, 0x79, 0x39, 0x49, 0x62, 0x45, 0x6e, + 0x68, 0x77, 0x74, 0x5a, 0x33, 0x62, 0x70, 0x48, 0x6d, 0x77, 0x31, 0x31, + 0x4a, 0x31, 0x6b, 0x36, 0x31, 0x6f, 0x64, 0x41, 0x77, 0x79, 0x35, 0x73, + 0x45, 0x33, 0x50, 0x34, 0x53, 0x0a, 0x6b, 0x53, 0x2f, 0x53, 0x76, 0x6c, + 0x37, 0x57, 0x78, 0x6a, 0x63, 0x72, 0x35, 0x77, 0x49, 0x44, 0x41, 0x51, + 0x41, 0x42, 0x41, 0x6d, 0x45, 0x41, 0x78, 0x35, 0x30, 0x70, 0x47, 0x32, + 0x51, 0x69, 0x5a, 0x70, 0x4d, 0x47, 0x51, 0x76, 0x45, 0x45, 0x69, 0x78, + 0x45, 0x33, 0x32, 0x69, 0x5a, 0x31, 0x4f, 0x58, 0x55, 0x34, 0x34, 0x6b, + 0x77, 0x46, 0x45, 0x4f, 0x31, 0x59, 0x2f, 0x4e, 0x2b, 0x4f, 0x0a, 0x47, + 0x62, 0x4b, 0x6b, 0x7a, 0x66, 0x35, 0x46, 0x39, 0x69, 0x67, 0x50, 0x49, + 0x65, 0x77, 0x73, 0x64, 0x34, 0x72, 0x6b, 0x43, 0x31, 0x4d, 0x62, 0x63, + 0x56, 0x50, 0x59, 0x54, 0x4e, 0x36, 0x61, 0x37, 0x57, 0x6c, 0x46, 0x68, + 0x32, 0x64, 0x50, 0x31, 0x6b, 0x43, 0x35, 0x77, 0x64, 0x50, 0x41, 0x64, + 0x56, 0x6a, 0x42, 0x66, 0x31, 0x70, 0x37, 0x49, 0x69, 0x34, 0x74, 0x34, + 0x48, 0x5a, 0x74, 0x0a, 0x4f, 0x6f, 0x6b, 0x69, 0x64, 0x64, 0x75, 0x4a, + 0x7a, 0x43, 0x6d, 0x43, 0x2b, 0x54, 0x75, 0x6c, 0x44, 0x43, 0x4e, 0x4c, + 0x46, 0x6d, 0x6c, 0x42, 0x41, 0x6a, 0x45, 0x41, 0x2f, 0x36, 0x53, 0x55, + 0x78, 0x63, 0x78, 0x52, 0x58, 0x4a, 0x56, 0x37, 0x47, 0x48, 0x42, 0x6d, + 0x75, 0x2b, 0x46, 0x49, 0x62, 0x6e, 0x52, 0x36, 0x2f, 0x64, 0x72, 0x48, + 0x61, 0x42, 0x76, 0x4d, 0x6b, 0x4e, 0x4b, 0x5a, 0x0a, 0x2f, 0x74, 0x47, + 0x49, 0x71, 0x31, 0x4b, 0x66, 0x72, 0x48, 0x49, 0x57, 0x72, 0x68, 0x47, + 0x6c, 0x32, 0x76, 0x59, 0x71, 0x6f, 0x74, 0x36, 0x68, 0x52, 0x67, 0x6f, + 0x58, 0x41, 0x6a, 0x45, 0x41, 0x31, 0x6a, 0x39, 0x56, 0x41, 0x79, 0x75, + 0x44, 0x4b, 0x32, 0x4e, 0x68, 0x51, 0x47, 0x2f, 0x57, 0x4d, 0x6d, 0x66, + 0x38, 0x57, 0x56, 0x2b, 0x4f, 0x4d, 0x65, 0x4a, 0x51, 0x37, 0x76, 0x70, + 0x6e, 0x0a, 0x33, 0x4b, 0x6d, 0x74, 0x50, 0x63, 0x2f, 0x43, 0x73, 0x57, + 0x66, 0x50, 0x4e, 0x59, 0x65, 0x51, 0x61, 0x67, 0x66, 0x77, 0x6c, 0x6a, + 0x30, 0x53, 0x4c, 0x47, 0x77, 0x7a, 0x38, 0x4a, 0x36, 0x78, 0x41, 0x6a, + 0x45, 0x41, 0x34, 0x71, 0x49, 0x52, 0x6b, 0x6c, 0x6c, 0x55, 0x4e, 0x2f, + 0x50, 0x39, 0x4d, 0x4f, 0x6c, 0x55, 0x36, 0x6e, 0x4d, 0x4b, 0x4e, 0x34, + 0x48, 0x6b, 0x46, 0x33, 0x45, 0x42, 0x0a, 0x48, 0x76, 0x61, 0x6d, 0x49, + 0x43, 0x33, 0x55, 0x66, 0x2b, 0x64, 0x61, 0x64, 0x69, 0x66, 0x46, 0x6a, + 0x71, 0x65, 0x47, 0x47, 0x38, 0x4e, 0x68, 0x65, 0x67, 0x43, 0x4b, 0x51, + 0x2b, 0x47, 0x43, 0x73, 0x41, 0x6a, 0x35, 0x41, 0x6a, 0x41, 0x65, 0x63, + 0x73, 0x33, 0x41, 0x4c, 0x35, 0x54, 0x71, 0x75, 0x36, 0x72, 0x38, 0x6e, + 0x32, 0x68, 0x50, 0x72, 0x5a, 0x75, 0x64, 0x6b, 0x41, 0x6b, 0x44, 0x0a, + 0x61, 0x65, 0x69, 0x61, 0x72, 0x68, 0x66, 0x49, 0x73, 0x6f, 0x79, 0x65, + 0x64, 0x6b, 0x4a, 0x7a, 0x4f, 0x41, 0x2b, 0x6f, 0x79, 0x65, 0x56, 0x71, + 0x54, 0x45, 0x71, 0x53, 0x37, 0x34, 0x62, 0x2f, 0x72, 0x54, 0x6b, 0x4d, + 0x66, 0x32, 0x45, 0x43, 0x4d, 0x42, 0x72, 0x74, 0x73, 0x30, 0x6f, 0x46, + 0x6d, 0x56, 0x4a, 0x59, 0x6f, 0x37, 0x37, 0x72, 0x69, 0x4b, 0x51, 0x42, + 0x59, 0x62, 0x52, 0x37, 0x0a, 0x2f, 0x38, 0x66, 0x65, 0x69, 0x73, 0x59, + 0x53, 0x50, 0x48, 0x53, 0x67, 0x37, 0x68, 0x77, 0x61, 0x6f, 0x58, 0x53, + 0x77, 0x55, 0x2b, 0x6a, 0x55, 0x34, 0x67, 0x33, 0x39, 0x77, 0x37, 0x72, + 0x67, 0x76, 0x4f, 0x2b, 0x57, 0x6b, 0x47, 0x75, 0x7a, 0x79, 0x51, 0x3d, + 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x52, + 0x53, 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, + 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + ]), + public: undefined, + publicOrig: undefined + }, + what: 'Unencrypted RSA private key (OpenSSH format)' + }, + { source: [ + ' ', + '-----BEGIN RSA PRIVATE KEY-----', + 'MIIBywIBAAJhANXy0sLFQFgcY6sfyqlrBBNAcow7MWjQS0flUEj8HmrdTX+denZ5', + 'sArVEBWIoIcCWt0DWGz/mZDS2XPqyy9IbEnhwtZ3bpHmw11J1k61odAwy5sE3P4S', + 'kS/Svl7Wxjcr5wIDAQABAmEAx50pG2QiZpMGQvEEixE32iZ1OXU44kwFEO1Y/N+O', + 'GbKkzf5F9igPIewsd4rkC1MbcVPYTN6a7WlFh2dP1kC5wdPAdVjBf1p7Ii4t4HZt', + 'OokidduJzCmC+TulDCNLFmlBAjEA/6SUxcxRXJV7GHBmu+FIbnR6/drHaBvMkNKZ', + '/tGIq1KfrHIWrhGl2vYqot6hRgoXAjEA1j9VAyuDK2NhQG/WMmf8WV+OMeJQ7vpn', + '3KmtPc/CsWfPNYeQagfwlj0SLGwz8J6xAjEA4qIRkllUN/P9MOlU6nMKN4HkF3EB', + 'HvamIC3Uf+dadifFjqeGG8NhegCKQ+GCsAj5AjAecs3AL5Tqu6r8n2hPrZudkAkD', + 'aeiarhfIsoyedkJzOA+oyeVqTEqS74b/rTkMf2ECMBrts0oFmVJYo77riKQBYbR7', + '/8feisYSPHSg7hwaoXSwU+jU4g39w7rgvO+WkGuzyQ==', + '-----END RSA PRIVATE KEY-----', + ' ' + ].join('\n'), + expected: { + fulltype: 'ssh-rsa', + type: 'rsa', + curve: undefined, + extra: undefined, + comment: undefined, + encryption: undefined, + private: new Buffer([ + 0x30, 0x82, 0x01, 0xcb, 0x02, 0x01, 0x00, 0x02, 0x61, 0x00, 0xd5, 0xf2, + 0xd2, 0xc2, 0xc5, 0x40, 0x58, 0x1c, 0x63, 0xab, 0x1f, 0xca, 0xa9, 0x6b, + 0x04, 0x13, 0x40, 0x72, 0x8c, 0x3b, 0x31, 0x68, 0xd0, 0x4b, 0x47, 0xe5, + 0x50, 0x48, 0xfc, 0x1e, 0x6a, 0xdd, 0x4d, 0x7f, 0x9d, 0x7a, 0x76, 0x79, + 0xb0, 0x0a, 0xd5, 0x10, 0x15, 0x88, 0xa0, 0x87, 0x02, 0x5a, 0xdd, 0x03, + 0x58, 0x6c, 0xff, 0x99, 0x90, 0xd2, 0xd9, 0x73, 0xea, 0xcb, 0x2f, 0x48, + 0x6c, 0x49, 0xe1, 0xc2, 0xd6, 0x77, 0x6e, 0x91, 0xe6, 0xc3, 0x5d, 0x49, + 0xd6, 0x4e, 0xb5, 0xa1, 0xd0, 0x30, 0xcb, 0x9b, 0x04, 0xdc, 0xfe, 0x12, + 0x91, 0x2f, 0xd2, 0xbe, 0x5e, 0xd6, 0xc6, 0x37, 0x2b, 0xe7, 0x02, 0x03, + 0x01, 0x00, 0x01, 0x02, 0x61, 0x00, 0xc7, 0x9d, 0x29, 0x1b, 0x64, 0x22, + 0x66, 0x93, 0x06, 0x42, 0xf1, 0x04, 0x8b, 0x11, 0x37, 0xda, 0x26, 0x75, + 0x39, 0x75, 0x38, 0xe2, 0x4c, 0x05, 0x10, 0xed, 0x58, 0xfc, 0xdf, 0x8e, + 0x19, 0xb2, 0xa4, 0xcd, 0xfe, 0x45, 0xf6, 0x28, 0x0f, 0x21, 0xec, 0x2c, + 0x77, 0x8a, 0xe4, 0x0b, 0x53, 0x1b, 0x71, 0x53, 0xd8, 0x4c, 0xde, 0x9a, + 0xed, 0x69, 0x45, 0x87, 0x67, 0x4f, 0xd6, 0x40, 0xb9, 0xc1, 0xd3, 0xc0, + 0x75, 0x58, 0xc1, 0x7f, 0x5a, 0x7b, 0x22, 0x2e, 0x2d, 0xe0, 0x76, 0x6d, + 0x3a, 0x89, 0x22, 0x75, 0xdb, 0x89, 0xcc, 0x29, 0x82, 0xf9, 0x3b, 0xa5, + 0x0c, 0x23, 0x4b, 0x16, 0x69, 0x41, 0x02, 0x31, 0x00, 0xff, 0xa4, 0x94, + 0xc5, 0xcc, 0x51, 0x5c, 0x95, 0x7b, 0x18, 0x70, 0x66, 0xbb, 0xe1, 0x48, + 0x6e, 0x74, 0x7a, 0xfd, 0xda, 0xc7, 0x68, 0x1b, 0xcc, 0x90, 0xd2, 0x99, + 0xfe, 0xd1, 0x88, 0xab, 0x52, 0x9f, 0xac, 0x72, 0x16, 0xae, 0x11, 0xa5, + 0xda, 0xf6, 0x2a, 0xa2, 0xde, 0xa1, 0x46, 0x0a, 0x17, 0x02, 0x31, 0x00, + 0xd6, 0x3f, 0x55, 0x03, 0x2b, 0x83, 0x2b, 0x63, 0x61, 0x40, 0x6f, 0xd6, + 0x32, 0x67, 0xfc, 0x59, 0x5f, 0x8e, 0x31, 0xe2, 0x50, 0xee, 0xfa, 0x67, + 0xdc, 0xa9, 0xad, 0x3d, 0xcf, 0xc2, 0xb1, 0x67, 0xcf, 0x35, 0x87, 0x90, + 0x6a, 0x07, 0xf0, 0x96, 0x3d, 0x12, 0x2c, 0x6c, 0x33, 0xf0, 0x9e, 0xb1, + 0x02, 0x31, 0x00, 0xe2, 0xa2, 0x11, 0x92, 0x59, 0x54, 0x37, 0xf3, 0xfd, + 0x30, 0xe9, 0x54, 0xea, 0x73, 0x0a, 0x37, 0x81, 0xe4, 0x17, 0x71, 0x01, + 0x1e, 0xf6, 0xa6, 0x20, 0x2d, 0xd4, 0x7f, 0xe7, 0x5a, 0x76, 0x27, 0xc5, + 0x8e, 0xa7, 0x86, 0x1b, 0xc3, 0x61, 0x7a, 0x00, 0x8a, 0x43, 0xe1, 0x82, + 0xb0, 0x08, 0xf9, 0x02, 0x30, 0x1e, 0x72, 0xcd, 0xc0, 0x2f, 0x94, 0xea, + 0xbb, 0xaa, 0xfc, 0x9f, 0x68, 0x4f, 0xad, 0x9b, 0x9d, 0x90, 0x09, 0x03, + 0x69, 0xe8, 0x9a, 0xae, 0x17, 0xc8, 0xb2, 0x8c, 0x9e, 0x76, 0x42, 0x73, + 0x38, 0x0f, 0xa8, 0xc9, 0xe5, 0x6a, 0x4c, 0x4a, 0x92, 0xef, 0x86, 0xff, + 0xad, 0x39, 0x0c, 0x7f, 0x61, 0x02, 0x30, 0x1a, 0xed, 0xb3, 0x4a, 0x05, + 0x99, 0x52, 0x58, 0xa3, 0xbe, 0xeb, 0x88, 0xa4, 0x01, 0x61, 0xb4, 0x7b, + 0xff, 0xc7, 0xde, 0x8a, 0xc6, 0x12, 0x3c, 0x74, 0xa0, 0xee, 0x1c, 0x1a, + 0xa1, 0x74, 0xb0, 0x53, 0xe8, 0xd4, 0xe2, 0x0d, 0xfd, 0xc3, 0xba, 0xe0, + 0xbc, 0xef, 0x96, 0x90, 0x6b, 0xb3, 0xc9, + ]), + privateOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x52, + 0x53, 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, + 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x42, + 0x79, 0x77, 0x49, 0x42, 0x41, 0x41, 0x4a, 0x68, 0x41, 0x4e, 0x58, 0x79, + 0x30, 0x73, 0x4c, 0x46, 0x51, 0x46, 0x67, 0x63, 0x59, 0x36, 0x73, 0x66, + 0x79, 0x71, 0x6c, 0x72, 0x42, 0x42, 0x4e, 0x41, 0x63, 0x6f, 0x77, 0x37, + 0x4d, 0x57, 0x6a, 0x51, 0x53, 0x30, 0x66, 0x6c, 0x55, 0x45, 0x6a, 0x38, + 0x48, 0x6d, 0x72, 0x64, 0x54, 0x58, 0x2b, 0x64, 0x65, 0x6e, 0x5a, 0x35, + 0x0a, 0x73, 0x41, 0x72, 0x56, 0x45, 0x42, 0x57, 0x49, 0x6f, 0x49, 0x63, + 0x43, 0x57, 0x74, 0x30, 0x44, 0x57, 0x47, 0x7a, 0x2f, 0x6d, 0x5a, 0x44, + 0x53, 0x32, 0x58, 0x50, 0x71, 0x79, 0x79, 0x39, 0x49, 0x62, 0x45, 0x6e, + 0x68, 0x77, 0x74, 0x5a, 0x33, 0x62, 0x70, 0x48, 0x6d, 0x77, 0x31, 0x31, + 0x4a, 0x31, 0x6b, 0x36, 0x31, 0x6f, 0x64, 0x41, 0x77, 0x79, 0x35, 0x73, + 0x45, 0x33, 0x50, 0x34, 0x53, 0x0a, 0x6b, 0x53, 0x2f, 0x53, 0x76, 0x6c, + 0x37, 0x57, 0x78, 0x6a, 0x63, 0x72, 0x35, 0x77, 0x49, 0x44, 0x41, 0x51, + 0x41, 0x42, 0x41, 0x6d, 0x45, 0x41, 0x78, 0x35, 0x30, 0x70, 0x47, 0x32, + 0x51, 0x69, 0x5a, 0x70, 0x4d, 0x47, 0x51, 0x76, 0x45, 0x45, 0x69, 0x78, + 0x45, 0x33, 0x32, 0x69, 0x5a, 0x31, 0x4f, 0x58, 0x55, 0x34, 0x34, 0x6b, + 0x77, 0x46, 0x45, 0x4f, 0x31, 0x59, 0x2f, 0x4e, 0x2b, 0x4f, 0x0a, 0x47, + 0x62, 0x4b, 0x6b, 0x7a, 0x66, 0x35, 0x46, 0x39, 0x69, 0x67, 0x50, 0x49, + 0x65, 0x77, 0x73, 0x64, 0x34, 0x72, 0x6b, 0x43, 0x31, 0x4d, 0x62, 0x63, + 0x56, 0x50, 0x59, 0x54, 0x4e, 0x36, 0x61, 0x37, 0x57, 0x6c, 0x46, 0x68, + 0x32, 0x64, 0x50, 0x31, 0x6b, 0x43, 0x35, 0x77, 0x64, 0x50, 0x41, 0x64, + 0x56, 0x6a, 0x42, 0x66, 0x31, 0x70, 0x37, 0x49, 0x69, 0x34, 0x74, 0x34, + 0x48, 0x5a, 0x74, 0x0a, 0x4f, 0x6f, 0x6b, 0x69, 0x64, 0x64, 0x75, 0x4a, + 0x7a, 0x43, 0x6d, 0x43, 0x2b, 0x54, 0x75, 0x6c, 0x44, 0x43, 0x4e, 0x4c, + 0x46, 0x6d, 0x6c, 0x42, 0x41, 0x6a, 0x45, 0x41, 0x2f, 0x36, 0x53, 0x55, + 0x78, 0x63, 0x78, 0x52, 0x58, 0x4a, 0x56, 0x37, 0x47, 0x48, 0x42, 0x6d, + 0x75, 0x2b, 0x46, 0x49, 0x62, 0x6e, 0x52, 0x36, 0x2f, 0x64, 0x72, 0x48, + 0x61, 0x42, 0x76, 0x4d, 0x6b, 0x4e, 0x4b, 0x5a, 0x0a, 0x2f, 0x74, 0x47, + 0x49, 0x71, 0x31, 0x4b, 0x66, 0x72, 0x48, 0x49, 0x57, 0x72, 0x68, 0x47, + 0x6c, 0x32, 0x76, 0x59, 0x71, 0x6f, 0x74, 0x36, 0x68, 0x52, 0x67, 0x6f, + 0x58, 0x41, 0x6a, 0x45, 0x41, 0x31, 0x6a, 0x39, 0x56, 0x41, 0x79, 0x75, + 0x44, 0x4b, 0x32, 0x4e, 0x68, 0x51, 0x47, 0x2f, 0x57, 0x4d, 0x6d, 0x66, + 0x38, 0x57, 0x56, 0x2b, 0x4f, 0x4d, 0x65, 0x4a, 0x51, 0x37, 0x76, 0x70, + 0x6e, 0x0a, 0x33, 0x4b, 0x6d, 0x74, 0x50, 0x63, 0x2f, 0x43, 0x73, 0x57, + 0x66, 0x50, 0x4e, 0x59, 0x65, 0x51, 0x61, 0x67, 0x66, 0x77, 0x6c, 0x6a, + 0x30, 0x53, 0x4c, 0x47, 0x77, 0x7a, 0x38, 0x4a, 0x36, 0x78, 0x41, 0x6a, + 0x45, 0x41, 0x34, 0x71, 0x49, 0x52, 0x6b, 0x6c, 0x6c, 0x55, 0x4e, 0x2f, + 0x50, 0x39, 0x4d, 0x4f, 0x6c, 0x55, 0x36, 0x6e, 0x4d, 0x4b, 0x4e, 0x34, + 0x48, 0x6b, 0x46, 0x33, 0x45, 0x42, 0x0a, 0x48, 0x76, 0x61, 0x6d, 0x49, + 0x43, 0x33, 0x55, 0x66, 0x2b, 0x64, 0x61, 0x64, 0x69, 0x66, 0x46, 0x6a, + 0x71, 0x65, 0x47, 0x47, 0x38, 0x4e, 0x68, 0x65, 0x67, 0x43, 0x4b, 0x51, + 0x2b, 0x47, 0x43, 0x73, 0x41, 0x6a, 0x35, 0x41, 0x6a, 0x41, 0x65, 0x63, + 0x73, 0x33, 0x41, 0x4c, 0x35, 0x54, 0x71, 0x75, 0x36, 0x72, 0x38, 0x6e, + 0x32, 0x68, 0x50, 0x72, 0x5a, 0x75, 0x64, 0x6b, 0x41, 0x6b, 0x44, 0x0a, + 0x61, 0x65, 0x69, 0x61, 0x72, 0x68, 0x66, 0x49, 0x73, 0x6f, 0x79, 0x65, + 0x64, 0x6b, 0x4a, 0x7a, 0x4f, 0x41, 0x2b, 0x6f, 0x79, 0x65, 0x56, 0x71, + 0x54, 0x45, 0x71, 0x53, 0x37, 0x34, 0x62, 0x2f, 0x72, 0x54, 0x6b, 0x4d, + 0x66, 0x32, 0x45, 0x43, 0x4d, 0x42, 0x72, 0x74, 0x73, 0x30, 0x6f, 0x46, + 0x6d, 0x56, 0x4a, 0x59, 0x6f, 0x37, 0x37, 0x72, 0x69, 0x4b, 0x51, 0x42, + 0x59, 0x62, 0x52, 0x37, 0x0a, 0x2f, 0x38, 0x66, 0x65, 0x69, 0x73, 0x59, + 0x53, 0x50, 0x48, 0x53, 0x67, 0x37, 0x68, 0x77, 0x61, 0x6f, 0x58, 0x53, + 0x77, 0x55, 0x2b, 0x6a, 0x55, 0x34, 0x67, 0x33, 0x39, 0x77, 0x37, 0x72, + 0x67, 0x76, 0x4f, 0x2b, 0x57, 0x6b, 0x47, 0x75, 0x7a, 0x79, 0x51, 0x3d, + 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x52, + 0x53, 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, + 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + ]), + public: undefined, + publicOrig: undefined + }, + what: 'Unencrypted RSA private key (OpenSSH format) with surrounding whitespace' + }, + { source: [ + '-----BEGIN RSA PRIVATE KEY-----', + 'Proc-Type: 4,ENCRYPTED', + 'DEK-Info: AES-128-CBC,E9F7397F94E585BCE4C739D5C5226A2D', + '', + 'mshPNeXq8XAh79N3F1vKUOCsWoTofhz/Kpt/ddYdgnGG9L5wGDoveJQtpsa5u+A4', + 'hCkAWA7KRCUKbOxZd8lG00cm7HILN7eHCKSoSkyA+X1jN7v1tSGPjiN2RSZFHCOI', + '8jEF0fyTeg9GZzFaiyyD5p1niy7uCssEeo8AzbIBX4yLDR18mmBiMhn0FxVu/YFn', + 'rfkm+ciE4WhkqdCUOkKiqIux7RI6O9ttUuZlhwVvoKZqujMeNrFppOC9kF5hAi6Y', + 'oHvrweE8QmimEUIMAwdDrI1/jglFw2x2K5sRxPIIFJC1aHR8nXLTuO1g2/g6aqls', + 'jGkwlQU4cU5pnkxkLUVCSHi6A6nwbdjQTIIDofpcckQVFHZaBCJx9UF691NR05Dc', + 'GthFFfNGXWU6vbwKia/LDX8R98ay4Ci2zoDXxe7QBnvnWbs2m69HPh6opmo5gKL+', + 'y65Sf6MAi5udIJLVfgXQBgRyX3glS7/rH8YbrrNY9Iop1KcSWXAIC4zlCoO3tBJB', + '9464YBD/R+qOvVMcBGxTjabudi00ougeTgsS7idDTmfc4HYIls0E7yWqzgspsws5', + 'w7K4crSgm+u3oypViUSre2qSvAHTC5gXth8LVCnDZuA=', + '-----END RSA PRIVATE KEY-----' + ].join('\n'), + expected: { + fulltype: undefined, + type: 'rsa', + curve: undefined, + extra: [ 'E9F7397F94E585BCE4C739D5C5226A2D' ], + comment: undefined, + encryption: 'aes-128-cbc', + private: new Buffer([ + 0x9a, 0xc8, 0x4f, 0x35, 0xe5, 0xea, 0xf1, 0x70, 0x21, 0xef, 0xd3, 0x77, + 0x17, 0x5b, 0xca, 0x50, 0xe0, 0xac, 0x5a, 0x84, 0xe8, 0x7e, 0x1c, 0xff, + 0x2a, 0x9b, 0x7f, 0x75, 0xd6, 0x1d, 0x82, 0x71, 0x86, 0xf4, 0xbe, 0x70, + 0x18, 0x3a, 0x2f, 0x78, 0x94, 0x2d, 0xa6, 0xc6, 0xb9, 0xbb, 0xe0, 0x38, + 0x84, 0x29, 0x00, 0x58, 0x0e, 0xca, 0x44, 0x25, 0x0a, 0x6c, 0xec, 0x59, + 0x77, 0xc9, 0x46, 0xd3, 0x47, 0x26, 0xec, 0x72, 0x0b, 0x37, 0xb7, 0x87, + 0x08, 0xa4, 0xa8, 0x4a, 0x4c, 0x80, 0xf9, 0x7d, 0x63, 0x37, 0xbb, 0xf5, + 0xb5, 0x21, 0x8f, 0x8e, 0x23, 0x76, 0x45, 0x26, 0x45, 0x1c, 0x23, 0x88, + 0xf2, 0x31, 0x05, 0xd1, 0xfc, 0x93, 0x7a, 0x0f, 0x46, 0x67, 0x31, 0x5a, + 0x8b, 0x2c, 0x83, 0xe6, 0x9d, 0x67, 0x8b, 0x2e, 0xee, 0x0a, 0xcb, 0x04, + 0x7a, 0x8f, 0x00, 0xcd, 0xb2, 0x01, 0x5f, 0x8c, 0x8b, 0x0d, 0x1d, 0x7c, + 0x9a, 0x60, 0x62, 0x32, 0x19, 0xf4, 0x17, 0x15, 0x6e, 0xfd, 0x81, 0x67, + 0xad, 0xf9, 0x26, 0xf9, 0xc8, 0x84, 0xe1, 0x68, 0x64, 0xa9, 0xd0, 0x94, + 0x3a, 0x42, 0xa2, 0xa8, 0x8b, 0xb1, 0xed, 0x12, 0x3a, 0x3b, 0xdb, 0x6d, + 0x52, 0xe6, 0x65, 0x87, 0x05, 0x6f, 0xa0, 0xa6, 0x6a, 0xba, 0x33, 0x1e, + 0x36, 0xb1, 0x69, 0xa4, 0xe0, 0xbd, 0x90, 0x5e, 0x61, 0x02, 0x2e, 0x98, + 0xa0, 0x7b, 0xeb, 0xc1, 0xe1, 0x3c, 0x42, 0x68, 0xa6, 0x11, 0x42, 0x0c, + 0x03, 0x07, 0x43, 0xac, 0x8d, 0x7f, 0x8e, 0x09, 0x45, 0xc3, 0x6c, 0x76, + 0x2b, 0x9b, 0x11, 0xc4, 0xf2, 0x08, 0x14, 0x90, 0xb5, 0x68, 0x74, 0x7c, + 0x9d, 0x72, 0xd3, 0xb8, 0xed, 0x60, 0xdb, 0xf8, 0x3a, 0x6a, 0xa9, 0x6c, + 0x8c, 0x69, 0x30, 0x95, 0x05, 0x38, 0x71, 0x4e, 0x69, 0x9e, 0x4c, 0x64, + 0x2d, 0x45, 0x42, 0x48, 0x78, 0xba, 0x03, 0xa9, 0xf0, 0x6d, 0xd8, 0xd0, + 0x4c, 0x82, 0x03, 0xa1, 0xfa, 0x5c, 0x72, 0x44, 0x15, 0x14, 0x76, 0x5a, + 0x04, 0x22, 0x71, 0xf5, 0x41, 0x7a, 0xf7, 0x53, 0x51, 0xd3, 0x90, 0xdc, + 0x1a, 0xd8, 0x45, 0x15, 0xf3, 0x46, 0x5d, 0x65, 0x3a, 0xbd, 0xbc, 0x0a, + 0x89, 0xaf, 0xcb, 0x0d, 0x7f, 0x11, 0xf7, 0xc6, 0xb2, 0xe0, 0x28, 0xb6, + 0xce, 0x80, 0xd7, 0xc5, 0xee, 0xd0, 0x06, 0x7b, 0xe7, 0x59, 0xbb, 0x36, + 0x9b, 0xaf, 0x47, 0x3e, 0x1e, 0xa8, 0xa6, 0x6a, 0x39, 0x80, 0xa2, 0xfe, + 0xcb, 0xae, 0x52, 0x7f, 0xa3, 0x00, 0x8b, 0x9b, 0x9d, 0x20, 0x92, 0xd5, + 0x7e, 0x05, 0xd0, 0x06, 0x04, 0x72, 0x5f, 0x78, 0x25, 0x4b, 0xbf, 0xeb, + 0x1f, 0xc6, 0x1b, 0xae, 0xb3, 0x58, 0xf4, 0x8a, 0x29, 0xd4, 0xa7, 0x12, + 0x59, 0x70, 0x08, 0x0b, 0x8c, 0xe5, 0x0a, 0x83, 0xb7, 0xb4, 0x12, 0x41, + 0xf7, 0x8e, 0xb8, 0x60, 0x10, 0xff, 0x47, 0xea, 0x8e, 0xbd, 0x53, 0x1c, + 0x04, 0x6c, 0x53, 0x8d, 0xa6, 0xee, 0x76, 0x2d, 0x34, 0xa2, 0xe8, 0x1e, + 0x4e, 0x0b, 0x12, 0xee, 0x27, 0x43, 0x4e, 0x67, 0xdc, 0xe0, 0x76, 0x08, + 0x96, 0xcd, 0x04, 0xef, 0x25, 0xaa, 0xce, 0x0b, 0x29, 0xb3, 0x0b, 0x39, + 0xc3, 0xb2, 0xb8, 0x72, 0xb4, 0xa0, 0x9b, 0xeb, 0xb7, 0xa3, 0x2a, 0x55, + 0x89, 0x44, 0xab, 0x7b, 0x6a, 0x92, 0xbc, 0x01, 0xd3, 0x0b, 0x98, 0x17, + 0xb6, 0x1f, 0x0b, 0x54, 0x29, 0xc3, 0x66, 0xe0, + ]), + privateOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x52, + 0x53, 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, + 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x50, 0x72, 0x6f, 0x63, + 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x34, 0x2c, 0x45, 0x4e, 0x43, + 0x52, 0x59, 0x50, 0x54, 0x45, 0x44, 0x0a, 0x44, 0x45, 0x4b, 0x2d, 0x49, + 0x6e, 0x66, 0x6f, 0x3a, 0x20, 0x41, 0x45, 0x53, 0x2d, 0x31, 0x32, 0x38, + 0x2d, 0x43, 0x42, 0x43, 0x2c, 0x45, 0x39, 0x46, 0x37, 0x33, 0x39, 0x37, + 0x46, 0x39, 0x34, 0x45, 0x35, 0x38, 0x35, 0x42, 0x43, 0x45, 0x34, 0x43, + 0x37, 0x33, 0x39, 0x44, 0x35, 0x43, 0x35, 0x32, 0x32, 0x36, 0x41, 0x32, + 0x44, 0x0a, 0x0a, 0x6d, 0x73, 0x68, 0x50, 0x4e, 0x65, 0x58, 0x71, 0x38, + 0x58, 0x41, 0x68, 0x37, 0x39, 0x4e, 0x33, 0x46, 0x31, 0x76, 0x4b, 0x55, + 0x4f, 0x43, 0x73, 0x57, 0x6f, 0x54, 0x6f, 0x66, 0x68, 0x7a, 0x2f, 0x4b, + 0x70, 0x74, 0x2f, 0x64, 0x64, 0x59, 0x64, 0x67, 0x6e, 0x47, 0x47, 0x39, + 0x4c, 0x35, 0x77, 0x47, 0x44, 0x6f, 0x76, 0x65, 0x4a, 0x51, 0x74, 0x70, + 0x73, 0x61, 0x35, 0x75, 0x2b, 0x41, 0x34, 0x0a, 0x68, 0x43, 0x6b, 0x41, + 0x57, 0x41, 0x37, 0x4b, 0x52, 0x43, 0x55, 0x4b, 0x62, 0x4f, 0x78, 0x5a, + 0x64, 0x38, 0x6c, 0x47, 0x30, 0x30, 0x63, 0x6d, 0x37, 0x48, 0x49, 0x4c, + 0x4e, 0x37, 0x65, 0x48, 0x43, 0x4b, 0x53, 0x6f, 0x53, 0x6b, 0x79, 0x41, + 0x2b, 0x58, 0x31, 0x6a, 0x4e, 0x37, 0x76, 0x31, 0x74, 0x53, 0x47, 0x50, + 0x6a, 0x69, 0x4e, 0x32, 0x52, 0x53, 0x5a, 0x46, 0x48, 0x43, 0x4f, 0x49, + 0x0a, 0x38, 0x6a, 0x45, 0x46, 0x30, 0x66, 0x79, 0x54, 0x65, 0x67, 0x39, + 0x47, 0x5a, 0x7a, 0x46, 0x61, 0x69, 0x79, 0x79, 0x44, 0x35, 0x70, 0x31, + 0x6e, 0x69, 0x79, 0x37, 0x75, 0x43, 0x73, 0x73, 0x45, 0x65, 0x6f, 0x38, + 0x41, 0x7a, 0x62, 0x49, 0x42, 0x58, 0x34, 0x79, 0x4c, 0x44, 0x52, 0x31, + 0x38, 0x6d, 0x6d, 0x42, 0x69, 0x4d, 0x68, 0x6e, 0x30, 0x46, 0x78, 0x56, + 0x75, 0x2f, 0x59, 0x46, 0x6e, 0x0a, 0x72, 0x66, 0x6b, 0x6d, 0x2b, 0x63, + 0x69, 0x45, 0x34, 0x57, 0x68, 0x6b, 0x71, 0x64, 0x43, 0x55, 0x4f, 0x6b, + 0x4b, 0x69, 0x71, 0x49, 0x75, 0x78, 0x37, 0x52, 0x49, 0x36, 0x4f, 0x39, + 0x74, 0x74, 0x55, 0x75, 0x5a, 0x6c, 0x68, 0x77, 0x56, 0x76, 0x6f, 0x4b, + 0x5a, 0x71, 0x75, 0x6a, 0x4d, 0x65, 0x4e, 0x72, 0x46, 0x70, 0x70, 0x4f, + 0x43, 0x39, 0x6b, 0x46, 0x35, 0x68, 0x41, 0x69, 0x36, 0x59, 0x0a, 0x6f, + 0x48, 0x76, 0x72, 0x77, 0x65, 0x45, 0x38, 0x51, 0x6d, 0x69, 0x6d, 0x45, + 0x55, 0x49, 0x4d, 0x41, 0x77, 0x64, 0x44, 0x72, 0x49, 0x31, 0x2f, 0x6a, + 0x67, 0x6c, 0x46, 0x77, 0x32, 0x78, 0x32, 0x4b, 0x35, 0x73, 0x52, 0x78, + 0x50, 0x49, 0x49, 0x46, 0x4a, 0x43, 0x31, 0x61, 0x48, 0x52, 0x38, 0x6e, + 0x58, 0x4c, 0x54, 0x75, 0x4f, 0x31, 0x67, 0x32, 0x2f, 0x67, 0x36, 0x61, + 0x71, 0x6c, 0x73, 0x0a, 0x6a, 0x47, 0x6b, 0x77, 0x6c, 0x51, 0x55, 0x34, + 0x63, 0x55, 0x35, 0x70, 0x6e, 0x6b, 0x78, 0x6b, 0x4c, 0x55, 0x56, 0x43, + 0x53, 0x48, 0x69, 0x36, 0x41, 0x36, 0x6e, 0x77, 0x62, 0x64, 0x6a, 0x51, + 0x54, 0x49, 0x49, 0x44, 0x6f, 0x66, 0x70, 0x63, 0x63, 0x6b, 0x51, 0x56, + 0x46, 0x48, 0x5a, 0x61, 0x42, 0x43, 0x4a, 0x78, 0x39, 0x55, 0x46, 0x36, + 0x39, 0x31, 0x4e, 0x52, 0x30, 0x35, 0x44, 0x63, 0x0a, 0x47, 0x74, 0x68, + 0x46, 0x46, 0x66, 0x4e, 0x47, 0x58, 0x57, 0x55, 0x36, 0x76, 0x62, 0x77, + 0x4b, 0x69, 0x61, 0x2f, 0x4c, 0x44, 0x58, 0x38, 0x52, 0x39, 0x38, 0x61, + 0x79, 0x34, 0x43, 0x69, 0x32, 0x7a, 0x6f, 0x44, 0x58, 0x78, 0x65, 0x37, + 0x51, 0x42, 0x6e, 0x76, 0x6e, 0x57, 0x62, 0x73, 0x32, 0x6d, 0x36, 0x39, + 0x48, 0x50, 0x68, 0x36, 0x6f, 0x70, 0x6d, 0x6f, 0x35, 0x67, 0x4b, 0x4c, + 0x2b, 0x0a, 0x79, 0x36, 0x35, 0x53, 0x66, 0x36, 0x4d, 0x41, 0x69, 0x35, + 0x75, 0x64, 0x49, 0x4a, 0x4c, 0x56, 0x66, 0x67, 0x58, 0x51, 0x42, 0x67, + 0x52, 0x79, 0x58, 0x33, 0x67, 0x6c, 0x53, 0x37, 0x2f, 0x72, 0x48, 0x38, + 0x59, 0x62, 0x72, 0x72, 0x4e, 0x59, 0x39, 0x49, 0x6f, 0x70, 0x31, 0x4b, + 0x63, 0x53, 0x57, 0x58, 0x41, 0x49, 0x43, 0x34, 0x7a, 0x6c, 0x43, 0x6f, + 0x4f, 0x33, 0x74, 0x42, 0x4a, 0x42, 0x0a, 0x39, 0x34, 0x36, 0x34, 0x59, + 0x42, 0x44, 0x2f, 0x52, 0x2b, 0x71, 0x4f, 0x76, 0x56, 0x4d, 0x63, 0x42, + 0x47, 0x78, 0x54, 0x6a, 0x61, 0x62, 0x75, 0x64, 0x69, 0x30, 0x30, 0x6f, + 0x75, 0x67, 0x65, 0x54, 0x67, 0x73, 0x53, 0x37, 0x69, 0x64, 0x44, 0x54, + 0x6d, 0x66, 0x63, 0x34, 0x48, 0x59, 0x49, 0x6c, 0x73, 0x30, 0x45, 0x37, + 0x79, 0x57, 0x71, 0x7a, 0x67, 0x73, 0x70, 0x73, 0x77, 0x73, 0x35, 0x0a, + 0x77, 0x37, 0x4b, 0x34, 0x63, 0x72, 0x53, 0x67, 0x6d, 0x2b, 0x75, 0x33, + 0x6f, 0x79, 0x70, 0x56, 0x69, 0x55, 0x53, 0x72, 0x65, 0x32, 0x71, 0x53, + 0x76, 0x41, 0x48, 0x54, 0x43, 0x35, 0x67, 0x58, 0x74, 0x68, 0x38, 0x4c, + 0x56, 0x43, 0x6e, 0x44, 0x5a, 0x75, 0x41, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x52, 0x53, 0x41, 0x20, 0x50, 0x52, + 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, + ]), + public: undefined, + publicOrig: undefined + }, + what: 'Encrypted RSA private key (OpenSSH format)' + }, + { source: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAYQDl6dxL+hgxwGNhZrq18vArbNB0UqNxvclf+ociRLlnR5O6r/czAhySO+eOc5SF7wexZzWo/COQ37tEi9reTucYFNQQWFvx4E8CRFP+UPR6hQX0fxoLSF3lxQFJ+32/rS0=', + expected: { + fulltype: 'ssh-rsa', + type: 'rsa', + curve: undefined, + extra: undefined, + comment: undefined, + encryption: undefined, + private: undefined, + privateOrig: undefined, + public: new Buffer([ + 0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2d, 0x72, 0x73, 0x61, 0x00, + 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x61, 0x00, 0xe5, + 0xe9, 0xdc, 0x4b, 0xfa, 0x18, 0x31, 0xc0, 0x63, 0x61, 0x66, 0xba, 0xb5, + 0xf2, 0xf0, 0x2b, 0x6c, 0xd0, 0x74, 0x52, 0xa3, 0x71, 0xbd, 0xc9, 0x5f, + 0xfa, 0x87, 0x22, 0x44, 0xb9, 0x67, 0x47, 0x93, 0xba, 0xaf, 0xf7, 0x33, + 0x02, 0x1c, 0x92, 0x3b, 0xe7, 0x8e, 0x73, 0x94, 0x85, 0xef, 0x07, 0xb1, + 0x67, 0x35, 0xa8, 0xfc, 0x23, 0x90, 0xdf, 0xbb, 0x44, 0x8b, 0xda, 0xde, + 0x4e, 0xe7, 0x18, 0x14, 0xd4, 0x10, 0x58, 0x5b, 0xf1, 0xe0, 0x4f, 0x02, + 0x44, 0x53, 0xfe, 0x50, 0xf4, 0x7a, 0x85, 0x05, 0xf4, 0x7f, 0x1a, 0x0b, + 0x48, 0x5d, 0xe5, 0xc5, 0x01, 0x49, 0xfb, 0x7d, 0xbf, 0xad, 0x2d, + ]), + publicOrig: new Buffer([ + 0x73, 0x73, 0x68, 0x2d, 0x72, 0x73, 0x61, 0x20, 0x41, 0x41, 0x41, 0x41, + 0x42, 0x33, 0x4e, 0x7a, 0x61, 0x43, 0x31, 0x79, 0x63, 0x32, 0x45, 0x41, + 0x41, 0x41, 0x41, 0x44, 0x41, 0x51, 0x41, 0x42, 0x41, 0x41, 0x41, 0x41, + 0x59, 0x51, 0x44, 0x6c, 0x36, 0x64, 0x78, 0x4c, 0x2b, 0x68, 0x67, 0x78, + 0x77, 0x47, 0x4e, 0x68, 0x5a, 0x72, 0x71, 0x31, 0x38, 0x76, 0x41, 0x72, + 0x62, 0x4e, 0x42, 0x30, 0x55, 0x71, 0x4e, 0x78, 0x76, 0x63, 0x6c, 0x66, + 0x2b, 0x6f, 0x63, 0x69, 0x52, 0x4c, 0x6c, 0x6e, 0x52, 0x35, 0x4f, 0x36, + 0x72, 0x2f, 0x63, 0x7a, 0x41, 0x68, 0x79, 0x53, 0x4f, 0x2b, 0x65, 0x4f, + 0x63, 0x35, 0x53, 0x46, 0x37, 0x77, 0x65, 0x78, 0x5a, 0x7a, 0x57, 0x6f, + 0x2f, 0x43, 0x4f, 0x51, 0x33, 0x37, 0x74, 0x45, 0x69, 0x39, 0x72, 0x65, + 0x54, 0x75, 0x63, 0x59, 0x46, 0x4e, 0x51, 0x51, 0x57, 0x46, 0x76, 0x78, + 0x34, 0x45, 0x38, 0x43, 0x52, 0x46, 0x50, 0x2b, 0x55, 0x50, 0x52, 0x36, + 0x68, 0x51, 0x58, 0x30, 0x66, 0x78, 0x6f, 0x4c, 0x53, 0x46, 0x33, 0x6c, + 0x78, 0x51, 0x46, 0x4a, 0x2b, 0x33, 0x32, 0x2f, 0x72, 0x53, 0x30, 0x3d, + ]) + }, + what: 'RSA public key (OpenSSH format)' + }, + { source: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAYQD3txsEf0HAKElAFUvIXzsM98gfPlIbG4/GlqbYYBulkHu6z0laOdoT14Zx2M+3q+9RjhTZjHxyMfePdcgNK9z98V6tOz5bIQhtMS8tl1Tnw5qZByGqpqOKf665ev62LaM= testing-ssh2-from-node.js', + expected: { + fulltype: 'ssh-rsa', + type: 'rsa', + curve: undefined, + extra: undefined, + comment: 'testing-ssh2-from-node.js', + encryption: undefined, + private: undefined, + privateOrig: undefined, + public: new Buffer([ + 0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2d, 0x72, 0x73, 0x61, 0x00, + 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x61, 0x00, 0xf7, + 0xb7, 0x1b, 0x04, 0x7f, 0x41, 0xc0, 0x28, 0x49, 0x40, 0x15, 0x4b, 0xc8, + 0x5f, 0x3b, 0x0c, 0xf7, 0xc8, 0x1f, 0x3e, 0x52, 0x1b, 0x1b, 0x8f, 0xc6, + 0x96, 0xa6, 0xd8, 0x60, 0x1b, 0xa5, 0x90, 0x7b, 0xba, 0xcf, 0x49, 0x5a, + 0x39, 0xda, 0x13, 0xd7, 0x86, 0x71, 0xd8, 0xcf, 0xb7, 0xab, 0xef, 0x51, + 0x8e, 0x14, 0xd9, 0x8c, 0x7c, 0x72, 0x31, 0xf7, 0x8f, 0x75, 0xc8, 0x0d, + 0x2b, 0xdc, 0xfd, 0xf1, 0x5e, 0xad, 0x3b, 0x3e, 0x5b, 0x21, 0x08, 0x6d, + 0x31, 0x2f, 0x2d, 0x97, 0x54, 0xe7, 0xc3, 0x9a, 0x99, 0x07, 0x21, 0xaa, + 0xa6, 0xa3, 0x8a, 0x7f, 0xae, 0xb9, 0x7a, 0xfe, 0xb6, 0x2d, 0xa3, + ]), + publicOrig: new Buffer([ + 0x73, 0x73, 0x68, 0x2d, 0x72, 0x73, 0x61, 0x20, 0x41, 0x41, 0x41, 0x41, + 0x42, 0x33, 0x4e, 0x7a, 0x61, 0x43, 0x31, 0x79, 0x63, 0x32, 0x45, 0x41, + 0x41, 0x41, 0x41, 0x44, 0x41, 0x51, 0x41, 0x42, 0x41, 0x41, 0x41, 0x41, + 0x59, 0x51, 0x44, 0x33, 0x74, 0x78, 0x73, 0x45, 0x66, 0x30, 0x48, 0x41, + 0x4b, 0x45, 0x6c, 0x41, 0x46, 0x55, 0x76, 0x49, 0x58, 0x7a, 0x73, 0x4d, + 0x39, 0x38, 0x67, 0x66, 0x50, 0x6c, 0x49, 0x62, 0x47, 0x34, 0x2f, 0x47, + 0x6c, 0x71, 0x62, 0x59, 0x59, 0x42, 0x75, 0x6c, 0x6b, 0x48, 0x75, 0x36, + 0x7a, 0x30, 0x6c, 0x61, 0x4f, 0x64, 0x6f, 0x54, 0x31, 0x34, 0x5a, 0x78, + 0x32, 0x4d, 0x2b, 0x33, 0x71, 0x2b, 0x39, 0x52, 0x6a, 0x68, 0x54, 0x5a, + 0x6a, 0x48, 0x78, 0x79, 0x4d, 0x66, 0x65, 0x50, 0x64, 0x63, 0x67, 0x4e, + 0x4b, 0x39, 0x7a, 0x39, 0x38, 0x56, 0x36, 0x74, 0x4f, 0x7a, 0x35, 0x62, + 0x49, 0x51, 0x68, 0x74, 0x4d, 0x53, 0x38, 0x74, 0x6c, 0x31, 0x54, 0x6e, + 0x77, 0x35, 0x71, 0x5a, 0x42, 0x79, 0x47, 0x71, 0x70, 0x71, 0x4f, 0x4b, + 0x66, 0x36, 0x36, 0x35, 0x65, 0x76, 0x36, 0x32, 0x4c, 0x61, 0x4d, 0x3d, + 0x20, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2d, 0x73, 0x73, 0x68, + 0x32, 0x2d, 0x66, 0x72, 0x6f, 0x6d, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x6a, 0x73, + ]) + }, + what: 'RSA public key with comment (OpenSSH format)' + }, + { source: [ + '-----BEGIN DSA PRIVATE KEY-----', + 'MIIBuwIBAAKBgQD7v1kR31D2NhZIzOjJL1hPzvw79K3eWZqQEgqKmeB+P9MhOx51', + 'MOZrvs3hZoYqmsNxT/Y29EwQ+o+SXpTYjJhw/s2vR0AeJBj32l8weD804+T+S8yr', + 'MJBdgsc5AbV2XYKnsNzl65kAEOLPCobUNysKqYnJ8naYCYL3jjwGhW36iwIVANqh', + 'gZgvnVpVXyYx1GlceA5/8mI1AoGBAOyjuQhGoOW4hILR02WrqwCEPqhRyMp87dMU', + '9z0PQKKrACmiQpEUawvtR4aMB7Xzy+f6MRLwdonQISzswopa7Gwl3CYLiOdKFFIQ', + 'zDdymwGovTjN2fQm8v/UHdafZBPImGBDzf+iykNBhZc7UP1rciMzKOnT3BTF/al8', + 'hhBy0bjsAoGAYrykryPYWUGArKS6NO9Ijtwc7SbbNXZCuBcl6hc1Hdr1UEEKQcsW', + '5fajF5Ut9ZLwcggsWSKZtZk9NA7xybmObuDEU7oiFFNRAbBkam/v/3a3bwvSHGKg', + 'q15cvC313zg1ii9NXylvBIoIS8EWfekl1LMvHC7NdJ41wPYhhmPrUk4CFHJjavJH', + 'kb6tDtemyiAq3N9aQj/D', + '-----END DSA PRIVATE KEY-----' + ].join('\n'), + expected: { + fulltype: 'ssh-dss', + type: 'dss', + curve: undefined, + extra: undefined, + comment: undefined, + encryption: undefined, + private: new Buffer([ + 0x30, 0x82, 0x01, 0xbb, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xfb, + 0xbf, 0x59, 0x11, 0xdf, 0x50, 0xf6, 0x36, 0x16, 0x48, 0xcc, 0xe8, 0xc9, + 0x2f, 0x58, 0x4f, 0xce, 0xfc, 0x3b, 0xf4, 0xad, 0xde, 0x59, 0x9a, 0x90, + 0x12, 0x0a, 0x8a, 0x99, 0xe0, 0x7e, 0x3f, 0xd3, 0x21, 0x3b, 0x1e, 0x75, + 0x30, 0xe6, 0x6b, 0xbe, 0xcd, 0xe1, 0x66, 0x86, 0x2a, 0x9a, 0xc3, 0x71, + 0x4f, 0xf6, 0x36, 0xf4, 0x4c, 0x10, 0xfa, 0x8f, 0x92, 0x5e, 0x94, 0xd8, + 0x8c, 0x98, 0x70, 0xfe, 0xcd, 0xaf, 0x47, 0x40, 0x1e, 0x24, 0x18, 0xf7, + 0xda, 0x5f, 0x30, 0x78, 0x3f, 0x34, 0xe3, 0xe4, 0xfe, 0x4b, 0xcc, 0xab, + 0x30, 0x90, 0x5d, 0x82, 0xc7, 0x39, 0x01, 0xb5, 0x76, 0x5d, 0x82, 0xa7, + 0xb0, 0xdc, 0xe5, 0xeb, 0x99, 0x00, 0x10, 0xe2, 0xcf, 0x0a, 0x86, 0xd4, + 0x37, 0x2b, 0x0a, 0xa9, 0x89, 0xc9, 0xf2, 0x76, 0x98, 0x09, 0x82, 0xf7, + 0x8e, 0x3c, 0x06, 0x85, 0x6d, 0xfa, 0x8b, 0x02, 0x15, 0x00, 0xda, 0xa1, + 0x81, 0x98, 0x2f, 0x9d, 0x5a, 0x55, 0x5f, 0x26, 0x31, 0xd4, 0x69, 0x5c, + 0x78, 0x0e, 0x7f, 0xf2, 0x62, 0x35, 0x02, 0x81, 0x81, 0x00, 0xec, 0xa3, + 0xb9, 0x08, 0x46, 0xa0, 0xe5, 0xb8, 0x84, 0x82, 0xd1, 0xd3, 0x65, 0xab, + 0xab, 0x00, 0x84, 0x3e, 0xa8, 0x51, 0xc8, 0xca, 0x7c, 0xed, 0xd3, 0x14, + 0xf7, 0x3d, 0x0f, 0x40, 0xa2, 0xab, 0x00, 0x29, 0xa2, 0x42, 0x91, 0x14, + 0x6b, 0x0b, 0xed, 0x47, 0x86, 0x8c, 0x07, 0xb5, 0xf3, 0xcb, 0xe7, 0xfa, + 0x31, 0x12, 0xf0, 0x76, 0x89, 0xd0, 0x21, 0x2c, 0xec, 0xc2, 0x8a, 0x5a, + 0xec, 0x6c, 0x25, 0xdc, 0x26, 0x0b, 0x88, 0xe7, 0x4a, 0x14, 0x52, 0x10, + 0xcc, 0x37, 0x72, 0x9b, 0x01, 0xa8, 0xbd, 0x38, 0xcd, 0xd9, 0xf4, 0x26, + 0xf2, 0xff, 0xd4, 0x1d, 0xd6, 0x9f, 0x64, 0x13, 0xc8, 0x98, 0x60, 0x43, + 0xcd, 0xff, 0xa2, 0xca, 0x43, 0x41, 0x85, 0x97, 0x3b, 0x50, 0xfd, 0x6b, + 0x72, 0x23, 0x33, 0x28, 0xe9, 0xd3, 0xdc, 0x14, 0xc5, 0xfd, 0xa9, 0x7c, + 0x86, 0x10, 0x72, 0xd1, 0xb8, 0xec, 0x02, 0x81, 0x80, 0x62, 0xbc, 0xa4, + 0xaf, 0x23, 0xd8, 0x59, 0x41, 0x80, 0xac, 0xa4, 0xba, 0x34, 0xef, 0x48, + 0x8e, 0xdc, 0x1c, 0xed, 0x26, 0xdb, 0x35, 0x76, 0x42, 0xb8, 0x17, 0x25, + 0xea, 0x17, 0x35, 0x1d, 0xda, 0xf5, 0x50, 0x41, 0x0a, 0x41, 0xcb, 0x16, + 0xe5, 0xf6, 0xa3, 0x17, 0x95, 0x2d, 0xf5, 0x92, 0xf0, 0x72, 0x08, 0x2c, + 0x59, 0x22, 0x99, 0xb5, 0x99, 0x3d, 0x34, 0x0e, 0xf1, 0xc9, 0xb9, 0x8e, + 0x6e, 0xe0, 0xc4, 0x53, 0xba, 0x22, 0x14, 0x53, 0x51, 0x01, 0xb0, 0x64, + 0x6a, 0x6f, 0xef, 0xff, 0x76, 0xb7, 0x6f, 0x0b, 0xd2, 0x1c, 0x62, 0xa0, + 0xab, 0x5e, 0x5c, 0xbc, 0x2d, 0xf5, 0xdf, 0x38, 0x35, 0x8a, 0x2f, 0x4d, + 0x5f, 0x29, 0x6f, 0x04, 0x8a, 0x08, 0x4b, 0xc1, 0x16, 0x7d, 0xe9, 0x25, + 0xd4, 0xb3, 0x2f, 0x1c, 0x2e, 0xcd, 0x74, 0x9e, 0x35, 0xc0, 0xf6, 0x21, + 0x86, 0x63, 0xeb, 0x52, 0x4e, 0x02, 0x14, 0x72, 0x63, 0x6a, 0xf2, 0x47, + 0x91, 0xbe, 0xad, 0x0e, 0xd7, 0xa6, 0xca, 0x20, 0x2a, 0xdc, 0xdf, 0x5a, + 0x42, 0x3f, 0xc3, + ]), + privateOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x44, + 0x53, 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, + 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x42, + 0x75, 0x77, 0x49, 0x42, 0x41, 0x41, 0x4b, 0x42, 0x67, 0x51, 0x44, 0x37, + 0x76, 0x31, 0x6b, 0x52, 0x33, 0x31, 0x44, 0x32, 0x4e, 0x68, 0x5a, 0x49, + 0x7a, 0x4f, 0x6a, 0x4a, 0x4c, 0x31, 0x68, 0x50, 0x7a, 0x76, 0x77, 0x37, + 0x39, 0x4b, 0x33, 0x65, 0x57, 0x5a, 0x71, 0x51, 0x45, 0x67, 0x71, 0x4b, + 0x6d, 0x65, 0x42, 0x2b, 0x50, 0x39, 0x4d, 0x68, 0x4f, 0x78, 0x35, 0x31, + 0x0a, 0x4d, 0x4f, 0x5a, 0x72, 0x76, 0x73, 0x33, 0x68, 0x5a, 0x6f, 0x59, + 0x71, 0x6d, 0x73, 0x4e, 0x78, 0x54, 0x2f, 0x59, 0x32, 0x39, 0x45, 0x77, + 0x51, 0x2b, 0x6f, 0x2b, 0x53, 0x58, 0x70, 0x54, 0x59, 0x6a, 0x4a, 0x68, + 0x77, 0x2f, 0x73, 0x32, 0x76, 0x52, 0x30, 0x41, 0x65, 0x4a, 0x42, 0x6a, + 0x33, 0x32, 0x6c, 0x38, 0x77, 0x65, 0x44, 0x38, 0x30, 0x34, 0x2b, 0x54, + 0x2b, 0x53, 0x38, 0x79, 0x72, 0x0a, 0x4d, 0x4a, 0x42, 0x64, 0x67, 0x73, + 0x63, 0x35, 0x41, 0x62, 0x56, 0x32, 0x58, 0x59, 0x4b, 0x6e, 0x73, 0x4e, + 0x7a, 0x6c, 0x36, 0x35, 0x6b, 0x41, 0x45, 0x4f, 0x4c, 0x50, 0x43, 0x6f, + 0x62, 0x55, 0x4e, 0x79, 0x73, 0x4b, 0x71, 0x59, 0x6e, 0x4a, 0x38, 0x6e, + 0x61, 0x59, 0x43, 0x59, 0x4c, 0x33, 0x6a, 0x6a, 0x77, 0x47, 0x68, 0x57, + 0x33, 0x36, 0x69, 0x77, 0x49, 0x56, 0x41, 0x4e, 0x71, 0x68, 0x0a, 0x67, + 0x5a, 0x67, 0x76, 0x6e, 0x56, 0x70, 0x56, 0x58, 0x79, 0x59, 0x78, 0x31, + 0x47, 0x6c, 0x63, 0x65, 0x41, 0x35, 0x2f, 0x38, 0x6d, 0x49, 0x31, 0x41, + 0x6f, 0x47, 0x42, 0x41, 0x4f, 0x79, 0x6a, 0x75, 0x51, 0x68, 0x47, 0x6f, + 0x4f, 0x57, 0x34, 0x68, 0x49, 0x4c, 0x52, 0x30, 0x32, 0x57, 0x72, 0x71, + 0x77, 0x43, 0x45, 0x50, 0x71, 0x68, 0x52, 0x79, 0x4d, 0x70, 0x38, 0x37, + 0x64, 0x4d, 0x55, 0x0a, 0x39, 0x7a, 0x30, 0x50, 0x51, 0x4b, 0x4b, 0x72, + 0x41, 0x43, 0x6d, 0x69, 0x51, 0x70, 0x45, 0x55, 0x61, 0x77, 0x76, 0x74, + 0x52, 0x34, 0x61, 0x4d, 0x42, 0x37, 0x58, 0x7a, 0x79, 0x2b, 0x66, 0x36, + 0x4d, 0x52, 0x4c, 0x77, 0x64, 0x6f, 0x6e, 0x51, 0x49, 0x53, 0x7a, 0x73, + 0x77, 0x6f, 0x70, 0x61, 0x37, 0x47, 0x77, 0x6c, 0x33, 0x43, 0x59, 0x4c, + 0x69, 0x4f, 0x64, 0x4b, 0x46, 0x46, 0x49, 0x51, 0x0a, 0x7a, 0x44, 0x64, + 0x79, 0x6d, 0x77, 0x47, 0x6f, 0x76, 0x54, 0x6a, 0x4e, 0x32, 0x66, 0x51, + 0x6d, 0x38, 0x76, 0x2f, 0x55, 0x48, 0x64, 0x61, 0x66, 0x5a, 0x42, 0x50, + 0x49, 0x6d, 0x47, 0x42, 0x44, 0x7a, 0x66, 0x2b, 0x69, 0x79, 0x6b, 0x4e, + 0x42, 0x68, 0x5a, 0x63, 0x37, 0x55, 0x50, 0x31, 0x72, 0x63, 0x69, 0x4d, + 0x7a, 0x4b, 0x4f, 0x6e, 0x54, 0x33, 0x42, 0x54, 0x46, 0x2f, 0x61, 0x6c, + 0x38, 0x0a, 0x68, 0x68, 0x42, 0x79, 0x30, 0x62, 0x6a, 0x73, 0x41, 0x6f, + 0x47, 0x41, 0x59, 0x72, 0x79, 0x6b, 0x72, 0x79, 0x50, 0x59, 0x57, 0x55, + 0x47, 0x41, 0x72, 0x4b, 0x53, 0x36, 0x4e, 0x4f, 0x39, 0x49, 0x6a, 0x74, + 0x77, 0x63, 0x37, 0x53, 0x62, 0x62, 0x4e, 0x58, 0x5a, 0x43, 0x75, 0x42, + 0x63, 0x6c, 0x36, 0x68, 0x63, 0x31, 0x48, 0x64, 0x72, 0x31, 0x55, 0x45, + 0x45, 0x4b, 0x51, 0x63, 0x73, 0x57, 0x0a, 0x35, 0x66, 0x61, 0x6a, 0x46, + 0x35, 0x55, 0x74, 0x39, 0x5a, 0x4c, 0x77, 0x63, 0x67, 0x67, 0x73, 0x57, + 0x53, 0x4b, 0x5a, 0x74, 0x5a, 0x6b, 0x39, 0x4e, 0x41, 0x37, 0x78, 0x79, + 0x62, 0x6d, 0x4f, 0x62, 0x75, 0x44, 0x45, 0x55, 0x37, 0x6f, 0x69, 0x46, + 0x46, 0x4e, 0x52, 0x41, 0x62, 0x42, 0x6b, 0x61, 0x6d, 0x2f, 0x76, 0x2f, + 0x33, 0x61, 0x33, 0x62, 0x77, 0x76, 0x53, 0x48, 0x47, 0x4b, 0x67, 0x0a, + 0x71, 0x31, 0x35, 0x63, 0x76, 0x43, 0x33, 0x31, 0x33, 0x7a, 0x67, 0x31, + 0x69, 0x69, 0x39, 0x4e, 0x58, 0x79, 0x6c, 0x76, 0x42, 0x49, 0x6f, 0x49, + 0x53, 0x38, 0x45, 0x57, 0x66, 0x65, 0x6b, 0x6c, 0x31, 0x4c, 0x4d, 0x76, + 0x48, 0x43, 0x37, 0x4e, 0x64, 0x4a, 0x34, 0x31, 0x77, 0x50, 0x59, 0x68, + 0x68, 0x6d, 0x50, 0x72, 0x55, 0x6b, 0x34, 0x43, 0x46, 0x48, 0x4a, 0x6a, + 0x61, 0x76, 0x4a, 0x48, 0x0a, 0x6b, 0x62, 0x36, 0x74, 0x44, 0x74, 0x65, + 0x6d, 0x79, 0x69, 0x41, 0x71, 0x33, 0x4e, 0x39, 0x61, 0x51, 0x6a, 0x2f, + 0x44, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x44, + 0x53, 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, + 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + ]), + public: undefined, + publicOrig: undefined + }, + what: 'Unencrypted DSA private key (OpenSSH format)' + }, + { source: [ + '-----BEGIN DSA PRIVATE KEY-----', + 'Proc-Type: 4,ENCRYPTED', + 'DEK-Info: AES-128-CBC,D6218FEC397F57918B06DC3F9EC33487', + '', + 'OjtbW9WChM2baMDRXW/IYhmqAmlaulb8pQd0rDcFYGrAS/5PnA96R3X6f9tdooSv', + 'uPrQ37oCI7FfDrRmVy6pn6QOLxLZHk7LViBAA7q8VytRHUyezauicTkhc6/nfxQU', + 'tYN5dNajSl/aFuv/IitaYtuG2ORvXLLJhR3sYe5fs2ai14qtULdWxtrZ4cACXPSz', + 'Ij29/lUfeBIYxNFFDF5hgsyO+jHLHO8bJCgXLCEb1o/Im68kQT3LjmvLbdhVM2+V', + '5c+YVDW/yXKpaSDNqctJFsETP3SsI5k9PVijSeND4U27W9HAoukJmG8jNBXmMOKW', + 'MtOEp0Yw5+fu0OPTACMcK7UoiN90RTFLNcDT9kKjeQwqk37sZBNyOpnQ57Mu6YWX', + 'BS5nnT4bK/WpyWUgGJ+MVzcp6pErBUy3SxlV2LN/LIZq+YzME55sygtwNSuVhpBH', + '+9UwrUIlaT8Ru//OdRKY5Vp8AqomjlAzCkBxnmC9XhVB0r4zqsqgVyzSfsX+oGLe', + 'dbixpbeMXe3WoAowx6LmqojuP46MIL80/9BH6Xr51UqJj156bYXashJtgpYaAQIn', + '8YB9sXf4S027sgHxK0Xanw==', + '-----END DSA PRIVATE KEY-----' + ].join('\n'), + expected: { + fulltype: undefined, + type: 'dss', + curve: undefined, + extra: [ 'D6218FEC397F57918B06DC3F9EC33487' ], + comment: undefined, + encryption: 'aes-128-cbc', + private: new Buffer([ + 0x3a, 0x3b, 0x5b, 0x5b, 0xd5, 0x82, 0x84, 0xcd, 0x9b, 0x68, 0xc0, 0xd1, + 0x5d, 0x6f, 0xc8, 0x62, 0x19, 0xaa, 0x02, 0x69, 0x5a, 0xba, 0x56, 0xfc, + 0xa5, 0x07, 0x74, 0xac, 0x37, 0x05, 0x60, 0x6a, 0xc0, 0x4b, 0xfe, 0x4f, + 0x9c, 0x0f, 0x7a, 0x47, 0x75, 0xfa, 0x7f, 0xdb, 0x5d, 0xa2, 0x84, 0xaf, + 0xb8, 0xfa, 0xd0, 0xdf, 0xba, 0x02, 0x23, 0xb1, 0x5f, 0x0e, 0xb4, 0x66, + 0x57, 0x2e, 0xa9, 0x9f, 0xa4, 0x0e, 0x2f, 0x12, 0xd9, 0x1e, 0x4e, 0xcb, + 0x56, 0x20, 0x40, 0x03, 0xba, 0xbc, 0x57, 0x2b, 0x51, 0x1d, 0x4c, 0x9e, + 0xcd, 0xab, 0xa2, 0x71, 0x39, 0x21, 0x73, 0xaf, 0xe7, 0x7f, 0x14, 0x14, + 0xb5, 0x83, 0x79, 0x74, 0xd6, 0xa3, 0x4a, 0x5f, 0xda, 0x16, 0xeb, 0xff, + 0x22, 0x2b, 0x5a, 0x62, 0xdb, 0x86, 0xd8, 0xe4, 0x6f, 0x5c, 0xb2, 0xc9, + 0x85, 0x1d, 0xec, 0x61, 0xee, 0x5f, 0xb3, 0x66, 0xa2, 0xd7, 0x8a, 0xad, + 0x50, 0xb7, 0x56, 0xc6, 0xda, 0xd9, 0xe1, 0xc0, 0x02, 0x5c, 0xf4, 0xb3, + 0x22, 0x3d, 0xbd, 0xfe, 0x55, 0x1f, 0x78, 0x12, 0x18, 0xc4, 0xd1, 0x45, + 0x0c, 0x5e, 0x61, 0x82, 0xcc, 0x8e, 0xfa, 0x31, 0xcb, 0x1c, 0xef, 0x1b, + 0x24, 0x28, 0x17, 0x2c, 0x21, 0x1b, 0xd6, 0x8f, 0xc8, 0x9b, 0xaf, 0x24, + 0x41, 0x3d, 0xcb, 0x8e, 0x6b, 0xcb, 0x6d, 0xd8, 0x55, 0x33, 0x6f, 0x95, + 0xe5, 0xcf, 0x98, 0x54, 0x35, 0xbf, 0xc9, 0x72, 0xa9, 0x69, 0x20, 0xcd, + 0xa9, 0xcb, 0x49, 0x16, 0xc1, 0x13, 0x3f, 0x74, 0xac, 0x23, 0x99, 0x3d, + 0x3d, 0x58, 0xa3, 0x49, 0xe3, 0x43, 0xe1, 0x4d, 0xbb, 0x5b, 0xd1, 0xc0, + 0xa2, 0xe9, 0x09, 0x98, 0x6f, 0x23, 0x34, 0x15, 0xe6, 0x30, 0xe2, 0x96, + 0x32, 0xd3, 0x84, 0xa7, 0x46, 0x30, 0xe7, 0xe7, 0xee, 0xd0, 0xe3, 0xd3, + 0x00, 0x23, 0x1c, 0x2b, 0xb5, 0x28, 0x88, 0xdf, 0x74, 0x45, 0x31, 0x4b, + 0x35, 0xc0, 0xd3, 0xf6, 0x42, 0xa3, 0x79, 0x0c, 0x2a, 0x93, 0x7e, 0xec, + 0x64, 0x13, 0x72, 0x3a, 0x99, 0xd0, 0xe7, 0xb3, 0x2e, 0xe9, 0x85, 0x97, + 0x05, 0x2e, 0x67, 0x9d, 0x3e, 0x1b, 0x2b, 0xf5, 0xa9, 0xc9, 0x65, 0x20, + 0x18, 0x9f, 0x8c, 0x57, 0x37, 0x29, 0xea, 0x91, 0x2b, 0x05, 0x4c, 0xb7, + 0x4b, 0x19, 0x55, 0xd8, 0xb3, 0x7f, 0x2c, 0x86, 0x6a, 0xf9, 0x8c, 0xcc, + 0x13, 0x9e, 0x6c, 0xca, 0x0b, 0x70, 0x35, 0x2b, 0x95, 0x86, 0x90, 0x47, + 0xfb, 0xd5, 0x30, 0xad, 0x42, 0x25, 0x69, 0x3f, 0x11, 0xbb, 0xff, 0xce, + 0x75, 0x12, 0x98, 0xe5, 0x5a, 0x7c, 0x02, 0xaa, 0x26, 0x8e, 0x50, 0x33, + 0x0a, 0x40, 0x71, 0x9e, 0x60, 0xbd, 0x5e, 0x15, 0x41, 0xd2, 0xbe, 0x33, + 0xaa, 0xca, 0xa0, 0x57, 0x2c, 0xd2, 0x7e, 0xc5, 0xfe, 0xa0, 0x62, 0xde, + 0x75, 0xb8, 0xb1, 0xa5, 0xb7, 0x8c, 0x5d, 0xed, 0xd6, 0xa0, 0x0a, 0x30, + 0xc7, 0xa2, 0xe6, 0xaa, 0x88, 0xee, 0x3f, 0x8e, 0x8c, 0x20, 0xbf, 0x34, + 0xff, 0xd0, 0x47, 0xe9, 0x7a, 0xf9, 0xd5, 0x4a, 0x89, 0x8f, 0x5e, 0x7a, + 0x6d, 0x85, 0xda, 0xb2, 0x12, 0x6d, 0x82, 0x96, 0x1a, 0x01, 0x02, 0x27, + 0xf1, 0x80, 0x7d, 0xb1, 0x77, 0xf8, 0x4b, 0x4d, 0xbb, 0xb2, 0x01, 0xf1, + 0x2b, 0x45, 0xda, 0x9f, + ]), + privateOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x44, + 0x53, 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, + 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x50, 0x72, 0x6f, 0x63, + 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x34, 0x2c, 0x45, 0x4e, 0x43, + 0x52, 0x59, 0x50, 0x54, 0x45, 0x44, 0x0a, 0x44, 0x45, 0x4b, 0x2d, 0x49, + 0x6e, 0x66, 0x6f, 0x3a, 0x20, 0x41, 0x45, 0x53, 0x2d, 0x31, 0x32, 0x38, + 0x2d, 0x43, 0x42, 0x43, 0x2c, 0x44, 0x36, 0x32, 0x31, 0x38, 0x46, 0x45, + 0x43, 0x33, 0x39, 0x37, 0x46, 0x35, 0x37, 0x39, 0x31, 0x38, 0x42, 0x30, + 0x36, 0x44, 0x43, 0x33, 0x46, 0x39, 0x45, 0x43, 0x33, 0x33, 0x34, 0x38, + 0x37, 0x0a, 0x0a, 0x4f, 0x6a, 0x74, 0x62, 0x57, 0x39, 0x57, 0x43, 0x68, + 0x4d, 0x32, 0x62, 0x61, 0x4d, 0x44, 0x52, 0x58, 0x57, 0x2f, 0x49, 0x59, + 0x68, 0x6d, 0x71, 0x41, 0x6d, 0x6c, 0x61, 0x75, 0x6c, 0x62, 0x38, 0x70, + 0x51, 0x64, 0x30, 0x72, 0x44, 0x63, 0x46, 0x59, 0x47, 0x72, 0x41, 0x53, + 0x2f, 0x35, 0x50, 0x6e, 0x41, 0x39, 0x36, 0x52, 0x33, 0x58, 0x36, 0x66, + 0x39, 0x74, 0x64, 0x6f, 0x6f, 0x53, 0x76, 0x0a, 0x75, 0x50, 0x72, 0x51, + 0x33, 0x37, 0x6f, 0x43, 0x49, 0x37, 0x46, 0x66, 0x44, 0x72, 0x52, 0x6d, + 0x56, 0x79, 0x36, 0x70, 0x6e, 0x36, 0x51, 0x4f, 0x4c, 0x78, 0x4c, 0x5a, + 0x48, 0x6b, 0x37, 0x4c, 0x56, 0x69, 0x42, 0x41, 0x41, 0x37, 0x71, 0x38, + 0x56, 0x79, 0x74, 0x52, 0x48, 0x55, 0x79, 0x65, 0x7a, 0x61, 0x75, 0x69, + 0x63, 0x54, 0x6b, 0x68, 0x63, 0x36, 0x2f, 0x6e, 0x66, 0x78, 0x51, 0x55, + 0x0a, 0x74, 0x59, 0x4e, 0x35, 0x64, 0x4e, 0x61, 0x6a, 0x53, 0x6c, 0x2f, + 0x61, 0x46, 0x75, 0x76, 0x2f, 0x49, 0x69, 0x74, 0x61, 0x59, 0x74, 0x75, + 0x47, 0x32, 0x4f, 0x52, 0x76, 0x58, 0x4c, 0x4c, 0x4a, 0x68, 0x52, 0x33, + 0x73, 0x59, 0x65, 0x35, 0x66, 0x73, 0x32, 0x61, 0x69, 0x31, 0x34, 0x71, + 0x74, 0x55, 0x4c, 0x64, 0x57, 0x78, 0x74, 0x72, 0x5a, 0x34, 0x63, 0x41, + 0x43, 0x58, 0x50, 0x53, 0x7a, 0x0a, 0x49, 0x6a, 0x32, 0x39, 0x2f, 0x6c, + 0x55, 0x66, 0x65, 0x42, 0x49, 0x59, 0x78, 0x4e, 0x46, 0x46, 0x44, 0x46, + 0x35, 0x68, 0x67, 0x73, 0x79, 0x4f, 0x2b, 0x6a, 0x48, 0x4c, 0x48, 0x4f, + 0x38, 0x62, 0x4a, 0x43, 0x67, 0x58, 0x4c, 0x43, 0x45, 0x62, 0x31, 0x6f, + 0x2f, 0x49, 0x6d, 0x36, 0x38, 0x6b, 0x51, 0x54, 0x33, 0x4c, 0x6a, 0x6d, + 0x76, 0x4c, 0x62, 0x64, 0x68, 0x56, 0x4d, 0x32, 0x2b, 0x56, 0x0a, 0x35, + 0x63, 0x2b, 0x59, 0x56, 0x44, 0x57, 0x2f, 0x79, 0x58, 0x4b, 0x70, 0x61, + 0x53, 0x44, 0x4e, 0x71, 0x63, 0x74, 0x4a, 0x46, 0x73, 0x45, 0x54, 0x50, + 0x33, 0x53, 0x73, 0x49, 0x35, 0x6b, 0x39, 0x50, 0x56, 0x69, 0x6a, 0x53, + 0x65, 0x4e, 0x44, 0x34, 0x55, 0x32, 0x37, 0x57, 0x39, 0x48, 0x41, 0x6f, + 0x75, 0x6b, 0x4a, 0x6d, 0x47, 0x38, 0x6a, 0x4e, 0x42, 0x58, 0x6d, 0x4d, + 0x4f, 0x4b, 0x57, 0x0a, 0x4d, 0x74, 0x4f, 0x45, 0x70, 0x30, 0x59, 0x77, + 0x35, 0x2b, 0x66, 0x75, 0x30, 0x4f, 0x50, 0x54, 0x41, 0x43, 0x4d, 0x63, + 0x4b, 0x37, 0x55, 0x6f, 0x69, 0x4e, 0x39, 0x30, 0x52, 0x54, 0x46, 0x4c, + 0x4e, 0x63, 0x44, 0x54, 0x39, 0x6b, 0x4b, 0x6a, 0x65, 0x51, 0x77, 0x71, + 0x6b, 0x33, 0x37, 0x73, 0x5a, 0x42, 0x4e, 0x79, 0x4f, 0x70, 0x6e, 0x51, + 0x35, 0x37, 0x4d, 0x75, 0x36, 0x59, 0x57, 0x58, 0x0a, 0x42, 0x53, 0x35, + 0x6e, 0x6e, 0x54, 0x34, 0x62, 0x4b, 0x2f, 0x57, 0x70, 0x79, 0x57, 0x55, + 0x67, 0x47, 0x4a, 0x2b, 0x4d, 0x56, 0x7a, 0x63, 0x70, 0x36, 0x70, 0x45, + 0x72, 0x42, 0x55, 0x79, 0x33, 0x53, 0x78, 0x6c, 0x56, 0x32, 0x4c, 0x4e, + 0x2f, 0x4c, 0x49, 0x5a, 0x71, 0x2b, 0x59, 0x7a, 0x4d, 0x45, 0x35, 0x35, + 0x73, 0x79, 0x67, 0x74, 0x77, 0x4e, 0x53, 0x75, 0x56, 0x68, 0x70, 0x42, + 0x48, 0x0a, 0x2b, 0x39, 0x55, 0x77, 0x72, 0x55, 0x49, 0x6c, 0x61, 0x54, + 0x38, 0x52, 0x75, 0x2f, 0x2f, 0x4f, 0x64, 0x52, 0x4b, 0x59, 0x35, 0x56, + 0x70, 0x38, 0x41, 0x71, 0x6f, 0x6d, 0x6a, 0x6c, 0x41, 0x7a, 0x43, 0x6b, + 0x42, 0x78, 0x6e, 0x6d, 0x43, 0x39, 0x58, 0x68, 0x56, 0x42, 0x30, 0x72, + 0x34, 0x7a, 0x71, 0x73, 0x71, 0x67, 0x56, 0x79, 0x7a, 0x53, 0x66, 0x73, + 0x58, 0x2b, 0x6f, 0x47, 0x4c, 0x65, 0x0a, 0x64, 0x62, 0x69, 0x78, 0x70, + 0x62, 0x65, 0x4d, 0x58, 0x65, 0x33, 0x57, 0x6f, 0x41, 0x6f, 0x77, 0x78, + 0x36, 0x4c, 0x6d, 0x71, 0x6f, 0x6a, 0x75, 0x50, 0x34, 0x36, 0x4d, 0x49, + 0x4c, 0x38, 0x30, 0x2f, 0x39, 0x42, 0x48, 0x36, 0x58, 0x72, 0x35, 0x31, + 0x55, 0x71, 0x4a, 0x6a, 0x31, 0x35, 0x36, 0x62, 0x59, 0x58, 0x61, 0x73, + 0x68, 0x4a, 0x74, 0x67, 0x70, 0x59, 0x61, 0x41, 0x51, 0x49, 0x6e, 0x0a, + 0x38, 0x59, 0x42, 0x39, 0x73, 0x58, 0x66, 0x34, 0x53, 0x30, 0x32, 0x37, + 0x73, 0x67, 0x48, 0x78, 0x4b, 0x30, 0x58, 0x61, 0x6e, 0x77, 0x3d, 0x3d, + 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x44, 0x53, + 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, + 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + ]), + public: undefined, + publicOrig: undefined + }, + what: 'Encrypted DSA private key (OpenSSH format)' + }, + { source: 'ssh-dss AAAAB3NzaC1kc3MAAACBAL1FzdhtSYN22YgbInypxa//RyKiZAvWxNzDKNF0cYvabH6ESjdwdEcW96H7pHaKb69hoCHKZzfWmdpj93CcezGnorWvUaO4nAvbR+l/gH+AEYzHmJsECvM/nWnmPltwbvrPi/NmXCNf5aeqQlPbL44vZZjFRcCEwOomGY2FWUKJAAAAFQDBD5Y6VM8slL2I/HhqTmnoVFuGmQAAAIAUkwKajnUklN4CX/ZWEhIOZWCRa6ZKCosICBc/yC4RGJldqsXaM0PCmdy0dmcv0XuOZ4Nb92aiZnWdGRXTN5KJ405WVOQLBB3LpebA6qeyDGiVt/iPOxgJGZy0LIWiqWuzAAf199cQ2BkWmGTC6AAJi1depXC+KVAP+HwXOLjSUAAAAIBeoyKKEiVDQOpB0KAr5RLH3/+5BP+mR+52gTAbxZbxQPYyH7mqq2/PI1A0bjnvnLe45a/iVumoIjP/atMtVJ6w103Ex5JGMwVB7uZBWeyJ4m3MqQdPf1/+r+UCoOaL7stK3rWeTCydb82z34ejX0dZobAPGj2F7SyZy7jM8THgcw==', + expected: { + fulltype: 'ssh-dss', + type: 'dss', + curve: undefined, + extra: undefined, + comment: undefined, + encryption: undefined, + private: undefined, + privateOrig: undefined, + public: new Buffer([ + 0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2d, 0x64, 0x73, 0x73, 0x00, + 0x00, 0x00, 0x81, 0x00, 0xbd, 0x45, 0xcd, 0xd8, 0x6d, 0x49, 0x83, 0x76, + 0xd9, 0x88, 0x1b, 0x22, 0x7c, 0xa9, 0xc5, 0xaf, 0xff, 0x47, 0x22, 0xa2, + 0x64, 0x0b, 0xd6, 0xc4, 0xdc, 0xc3, 0x28, 0xd1, 0x74, 0x71, 0x8b, 0xda, + 0x6c, 0x7e, 0x84, 0x4a, 0x37, 0x70, 0x74, 0x47, 0x16, 0xf7, 0xa1, 0xfb, + 0xa4, 0x76, 0x8a, 0x6f, 0xaf, 0x61, 0xa0, 0x21, 0xca, 0x67, 0x37, 0xd6, + 0x99, 0xda, 0x63, 0xf7, 0x70, 0x9c, 0x7b, 0x31, 0xa7, 0xa2, 0xb5, 0xaf, + 0x51, 0xa3, 0xb8, 0x9c, 0x0b, 0xdb, 0x47, 0xe9, 0x7f, 0x80, 0x7f, 0x80, + 0x11, 0x8c, 0xc7, 0x98, 0x9b, 0x04, 0x0a, 0xf3, 0x3f, 0x9d, 0x69, 0xe6, + 0x3e, 0x5b, 0x70, 0x6e, 0xfa, 0xcf, 0x8b, 0xf3, 0x66, 0x5c, 0x23, 0x5f, + 0xe5, 0xa7, 0xaa, 0x42, 0x53, 0xdb, 0x2f, 0x8e, 0x2f, 0x65, 0x98, 0xc5, + 0x45, 0xc0, 0x84, 0xc0, 0xea, 0x26, 0x19, 0x8d, 0x85, 0x59, 0x42, 0x89, + 0x00, 0x00, 0x00, 0x15, 0x00, 0xc1, 0x0f, 0x96, 0x3a, 0x54, 0xcf, 0x2c, + 0x94, 0xbd, 0x88, 0xfc, 0x78, 0x6a, 0x4e, 0x69, 0xe8, 0x54, 0x5b, 0x86, + 0x99, 0x00, 0x00, 0x00, 0x80, 0x14, 0x93, 0x02, 0x9a, 0x8e, 0x75, 0x24, + 0x94, 0xde, 0x02, 0x5f, 0xf6, 0x56, 0x12, 0x12, 0x0e, 0x65, 0x60, 0x91, + 0x6b, 0xa6, 0x4a, 0x0a, 0x8b, 0x08, 0x08, 0x17, 0x3f, 0xc8, 0x2e, 0x11, + 0x18, 0x99, 0x5d, 0xaa, 0xc5, 0xda, 0x33, 0x43, 0xc2, 0x99, 0xdc, 0xb4, + 0x76, 0x67, 0x2f, 0xd1, 0x7b, 0x8e, 0x67, 0x83, 0x5b, 0xf7, 0x66, 0xa2, + 0x66, 0x75, 0x9d, 0x19, 0x15, 0xd3, 0x37, 0x92, 0x89, 0xe3, 0x4e, 0x56, + 0x54, 0xe4, 0x0b, 0x04, 0x1d, 0xcb, 0xa5, 0xe6, 0xc0, 0xea, 0xa7, 0xb2, + 0x0c, 0x68, 0x95, 0xb7, 0xf8, 0x8f, 0x3b, 0x18, 0x09, 0x19, 0x9c, 0xb4, + 0x2c, 0x85, 0xa2, 0xa9, 0x6b, 0xb3, 0x00, 0x07, 0xf5, 0xf7, 0xd7, 0x10, + 0xd8, 0x19, 0x16, 0x98, 0x64, 0xc2, 0xe8, 0x00, 0x09, 0x8b, 0x57, 0x5e, + 0xa5, 0x70, 0xbe, 0x29, 0x50, 0x0f, 0xf8, 0x7c, 0x17, 0x38, 0xb8, 0xd2, + 0x50, 0x00, 0x00, 0x00, 0x80, 0x5e, 0xa3, 0x22, 0x8a, 0x12, 0x25, 0x43, + 0x40, 0xea, 0x41, 0xd0, 0xa0, 0x2b, 0xe5, 0x12, 0xc7, 0xdf, 0xff, 0xb9, + 0x04, 0xff, 0xa6, 0x47, 0xee, 0x76, 0x81, 0x30, 0x1b, 0xc5, 0x96, 0xf1, + 0x40, 0xf6, 0x32, 0x1f, 0xb9, 0xaa, 0xab, 0x6f, 0xcf, 0x23, 0x50, 0x34, + 0x6e, 0x39, 0xef, 0x9c, 0xb7, 0xb8, 0xe5, 0xaf, 0xe2, 0x56, 0xe9, 0xa8, + 0x22, 0x33, 0xff, 0x6a, 0xd3, 0x2d, 0x54, 0x9e, 0xb0, 0xd7, 0x4d, 0xc4, + 0xc7, 0x92, 0x46, 0x33, 0x05, 0x41, 0xee, 0xe6, 0x41, 0x59, 0xec, 0x89, + 0xe2, 0x6d, 0xcc, 0xa9, 0x07, 0x4f, 0x7f, 0x5f, 0xfe, 0xaf, 0xe5, 0x02, + 0xa0, 0xe6, 0x8b, 0xee, 0xcb, 0x4a, 0xde, 0xb5, 0x9e, 0x4c, 0x2c, 0x9d, + 0x6f, 0xcd, 0xb3, 0xdf, 0x87, 0xa3, 0x5f, 0x47, 0x59, 0xa1, 0xb0, 0x0f, + 0x1a, 0x3d, 0x85, 0xed, 0x2c, 0x99, 0xcb, 0xb8, 0xcc, 0xf1, 0x31, 0xe0, + 0x73, + ]), + publicOrig: new Buffer([ + 0x73, 0x73, 0x68, 0x2d, 0x64, 0x73, 0x73, 0x20, 0x41, 0x41, 0x41, 0x41, + 0x42, 0x33, 0x4e, 0x7a, 0x61, 0x43, 0x31, 0x6b, 0x63, 0x33, 0x4d, 0x41, + 0x41, 0x41, 0x43, 0x42, 0x41, 0x4c, 0x31, 0x46, 0x7a, 0x64, 0x68, 0x74, + 0x53, 0x59, 0x4e, 0x32, 0x32, 0x59, 0x67, 0x62, 0x49, 0x6e, 0x79, 0x70, + 0x78, 0x61, 0x2f, 0x2f, 0x52, 0x79, 0x4b, 0x69, 0x5a, 0x41, 0x76, 0x57, + 0x78, 0x4e, 0x7a, 0x44, 0x4b, 0x4e, 0x46, 0x30, 0x63, 0x59, 0x76, 0x61, + 0x62, 0x48, 0x36, 0x45, 0x53, 0x6a, 0x64, 0x77, 0x64, 0x45, 0x63, 0x57, + 0x39, 0x36, 0x48, 0x37, 0x70, 0x48, 0x61, 0x4b, 0x62, 0x36, 0x39, 0x68, + 0x6f, 0x43, 0x48, 0x4b, 0x5a, 0x7a, 0x66, 0x57, 0x6d, 0x64, 0x70, 0x6a, + 0x39, 0x33, 0x43, 0x63, 0x65, 0x7a, 0x47, 0x6e, 0x6f, 0x72, 0x57, 0x76, + 0x55, 0x61, 0x4f, 0x34, 0x6e, 0x41, 0x76, 0x62, 0x52, 0x2b, 0x6c, 0x2f, + 0x67, 0x48, 0x2b, 0x41, 0x45, 0x59, 0x7a, 0x48, 0x6d, 0x4a, 0x73, 0x45, + 0x43, 0x76, 0x4d, 0x2f, 0x6e, 0x57, 0x6e, 0x6d, 0x50, 0x6c, 0x74, 0x77, + 0x62, 0x76, 0x72, 0x50, 0x69, 0x2f, 0x4e, 0x6d, 0x58, 0x43, 0x4e, 0x66, + 0x35, 0x61, 0x65, 0x71, 0x51, 0x6c, 0x50, 0x62, 0x4c, 0x34, 0x34, 0x76, + 0x5a, 0x5a, 0x6a, 0x46, 0x52, 0x63, 0x43, 0x45, 0x77, 0x4f, 0x6f, 0x6d, + 0x47, 0x59, 0x32, 0x46, 0x57, 0x55, 0x4b, 0x4a, 0x41, 0x41, 0x41, 0x41, + 0x46, 0x51, 0x44, 0x42, 0x44, 0x35, 0x59, 0x36, 0x56, 0x4d, 0x38, 0x73, + 0x6c, 0x4c, 0x32, 0x49, 0x2f, 0x48, 0x68, 0x71, 0x54, 0x6d, 0x6e, 0x6f, + 0x56, 0x46, 0x75, 0x47, 0x6d, 0x51, 0x41, 0x41, 0x41, 0x49, 0x41, 0x55, + 0x6b, 0x77, 0x4b, 0x61, 0x6a, 0x6e, 0x55, 0x6b, 0x6c, 0x4e, 0x34, 0x43, + 0x58, 0x2f, 0x5a, 0x57, 0x45, 0x68, 0x49, 0x4f, 0x5a, 0x57, 0x43, 0x52, + 0x61, 0x36, 0x5a, 0x4b, 0x43, 0x6f, 0x73, 0x49, 0x43, 0x42, 0x63, 0x2f, + 0x79, 0x43, 0x34, 0x52, 0x47, 0x4a, 0x6c, 0x64, 0x71, 0x73, 0x58, 0x61, + 0x4d, 0x30, 0x50, 0x43, 0x6d, 0x64, 0x79, 0x30, 0x64, 0x6d, 0x63, 0x76, + 0x30, 0x58, 0x75, 0x4f, 0x5a, 0x34, 0x4e, 0x62, 0x39, 0x32, 0x61, 0x69, + 0x5a, 0x6e, 0x57, 0x64, 0x47, 0x52, 0x58, 0x54, 0x4e, 0x35, 0x4b, 0x4a, + 0x34, 0x30, 0x35, 0x57, 0x56, 0x4f, 0x51, 0x4c, 0x42, 0x42, 0x33, 0x4c, + 0x70, 0x65, 0x62, 0x41, 0x36, 0x71, 0x65, 0x79, 0x44, 0x47, 0x69, 0x56, + 0x74, 0x2f, 0x69, 0x50, 0x4f, 0x78, 0x67, 0x4a, 0x47, 0x5a, 0x79, 0x30, + 0x4c, 0x49, 0x57, 0x69, 0x71, 0x57, 0x75, 0x7a, 0x41, 0x41, 0x66, 0x31, + 0x39, 0x39, 0x63, 0x51, 0x32, 0x42, 0x6b, 0x57, 0x6d, 0x47, 0x54, 0x43, + 0x36, 0x41, 0x41, 0x4a, 0x69, 0x31, 0x64, 0x65, 0x70, 0x58, 0x43, 0x2b, + 0x4b, 0x56, 0x41, 0x50, 0x2b, 0x48, 0x77, 0x58, 0x4f, 0x4c, 0x6a, 0x53, + 0x55, 0x41, 0x41, 0x41, 0x41, 0x49, 0x42, 0x65, 0x6f, 0x79, 0x4b, 0x4b, + 0x45, 0x69, 0x56, 0x44, 0x51, 0x4f, 0x70, 0x42, 0x30, 0x4b, 0x41, 0x72, + 0x35, 0x52, 0x4c, 0x48, 0x33, 0x2f, 0x2b, 0x35, 0x42, 0x50, 0x2b, 0x6d, + 0x52, 0x2b, 0x35, 0x32, 0x67, 0x54, 0x41, 0x62, 0x78, 0x5a, 0x62, 0x78, + 0x51, 0x50, 0x59, 0x79, 0x48, 0x37, 0x6d, 0x71, 0x71, 0x32, 0x2f, 0x50, + 0x49, 0x31, 0x41, 0x30, 0x62, 0x6a, 0x6e, 0x76, 0x6e, 0x4c, 0x65, 0x34, + 0x35, 0x61, 0x2f, 0x69, 0x56, 0x75, 0x6d, 0x6f, 0x49, 0x6a, 0x50, 0x2f, + 0x61, 0x74, 0x4d, 0x74, 0x56, 0x4a, 0x36, 0x77, 0x31, 0x30, 0x33, 0x45, + 0x78, 0x35, 0x4a, 0x47, 0x4d, 0x77, 0x56, 0x42, 0x37, 0x75, 0x5a, 0x42, + 0x57, 0x65, 0x79, 0x4a, 0x34, 0x6d, 0x33, 0x4d, 0x71, 0x51, 0x64, 0x50, + 0x66, 0x31, 0x2f, 0x2b, 0x72, 0x2b, 0x55, 0x43, 0x6f, 0x4f, 0x61, 0x4c, + 0x37, 0x73, 0x74, 0x4b, 0x33, 0x72, 0x57, 0x65, 0x54, 0x43, 0x79, 0x64, + 0x62, 0x38, 0x32, 0x7a, 0x33, 0x34, 0x65, 0x6a, 0x58, 0x30, 0x64, 0x5a, + 0x6f, 0x62, 0x41, 0x50, 0x47, 0x6a, 0x32, 0x46, 0x37, 0x53, 0x79, 0x5a, + 0x79, 0x37, 0x6a, 0x4d, 0x38, 0x54, 0x48, 0x67, 0x63, 0x77, 0x3d, 0x3d, + ]) + }, + what: 'DSA public key (OpenSSH format)' + }, + { source: 'ssh-dss AAAAB3NzaC1kc3MAAACBAILCaN5QbaErJBa0nNoCY2QvvgcSd7WMgIgQ2qPAPH3Sav+9SWZB0SlHP8QYmV/ntBufaRw9ZdIop6esZBoXmNXDxjcfwpJAzrT3qOMfHXeNcc7w/6dHp+2DlkWD3yzK07SheIZnGNtF1fpfrUvkHFA8UX96awWRLnYuSvWvAK9dAAAAFQCrfeadO0tCCwgnq97Skk0Ng/xV6wAAAIBcVYaMkjXNgfvcUS4pwMabY8rFNGbYo9Jgv7IU2LGFEzD6yFbp2t1sQw031EYlad4n3BMTrZdE6K2/SMi3f3yRr0Z6S6nVSbo7/kIT8/tGJAj9/8RHdCihrFUMaAJNzdk5dmbyaCzexLmLXlKfUVW9A1WOsASjeJBwpFrJ8deuVAAAAIAu/zdW1qxdUVd0b7sjWFFZpp3l6HgOXlZpaOYchIoybs7n2dkYwmvn9glNcLCvRqiZpm2oEZIg1dy8RaH5b7AqY2huwmv+hLZ1XkUFyS2Ae2AKux5rslmiKmvglbDY0Rng1Wj3r3/N0KcKke1g1ohEUaQfXnz7VVx2YoVxhT1dTQ== testing ssh2 from node.js', + expected: { + fulltype: 'ssh-dss', + type: 'dss', + curve: undefined, + extra: undefined, + comment: 'testing ssh2 from node.js', + encryption: undefined, + private: undefined, + privateOrig: undefined, + public: new Buffer([ + 0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2d, 0x64, 0x73, 0x73, 0x00, + 0x00, 0x00, 0x81, 0x00, 0x82, 0xc2, 0x68, 0xde, 0x50, 0x6d, 0xa1, 0x2b, + 0x24, 0x16, 0xb4, 0x9c, 0xda, 0x02, 0x63, 0x64, 0x2f, 0xbe, 0x07, 0x12, + 0x77, 0xb5, 0x8c, 0x80, 0x88, 0x10, 0xda, 0xa3, 0xc0, 0x3c, 0x7d, 0xd2, + 0x6a, 0xff, 0xbd, 0x49, 0x66, 0x41, 0xd1, 0x29, 0x47, 0x3f, 0xc4, 0x18, + 0x99, 0x5f, 0xe7, 0xb4, 0x1b, 0x9f, 0x69, 0x1c, 0x3d, 0x65, 0xd2, 0x28, + 0xa7, 0xa7, 0xac, 0x64, 0x1a, 0x17, 0x98, 0xd5, 0xc3, 0xc6, 0x37, 0x1f, + 0xc2, 0x92, 0x40, 0xce, 0xb4, 0xf7, 0xa8, 0xe3, 0x1f, 0x1d, 0x77, 0x8d, + 0x71, 0xce, 0xf0, 0xff, 0xa7, 0x47, 0xa7, 0xed, 0x83, 0x96, 0x45, 0x83, + 0xdf, 0x2c, 0xca, 0xd3, 0xb4, 0xa1, 0x78, 0x86, 0x67, 0x18, 0xdb, 0x45, + 0xd5, 0xfa, 0x5f, 0xad, 0x4b, 0xe4, 0x1c, 0x50, 0x3c, 0x51, 0x7f, 0x7a, + 0x6b, 0x05, 0x91, 0x2e, 0x76, 0x2e, 0x4a, 0xf5, 0xaf, 0x00, 0xaf, 0x5d, + 0x00, 0x00, 0x00, 0x15, 0x00, 0xab, 0x7d, 0xe6, 0x9d, 0x3b, 0x4b, 0x42, + 0x0b, 0x08, 0x27, 0xab, 0xde, 0xd2, 0x92, 0x4d, 0x0d, 0x83, 0xfc, 0x55, + 0xeb, 0x00, 0x00, 0x00, 0x80, 0x5c, 0x55, 0x86, 0x8c, 0x92, 0x35, 0xcd, + 0x81, 0xfb, 0xdc, 0x51, 0x2e, 0x29, 0xc0, 0xc6, 0x9b, 0x63, 0xca, 0xc5, + 0x34, 0x66, 0xd8, 0xa3, 0xd2, 0x60, 0xbf, 0xb2, 0x14, 0xd8, 0xb1, 0x85, + 0x13, 0x30, 0xfa, 0xc8, 0x56, 0xe9, 0xda, 0xdd, 0x6c, 0x43, 0x0d, 0x37, + 0xd4, 0x46, 0x25, 0x69, 0xde, 0x27, 0xdc, 0x13, 0x13, 0xad, 0x97, 0x44, + 0xe8, 0xad, 0xbf, 0x48, 0xc8, 0xb7, 0x7f, 0x7c, 0x91, 0xaf, 0x46, 0x7a, + 0x4b, 0xa9, 0xd5, 0x49, 0xba, 0x3b, 0xfe, 0x42, 0x13, 0xf3, 0xfb, 0x46, + 0x24, 0x08, 0xfd, 0xff, 0xc4, 0x47, 0x74, 0x28, 0xa1, 0xac, 0x55, 0x0c, + 0x68, 0x02, 0x4d, 0xcd, 0xd9, 0x39, 0x76, 0x66, 0xf2, 0x68, 0x2c, 0xde, + 0xc4, 0xb9, 0x8b, 0x5e, 0x52, 0x9f, 0x51, 0x55, 0xbd, 0x03, 0x55, 0x8e, + 0xb0, 0x04, 0xa3, 0x78, 0x90, 0x70, 0xa4, 0x5a, 0xc9, 0xf1, 0xd7, 0xae, + 0x54, 0x00, 0x00, 0x00, 0x80, 0x2e, 0xff, 0x37, 0x56, 0xd6, 0xac, 0x5d, + 0x51, 0x57, 0x74, 0x6f, 0xbb, 0x23, 0x58, 0x51, 0x59, 0xa6, 0x9d, 0xe5, + 0xe8, 0x78, 0x0e, 0x5e, 0x56, 0x69, 0x68, 0xe6, 0x1c, 0x84, 0x8a, 0x32, + 0x6e, 0xce, 0xe7, 0xd9, 0xd9, 0x18, 0xc2, 0x6b, 0xe7, 0xf6, 0x09, 0x4d, + 0x70, 0xb0, 0xaf, 0x46, 0xa8, 0x99, 0xa6, 0x6d, 0xa8, 0x11, 0x92, 0x20, + 0xd5, 0xdc, 0xbc, 0x45, 0xa1, 0xf9, 0x6f, 0xb0, 0x2a, 0x63, 0x68, 0x6e, + 0xc2, 0x6b, 0xfe, 0x84, 0xb6, 0x75, 0x5e, 0x45, 0x05, 0xc9, 0x2d, 0x80, + 0x7b, 0x60, 0x0a, 0xbb, 0x1e, 0x6b, 0xb2, 0x59, 0xa2, 0x2a, 0x6b, 0xe0, + 0x95, 0xb0, 0xd8, 0xd1, 0x19, 0xe0, 0xd5, 0x68, 0xf7, 0xaf, 0x7f, 0xcd, + 0xd0, 0xa7, 0x0a, 0x91, 0xed, 0x60, 0xd6, 0x88, 0x44, 0x51, 0xa4, 0x1f, + 0x5e, 0x7c, 0xfb, 0x55, 0x5c, 0x76, 0x62, 0x85, 0x71, 0x85, 0x3d, 0x5d, + 0x4d, + ]), + publicOrig: new Buffer([ + 0x73, 0x73, 0x68, 0x2d, 0x64, 0x73, 0x73, 0x20, 0x41, 0x41, 0x41, 0x41, + 0x42, 0x33, 0x4e, 0x7a, 0x61, 0x43, 0x31, 0x6b, 0x63, 0x33, 0x4d, 0x41, + 0x41, 0x41, 0x43, 0x42, 0x41, 0x49, 0x4c, 0x43, 0x61, 0x4e, 0x35, 0x51, + 0x62, 0x61, 0x45, 0x72, 0x4a, 0x42, 0x61, 0x30, 0x6e, 0x4e, 0x6f, 0x43, + 0x59, 0x32, 0x51, 0x76, 0x76, 0x67, 0x63, 0x53, 0x64, 0x37, 0x57, 0x4d, + 0x67, 0x49, 0x67, 0x51, 0x32, 0x71, 0x50, 0x41, 0x50, 0x48, 0x33, 0x53, + 0x61, 0x76, 0x2b, 0x39, 0x53, 0x57, 0x5a, 0x42, 0x30, 0x53, 0x6c, 0x48, + 0x50, 0x38, 0x51, 0x59, 0x6d, 0x56, 0x2f, 0x6e, 0x74, 0x42, 0x75, 0x66, + 0x61, 0x52, 0x77, 0x39, 0x5a, 0x64, 0x49, 0x6f, 0x70, 0x36, 0x65, 0x73, + 0x5a, 0x42, 0x6f, 0x58, 0x6d, 0x4e, 0x58, 0x44, 0x78, 0x6a, 0x63, 0x66, + 0x77, 0x70, 0x4a, 0x41, 0x7a, 0x72, 0x54, 0x33, 0x71, 0x4f, 0x4d, 0x66, + 0x48, 0x58, 0x65, 0x4e, 0x63, 0x63, 0x37, 0x77, 0x2f, 0x36, 0x64, 0x48, + 0x70, 0x2b, 0x32, 0x44, 0x6c, 0x6b, 0x57, 0x44, 0x33, 0x79, 0x7a, 0x4b, + 0x30, 0x37, 0x53, 0x68, 0x65, 0x49, 0x5a, 0x6e, 0x47, 0x4e, 0x74, 0x46, + 0x31, 0x66, 0x70, 0x66, 0x72, 0x55, 0x76, 0x6b, 0x48, 0x46, 0x41, 0x38, + 0x55, 0x58, 0x39, 0x36, 0x61, 0x77, 0x57, 0x52, 0x4c, 0x6e, 0x59, 0x75, + 0x53, 0x76, 0x57, 0x76, 0x41, 0x4b, 0x39, 0x64, 0x41, 0x41, 0x41, 0x41, + 0x46, 0x51, 0x43, 0x72, 0x66, 0x65, 0x61, 0x64, 0x4f, 0x30, 0x74, 0x43, + 0x43, 0x77, 0x67, 0x6e, 0x71, 0x39, 0x37, 0x53, 0x6b, 0x6b, 0x30, 0x4e, + 0x67, 0x2f, 0x78, 0x56, 0x36, 0x77, 0x41, 0x41, 0x41, 0x49, 0x42, 0x63, + 0x56, 0x59, 0x61, 0x4d, 0x6b, 0x6a, 0x58, 0x4e, 0x67, 0x66, 0x76, 0x63, + 0x55, 0x53, 0x34, 0x70, 0x77, 0x4d, 0x61, 0x62, 0x59, 0x38, 0x72, 0x46, + 0x4e, 0x47, 0x62, 0x59, 0x6f, 0x39, 0x4a, 0x67, 0x76, 0x37, 0x49, 0x55, + 0x32, 0x4c, 0x47, 0x46, 0x45, 0x7a, 0x44, 0x36, 0x79, 0x46, 0x62, 0x70, + 0x32, 0x74, 0x31, 0x73, 0x51, 0x77, 0x30, 0x33, 0x31, 0x45, 0x59, 0x6c, + 0x61, 0x64, 0x34, 0x6e, 0x33, 0x42, 0x4d, 0x54, 0x72, 0x5a, 0x64, 0x45, + 0x36, 0x4b, 0x32, 0x2f, 0x53, 0x4d, 0x69, 0x33, 0x66, 0x33, 0x79, 0x52, + 0x72, 0x30, 0x5a, 0x36, 0x53, 0x36, 0x6e, 0x56, 0x53, 0x62, 0x6f, 0x37, + 0x2f, 0x6b, 0x49, 0x54, 0x38, 0x2f, 0x74, 0x47, 0x4a, 0x41, 0x6a, 0x39, + 0x2f, 0x38, 0x52, 0x48, 0x64, 0x43, 0x69, 0x68, 0x72, 0x46, 0x55, 0x4d, + 0x61, 0x41, 0x4a, 0x4e, 0x7a, 0x64, 0x6b, 0x35, 0x64, 0x6d, 0x62, 0x79, + 0x61, 0x43, 0x7a, 0x65, 0x78, 0x4c, 0x6d, 0x4c, 0x58, 0x6c, 0x4b, 0x66, + 0x55, 0x56, 0x57, 0x39, 0x41, 0x31, 0x57, 0x4f, 0x73, 0x41, 0x53, 0x6a, + 0x65, 0x4a, 0x42, 0x77, 0x70, 0x46, 0x72, 0x4a, 0x38, 0x64, 0x65, 0x75, + 0x56, 0x41, 0x41, 0x41, 0x41, 0x49, 0x41, 0x75, 0x2f, 0x7a, 0x64, 0x57, + 0x31, 0x71, 0x78, 0x64, 0x55, 0x56, 0x64, 0x30, 0x62, 0x37, 0x73, 0x6a, + 0x57, 0x46, 0x46, 0x5a, 0x70, 0x70, 0x33, 0x6c, 0x36, 0x48, 0x67, 0x4f, + 0x58, 0x6c, 0x5a, 0x70, 0x61, 0x4f, 0x59, 0x63, 0x68, 0x49, 0x6f, 0x79, + 0x62, 0x73, 0x37, 0x6e, 0x32, 0x64, 0x6b, 0x59, 0x77, 0x6d, 0x76, 0x6e, + 0x39, 0x67, 0x6c, 0x4e, 0x63, 0x4c, 0x43, 0x76, 0x52, 0x71, 0x69, 0x5a, + 0x70, 0x6d, 0x32, 0x6f, 0x45, 0x5a, 0x49, 0x67, 0x31, 0x64, 0x79, 0x38, + 0x52, 0x61, 0x48, 0x35, 0x62, 0x37, 0x41, 0x71, 0x59, 0x32, 0x68, 0x75, + 0x77, 0x6d, 0x76, 0x2b, 0x68, 0x4c, 0x5a, 0x31, 0x58, 0x6b, 0x55, 0x46, + 0x79, 0x53, 0x32, 0x41, 0x65, 0x32, 0x41, 0x4b, 0x75, 0x78, 0x35, 0x72, + 0x73, 0x6c, 0x6d, 0x69, 0x4b, 0x6d, 0x76, 0x67, 0x6c, 0x62, 0x44, 0x59, + 0x30, 0x52, 0x6e, 0x67, 0x31, 0x57, 0x6a, 0x33, 0x72, 0x33, 0x2f, 0x4e, + 0x30, 0x4b, 0x63, 0x4b, 0x6b, 0x65, 0x31, 0x67, 0x31, 0x6f, 0x68, 0x45, + 0x55, 0x61, 0x51, 0x66, 0x58, 0x6e, 0x7a, 0x37, 0x56, 0x56, 0x78, 0x32, + 0x59, 0x6f, 0x56, 0x78, 0x68, 0x54, 0x31, 0x64, 0x54, 0x51, 0x3d, 0x3d, + 0x20, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x73, 0x68, + 0x32, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x6a, 0x73, + ]) + }, + what: 'DSA public key (OpenSSH format) with comment' + }, + { source: 'ssh-dss AAAAB3NzaC1kc3MAAACBAILCaN5QbaErJBa0nNoCY2QvvgcSd7WMgIgQ2qPAPH3Sav+9SWZB0SlHP8QYmV/ntBufaRw9ZdIop6esZBoXmNXDxjcfwpJAzrT3qOMfHXeNcc7w/6dHp+2DlkWD3yzK07SheIZnGNtF1fpfrUvkHFA8UX96awWRLnYuSvWvAK9dAAAAFQCrfeadO0tCCwgnq97Skk0Ng/xV6wAAAIBcVYaMkjXNgfvcUS4pwMabY8rFNGbYo9Jgv7IU2LGFEzD6yFbp2t1sQw031EYlad4n3BMTrZdE6K2/SMi3f3yRr0Z6S6nVSbo7/kIT8/tGJAj9/8RHdCihrFUMaAJNzdk5dmbyaCzexLmLXlKfUVW9A1WOsASjeJBwpFrJ8deuVAAAAIAu/zdW1qxdUVd0b7sjWFFZpp3l6HgOXlZpaOYchIoybs7n2dkYwmvn9glNcLCvRqiZpm2oEZIg1dy8RaH5b7AqY2huwmv+hLZ1XkUFyS2Ae2AKux5rslmiKmvglbDY0Rng1Wj3r3/N0KcKke1g1ohEUaQfXnz7VVx2YoVxhT1dTQ== ssh2test', + expected: { + fulltype: 'ssh-dss', + type: 'dss', + curve: undefined, + extra: undefined, + comment: 'ssh2test', + encryption: undefined, + private: undefined, + privateOrig: undefined, + public: new Buffer([ + 0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2d, 0x64, 0x73, 0x73, 0x00, + 0x00, 0x00, 0x81, 0x00, 0x82, 0xc2, 0x68, 0xde, 0x50, 0x6d, 0xa1, 0x2b, + 0x24, 0x16, 0xb4, 0x9c, 0xda, 0x02, 0x63, 0x64, 0x2f, 0xbe, 0x07, 0x12, + 0x77, 0xb5, 0x8c, 0x80, 0x88, 0x10, 0xda, 0xa3, 0xc0, 0x3c, 0x7d, 0xd2, + 0x6a, 0xff, 0xbd, 0x49, 0x66, 0x41, 0xd1, 0x29, 0x47, 0x3f, 0xc4, 0x18, + 0x99, 0x5f, 0xe7, 0xb4, 0x1b, 0x9f, 0x69, 0x1c, 0x3d, 0x65, 0xd2, 0x28, + 0xa7, 0xa7, 0xac, 0x64, 0x1a, 0x17, 0x98, 0xd5, 0xc3, 0xc6, 0x37, 0x1f, + 0xc2, 0x92, 0x40, 0xce, 0xb4, 0xf7, 0xa8, 0xe3, 0x1f, 0x1d, 0x77, 0x8d, + 0x71, 0xce, 0xf0, 0xff, 0xa7, 0x47, 0xa7, 0xed, 0x83, 0x96, 0x45, 0x83, + 0xdf, 0x2c, 0xca, 0xd3, 0xb4, 0xa1, 0x78, 0x86, 0x67, 0x18, 0xdb, 0x45, + 0xd5, 0xfa, 0x5f, 0xad, 0x4b, 0xe4, 0x1c, 0x50, 0x3c, 0x51, 0x7f, 0x7a, + 0x6b, 0x05, 0x91, 0x2e, 0x76, 0x2e, 0x4a, 0xf5, 0xaf, 0x00, 0xaf, 0x5d, + 0x00, 0x00, 0x00, 0x15, 0x00, 0xab, 0x7d, 0xe6, 0x9d, 0x3b, 0x4b, 0x42, + 0x0b, 0x08, 0x27, 0xab, 0xde, 0xd2, 0x92, 0x4d, 0x0d, 0x83, 0xfc, 0x55, + 0xeb, 0x00, 0x00, 0x00, 0x80, 0x5c, 0x55, 0x86, 0x8c, 0x92, 0x35, 0xcd, + 0x81, 0xfb, 0xdc, 0x51, 0x2e, 0x29, 0xc0, 0xc6, 0x9b, 0x63, 0xca, 0xc5, + 0x34, 0x66, 0xd8, 0xa3, 0xd2, 0x60, 0xbf, 0xb2, 0x14, 0xd8, 0xb1, 0x85, + 0x13, 0x30, 0xfa, 0xc8, 0x56, 0xe9, 0xda, 0xdd, 0x6c, 0x43, 0x0d, 0x37, + 0xd4, 0x46, 0x25, 0x69, 0xde, 0x27, 0xdc, 0x13, 0x13, 0xad, 0x97, 0x44, + 0xe8, 0xad, 0xbf, 0x48, 0xc8, 0xb7, 0x7f, 0x7c, 0x91, 0xaf, 0x46, 0x7a, + 0x4b, 0xa9, 0xd5, 0x49, 0xba, 0x3b, 0xfe, 0x42, 0x13, 0xf3, 0xfb, 0x46, + 0x24, 0x08, 0xfd, 0xff, 0xc4, 0x47, 0x74, 0x28, 0xa1, 0xac, 0x55, 0x0c, + 0x68, 0x02, 0x4d, 0xcd, 0xd9, 0x39, 0x76, 0x66, 0xf2, 0x68, 0x2c, 0xde, + 0xc4, 0xb9, 0x8b, 0x5e, 0x52, 0x9f, 0x51, 0x55, 0xbd, 0x03, 0x55, 0x8e, + 0xb0, 0x04, 0xa3, 0x78, 0x90, 0x70, 0xa4, 0x5a, 0xc9, 0xf1, 0xd7, 0xae, + 0x54, 0x00, 0x00, 0x00, 0x80, 0x2e, 0xff, 0x37, 0x56, 0xd6, 0xac, 0x5d, + 0x51, 0x57, 0x74, 0x6f, 0xbb, 0x23, 0x58, 0x51, 0x59, 0xa6, 0x9d, 0xe5, + 0xe8, 0x78, 0x0e, 0x5e, 0x56, 0x69, 0x68, 0xe6, 0x1c, 0x84, 0x8a, 0x32, + 0x6e, 0xce, 0xe7, 0xd9, 0xd9, 0x18, 0xc2, 0x6b, 0xe7, 0xf6, 0x09, 0x4d, + 0x70, 0xb0, 0xaf, 0x46, 0xa8, 0x99, 0xa6, 0x6d, 0xa8, 0x11, 0x92, 0x20, + 0xd5, 0xdc, 0xbc, 0x45, 0xa1, 0xf9, 0x6f, 0xb0, 0x2a, 0x63, 0x68, 0x6e, + 0xc2, 0x6b, 0xfe, 0x84, 0xb6, 0x75, 0x5e, 0x45, 0x05, 0xc9, 0x2d, 0x80, + 0x7b, 0x60, 0x0a, 0xbb, 0x1e, 0x6b, 0xb2, 0x59, 0xa2, 0x2a, 0x6b, 0xe0, + 0x95, 0xb0, 0xd8, 0xd1, 0x19, 0xe0, 0xd5, 0x68, 0xf7, 0xaf, 0x7f, 0xcd, + 0xd0, 0xa7, 0x0a, 0x91, 0xed, 0x60, 0xd6, 0x88, 0x44, 0x51, 0xa4, 0x1f, + 0x5e, 0x7c, 0xfb, 0x55, 0x5c, 0x76, 0x62, 0x85, 0x71, 0x85, 0x3d, 0x5d, + 0x4d, + ]), + publicOrig: new Buffer([ + 0x73, 0x73, 0x68, 0x2d, 0x64, 0x73, 0x73, 0x20, 0x41, 0x41, 0x41, 0x41, + 0x42, 0x33, 0x4e, 0x7a, 0x61, 0x43, 0x31, 0x6b, 0x63, 0x33, 0x4d, 0x41, + 0x41, 0x41, 0x43, 0x42, 0x41, 0x49, 0x4c, 0x43, 0x61, 0x4e, 0x35, 0x51, + 0x62, 0x61, 0x45, 0x72, 0x4a, 0x42, 0x61, 0x30, 0x6e, 0x4e, 0x6f, 0x43, + 0x59, 0x32, 0x51, 0x76, 0x76, 0x67, 0x63, 0x53, 0x64, 0x37, 0x57, 0x4d, + 0x67, 0x49, 0x67, 0x51, 0x32, 0x71, 0x50, 0x41, 0x50, 0x48, 0x33, 0x53, + 0x61, 0x76, 0x2b, 0x39, 0x53, 0x57, 0x5a, 0x42, 0x30, 0x53, 0x6c, 0x48, + 0x50, 0x38, 0x51, 0x59, 0x6d, 0x56, 0x2f, 0x6e, 0x74, 0x42, 0x75, 0x66, + 0x61, 0x52, 0x77, 0x39, 0x5a, 0x64, 0x49, 0x6f, 0x70, 0x36, 0x65, 0x73, + 0x5a, 0x42, 0x6f, 0x58, 0x6d, 0x4e, 0x58, 0x44, 0x78, 0x6a, 0x63, 0x66, + 0x77, 0x70, 0x4a, 0x41, 0x7a, 0x72, 0x54, 0x33, 0x71, 0x4f, 0x4d, 0x66, + 0x48, 0x58, 0x65, 0x4e, 0x63, 0x63, 0x37, 0x77, 0x2f, 0x36, 0x64, 0x48, + 0x70, 0x2b, 0x32, 0x44, 0x6c, 0x6b, 0x57, 0x44, 0x33, 0x79, 0x7a, 0x4b, + 0x30, 0x37, 0x53, 0x68, 0x65, 0x49, 0x5a, 0x6e, 0x47, 0x4e, 0x74, 0x46, + 0x31, 0x66, 0x70, 0x66, 0x72, 0x55, 0x76, 0x6b, 0x48, 0x46, 0x41, 0x38, + 0x55, 0x58, 0x39, 0x36, 0x61, 0x77, 0x57, 0x52, 0x4c, 0x6e, 0x59, 0x75, + 0x53, 0x76, 0x57, 0x76, 0x41, 0x4b, 0x39, 0x64, 0x41, 0x41, 0x41, 0x41, + 0x46, 0x51, 0x43, 0x72, 0x66, 0x65, 0x61, 0x64, 0x4f, 0x30, 0x74, 0x43, + 0x43, 0x77, 0x67, 0x6e, 0x71, 0x39, 0x37, 0x53, 0x6b, 0x6b, 0x30, 0x4e, + 0x67, 0x2f, 0x78, 0x56, 0x36, 0x77, 0x41, 0x41, 0x41, 0x49, 0x42, 0x63, + 0x56, 0x59, 0x61, 0x4d, 0x6b, 0x6a, 0x58, 0x4e, 0x67, 0x66, 0x76, 0x63, + 0x55, 0x53, 0x34, 0x70, 0x77, 0x4d, 0x61, 0x62, 0x59, 0x38, 0x72, 0x46, + 0x4e, 0x47, 0x62, 0x59, 0x6f, 0x39, 0x4a, 0x67, 0x76, 0x37, 0x49, 0x55, + 0x32, 0x4c, 0x47, 0x46, 0x45, 0x7a, 0x44, 0x36, 0x79, 0x46, 0x62, 0x70, + 0x32, 0x74, 0x31, 0x73, 0x51, 0x77, 0x30, 0x33, 0x31, 0x45, 0x59, 0x6c, + 0x61, 0x64, 0x34, 0x6e, 0x33, 0x42, 0x4d, 0x54, 0x72, 0x5a, 0x64, 0x45, + 0x36, 0x4b, 0x32, 0x2f, 0x53, 0x4d, 0x69, 0x33, 0x66, 0x33, 0x79, 0x52, + 0x72, 0x30, 0x5a, 0x36, 0x53, 0x36, 0x6e, 0x56, 0x53, 0x62, 0x6f, 0x37, + 0x2f, 0x6b, 0x49, 0x54, 0x38, 0x2f, 0x74, 0x47, 0x4a, 0x41, 0x6a, 0x39, + 0x2f, 0x38, 0x52, 0x48, 0x64, 0x43, 0x69, 0x68, 0x72, 0x46, 0x55, 0x4d, + 0x61, 0x41, 0x4a, 0x4e, 0x7a, 0x64, 0x6b, 0x35, 0x64, 0x6d, 0x62, 0x79, + 0x61, 0x43, 0x7a, 0x65, 0x78, 0x4c, 0x6d, 0x4c, 0x58, 0x6c, 0x4b, 0x66, + 0x55, 0x56, 0x57, 0x39, 0x41, 0x31, 0x57, 0x4f, 0x73, 0x41, 0x53, 0x6a, + 0x65, 0x4a, 0x42, 0x77, 0x70, 0x46, 0x72, 0x4a, 0x38, 0x64, 0x65, 0x75, + 0x56, 0x41, 0x41, 0x41, 0x41, 0x49, 0x41, 0x75, 0x2f, 0x7a, 0x64, 0x57, + 0x31, 0x71, 0x78, 0x64, 0x55, 0x56, 0x64, 0x30, 0x62, 0x37, 0x73, 0x6a, + 0x57, 0x46, 0x46, 0x5a, 0x70, 0x70, 0x33, 0x6c, 0x36, 0x48, 0x67, 0x4f, + 0x58, 0x6c, 0x5a, 0x70, 0x61, 0x4f, 0x59, 0x63, 0x68, 0x49, 0x6f, 0x79, + 0x62, 0x73, 0x37, 0x6e, 0x32, 0x64, 0x6b, 0x59, 0x77, 0x6d, 0x76, 0x6e, + 0x39, 0x67, 0x6c, 0x4e, 0x63, 0x4c, 0x43, 0x76, 0x52, 0x71, 0x69, 0x5a, + 0x70, 0x6d, 0x32, 0x6f, 0x45, 0x5a, 0x49, 0x67, 0x31, 0x64, 0x79, 0x38, + 0x52, 0x61, 0x48, 0x35, 0x62, 0x37, 0x41, 0x71, 0x59, 0x32, 0x68, 0x75, + 0x77, 0x6d, 0x76, 0x2b, 0x68, 0x4c, 0x5a, 0x31, 0x58, 0x6b, 0x55, 0x46, + 0x79, 0x53, 0x32, 0x41, 0x65, 0x32, 0x41, 0x4b, 0x75, 0x78, 0x35, 0x72, + 0x73, 0x6c, 0x6d, 0x69, 0x4b, 0x6d, 0x76, 0x67, 0x6c, 0x62, 0x44, 0x59, + 0x30, 0x52, 0x6e, 0x67, 0x31, 0x57, 0x6a, 0x33, 0x72, 0x33, 0x2f, 0x4e, + 0x30, 0x4b, 0x63, 0x4b, 0x6b, 0x65, 0x31, 0x67, 0x31, 0x6f, 0x68, 0x45, + 0x55, 0x61, 0x51, 0x66, 0x58, 0x6e, 0x7a, 0x37, 0x56, 0x56, 0x78, 0x32, + 0x59, 0x6f, 0x56, 0x78, 0x68, 0x54, 0x31, 0x64, 0x54, 0x51, 0x3d, 0x3d, + 0x20, 0x73, 0x73, 0x68, 0x32, 0x74, 0x65, 0x73, 0x74, + ]) + }, + what: 'DSA public key (OpenSSH format) with comment (no spaces)' + }, + { source: [ + '---- BEGIN SSH2 PUBLIC KEY ----', + 'Comment: "testing ssh2 from node.js"', + 'AAAAB3NzaC1yc2EAAAADAQABAAAAYQDl6dxL+hgxwGNhZrq18vArbNB0UqNxvclf+ociRL', + 'lnR5O6r/czAhySO+eOc5SF7wexZzWo/COQ37tEi9reTucYFNQQWFvx4E8CRFP+UPR6hQX0', + 'fxoLSF3lxQFJ+32/rS0=', + '---- END SSH2 PUBLIC KEY ----' + ].join('\n'), + expected: { + fulltype: 'ssh-rsa', + type: 'rsa', + curve: undefined, + extra: undefined, + comment: 'testing ssh2 from node.js', + encryption: undefined, + private: undefined, + privateOrig: undefined, + public: new Buffer([ + 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x61, 0x00, + 0xe5, 0xe9, 0xdc, 0x4b, 0xfa, 0x18, 0x31, 0xc0, 0x63, 0x61, 0x66, 0xba, + 0xb5, 0xf2, 0xf0, 0x2b, 0x6c, 0xd0, 0x74, 0x52, 0xa3, 0x71, 0xbd, 0xc9, + 0x5f, 0xfa, 0x87, 0x22, 0x44, 0xb9, 0x67, 0x47, 0x93, 0xba, 0xaf, 0xf7, + 0x33, 0x02, 0x1c, 0x92, 0x3b, 0xe7, 0x8e, 0x73, 0x94, 0x85, 0xef, 0x07, + 0xb1, 0x67, 0x35, 0xa8, 0xfc, 0x23, 0x90, 0xdf, 0xbb, 0x44, 0x8b, 0xda, + 0xde, 0x4e, 0xe7, 0x18, 0x14, 0xd4, 0x10, 0x58, 0x5b, 0xf1, 0xe0, 0x4f, + 0x02, 0x44, 0x53, 0xfe, 0x50, 0xf4, 0x7a, 0x85, 0x05, 0xf4, 0x7f, 0x1a, + 0x0b, 0x48, 0x5d, 0xe5, 0xc5, 0x01, 0x49, 0xfb, 0x7d, 0xbf, 0xad, 0x2d, + ]), + publicOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x53, + 0x53, 0x48, 0x32, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, + 0x45, 0x59, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x43, 0x6f, 0x6d, 0x6d, + 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x22, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x67, 0x20, 0x73, 0x73, 0x68, 0x32, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, + 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6a, 0x73, 0x22, 0x0a, 0x41, 0x41, 0x41, + 0x41, 0x42, 0x33, 0x4e, 0x7a, 0x61, 0x43, 0x31, 0x79, 0x63, 0x32, 0x45, + 0x41, 0x41, 0x41, 0x41, 0x44, 0x41, 0x51, 0x41, 0x42, 0x41, 0x41, 0x41, + 0x41, 0x59, 0x51, 0x44, 0x6c, 0x36, 0x64, 0x78, 0x4c, 0x2b, 0x68, 0x67, + 0x78, 0x77, 0x47, 0x4e, 0x68, 0x5a, 0x72, 0x71, 0x31, 0x38, 0x76, 0x41, + 0x72, 0x62, 0x4e, 0x42, 0x30, 0x55, 0x71, 0x4e, 0x78, 0x76, 0x63, 0x6c, + 0x66, 0x2b, 0x6f, 0x63, 0x69, 0x52, 0x4c, 0x0a, 0x6c, 0x6e, 0x52, 0x35, + 0x4f, 0x36, 0x72, 0x2f, 0x63, 0x7a, 0x41, 0x68, 0x79, 0x53, 0x4f, 0x2b, + 0x65, 0x4f, 0x63, 0x35, 0x53, 0x46, 0x37, 0x77, 0x65, 0x78, 0x5a, 0x7a, + 0x57, 0x6f, 0x2f, 0x43, 0x4f, 0x51, 0x33, 0x37, 0x74, 0x45, 0x69, 0x39, + 0x72, 0x65, 0x54, 0x75, 0x63, 0x59, 0x46, 0x4e, 0x51, 0x51, 0x57, 0x46, + 0x76, 0x78, 0x34, 0x45, 0x38, 0x43, 0x52, 0x46, 0x50, 0x2b, 0x55, 0x50, + 0x52, 0x36, 0x68, 0x51, 0x58, 0x30, 0x0a, 0x66, 0x78, 0x6f, 0x4c, 0x53, + 0x46, 0x33, 0x6c, 0x78, 0x51, 0x46, 0x4a, 0x2b, 0x33, 0x32, 0x2f, 0x72, + 0x53, 0x30, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x45, 0x4e, 0x44, + 0x20, 0x53, 0x53, 0x48, 0x32, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, + 0x20, 0x4b, 0x45, 0x59, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, + ]) + }, + what: 'RSA public key (RFC4716 format) with quoted comment' + }, + { source: [ + '---- BEGIN SSH2 PUBLIC KEY ----', + 'Comment: testing ssh2 from node.js', + 'AAAAB3NzaC1yc2EAAAADAQABAAAAYQDl6dxL+hgxwGNhZrq18vArbNB0UqNxvclf+ociRL', + 'lnR5O6r/czAhySO+eOc5SF7wexZzWo/COQ37tEi9reTucYFNQQWFvx4E8CRFP+UPR6hQX0', + 'fxoLSF3lxQFJ+32/rS0=', + '---- END SSH2 PUBLIC KEY ----' + ].join('\n'), + expected: { + fulltype: 'ssh-rsa', + type: 'rsa', + curve: undefined, + extra: undefined, + comment: 'testing ssh2 from node.js', + encryption: undefined, + private: undefined, + privateOrig: undefined, + public: new Buffer([ + 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x61, 0x00, + 0xe5, 0xe9, 0xdc, 0x4b, 0xfa, 0x18, 0x31, 0xc0, 0x63, 0x61, 0x66, 0xba, + 0xb5, 0xf2, 0xf0, 0x2b, 0x6c, 0xd0, 0x74, 0x52, 0xa3, 0x71, 0xbd, 0xc9, + 0x5f, 0xfa, 0x87, 0x22, 0x44, 0xb9, 0x67, 0x47, 0x93, 0xba, 0xaf, 0xf7, + 0x33, 0x02, 0x1c, 0x92, 0x3b, 0xe7, 0x8e, 0x73, 0x94, 0x85, 0xef, 0x07, + 0xb1, 0x67, 0x35, 0xa8, 0xfc, 0x23, 0x90, 0xdf, 0xbb, 0x44, 0x8b, 0xda, + 0xde, 0x4e, 0xe7, 0x18, 0x14, 0xd4, 0x10, 0x58, 0x5b, 0xf1, 0xe0, 0x4f, + 0x02, 0x44, 0x53, 0xfe, 0x50, 0xf4, 0x7a, 0x85, 0x05, 0xf4, 0x7f, 0x1a, + 0x0b, 0x48, 0x5d, 0xe5, 0xc5, 0x01, 0x49, 0xfb, 0x7d, 0xbf, 0xad, 0x2d, + ]), + publicOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x53, + 0x53, 0x48, 0x32, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, + 0x45, 0x59, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x43, 0x6f, 0x6d, 0x6d, + 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, + 0x20, 0x73, 0x73, 0x68, 0x32, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x6e, + 0x6f, 0x64, 0x65, 0x2e, 0x6a, 0x73, 0x0a, 0x41, 0x41, 0x41, 0x41, 0x42, + 0x33, 0x4e, 0x7a, 0x61, 0x43, 0x31, 0x79, 0x63, 0x32, 0x45, 0x41, 0x41, + 0x41, 0x41, 0x44, 0x41, 0x51, 0x41, 0x42, 0x41, 0x41, 0x41, 0x41, 0x59, + 0x51, 0x44, 0x6c, 0x36, 0x64, 0x78, 0x4c, 0x2b, 0x68, 0x67, 0x78, 0x77, + 0x47, 0x4e, 0x68, 0x5a, 0x72, 0x71, 0x31, 0x38, 0x76, 0x41, 0x72, 0x62, + 0x4e, 0x42, 0x30, 0x55, 0x71, 0x4e, 0x78, 0x76, 0x63, 0x6c, 0x66, 0x2b, + 0x6f, 0x63, 0x69, 0x52, 0x4c, 0x0a, 0x6c, 0x6e, 0x52, 0x35, 0x4f, 0x36, + 0x72, 0x2f, 0x63, 0x7a, 0x41, 0x68, 0x79, 0x53, 0x4f, 0x2b, 0x65, 0x4f, + 0x63, 0x35, 0x53, 0x46, 0x37, 0x77, 0x65, 0x78, 0x5a, 0x7a, 0x57, 0x6f, + 0x2f, 0x43, 0x4f, 0x51, 0x33, 0x37, 0x74, 0x45, 0x69, 0x39, 0x72, 0x65, + 0x54, 0x75, 0x63, 0x59, 0x46, 0x4e, 0x51, 0x51, 0x57, 0x46, 0x76, 0x78, + 0x34, 0x45, 0x38, 0x43, 0x52, 0x46, 0x50, 0x2b, 0x55, 0x50, 0x52, 0x36, + 0x68, 0x51, 0x58, 0x30, 0x0a, 0x66, 0x78, 0x6f, 0x4c, 0x53, 0x46, 0x33, + 0x6c, 0x78, 0x51, 0x46, 0x4a, 0x2b, 0x33, 0x32, 0x2f, 0x72, 0x53, 0x30, + 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x45, 0x4e, 0x44, 0x20, 0x53, + 0x53, 0x48, 0x32, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, + 0x45, 0x59, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, + ]) + }, + what: 'RSA public key (RFC4716 format) with unquoted comment' + }, + { source: [ + '---- BEGIN SSH2 PUBLIC KEY ----', + 'Comment: "testing ssh2 \\', + 'from node.js"', + 'AAAAB3NzaC1yc2EAAAADAQABAAAAYQDl6dxL+hgxwGNhZrq18vArbNB0UqNxvclf+ociRL', + 'lnR5O6r/czAhySO+eOc5SF7wexZzWo/COQ37tEi9reTucYFNQQWFvx4E8CRFP+UPR6hQX0', + 'fxoLSF3lxQFJ+32/rS0=', + '---- END SSH2 PUBLIC KEY ----' + ].join('\n'), + expected: { + fulltype: 'ssh-rsa', + type: 'rsa', + curve: undefined, + extra: undefined, + comment: 'testing ssh2 from node.js', + encryption: undefined, + private: undefined, + privateOrig: undefined, + public: new Buffer([ + 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x61, 0x00, + 0xe5, 0xe9, 0xdc, 0x4b, 0xfa, 0x18, 0x31, 0xc0, 0x63, 0x61, 0x66, 0xba, + 0xb5, 0xf2, 0xf0, 0x2b, 0x6c, 0xd0, 0x74, 0x52, 0xa3, 0x71, 0xbd, 0xc9, + 0x5f, 0xfa, 0x87, 0x22, 0x44, 0xb9, 0x67, 0x47, 0x93, 0xba, 0xaf, 0xf7, + 0x33, 0x02, 0x1c, 0x92, 0x3b, 0xe7, 0x8e, 0x73, 0x94, 0x85, 0xef, 0x07, + 0xb1, 0x67, 0x35, 0xa8, 0xfc, 0x23, 0x90, 0xdf, 0xbb, 0x44, 0x8b, 0xda, + 0xde, 0x4e, 0xe7, 0x18, 0x14, 0xd4, 0x10, 0x58, 0x5b, 0xf1, 0xe0, 0x4f, + 0x02, 0x44, 0x53, 0xfe, 0x50, 0xf4, 0x7a, 0x85, 0x05, 0xf4, 0x7f, 0x1a, + 0x0b, 0x48, 0x5d, 0xe5, 0xc5, 0x01, 0x49, 0xfb, 0x7d, 0xbf, 0xad, 0x2d, + ]), + publicOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x53, + 0x53, 0x48, 0x32, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, + 0x45, 0x59, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x43, 0x6f, 0x6d, 0x6d, + 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x22, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x67, 0x20, 0x73, 0x73, 0x68, 0x32, 0x20, 0x5c, 0x0a, 0x66, 0x72, 0x6f, + 0x6d, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6a, 0x73, 0x22, 0x0a, 0x41, + 0x41, 0x41, 0x41, 0x42, 0x33, 0x4e, 0x7a, 0x61, 0x43, 0x31, 0x79, 0x63, + 0x32, 0x45, 0x41, 0x41, 0x41, 0x41, 0x44, 0x41, 0x51, 0x41, 0x42, 0x41, + 0x41, 0x41, 0x41, 0x59, 0x51, 0x44, 0x6c, 0x36, 0x64, 0x78, 0x4c, 0x2b, + 0x68, 0x67, 0x78, 0x77, 0x47, 0x4e, 0x68, 0x5a, 0x72, 0x71, 0x31, 0x38, + 0x76, 0x41, 0x72, 0x62, 0x4e, 0x42, 0x30, 0x55, 0x71, 0x4e, 0x78, 0x76, + 0x63, 0x6c, 0x66, 0x2b, 0x6f, 0x63, 0x69, 0x52, 0x4c, 0x0a, 0x6c, 0x6e, + 0x52, 0x35, 0x4f, 0x36, 0x72, 0x2f, 0x63, 0x7a, 0x41, 0x68, 0x79, 0x53, + 0x4f, 0x2b, 0x65, 0x4f, 0x63, 0x35, 0x53, 0x46, 0x37, 0x77, 0x65, 0x78, + 0x5a, 0x7a, 0x57, 0x6f, 0x2f, 0x43, 0x4f, 0x51, 0x33, 0x37, 0x74, 0x45, + 0x69, 0x39, 0x72, 0x65, 0x54, 0x75, 0x63, 0x59, 0x46, 0x4e, 0x51, 0x51, + 0x57, 0x46, 0x76, 0x78, 0x34, 0x45, 0x38, 0x43, 0x52, 0x46, 0x50, 0x2b, + 0x55, 0x50, 0x52, 0x36, 0x68, 0x51, 0x58, 0x30, 0x0a, 0x66, 0x78, 0x6f, + 0x4c, 0x53, 0x46, 0x33, 0x6c, 0x78, 0x51, 0x46, 0x4a, 0x2b, 0x33, 0x32, + 0x2f, 0x72, 0x53, 0x30, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x45, + 0x4e, 0x44, 0x20, 0x53, 0x53, 0x48, 0x32, 0x20, 0x50, 0x55, 0x42, 0x4c, + 0x49, 0x43, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, + ]) + }, + what: 'RSA public key (RFC4716 format) with multi-line quoted comment' + }, + { source: [ + '---- BEGIN SSH2 PUBLIC KEY ----', + 'Comment: testing ssh2 \\', + 'from node.js', + 'AAAAB3NzaC1yc2EAAAADAQABAAAAYQDl6dxL+hgxwGNhZrq18vArbNB0UqNxvclf+ociRL', + 'lnR5O6r/czAhySO+eOc5SF7wexZzWo/COQ37tEi9reTucYFNQQWFvx4E8CRFP+UPR6hQX0', + 'fxoLSF3lxQFJ+32/rS0=', + '---- END SSH2 PUBLIC KEY ----' + ].join('\n'), + expected: { + fulltype: 'ssh-rsa', + type: 'rsa', + curve: undefined, + extra: undefined, + comment: 'testing ssh2 from node.js', + encryption: undefined, + private: undefined, + privateOrig: undefined, + public: new Buffer([ + 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x61, 0x00, + 0xe5, 0xe9, 0xdc, 0x4b, 0xfa, 0x18, 0x31, 0xc0, 0x63, 0x61, 0x66, 0xba, + 0xb5, 0xf2, 0xf0, 0x2b, 0x6c, 0xd0, 0x74, 0x52, 0xa3, 0x71, 0xbd, 0xc9, + 0x5f, 0xfa, 0x87, 0x22, 0x44, 0xb9, 0x67, 0x47, 0x93, 0xba, 0xaf, 0xf7, + 0x33, 0x02, 0x1c, 0x92, 0x3b, 0xe7, 0x8e, 0x73, 0x94, 0x85, 0xef, 0x07, + 0xb1, 0x67, 0x35, 0xa8, 0xfc, 0x23, 0x90, 0xdf, 0xbb, 0x44, 0x8b, 0xda, + 0xde, 0x4e, 0xe7, 0x18, 0x14, 0xd4, 0x10, 0x58, 0x5b, 0xf1, 0xe0, 0x4f, + 0x02, 0x44, 0x53, 0xfe, 0x50, 0xf4, 0x7a, 0x85, 0x05, 0xf4, 0x7f, 0x1a, + 0x0b, 0x48, 0x5d, 0xe5, 0xc5, 0x01, 0x49, 0xfb, 0x7d, 0xbf, 0xad, 0x2d, + ]), + publicOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x53, + 0x53, 0x48, 0x32, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, + 0x45, 0x59, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x43, 0x6f, 0x6d, 0x6d, + 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, + 0x20, 0x73, 0x73, 0x68, 0x32, 0x20, 0x5c, 0x0a, 0x66, 0x72, 0x6f, 0x6d, + 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6a, 0x73, 0x0a, 0x41, 0x41, 0x41, + 0x41, 0x42, 0x33, 0x4e, 0x7a, 0x61, 0x43, 0x31, 0x79, 0x63, 0x32, 0x45, + 0x41, 0x41, 0x41, 0x41, 0x44, 0x41, 0x51, 0x41, 0x42, 0x41, 0x41, 0x41, + 0x41, 0x59, 0x51, 0x44, 0x6c, 0x36, 0x64, 0x78, 0x4c, 0x2b, 0x68, 0x67, + 0x78, 0x77, 0x47, 0x4e, 0x68, 0x5a, 0x72, 0x71, 0x31, 0x38, 0x76, 0x41, + 0x72, 0x62, 0x4e, 0x42, 0x30, 0x55, 0x71, 0x4e, 0x78, 0x76, 0x63, 0x6c, + 0x66, 0x2b, 0x6f, 0x63, 0x69, 0x52, 0x4c, 0x0a, 0x6c, 0x6e, 0x52, 0x35, + 0x4f, 0x36, 0x72, 0x2f, 0x63, 0x7a, 0x41, 0x68, 0x79, 0x53, 0x4f, 0x2b, + 0x65, 0x4f, 0x63, 0x35, 0x53, 0x46, 0x37, 0x77, 0x65, 0x78, 0x5a, 0x7a, + 0x57, 0x6f, 0x2f, 0x43, 0x4f, 0x51, 0x33, 0x37, 0x74, 0x45, 0x69, 0x39, + 0x72, 0x65, 0x54, 0x75, 0x63, 0x59, 0x46, 0x4e, 0x51, 0x51, 0x57, 0x46, + 0x76, 0x78, 0x34, 0x45, 0x38, 0x43, 0x52, 0x46, 0x50, 0x2b, 0x55, 0x50, + 0x52, 0x36, 0x68, 0x51, 0x58, 0x30, 0x0a, 0x66, 0x78, 0x6f, 0x4c, 0x53, + 0x46, 0x33, 0x6c, 0x78, 0x51, 0x46, 0x4a, 0x2b, 0x33, 0x32, 0x2f, 0x72, + 0x53, 0x30, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x45, 0x4e, 0x44, + 0x20, 0x53, 0x53, 0x48, 0x32, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, + 0x20, 0x4b, 0x45, 0x59, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, + ]) + }, + what: 'RSA public key (RFC4716 format) with multi-line unquoted comment' + }, + { source: [ + '---- BEGIN SSH2 PUBLIC KEY ----', + 'Comment: ""', + 'AAAAB3NzaC1yc2EAAAADAQABAAAAYQDl6dxL+hgxwGNhZrq18vArbNB0UqNxvclf+ociRL', + 'lnR5O6r/czAhySO+eOc5SF7wexZzWo/COQ37tEi9reTucYFNQQWFvx4E8CRFP+UPR6hQX0', + 'fxoLSF3lxQFJ+32/rS0=', + '---- END SSH2 PUBLIC KEY ----' + ].join('\n'), + expected: { + fulltype: 'ssh-rsa', + type: 'rsa', + curve: undefined, + extra: undefined, + comment: '', + encryption: undefined, + private: undefined, + privateOrig: undefined, + public: new Buffer([ + 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x61, 0x00, + 0xe5, 0xe9, 0xdc, 0x4b, 0xfa, 0x18, 0x31, 0xc0, 0x63, 0x61, 0x66, 0xba, + 0xb5, 0xf2, 0xf0, 0x2b, 0x6c, 0xd0, 0x74, 0x52, 0xa3, 0x71, 0xbd, 0xc9, + 0x5f, 0xfa, 0x87, 0x22, 0x44, 0xb9, 0x67, 0x47, 0x93, 0xba, 0xaf, 0xf7, + 0x33, 0x02, 0x1c, 0x92, 0x3b, 0xe7, 0x8e, 0x73, 0x94, 0x85, 0xef, 0x07, + 0xb1, 0x67, 0x35, 0xa8, 0xfc, 0x23, 0x90, 0xdf, 0xbb, 0x44, 0x8b, 0xda, + 0xde, 0x4e, 0xe7, 0x18, 0x14, 0xd4, 0x10, 0x58, 0x5b, 0xf1, 0xe0, 0x4f, + 0x02, 0x44, 0x53, 0xfe, 0x50, 0xf4, 0x7a, 0x85, 0x05, 0xf4, 0x7f, 0x1a, + 0x0b, 0x48, 0x5d, 0xe5, 0xc5, 0x01, 0x49, 0xfb, 0x7d, 0xbf, 0xad, 0x2d, + ]), + publicOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x53, + 0x53, 0x48, 0x32, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, + 0x45, 0x59, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x43, 0x6f, 0x6d, 0x6d, + 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x22, 0x22, 0x0a, 0x41, 0x41, 0x41, 0x41, + 0x42, 0x33, 0x4e, 0x7a, 0x61, 0x43, 0x31, 0x79, 0x63, 0x32, 0x45, 0x41, + 0x41, 0x41, 0x41, 0x44, 0x41, 0x51, 0x41, 0x42, 0x41, 0x41, 0x41, 0x41, + 0x59, 0x51, 0x44, 0x6c, 0x36, 0x64, 0x78, 0x4c, 0x2b, 0x68, 0x67, 0x78, + 0x77, 0x47, 0x4e, 0x68, 0x5a, 0x72, 0x71, 0x31, 0x38, 0x76, 0x41, 0x72, + 0x62, 0x4e, 0x42, 0x30, 0x55, 0x71, 0x4e, 0x78, 0x76, 0x63, 0x6c, 0x66, + 0x2b, 0x6f, 0x63, 0x69, 0x52, 0x4c, 0x0a, 0x6c, 0x6e, 0x52, 0x35, 0x4f, + 0x36, 0x72, 0x2f, 0x63, 0x7a, 0x41, 0x68, 0x79, 0x53, 0x4f, 0x2b, 0x65, + 0x4f, 0x63, 0x35, 0x53, 0x46, 0x37, 0x77, 0x65, 0x78, 0x5a, 0x7a, 0x57, + 0x6f, 0x2f, 0x43, 0x4f, 0x51, 0x33, 0x37, 0x74, 0x45, 0x69, 0x39, 0x72, + 0x65, 0x54, 0x75, 0x63, 0x59, 0x46, 0x4e, 0x51, 0x51, 0x57, 0x46, 0x76, + 0x78, 0x34, 0x45, 0x38, 0x43, 0x52, 0x46, 0x50, 0x2b, 0x55, 0x50, 0x52, + 0x36, 0x68, 0x51, 0x58, 0x30, 0x0a, 0x66, 0x78, 0x6f, 0x4c, 0x53, 0x46, + 0x33, 0x6c, 0x78, 0x51, 0x46, 0x4a, 0x2b, 0x33, 0x32, 0x2f, 0x72, 0x53, + 0x30, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x45, 0x4e, 0x44, 0x20, + 0x53, 0x53, 0x48, 0x32, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, + 0x4b, 0x45, 0x59, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, + ]) + }, + what: 'RSA public key (RFC4716 format) with empty quoted comment' + }, + { source: [ + '---- BEGIN SSH2 PUBLIC KEY ----', + 'Comment: ', + 'AAAAB3NzaC1yc2EAAAADAQABAAAAYQDl6dxL+hgxwGNhZrq18vArbNB0UqNxvclf+ociRL', + 'lnR5O6r/czAhySO+eOc5SF7wexZzWo/COQ37tEi9reTucYFNQQWFvx4E8CRFP+UPR6hQX0', + 'fxoLSF3lxQFJ+32/rS0=', + '---- END SSH2 PUBLIC KEY ----' + ].join('\n'), + expected: { + fulltype: 'ssh-rsa', + type: 'rsa', + curve: undefined, + extra: undefined, + comment: '', + encryption: undefined, + private: undefined, + privateOrig: undefined, + public: new Buffer([ + 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x61, 0x00, + 0xe5, 0xe9, 0xdc, 0x4b, 0xfa, 0x18, 0x31, 0xc0, 0x63, 0x61, 0x66, 0xba, + 0xb5, 0xf2, 0xf0, 0x2b, 0x6c, 0xd0, 0x74, 0x52, 0xa3, 0x71, 0xbd, 0xc9, + 0x5f, 0xfa, 0x87, 0x22, 0x44, 0xb9, 0x67, 0x47, 0x93, 0xba, 0xaf, 0xf7, + 0x33, 0x02, 0x1c, 0x92, 0x3b, 0xe7, 0x8e, 0x73, 0x94, 0x85, 0xef, 0x07, + 0xb1, 0x67, 0x35, 0xa8, 0xfc, 0x23, 0x90, 0xdf, 0xbb, 0x44, 0x8b, 0xda, + 0xde, 0x4e, 0xe7, 0x18, 0x14, 0xd4, 0x10, 0x58, 0x5b, 0xf1, 0xe0, 0x4f, + 0x02, 0x44, 0x53, 0xfe, 0x50, 0xf4, 0x7a, 0x85, 0x05, 0xf4, 0x7f, 0x1a, + 0x0b, 0x48, 0x5d, 0xe5, 0xc5, 0x01, 0x49, 0xfb, 0x7d, 0xbf, 0xad, 0x2d, + ]), + publicOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x53, + 0x53, 0x48, 0x32, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, + 0x45, 0x59, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x43, 0x6f, 0x6d, 0x6d, + 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x0a, 0x41, 0x41, 0x41, 0x41, 0x42, 0x33, + 0x4e, 0x7a, 0x61, 0x43, 0x31, 0x79, 0x63, 0x32, 0x45, 0x41, 0x41, 0x41, + 0x41, 0x44, 0x41, 0x51, 0x41, 0x42, 0x41, 0x41, 0x41, 0x41, 0x59, 0x51, + 0x44, 0x6c, 0x36, 0x64, 0x78, 0x4c, 0x2b, 0x68, 0x67, 0x78, 0x77, 0x47, + 0x4e, 0x68, 0x5a, 0x72, 0x71, 0x31, 0x38, 0x76, 0x41, 0x72, 0x62, 0x4e, + 0x42, 0x30, 0x55, 0x71, 0x4e, 0x78, 0x76, 0x63, 0x6c, 0x66, 0x2b, 0x6f, + 0x63, 0x69, 0x52, 0x4c, 0x0a, 0x6c, 0x6e, 0x52, 0x35, 0x4f, 0x36, 0x72, + 0x2f, 0x63, 0x7a, 0x41, 0x68, 0x79, 0x53, 0x4f, 0x2b, 0x65, 0x4f, 0x63, + 0x35, 0x53, 0x46, 0x37, 0x77, 0x65, 0x78, 0x5a, 0x7a, 0x57, 0x6f, 0x2f, + 0x43, 0x4f, 0x51, 0x33, 0x37, 0x74, 0x45, 0x69, 0x39, 0x72, 0x65, 0x54, + 0x75, 0x63, 0x59, 0x46, 0x4e, 0x51, 0x51, 0x57, 0x46, 0x76, 0x78, 0x34, + 0x45, 0x38, 0x43, 0x52, 0x46, 0x50, 0x2b, 0x55, 0x50, 0x52, 0x36, 0x68, + 0x51, 0x58, 0x30, 0x0a, 0x66, 0x78, 0x6f, 0x4c, 0x53, 0x46, 0x33, 0x6c, + 0x78, 0x51, 0x46, 0x4a, 0x2b, 0x33, 0x32, 0x2f, 0x72, 0x53, 0x30, 0x3d, + 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x45, 0x4e, 0x44, 0x20, 0x53, 0x53, + 0x48, 0x32, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, 0x45, + 0x59, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, + ]) + }, + what: 'RSA public key (RFC4716 format) with empty unquoted comment' + }, + { source: [ + '---- BEGIN SSH2 PUBLIC KEY ----', + 'AAAAB3NzaC1yc2EAAAADAQABAAAAYQDl6dxL+hgxwGNhZrq18vArbNB0UqNxvclf+ociRL', + 'lnR5O6r/czAhySO+eOc5SF7wexZzWo/COQ37tEi9reTucYFNQQWFvx4E8CRFP+UPR6hQX0', + 'fxoLSF3lxQFJ+32/rS0=', + '---- END SSH2 PUBLIC KEY ----' + ].join('\n'), + expected: { + fulltype: 'ssh-rsa', + type: 'rsa', + curve: undefined, + extra: undefined, + comment: undefined, + encryption: undefined, + private: undefined, + privateOrig: undefined, + public: new Buffer([ + 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x61, 0x00, + 0xe5, 0xe9, 0xdc, 0x4b, 0xfa, 0x18, 0x31, 0xc0, 0x63, 0x61, 0x66, 0xba, + 0xb5, 0xf2, 0xf0, 0x2b, 0x6c, 0xd0, 0x74, 0x52, 0xa3, 0x71, 0xbd, 0xc9, + 0x5f, 0xfa, 0x87, 0x22, 0x44, 0xb9, 0x67, 0x47, 0x93, 0xba, 0xaf, 0xf7, + 0x33, 0x02, 0x1c, 0x92, 0x3b, 0xe7, 0x8e, 0x73, 0x94, 0x85, 0xef, 0x07, + 0xb1, 0x67, 0x35, 0xa8, 0xfc, 0x23, 0x90, 0xdf, 0xbb, 0x44, 0x8b, 0xda, + 0xde, 0x4e, 0xe7, 0x18, 0x14, 0xd4, 0x10, 0x58, 0x5b, 0xf1, 0xe0, 0x4f, + 0x02, 0x44, 0x53, 0xfe, 0x50, 0xf4, 0x7a, 0x85, 0x05, 0xf4, 0x7f, 0x1a, + 0x0b, 0x48, 0x5d, 0xe5, 0xc5, 0x01, 0x49, 0xfb, 0x7d, 0xbf, 0xad, 0x2d, + ]), + publicOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x53, + 0x53, 0x48, 0x32, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, + 0x45, 0x59, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x41, 0x41, 0x41, 0x41, + 0x42, 0x33, 0x4e, 0x7a, 0x61, 0x43, 0x31, 0x79, 0x63, 0x32, 0x45, 0x41, + 0x41, 0x41, 0x41, 0x44, 0x41, 0x51, 0x41, 0x42, 0x41, 0x41, 0x41, 0x41, + 0x59, 0x51, 0x44, 0x6c, 0x36, 0x64, 0x78, 0x4c, 0x2b, 0x68, 0x67, 0x78, + 0x77, 0x47, 0x4e, 0x68, 0x5a, 0x72, 0x71, 0x31, 0x38, 0x76, 0x41, 0x72, + 0x62, 0x4e, 0x42, 0x30, 0x55, 0x71, 0x4e, 0x78, 0x76, 0x63, 0x6c, 0x66, + 0x2b, 0x6f, 0x63, 0x69, 0x52, 0x4c, 0x0a, 0x6c, 0x6e, 0x52, 0x35, 0x4f, + 0x36, 0x72, 0x2f, 0x63, 0x7a, 0x41, 0x68, 0x79, 0x53, 0x4f, 0x2b, 0x65, + 0x4f, 0x63, 0x35, 0x53, 0x46, 0x37, 0x77, 0x65, 0x78, 0x5a, 0x7a, 0x57, + 0x6f, 0x2f, 0x43, 0x4f, 0x51, 0x33, 0x37, 0x74, 0x45, 0x69, 0x39, 0x72, + 0x65, 0x54, 0x75, 0x63, 0x59, 0x46, 0x4e, 0x51, 0x51, 0x57, 0x46, 0x76, + 0x78, 0x34, 0x45, 0x38, 0x43, 0x52, 0x46, 0x50, 0x2b, 0x55, 0x50, 0x52, + 0x36, 0x68, 0x51, 0x58, 0x30, 0x0a, 0x66, 0x78, 0x6f, 0x4c, 0x53, 0x46, + 0x33, 0x6c, 0x78, 0x51, 0x46, 0x4a, 0x2b, 0x33, 0x32, 0x2f, 0x72, 0x53, + 0x30, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x45, 0x4e, 0x44, 0x20, + 0x53, 0x53, 0x48, 0x32, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, + 0x4b, 0x45, 0x59, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, + ]) + }, + what: 'RSA public key (RFC4716 format) with no comment' + }, + { source: [ + '---- BEGIN SSH2 PUBLIC KEY ----', + '', + '', + 'AAAAB3NzaC1yc2EAAAADAQABAAAAYQDl6dxL+hgxwGNhZrq18vArbNB0UqNxvclf+ociRL', + 'lnR5O6r/czAhySO+eOc5SF7wexZzWo/COQ37tEi9reTucYFNQQWFvx4E8CRFP+UPR6hQX0', + 'fxoLSF3lxQFJ+32/rS0=', + '---- END SSH2 PUBLIC KEY ----' + ].join('\n'), + expected: { + fulltype: 'ssh-rsa', + type: 'rsa', + curve: undefined, + extra: undefined, + comment: undefined, + encryption: undefined, + private: undefined, + privateOrig: undefined, + public: new Buffer([ + 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x61, 0x00, + 0xe5, 0xe9, 0xdc, 0x4b, 0xfa, 0x18, 0x31, 0xc0, 0x63, 0x61, 0x66, 0xba, + 0xb5, 0xf2, 0xf0, 0x2b, 0x6c, 0xd0, 0x74, 0x52, 0xa3, 0x71, 0xbd, 0xc9, + 0x5f, 0xfa, 0x87, 0x22, 0x44, 0xb9, 0x67, 0x47, 0x93, 0xba, 0xaf, 0xf7, + 0x33, 0x02, 0x1c, 0x92, 0x3b, 0xe7, 0x8e, 0x73, 0x94, 0x85, 0xef, 0x07, + 0xb1, 0x67, 0x35, 0xa8, 0xfc, 0x23, 0x90, 0xdf, 0xbb, 0x44, 0x8b, 0xda, + 0xde, 0x4e, 0xe7, 0x18, 0x14, 0xd4, 0x10, 0x58, 0x5b, 0xf1, 0xe0, 0x4f, + 0x02, 0x44, 0x53, 0xfe, 0x50, 0xf4, 0x7a, 0x85, 0x05, 0xf4, 0x7f, 0x1a, + 0x0b, 0x48, 0x5d, 0xe5, 0xc5, 0x01, 0x49, 0xfb, 0x7d, 0xbf, 0xad, 0x2d, + ]), + publicOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x53, + 0x53, 0x48, 0x32, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, + 0x45, 0x59, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x0a, 0x41, 0x41, + 0x41, 0x41, 0x42, 0x33, 0x4e, 0x7a, 0x61, 0x43, 0x31, 0x79, 0x63, 0x32, + 0x45, 0x41, 0x41, 0x41, 0x41, 0x44, 0x41, 0x51, 0x41, 0x42, 0x41, 0x41, + 0x41, 0x41, 0x59, 0x51, 0x44, 0x6c, 0x36, 0x64, 0x78, 0x4c, 0x2b, 0x68, + 0x67, 0x78, 0x77, 0x47, 0x4e, 0x68, 0x5a, 0x72, 0x71, 0x31, 0x38, 0x76, + 0x41, 0x72, 0x62, 0x4e, 0x42, 0x30, 0x55, 0x71, 0x4e, 0x78, 0x76, 0x63, + 0x6c, 0x66, 0x2b, 0x6f, 0x63, 0x69, 0x52, 0x4c, 0x0a, 0x6c, 0x6e, 0x52, + 0x35, 0x4f, 0x36, 0x72, 0x2f, 0x63, 0x7a, 0x41, 0x68, 0x79, 0x53, 0x4f, + 0x2b, 0x65, 0x4f, 0x63, 0x35, 0x53, 0x46, 0x37, 0x77, 0x65, 0x78, 0x5a, + 0x7a, 0x57, 0x6f, 0x2f, 0x43, 0x4f, 0x51, 0x33, 0x37, 0x74, 0x45, 0x69, + 0x39, 0x72, 0x65, 0x54, 0x75, 0x63, 0x59, 0x46, 0x4e, 0x51, 0x51, 0x57, + 0x46, 0x76, 0x78, 0x34, 0x45, 0x38, 0x43, 0x52, 0x46, 0x50, 0x2b, 0x55, + 0x50, 0x52, 0x36, 0x68, 0x51, 0x58, 0x30, 0x0a, 0x66, 0x78, 0x6f, 0x4c, + 0x53, 0x46, 0x33, 0x6c, 0x78, 0x51, 0x46, 0x4a, 0x2b, 0x33, 0x32, 0x2f, + 0x72, 0x53, 0x30, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x45, 0x4e, + 0x44, 0x20, 0x53, 0x53, 0x48, 0x32, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, + ]) + }, + what: 'RSA public key (RFC4716 format) with blank lines' + }, + { source: [ + '---- BEGIN SSH2 PUBLIC KEY ----', + 'AAAAB3NzaC1kc3MAAACBAI4CR+tgz/kZnbmKJjccZNWKqcifcxLy/pTMnRLh5SrzQ44R8T', + 'QSbQTNnJHVpc6ucW369+TtQRpRmr4iU65ttZkZqCJ1jawXAnxcpIrVq/xBfsXfCIr26LaG', + 'qNm//vYBAPs5j648Fhg6AHyM/LewPSnek3fE8gIB9gtCsPei5L7lAAAAFQDJ3k6TdJK/eo', + 'LgUqg2bUB94Mjg9wAAAIAp9Q3SyooklLGMPdG2kj0vMWF+cVtChcjGjemhPeHXyjD5/in8', + 'gWYFifVqoYKBJhAaPP5HpPtA3BEGgIkLVGRzCk3tnwXbutGbwt7PzutbJ9LKiiR7z1HLqn', + 'E+r0//6Nhqz/ZNQPWZRbcG0l1EIQNgjuZkSzJLLO15TSPZeVhZcQAAAIAUAYobyKQ3Rl4q', + 'XAcOP8uOt5q7YHMy43JmZJnTCQ7X95TuNv5kFj7a5RkDU9HjgzSg5aabVsJAD6wDy5/rm+', + 'kJA9uXGOvHfiToh+tRjDp2SrWDERfPCRDl8oTJr36p1zqFXERwTJsNJF32QClszhzk7NYv', + 'G6kcaQC8Hhm9yccRoA==', + '---- END SSH2 PUBLIC KEY ----' + ].join('\n'), + expected: { + fulltype: 'ssh-dss', + type: 'dss', + curve: undefined, + extra: undefined, + comment: undefined, + encryption: undefined, + private: undefined, + privateOrig: undefined, + public: new Buffer([ + 0x00, 0x00, 0x00, 0x81, 0x00, 0x8e, 0x02, 0x47, 0xeb, 0x60, 0xcf, 0xf9, + 0x19, 0x9d, 0xb9, 0x8a, 0x26, 0x37, 0x1c, 0x64, 0xd5, 0x8a, 0xa9, 0xc8, + 0x9f, 0x73, 0x12, 0xf2, 0xfe, 0x94, 0xcc, 0x9d, 0x12, 0xe1, 0xe5, 0x2a, + 0xf3, 0x43, 0x8e, 0x11, 0xf1, 0x34, 0x12, 0x6d, 0x04, 0xcd, 0x9c, 0x91, + 0xd5, 0xa5, 0xce, 0xae, 0x71, 0x6d, 0xfa, 0xf7, 0xe4, 0xed, 0x41, 0x1a, + 0x51, 0x9a, 0xbe, 0x22, 0x53, 0xae, 0x6d, 0xb5, 0x99, 0x19, 0xa8, 0x22, + 0x75, 0x8d, 0xac, 0x17, 0x02, 0x7c, 0x5c, 0xa4, 0x8a, 0xd5, 0xab, 0xfc, + 0x41, 0x7e, 0xc5, 0xdf, 0x08, 0x8a, 0xf6, 0xe8, 0xb6, 0x86, 0xa8, 0xd9, + 0xbf, 0xfe, 0xf6, 0x01, 0x00, 0xfb, 0x39, 0x8f, 0xae, 0x3c, 0x16, 0x18, + 0x3a, 0x00, 0x7c, 0x8c, 0xfc, 0xb7, 0xb0, 0x3d, 0x29, 0xde, 0x93, 0x77, + 0xc4, 0xf2, 0x02, 0x01, 0xf6, 0x0b, 0x42, 0xb0, 0xf7, 0xa2, 0xe4, 0xbe, + 0xe5, 0x00, 0x00, 0x00, 0x15, 0x00, 0xc9, 0xde, 0x4e, 0x93, 0x74, 0x92, + 0xbf, 0x7a, 0x82, 0xe0, 0x52, 0xa8, 0x36, 0x6d, 0x40, 0x7d, 0xe0, 0xc8, + 0xe0, 0xf7, 0x00, 0x00, 0x00, 0x80, 0x29, 0xf5, 0x0d, 0xd2, 0xca, 0x8a, + 0x24, 0x94, 0xb1, 0x8c, 0x3d, 0xd1, 0xb6, 0x92, 0x3d, 0x2f, 0x31, 0x61, + 0x7e, 0x71, 0x5b, 0x42, 0x85, 0xc8, 0xc6, 0x8d, 0xe9, 0xa1, 0x3d, 0xe1, + 0xd7, 0xca, 0x30, 0xf9, 0xfe, 0x29, 0xfc, 0x81, 0x66, 0x05, 0x89, 0xf5, + 0x6a, 0xa1, 0x82, 0x81, 0x26, 0x10, 0x1a, 0x3c, 0xfe, 0x47, 0xa4, 0xfb, + 0x40, 0xdc, 0x11, 0x06, 0x80, 0x89, 0x0b, 0x54, 0x64, 0x73, 0x0a, 0x4d, + 0xed, 0x9f, 0x05, 0xdb, 0xba, 0xd1, 0x9b, 0xc2, 0xde, 0xcf, 0xce, 0xeb, + 0x5b, 0x27, 0xd2, 0xca, 0x8a, 0x24, 0x7b, 0xcf, 0x51, 0xcb, 0xaa, 0x71, + 0x3e, 0xaf, 0x4f, 0xff, 0xe8, 0xd8, 0x6a, 0xcf, 0xf6, 0x4d, 0x40, 0xf5, + 0x99, 0x45, 0xb7, 0x06, 0xd2, 0x5d, 0x44, 0x21, 0x03, 0x60, 0x8e, 0xe6, + 0x64, 0x4b, 0x32, 0x4b, 0x2c, 0xed, 0x79, 0x4d, 0x23, 0xd9, 0x79, 0x58, + 0x59, 0x71, 0x00, 0x00, 0x00, 0x80, 0x14, 0x01, 0x8a, 0x1b, 0xc8, 0xa4, + 0x37, 0x46, 0x5e, 0x2a, 0x5c, 0x07, 0x0e, 0x3f, 0xcb, 0x8e, 0xb7, 0x9a, + 0xbb, 0x60, 0x73, 0x32, 0xe3, 0x72, 0x66, 0x64, 0x99, 0xd3, 0x09, 0x0e, + 0xd7, 0xf7, 0x94, 0xee, 0x36, 0xfe, 0x64, 0x16, 0x3e, 0xda, 0xe5, 0x19, + 0x03, 0x53, 0xd1, 0xe3, 0x83, 0x34, 0xa0, 0xe5, 0xa6, 0x9b, 0x56, 0xc2, + 0x40, 0x0f, 0xac, 0x03, 0xcb, 0x9f, 0xeb, 0x9b, 0xe9, 0x09, 0x03, 0xdb, + 0x97, 0x18, 0xeb, 0xc7, 0x7e, 0x24, 0xe8, 0x87, 0xeb, 0x51, 0x8c, 0x3a, + 0x76, 0x4a, 0xb5, 0x83, 0x11, 0x17, 0xcf, 0x09, 0x10, 0xe5, 0xf2, 0x84, + 0xc9, 0xaf, 0x7e, 0xa9, 0xd7, 0x3a, 0x85, 0x5c, 0x44, 0x70, 0x4c, 0x9b, + 0x0d, 0x24, 0x5d, 0xf6, 0x40, 0x29, 0x6c, 0xce, 0x1c, 0xe4, 0xec, 0xd6, + 0x2f, 0x1b, 0xa9, 0x1c, 0x69, 0x00, 0xbc, 0x1e, 0x19, 0xbd, 0xc9, 0xc7, + 0x11, 0xa0, + ]), + publicOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x53, + 0x53, 0x48, 0x32, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, + 0x45, 0x59, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x41, 0x41, 0x41, 0x41, + 0x42, 0x33, 0x4e, 0x7a, 0x61, 0x43, 0x31, 0x6b, 0x63, 0x33, 0x4d, 0x41, + 0x41, 0x41, 0x43, 0x42, 0x41, 0x49, 0x34, 0x43, 0x52, 0x2b, 0x74, 0x67, + 0x7a, 0x2f, 0x6b, 0x5a, 0x6e, 0x62, 0x6d, 0x4b, 0x4a, 0x6a, 0x63, 0x63, + 0x5a, 0x4e, 0x57, 0x4b, 0x71, 0x63, 0x69, 0x66, 0x63, 0x78, 0x4c, 0x79, + 0x2f, 0x70, 0x54, 0x4d, 0x6e, 0x52, 0x4c, 0x68, 0x35, 0x53, 0x72, 0x7a, + 0x51, 0x34, 0x34, 0x52, 0x38, 0x54, 0x0a, 0x51, 0x53, 0x62, 0x51, 0x54, + 0x4e, 0x6e, 0x4a, 0x48, 0x56, 0x70, 0x63, 0x36, 0x75, 0x63, 0x57, 0x33, + 0x36, 0x39, 0x2b, 0x54, 0x74, 0x51, 0x52, 0x70, 0x52, 0x6d, 0x72, 0x34, + 0x69, 0x55, 0x36, 0x35, 0x74, 0x74, 0x5a, 0x6b, 0x5a, 0x71, 0x43, 0x4a, + 0x31, 0x6a, 0x61, 0x77, 0x58, 0x41, 0x6e, 0x78, 0x63, 0x70, 0x49, 0x72, + 0x56, 0x71, 0x2f, 0x78, 0x42, 0x66, 0x73, 0x58, 0x66, 0x43, 0x49, 0x72, + 0x32, 0x36, 0x4c, 0x61, 0x47, 0x0a, 0x71, 0x4e, 0x6d, 0x2f, 0x2f, 0x76, + 0x59, 0x42, 0x41, 0x50, 0x73, 0x35, 0x6a, 0x36, 0x34, 0x38, 0x46, 0x68, + 0x67, 0x36, 0x41, 0x48, 0x79, 0x4d, 0x2f, 0x4c, 0x65, 0x77, 0x50, 0x53, + 0x6e, 0x65, 0x6b, 0x33, 0x66, 0x45, 0x38, 0x67, 0x49, 0x42, 0x39, 0x67, + 0x74, 0x43, 0x73, 0x50, 0x65, 0x69, 0x35, 0x4c, 0x37, 0x6c, 0x41, 0x41, + 0x41, 0x41, 0x46, 0x51, 0x44, 0x4a, 0x33, 0x6b, 0x36, 0x54, 0x64, 0x4a, + 0x4b, 0x2f, 0x65, 0x6f, 0x0a, 0x4c, 0x67, 0x55, 0x71, 0x67, 0x32, 0x62, + 0x55, 0x42, 0x39, 0x34, 0x4d, 0x6a, 0x67, 0x39, 0x77, 0x41, 0x41, 0x41, + 0x49, 0x41, 0x70, 0x39, 0x51, 0x33, 0x53, 0x79, 0x6f, 0x6f, 0x6b, 0x6c, + 0x4c, 0x47, 0x4d, 0x50, 0x64, 0x47, 0x32, 0x6b, 0x6a, 0x30, 0x76, 0x4d, + 0x57, 0x46, 0x2b, 0x63, 0x56, 0x74, 0x43, 0x68, 0x63, 0x6a, 0x47, 0x6a, + 0x65, 0x6d, 0x68, 0x50, 0x65, 0x48, 0x58, 0x79, 0x6a, 0x44, 0x35, 0x2f, + 0x69, 0x6e, 0x38, 0x0a, 0x67, 0x57, 0x59, 0x46, 0x69, 0x66, 0x56, 0x71, + 0x6f, 0x59, 0x4b, 0x42, 0x4a, 0x68, 0x41, 0x61, 0x50, 0x50, 0x35, 0x48, + 0x70, 0x50, 0x74, 0x41, 0x33, 0x42, 0x45, 0x47, 0x67, 0x49, 0x6b, 0x4c, + 0x56, 0x47, 0x52, 0x7a, 0x43, 0x6b, 0x33, 0x74, 0x6e, 0x77, 0x58, 0x62, + 0x75, 0x74, 0x47, 0x62, 0x77, 0x74, 0x37, 0x50, 0x7a, 0x75, 0x74, 0x62, + 0x4a, 0x39, 0x4c, 0x4b, 0x69, 0x69, 0x52, 0x37, 0x7a, 0x31, 0x48, 0x4c, + 0x71, 0x6e, 0x0a, 0x45, 0x2b, 0x72, 0x30, 0x2f, 0x2f, 0x36, 0x4e, 0x68, + 0x71, 0x7a, 0x2f, 0x5a, 0x4e, 0x51, 0x50, 0x57, 0x5a, 0x52, 0x62, 0x63, + 0x47, 0x30, 0x6c, 0x31, 0x45, 0x49, 0x51, 0x4e, 0x67, 0x6a, 0x75, 0x5a, + 0x6b, 0x53, 0x7a, 0x4a, 0x4c, 0x4c, 0x4f, 0x31, 0x35, 0x54, 0x53, 0x50, + 0x5a, 0x65, 0x56, 0x68, 0x5a, 0x63, 0x51, 0x41, 0x41, 0x41, 0x49, 0x41, + 0x55, 0x41, 0x59, 0x6f, 0x62, 0x79, 0x4b, 0x51, 0x33, 0x52, 0x6c, 0x34, + 0x71, 0x0a, 0x58, 0x41, 0x63, 0x4f, 0x50, 0x38, 0x75, 0x4f, 0x74, 0x35, + 0x71, 0x37, 0x59, 0x48, 0x4d, 0x79, 0x34, 0x33, 0x4a, 0x6d, 0x5a, 0x4a, + 0x6e, 0x54, 0x43, 0x51, 0x37, 0x58, 0x39, 0x35, 0x54, 0x75, 0x4e, 0x76, + 0x35, 0x6b, 0x46, 0x6a, 0x37, 0x61, 0x35, 0x52, 0x6b, 0x44, 0x55, 0x39, + 0x48, 0x6a, 0x67, 0x7a, 0x53, 0x67, 0x35, 0x61, 0x61, 0x62, 0x56, 0x73, + 0x4a, 0x41, 0x44, 0x36, 0x77, 0x44, 0x79, 0x35, 0x2f, 0x72, 0x6d, 0x2b, + 0x0a, 0x6b, 0x4a, 0x41, 0x39, 0x75, 0x58, 0x47, 0x4f, 0x76, 0x48, 0x66, + 0x69, 0x54, 0x6f, 0x68, 0x2b, 0x74, 0x52, 0x6a, 0x44, 0x70, 0x32, 0x53, + 0x72, 0x57, 0x44, 0x45, 0x52, 0x66, 0x50, 0x43, 0x52, 0x44, 0x6c, 0x38, + 0x6f, 0x54, 0x4a, 0x72, 0x33, 0x36, 0x70, 0x31, 0x7a, 0x71, 0x46, 0x58, + 0x45, 0x52, 0x77, 0x54, 0x4a, 0x73, 0x4e, 0x4a, 0x46, 0x33, 0x32, 0x51, + 0x43, 0x6c, 0x73, 0x7a, 0x68, 0x7a, 0x6b, 0x37, 0x4e, 0x59, 0x76, 0x0a, + 0x47, 0x36, 0x6b, 0x63, 0x61, 0x51, 0x43, 0x38, 0x48, 0x68, 0x6d, 0x39, + 0x79, 0x63, 0x63, 0x52, 0x6f, 0x41, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, + 0x2d, 0x20, 0x45, 0x4e, 0x44, 0x20, 0x53, 0x53, 0x48, 0x32, 0x20, 0x50, + 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x2d, 0x2d, + 0x2d, 0x2d, + ]) + }, + what: 'DSA public key (RFC4716 format) with no comment' + }, + { source: [ + 'PuTTY-User-Key-File-2: ssh-rsa', + 'Encryption: none', + 'Comment: rsa-key-20141119', + 'Public-Lines: 4', + 'AAAAB3NzaC1yc2EAAAABJQAAAIBrBWETAVAyJmuNG53jwTNDlbIcH5lrEvcx6lx5', + 'bM6EKg0XmOIH96VqUjS7eRRTTD9lpBA8hYhkrOjOx93/JWB/pcVN8/B3DYHshT9O', + 'BW1DCkrNwut2pbJ2oZOBirhhAr+xqWFr3551FqbzaCIXpOKubr4EcIwCipBl6PxL', + 'USfHgw==', + 'Private-Lines: 8', + 'AAAAgFPhnxy71xKM0NZhwPDH3BJgkoS+0jFUDdsDy/B34CJmJe/mh6VhPHXtZ5nb', + 'cMuqduD2Nj1GEPT2Oe4t8y/DWXfFkO0YNEQRw5Z3WhXheBH9Li26KmHf8TdK838u', + 'ec+4Vji/vFYaMU6wVL73joWcAT5Dnh38ZpFc98W264N5DZaNAAAAQQDJYPKtCs/l', + '46KJmN3lUANdI4QIuWQ+Zllz7p94FfdotnkvqG++Bp1wOqJSCih6UViwLfvpNZtG', + 'MCtk46WNhc0zAAAAQQCIDI3hZSz/THhai8b3nonUD65IQp5bO6p+kYZtaBn1d+c+', + 'eT7UCXwU5bW271Zasw8hq9Cdlb91fGGR41ZMfvxxAAAAQFSBjCa/fzeICVkPFBaK', + 'QUmXjQ3IcPTOr90mSAiPnAAppSwTj5SYSfE9rSVb+EhQ0hk2VKWIfocNHBD1MAN9', + 'zb4=', + 'Private-MAC: 0bc5cc619df85b79dfd3ea25f0e59230cf671cd2' + ].join('\n'), + expected: { + fulltype: 'ssh-rsa', + type: 'rsa', + curve: undefined, + extra: undefined, + comment: 'rsa-key-20141119', + encryption: undefined, + private: new Buffer([ + 0x30, 0x82, 0x02, 0x59, 0x02, 0x01, 0x00, 0x02, 0x81, 0x80, 0x6b, 0x05, + 0x61, 0x13, 0x01, 0x50, 0x32, 0x26, 0x6b, 0x8d, 0x1b, 0x9d, 0xe3, 0xc1, + 0x33, 0x43, 0x95, 0xb2, 0x1c, 0x1f, 0x99, 0x6b, 0x12, 0xf7, 0x31, 0xea, + 0x5c, 0x79, 0x6c, 0xce, 0x84, 0x2a, 0x0d, 0x17, 0x98, 0xe2, 0x07, 0xf7, + 0xa5, 0x6a, 0x52, 0x34, 0xbb, 0x79, 0x14, 0x53, 0x4c, 0x3f, 0x65, 0xa4, + 0x10, 0x3c, 0x85, 0x88, 0x64, 0xac, 0xe8, 0xce, 0xc7, 0xdd, 0xff, 0x25, + 0x60, 0x7f, 0xa5, 0xc5, 0x4d, 0xf3, 0xf0, 0x77, 0x0d, 0x81, 0xec, 0x85, + 0x3f, 0x4e, 0x05, 0x6d, 0x43, 0x0a, 0x4a, 0xcd, 0xc2, 0xeb, 0x76, 0xa5, + 0xb2, 0x76, 0xa1, 0x93, 0x81, 0x8a, 0xb8, 0x61, 0x02, 0xbf, 0xb1, 0xa9, + 0x61, 0x6b, 0xdf, 0x9e, 0x75, 0x16, 0xa6, 0xf3, 0x68, 0x22, 0x17, 0xa4, + 0xe2, 0xae, 0x6e, 0xbe, 0x04, 0x70, 0x8c, 0x02, 0x8a, 0x90, 0x65, 0xe8, + 0xfc, 0x4b, 0x51, 0x27, 0xc7, 0x83, 0x02, 0x01, 0x25, 0x02, 0x81, 0x80, + 0x53, 0xe1, 0x9f, 0x1c, 0xbb, 0xd7, 0x12, 0x8c, 0xd0, 0xd6, 0x61, 0xc0, + 0xf0, 0xc7, 0xdc, 0x12, 0x60, 0x92, 0x84, 0xbe, 0xd2, 0x31, 0x54, 0x0d, + 0xdb, 0x03, 0xcb, 0xf0, 0x77, 0xe0, 0x22, 0x66, 0x25, 0xef, 0xe6, 0x87, + 0xa5, 0x61, 0x3c, 0x75, 0xed, 0x67, 0x99, 0xdb, 0x70, 0xcb, 0xaa, 0x76, + 0xe0, 0xf6, 0x36, 0x3d, 0x46, 0x10, 0xf4, 0xf6, 0x39, 0xee, 0x2d, 0xf3, + 0x2f, 0xc3, 0x59, 0x77, 0xc5, 0x90, 0xed, 0x18, 0x34, 0x44, 0x11, 0xc3, + 0x96, 0x77, 0x5a, 0x15, 0xe1, 0x78, 0x11, 0xfd, 0x2e, 0x2d, 0xba, 0x2a, + 0x61, 0xdf, 0xf1, 0x37, 0x4a, 0xf3, 0x7f, 0x2e, 0x79, 0xcf, 0xb8, 0x56, + 0x38, 0xbf, 0xbc, 0x56, 0x1a, 0x31, 0x4e, 0xb0, 0x54, 0xbe, 0xf7, 0x8e, + 0x85, 0x9c, 0x01, 0x3e, 0x43, 0x9e, 0x1d, 0xfc, 0x66, 0x91, 0x5c, 0xf7, + 0xc5, 0xb6, 0xeb, 0x83, 0x79, 0x0d, 0x96, 0x8d, 0x02, 0x41, 0x00, 0xc9, + 0x60, 0xf2, 0xad, 0x0a, 0xcf, 0xe5, 0xe3, 0xa2, 0x89, 0x98, 0xdd, 0xe5, + 0x50, 0x03, 0x5d, 0x23, 0x84, 0x08, 0xb9, 0x64, 0x3e, 0x66, 0x59, 0x73, + 0xee, 0x9f, 0x78, 0x15, 0xf7, 0x68, 0xb6, 0x79, 0x2f, 0xa8, 0x6f, 0xbe, + 0x06, 0x9d, 0x70, 0x3a, 0xa2, 0x52, 0x0a, 0x28, 0x7a, 0x51, 0x58, 0xb0, + 0x2d, 0xfb, 0xe9, 0x35, 0x9b, 0x46, 0x30, 0x2b, 0x64, 0xe3, 0xa5, 0x8d, + 0x85, 0xcd, 0x33, 0x02, 0x41, 0x00, 0x88, 0x0c, 0x8d, 0xe1, 0x65, 0x2c, + 0xff, 0x4c, 0x78, 0x5a, 0x8b, 0xc6, 0xf7, 0x9e, 0x89, 0xd4, 0x0f, 0xae, + 0x48, 0x42, 0x9e, 0x5b, 0x3b, 0xaa, 0x7e, 0x91, 0x86, 0x6d, 0x68, 0x19, + 0xf5, 0x77, 0xe7, 0x3e, 0x79, 0x3e, 0xd4, 0x09, 0x7c, 0x14, 0xe5, 0xb5, + 0xb6, 0xef, 0x56, 0x5a, 0xb3, 0x0f, 0x21, 0xab, 0xd0, 0x9d, 0x95, 0xbf, + 0x75, 0x7c, 0x61, 0x91, 0xe3, 0x56, 0x4c, 0x7e, 0xfc, 0x71, 0x02, 0x41, + 0x00, 0xb9, 0x0c, 0xfa, 0xac, 0xd9, 0x80, 0xc5, 0x69, 0x64, 0xed, 0x24, + 0xb0, 0x3a, 0x80, 0xe0, 0x7f, 0x19, 0xb7, 0x99, 0x50, 0x69, 0xf4, 0x26, + 0xb3, 0x10, 0x96, 0x15, 0xff, 0xa5, 0x7b, 0x90, 0xa7, 0xad, 0xa1, 0x6a, + 0x58, 0xd8, 0x21, 0xc1, 0x1b, 0x05, 0x72, 0x90, 0x93, 0xb6, 0x7e, 0x3c, + 0xe9, 0xb6, 0xa6, 0xcb, 0xcf, 0x61, 0xb1, 0x47, 0x6a, 0x88, 0xbd, 0x92, + 0xeb, 0x28, 0x1a, 0x16, 0x81, 0x02, 0x40, 0x50, 0xe4, 0xde, 0xbd, 0x5e, + 0xc0, 0xcf, 0x26, 0x8c, 0xc0, 0x37, 0x6f, 0x62, 0xcc, 0xf8, 0x01, 0x8c, + 0xc8, 0x7d, 0xfe, 0x18, 0xf7, 0xf9, 0xf6, 0xac, 0x1f, 0x2d, 0x55, 0xcf, + 0x32, 0x07, 0x93, 0x66, 0xe6, 0xe0, 0x4e, 0xde, 0xf0, 0xe1, 0xfe, 0x96, + 0x6c, 0x0b, 0xe8, 0x41, 0x2f, 0x02, 0xaf, 0x0d, 0x1a, 0x0d, 0x56, 0xc7, + 0xbd, 0xf2, 0xd4, 0x55, 0xb0, 0xb0, 0xaf, 0xda, 0x75, 0x04, 0xcd, 0x02, + 0x40, 0x54, 0x81, 0x8c, 0x26, 0xbf, 0x7f, 0x37, 0x88, 0x09, 0x59, 0x0f, + 0x14, 0x16, 0x8a, 0x41, 0x49, 0x97, 0x8d, 0x0d, 0xc8, 0x70, 0xf4, 0xce, + 0xaf, 0xdd, 0x26, 0x48, 0x08, 0x8f, 0x9c, 0x00, 0x29, 0xa5, 0x2c, 0x13, + 0x8f, 0x94, 0x98, 0x49, 0xf1, 0x3d, 0xad, 0x25, 0x5b, 0xf8, 0x48, 0x50, + 0xd2, 0x19, 0x36, 0x54, 0xa5, 0x88, 0x7e, 0x87, 0x0d, 0x1c, 0x10, 0xf5, + 0x30, 0x03, 0x7d, 0xcd, 0xbe, + ]), + privateOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x52, + 0x53, 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, + 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, + 0x57, 0x51, 0x49, 0x42, 0x41, 0x41, 0x4b, 0x42, 0x67, 0x47, 0x73, 0x46, + 0x59, 0x52, 0x4d, 0x42, 0x55, 0x44, 0x49, 0x6d, 0x61, 0x34, 0x30, 0x62, + 0x6e, 0x65, 0x50, 0x42, 0x4d, 0x30, 0x4f, 0x56, 0x73, 0x68, 0x77, 0x66, + 0x6d, 0x57, 0x73, 0x53, 0x39, 0x7a, 0x48, 0x71, 0x58, 0x48, 0x6c, 0x73, + 0x7a, 0x6f, 0x51, 0x71, 0x44, 0x52, 0x65, 0x59, 0x34, 0x67, 0x66, 0x33, + 0x0a, 0x70, 0x57, 0x70, 0x53, 0x4e, 0x4c, 0x74, 0x35, 0x46, 0x46, 0x4e, + 0x4d, 0x50, 0x32, 0x57, 0x6b, 0x45, 0x44, 0x79, 0x46, 0x69, 0x47, 0x53, + 0x73, 0x36, 0x4d, 0x37, 0x48, 0x33, 0x66, 0x38, 0x6c, 0x59, 0x48, 0x2b, + 0x6c, 0x78, 0x55, 0x33, 0x7a, 0x38, 0x48, 0x63, 0x4e, 0x67, 0x65, 0x79, + 0x46, 0x50, 0x30, 0x34, 0x46, 0x62, 0x55, 0x4d, 0x4b, 0x53, 0x73, 0x33, + 0x43, 0x36, 0x33, 0x61, 0x6c, 0x0a, 0x73, 0x6e, 0x61, 0x68, 0x6b, 0x34, + 0x47, 0x4b, 0x75, 0x47, 0x45, 0x43, 0x76, 0x37, 0x47, 0x70, 0x59, 0x57, + 0x76, 0x66, 0x6e, 0x6e, 0x55, 0x57, 0x70, 0x76, 0x4e, 0x6f, 0x49, 0x68, + 0x65, 0x6b, 0x34, 0x71, 0x35, 0x75, 0x76, 0x67, 0x52, 0x77, 0x6a, 0x41, + 0x4b, 0x4b, 0x6b, 0x47, 0x58, 0x6f, 0x2f, 0x45, 0x74, 0x52, 0x4a, 0x38, + 0x65, 0x44, 0x41, 0x67, 0x45, 0x6c, 0x41, 0x6f, 0x47, 0x41, 0x0a, 0x55, + 0x2b, 0x47, 0x66, 0x48, 0x4c, 0x76, 0x58, 0x45, 0x6f, 0x7a, 0x51, 0x31, + 0x6d, 0x48, 0x41, 0x38, 0x4d, 0x66, 0x63, 0x45, 0x6d, 0x43, 0x53, 0x68, + 0x4c, 0x37, 0x53, 0x4d, 0x56, 0x51, 0x4e, 0x32, 0x77, 0x50, 0x4c, 0x38, + 0x48, 0x66, 0x67, 0x49, 0x6d, 0x59, 0x6c, 0x37, 0x2b, 0x61, 0x48, 0x70, + 0x57, 0x45, 0x38, 0x64, 0x65, 0x31, 0x6e, 0x6d, 0x64, 0x74, 0x77, 0x79, + 0x36, 0x70, 0x32, 0x0a, 0x34, 0x50, 0x59, 0x32, 0x50, 0x55, 0x59, 0x51, + 0x39, 0x50, 0x59, 0x35, 0x37, 0x69, 0x33, 0x7a, 0x4c, 0x38, 0x4e, 0x5a, + 0x64, 0x38, 0x57, 0x51, 0x37, 0x52, 0x67, 0x30, 0x52, 0x42, 0x48, 0x44, + 0x6c, 0x6e, 0x64, 0x61, 0x46, 0x65, 0x46, 0x34, 0x45, 0x66, 0x30, 0x75, + 0x4c, 0x62, 0x6f, 0x71, 0x59, 0x64, 0x2f, 0x78, 0x4e, 0x30, 0x72, 0x7a, + 0x66, 0x79, 0x35, 0x35, 0x7a, 0x37, 0x68, 0x57, 0x0a, 0x4f, 0x4c, 0x2b, + 0x38, 0x56, 0x68, 0x6f, 0x78, 0x54, 0x72, 0x42, 0x55, 0x76, 0x76, 0x65, + 0x4f, 0x68, 0x5a, 0x77, 0x42, 0x50, 0x6b, 0x4f, 0x65, 0x48, 0x66, 0x78, + 0x6d, 0x6b, 0x56, 0x7a, 0x33, 0x78, 0x62, 0x62, 0x72, 0x67, 0x33, 0x6b, + 0x4e, 0x6c, 0x6f, 0x30, 0x43, 0x51, 0x51, 0x44, 0x4a, 0x59, 0x50, 0x4b, + 0x74, 0x43, 0x73, 0x2f, 0x6c, 0x34, 0x36, 0x4b, 0x4a, 0x6d, 0x4e, 0x33, + 0x6c, 0x0a, 0x55, 0x41, 0x4e, 0x64, 0x49, 0x34, 0x51, 0x49, 0x75, 0x57, + 0x51, 0x2b, 0x5a, 0x6c, 0x6c, 0x7a, 0x37, 0x70, 0x39, 0x34, 0x46, 0x66, + 0x64, 0x6f, 0x74, 0x6e, 0x6b, 0x76, 0x71, 0x47, 0x2b, 0x2b, 0x42, 0x70, + 0x31, 0x77, 0x4f, 0x71, 0x4a, 0x53, 0x43, 0x69, 0x68, 0x36, 0x55, 0x56, + 0x69, 0x77, 0x4c, 0x66, 0x76, 0x70, 0x4e, 0x5a, 0x74, 0x47, 0x4d, 0x43, + 0x74, 0x6b, 0x34, 0x36, 0x57, 0x4e, 0x0a, 0x68, 0x63, 0x30, 0x7a, 0x41, + 0x6b, 0x45, 0x41, 0x69, 0x41, 0x79, 0x4e, 0x34, 0x57, 0x55, 0x73, 0x2f, + 0x30, 0x78, 0x34, 0x57, 0x6f, 0x76, 0x47, 0x39, 0x35, 0x36, 0x4a, 0x31, + 0x41, 0x2b, 0x75, 0x53, 0x45, 0x4b, 0x65, 0x57, 0x7a, 0x75, 0x71, 0x66, + 0x70, 0x47, 0x47, 0x62, 0x57, 0x67, 0x5a, 0x39, 0x58, 0x66, 0x6e, 0x50, + 0x6e, 0x6b, 0x2b, 0x31, 0x41, 0x6c, 0x38, 0x46, 0x4f, 0x57, 0x31, 0x0a, + 0x74, 0x75, 0x39, 0x57, 0x57, 0x72, 0x4d, 0x50, 0x49, 0x61, 0x76, 0x51, + 0x6e, 0x5a, 0x57, 0x2f, 0x64, 0x58, 0x78, 0x68, 0x6b, 0x65, 0x4e, 0x57, + 0x54, 0x48, 0x37, 0x38, 0x63, 0x51, 0x4a, 0x42, 0x41, 0x4c, 0x6b, 0x4d, + 0x2b, 0x71, 0x7a, 0x5a, 0x67, 0x4d, 0x56, 0x70, 0x5a, 0x4f, 0x30, 0x6b, + 0x73, 0x44, 0x71, 0x41, 0x34, 0x48, 0x38, 0x5a, 0x74, 0x35, 0x6c, 0x51, + 0x61, 0x66, 0x51, 0x6d, 0x0a, 0x73, 0x78, 0x43, 0x57, 0x46, 0x66, 0x2b, + 0x6c, 0x65, 0x35, 0x43, 0x6e, 0x72, 0x61, 0x46, 0x71, 0x57, 0x4e, 0x67, + 0x68, 0x77, 0x52, 0x73, 0x46, 0x63, 0x70, 0x43, 0x54, 0x74, 0x6e, 0x34, + 0x38, 0x36, 0x62, 0x61, 0x6d, 0x79, 0x38, 0x39, 0x68, 0x73, 0x55, 0x64, + 0x71, 0x69, 0x4c, 0x32, 0x53, 0x36, 0x79, 0x67, 0x61, 0x46, 0x6f, 0x45, + 0x43, 0x51, 0x46, 0x44, 0x6b, 0x33, 0x72, 0x31, 0x65, 0x0a, 0x77, 0x4d, + 0x38, 0x6d, 0x6a, 0x4d, 0x41, 0x33, 0x62, 0x32, 0x4c, 0x4d, 0x2b, 0x41, + 0x47, 0x4d, 0x79, 0x48, 0x33, 0x2b, 0x47, 0x50, 0x66, 0x35, 0x39, 0x71, + 0x77, 0x66, 0x4c, 0x56, 0x58, 0x50, 0x4d, 0x67, 0x65, 0x54, 0x5a, 0x75, + 0x62, 0x67, 0x54, 0x74, 0x37, 0x77, 0x34, 0x66, 0x36, 0x57, 0x62, 0x41, + 0x76, 0x6f, 0x51, 0x53, 0x38, 0x43, 0x72, 0x77, 0x30, 0x61, 0x44, 0x56, + 0x62, 0x48, 0x0a, 0x76, 0x66, 0x4c, 0x55, 0x56, 0x62, 0x43, 0x77, 0x72, + 0x39, 0x70, 0x31, 0x42, 0x4d, 0x30, 0x43, 0x51, 0x46, 0x53, 0x42, 0x6a, + 0x43, 0x61, 0x2f, 0x66, 0x7a, 0x65, 0x49, 0x43, 0x56, 0x6b, 0x50, 0x46, + 0x42, 0x61, 0x4b, 0x51, 0x55, 0x6d, 0x58, 0x6a, 0x51, 0x33, 0x49, 0x63, + 0x50, 0x54, 0x4f, 0x72, 0x39, 0x30, 0x6d, 0x53, 0x41, 0x69, 0x50, 0x6e, + 0x41, 0x41, 0x70, 0x70, 0x53, 0x77, 0x54, 0x0a, 0x6a, 0x35, 0x53, 0x59, + 0x53, 0x66, 0x45, 0x39, 0x72, 0x53, 0x56, 0x62, 0x2b, 0x45, 0x68, 0x51, + 0x30, 0x68, 0x6b, 0x32, 0x56, 0x4b, 0x57, 0x49, 0x66, 0x6f, 0x63, 0x4e, + 0x48, 0x42, 0x44, 0x31, 0x4d, 0x41, 0x4e, 0x39, 0x7a, 0x62, 0x34, 0x3d, + 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x52, 0x53, + 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, + 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + ]), + public: new Buffer([ + 0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2d, 0x72, 0x73, 0x61, 0x00, + 0x00, 0x00, 0x01, 0x25, 0x00, 0x00, 0x00, 0x80, 0x6b, 0x05, 0x61, 0x13, + 0x01, 0x50, 0x32, 0x26, 0x6b, 0x8d, 0x1b, 0x9d, 0xe3, 0xc1, 0x33, 0x43, + 0x95, 0xb2, 0x1c, 0x1f, 0x99, 0x6b, 0x12, 0xf7, 0x31, 0xea, 0x5c, 0x79, + 0x6c, 0xce, 0x84, 0x2a, 0x0d, 0x17, 0x98, 0xe2, 0x07, 0xf7, 0xa5, 0x6a, + 0x52, 0x34, 0xbb, 0x79, 0x14, 0x53, 0x4c, 0x3f, 0x65, 0xa4, 0x10, 0x3c, + 0x85, 0x88, 0x64, 0xac, 0xe8, 0xce, 0xc7, 0xdd, 0xff, 0x25, 0x60, 0x7f, + 0xa5, 0xc5, 0x4d, 0xf3, 0xf0, 0x77, 0x0d, 0x81, 0xec, 0x85, 0x3f, 0x4e, + 0x05, 0x6d, 0x43, 0x0a, 0x4a, 0xcd, 0xc2, 0xeb, 0x76, 0xa5, 0xb2, 0x76, + 0xa1, 0x93, 0x81, 0x8a, 0xb8, 0x61, 0x02, 0xbf, 0xb1, 0xa9, 0x61, 0x6b, + 0xdf, 0x9e, 0x75, 0x16, 0xa6, 0xf3, 0x68, 0x22, 0x17, 0xa4, 0xe2, 0xae, + 0x6e, 0xbe, 0x04, 0x70, 0x8c, 0x02, 0x8a, 0x90, 0x65, 0xe8, 0xfc, 0x4b, + 0x51, 0x27, 0xc7, 0x83, + ]), + publicOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50, + 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x47, 0x63, 0x4d, 0x41, 0x30, 0x47, 0x43, + 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, + 0x51, 0x55, 0x41, 0x41, 0x34, 0x47, 0x4b, 0x41, 0x44, 0x43, 0x42, 0x68, + 0x67, 0x4b, 0x42, 0x67, 0x47, 0x73, 0x46, 0x59, 0x52, 0x4d, 0x42, 0x55, + 0x44, 0x49, 0x6d, 0x61, 0x34, 0x30, 0x62, 0x6e, 0x65, 0x50, 0x42, 0x4d, + 0x30, 0x4f, 0x56, 0x73, 0x68, 0x77, 0x66, 0x0a, 0x6d, 0x57, 0x73, 0x53, + 0x39, 0x7a, 0x48, 0x71, 0x58, 0x48, 0x6c, 0x73, 0x7a, 0x6f, 0x51, 0x71, + 0x44, 0x52, 0x65, 0x59, 0x34, 0x67, 0x66, 0x33, 0x70, 0x57, 0x70, 0x53, + 0x4e, 0x4c, 0x74, 0x35, 0x46, 0x46, 0x4e, 0x4d, 0x50, 0x32, 0x57, 0x6b, + 0x45, 0x44, 0x79, 0x46, 0x69, 0x47, 0x53, 0x73, 0x36, 0x4d, 0x37, 0x48, + 0x33, 0x66, 0x38, 0x6c, 0x59, 0x48, 0x2b, 0x6c, 0x78, 0x55, 0x33, 0x7a, + 0x0a, 0x38, 0x48, 0x63, 0x4e, 0x67, 0x65, 0x79, 0x46, 0x50, 0x30, 0x34, + 0x46, 0x62, 0x55, 0x4d, 0x4b, 0x53, 0x73, 0x33, 0x43, 0x36, 0x33, 0x61, + 0x6c, 0x73, 0x6e, 0x61, 0x68, 0x6b, 0x34, 0x47, 0x4b, 0x75, 0x47, 0x45, + 0x43, 0x76, 0x37, 0x47, 0x70, 0x59, 0x57, 0x76, 0x66, 0x6e, 0x6e, 0x55, + 0x57, 0x70, 0x76, 0x4e, 0x6f, 0x49, 0x68, 0x65, 0x6b, 0x34, 0x71, 0x35, + 0x75, 0x76, 0x67, 0x52, 0x77, 0x0a, 0x6a, 0x41, 0x4b, 0x4b, 0x6b, 0x47, + 0x58, 0x6f, 0x2f, 0x45, 0x74, 0x52, 0x4a, 0x38, 0x65, 0x44, 0x41, 0x67, + 0x45, 0x6c, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, + 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, + ]), + ppk: true, + privateMAC: '0bc5cc619df85b79dfd3ea25f0e59230cf671cd2', + _converted: true, + _macresult: true + }, + what: 'Unencrypted RSA key (PPK format)' + }, + { source: [ + 'PuTTY-User-Key-File-2: ssh-rsa', + 'Encryption: aes256-cbc', + 'Comment: rsa-key-20141119', + 'Public-Lines: 4', + 'AAAAB3NzaC1yc2EAAAABJQAAAIBrBWETAVAyJmuNG53jwTNDlbIcH5lrEvcx6lx5', + 'bM6EKg0XmOIH96VqUjS7eRRTTD9lpBA8hYhkrOjOx93/JWB/pcVN8/B3DYHshT9O', + 'BW1DCkrNwut2pbJ2oZOBirhhAr+xqWFr3551FqbzaCIXpOKubr4EcIwCipBl6PxL', + 'USfHgw==', + 'Private-Lines: 8', + '8O3NrBePR4+4RHHys8wrRKCmgx3Gsdz1cKoRJJDgnnrQxuAxBTVUlVTC2vzSOXrP', + 'jlKdRP9DbtrL5YF8g9HkMPpzzTdgpiEAGikpIc+L0sJhN+S9VvMoXRRKqyuB7o1C', + 'xZhAeRaZ68izdUUbFd7ajUwBNpGoFppOznGXyf/3/Ao9FfoTKReZzeBd/e2/JFhc', + 'nsYkSbtWfKQBVXF1Fhr10UwRWSMaVJSDkcSuk8ghICoKBBCgRBnZFap0SR77oIJh', + 'DKgmNFktoKzEqh111vYPhQyEEyGNxpD0aEPaGUJEjPEd3C5a46n7mIiqrNX7QJoo', + 'xxZtkueGdXWaoe5mBf1tFc+nCA1l72nUlghJZooQhnO9NPpieu6NNZ8X+tFQ1Rq/', + 'xvOZHzpDOOeOgWdV7oAmRDbDjYPh0H67z2OKCFaP0Z9kgmnwqV2IJvTDrexj1VwY', + '6kFaPldnK+ohXl37oVIlWA==', + 'Private-MAC: 9d09a15a122e48955682ba969d33c75ba8e4be2c' + ].join('\n'), + expected: { + fulltype: 'ssh-rsa', + type: 'rsa', + curve: undefined, + extra: undefined, + comment: 'rsa-key-20141119', + encryption: 'aes256-cbc', + private: new Buffer([ + 0xf0, 0xed, 0xcd, 0xac, 0x17, 0x8f, 0x47, 0x8f, 0xb8, 0x44, 0x71, 0xf2, + 0xb3, 0xcc, 0x2b, 0x44, 0xa0, 0xa6, 0x83, 0x1d, 0xc6, 0xb1, 0xdc, 0xf5, + 0x70, 0xaa, 0x11, 0x24, 0x90, 0xe0, 0x9e, 0x7a, 0xd0, 0xc6, 0xe0, 0x31, + 0x05, 0x35, 0x54, 0x95, 0x54, 0xc2, 0xda, 0xfc, 0xd2, 0x39, 0x7a, 0xcf, + 0x8e, 0x52, 0x9d, 0x44, 0xff, 0x43, 0x6e, 0xda, 0xcb, 0xe5, 0x81, 0x7c, + 0x83, 0xd1, 0xe4, 0x30, 0xfa, 0x73, 0xcd, 0x37, 0x60, 0xa6, 0x21, 0x00, + 0x1a, 0x29, 0x29, 0x21, 0xcf, 0x8b, 0xd2, 0xc2, 0x61, 0x37, 0xe4, 0xbd, + 0x56, 0xf3, 0x28, 0x5d, 0x14, 0x4a, 0xab, 0x2b, 0x81, 0xee, 0x8d, 0x42, + 0xc5, 0x98, 0x40, 0x79, 0x16, 0x99, 0xeb, 0xc8, 0xb3, 0x75, 0x45, 0x1b, + 0x15, 0xde, 0xda, 0x8d, 0x4c, 0x01, 0x36, 0x91, 0xa8, 0x16, 0x9a, 0x4e, + 0xce, 0x71, 0x97, 0xc9, 0xff, 0xf7, 0xfc, 0x0a, 0x3d, 0x15, 0xfa, 0x13, + 0x29, 0x17, 0x99, 0xcd, 0xe0, 0x5d, 0xfd, 0xed, 0xbf, 0x24, 0x58, 0x5c, + 0x9e, 0xc6, 0x24, 0x49, 0xbb, 0x56, 0x7c, 0xa4, 0x01, 0x55, 0x71, 0x75, + 0x16, 0x1a, 0xf5, 0xd1, 0x4c, 0x11, 0x59, 0x23, 0x1a, 0x54, 0x94, 0x83, + 0x91, 0xc4, 0xae, 0x93, 0xc8, 0x21, 0x20, 0x2a, 0x0a, 0x04, 0x10, 0xa0, + 0x44, 0x19, 0xd9, 0x15, 0xaa, 0x74, 0x49, 0x1e, 0xfb, 0xa0, 0x82, 0x61, + 0x0c, 0xa8, 0x26, 0x34, 0x59, 0x2d, 0xa0, 0xac, 0xc4, 0xaa, 0x1d, 0x75, + 0xd6, 0xf6, 0x0f, 0x85, 0x0c, 0x84, 0x13, 0x21, 0x8d, 0xc6, 0x90, 0xf4, + 0x68, 0x43, 0xda, 0x19, 0x42, 0x44, 0x8c, 0xf1, 0x1d, 0xdc, 0x2e, 0x5a, + 0xe3, 0xa9, 0xfb, 0x98, 0x88, 0xaa, 0xac, 0xd5, 0xfb, 0x40, 0x9a, 0x28, + 0xc7, 0x16, 0x6d, 0x92, 0xe7, 0x86, 0x75, 0x75, 0x9a, 0xa1, 0xee, 0x66, + 0x05, 0xfd, 0x6d, 0x15, 0xcf, 0xa7, 0x08, 0x0d, 0x65, 0xef, 0x69, 0xd4, + 0x96, 0x08, 0x49, 0x66, 0x8a, 0x10, 0x86, 0x73, 0xbd, 0x34, 0xfa, 0x62, + 0x7a, 0xee, 0x8d, 0x35, 0x9f, 0x17, 0xfa, 0xd1, 0x50, 0xd5, 0x1a, 0xbf, + 0xc6, 0xf3, 0x99, 0x1f, 0x3a, 0x43, 0x38, 0xe7, 0x8e, 0x81, 0x67, 0x55, + 0xee, 0x80, 0x26, 0x44, 0x36, 0xc3, 0x8d, 0x83, 0xe1, 0xd0, 0x7e, 0xbb, + 0xcf, 0x63, 0x8a, 0x08, 0x56, 0x8f, 0xd1, 0x9f, 0x64, 0x82, 0x69, 0xf0, + 0xa9, 0x5d, 0x88, 0x26, 0xf4, 0xc3, 0xad, 0xec, 0x63, 0xd5, 0x5c, 0x18, + 0xea, 0x41, 0x5a, 0x3e, 0x57, 0x67, 0x2b, 0xea, 0x21, 0x5e, 0x5d, 0xfb, + 0xa1, 0x52, 0x25, 0x58, + ]), + privateOrig: undefined, + public: new Buffer([ + 0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2d, 0x72, 0x73, 0x61, 0x00, + 0x00, 0x00, 0x01, 0x25, 0x00, 0x00, 0x00, 0x80, 0x6b, 0x05, 0x61, 0x13, + 0x01, 0x50, 0x32, 0x26, 0x6b, 0x8d, 0x1b, 0x9d, 0xe3, 0xc1, 0x33, 0x43, + 0x95, 0xb2, 0x1c, 0x1f, 0x99, 0x6b, 0x12, 0xf7, 0x31, 0xea, 0x5c, 0x79, + 0x6c, 0xce, 0x84, 0x2a, 0x0d, 0x17, 0x98, 0xe2, 0x07, 0xf7, 0xa5, 0x6a, + 0x52, 0x34, 0xbb, 0x79, 0x14, 0x53, 0x4c, 0x3f, 0x65, 0xa4, 0x10, 0x3c, + 0x85, 0x88, 0x64, 0xac, 0xe8, 0xce, 0xc7, 0xdd, 0xff, 0x25, 0x60, 0x7f, + 0xa5, 0xc5, 0x4d, 0xf3, 0xf0, 0x77, 0x0d, 0x81, 0xec, 0x85, 0x3f, 0x4e, + 0x05, 0x6d, 0x43, 0x0a, 0x4a, 0xcd, 0xc2, 0xeb, 0x76, 0xa5, 0xb2, 0x76, + 0xa1, 0x93, 0x81, 0x8a, 0xb8, 0x61, 0x02, 0xbf, 0xb1, 0xa9, 0x61, 0x6b, + 0xdf, 0x9e, 0x75, 0x16, 0xa6, 0xf3, 0x68, 0x22, 0x17, 0xa4, 0xe2, 0xae, + 0x6e, 0xbe, 0x04, 0x70, 0x8c, 0x02, 0x8a, 0x90, 0x65, 0xe8, 0xfc, 0x4b, + 0x51, 0x27, 0xc7, 0x83, + ]), + publicOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50, + 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x47, 0x63, 0x4d, 0x41, 0x30, 0x47, 0x43, + 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, + 0x51, 0x55, 0x41, 0x41, 0x34, 0x47, 0x4b, 0x41, 0x44, 0x43, 0x42, 0x68, + 0x67, 0x4b, 0x42, 0x67, 0x47, 0x73, 0x46, 0x59, 0x52, 0x4d, 0x42, 0x55, + 0x44, 0x49, 0x6d, 0x61, 0x34, 0x30, 0x62, 0x6e, 0x65, 0x50, 0x42, 0x4d, + 0x30, 0x4f, 0x56, 0x73, 0x68, 0x77, 0x66, 0x0a, 0x6d, 0x57, 0x73, 0x53, + 0x39, 0x7a, 0x48, 0x71, 0x58, 0x48, 0x6c, 0x73, 0x7a, 0x6f, 0x51, 0x71, + 0x44, 0x52, 0x65, 0x59, 0x34, 0x67, 0x66, 0x33, 0x70, 0x57, 0x70, 0x53, + 0x4e, 0x4c, 0x74, 0x35, 0x46, 0x46, 0x4e, 0x4d, 0x50, 0x32, 0x57, 0x6b, + 0x45, 0x44, 0x79, 0x46, 0x69, 0x47, 0x53, 0x73, 0x36, 0x4d, 0x37, 0x48, + 0x33, 0x66, 0x38, 0x6c, 0x59, 0x48, 0x2b, 0x6c, 0x78, 0x55, 0x33, 0x7a, + 0x0a, 0x38, 0x48, 0x63, 0x4e, 0x67, 0x65, 0x79, 0x46, 0x50, 0x30, 0x34, + 0x46, 0x62, 0x55, 0x4d, 0x4b, 0x53, 0x73, 0x33, 0x43, 0x36, 0x33, 0x61, + 0x6c, 0x73, 0x6e, 0x61, 0x68, 0x6b, 0x34, 0x47, 0x4b, 0x75, 0x47, 0x45, + 0x43, 0x76, 0x37, 0x47, 0x70, 0x59, 0x57, 0x76, 0x66, 0x6e, 0x6e, 0x55, + 0x57, 0x70, 0x76, 0x4e, 0x6f, 0x49, 0x68, 0x65, 0x6b, 0x34, 0x71, 0x35, + 0x75, 0x76, 0x67, 0x52, 0x77, 0x0a, 0x6a, 0x41, 0x4b, 0x4b, 0x6b, 0x47, + 0x58, 0x6f, 0x2f, 0x45, 0x74, 0x52, 0x4a, 0x38, 0x65, 0x44, 0x41, 0x67, + 0x45, 0x6c, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, + 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, + ]), + ppk: true, + privateMAC: '9d09a15a122e48955682ba969d33c75ba8e4be2c' + }, + what: 'Encrypted RSA key (PPK format)' + }, + { source: [ + 'PuTTY-User-Key-File-2: ssh-dss', + 'Encryption: none', + 'Comment: dsa-key-20141202', + 'Public-Lines: 10', + 'AAAAB3NzaC1kc3MAAACBAJn2I8YefRo3BsEeinQt8KQ4cEyArAs7Y/W733oRSYOI', + 'zWF1Ju124ysKrmg2okv+05CYcjV3Yp4AzQeomYAlgmB/7xCEnWaEnxCwAxmrrJMm', + 'PrkwNjHOIi7yM5QOE90IM/Q+IJA4EPBfSb+Xr8fYhrp53KNHVSnc2KkOqpo2FsIj', + 'AAAAFQC4NlP50GqyUqq2B82Vh/w5j3TzwQAAAIAeSGom9LLNdzcwCHnGfxKNnEz3', + '55KITADTxiIpBvnQW+eDHwQvIw6V2Oc73bKCu5ZirZmIMW5w6KjQVwkuQBoF9Koq', + '/2u6VeevtL9pD6TBzSLMVw5pV3PmE4/C/eLiaUxZLIHdbzpqPkAvAUBrXKkj0ijz', + 'cNzCp1fuF8H0pvR8yQAAAIAmvV+kqWhUgDYwNNz1qDaoS8XdsOponutZ/0stRQ66', + 'mKAy8kNVNNQ6oUx1XFl1WUt4iyFY/2Rz2fZhLz5/TbZRK5ygo666WgnxB/Ud4GAx', + '/BPQTghOJJOL00vJk+8jVCGNDc942V6nFXznDMXwqxhRCW6dm+2lTh7ntrli8mCk', + '5g==', + 'Private-Lines: 1', + 'AAAAFAiWSgDAM5Mq9r5dj3uPGnYvFbPb', + 'Private-MAC: c07e1d3ae080613e7cdb63ab06bde2e805bc420b' + ].join('\n'), + expected: { + fulltype: 'ssh-dss', + type: 'dss', + curve: undefined, + extra: undefined, + comment: 'dsa-key-20141202', + encryption: undefined, + private: new Buffer([ + 0x30, 0x82, 0x01, 0xba, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0x99, + 0xf6, 0x23, 0xc6, 0x1e, 0x7d, 0x1a, 0x37, 0x06, 0xc1, 0x1e, 0x8a, 0x74, + 0x2d, 0xf0, 0xa4, 0x38, 0x70, 0x4c, 0x80, 0xac, 0x0b, 0x3b, 0x63, 0xf5, + 0xbb, 0xdf, 0x7a, 0x11, 0x49, 0x83, 0x88, 0xcd, 0x61, 0x75, 0x26, 0xed, + 0x76, 0xe3, 0x2b, 0x0a, 0xae, 0x68, 0x36, 0xa2, 0x4b, 0xfe, 0xd3, 0x90, + 0x98, 0x72, 0x35, 0x77, 0x62, 0x9e, 0x00, 0xcd, 0x07, 0xa8, 0x99, 0x80, + 0x25, 0x82, 0x60, 0x7f, 0xef, 0x10, 0x84, 0x9d, 0x66, 0x84, 0x9f, 0x10, + 0xb0, 0x03, 0x19, 0xab, 0xac, 0x93, 0x26, 0x3e, 0xb9, 0x30, 0x36, 0x31, + 0xce, 0x22, 0x2e, 0xf2, 0x33, 0x94, 0x0e, 0x13, 0xdd, 0x08, 0x33, 0xf4, + 0x3e, 0x20, 0x90, 0x38, 0x10, 0xf0, 0x5f, 0x49, 0xbf, 0x97, 0xaf, 0xc7, + 0xd8, 0x86, 0xba, 0x79, 0xdc, 0xa3, 0x47, 0x55, 0x29, 0xdc, 0xd8, 0xa9, + 0x0e, 0xaa, 0x9a, 0x36, 0x16, 0xc2, 0x23, 0x02, 0x15, 0x00, 0xb8, 0x36, + 0x53, 0xf9, 0xd0, 0x6a, 0xb2, 0x52, 0xaa, 0xb6, 0x07, 0xcd, 0x95, 0x87, + 0xfc, 0x39, 0x8f, 0x74, 0xf3, 0xc1, 0x02, 0x81, 0x80, 0x1e, 0x48, 0x6a, + 0x26, 0xf4, 0xb2, 0xcd, 0x77, 0x37, 0x30, 0x08, 0x79, 0xc6, 0x7f, 0x12, + 0x8d, 0x9c, 0x4c, 0xf7, 0xe7, 0x92, 0x88, 0x4c, 0x00, 0xd3, 0xc6, 0x22, + 0x29, 0x06, 0xf9, 0xd0, 0x5b, 0xe7, 0x83, 0x1f, 0x04, 0x2f, 0x23, 0x0e, + 0x95, 0xd8, 0xe7, 0x3b, 0xdd, 0xb2, 0x82, 0xbb, 0x96, 0x62, 0xad, 0x99, + 0x88, 0x31, 0x6e, 0x70, 0xe8, 0xa8, 0xd0, 0x57, 0x09, 0x2e, 0x40, 0x1a, + 0x05, 0xf4, 0xaa, 0x2a, 0xff, 0x6b, 0xba, 0x55, 0xe7, 0xaf, 0xb4, 0xbf, + 0x69, 0x0f, 0xa4, 0xc1, 0xcd, 0x22, 0xcc, 0x57, 0x0e, 0x69, 0x57, 0x73, + 0xe6, 0x13, 0x8f, 0xc2, 0xfd, 0xe2, 0xe2, 0x69, 0x4c, 0x59, 0x2c, 0x81, + 0xdd, 0x6f, 0x3a, 0x6a, 0x3e, 0x40, 0x2f, 0x01, 0x40, 0x6b, 0x5c, 0xa9, + 0x23, 0xd2, 0x28, 0xf3, 0x70, 0xdc, 0xc2, 0xa7, 0x57, 0xee, 0x17, 0xc1, + 0xf4, 0xa6, 0xf4, 0x7c, 0xc9, 0x02, 0x81, 0x80, 0x26, 0xbd, 0x5f, 0xa4, + 0xa9, 0x68, 0x54, 0x80, 0x36, 0x30, 0x34, 0xdc, 0xf5, 0xa8, 0x36, 0xa8, + 0x4b, 0xc5, 0xdd, 0xb0, 0xea, 0x68, 0x9e, 0xeb, 0x59, 0xff, 0x4b, 0x2d, + 0x45, 0x0e, 0xba, 0x98, 0xa0, 0x32, 0xf2, 0x43, 0x55, 0x34, 0xd4, 0x3a, + 0xa1, 0x4c, 0x75, 0x5c, 0x59, 0x75, 0x59, 0x4b, 0x78, 0x8b, 0x21, 0x58, + 0xff, 0x64, 0x73, 0xd9, 0xf6, 0x61, 0x2f, 0x3e, 0x7f, 0x4d, 0xb6, 0x51, + 0x2b, 0x9c, 0xa0, 0xa3, 0xae, 0xba, 0x5a, 0x09, 0xf1, 0x07, 0xf5, 0x1d, + 0xe0, 0x60, 0x31, 0xfc, 0x13, 0xd0, 0x4e, 0x08, 0x4e, 0x24, 0x93, 0x8b, + 0xd3, 0x4b, 0xc9, 0x93, 0xef, 0x23, 0x54, 0x21, 0x8d, 0x0d, 0xcf, 0x78, + 0xd9, 0x5e, 0xa7, 0x15, 0x7c, 0xe7, 0x0c, 0xc5, 0xf0, 0xab, 0x18, 0x51, + 0x09, 0x6e, 0x9d, 0x9b, 0xed, 0xa5, 0x4e, 0x1e, 0xe7, 0xb6, 0xb9, 0x62, + 0xf2, 0x60, 0xa4, 0xe6, 0x02, 0x14, 0x08, 0x96, 0x4a, 0x00, 0xc0, 0x33, + 0x93, 0x2a, 0xf6, 0xbe, 0x5d, 0x8f, 0x7b, 0x8f, 0x1a, 0x76, 0x2f, 0x15, + 0xb3, 0xdb, + ]), + privateOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x44, + 0x53, 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, + 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x42, + 0x75, 0x67, 0x49, 0x42, 0x41, 0x41, 0x4b, 0x42, 0x67, 0x51, 0x43, 0x5a, + 0x39, 0x69, 0x50, 0x47, 0x48, 0x6e, 0x30, 0x61, 0x4e, 0x77, 0x62, 0x42, + 0x48, 0x6f, 0x70, 0x30, 0x4c, 0x66, 0x43, 0x6b, 0x4f, 0x48, 0x42, 0x4d, + 0x67, 0x4b, 0x77, 0x4c, 0x4f, 0x32, 0x50, 0x31, 0x75, 0x39, 0x39, 0x36, + 0x45, 0x55, 0x6d, 0x44, 0x69, 0x4d, 0x31, 0x68, 0x64, 0x53, 0x62, 0x74, + 0x0a, 0x64, 0x75, 0x4d, 0x72, 0x43, 0x71, 0x35, 0x6f, 0x4e, 0x71, 0x4a, + 0x4c, 0x2f, 0x74, 0x4f, 0x51, 0x6d, 0x48, 0x49, 0x31, 0x64, 0x32, 0x4b, + 0x65, 0x41, 0x4d, 0x30, 0x48, 0x71, 0x4a, 0x6d, 0x41, 0x4a, 0x59, 0x4a, + 0x67, 0x66, 0x2b, 0x38, 0x51, 0x68, 0x4a, 0x31, 0x6d, 0x68, 0x4a, 0x38, + 0x51, 0x73, 0x41, 0x4d, 0x5a, 0x71, 0x36, 0x79, 0x54, 0x4a, 0x6a, 0x36, + 0x35, 0x4d, 0x44, 0x59, 0x78, 0x0a, 0x7a, 0x69, 0x49, 0x75, 0x38, 0x6a, + 0x4f, 0x55, 0x44, 0x68, 0x50, 0x64, 0x43, 0x44, 0x50, 0x30, 0x50, 0x69, + 0x43, 0x51, 0x4f, 0x42, 0x44, 0x77, 0x58, 0x30, 0x6d, 0x2f, 0x6c, 0x36, + 0x2f, 0x48, 0x32, 0x49, 0x61, 0x36, 0x65, 0x64, 0x79, 0x6a, 0x52, 0x31, + 0x55, 0x70, 0x33, 0x4e, 0x69, 0x70, 0x44, 0x71, 0x71, 0x61, 0x4e, 0x68, + 0x62, 0x43, 0x49, 0x77, 0x49, 0x56, 0x41, 0x4c, 0x67, 0x32, 0x0a, 0x55, + 0x2f, 0x6e, 0x51, 0x61, 0x72, 0x4a, 0x53, 0x71, 0x72, 0x59, 0x48, 0x7a, + 0x5a, 0x57, 0x48, 0x2f, 0x44, 0x6d, 0x50, 0x64, 0x50, 0x50, 0x42, 0x41, + 0x6f, 0x47, 0x41, 0x48, 0x6b, 0x68, 0x71, 0x4a, 0x76, 0x53, 0x79, 0x7a, + 0x58, 0x63, 0x33, 0x4d, 0x41, 0x68, 0x35, 0x78, 0x6e, 0x38, 0x53, 0x6a, + 0x5a, 0x78, 0x4d, 0x39, 0x2b, 0x65, 0x53, 0x69, 0x45, 0x77, 0x41, 0x30, + 0x38, 0x59, 0x69, 0x0a, 0x4b, 0x51, 0x62, 0x35, 0x30, 0x46, 0x76, 0x6e, + 0x67, 0x78, 0x38, 0x45, 0x4c, 0x79, 0x4d, 0x4f, 0x6c, 0x64, 0x6a, 0x6e, + 0x4f, 0x39, 0x32, 0x79, 0x67, 0x72, 0x75, 0x57, 0x59, 0x71, 0x32, 0x5a, + 0x69, 0x44, 0x46, 0x75, 0x63, 0x4f, 0x69, 0x6f, 0x30, 0x46, 0x63, 0x4a, + 0x4c, 0x6b, 0x41, 0x61, 0x42, 0x66, 0x53, 0x71, 0x4b, 0x76, 0x39, 0x72, + 0x75, 0x6c, 0x58, 0x6e, 0x72, 0x37, 0x53, 0x2f, 0x0a, 0x61, 0x51, 0x2b, + 0x6b, 0x77, 0x63, 0x30, 0x69, 0x7a, 0x46, 0x63, 0x4f, 0x61, 0x56, 0x64, + 0x7a, 0x35, 0x68, 0x4f, 0x50, 0x77, 0x76, 0x33, 0x69, 0x34, 0x6d, 0x6c, + 0x4d, 0x57, 0x53, 0x79, 0x42, 0x33, 0x57, 0x38, 0x36, 0x61, 0x6a, 0x35, + 0x41, 0x4c, 0x77, 0x46, 0x41, 0x61, 0x31, 0x79, 0x70, 0x49, 0x39, 0x49, + 0x6f, 0x38, 0x33, 0x44, 0x63, 0x77, 0x71, 0x64, 0x58, 0x37, 0x68, 0x66, + 0x42, 0x0a, 0x39, 0x4b, 0x62, 0x30, 0x66, 0x4d, 0x6b, 0x43, 0x67, 0x59, + 0x41, 0x6d, 0x76, 0x56, 0x2b, 0x6b, 0x71, 0x57, 0x68, 0x55, 0x67, 0x44, + 0x59, 0x77, 0x4e, 0x4e, 0x7a, 0x31, 0x71, 0x44, 0x61, 0x6f, 0x53, 0x38, + 0x58, 0x64, 0x73, 0x4f, 0x70, 0x6f, 0x6e, 0x75, 0x74, 0x5a, 0x2f, 0x30, + 0x73, 0x74, 0x52, 0x51, 0x36, 0x36, 0x6d, 0x4b, 0x41, 0x79, 0x38, 0x6b, + 0x4e, 0x56, 0x4e, 0x4e, 0x51, 0x36, 0x0a, 0x6f, 0x55, 0x78, 0x31, 0x58, + 0x46, 0x6c, 0x31, 0x57, 0x55, 0x74, 0x34, 0x69, 0x79, 0x46, 0x59, 0x2f, + 0x32, 0x52, 0x7a, 0x32, 0x66, 0x5a, 0x68, 0x4c, 0x7a, 0x35, 0x2f, 0x54, + 0x62, 0x5a, 0x52, 0x4b, 0x35, 0x79, 0x67, 0x6f, 0x36, 0x36, 0x36, 0x57, + 0x67, 0x6e, 0x78, 0x42, 0x2f, 0x55, 0x64, 0x34, 0x47, 0x41, 0x78, 0x2f, + 0x42, 0x50, 0x51, 0x54, 0x67, 0x68, 0x4f, 0x4a, 0x4a, 0x4f, 0x4c, 0x0a, + 0x30, 0x30, 0x76, 0x4a, 0x6b, 0x2b, 0x38, 0x6a, 0x56, 0x43, 0x47, 0x4e, + 0x44, 0x63, 0x39, 0x34, 0x32, 0x56, 0x36, 0x6e, 0x46, 0x58, 0x7a, 0x6e, + 0x44, 0x4d, 0x58, 0x77, 0x71, 0x78, 0x68, 0x52, 0x43, 0x57, 0x36, 0x64, + 0x6d, 0x2b, 0x32, 0x6c, 0x54, 0x68, 0x37, 0x6e, 0x74, 0x72, 0x6c, 0x69, + 0x38, 0x6d, 0x43, 0x6b, 0x35, 0x67, 0x49, 0x55, 0x43, 0x4a, 0x5a, 0x4b, + 0x41, 0x4d, 0x41, 0x7a, 0x0a, 0x6b, 0x79, 0x72, 0x32, 0x76, 0x6c, 0x32, + 0x50, 0x65, 0x34, 0x38, 0x61, 0x64, 0x69, 0x38, 0x56, 0x73, 0x39, 0x73, + 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x44, + 0x53, 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, + 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + ]), + public: new Buffer([ + 0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2d, 0x64, 0x73, 0x73, 0x00, + 0x00, 0x00, 0x81, 0x00, 0x99, 0xf6, 0x23, 0xc6, 0x1e, 0x7d, 0x1a, 0x37, + 0x06, 0xc1, 0x1e, 0x8a, 0x74, 0x2d, 0xf0, 0xa4, 0x38, 0x70, 0x4c, 0x80, + 0xac, 0x0b, 0x3b, 0x63, 0xf5, 0xbb, 0xdf, 0x7a, 0x11, 0x49, 0x83, 0x88, + 0xcd, 0x61, 0x75, 0x26, 0xed, 0x76, 0xe3, 0x2b, 0x0a, 0xae, 0x68, 0x36, + 0xa2, 0x4b, 0xfe, 0xd3, 0x90, 0x98, 0x72, 0x35, 0x77, 0x62, 0x9e, 0x00, + 0xcd, 0x07, 0xa8, 0x99, 0x80, 0x25, 0x82, 0x60, 0x7f, 0xef, 0x10, 0x84, + 0x9d, 0x66, 0x84, 0x9f, 0x10, 0xb0, 0x03, 0x19, 0xab, 0xac, 0x93, 0x26, + 0x3e, 0xb9, 0x30, 0x36, 0x31, 0xce, 0x22, 0x2e, 0xf2, 0x33, 0x94, 0x0e, + 0x13, 0xdd, 0x08, 0x33, 0xf4, 0x3e, 0x20, 0x90, 0x38, 0x10, 0xf0, 0x5f, + 0x49, 0xbf, 0x97, 0xaf, 0xc7, 0xd8, 0x86, 0xba, 0x79, 0xdc, 0xa3, 0x47, + 0x55, 0x29, 0xdc, 0xd8, 0xa9, 0x0e, 0xaa, 0x9a, 0x36, 0x16, 0xc2, 0x23, + 0x00, 0x00, 0x00, 0x15, 0x00, 0xb8, 0x36, 0x53, 0xf9, 0xd0, 0x6a, 0xb2, + 0x52, 0xaa, 0xb6, 0x07, 0xcd, 0x95, 0x87, 0xfc, 0x39, 0x8f, 0x74, 0xf3, + 0xc1, 0x00, 0x00, 0x00, 0x80, 0x1e, 0x48, 0x6a, 0x26, 0xf4, 0xb2, 0xcd, + 0x77, 0x37, 0x30, 0x08, 0x79, 0xc6, 0x7f, 0x12, 0x8d, 0x9c, 0x4c, 0xf7, + 0xe7, 0x92, 0x88, 0x4c, 0x00, 0xd3, 0xc6, 0x22, 0x29, 0x06, 0xf9, 0xd0, + 0x5b, 0xe7, 0x83, 0x1f, 0x04, 0x2f, 0x23, 0x0e, 0x95, 0xd8, 0xe7, 0x3b, + 0xdd, 0xb2, 0x82, 0xbb, 0x96, 0x62, 0xad, 0x99, 0x88, 0x31, 0x6e, 0x70, + 0xe8, 0xa8, 0xd0, 0x57, 0x09, 0x2e, 0x40, 0x1a, 0x05, 0xf4, 0xaa, 0x2a, + 0xff, 0x6b, 0xba, 0x55, 0xe7, 0xaf, 0xb4, 0xbf, 0x69, 0x0f, 0xa4, 0xc1, + 0xcd, 0x22, 0xcc, 0x57, 0x0e, 0x69, 0x57, 0x73, 0xe6, 0x13, 0x8f, 0xc2, + 0xfd, 0xe2, 0xe2, 0x69, 0x4c, 0x59, 0x2c, 0x81, 0xdd, 0x6f, 0x3a, 0x6a, + 0x3e, 0x40, 0x2f, 0x01, 0x40, 0x6b, 0x5c, 0xa9, 0x23, 0xd2, 0x28, 0xf3, + 0x70, 0xdc, 0xc2, 0xa7, 0x57, 0xee, 0x17, 0xc1, 0xf4, 0xa6, 0xf4, 0x7c, + 0xc9, 0x00, 0x00, 0x00, 0x80, 0x26, 0xbd, 0x5f, 0xa4, 0xa9, 0x68, 0x54, + 0x80, 0x36, 0x30, 0x34, 0xdc, 0xf5, 0xa8, 0x36, 0xa8, 0x4b, 0xc5, 0xdd, + 0xb0, 0xea, 0x68, 0x9e, 0xeb, 0x59, 0xff, 0x4b, 0x2d, 0x45, 0x0e, 0xba, + 0x98, 0xa0, 0x32, 0xf2, 0x43, 0x55, 0x34, 0xd4, 0x3a, 0xa1, 0x4c, 0x75, + 0x5c, 0x59, 0x75, 0x59, 0x4b, 0x78, 0x8b, 0x21, 0x58, 0xff, 0x64, 0x73, + 0xd9, 0xf6, 0x61, 0x2f, 0x3e, 0x7f, 0x4d, 0xb6, 0x51, 0x2b, 0x9c, 0xa0, + 0xa3, 0xae, 0xba, 0x5a, 0x09, 0xf1, 0x07, 0xf5, 0x1d, 0xe0, 0x60, 0x31, + 0xfc, 0x13, 0xd0, 0x4e, 0x08, 0x4e, 0x24, 0x93, 0x8b, 0xd3, 0x4b, 0xc9, + 0x93, 0xef, 0x23, 0x54, 0x21, 0x8d, 0x0d, 0xcf, 0x78, 0xd9, 0x5e, 0xa7, + 0x15, 0x7c, 0xe7, 0x0c, 0xc5, 0xf0, 0xab, 0x18, 0x51, 0x09, 0x6e, 0x9d, + 0x9b, 0xed, 0xa5, 0x4e, 0x1e, 0xe7, 0xb6, 0xb9, 0x62, 0xf2, 0x60, 0xa4, + 0xe6, + ]), + publicOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50, + 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x42, 0x74, 0x6a, 0x43, 0x43, 0x41, + 0x53, 0x73, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4d, 0x34, 0x34, 0x42, + 0x41, 0x45, 0x77, 0x67, 0x67, 0x45, 0x65, 0x41, 0x6f, 0x47, 0x42, 0x41, + 0x4a, 0x6e, 0x32, 0x49, 0x38, 0x59, 0x65, 0x66, 0x52, 0x6f, 0x33, 0x42, + 0x73, 0x45, 0x65, 0x69, 0x6e, 0x51, 0x74, 0x38, 0x4b, 0x51, 0x34, 0x63, + 0x45, 0x79, 0x41, 0x72, 0x41, 0x73, 0x37, 0x0a, 0x59, 0x2f, 0x57, 0x37, + 0x33, 0x33, 0x6f, 0x52, 0x53, 0x59, 0x4f, 0x49, 0x7a, 0x57, 0x46, 0x31, + 0x4a, 0x75, 0x31, 0x32, 0x34, 0x79, 0x73, 0x4b, 0x72, 0x6d, 0x67, 0x32, + 0x6f, 0x6b, 0x76, 0x2b, 0x30, 0x35, 0x43, 0x59, 0x63, 0x6a, 0x56, 0x33, + 0x59, 0x70, 0x34, 0x41, 0x7a, 0x51, 0x65, 0x6f, 0x6d, 0x59, 0x41, 0x6c, + 0x67, 0x6d, 0x42, 0x2f, 0x37, 0x78, 0x43, 0x45, 0x6e, 0x57, 0x61, 0x45, + 0x0a, 0x6e, 0x78, 0x43, 0x77, 0x41, 0x78, 0x6d, 0x72, 0x72, 0x4a, 0x4d, + 0x6d, 0x50, 0x72, 0x6b, 0x77, 0x4e, 0x6a, 0x48, 0x4f, 0x49, 0x69, 0x37, + 0x79, 0x4d, 0x35, 0x51, 0x4f, 0x45, 0x39, 0x30, 0x49, 0x4d, 0x2f, 0x51, + 0x2b, 0x49, 0x4a, 0x41, 0x34, 0x45, 0x50, 0x42, 0x66, 0x53, 0x62, 0x2b, + 0x58, 0x72, 0x38, 0x66, 0x59, 0x68, 0x72, 0x70, 0x35, 0x33, 0x4b, 0x4e, + 0x48, 0x56, 0x53, 0x6e, 0x63, 0x0a, 0x32, 0x4b, 0x6b, 0x4f, 0x71, 0x70, + 0x6f, 0x32, 0x46, 0x73, 0x49, 0x6a, 0x41, 0x68, 0x55, 0x41, 0x75, 0x44, + 0x5a, 0x54, 0x2b, 0x64, 0x42, 0x71, 0x73, 0x6c, 0x4b, 0x71, 0x74, 0x67, + 0x66, 0x4e, 0x6c, 0x59, 0x66, 0x38, 0x4f, 0x59, 0x39, 0x30, 0x38, 0x38, + 0x45, 0x43, 0x67, 0x59, 0x41, 0x65, 0x53, 0x47, 0x6f, 0x6d, 0x39, 0x4c, + 0x4c, 0x4e, 0x64, 0x7a, 0x63, 0x77, 0x43, 0x48, 0x6e, 0x47, 0x0a, 0x66, + 0x78, 0x4b, 0x4e, 0x6e, 0x45, 0x7a, 0x33, 0x35, 0x35, 0x4b, 0x49, 0x54, + 0x41, 0x44, 0x54, 0x78, 0x69, 0x49, 0x70, 0x42, 0x76, 0x6e, 0x51, 0x57, + 0x2b, 0x65, 0x44, 0x48, 0x77, 0x51, 0x76, 0x49, 0x77, 0x36, 0x56, 0x32, + 0x4f, 0x63, 0x37, 0x33, 0x62, 0x4b, 0x43, 0x75, 0x35, 0x5a, 0x69, 0x72, + 0x5a, 0x6d, 0x49, 0x4d, 0x57, 0x35, 0x77, 0x36, 0x4b, 0x6a, 0x51, 0x56, + 0x77, 0x6b, 0x75, 0x0a, 0x51, 0x42, 0x6f, 0x46, 0x39, 0x4b, 0x6f, 0x71, + 0x2f, 0x32, 0x75, 0x36, 0x56, 0x65, 0x65, 0x76, 0x74, 0x4c, 0x39, 0x70, + 0x44, 0x36, 0x54, 0x42, 0x7a, 0x53, 0x4c, 0x4d, 0x56, 0x77, 0x35, 0x70, + 0x56, 0x33, 0x50, 0x6d, 0x45, 0x34, 0x2f, 0x43, 0x2f, 0x65, 0x4c, 0x69, + 0x61, 0x55, 0x78, 0x5a, 0x4c, 0x49, 0x48, 0x64, 0x62, 0x7a, 0x70, 0x71, + 0x50, 0x6b, 0x41, 0x76, 0x41, 0x55, 0x42, 0x72, 0x0a, 0x58, 0x4b, 0x6b, + 0x6a, 0x30, 0x69, 0x6a, 0x7a, 0x63, 0x4e, 0x7a, 0x43, 0x70, 0x31, 0x66, + 0x75, 0x46, 0x38, 0x48, 0x30, 0x70, 0x76, 0x52, 0x38, 0x79, 0x51, 0x4f, + 0x42, 0x68, 0x41, 0x41, 0x43, 0x67, 0x59, 0x41, 0x6d, 0x76, 0x56, 0x2b, + 0x6b, 0x71, 0x57, 0x68, 0x55, 0x67, 0x44, 0x59, 0x77, 0x4e, 0x4e, 0x7a, + 0x31, 0x71, 0x44, 0x61, 0x6f, 0x53, 0x38, 0x58, 0x64, 0x73, 0x4f, 0x70, + 0x6f, 0x0a, 0x6e, 0x75, 0x74, 0x5a, 0x2f, 0x30, 0x73, 0x74, 0x52, 0x51, + 0x36, 0x36, 0x6d, 0x4b, 0x41, 0x79, 0x38, 0x6b, 0x4e, 0x56, 0x4e, 0x4e, + 0x51, 0x36, 0x6f, 0x55, 0x78, 0x31, 0x58, 0x46, 0x6c, 0x31, 0x57, 0x55, + 0x74, 0x34, 0x69, 0x79, 0x46, 0x59, 0x2f, 0x32, 0x52, 0x7a, 0x32, 0x66, + 0x5a, 0x68, 0x4c, 0x7a, 0x35, 0x2f, 0x54, 0x62, 0x5a, 0x52, 0x4b, 0x35, + 0x79, 0x67, 0x6f, 0x36, 0x36, 0x36, 0x0a, 0x57, 0x67, 0x6e, 0x78, 0x42, + 0x2f, 0x55, 0x64, 0x34, 0x47, 0x41, 0x78, 0x2f, 0x42, 0x50, 0x51, 0x54, + 0x67, 0x68, 0x4f, 0x4a, 0x4a, 0x4f, 0x4c, 0x30, 0x30, 0x76, 0x4a, 0x6b, + 0x2b, 0x38, 0x6a, 0x56, 0x43, 0x47, 0x4e, 0x44, 0x63, 0x39, 0x34, 0x32, + 0x56, 0x36, 0x6e, 0x46, 0x58, 0x7a, 0x6e, 0x44, 0x4d, 0x58, 0x77, 0x71, + 0x78, 0x68, 0x52, 0x43, 0x57, 0x36, 0x64, 0x6d, 0x2b, 0x32, 0x6c, 0x0a, + 0x54, 0x68, 0x37, 0x6e, 0x74, 0x72, 0x6c, 0x69, 0x38, 0x6d, 0x43, 0x6b, + 0x35, 0x67, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, + 0x44, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, 0x45, 0x59, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + ]), + ppk: true, + privateMAC: 'c07e1d3ae080613e7cdb63ab06bde2e805bc420b', + _converted: true, + _macresult: true + }, + what: 'Unencrypted DSA key (PPK format)' + }, + { source: [ + 'PuTTY-User-Key-File-2: ssh-dss', + 'Encryption: aes256-cbc', + 'Comment: dsa-key-20141202', + 'Public-Lines: 10', + 'AAAAB3NzaC1kc3MAAACBAJn2I8YefRo3BsEeinQt8KQ4cEyArAs7Y/W733oRSYOI', + 'zWF1Ju124ysKrmg2okv+05CYcjV3Yp4AzQeomYAlgmB/7xCEnWaEnxCwAxmrrJMm', + 'PrkwNjHOIi7yM5QOE90IM/Q+IJA4EPBfSb+Xr8fYhrp53KNHVSnc2KkOqpo2FsIj', + 'AAAAFQC4NlP50GqyUqq2B82Vh/w5j3TzwQAAAIAeSGom9LLNdzcwCHnGfxKNnEz3', + '55KITADTxiIpBvnQW+eDHwQvIw6V2Oc73bKCu5ZirZmIMW5w6KjQVwkuQBoF9Koq', + '/2u6VeevtL9pD6TBzSLMVw5pV3PmE4/C/eLiaUxZLIHdbzpqPkAvAUBrXKkj0ijz', + 'cNzCp1fuF8H0pvR8yQAAAIAmvV+kqWhUgDYwNNz1qDaoS8XdsOponutZ/0stRQ66', + 'mKAy8kNVNNQ6oUx1XFl1WUt4iyFY/2Rz2fZhLz5/TbZRK5ygo666WgnxB/Ud4GAx', + '/BPQTghOJJOL00vJk+8jVCGNDc942V6nFXznDMXwqxhRCW6dm+2lTh7ntrli8mCk', + '5g==', + 'Private-Lines: 1', + 'BytvbK+jNyMjiVxCO5lcE4YbW7q293oC+LZjkZ8Ajlw=', + 'Private-MAC: c3da536ea28851fc32d5d1ff01498c8fcebc1170' + ].join('\n'), + expected: { + fulltype: 'ssh-dss', + type: 'dss', + curve: undefined, + extra: undefined, + comment: 'dsa-key-20141202', + encryption: 'aes256-cbc', + private: new Buffer([ + 0x07, 0x2b, 0x6f, 0x6c, 0xaf, 0xa3, 0x37, 0x23, 0x23, 0x89, 0x5c, 0x42, + 0x3b, 0x99, 0x5c, 0x13, 0x86, 0x1b, 0x5b, 0xba, 0xb6, 0xf7, 0x7a, 0x02, + 0xf8, 0xb6, 0x63, 0x91, 0x9f, 0x00, 0x8e, 0x5c, + ]), + privateOrig: undefined, + public: new Buffer([ + 0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2d, 0x64, 0x73, 0x73, 0x00, + 0x00, 0x00, 0x81, 0x00, 0x99, 0xf6, 0x23, 0xc6, 0x1e, 0x7d, 0x1a, 0x37, + 0x06, 0xc1, 0x1e, 0x8a, 0x74, 0x2d, 0xf0, 0xa4, 0x38, 0x70, 0x4c, 0x80, + 0xac, 0x0b, 0x3b, 0x63, 0xf5, 0xbb, 0xdf, 0x7a, 0x11, 0x49, 0x83, 0x88, + 0xcd, 0x61, 0x75, 0x26, 0xed, 0x76, 0xe3, 0x2b, 0x0a, 0xae, 0x68, 0x36, + 0xa2, 0x4b, 0xfe, 0xd3, 0x90, 0x98, 0x72, 0x35, 0x77, 0x62, 0x9e, 0x00, + 0xcd, 0x07, 0xa8, 0x99, 0x80, 0x25, 0x82, 0x60, 0x7f, 0xef, 0x10, 0x84, + 0x9d, 0x66, 0x84, 0x9f, 0x10, 0xb0, 0x03, 0x19, 0xab, 0xac, 0x93, 0x26, + 0x3e, 0xb9, 0x30, 0x36, 0x31, 0xce, 0x22, 0x2e, 0xf2, 0x33, 0x94, 0x0e, + 0x13, 0xdd, 0x08, 0x33, 0xf4, 0x3e, 0x20, 0x90, 0x38, 0x10, 0xf0, 0x5f, + 0x49, 0xbf, 0x97, 0xaf, 0xc7, 0xd8, 0x86, 0xba, 0x79, 0xdc, 0xa3, 0x47, + 0x55, 0x29, 0xdc, 0xd8, 0xa9, 0x0e, 0xaa, 0x9a, 0x36, 0x16, 0xc2, 0x23, + 0x00, 0x00, 0x00, 0x15, 0x00, 0xb8, 0x36, 0x53, 0xf9, 0xd0, 0x6a, 0xb2, + 0x52, 0xaa, 0xb6, 0x07, 0xcd, 0x95, 0x87, 0xfc, 0x39, 0x8f, 0x74, 0xf3, + 0xc1, 0x00, 0x00, 0x00, 0x80, 0x1e, 0x48, 0x6a, 0x26, 0xf4, 0xb2, 0xcd, + 0x77, 0x37, 0x30, 0x08, 0x79, 0xc6, 0x7f, 0x12, 0x8d, 0x9c, 0x4c, 0xf7, + 0xe7, 0x92, 0x88, 0x4c, 0x00, 0xd3, 0xc6, 0x22, 0x29, 0x06, 0xf9, 0xd0, + 0x5b, 0xe7, 0x83, 0x1f, 0x04, 0x2f, 0x23, 0x0e, 0x95, 0xd8, 0xe7, 0x3b, + 0xdd, 0xb2, 0x82, 0xbb, 0x96, 0x62, 0xad, 0x99, 0x88, 0x31, 0x6e, 0x70, + 0xe8, 0xa8, 0xd0, 0x57, 0x09, 0x2e, 0x40, 0x1a, 0x05, 0xf4, 0xaa, 0x2a, + 0xff, 0x6b, 0xba, 0x55, 0xe7, 0xaf, 0xb4, 0xbf, 0x69, 0x0f, 0xa4, 0xc1, + 0xcd, 0x22, 0xcc, 0x57, 0x0e, 0x69, 0x57, 0x73, 0xe6, 0x13, 0x8f, 0xc2, + 0xfd, 0xe2, 0xe2, 0x69, 0x4c, 0x59, 0x2c, 0x81, 0xdd, 0x6f, 0x3a, 0x6a, + 0x3e, 0x40, 0x2f, 0x01, 0x40, 0x6b, 0x5c, 0xa9, 0x23, 0xd2, 0x28, 0xf3, + 0x70, 0xdc, 0xc2, 0xa7, 0x57, 0xee, 0x17, 0xc1, 0xf4, 0xa6, 0xf4, 0x7c, + 0xc9, 0x00, 0x00, 0x00, 0x80, 0x26, 0xbd, 0x5f, 0xa4, 0xa9, 0x68, 0x54, + 0x80, 0x36, 0x30, 0x34, 0xdc, 0xf5, 0xa8, 0x36, 0xa8, 0x4b, 0xc5, 0xdd, + 0xb0, 0xea, 0x68, 0x9e, 0xeb, 0x59, 0xff, 0x4b, 0x2d, 0x45, 0x0e, 0xba, + 0x98, 0xa0, 0x32, 0xf2, 0x43, 0x55, 0x34, 0xd4, 0x3a, 0xa1, 0x4c, 0x75, + 0x5c, 0x59, 0x75, 0x59, 0x4b, 0x78, 0x8b, 0x21, 0x58, 0xff, 0x64, 0x73, + 0xd9, 0xf6, 0x61, 0x2f, 0x3e, 0x7f, 0x4d, 0xb6, 0x51, 0x2b, 0x9c, 0xa0, + 0xa3, 0xae, 0xba, 0x5a, 0x09, 0xf1, 0x07, 0xf5, 0x1d, 0xe0, 0x60, 0x31, + 0xfc, 0x13, 0xd0, 0x4e, 0x08, 0x4e, 0x24, 0x93, 0x8b, 0xd3, 0x4b, 0xc9, + 0x93, 0xef, 0x23, 0x54, 0x21, 0x8d, 0x0d, 0xcf, 0x78, 0xd9, 0x5e, 0xa7, + 0x15, 0x7c, 0xe7, 0x0c, 0xc5, 0xf0, 0xab, 0x18, 0x51, 0x09, 0x6e, 0x9d, + 0x9b, 0xed, 0xa5, 0x4e, 0x1e, 0xe7, 0xb6, 0xb9, 0x62, 0xf2, 0x60, 0xa4, + 0xe6, + ]), + publicOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50, + 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x42, 0x74, 0x6a, 0x43, 0x43, 0x41, + 0x53, 0x73, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, 0x4d, 0x34, 0x34, 0x42, + 0x41, 0x45, 0x77, 0x67, 0x67, 0x45, 0x65, 0x41, 0x6f, 0x47, 0x42, 0x41, + 0x4a, 0x6e, 0x32, 0x49, 0x38, 0x59, 0x65, 0x66, 0x52, 0x6f, 0x33, 0x42, + 0x73, 0x45, 0x65, 0x69, 0x6e, 0x51, 0x74, 0x38, 0x4b, 0x51, 0x34, 0x63, + 0x45, 0x79, 0x41, 0x72, 0x41, 0x73, 0x37, 0x0a, 0x59, 0x2f, 0x57, 0x37, + 0x33, 0x33, 0x6f, 0x52, 0x53, 0x59, 0x4f, 0x49, 0x7a, 0x57, 0x46, 0x31, + 0x4a, 0x75, 0x31, 0x32, 0x34, 0x79, 0x73, 0x4b, 0x72, 0x6d, 0x67, 0x32, + 0x6f, 0x6b, 0x76, 0x2b, 0x30, 0x35, 0x43, 0x59, 0x63, 0x6a, 0x56, 0x33, + 0x59, 0x70, 0x34, 0x41, 0x7a, 0x51, 0x65, 0x6f, 0x6d, 0x59, 0x41, 0x6c, + 0x67, 0x6d, 0x42, 0x2f, 0x37, 0x78, 0x43, 0x45, 0x6e, 0x57, 0x61, 0x45, + 0x0a, 0x6e, 0x78, 0x43, 0x77, 0x41, 0x78, 0x6d, 0x72, 0x72, 0x4a, 0x4d, + 0x6d, 0x50, 0x72, 0x6b, 0x77, 0x4e, 0x6a, 0x48, 0x4f, 0x49, 0x69, 0x37, + 0x79, 0x4d, 0x35, 0x51, 0x4f, 0x45, 0x39, 0x30, 0x49, 0x4d, 0x2f, 0x51, + 0x2b, 0x49, 0x4a, 0x41, 0x34, 0x45, 0x50, 0x42, 0x66, 0x53, 0x62, 0x2b, + 0x58, 0x72, 0x38, 0x66, 0x59, 0x68, 0x72, 0x70, 0x35, 0x33, 0x4b, 0x4e, + 0x48, 0x56, 0x53, 0x6e, 0x63, 0x0a, 0x32, 0x4b, 0x6b, 0x4f, 0x71, 0x70, + 0x6f, 0x32, 0x46, 0x73, 0x49, 0x6a, 0x41, 0x68, 0x55, 0x41, 0x75, 0x44, + 0x5a, 0x54, 0x2b, 0x64, 0x42, 0x71, 0x73, 0x6c, 0x4b, 0x71, 0x74, 0x67, + 0x66, 0x4e, 0x6c, 0x59, 0x66, 0x38, 0x4f, 0x59, 0x39, 0x30, 0x38, 0x38, + 0x45, 0x43, 0x67, 0x59, 0x41, 0x65, 0x53, 0x47, 0x6f, 0x6d, 0x39, 0x4c, + 0x4c, 0x4e, 0x64, 0x7a, 0x63, 0x77, 0x43, 0x48, 0x6e, 0x47, 0x0a, 0x66, + 0x78, 0x4b, 0x4e, 0x6e, 0x45, 0x7a, 0x33, 0x35, 0x35, 0x4b, 0x49, 0x54, + 0x41, 0x44, 0x54, 0x78, 0x69, 0x49, 0x70, 0x42, 0x76, 0x6e, 0x51, 0x57, + 0x2b, 0x65, 0x44, 0x48, 0x77, 0x51, 0x76, 0x49, 0x77, 0x36, 0x56, 0x32, + 0x4f, 0x63, 0x37, 0x33, 0x62, 0x4b, 0x43, 0x75, 0x35, 0x5a, 0x69, 0x72, + 0x5a, 0x6d, 0x49, 0x4d, 0x57, 0x35, 0x77, 0x36, 0x4b, 0x6a, 0x51, 0x56, + 0x77, 0x6b, 0x75, 0x0a, 0x51, 0x42, 0x6f, 0x46, 0x39, 0x4b, 0x6f, 0x71, + 0x2f, 0x32, 0x75, 0x36, 0x56, 0x65, 0x65, 0x76, 0x74, 0x4c, 0x39, 0x70, + 0x44, 0x36, 0x54, 0x42, 0x7a, 0x53, 0x4c, 0x4d, 0x56, 0x77, 0x35, 0x70, + 0x56, 0x33, 0x50, 0x6d, 0x45, 0x34, 0x2f, 0x43, 0x2f, 0x65, 0x4c, 0x69, + 0x61, 0x55, 0x78, 0x5a, 0x4c, 0x49, 0x48, 0x64, 0x62, 0x7a, 0x70, 0x71, + 0x50, 0x6b, 0x41, 0x76, 0x41, 0x55, 0x42, 0x72, 0x0a, 0x58, 0x4b, 0x6b, + 0x6a, 0x30, 0x69, 0x6a, 0x7a, 0x63, 0x4e, 0x7a, 0x43, 0x70, 0x31, 0x66, + 0x75, 0x46, 0x38, 0x48, 0x30, 0x70, 0x76, 0x52, 0x38, 0x79, 0x51, 0x4f, + 0x42, 0x68, 0x41, 0x41, 0x43, 0x67, 0x59, 0x41, 0x6d, 0x76, 0x56, 0x2b, + 0x6b, 0x71, 0x57, 0x68, 0x55, 0x67, 0x44, 0x59, 0x77, 0x4e, 0x4e, 0x7a, + 0x31, 0x71, 0x44, 0x61, 0x6f, 0x53, 0x38, 0x58, 0x64, 0x73, 0x4f, 0x70, + 0x6f, 0x0a, 0x6e, 0x75, 0x74, 0x5a, 0x2f, 0x30, 0x73, 0x74, 0x52, 0x51, + 0x36, 0x36, 0x6d, 0x4b, 0x41, 0x79, 0x38, 0x6b, 0x4e, 0x56, 0x4e, 0x4e, + 0x51, 0x36, 0x6f, 0x55, 0x78, 0x31, 0x58, 0x46, 0x6c, 0x31, 0x57, 0x55, + 0x74, 0x34, 0x69, 0x79, 0x46, 0x59, 0x2f, 0x32, 0x52, 0x7a, 0x32, 0x66, + 0x5a, 0x68, 0x4c, 0x7a, 0x35, 0x2f, 0x54, 0x62, 0x5a, 0x52, 0x4b, 0x35, + 0x79, 0x67, 0x6f, 0x36, 0x36, 0x36, 0x0a, 0x57, 0x67, 0x6e, 0x78, 0x42, + 0x2f, 0x55, 0x64, 0x34, 0x47, 0x41, 0x78, 0x2f, 0x42, 0x50, 0x51, 0x54, + 0x67, 0x68, 0x4f, 0x4a, 0x4a, 0x4f, 0x4c, 0x30, 0x30, 0x76, 0x4a, 0x6b, + 0x2b, 0x38, 0x6a, 0x56, 0x43, 0x47, 0x4e, 0x44, 0x63, 0x39, 0x34, 0x32, + 0x56, 0x36, 0x6e, 0x46, 0x58, 0x7a, 0x6e, 0x44, 0x4d, 0x58, 0x77, 0x71, + 0x78, 0x68, 0x52, 0x43, 0x57, 0x36, 0x64, 0x6d, 0x2b, 0x32, 0x6c, 0x0a, + 0x54, 0x68, 0x37, 0x6e, 0x74, 0x72, 0x6c, 0x69, 0x38, 0x6d, 0x43, 0x6b, + 0x35, 0x67, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, + 0x44, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, 0x45, 0x59, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + ]), + ppk: true, + privateMAC: 'c3da536ea28851fc32d5d1ff01498c8fcebc1170' + }, + what: 'Encrypted DSA key (PPK format)' + }, +].forEach(function(v) { + require('buffer').INSPECT_MAX_BYTES = Infinity; + var result; + try { + result = parser(v.source); + } catch (ex) { + console.log('Exception encountered for: ' + v.what + '\n' + ex.stack); + process.exit(1); + } + /*if (result.private) { + for (var i = 0; i < result.private.length; ++i) { + if (i % 12 === 0) + process.stdout.write('\n'); + process.stdout.write('0x' + (result.private[i] < 16 ? '0' : '') + result.private[i].toString(16) + ', '); + } + } + console.log('');*/ + assert.deepEqual(result, + v.expected, + '[' + group + v.what + ']: parser output mismatch.' + + '\nSaw: ' + inspect(result) + + '\nExpected: ' + inspect(v.expected)); +}); diff --git a/node_modules/ssh2-streams/test/test-packet60.js b/node_modules/ssh2-streams/test/test-packet60.js new file mode 100644 index 0000000..eba9b79 --- /dev/null +++ b/node_modules/ssh2-streams/test/test-packet60.js @@ -0,0 +1,256 @@ +var SSH2Stream = require('../lib/ssh'); +var parseKey = require('../lib/utils').parseKey; +var genPubKey = require('../lib/utils').genPublicKey; + +var assert = require('assert'); +var crypto = require('crypto'); +var fs = require('fs'); + +var t = -1; +var SERVER_PRV_KEY = fs.readFileSync(__dirname + '/fixtures/ssh_host_rsa_key'); +var PARSED_SERVER_PRV_KEY = parseKey(SERVER_PRV_KEY); +var PARSED_SERVER_PUB_KEY = genPubKey(PARSED_SERVER_PRV_KEY); +var CLIENT_PRV_KEY = fs.readFileSync(__dirname + '/fixtures/id_rsa'); +var PARSED_CLIENT_PRV_KEY = parseKey(CLIENT_PRV_KEY); +var PARSED_CLIENT_PUB_KEY = genPubKey(PARSED_CLIENT_PRV_KEY); + +function makePair(cb) { + var server = new SSH2Stream({ + server: true, + hostKeys: { + 'ssh-rsa': { + privateKey: PARSED_SERVER_PRV_KEY, + publicKey: PARSED_SERVER_PUB_KEY + } + } + }); + var client = new SSH2Stream(); + + var done = []; + function tryDone(who) { + done.push(who); + if (done.length !== 2) + return; + cb(server, client); + } + + server.on('NEWKEYS', function () { tryDone('server'); }); + client.on('NEWKEYS', function () { tryDone('client'); }); + server.pipe(client).pipe(server); +} + +function signWithClientKey(blob, syncCb) { + var signType = (PARSED_CLIENT_PRV_KEY.type === 'rsa' ? 'R' : 'D') + 'SA-SHA1'; + var signature = crypto.createSign(signType); + signature.update(blob); + signature = signature.sign(PARSED_CLIENT_PRV_KEY.privateOrig); + syncCb(signature); +} + +function bufferEqual(a, b) { + if (a.length !== b.length) + return false; + for (var i = 0; i < a.length; ++i) { + if (a[i] !== b[i]) + return false; + } + return true; +} + +function publickey(server, client) { + server.on('USERAUTH_REQUEST', function(user, service, method, data) { + assert.equal(user, 'bob'); + assert.equal(service, 'ssh-connection'); + assert.equal(method, 'publickey'); + assert.equal(data.keyAlgo, PARSED_CLIENT_PUB_KEY.fulltype); + assert.equal(true, bufferEqual(data.key, PARSED_CLIENT_PUB_KEY.public)); + assert.equal(data.signature, undefined); + assert.equal(data.blob, undefined); + return server.authPKOK(data.keyAlgo, data.key); + }); + client.on('USERAUTH_PK_OK', function() { + next(); + }).authPK('bob', PARSED_CLIENT_PUB_KEY); +} + +function keyboardInteractive(server, client) { + var infoReqsRxed = 0; + + server.on('USERAUTH_REQUEST', function(user, service, method, data) { + assert.equal(user, 'bob'); + assert.equal(service, 'ssh-connection'); + assert.equal(method, 'keyboard-interactive'); + assert.equal(data, ''); + process.nextTick(function() { + server.authInfoReq('req 0', 'instructions', [ + { prompt: 'Say something to req 0', echo: true } + ]); + }); + }).on('USERAUTH_INFO_RESPONSE', function(responses) { + if (infoReqsRxed === 1) { + assert.equal(responses.length, 1); + assert.equal(responses[0], 'hello to req 0'); + process.nextTick(function() { + server.authInfoReq('req 1', 'new instructions', [ + { prompt: 'Say something to req 1', echo: true }, + { prompt: 'Say something else', echo: false } + ]); + }); + } else if (infoReqsRxed === 2) { + assert.equal(responses.length, 2); + assert.equal(responses[0], 'hello to req 1'); + assert.equal(responses[1], 'something else'); + next(); + } else { + throw new Error('Received too many info reqs: ' + infoReqsRxed); + } + }); + + client.on('USERAUTH_INFO_REQUEST', function (name, inst, lang, prompts) { + infoReqsRxed++; + if (infoReqsRxed === 1) { + assert.equal(name, 'req 0'); + assert.equal(inst, 'instructions'); + assert.equal(lang, ''); + assert.deepEqual(prompts, [ + { prompt: 'Say something to req 0', echo: true } + ]); + process.nextTick(function() { + client.authInfoRes([ 'hello to req 0' ]); + }); + } else if (infoReqsRxed === 2) { + assert.equal(name, 'req 1'); + assert.equal(inst, 'new instructions'); + assert.equal(lang, ''); + assert.deepEqual(prompts, [ + { prompt: 'Say something to req 1', echo: true }, + { prompt: 'Say something else', echo: false } + ]); + process.nextTick(function() { + client.authInfoRes([ 'hello to req 1', 'something else' ]); + }); + } else { + throw new Error('Received too many info reqs: ' + infoReqsRxed); + } + }).authKeyboard('bob'); +} + +function mixedMethods(server, client) { + var expectedStages = [ + 'SERVER_SEES_PK_CHECK', + 'SERVER_SEES_PK_REQUEST', + 'SERVER_SEES_PASSWORD', + 'SERVER_SEES_KEYBOARD_INTERACTIVE', + 'CLIENT_SEES_PK_OK', + 'CLIENT_SEES_USERAUTH_FAILURE_PK', + 'CLIENT_SEES_USERAUTH_FAILURE_PASSWORD', + 'CLIENT_SEES_KEYBOARD_REQ', + 'SERVER_SEES_KEYBOARD_RES', + 'CLIENT_SEES_USERAUTH_SUCCESS', + ]; + + server.on('USERAUTH_REQUEST', function(name, service, method, data) { + assert.equal(name, 'bob'); + assert.equal(service, 'ssh-connection'); + var expectedStage = expectedStages.shift(); + switch (expectedStage) { + case 'SERVER_SEES_PK_CHECK': + assert.equal(method, 'publickey'); + assert.equal(data.signature, undefined); + return process.nextTick(function() { + server.authPKOK(data.keyAlgo, data.key); + }); + case 'SERVER_SEES_PK_REQUEST': + assert.equal(method, 'publickey'); + assert.notEqual(data.signature, undefined); + return process.nextTick(function() { + server.authFailure( + ['publickey', 'password', 'keyboard-interactive'], + false + ); + }); + case 'SERVER_SEES_PASSWORD': + assert.equal(method, 'password'); + assert.equal(data, 'seekrit'); + return process.nextTick(function() { + server.authFailure( + ['publickey', 'password', 'keyboard-interactive'], + false + ); + }); + case 'SERVER_SEES_KEYBOARD_INTERACTIVE': + assert.equal(method, 'keyboard-interactive'); + assert.equal(data, ''); + return process.nextTick(function() { + server.authInfoReq('Password required', 'Password prompt', [ + { prompt: 'Password:', echo: false } + ]); + }); + default: + throw new Error('Server saw USERAUTH_REQUEST ' + method + + ' but expected ' + expectedStage); + } + }).on('USERAUTH_INFO_RESPONSE', function(responses) { + assert.equal(expectedStages.shift(), 'SERVER_SEES_KEYBOARD_RES'); + assert.deepEqual(responses, [ 'seekrit' ]); + process.nextTick(function() { + server.authSuccess(); + }); + }); + + + client.on('USERAUTH_PK_OK', function() { + assert.equal(expectedStages.shift(), 'CLIENT_SEES_PK_OK'); + }).on('USERAUTH_FAILURE', function() { + var expectedStage = expectedStages.shift(); + if (expectedStage !== 'CLIENT_SEES_USERAUTH_FAILURE_PK' && + expectedStage !== 'CLIENT_SEES_USERAUTH_FAILURE_PASSWORD') { + throw new Error('Client saw USERAUTH_FAILURE but expected ' + + expectedStage); + } + }).on('USERAUTH_INFO_REQUEST', function(name, inst, lang, prompts) { + assert.equal(expectedStages.shift(), 'CLIENT_SEES_KEYBOARD_REQ'); + assert.equal(name, 'Password required'); + assert.equal(inst, 'Password prompt'); + assert.equal(lang, ''); + assert.deepEqual(prompts, [ { prompt: 'Password:', echo: false } ]); + process.nextTick(function() { + client.authInfoRes([ 'seekrit' ]); + }); + }).on('USERAUTH_SUCCESS', function() { + assert.equal(expectedStages.shift(), 'CLIENT_SEES_USERAUTH_SUCCESS'); + assert.equal(expectedStages.shift(), undefined); + next(); + }); + + // Silly to submit all these auths at once, but allowed by RFC4252 + client.authPK('bob', PARSED_CLIENT_PUB_KEY); + client.authPK('bob', PARSED_CLIENT_PUB_KEY, signWithClientKey); + client.authPassword('bob', 'seekrit'); + client.authKeyboard('bob'); +} + +var tests = [ + publickey, + keyboardInteractive, + // password // ssh2-streams can't generate a password change request + mixedMethods +]; + + +function next() { + if (Array.isArray(process._events.exit)) + process._events.exit = process._events.exit[1]; + if (++t === tests.length) + return; + + var v = tests[t]; + makePair(v); +} + +process.once('exit', function() { + assert(t === tests.length, + 'Only finished ' + t + '/' + tests.length + ' tests'); +}); + +next(); diff --git a/node_modules/ssh2-streams/test/test-sftp.js b/node_modules/ssh2-streams/test/test-sftp.js new file mode 100644 index 0000000..2429bf4 --- /dev/null +++ b/node_modules/ssh2-streams/test/test-sftp.js @@ -0,0 +1,1173 @@ +var SFTPStream = require('../lib/sftp'); +var Stats = SFTPStream.Stats; +var STATUS_CODE = SFTPStream.STATUS_CODE; +var OPEN_MODE = SFTPStream.OPEN_MODE; + +var constants = require('constants'); +var basename = require('path').basename; +var assert = require('assert'); + +var group = basename(__filename, '.js') + '/'; +var t = -1; + +var tests = [ +// successful client requests + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var path_ = '/tmp/foo.txt'; + var handle_ = new Buffer('node.js'); + server.on('OPEN', function(id, path, pflags, attrs) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert(path === path_, makeMsg(what, 'Wrong path: ' + path)); + assert(pflags === (OPEN_MODE.TRUNC | OPEN_MODE.CREAT | OPEN_MODE.WRITE), + makeMsg(what, 'Wrong flags: ' + flagsToHuman(pflags))); + server.handle(id, handle_); + server.end(); + }); + client.open(path_, 'w', function(err, handle) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected open() error: ' + err)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + }); + }; + }, + what: 'open' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var handle_ = new Buffer('node.js'); + server.on('CLOSE', function(id, handle) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + server.status(id, STATUS_CODE.OK); + server.end(); + }); + client.close(handle_, function(err) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected close() error: ' + err)); + }); + }; + }, + what: 'close' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var handle_ = new Buffer('node.js'); + var expected = new Buffer('node.jsnode.jsnode.jsnode.jsnode.jsnode.js'); + var buffer = new Buffer(expected.length); + buffer.fill(0); + server.on('READ', function(id, handle, offset, len) { + assert(++self.state.requests <= 2, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + assert(offset === 5, makeMsg(what, 'Wrong read offset: ' + offset)); + assert(len === buffer.length, makeMsg(what, 'Wrong read len: ' + len)); + server.data(id, expected); + server.end(); + }); + client.readData(handle_, buffer, 0, buffer.length, 5, clientReadCb); + function clientReadCb(err, code) { + assert(++self.state.responses <= 2, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected readData() error: ' + err)); + assert.deepEqual(buffer, + expected, + makeMsg(what, 'read data mismatch')); + } + }; + }, + what: 'readData' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var handle_ = new Buffer('node.js'); + var buf = new Buffer('node.jsnode.jsnode.jsnode.jsnode.jsnode.js'); + server.on('WRITE', function(id, handle, offset, data) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + assert(offset === 5, makeMsg(what, 'Wrong write offset: ' + offset)); + assert.deepEqual(data, buf, makeMsg(what, 'write data mismatch')); + server.status(id, STATUS_CODE.OK); + server.end(); + }); + client.writeData(handle_, buf, 0, buf.length, 5, function(err, nb) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected writeData() error: ' + err)); + assert.equal(nb, buf.length); + }); + }; + }, + what: 'write' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var handle_ = new Buffer('node.js'); + var buf = new Buffer(3 * 32 * 1024); + server.on('WRITE', function(id, handle, offset, data) { + ++self.state.requests; + assert.equal(id, + self.state.requests - 1, + makeMsg(what, 'Wrong request id: ' + id)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + assert.equal(offset, + (self.state.requests - 1) * 32 * 1024, + makeMsg(what, 'Wrong write offset: ' + offset)); + assert((offset + data.length) <= buf.length); + assert.deepEqual(data, + buf.slice(offset, offset + data.length), + makeMsg(what, 'write data mismatch')); + server.status(id, STATUS_CODE.OK); + if (self.state.requests === 3) + server.end(); + }); + client.writeData(handle_, buf, 0, buf.length, 0, function(err, nb) { + ++self.state.responses; + assert(!err, makeMsg(what, 'Unexpected writeData() error: ' + err)); + assert.equal(nb, buf.length); + }); + }; + }, + expected: { + requests: 3, + responses: 1 + }, + what: 'write (overflow)' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var path_ = '/foo/bar/baz'; + var attrs_ = new Stats({ + size: 10 * 1024, + uid: 9001, + gid: 9001, + atime: (Date.now() / 1000) | 0, + mtime: (Date.now() / 1000) | 0 + }); + server.on('LSTAT', function(id, path) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert(path === path_, makeMsg(what, 'Wrong path: ' + path)); + server.attrs(id, attrs_); + server.end(); + }); + client.lstat(path_, function(err, attrs) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected lstat() error: ' + err)); + assert.deepEqual(attrs, attrs_, makeMsg(what, 'attrs mismatch')); + }); + }; + }, + what: 'lstat' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var handle_ = new Buffer('node.js'); + var attrs_ = new Stats({ + size: 10 * 1024, + uid: 9001, + gid: 9001, + atime: (Date.now() / 1000) | 0, + mtime: (Date.now() / 1000) | 0 + }); + server.on('FSTAT', function(id, handle) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + server.attrs(id, attrs_); + server.end(); + }); + client.fstat(handle_, function(err, attrs) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected fstat() error: ' + err)); + assert.deepEqual(attrs, attrs_, makeMsg(what, 'attrs mismatch')); + }); + }; + }, + what: 'fstat' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var path_ = '/foo/bar/baz'; + var attrs_ = new Stats({ + uid: 9001, + gid: 9001, + atime: (Date.now() / 1000) | 0, + mtime: (Date.now() / 1000) | 0 + }); + server.on('SETSTAT', function(id, path, attrs) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert(path === path_, makeMsg(what, 'Wrong path: ' + path)); + assert.deepEqual(attrs, attrs_, makeMsg(what, 'attrs mismatch')); + server.status(id, STATUS_CODE.OK); + server.end(); + }); + client.setstat(path_, attrs_, function(err) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected setstat() error: ' + err)); + }); + }; + }, + what: 'setstat' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var handle_ = new Buffer('node.js'); + var attrs_ = new Stats({ + uid: 9001, + gid: 9001, + atime: (Date.now() / 1000) | 0, + mtime: (Date.now() / 1000) | 0 + }); + server.on('FSETSTAT', function(id, handle, attrs) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + assert.deepEqual(attrs, attrs_, makeMsg(what, 'attrs mismatch')); + server.status(id, STATUS_CODE.OK); + server.end(); + }); + client.fsetstat(handle_, attrs_, function(err) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected fsetstat() error: ' + err)); + }); + }; + }, + what: 'fsetstat' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var handle_ = new Buffer('node.js'); + var path_ = '/tmp'; + server.on('OPENDIR', function(id, path) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert(path === path_, makeMsg(what, 'Wrong path: ' + path)); + server.handle(id, handle_); + server.end(); + }); + client.opendir(path_, function(err, handle) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected opendir() error: ' + err)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + }); + }; + }, + what: 'opendir' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var handle_ = new Buffer('node.js'); + var list_ = [ + { filename: '.', + longname: 'drwxr-xr-x 56 nodejs nodejs 4096 Nov 10 01:05 .', + attrs: new Stats({ + mode: 0755 | constants.S_IFDIR, + size: 4096, + uid: 9001, + gid: 8001, + atime: 1415599549, + mtime: 1415599590 + }) + }, + { filename: '..', + longname: 'drwxr-xr-x 4 root root 4096 May 16 2013 ..', + attrs: new Stats({ + mode: 0755 | constants.S_IFDIR, + size: 4096, + uid: 0, + gid: 0, + atime: 1368729954, + mtime: 1368729999 + }) + }, + { filename: 'foo', + longname: 'drwxrwxrwx 2 nodejs nodejs 4096 Mar 8 2009 foo', + attrs: new Stats({ + mode: 0777 | constants.S_IFDIR, + size: 4096, + uid: 9001, + gid: 8001, + atime: 1368729954, + mtime: 1368729999 + }) + }, + { filename: 'bar', + longname: '-rw-r--r-- 1 nodejs nodejs 513901992 Dec 4 2009 bar', + attrs: new Stats({ + mode: 0644 | constants.S_IFREG, + size: 513901992, + uid: 9001, + gid: 8001, + atime: 1259972199, + mtime: 1259972199 + }) + } + ]; + server.on('READDIR', function(id, handle) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + server.name(id, list_); + server.end(); + }); + client.readdir(handle_, function(err, list) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected readdir() error: ' + err)); + assert.deepEqual(list, + list_.slice(2), + makeMsg(what, 'dir list mismatch')); + }); + }; + }, + what: 'readdir' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var handle_ = new Buffer('node.js'); + var list_ = [ + { filename: '.', + longname: 'drwxr-xr-x 56 nodejs nodejs 4096 Nov 10 01:05 .', + attrs: new Stats({ + mode: 0755 | constants.S_IFDIR, + size: 4096, + uid: 9001, + gid: 8001, + atime: 1415599549, + mtime: 1415599590 + }) + }, + { filename: '..', + longname: 'drwxr-xr-x 4 root root 4096 May 16 2013 ..', + attrs: new Stats({ + mode: 0755 | constants.S_IFDIR, + size: 4096, + uid: 0, + gid: 0, + atime: 1368729954, + mtime: 1368729999 + }) + }, + { filename: 'foo', + longname: 'drwxrwxrwx 2 nodejs nodejs 4096 Mar 8 2009 foo', + attrs: new Stats({ + mode: 0777 | constants.S_IFDIR, + size: 4096, + uid: 9001, + gid: 8001, + atime: 1368729954, + mtime: 1368729999 + }) + }, + { filename: 'bar', + longname: '-rw-r--r-- 1 nodejs nodejs 513901992 Dec 4 2009 bar', + attrs: new Stats({ + mode: 0644 | constants.S_IFREG, + size: 513901992, + uid: 9001, + gid: 8001, + atime: 1259972199, + mtime: 1259972199 + }) + } + ]; + server.on('READDIR', function(id, handle) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + server.name(id, list_); + server.end(); + }); + client.readdir(handle_, { full: true }, function(err, list) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected readdir() error: ' + err)); + assert.deepEqual(list, list_, makeMsg(what, 'dir list mismatch')); + }); + }; + }, + what: 'readdir (full)' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var path_ = '/foo/bar/baz'; + server.on('REMOVE', function(id, path) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert(path === path_, makeMsg(what, 'Wrong path: ' + path)); + server.status(id, STATUS_CODE.OK); + server.end(); + }); + client.unlink(path_, function(err) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected unlink() error: ' + err)); + }); + }; + }, + what: 'remove' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var path_ = '/foo/bar/baz'; + server.on('MKDIR', function(id, path) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert(path === path_, makeMsg(what, 'Wrong path: ' + path)); + server.status(id, STATUS_CODE.OK); + server.end(); + }); + client.mkdir(path_, function(err) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected mkdir() error: ' + err)); + }); + }; + }, + what: 'mkdir' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var path_ = '/foo/bar/baz'; + server.on('RMDIR', function(id, path) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert(path === path_, makeMsg(what, 'Wrong path: ' + path)); + server.status(id, STATUS_CODE.OK); + server.end(); + }); + client.rmdir(path_, function(err) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected rmdir() error: ' + err)); + }); + }; + }, + what: 'rmdir' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var path_ = '/foo/bar/baz'; + var name_ = { filename: '/tmp/foo' }; + server.on('REALPATH', function(id, path) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert(path === path_, makeMsg(what, 'Wrong path: ' + path)); + server.name(id, name_); + server.end(); + }); + client.realpath(path_, function(err, name) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected realpath() error: ' + err)); + assert.deepEqual(name, name_.filename, makeMsg(what, 'name mismatch')); + }); + }; + }, + what: 'realpath' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var path_ = '/foo/bar/baz'; + var attrs_ = new Stats({ + size: 10 * 1024, + uid: 9001, + gid: 9001, + atime: (Date.now() / 1000) | 0, + mtime: (Date.now() / 1000) | 0 + }); + server.on('STAT', function(id, path) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert(path === path_, makeMsg(what, 'Wrong path: ' + path)); + server.attrs(id, attrs_); + server.end(); + }); + client.stat(path_, function(err, attrs) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected stat() error: ' + err)); + assert.deepEqual(attrs, attrs_, makeMsg(what, 'attrs mismatch')); + }); + }; + }, + what: 'stat' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var oldPath_ = '/foo/bar/baz'; + var newPath_ = '/tmp/foo'; + server.on('RENAME', function(id, oldPath, newPath) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert(oldPath === oldPath_, + makeMsg(what, 'Wrong old path: ' + oldPath)); + assert(newPath === newPath_, + makeMsg(what, 'Wrong new path: ' + newPath)); + server.status(id, STATUS_CODE.OK); + server.end(); + }); + client.rename(oldPath_, newPath_, function(err) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected rename() error: ' + err)); + }); + }; + }, + what: 'rename' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var linkPath_ = '/foo/bar/baz'; + var name = { filename: '/tmp/foo' }; + server.on('READLINK', function(id, linkPath) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert(linkPath === linkPath_, + makeMsg(what, 'Wrong link path: ' + linkPath)); + server.name(id, name); + server.end(); + }); + client.readlink(linkPath_, function(err, targetPath) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected readlink() error: ' + err)); + assert(targetPath === name.filename, + makeMsg(what, 'Wrong target path: ' + targetPath)); + }); + }; + }, + what: 'readlink' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var linkPath_ = '/foo/bar/baz'; + var targetPath_ = '/tmp/foo'; + server.on('SYMLINK', function(id, linkPath, targetPath) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert(linkPath === linkPath_, + makeMsg(what, 'Wrong link path: ' + linkPath)); + assert(targetPath === targetPath_, + makeMsg(what, 'Wrong target path: ' + targetPath)); + server.status(id, STATUS_CODE.OK); + server.end(); + }); + client.symlink(targetPath_, linkPath_, function(err) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(!err, makeMsg(what, 'Unexpected symlink() error: ' + err)); + }); + }; + }, + what: 'symlink' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var path_ = '/foo/bar/baz'; + var handle_ = new Buffer('hi mom!'); + var data_ = new Buffer('hello world'); + server.once('OPEN', function(id, path, pflags, attrs) { + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert(path === path_, makeMsg(what, 'Wrong path: ' + path)); + assert(pflags === OPEN_MODE.READ, + makeMsg(what, 'Wrong flags: ' + flagsToHuman(pflags))); + server.handle(id, handle_); + }).once('FSTAT', function(id, handle) { + assert(id === 1, makeMsg(what, 'Wrong request id: ' + id)); + var attrs = new Stats({ + size: data_.length, + uid: 9001, + gid: 9001, + atime: (Date.now() / 1000) | 0, + mtime: (Date.now() / 1000) | 0 + }); + server.attrs(id, attrs); + }).once('READ', function(id, handle, offset, len) { + assert(id === 2, makeMsg(what, 'Wrong request id: ' + id)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + assert(offset === 0, makeMsg(what, 'Wrong read offset: ' + offset)); + server.data(id, data_); + }).once('CLOSE', function(id, handle) { + ++self.state.requests; + assert(id === 3, makeMsg(what, 'Wrong request id: ' + id)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + server.status(id, STATUS_CODE.OK); + server.end(); + }); + var buf = []; + client.readFile(path_, function(err, buf) { + ++self.state.responses; + assert(!err, makeMsg(what, 'Unexpected error: ' + err)); + assert.deepEqual(buf, data_, makeMsg(what, 'data mismatch')); + }); + }; + }, + what: 'readFile' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var opens = 0; + var reads = 0; + var closes = 0; + var path_ = '/foo/bar/baz'; + var handle_ = new Buffer('hi mom!'); + var data_ = new Buffer('hello world'); + server.on('OPEN', function(id, path, pflags, attrs) { + assert(++opens === 1, makeMsg(what, 'Saw too many OPENs')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert(path === path_, makeMsg(what, 'Wrong path: ' + path)); + assert(pflags === OPEN_MODE.READ, + makeMsg(what, 'Wrong flags: ' + flagsToHuman(pflags))); + server.handle(id, handle_); + }).on('READ', function(id, handle, offset, len) { + assert(++reads <= 2, makeMsg(what, 'Saw too many READs')); + assert(id === reads, makeMsg(what, 'Wrong request id: ' + id)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + if (reads === 1) { + assert(offset === 0, makeMsg(what, 'Wrong read offset: ' + offset)); + server.data(id, data_); + } else + server.status(id, STATUS_CODE.EOF); + }).on('CLOSE', function(id, handle) { + ++self.state.requests; + assert(++closes === 1, makeMsg(what, 'Saw too many CLOSEs')); + assert(id === 3, makeMsg(what, 'Wrong request id: ' + id)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + server.status(id, STATUS_CODE.OK); + server.end(); + }); + var buf = []; + client.createReadStream(path_).on('readable', function() { + var chunk; + while ((chunk = this.read()) !== null) { + buf.push(chunk); + } + }).on('end', function() { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + buf = Buffer.concat(buf); + assert.deepEqual(buf, data_, makeMsg(what, 'data mismatch')); + }); + }; + }, + what: 'ReadStream' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var opens = 0; + var path_ = '/foo/bar/baz'; + var error; + server.on('OPEN', function(id, path, pflags, attrs) { + ++opens; + ++self.state.requests; + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert(path === path_, makeMsg(what, 'Wrong path: ' + path)); + assert(pflags === OPEN_MODE.READ, + makeMsg(what, 'Wrong flags: ' + flagsToHuman(pflags))); + server.status(id, STATUS_CODE.NO_SUCH_FILE); + server.end(); + }); + client.createReadStream(path_).on('error', function(err) { + error = err; + }).on('close', function() { + assert(opens === 1, makeMsg(what, 'Saw ' + opens + ' OPENs')); + assert(error, makeMsg(what, 'Expected error')); + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + }); + }; + }, + what: 'ReadStream (error)' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var opens = 0; + var writes = 0; + var closes = 0; + var fsetstat = false; + var path_ = '/foo/bar/baz'; + var handle_ = new Buffer('hi mom!'); + var data_ = new Buffer('hello world'); + var expFlags = OPEN_MODE.TRUNC | OPEN_MODE.CREAT | OPEN_MODE.WRITE; + server.on('OPEN', function(id, path, pflags, attrs) { + assert(++opens === 1, makeMsg(what, 'Saw too many OPENs')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert(path === path_, makeMsg(what, 'Wrong path: ' + path)); + assert(pflags === expFlags, + makeMsg(what, 'Wrong flags: ' + flagsToHuman(pflags))); + server.handle(id, handle_); + }).once('FSETSTAT', function(id, handle, attrs) { + fsetstat = true; + assert(id === 1, makeMsg(what, 'Wrong request id: ' + id)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + assert.strictEqual(attrs.mode, + parseInt('0666', 8), + makeMsg(what, 'Wrong file mode')); + server.status(id, STATUS_CODE.OK); + }).on('WRITE', function(id, handle, offset, data) { + assert(++writes <= 3, makeMsg(what, 'Saw too many WRITEs')); + assert(id === writes + 1, makeMsg(what, 'Wrong request id: ' + id)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + assert(offset === ((writes - 1) * data_.length), + makeMsg(what, 'Wrong write offset: ' + offset)); + assert.deepEqual(data, data_, makeMsg(what, 'Wrong data')); + server.status(id, STATUS_CODE.OK); + }).on('CLOSE', function(id, handle) { + ++self.state.requests; + assert(++closes === 1, makeMsg(what, 'Saw too many CLOSEs')); + assert(id === 5, makeMsg(what, 'Wrong request id: ' + id)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + server.status(id, STATUS_CODE.OK); + server.end(); + }).on('end', function() { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(opens === 1, makeMsg(what, 'Wrong OPEN count')); + assert(writes === 3, makeMsg(what, 'Wrong WRITE count')); + assert(closes === 1, makeMsg(what, 'Wrong CLOSE count')); + assert(fsetstat, makeMsg(what, 'Expected FSETSTAT')); + }); + + var writer = client.createWriteStream(path_); + if (writer.cork) + writer.cork(); + writer.write(data_); + writer.write(data_); + writer.write(data_); + if (writer.uncork) + writer.uncork(); + writer.end(); + }; + }, + what: 'WriteStream' + }, + +// other client request scenarios + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var handle_ = new Buffer('node.js'); + server.on('READDIR', function(id, handle) { + assert(++self.state.requests === 1, + makeMsg(what, 'Saw too many requests')); + assert(id === 0, makeMsg(what, 'Wrong request id: ' + id)); + assert.deepEqual(handle, handle_, makeMsg(what, 'handle mismatch')); + server.status(id, STATUS_CODE.EOF); + server.end(); + }); + client.readdir(handle_, function(err, list) { + assert(++self.state.responses === 1, + makeMsg(what, 'Saw too many responses')); + assert(err && err.code === STATUS_CODE.EOF, + makeMsg(what, 'Expected EOF, got: ' + err)); + }); + }; + }, + what: 'readdir (EOF)' + }, + { run: function() { + setup(this); + + var self = this; + var what = this.what; + var client = this.client; + var server = this.server; + + this.onReady = function() { + var path_ = '/tmp/foo.txt'; + var reqs = 0; + var continues = 0; + + client.unpipe(server); + + function clientCb(err, handle) { + assert(++self.state.responses <= reqs, + makeMsg(what, 'Saw too many responses')); + if (self.state.responses === reqs) { + assert(continues === 1, makeMsg(what, 'no continue event seen')); + server.end(); + } + } + + client.on('continue', function() { + assert(++continues === 1, makeMsg(what, 'saw > 1 continue event')); + }); + + while (true) { + ++reqs; + if (!client.open(path_, 'w', clientCb)) + break; + } + + client.pipe(server); + }; + }, + expected: { + requests: -1, + responses: -1 + }, + what: '"continue" event after push() === false' + }, + { run: function() { + var self = this; + var client = new SFTPStream(); + client.once('ready', function() { + client.open('/foo/bar', 'w', function(err, handle) { + assert(err, 'Expected error'); + assert.strictEqual(err.code, 4); + assert.strictEqual(err.message, 'Uh oh'); + assert.strictEqual(err.lang, ''); + next(); + }); + client.write(new Buffer([ + 0, 0, 0, 18, + 101, + 0, 0, 0, 0, + 0, 0, 0, SFTPStream.STATUS_CODE.FAILURE, + 0, 0, 0, 5, 85, 104, 32, 111, 104 + ])); + }); + client.write(new Buffer([ + 0, 0, 0, 5, + 2, + 0, 0, 0, 3 + ])); + }, + what: 'Can parse status response without language' + }, + { run: function() { + var self = this; + var client = new SFTPStream(); + client.once('ready', function() { + client.open('/foo/bar', 'w', function(err, handle) { + assert(err, 'Expected error'); + assert.strictEqual(err.code, 4); + assert.strictEqual(err.message, 'Failure'); + assert.strictEqual(err.lang, ''); + next(); + }); + client.write(new Buffer([ + 0, 0, 0, 9, + 101, + 0, 0, 0, 0, + 0, 0, 0, SFTPStream.STATUS_CODE.FAILURE + ])); + }); + client.write(new Buffer([ + 0, 0, 0, 5, + 2, + 0, 0, 0, 3 + ])); + }, + what: 'Can parse status response without message' + }, +]; + +function setup(self) { + var expectedRequests = (self.expected && self.expected.requests) || 1; + var expectedResponses = (self.expected && self.expected.responses) || 1; + var clientEnded = false; + var serverEnded = false; + + self.state = { + clientReady: false, + serverReady: false, + requests: 0, + responses: 0 + }; + + self.client = new SFTPStream(); + self.server = new SFTPStream({ server: true }); + + self.server.on('error', onError) + .on('ready', onReady) + .on('end', onEnd); + self.client.on('error', onError) + .on('ready', onReady) + .on('end', onEnd); + + function onError(err) { + var which = (this === self.server ? 'server' : 'client'); + assert(false, makeMsg(self.what, 'Unexpected ' + which + ' error: ' + err)); + } + function onReady() { + if (this === self.client) { + assert(!self.state.clientReady, + makeMsg(self.what, 'Received multiple ready events for client')); + self.state.clientReady = true; + } else { + assert(!self.state.serverReady, + makeMsg(self.what, 'Received multiple ready events for server')); + self.state.serverReady = true; + } + if (self.state.clientReady && self.state.serverReady) + self.onReady && self.onReady(); + } + function onEnd() { + if (this === self.client) { + assert(!clientEnded, + makeMsg(self.what, 'Received multiple close events for client')); + clientEnded = true; + } else { + assert(!serverEnded, + makeMsg(self.what, 'Received multiple close events for server')); + serverEnded = true; + } + if (clientEnded && serverEnded) { + var msg; + if (expectedRequests > 0) { + msg = 'Expected ' + expectedRequests + ' request(s) but received ' + + self.state.requests; + assert(self.state.requests === expectedRequests, + makeMsg(self.what, msg)); + } + if (expectedResponses > 0) { + msg = 'Expected ' + expectedResponses + ' response(s) but received ' + + self.state.responses; + assert(self.state.responses === expectedResponses, + makeMsg(self.what, msg)); + } + next(); + } + } + + process.nextTick(function() { + self.client.pipe(self.server).pipe(self.client); + }); +} + +function flagsToHuman(flags) { + var ret = []; + + for (var i = 0, keys = Object.keys(OPEN_MODE), len = keys.length; i < len; ++i) + if (flags & OPEN_MODE[keys[i]]) + ret.push(keys[i]); + + return ret.join(' | '); +} + +function next() { + if (++t === tests.length) + return; + + var v = tests[t]; + v.run.call(v); +} + +function makeMsg(what, msg) { + return '[' + group + what + ']: ' + msg; +} + +process.once('exit', function() { + assert(t === tests.length, + makeMsg('_exit', + 'Only finished ' + t + '/' + tests.length + ' tests')); +}); + +next(); diff --git a/node_modules/ssh2-streams/test/test-ssh.js b/node_modules/ssh2-streams/test/test-ssh.js new file mode 100644 index 0000000..e7651c5 --- /dev/null +++ b/node_modules/ssh2-streams/test/test-ssh.js @@ -0,0 +1,120 @@ +var SSH2Stream = require('../lib/ssh'); +var utils = require('../lib/utils'); +var parseKey = utils.parseKey; +var genPubKey = utils.genPublicKey; + +var basename = require('path').basename; +var assert_ = require('assert'); +var inherits = require('util').inherits; +var TransformStream = require('stream').Transform; +var fs = require('fs'); + +var group = basename(__filename, '.js') + '/'; +var t = -1; +var SERVER_KEY = fs.readFileSync(__dirname + '/fixtures/ssh_host_rsa_key'); +var HOST_KEYS = { 'ssh-rsa': makeServerKey(SERVER_KEY) }; + +function SimpleStream() { + TransformStream.call(this); + this.buffer = ''; +} +inherits(SimpleStream, TransformStream); +SimpleStream.prototype._transform = function(chunk, encoding, cb) { + this.buffer += chunk.toString('binary'); + cb(null, chunk); +}; + +var tests = [ + // client-side tests + { run: function() { + var algos = ['ssh-dss', 'ssh-rsa', 'ecdsa-sha2-nistp521']; + var client = new SSH2Stream({ + algorithms: { + serverHostKey: algos + } + }); + var clientBufStream = new SimpleStream(); + var clientReady = false; + var server = new SSH2Stream({ + server: true, + hostKeys: HOST_KEYS + }); + var serverBufStream = new SimpleStream(); + var serverReady = false; + + function onNEWKEYS() { + if (this === client) { + assert(!clientReady, 'Already received client NEWKEYS event'); + clientReady = true; + } else { + assert(!serverReady, 'Already received server NEWKEYS event'); + serverReady = true; + } + if (clientReady && serverReady) { + var traffic = clientBufStream.buffer; + var algoList = algos.join(','); + var re = new RegExp('\x00\x00\x00' + + hexByte(algoList.length) + + algoList); + assert(re.test(traffic), 'Unexpected client algorithms'); + + traffic = serverBufStream.buffer; + assert(/\x00\x00\x00\x07ssh-rsa/.test(traffic), + 'Unexpected server algorithms'); + + next(); + } + } + + client.on('NEWKEYS', onNEWKEYS); + server.on('NEWKEYS', onNEWKEYS); + + client.pipe(clientBufStream) + .pipe(server) + .pipe(serverBufStream) + .pipe(client); + }, + what: 'Custom algorithms' + }, +]; + +function makeServerKey(raw) { + var privateKey = parseKey(raw); + return { + privateKey: privateKey, + publicKey: genPubKey(privateKey) + }; +} + +function hexByte(n) { + return String.fromCharCode(n); +} + +function assert(expression, msg) { + msg || (msg = 'failed assertion'); + assert_(expression, makeMsg(tests[t].what, msg)); +} + + + +function next() { + if (Array.isArray(process._events.exit)) + process._events.exit = process._events.exit[1]; + if (++t === tests.length) + return; + + var v = tests[t]; + v.run.call(v); +} + +function makeMsg(what, msg) { + return '[' + group + what + ']: ' + msg; +} + +process.once('exit', function() { + assert_(t === tests.length, + makeMsg('_exit', + 'Only finished ' + t + '/' + tests.length + ' tests')); +}); + +next(); diff --git a/node_modules/ssh2-streams/test/test-utils.js b/node_modules/ssh2-streams/test/test-utils.js new file mode 100644 index 0000000..2949ab3 --- /dev/null +++ b/node_modules/ssh2-streams/test/test-utils.js @@ -0,0 +1,678 @@ +var utils = require('../lib/utils'); + +var fs = require('fs'); +var path = require('path'); +var assert = require('assert'); + +var t = -1; +var group = path.basename(__filename, '.js') + '/'; +var fixturesdir = path.join(__dirname, 'fixtures'); + +var tests = [ + { run: function() { + var what = this.what; + var r; + + assert.strictEqual(r = utils.readInt(new Buffer([0,0,0]), 0), + false, + makeMsg(what, 'Wrong result: ' + r)); + next(); + }, + what: 'readInt - without stream callback - failure #1' + }, + { run: function() { + var what = this.what; + var r; + + assert.strictEqual(r = utils.readInt(new Buffer([]), 0), + false, + makeMsg(what, 'Wrong result: ' + r)); + next(); + }, + what: 'readInt - without stream callback - failure #2' + }, + { run: function() { + var what = this.what; + var r; + + assert.strictEqual(r = utils.readInt(new Buffer([0,0,0,5]), 0), + 5, + makeMsg(what, 'Wrong result: ' + r)); + next(); + }, + what: 'readInt - without stream callback - success' + }, + { run: function() { + var what = this.what; + var callback = function() {}; + var stream = { + _cleanup: function(cb) { + cleanupCalled = true; + assert(cb === callback, makeMsg(what, 'Wrong callback')); + } + }; + var cleanupCalled = false; + var r; + + assert.strictEqual(r = utils.readInt(new Buffer([]), 0, stream, callback), + false, + makeMsg(what, 'Wrong result: ' + r)); + assert(cleanupCalled, makeMsg(what, 'Cleanup not called')); + next(); + }, + what: 'readInt - with stream callback' + }, + { run: function() { + var what = this.what; + var r; + + assert.strictEqual(r = utils.readString(new Buffer([0,0,0]), 0), + false, + makeMsg(what, 'Wrong result: ' + r)); + next(); + }, + what: 'readString - without stream callback - bad length #1' + }, + { run: function() { + var what = this.what; + var r; + + assert.strictEqual(r = utils.readString(new Buffer([]), 0), + false, + makeMsg(what, 'Wrong result: ' + r)); + next(); + }, + what: 'readString - without stream callback - bad length #2' + }, + { run: function() { + var what = this.what; + var r; + + assert.deepEqual(r = utils.readString(new Buffer([0,0,0,1,5]), 0), + new Buffer([5]), + makeMsg(what, 'Wrong result: ' + r)); + next(); + }, + what: 'readString - without stream callback - success' + }, + { run: function() { + var what = this.what; + var r; + + assert.deepEqual(r = utils.readString(new Buffer([0,0,0,1,33]), 0, 'ascii'), + '!', + makeMsg(what, 'Wrong result: ' + r)); + next(); + }, + what: 'readString - without stream callback - encoding' + }, + { run: function() { + var what = this.what; + var callback = function() {}; + var stream = { + _cleanup: function(cb) { + cleanupCalled = true; + assert(cb === callback, makeMsg(what, 'Wrong callback')); + } + }; + var cleanupCalled = false; + var r; + + assert.deepEqual(r = utils.readString(new Buffer([0,0,0,1]), + 0, + stream, + callback), + false, + makeMsg(what, 'Wrong result: ' + r)); + assert(cleanupCalled, makeMsg(what, 'Cleanup not called')); + next(); + }, + what: 'readString - with stream callback - no encoding' + }, + { run: function() { + var what = this.what; + var callback = function() {}; + var stream = { + _cleanup: function(cb) { + cleanupCalled = true; + assert(cb === callback, makeMsg(what, 'Wrong callback')); + } + }; + var cleanupCalled = false; + var r; + + assert.deepEqual(r = utils.readString(new Buffer([0,0,0,1]), + 0, + 'ascii', + stream, + callback), + false, + makeMsg(what, 'Wrong result: ' + r)); + assert(cleanupCalled, makeMsg(what, 'Cleanup not called')); + next(); + }, + what: 'readString - with stream callback - encoding' + }, + { run: function() { + var what = this.what; + var filepath = fixturesdir + '/encrypted-rsa.ppk'; + var passphrase = 'node.js'; + var keyInfo = utils.parseKey(fs.readFileSync(filepath)); + + utils.decryptKey(keyInfo, passphrase); + + var expPrivOrig = new Buffer([ + 45,45,45,45,45,66,69,71,73,78,32,82,83,65,32,80,82,73,86,65,84,69,32,75, + 69,89,45,45,45,45,45,10,77,73,73,67,87,81,73,66,65,65,75,66,103,71,115, + 70,89,82,77,66,85,68,73,109,97,52,48,98,110,101,80,66,77,48,79,86,115, + 104,119,102,109,87,115,83,57,122,72,113,88,72,108,115,122,111,81,113,68, + 82,101,89,52,103,102,51,10,112,87,112,83,78,76,116,53,70,70,78,77,80,50, + 87,107,69,68,121,70,105,71,83,115,54,77,55,72,51,102,56,108,89,72,43,108, + 120,85,51,122,56,72,99,78,103,101,121,70,80,48,52,70,98,85,77,75,83,115, + 51,67,54,51,97,108,10,115,110,97,104,107,52,71,75,117,71,69,67,118,55,71, + 112,89,87,118,102,110,110,85,87,112,118,78,111,73,104,101,107,52,113,53, + 117,118,103,82,119,106,65,75,75,107,71,88,111,47,69,116,82,74,56,101,68, + 65,103,69,108,65,111,71,65,10,85,43,71,102,72,76,118,88,69,111,122,81,49, + 109,72,65,56,77,102,99,69,109,67,83,104,76,55,83,77,86,81,78,50,119,80, + 76,56,72,102,103,73,109,89,108,55,43,97,72,112,87,69,56,100,101,49,110, + 109,100,116,119,121,54,112,50,10,52,80,89,50,80,85,89,81,57,80,89,53,55, + 105,51,122,76,56,78,90,100,56,87,81,55,82,103,48,82,66,72,68,108,110,100, + 97,70,101,70,52,69,102,48,117,76,98,111,113,89,100,47,120,78,48,114,122, + 102,121,53,53,122,55,104,87,10,79,76,43,56,86,104,111,120,84,114,66,85, + 118,118,101,79,104,90,119,66,80,107,79,101,72,102,120,109,107,86,122,51, + 120,98,98,114,103,51,107,78,108,111,48,67,81,81,68,74,89,80,75,116,67, + 115,47,108,52,54,75,74,109,78,51,108,10,85,65,78,100,73,52,81,73,117,87, + 81,43,90,108,108,122,55,112,57,52,70,102,100,111,116,110,107,118,113,71, + 43,43,66,112,49,119,79,113,74,83,67,105,104,54,85,86,105,119,76,102,118, + 112,78,90,116,71,77,67,116,107,52,54,87,78,10,104,99,48,122,65,107,69,65, + 105,65,121,78,52,87,85,115,47,48,120,52,87,111,118,71,57,53,54,74,49,65, + 43,117,83,69,75,101,87,122,117,113,102,112,71,71,98,87,103,90,57,88,102, + 110,80,110,107,43,49,65,108,56,70,79,87,49,10,116,117,57,87,87,114,77,80, + 73,97,118,81,110,90,87,47,100,88,120,104,107,101,78,87,84,72,55,56,99,81, + 74,66,65,76,107,77,43,113,122,90,103,77,86,112,90,79,48,107,115,68,113, + 65,52,72,56,90,116,53,108,81,97,102,81,109,10,115,120,67,87,70,102,43, + 108,101,53,67,110,114,97,70,113,87,78,103,104,119,82,115,70,99,112,67,84, + 116,110,52,56,54,98,97,109,121,56,57,104,115,85,100,113,105,76,50,83,54, + 121,103,97,70,111,69,67,81,70,68,107,51,114,49,101,10,119,77,56,109,106, + 77,65,51,98,50,76,77,43,65,71,77,121,72,51,43,71,80,102,53,57,113,119, + 102,76,86,88,80,77,103,101,84,90,117,98,103,84,116,55,119,52,102,54,87, + 98,65,118,111,81,83,56,67,114,119,48,97,68,86,98,72,10,118,102,76,85,86, + 98,67,119,114,57,112,49,66,77,48,67,81,70,83,66,106,67,97,47,102,122,101, + 73,67,86,107,80,70,66,97,75,81,85,109,88,106,81,51,73,99,80,84,79,114,57, + 48,109,83,65,105,80,110,65,65,112,112,83,119,84,10,106,53,83,89,83,102, + 69,57,114,83,86,98,43,69,104,81,48,104,107,50,86,75,87,73,102,111,99,78, + 72,66,68,49,77,65,78,57,122,98,52,61,10,45,45,45,45,45,69,78,68,32,82,83, + 65,32,80,82,73,86,65,84,69,32,75,69,89,45,45,45,45,45 + ]); + assert(keyInfo.ppk === true, makeMsg(what, 'Expected PPK flag')); + assert(keyInfo._converted === true, + makeMsg(what, 'Expected automatic private PEM generation')); + assert(keyInfo._macresult === true, + makeMsg(what, 'Expected successful MAC verification')); + assert(keyInfo._decrypted === true, + makeMsg(what, 'Expected decrypted flag')); + assert.deepEqual(keyInfo.privateOrig, + expPrivOrig, + makeMsg(what, 'Decrypted private PEM data mismatch')); + next(); + }, + what: 'decryptKey - with encrypted RSA PPK' + }, + { run: function() { + var what = this.what; + var filepath = fixturesdir + '/encrypted-dsa.ppk'; + var passphrase = 'node.js'; + var keyInfo = utils.parseKey(fs.readFileSync(filepath)); + + utils.decryptKey(keyInfo, passphrase); + + var expPrivOrig = new Buffer([ + 45,45,45,45,45,66,69,71,73,78,32,68,83,65,32,80,82,73,86,65,84,69,32,75, + 69,89,45,45,45,45,45,10,77,73,73,66,117,103,73,66,65,65,75,66,103,81,67, + 90,57,105,80,71,72,110,48,97,78,119,98,66,72,111,112,48,76,102,67,107, + 79,72,66,77,103,75,119,76,79,50,80,49,117,57,57,54,69,85,109,68,105,77, + 49,104,100,83,98,116,10,100,117,77,114,67,113,53,111,78,113,74,76,47,116, + 79,81,109,72,73,49,100,50,75,101,65,77,48,72,113,74,109,65,74,89,74,103, + 102,43,56,81,104,74,49,109,104,74,56,81,115,65,77,90,113,54,121,84,74, + 106,54,53,77,68,89,120,10,122,105,73,117,56,106,79,85,68,104,80,100,67, + 68,80,48,80,105,67,81,79,66,68,119,88,48,109,47,108,54,47,72,50,73,97,54, + 101,100,121,106,82,49,85,112,51,78,105,112,68,113,113,97,78,104,98,67,73, + 119,73,86,65,76,103,50,10,85,47,110,81,97,114,74,83,113,114,89,72,122,90, + 87,72,47,68,109,80,100,80,80,66,65,111,71,65,72,107,104,113,74,118,83, + 121,122,88,99,51,77,65,104,53,120,110,56,83,106,90,120,77,57,43,101,83, + 105,69,119,65,48,56,89,105,10,75,81,98,53,48,70,118,110,103,120,56,69,76, + 121,77,79,108,100,106,110,79,57,50,121,103,114,117,87,89,113,50,90,105, + 68,70,117,99,79,105,111,48,70,99,74,76,107,65,97,66,102,83,113,75,118,57, + 114,117,108,88,110,114,55,83,47,10,97,81,43,107,119,99,48,105,122,70,99, + 79,97,86,100,122,53,104,79,80,119,118,51,105,52,109,108,77,87,83,121,66, + 51,87,56,54,97,106,53,65,76,119,70,65,97,49,121,112,73,57,73,111,56,51, + 68,99,119,113,100,88,55,104,102,66,10,57,75,98,48,102,77,107,67,103,89, + 65,109,118,86,43,107,113,87,104,85,103,68,89,119,78,78,122,49,113,68,97, + 111,83,56,88,100,115,79,112,111,110,117,116,90,47,48,115,116,82,81,54,54, + 109,75,65,121,56,107,78,86,78,78,81,54,10,111,85,120,49,88,70,108,49,87, + 85,116,52,105,121,70,89,47,50,82,122,50,102,90,104,76,122,53,47,84,98,90, + 82,75,53,121,103,111,54,54,54,87,103,110,120,66,47,85,100,52,71,65,120, + 47,66,80,81,84,103,104,79,74,74,79,76,10,48,48,118,74,107,43,56,106,86, + 67,71,78,68,99,57,52,50,86,54,110,70,88,122,110,68,77,88,119,113,120,104, + 82,67,87,54,100,109,43,50,108,84,104,55,110,116,114,108,105,56,109,67, + 107,53,103,73,85,67,74,90,75,65,77,65,122,10,107,121,114,50,118,108,50, + 80,101,52,56,97,100,105,56,86,115,57,115,61,10,45,45,45,45,45,69,78,68, + 32,68,83,65,32,80,82,73,86,65,84,69,32,75,69,89,45,45,45,45,45, + ]); + assert(keyInfo.ppk === true, makeMsg(what, 'Expected PPK flag')); + assert(keyInfo._converted === true, + makeMsg(what, 'Expected automatic private PEM generation')); + assert(keyInfo._macresult === true, + makeMsg(what, 'Expected successful MAC verification')); + assert(keyInfo._decrypted === true, + makeMsg(what, 'Expected decrypted flag')); + assert.deepEqual(keyInfo.privateOrig, + expPrivOrig, + makeMsg(what, 'Decrypted private PEM data mismatch')); + next(); + }, + what: 'decryptKey - with encrypted DSA PPK' + }, + { run: function() { + var what = this.what; + var filepath = fixturesdir + '/id_rsa_enc'; + var passphrase = 'foobarbaz'; + var keyInfo = utils.parseKey(fs.readFileSync(filepath)); + + utils.decryptKey(keyInfo, passphrase); + + var expPriv = new Buffer([ + 0x30, 0x82, 0x04, 0xa5, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, + 0xec, 0x9f, 0xd7, 0x6e, 0x17, 0xfa, 0xe4, 0xc5, 0xff, 0xac, 0x83, 0x6e, + 0xbe, 0x60, 0x66, 0xb2, 0xf2, 0x6a, 0x34, 0xfa, 0x4f, 0xe2, 0x49, 0xcd, + 0x54, 0x29, 0x34, 0x95, 0x3b, 0x55, 0xc1, 0xf5, 0x1f, 0x16, 0x3f, 0x6a, + 0x9f, 0xe5, 0x93, 0x7c, 0x25, 0xe0, 0x92, 0xdb, 0x63, 0x8d, 0xbb, 0xb4, + 0xc2, 0x24, 0x7c, 0x9c, 0x69, 0x4c, 0xe0, 0xa7, 0x21, 0xac, 0xfc, 0xd3, + 0x44, 0x3b, 0x1a, 0xaf, 0x9e, 0x60, 0x93, 0x09, 0xd3, 0xac, 0xb4, 0x65, + 0x88, 0x39, 0x85, 0x8c, 0xd2, 0x04, 0x2c, 0xaf, 0x85, 0x27, 0x92, 0x59, + 0x1b, 0x28, 0x73, 0x99, 0xf9, 0xc1, 0x6c, 0x37, 0x08, 0xa2, 0x77, 0x58, + 0x5a, 0x8c, 0xb0, 0x96, 0xc0, 0x63, 0x8a, 0x10, 0x10, 0x84, 0xd8, 0xfa, + 0x1e, 0xb7, 0x27, 0x58, 0xc1, 0x6b, 0x34, 0xb4, 0xe6, 0xa1, 0x05, 0x68, + 0x82, 0xc9, 0xe3, 0x6a, 0x6f, 0x0b, 0xb5, 0xf7, 0x13, 0xa8, 0x8b, 0x14, + 0x4a, 0x6e, 0x0a, 0x72, 0x39, 0xa6, 0x1f, 0xa0, 0x4f, 0xcb, 0x72, 0xd9, + 0xe5, 0x61, 0x61, 0xa7, 0x63, 0x53, 0xae, 0x66, 0xd6, 0xba, 0xb4, 0xda, + 0x98, 0x92, 0xb4, 0x50, 0x93, 0x36, 0xdf, 0x9a, 0xfe, 0x58, 0x36, 0x6d, + 0x31, 0xd7, 0xff, 0x01, 0x88, 0xe4, 0x49, 0x3b, 0x71, 0x8f, 0x09, 0xe6, + 0x6f, 0xc9, 0xe1, 0x98, 0x51, 0x8c, 0xc4, 0xfa, 0x16, 0xb9, 0x45, 0x14, + 0x7b, 0x9e, 0x0e, 0x09, 0x6d, 0x07, 0x1e, 0x79, 0x4e, 0xa1, 0xb6, 0xf0, + 0xdd, 0x0a, 0x3d, 0xa3, 0x9c, 0xf4, 0xeb, 0x5f, 0xaa, 0x29, 0x37, 0x8c, + 0xb4, 0x03, 0x25, 0xac, 0xe8, 0x64, 0xf6, 0x07, 0xbe, 0xca, 0xc8, 0x48, + 0x39, 0x51, 0xaf, 0x36, 0x42, 0xdd, 0x32, 0x7d, 0x37, 0x7a, 0xdd, 0xd6, + 0xbf, 0x57, 0xf9, 0x10, 0xd7, 0x9f, 0xe4, 0xb8, 0xc8, 0xa7, 0x1b, 0x0c, + 0x89, 0x69, 0xf0, 0x9d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, + 0x01, 0x00, 0xcb, 0xad, 0x9a, 0xe6, 0x6d, 0x45, 0xcd, 0x7e, 0x91, 0x61, + 0x91, 0x90, 0xd5, 0xd6, 0x6d, 0x10, 0x43, 0x92, 0x20, 0x20, 0x06, 0x7b, + 0x26, 0x43, 0xd3, 0xd9, 0xd4, 0x25, 0x50, 0x79, 0xb5, 0x06, 0xa5, 0xc7, + 0xa4, 0xb6, 0xc7, 0x03, 0xfa, 0x3b, 0xb6, 0xee, 0xe3, 0xfa, 0x6c, 0x6b, + 0x27, 0xd3, 0xa3, 0xf9, 0x7c, 0x39, 0xb6, 0x7a, 0x32, 0x36, 0x2a, 0xca, + 0x98, 0xa5, 0xd1, 0xe9, 0x7e, 0x43, 0x04, 0xf4, 0xe4, 0x1c, 0x65, 0x54, + 0x17, 0xc3, 0xfd, 0xca, 0x65, 0xa6, 0x9d, 0x70, 0x72, 0x76, 0x73, 0x0b, + 0x68, 0xf1, 0xc2, 0x6a, 0xc3, 0x77, 0x1a, 0x80, 0xe0, 0x01, 0x4f, 0x31, + 0x69, 0xc1, 0x67, 0xd0, 0x0a, 0x80, 0xf9, 0x01, 0xb5, 0x69, 0xb6, 0x8e, + 0x63, 0xa6, 0x88, 0xa1, 0xe7, 0x00, 0x83, 0x1d, 0x20, 0xb5, 0x46, 0x7f, + 0xfc, 0x03, 0xc5, 0xf0, 0xba, 0x0c, 0x77, 0xa1, 0x80, 0xf2, 0x90, 0xcf, + 0x0a, 0x57, 0x14, 0xa0, 0xc7, 0x30, 0x5b, 0x10, 0x2c, 0x78, 0x85, 0xa2, + 0x52, 0x7e, 0xf1, 0xa8, 0xd0, 0xbc, 0x78, 0x3e, 0x7e, 0xf6, 0xc5, 0xc5, + 0xac, 0xf3, 0x02, 0xd4, 0xdc, 0x02, 0x20, 0xb8, 0xcc, 0x37, 0xe1, 0xaa, + 0x2d, 0x24, 0xed, 0x44, 0xfb, 0x77, 0x20, 0xe5, 0xc4, 0x38, 0x63, 0x08, + 0xe2, 0x92, 0xd2, 0x6a, 0xdf, 0x0a, 0xcb, 0x54, 0x97, 0x91, 0xc7, 0x55, + 0x9c, 0x31, 0x00, 0xe2, 0xf2, 0x25, 0xda, 0xd8, 0x6c, 0xea, 0x6d, 0xf2, + 0xff, 0x98, 0x16, 0x17, 0xf5, 0xfa, 0x5c, 0xd8, 0xfd, 0x8a, 0xf7, 0xea, + 0x35, 0xa0, 0x96, 0xbd, 0xed, 0xd3, 0x35, 0x1c, 0xee, 0x78, 0xa3, 0x1f, + 0xfd, 0x0c, 0x24, 0x4b, 0xad, 0x4f, 0xa5, 0x08, 0xb3, 0xd7, 0x90, 0xe7, + 0x08, 0x60, 0x52, 0x26, 0xee, 0x93, 0x40, 0x80, 0xd1, 0xaf, 0xaf, 0x74, + 0x4d, 0x3b, 0x6f, 0x4e, 0x42, 0x91, 0x02, 0x81, 0x81, 0x00, 0xfe, 0x26, + 0x9d, 0x81, 0xa1, 0xf3, 0xe2, 0x48, 0xad, 0x22, 0x4d, 0xf4, 0x1c, 0x68, + 0x4d, 0xe1, 0xe2, 0xff, 0x09, 0xbf, 0xa6, 0x12, 0x0a, 0x16, 0xce, 0xd6, + 0x34, 0x73, 0x7d, 0x55, 0xd3, 0x35, 0x6f, 0xb2, 0x4d, 0x64, 0xcb, 0x5e, + 0x5e, 0x1a, 0xc8, 0xcf, 0x29, 0x58, 0x28, 0x30, 0xec, 0x29, 0x95, 0x09, + 0x1b, 0x11, 0x80, 0xba, 0xe0, 0x16, 0x99, 0x49, 0x76, 0xb3, 0x42, 0x72, + 0x05, 0x10, 0xf2, 0xf5, 0xa8, 0x36, 0x84, 0xf1, 0x83, 0x57, 0x5d, 0x27, + 0xae, 0xe9, 0xae, 0x13, 0x47, 0xf3, 0xda, 0xb1, 0x42, 0xde, 0xa1, 0x25, + 0xc7, 0x72, 0xee, 0x2e, 0x34, 0x78, 0x64, 0x6a, 0xed, 0x91, 0x81, 0xaf, + 0x1e, 0xd3, 0xed, 0x68, 0x91, 0x37, 0x2f, 0xdd, 0x57, 0x5d, 0x2a, 0x3a, + 0x21, 0x86, 0x74, 0x6d, 0xff, 0x0b, 0x56, 0xac, 0xc2, 0x65, 0x3a, 0x88, + 0x91, 0x5e, 0x3c, 0x10, 0x7e, 0x53, 0x02, 0x81, 0x81, 0x00, 0xee, 0x58, + 0x94, 0xcc, 0x96, 0x1b, 0x9a, 0x63, 0x84, 0x45, 0x7c, 0x92, 0x78, 0x35, + 0x17, 0x7e, 0x7f, 0x7d, 0x6f, 0x06, 0x77, 0x69, 0x5c, 0xc4, 0xe8, 0xc7, + 0x19, 0xd2, 0x5e, 0x58, 0xd2, 0x1d, 0xee, 0x4c, 0xf2, 0xd9, 0xcb, 0xca, + 0x2a, 0x27, 0xec, 0x5b, 0x55, 0x37, 0x66, 0x0d, 0x2c, 0xe6, 0xfd, 0x48, + 0x35, 0x51, 0x66, 0x13, 0x1e, 0xab, 0x70, 0xda, 0xe6, 0x45, 0xac, 0x25, + 0x8b, 0x2b, 0x89, 0x4b, 0x19, 0x99, 0x6a, 0x06, 0x81, 0x24, 0xd5, 0xa9, + 0x3c, 0xf6, 0xc4, 0x28, 0x39, 0x70, 0x24, 0x0d, 0x8d, 0xcd, 0x69, 0xb4, + 0x65, 0x78, 0x0d, 0xaf, 0x4f, 0x68, 0xe3, 0xac, 0x9d, 0xaf, 0x07, 0x93, + 0x10, 0xeb, 0xc9, 0x40, 0x8c, 0x82, 0x85, 0x85, 0x16, 0xc0, 0xfc, 0x49, + 0x76, 0x03, 0x63, 0x7a, 0x2c, 0x95, 0x61, 0xc8, 0x3b, 0x07, 0x79, 0x68, + 0x60, 0xb1, 0xc8, 0xf0, 0x97, 0x4f, 0x02, 0x81, 0x81, 0x00, 0xe4, 0xa3, + 0x3c, 0xa3, 0x38, 0x5d, 0x3d, 0x3f, 0x00, 0x72, 0x92, 0x0a, 0x7f, 0xdb, + 0xdd, 0xe4, 0xce, 0xdf, 0x7d, 0x97, 0xaa, 0x01, 0x24, 0x8e, 0x6c, 0x39, + 0x0c, 0x2a, 0xb1, 0xa0, 0x9a, 0x47, 0xc2, 0x5a, 0x77, 0x81, 0xab, 0xeb, + 0x13, 0x61, 0xa9, 0x31, 0xa5, 0x12, 0x27, 0xe6, 0x0b, 0x2f, 0x45, 0x62, + 0x51, 0xb5, 0xa7, 0x47, 0x76, 0xfd, 0x1d, 0x9d, 0x97, 0x69, 0xa0, 0xe7, + 0x0e, 0x63, 0xb7, 0x0f, 0x04, 0xeb, 0x37, 0x22, 0x46, 0x74, 0x3b, 0xdb, + 0xcd, 0x61, 0x70, 0x36, 0xec, 0x4e, 0x16, 0x79, 0xcd, 0x9c, 0x97, 0x00, + 0x73, 0xb3, 0x93, 0x4e, 0x81, 0xe9, 0xa4, 0xfd, 0x05, 0x08, 0x17, 0xd0, + 0xc1, 0x3d, 0x0a, 0xa1, 0x3d, 0xb2, 0x96, 0x1e, 0xdb, 0xcf, 0x76, 0x83, + 0xa1, 0x51, 0x62, 0x40, 0xea, 0x66, 0xfa, 0xec, 0xa4, 0x5d, 0x89, 0x10, + 0xff, 0x25, 0xf5, 0x87, 0x28, 0xfd, 0x02, 0x81, 0x80, 0x0e, 0xb4, 0x22, + 0x41, 0xd8, 0xc4, 0xcd, 0x2a, 0x74, 0x7f, 0x80, 0xe6, 0xdc, 0x49, 0x92, + 0x30, 0x78, 0x96, 0xf9, 0x61, 0x71, 0xbe, 0x6b, 0x3d, 0xae, 0x8a, 0x91, + 0xda, 0x3b, 0x7d, 0xc9, 0x40, 0x95, 0x71, 0xe3, 0xcd, 0x71, 0xd7, 0xff, + 0xef, 0xc4, 0x92, 0x01, 0xd8, 0xd0, 0x0f, 0xe2, 0x04, 0x41, 0xfd, 0xd1, + 0x64, 0x3b, 0x22, 0xd4, 0xd2, 0x88, 0xbc, 0xc8, 0x55, 0xe5, 0xff, 0xce, + 0xed, 0x19, 0xa4, 0x2b, 0x69, 0x1e, 0x74, 0x56, 0x45, 0x3a, 0x75, 0x1d, + 0x50, 0xaf, 0xdb, 0x37, 0x67, 0xe6, 0xa1, 0x7b, 0x6c, 0xff, 0xa7, 0x64, + 0x57, 0x1a, 0xa9, 0x05, 0x02, 0x18, 0x81, 0x8e, 0x9c, 0xbc, 0x9f, 0xe2, + 0xfc, 0x58, 0xc7, 0x05, 0xa4, 0x0b, 0xae, 0xa1, 0x2f, 0xb8, 0xa0, 0xa3, + 0x8a, 0x23, 0xf9, 0xe6, 0x84, 0x34, 0xab, 0x10, 0x91, 0x2e, 0x79, 0x34, + 0xf5, 0xe2, 0xca, 0x8c, 0xdb, 0x02, 0x81, 0x81, 0x00, 0x8e, 0x9e, 0xc9, + 0xc2, 0xdf, 0xf7, 0x36, 0xef, 0x6e, 0x2a, 0x36, 0xeb, 0xd7, 0xa4, 0x52, + 0x43, 0x27, 0x8d, 0xaa, 0x52, 0x2d, 0xa8, 0xc1, 0x66, 0xf4, 0x9f, 0xc6, + 0x78, 0x9e, 0x31, 0x64, 0xe6, 0x56, 0xc9, 0x6d, 0x85, 0x79, 0x2a, 0x5c, + 0xca, 0x53, 0x2b, 0x1a, 0x46, 0xf4, 0x16, 0x60, 0xfe, 0x41, 0xcf, 0xc7, + 0x74, 0x57, 0xd0, 0x06, 0xf4, 0xc9, 0xfa, 0x47, 0x9c, 0xa2, 0xcb, 0xe0, + 0x85, 0xc5, 0x95, 0x9f, 0x35, 0xdd, 0x4c, 0x15, 0x7a, 0xda, 0x34, 0xc4, + 0x81, 0x20, 0x7d, 0x55, 0x85, 0xee, 0x24, 0xa7, 0xa6, 0xcb, 0x0a, 0xec, + 0xa8, 0x13, 0x4a, 0xc4, 0xaa, 0x5a, 0x4c, 0xf9, 0x32, 0xc0, 0x4b, 0x65, + 0x47, 0x65, 0xba, 0x38, 0x57, 0x17, 0x0c, 0xdd, 0xe1, 0x68, 0xd1, 0x4f, + 0x3d, 0xb9, 0x0e, 0xdd, 0x3f, 0x53, 0xe6, 0x91, 0x0e, 0x33, 0xba, 0x77, + 0xc2, 0x03, 0xf5, 0x90, 0x60, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + ]); + var expPrivOrig = [ + '-----BEGIN RSA PRIVATE KEY-----', + 'MIIEpQIBAAKCAQEA7J/Xbhf65MX/rINuvmBmsvJqNPpP4knNVCk0lTtVwfUfFj9qn+WTfC', + 'Xgkttjjbu0wiR8nGlM4KchrPzTRDsar55gkwnTrLRliDmFjNIELK+FJ5JZGyhzmfnBbDcI', + 'ondYWoywlsBjihAQhNj6HrcnWMFrNLTmoQVogsnjam8LtfcTqIsUSm4KcjmmH6BPy3LZ5W', + 'Fhp2NTrmbWurTamJK0UJM235r+WDZtMdf/AYjkSTtxjwnmb8nhmFGMxPoWuUUUe54OCW0H', + 'HnlOobbw3Qo9o5z061+qKTeMtAMlrOhk9ge+yshIOVGvNkLdMn03et3Wv1f5ENef5LjIpx', + 'sMiWnwnQIDAQABAoIBAQDLrZrmbUXNfpFhkZDV1m0QQ5IgIAZ7JkPT2dQlUHm1BqXHpLbH', + 'A/o7tu7j+mxrJ9Oj+Xw5tnoyNirKmKXR6X5DBPTkHGVUF8P9ymWmnXBydnMLaPHCasN3Go', + 'DgAU8xacFn0AqA+QG1abaOY6aIoecAgx0gtUZ//APF8LoMd6GA8pDPClcUoMcwWxAseIWi', + 'Un7xqNC8eD5+9sXFrPMC1NwCILjMN+GqLSTtRPt3IOXEOGMI4pLSat8Ky1SXkcdVnDEA4v', + 'Il2ths6m3y/5gWF/X6XNj9ivfqNaCWve3TNRzueKMf/QwkS61PpQiz15DnCGBSJu6TQIDR', + 'r690TTtvTkKRAoGBAP4mnYGh8+JIrSJN9BxoTeHi/wm/phIKFs7WNHN9VdM1b7JNZMteXh', + 'rIzylYKDDsKZUJGxGAuuAWmUl2s0JyBRDy9ag2hPGDV10nrumuE0fz2rFC3qElx3LuLjR4', + 'ZGrtkYGvHtPtaJE3L91XXSo6IYZ0bf8LVqzCZTqIkV48EH5TAoGBAO5YlMyWG5pjhEV8kn', + 'g1F35/fW8Gd2lcxOjHGdJeWNId7kzy2cvKKifsW1U3Zg0s5v1INVFmEx6rcNrmRawliyuJ', + 'SxmZagaBJNWpPPbEKDlwJA2NzWm0ZXgNr09o46ydrweTEOvJQIyChYUWwPxJdgNjeiyVYc', + 'g7B3loYLHI8JdPAoGBAOSjPKM4XT0/AHKSCn/b3eTO332XqgEkjmw5DCqxoJpHwlp3gavr', + 'E2GpMaUSJ+YLL0ViUbWnR3b9HZ2XaaDnDmO3DwTrNyJGdDvbzWFwNuxOFnnNnJcAc7OTTo', + 'HppP0FCBfQwT0KoT2ylh7bz3aDoVFiQOpm+uykXYkQ/yX1hyj9AoGADrQiQdjEzSp0f4Dm', + '3EmSMHiW+WFxvms9roqR2jt9yUCVcePNcdf/78SSAdjQD+IEQf3RZDsi1NKIvMhV5f/O7R', + 'mkK2kedFZFOnUdUK/bN2fmoXts/6dkVxqpBQIYgY6cvJ/i/FjHBaQLrqEvuKCjiiP55oQ0', + 'qxCRLnk09eLKjNsCgYEAjp7Jwt/3Nu9uKjbr16RSQyeNqlItqMFm9J/GeJ4xZOZWyW2FeS', + 'pcylMrGkb0FmD+Qc/HdFfQBvTJ+kecosvghcWVnzXdTBV62jTEgSB9VYXuJKemywrsqBNK', + 'xKpaTPkywEtlR2W6OFcXDN3haNFPPbkO3T9T5pEOM7p3wgP1kGAHBwcHBwcH', + '-----END RSA PRIVATE KEY-----' + ].join('\n'); + assert(keyInfo.ppk === undefined, makeMsg(what, 'Unexpected PPK flag')); + assert(keyInfo._converted === undefined, + makeMsg(what, 'Unexpected automatic private PEM generation')); + assert(keyInfo._macresult === undefined, + makeMsg(what, 'Unexpected MAC verification')); + assert(keyInfo._decrypted === true, + makeMsg(what, 'Expected decrypted flag')); + assert.deepEqual(keyInfo.private, + expPriv, + makeMsg(what, 'Decrypted private data mismatch')); + assert.deepEqual(keyInfo.privateOrig, + expPrivOrig, + makeMsg(what, 'Decrypted private PEM data mismatch')); + next(); + }, + what: 'decryptKey - with encrypted RSA' + }, + { run: function() { + var pubkey = [ + '---- BEGIN SSH2 PUBLIC KEY ----', + 'Comment: "dsa-key-20151028"', + 'AAAAB3NzaC1kc3MAAAEBAJ0Gth9JHw/a8RmY3Y0UFqBWVWkzWxkzG+DR2oqHwTIq', + 'jAi9Xr06oSbdmXd3Jl3bHsbd2gVq4+/j32s0uIf6FEW7mFooSiDOcRWARJSAAmkI', + 'T9ep//ag+gNUmwhtPebliCqcAn9VWE7wq2v0FJsG3trFW/pvi/hVsBOrkz4Qieqb', + 'KbwNwZc/MI+h9KAQPV7tWN2y5aG3jlVD9PERyeFPlmYkD1P+IqytxvL3thUFKeru', + 'N8w+hjKIGGonEcVzWRJ9UUBQqAaNNH4/9mzedpS8CivfnUvsIw9rSTB4N+Wf70jb', + '6a2qD1mHs1DqOkX136UOn5HkFldBnny0NSmlR/LewQkAAAAVAMu94kPPMR0Ew6Zh', + 'mAoJJc0RjisBAAABAGkOU/b/I0opGITGCx9qFEcqiJ/VJHVsYhQgM/jCkydEc9kW', + 'yjY+wKulGWpmA8wGmYm9j4IAgMGEXjBR8dyYJNZVXK0JOJmWrqUj5Q1GCUS5hCyU', + 'iA7nmVQ4syhGE49aFBLFdyKS6t7//swEEEV+6Hw9qcQWB98zoD8qdPGz3W/9kNXB', + 'OgVHWyqfWsbA/7MW2vjjF/u2EJe8YRKIJnodLOSNwPf0iCmj1HdaIm5N2Nl1k/6/', + '9MwlY6tjn4hinrEN/pOiC1ci/1ADmTq4L9upi1Paix51zD8Yp7q3SxOgZqFU0ELF', + 'VP/XHokm278t1mE9hxDwkepv7XgBda8uamWzwSoAAAEAYl2bjiCjIB68+DNuRgtf', + 'lvVk00nOH3dYXSslwKIFTivYDczjz0splaLsEhrdTRiOXyVsCEDhYtlvWlTw34rg', + 's2QoutpqISOiq26XwPdOlejD7Hy7gtw3yRyrhbXHYHE0nOvx0/SP7il4ub//QRTd', + '7cUPao2f359cGpap84anqKJjF3m4oRGdZGhTAQPqtGMkchZvItKyZe6pJ9HhsE7h', + 'NMsxPHAUon8QwNL1v+JkHg7i+Oe8rEZx/51m/qGVtXLN+z885lsqzuwe9KhY5I8C', + 'C3f8nR+Mivfp1ce9pSMKCpdRASzOBuykZKYZmns6SA0UqAp7ZLDKubbhk9ZLVyAO', + 'dA==', + '---- END SSH2 PUBLIC KEY ----' + ].join('\n'); + assert.doesNotThrow(function() { + var res = utils.genPublicKey(utils.parseKey(pubkey)); + assert.deepEqual( + res, + { type: 'dss', + fulltype: 'ssh-dss', + curve: undefined, + public: new Buffer([ + 0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2d, 0x64, 0x73, 0x73, + 0x00, 0x00, 0x01, 0x01, 0x00, 0x9d, 0x06, 0xb6, 0x1f, 0x49, 0x1f, + 0x0f, 0xda, 0xf1, 0x19, 0x98, 0xdd, 0x8d, 0x14, 0x16, 0xa0, 0x56, + 0x55, 0x69, 0x33, 0x5b, 0x19, 0x33, 0x1b, 0xe0, 0xd1, 0xda, 0x8a, + 0x87, 0xc1, 0x32, 0x2a, 0x8c, 0x08, 0xbd, 0x5e, 0xbd, 0x3a, 0xa1, + 0x26, 0xdd, 0x99, 0x77, 0x77, 0x26, 0x5d, 0xdb, 0x1e, 0xc6, 0xdd, + 0xda, 0x05, 0x6a, 0xe3, 0xef, 0xe3, 0xdf, 0x6b, 0x34, 0xb8, 0x87, + 0xfa, 0x14, 0x45, 0xbb, 0x98, 0x5a, 0x28, 0x4a, 0x20, 0xce, 0x71, + 0x15, 0x80, 0x44, 0x94, 0x80, 0x02, 0x69, 0x08, 0x4f, 0xd7, 0xa9, + 0xff, 0xf6, 0xa0, 0xfa, 0x03, 0x54, 0x9b, 0x08, 0x6d, 0x3d, 0xe6, + 0xe5, 0x88, 0x2a, 0x9c, 0x02, 0x7f, 0x55, 0x58, 0x4e, 0xf0, 0xab, + 0x6b, 0xf4, 0x14, 0x9b, 0x06, 0xde, 0xda, 0xc5, 0x5b, 0xfa, 0x6f, + 0x8b, 0xf8, 0x55, 0xb0, 0x13, 0xab, 0x93, 0x3e, 0x10, 0x89, 0xea, + 0x9b, 0x29, 0xbc, 0x0d, 0xc1, 0x97, 0x3f, 0x30, 0x8f, 0xa1, 0xf4, + 0xa0, 0x10, 0x3d, 0x5e, 0xed, 0x58, 0xdd, 0xb2, 0xe5, 0xa1, 0xb7, + 0x8e, 0x55, 0x43, 0xf4, 0xf1, 0x11, 0xc9, 0xe1, 0x4f, 0x96, 0x66, + 0x24, 0x0f, 0x53, 0xfe, 0x22, 0xac, 0xad, 0xc6, 0xf2, 0xf7, 0xb6, + 0x15, 0x05, 0x29, 0xea, 0xee, 0x37, 0xcc, 0x3e, 0x86, 0x32, 0x88, + 0x18, 0x6a, 0x27, 0x11, 0xc5, 0x73, 0x59, 0x12, 0x7d, 0x51, 0x40, + 0x50, 0xa8, 0x06, 0x8d, 0x34, 0x7e, 0x3f, 0xf6, 0x6c, 0xde, 0x76, + 0x94, 0xbc, 0x0a, 0x2b, 0xdf, 0x9d, 0x4b, 0xec, 0x23, 0x0f, 0x6b, + 0x49, 0x30, 0x78, 0x37, 0xe5, 0x9f, 0xef, 0x48, 0xdb, 0xe9, 0xad, + 0xaa, 0x0f, 0x59, 0x87, 0xb3, 0x50, 0xea, 0x3a, 0x45, 0xf5, 0xdf, + 0xa5, 0x0e, 0x9f, 0x91, 0xe4, 0x16, 0x57, 0x41, 0x9e, 0x7c, 0xb4, + 0x35, 0x29, 0xa5, 0x47, 0xf2, 0xde, 0xc1, 0x09, 0x00, 0x00, 0x00, + 0x15, 0x00, 0xcb, 0xbd, 0xe2, 0x43, 0xcf, 0x31, 0x1d, 0x04, 0xc3, + 0xa6, 0x61, 0x98, 0x0a, 0x09, 0x25, 0xcd, 0x11, 0x8e, 0x2b, 0x01, + 0x00, 0x00, 0x01, 0x00, 0x69, 0x0e, 0x53, 0xf6, 0xff, 0x23, 0x4a, + 0x29, 0x18, 0x84, 0xc6, 0x0b, 0x1f, 0x6a, 0x14, 0x47, 0x2a, 0x88, + 0x9f, 0xd5, 0x24, 0x75, 0x6c, 0x62, 0x14, 0x20, 0x33, 0xf8, 0xc2, + 0x93, 0x27, 0x44, 0x73, 0xd9, 0x16, 0xca, 0x36, 0x3e, 0xc0, 0xab, + 0xa5, 0x19, 0x6a, 0x66, 0x03, 0xcc, 0x06, 0x99, 0x89, 0xbd, 0x8f, + 0x82, 0x00, 0x80, 0xc1, 0x84, 0x5e, 0x30, 0x51, 0xf1, 0xdc, 0x98, + 0x24, 0xd6, 0x55, 0x5c, 0xad, 0x09, 0x38, 0x99, 0x96, 0xae, 0xa5, + 0x23, 0xe5, 0x0d, 0x46, 0x09, 0x44, 0xb9, 0x84, 0x2c, 0x94, 0x88, + 0x0e, 0xe7, 0x99, 0x54, 0x38, 0xb3, 0x28, 0x46, 0x13, 0x8f, 0x5a, + 0x14, 0x12, 0xc5, 0x77, 0x22, 0x92, 0xea, 0xde, 0xff, 0xfe, 0xcc, + 0x04, 0x10, 0x45, 0x7e, 0xe8, 0x7c, 0x3d, 0xa9, 0xc4, 0x16, 0x07, + 0xdf, 0x33, 0xa0, 0x3f, 0x2a, 0x74, 0xf1, 0xb3, 0xdd, 0x6f, 0xfd, + 0x90, 0xd5, 0xc1, 0x3a, 0x05, 0x47, 0x5b, 0x2a, 0x9f, 0x5a, 0xc6, + 0xc0, 0xff, 0xb3, 0x16, 0xda, 0xf8, 0xe3, 0x17, 0xfb, 0xb6, 0x10, + 0x97, 0xbc, 0x61, 0x12, 0x88, 0x26, 0x7a, 0x1d, 0x2c, 0xe4, 0x8d, + 0xc0, 0xf7, 0xf4, 0x88, 0x29, 0xa3, 0xd4, 0x77, 0x5a, 0x22, 0x6e, + 0x4d, 0xd8, 0xd9, 0x75, 0x93, 0xfe, 0xbf, 0xf4, 0xcc, 0x25, 0x63, + 0xab, 0x63, 0x9f, 0x88, 0x62, 0x9e, 0xb1, 0x0d, 0xfe, 0x93, 0xa2, + 0x0b, 0x57, 0x22, 0xff, 0x50, 0x03, 0x99, 0x3a, 0xb8, 0x2f, 0xdb, + 0xa9, 0x8b, 0x53, 0xda, 0x8b, 0x1e, 0x75, 0xcc, 0x3f, 0x18, 0xa7, + 0xba, 0xb7, 0x4b, 0x13, 0xa0, 0x66, 0xa1, 0x54, 0xd0, 0x42, 0xc5, + 0x54, 0xff, 0xd7, 0x1e, 0x89, 0x26, 0xdb, 0xbf, 0x2d, 0xd6, 0x61, + 0x3d, 0x87, 0x10, 0xf0, 0x91, 0xea, 0x6f, 0xed, 0x78, 0x01, 0x75, + 0xaf, 0x2e, 0x6a, 0x65, 0xb3, 0xc1, 0x2a, 0x00, 0x00, 0x01, 0x00, + 0x62, 0x5d, 0x9b, 0x8e, 0x20, 0xa3, 0x20, 0x1e, 0xbc, 0xf8, 0x33, + 0x6e, 0x46, 0x0b, 0x5f, 0x96, 0xf5, 0x64, 0xd3, 0x49, 0xce, 0x1f, + 0x77, 0x58, 0x5d, 0x2b, 0x25, 0xc0, 0xa2, 0x05, 0x4e, 0x2b, 0xd8, + 0x0d, 0xcc, 0xe3, 0xcf, 0x4b, 0x29, 0x95, 0xa2, 0xec, 0x12, 0x1a, + 0xdd, 0x4d, 0x18, 0x8e, 0x5f, 0x25, 0x6c, 0x08, 0x40, 0xe1, 0x62, + 0xd9, 0x6f, 0x5a, 0x54, 0xf0, 0xdf, 0x8a, 0xe0, 0xb3, 0x64, 0x28, + 0xba, 0xda, 0x6a, 0x21, 0x23, 0xa2, 0xab, 0x6e, 0x97, 0xc0, 0xf7, + 0x4e, 0x95, 0xe8, 0xc3, 0xec, 0x7c, 0xbb, 0x82, 0xdc, 0x37, 0xc9, + 0x1c, 0xab, 0x85, 0xb5, 0xc7, 0x60, 0x71, 0x34, 0x9c, 0xeb, 0xf1, + 0xd3, 0xf4, 0x8f, 0xee, 0x29, 0x78, 0xb9, 0xbf, 0xff, 0x41, 0x14, + 0xdd, 0xed, 0xc5, 0x0f, 0x6a, 0x8d, 0x9f, 0xdf, 0x9f, 0x5c, 0x1a, + 0x96, 0xa9, 0xf3, 0x86, 0xa7, 0xa8, 0xa2, 0x63, 0x17, 0x79, 0xb8, + 0xa1, 0x11, 0x9d, 0x64, 0x68, 0x53, 0x01, 0x03, 0xea, 0xb4, 0x63, + 0x24, 0x72, 0x16, 0x6f, 0x22, 0xd2, 0xb2, 0x65, 0xee, 0xa9, 0x27, + 0xd1, 0xe1, 0xb0, 0x4e, 0xe1, 0x34, 0xcb, 0x31, 0x3c, 0x70, 0x14, + 0xa2, 0x7f, 0x10, 0xc0, 0xd2, 0xf5, 0xbf, 0xe2, 0x64, 0x1e, 0x0e, + 0xe2, 0xf8, 0xe7, 0xbc, 0xac, 0x46, 0x71, 0xff, 0x9d, 0x66, 0xfe, + 0xa1, 0x95, 0xb5, 0x72, 0xcd, 0xfb, 0x3f, 0x3c, 0xe6, 0x5b, 0x2a, + 0xce, 0xec, 0x1e, 0xf4, 0xa8, 0x58, 0xe4, 0x8f, 0x02, 0x0b, 0x77, + 0xfc, 0x9d, 0x1f, 0x8c, 0x8a, 0xf7, 0xe9, 0xd5, 0xc7, 0xbd, 0xa5, + 0x23, 0x0a, 0x0a, 0x97, 0x51, 0x01, 0x2c, 0xce, 0x06, 0xec, 0xa4, + 0x64, 0xa6, 0x19, 0x9a, 0x7b, 0x3a, 0x48, 0x0d, 0x14, 0xa8, 0x0a, + 0x7b, 0x64, 0xb0, 0xca, 0xb9, 0xb6, 0xe1, 0x93, 0xd6, 0x4b, 0x57, + 0x20, 0x0e, 0x74, + ]), + publicOrig: new Buffer([ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, + 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, 0x45, 0x59, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x4f, 0x6a, + 0x43, 0x43, 0x41, 0x69, 0x30, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, + 0x4d, 0x34, 0x34, 0x42, 0x41, 0x45, 0x77, 0x67, 0x67, 0x49, 0x67, + 0x41, 0x6f, 0x49, 0x42, 0x41, 0x51, 0x43, 0x64, 0x42, 0x72, 0x59, + 0x66, 0x53, 0x52, 0x38, 0x50, 0x32, 0x76, 0x45, 0x5a, 0x6d, 0x4e, + 0x32, 0x4e, 0x46, 0x42, 0x61, 0x67, 0x56, 0x6c, 0x56, 0x70, 0x4d, + 0x31, 0x73, 0x5a, 0x0a, 0x4d, 0x78, 0x76, 0x67, 0x30, 0x64, 0x71, + 0x4b, 0x68, 0x38, 0x45, 0x79, 0x4b, 0x6f, 0x77, 0x49, 0x76, 0x56, + 0x36, 0x39, 0x4f, 0x71, 0x45, 0x6d, 0x33, 0x5a, 0x6c, 0x33, 0x64, + 0x79, 0x5a, 0x64, 0x32, 0x78, 0x37, 0x47, 0x33, 0x64, 0x6f, 0x46, + 0x61, 0x75, 0x50, 0x76, 0x34, 0x39, 0x39, 0x72, 0x4e, 0x4c, 0x69, + 0x48, 0x2b, 0x68, 0x52, 0x46, 0x75, 0x35, 0x68, 0x61, 0x4b, 0x45, + 0x6f, 0x67, 0x0a, 0x7a, 0x6e, 0x45, 0x56, 0x67, 0x45, 0x53, 0x55, + 0x67, 0x41, 0x4a, 0x70, 0x43, 0x45, 0x2f, 0x58, 0x71, 0x66, 0x2f, + 0x32, 0x6f, 0x50, 0x6f, 0x44, 0x56, 0x4a, 0x73, 0x49, 0x62, 0x54, + 0x33, 0x6d, 0x35, 0x59, 0x67, 0x71, 0x6e, 0x41, 0x4a, 0x2f, 0x56, + 0x56, 0x68, 0x4f, 0x38, 0x4b, 0x74, 0x72, 0x39, 0x42, 0x53, 0x62, + 0x42, 0x74, 0x37, 0x61, 0x78, 0x56, 0x76, 0x36, 0x62, 0x34, 0x76, + 0x34, 0x0a, 0x56, 0x62, 0x41, 0x54, 0x71, 0x35, 0x4d, 0x2b, 0x45, + 0x49, 0x6e, 0x71, 0x6d, 0x79, 0x6d, 0x38, 0x44, 0x63, 0x47, 0x58, + 0x50, 0x7a, 0x43, 0x50, 0x6f, 0x66, 0x53, 0x67, 0x45, 0x44, 0x31, + 0x65, 0x37, 0x56, 0x6a, 0x64, 0x73, 0x75, 0x57, 0x68, 0x74, 0x34, + 0x35, 0x56, 0x51, 0x2f, 0x54, 0x78, 0x45, 0x63, 0x6e, 0x68, 0x54, + 0x35, 0x5a, 0x6d, 0x4a, 0x41, 0x39, 0x54, 0x2f, 0x69, 0x4b, 0x73, + 0x0a, 0x72, 0x63, 0x62, 0x79, 0x39, 0x37, 0x59, 0x56, 0x42, 0x53, + 0x6e, 0x71, 0x37, 0x6a, 0x66, 0x4d, 0x50, 0x6f, 0x59, 0x79, 0x69, + 0x42, 0x68, 0x71, 0x4a, 0x78, 0x48, 0x46, 0x63, 0x31, 0x6b, 0x53, + 0x66, 0x56, 0x46, 0x41, 0x55, 0x4b, 0x67, 0x47, 0x6a, 0x54, 0x52, + 0x2b, 0x50, 0x2f, 0x5a, 0x73, 0x33, 0x6e, 0x61, 0x55, 0x76, 0x41, + 0x6f, 0x72, 0x33, 0x35, 0x31, 0x4c, 0x37, 0x43, 0x4d, 0x50, 0x0a, + 0x61, 0x30, 0x6b, 0x77, 0x65, 0x44, 0x66, 0x6c, 0x6e, 0x2b, 0x39, + 0x49, 0x32, 0x2b, 0x6d, 0x74, 0x71, 0x67, 0x39, 0x5a, 0x68, 0x37, + 0x4e, 0x51, 0x36, 0x6a, 0x70, 0x46, 0x39, 0x64, 0x2b, 0x6c, 0x44, + 0x70, 0x2b, 0x52, 0x35, 0x42, 0x5a, 0x58, 0x51, 0x5a, 0x35, 0x38, + 0x74, 0x44, 0x55, 0x70, 0x70, 0x55, 0x66, 0x79, 0x33, 0x73, 0x45, + 0x4a, 0x41, 0x68, 0x55, 0x41, 0x79, 0x37, 0x33, 0x69, 0x0a, 0x51, + 0x38, 0x38, 0x78, 0x48, 0x51, 0x54, 0x44, 0x70, 0x6d, 0x47, 0x59, + 0x43, 0x67, 0x6b, 0x6c, 0x7a, 0x52, 0x47, 0x4f, 0x4b, 0x77, 0x45, + 0x43, 0x67, 0x67, 0x45, 0x41, 0x61, 0x51, 0x35, 0x54, 0x39, 0x76, + 0x38, 0x6a, 0x53, 0x69, 0x6b, 0x59, 0x68, 0x4d, 0x59, 0x4c, 0x48, + 0x32, 0x6f, 0x55, 0x52, 0x79, 0x71, 0x49, 0x6e, 0x39, 0x55, 0x6b, + 0x64, 0x57, 0x78, 0x69, 0x46, 0x43, 0x41, 0x7a, 0x0a, 0x2b, 0x4d, + 0x4b, 0x54, 0x4a, 0x30, 0x52, 0x7a, 0x32, 0x52, 0x62, 0x4b, 0x4e, + 0x6a, 0x37, 0x41, 0x71, 0x36, 0x55, 0x5a, 0x61, 0x6d, 0x59, 0x44, + 0x7a, 0x41, 0x61, 0x5a, 0x69, 0x62, 0x32, 0x50, 0x67, 0x67, 0x43, + 0x41, 0x77, 0x59, 0x52, 0x65, 0x4d, 0x46, 0x48, 0x78, 0x33, 0x4a, + 0x67, 0x6b, 0x31, 0x6c, 0x56, 0x63, 0x72, 0x51, 0x6b, 0x34, 0x6d, + 0x5a, 0x61, 0x75, 0x70, 0x53, 0x50, 0x6c, 0x0a, 0x44, 0x55, 0x59, + 0x4a, 0x52, 0x4c, 0x6d, 0x45, 0x4c, 0x4a, 0x53, 0x49, 0x44, 0x75, + 0x65, 0x5a, 0x56, 0x44, 0x69, 0x7a, 0x4b, 0x45, 0x59, 0x54, 0x6a, + 0x31, 0x6f, 0x55, 0x45, 0x73, 0x56, 0x33, 0x49, 0x70, 0x4c, 0x71, + 0x33, 0x76, 0x2f, 0x2b, 0x7a, 0x41, 0x51, 0x51, 0x52, 0x58, 0x37, + 0x6f, 0x66, 0x44, 0x32, 0x70, 0x78, 0x42, 0x59, 0x48, 0x33, 0x7a, + 0x4f, 0x67, 0x50, 0x79, 0x70, 0x30, 0x0a, 0x38, 0x62, 0x50, 0x64, + 0x62, 0x2f, 0x32, 0x51, 0x31, 0x63, 0x45, 0x36, 0x42, 0x55, 0x64, + 0x62, 0x4b, 0x70, 0x39, 0x61, 0x78, 0x73, 0x44, 0x2f, 0x73, 0x78, + 0x62, 0x61, 0x2b, 0x4f, 0x4d, 0x58, 0x2b, 0x37, 0x59, 0x51, 0x6c, + 0x37, 0x78, 0x68, 0x45, 0x6f, 0x67, 0x6d, 0x65, 0x68, 0x30, 0x73, + 0x35, 0x49, 0x33, 0x41, 0x39, 0x2f, 0x53, 0x49, 0x4b, 0x61, 0x50, + 0x55, 0x64, 0x31, 0x6f, 0x69, 0x0a, 0x62, 0x6b, 0x33, 0x59, 0x32, + 0x58, 0x57, 0x54, 0x2f, 0x72, 0x2f, 0x30, 0x7a, 0x43, 0x56, 0x6a, + 0x71, 0x32, 0x4f, 0x66, 0x69, 0x47, 0x4b, 0x65, 0x73, 0x51, 0x33, + 0x2b, 0x6b, 0x36, 0x49, 0x4c, 0x56, 0x79, 0x4c, 0x2f, 0x55, 0x41, + 0x4f, 0x5a, 0x4f, 0x72, 0x67, 0x76, 0x32, 0x36, 0x6d, 0x4c, 0x55, + 0x39, 0x71, 0x4c, 0x48, 0x6e, 0x58, 0x4d, 0x50, 0x78, 0x69, 0x6e, + 0x75, 0x72, 0x64, 0x4c, 0x0a, 0x45, 0x36, 0x42, 0x6d, 0x6f, 0x56, + 0x54, 0x51, 0x51, 0x73, 0x56, 0x55, 0x2f, 0x39, 0x63, 0x65, 0x69, + 0x53, 0x62, 0x62, 0x76, 0x79, 0x33, 0x57, 0x59, 0x54, 0x32, 0x48, + 0x45, 0x50, 0x43, 0x52, 0x36, 0x6d, 0x2f, 0x74, 0x65, 0x41, 0x46, + 0x31, 0x72, 0x79, 0x35, 0x71, 0x5a, 0x62, 0x50, 0x42, 0x4b, 0x67, + 0x4f, 0x43, 0x41, 0x51, 0x55, 0x41, 0x41, 0x6f, 0x49, 0x42, 0x41, + 0x47, 0x4a, 0x64, 0x0a, 0x6d, 0x34, 0x34, 0x67, 0x6f, 0x79, 0x41, + 0x65, 0x76, 0x50, 0x67, 0x7a, 0x62, 0x6b, 0x59, 0x4c, 0x58, 0x35, + 0x62, 0x31, 0x5a, 0x4e, 0x4e, 0x4a, 0x7a, 0x68, 0x39, 0x33, 0x57, + 0x46, 0x30, 0x72, 0x4a, 0x63, 0x43, 0x69, 0x42, 0x55, 0x34, 0x72, + 0x32, 0x41, 0x33, 0x4d, 0x34, 0x38, 0x39, 0x4c, 0x4b, 0x5a, 0x57, + 0x69, 0x37, 0x42, 0x49, 0x61, 0x33, 0x55, 0x30, 0x59, 0x6a, 0x6c, + 0x38, 0x6c, 0x0a, 0x62, 0x41, 0x68, 0x41, 0x34, 0x57, 0x4c, 0x5a, + 0x62, 0x31, 0x70, 0x55, 0x38, 0x4e, 0x2b, 0x4b, 0x34, 0x4c, 0x4e, + 0x6b, 0x4b, 0x4c, 0x72, 0x61, 0x61, 0x69, 0x45, 0x6a, 0x6f, 0x71, + 0x74, 0x75, 0x6c, 0x38, 0x44, 0x33, 0x54, 0x70, 0x58, 0x6f, 0x77, + 0x2b, 0x78, 0x38, 0x75, 0x34, 0x4c, 0x63, 0x4e, 0x38, 0x6b, 0x63, + 0x71, 0x34, 0x57, 0x31, 0x78, 0x32, 0x42, 0x78, 0x4e, 0x4a, 0x7a, + 0x72, 0x0a, 0x38, 0x64, 0x50, 0x30, 0x6a, 0x2b, 0x34, 0x70, 0x65, + 0x4c, 0x6d, 0x2f, 0x2f, 0x30, 0x45, 0x55, 0x33, 0x65, 0x33, 0x46, + 0x44, 0x32, 0x71, 0x4e, 0x6e, 0x39, 0x2b, 0x66, 0x58, 0x42, 0x71, + 0x57, 0x71, 0x66, 0x4f, 0x47, 0x70, 0x36, 0x69, 0x69, 0x59, 0x78, + 0x64, 0x35, 0x75, 0x4b, 0x45, 0x52, 0x6e, 0x57, 0x52, 0x6f, 0x55, + 0x77, 0x45, 0x44, 0x36, 0x72, 0x52, 0x6a, 0x4a, 0x48, 0x49, 0x57, + 0x0a, 0x62, 0x79, 0x4c, 0x53, 0x73, 0x6d, 0x58, 0x75, 0x71, 0x53, + 0x66, 0x52, 0x34, 0x62, 0x42, 0x4f, 0x34, 0x54, 0x54, 0x4c, 0x4d, + 0x54, 0x78, 0x77, 0x46, 0x4b, 0x4a, 0x2f, 0x45, 0x4d, 0x44, 0x53, + 0x39, 0x62, 0x2f, 0x69, 0x5a, 0x42, 0x34, 0x4f, 0x34, 0x76, 0x6a, + 0x6e, 0x76, 0x4b, 0x78, 0x47, 0x63, 0x66, 0x2b, 0x64, 0x5a, 0x76, + 0x36, 0x68, 0x6c, 0x62, 0x56, 0x79, 0x7a, 0x66, 0x73, 0x2f, 0x0a, + 0x50, 0x4f, 0x5a, 0x62, 0x4b, 0x73, 0x37, 0x73, 0x48, 0x76, 0x53, + 0x6f, 0x57, 0x4f, 0x53, 0x50, 0x41, 0x67, 0x74, 0x33, 0x2f, 0x4a, + 0x30, 0x66, 0x6a, 0x49, 0x72, 0x33, 0x36, 0x64, 0x58, 0x48, 0x76, + 0x61, 0x55, 0x6a, 0x43, 0x67, 0x71, 0x58, 0x55, 0x51, 0x45, 0x73, + 0x7a, 0x67, 0x62, 0x73, 0x70, 0x47, 0x53, 0x6d, 0x47, 0x5a, 0x70, + 0x37, 0x4f, 0x6b, 0x67, 0x4e, 0x46, 0x4b, 0x67, 0x4b, 0x0a, 0x65, + 0x32, 0x53, 0x77, 0x79, 0x72, 0x6d, 0x32, 0x34, 0x5a, 0x50, 0x57, + 0x53, 0x31, 0x63, 0x67, 0x44, 0x6e, 0x51, 0x3d, 0x0a, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4c, + 0x49, 0x43, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d + ]) + } + ); + next(); + }); + }, + what: 'Generate public key from parsed public key' + }, +]; + +function next() { + if (Array.isArray(process._events.exit)) + process._events.exit = process._events.exit[1]; + if (++t === tests.length) + return; + + var v = tests[t]; + process.nextTick(function() { + v.run.call(v); + }); +} + +function makeMsg(what, msg) { + return '[' + group + what + ']: ' + msg; +} + +process.once('exit', function() { + assert(t === tests.length, + makeMsg('_exit', + 'Only finished ' + t + '/' + tests.length + ' tests')); +}); + +next(); diff --git a/node_modules/ssh2-streams/test/test.js b/node_modules/ssh2-streams/test/test.js new file mode 100644 index 0000000..4a91765 --- /dev/null +++ b/node_modules/ssh2-streams/test/test.js @@ -0,0 +1,22 @@ +var spawn = require('child_process').spawn, + join = require('path').join; + +var files = require('fs').readdirSync(__dirname).filter(function(f) { + return (f.substr(0, 5) === 'test-'); + }).map(function(f) { + return join(__dirname, f); + }), + f = -1; + +function next() { + if (++f < files.length) { + spawn(process.argv[0], [ files[f] ], { stdio: 'inherit' }) + .on('exit', function(code) { + if (code === 0) + process.nextTick(next); + else + process.exit(code); + }); + } +} +next(); diff --git a/node_modules/ssh2/.travis.yml b/node_modules/ssh2/.travis.yml new file mode 100644 index 0000000..3511e64 --- /dev/null +++ b/node_modules/ssh2/.travis.yml @@ -0,0 +1,18 @@ +sudo: false +language: cpp +notifications: + email: false +env: + matrix: + - TRAVIS_NODE_VERSION="0.10" + - TRAVIS_NODE_VERSION="0.12" + - TRAVIS_NODE_VERSION="4" + - TRAVIS_NODE_VERSION="6" + - TRAVIS_NODE_VERSION="7" +install: + - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION + - node --version + - npm --version + - npm install + - ssh -V +script: npm test diff --git a/node_modules/ssh2/LICENSE b/node_modules/ssh2/LICENSE new file mode 100644 index 0000000..290762e --- /dev/null +++ b/node_modules/ssh2/LICENSE @@ -0,0 +1,19 @@ +Copyright Brian White. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/ssh2/README.md b/node_modules/ssh2/README.md new file mode 100644 index 0000000..39e5b6c --- /dev/null +++ b/node_modules/ssh2/README.md @@ -0,0 +1,1053 @@ +Description +=========== + +SSH2 client and server modules written in pure JavaScript for [node.js](http://nodejs.org/). + +Development/testing is done against OpenSSH (7.1 currently). + +[Changes from v0.4.x-v0.5.x](https://github.com/mscdex/ssh2/wiki/Changes-from-0.4.x-to-0.5.x) + +[![Build Status](https://travis-ci.org/mscdex/ssh2.svg?branch=master)](https://travis-ci.org/mscdex/ssh2) + + +Requirements +============ + +* [node.js](http://nodejs.org/) -- v0.10 or newer + + +Install +======= + + npm install ssh2 + + +Client Examples +=============== + +* Execute `uptime` on a server: + +```javascript +var Client = require('ssh2').Client; + +var conn = new Client(); +conn.on('ready', function() { + console.log('Client :: ready'); + conn.exec('uptime', function(err, stream) { + if (err) throw err; + stream.on('close', function(code, signal) { + console.log('Stream :: close :: code: ' + code + ', signal: ' + signal); + conn.end(); + }).on('data', function(data) { + console.log('STDOUT: ' + data); + }).stderr.on('data', function(data) { + console.log('STDERR: ' + data); + }); + }); +}).connect({ + host: '192.168.100.100', + port: 22, + username: 'frylock', + privateKey: require('fs').readFileSync('/here/is/my/key') +}); + +// example output: +// Client :: ready +// STDOUT: 17:41:15 up 22 days, 18:09, 1 user, load average: 0.00, 0.01, 0.05 +// +// Stream :: exit :: code: 0, signal: undefined +// Stream :: close +``` + +* Start an interactive shell session: + +```javascript +var Client = require('ssh2').Client; + +var conn = new Client(); +conn.on('ready', function() { + console.log('Client :: ready'); + conn.shell(function(err, stream) { + if (err) throw err; + stream.on('close', function() { + console.log('Stream :: close'); + conn.end(); + }).on('data', function(data) { + console.log('STDOUT: ' + data); + }).stderr.on('data', function(data) { + console.log('STDERR: ' + data); + }); + stream.end('ls -l\nexit\n'); + }); +}).connect({ + host: '192.168.100.100', + port: 22, + username: 'frylock', + privateKey: require('fs').readFileSync('/here/is/my/key') +}); + +// example output: +// Client :: ready +// STDOUT: Last login: Sun Jun 15 09:37:21 2014 from 192.168.100.100 +// +// STDOUT: ls -l +// exit +// +// STDOUT: frylock@athf:~$ ls -l +// +// STDOUT: total 8 +// +// STDOUT: drwxr-xr-x 2 frylock frylock 4096 Nov 18 2012 mydir +// +// STDOUT: -rw-r--r-- 1 frylock frylock 25 Apr 11 2013 test.txt +// +// STDOUT: frylock@athf:~$ exit +// +// STDOUT: logout +// +// Stream :: close +``` + +* Send a raw HTTP request to port 80 on the server: + +```javascript +var Client = require('ssh2').Client; + +var conn = new Client(); +conn.on('ready', function() { + console.log('Client :: ready'); + conn.forwardOut('192.168.100.102', 8000, '127.0.0.1', 80, function(err, stream) { + if (err) throw err; + stream.on('close', function() { + console.log('TCP :: CLOSED'); + conn.end(); + }).on('data', function(data) { + console.log('TCP :: DATA: ' + data); + }).end([ + 'HEAD / HTTP/1.1', + 'User-Agent: curl/7.27.0', + 'Host: 127.0.0.1', + 'Accept: */*', + 'Connection: close', + '', + '' + ].join('\r\n')); + }); +}).connect({ + host: '192.168.100.100', + port: 22, + username: 'frylock', + password: 'nodejsrules' +}); + +// example output: +// Client :: ready +// TCP :: DATA: HTTP/1.1 200 OK +// Date: Thu, 15 Nov 2012 13:52:58 GMT +// Server: Apache/2.2.22 (Ubuntu) +// X-Powered-By: PHP/5.4.6-1ubuntu1 +// Last-Modified: Thu, 01 Jan 1970 00:00:00 GMT +// Content-Encoding: gzip +// Vary: Accept-Encoding +// Connection: close +// Content-Type: text/html; charset=UTF-8 +// +// +// TCP :: CLOSED +``` + +* Forward connections to 127.0.0.1:8000 on the server to us: + +```javascript +var Client = require('ssh2').Client; + +var conn = new Client(); +conn.on('ready', function() { + console.log('Client :: ready'); + conn.forwardIn('127.0.0.1', 8000, function(err) { + if (err) throw err; + console.log('Listening for connections on server on port 8000!'); + }); +}).on('tcp connection', function(info, accept, reject) { + console.log('TCP :: INCOMING CONNECTION:'); + console.dir(info); + accept().on('close', function() { + console.log('TCP :: CLOSED'); + }).on('data', function(data) { + console.log('TCP :: DATA: ' + data); + }).end([ + 'HTTP/1.1 404 Not Found', + 'Date: Thu, 15 Nov 2012 02:07:58 GMT', + 'Server: ForwardedConnection', + 'Content-Length: 0', + 'Connection: close', + '', + '' + ].join('\r\n')); +}).connect({ + host: '192.168.100.100', + port: 22, + username: 'frylock', + password: 'nodejsrules' +}); + +// example output: +// Client :: ready +// Listening for connections on server on port 8000! +// (.... then from another terminal on the server: `curl -I http://127.0.0.1:8000`) +// TCP :: INCOMING CONNECTION: { destIP: '127.0.0.1', +// destPort: 8000, +// srcIP: '127.0.0.1', +// srcPort: 41969 } +// TCP DATA: HEAD / HTTP/1.1 +// User-Agent: curl/7.27.0 +// Host: 127.0.0.1:8000 +// Accept: */* +// +// +// TCP :: CLOSED +``` + +* Get a directory listing via SFTP: + +```javascript +var Client = require('ssh2').Client; + +var conn = new Client(); +conn.on('ready', function() { + console.log('Client :: ready'); + conn.sftp(function(err, sftp) { + if (err) throw err; + sftp.readdir('foo', function(err, list) { + if (err) throw err; + console.dir(list); + conn.end(); + }); + }); +}).connect({ + host: '192.168.100.100', + port: 22, + username: 'frylock', + password: 'nodejsrules' +}); + +// example output: +// Client :: ready +// [ { filename: 'test.txt', +// longname: '-rw-r--r-- 1 frylock frylock 12 Nov 18 11:05 test.txt', +// attrs: +// { size: 12, +// uid: 1000, +// gid: 1000, +// mode: 33188, +// atime: 1353254750, +// mtime: 1353254744 } }, +// { filename: 'mydir', +// longname: 'drwxr-xr-x 2 frylock frylock 4096 Nov 18 15:03 mydir', +// attrs: +// { size: 1048576, +// uid: 1000, +// gid: 1000, +// mode: 16877, +// atime: 1353269007, +// mtime: 1353269007 } } ] +``` + +* Connection hopping: + +```javascript +var Client = require('ssh2').Client; + +var conn1 = new Client(); +var conn2 = new Client(); + +conn1.on('ready', function() { + console.log('FIRST :: connection ready'); + conn1.exec('nc 192.168.1.2 22', function(err, stream) { + if (err) { + console.log('FIRST :: exec error: ' + err); + return conn1.end(); + } + conn2.connect({ + sock: stream, + username: 'user2', + password: 'password2', + }); + }); +}).connect({ + host: '192.168.1.1', + username: 'user1', + password: 'password1', +}); + +conn2.on('ready', function() { + console.log('SECOND :: connection ready'); + conn2.exec('uptime', function(err, stream) { + if (err) { + console.log('SECOND :: exec error: ' + err); + return conn1.end(); + } + stream.on('end', function() { + conn1.end(); // close parent (and this) connection + }).on('data', function(data) { + console.log(data.toString()); + }); + }); +}); +``` + +* Forward X11 connections (xeyes in this case): + +```javascript +var net = require('net'); + +var Client = require('ssh2').Client; + +var conn = new Client(); + +conn.on('x11', function(info, accept, reject) { + var xserversock = new net.Socket(); + xserversock.on('connect', function() { + var xclientsock = accept(); + xclientsock.pipe(xserversock).pipe(xclientsock); + }); + // connects to localhost:0.0 + xserversock.connect(6000, 'localhost'); +}); + +conn.on('ready', function() { + conn.exec('xeyes', { x11: true }, function(err, stream) { + if (err) throw err; + var code = 0; + stream.on('end', function() { + if (code !== 0) + console.log('Do you have X11 forwarding enabled on your SSH server?'); + conn.end(); + }).on('exit', function(exitcode) { + code = exitcode; + }); + }); +}).connect({ + host: '192.168.1.1', + username: 'foo', + password: 'bar' +}); +``` + +* Dynamic (1:1) port forwarding using a SOCKSv5 proxy (using [socksv5](https://github.com/mscdex/socksv5)): + +```javascript +var socks = require('socksv5'); +var Client = require('ssh2').Client; + +var ssh_config = { + host: '192.168.100.1', + port: 22, + username: 'nodejs', + password: 'rules' +}; + +socks.createServer(function(info, accept, deny) { + // NOTE: you could just use one ssh2 client connection for all forwards, but + // you could run into server-imposed limits if you have too many forwards open + // at any given time + var conn = new Client(); + conn.on('ready', function() { + conn.forwardOut(info.srcAddr, + info.srcPort, + info.dstAddr, + info.dstPort, + function(err, stream) { + if (err) { + conn.end(); + return deny(); + } + + var clientSocket; + if (clientSocket = accept(true)) { + stream.pipe(clientSocket).pipe(stream).on('close', function() { + conn.end(); + }); + } else + conn.end(); + }); + }).on('error', function(err) { + deny(); + }).connect(ssh_config); +}).listen(1080, 'localhost', function() { + console.log('SOCKSv5 proxy server started on port 1080'); +}).useAuth(socks.auth.None()); + +// test with cURL: +// curl -i --socks5 localhost:1080 google.com +``` + +* Invoke an arbitrary subsystem (netconf in this case): + +```javascript +var Client = require('ssh2').Client; +var xmlhello = '' + + '' + + ' ' + + ' urn:ietf:params:netconf:base:1.0' + + ' ' + + ']]>]]>'; + +var conn = new Client(); + +conn.on('ready', function() { + console.log('Client :: ready'); + conn.subsys('netconf', function(err, stream) { + if (err) throw err; + stream.on('data', function(data) { + console.log(data); + }).write(xmlhello); + }); +}).connect({ + host: '1.2.3.4', + port: 22, + username: 'blargh', + password: 'honk' +}); +``` + +Server Examples +=============== + +* Only allow password and public key authentication and non-interactive (exec) command execution: + +```javascript +var fs = require('fs'); +var crypto = require('crypto'); +var inspect = require('util').inspect; + +var buffersEqual = require('buffer-equal-constant-time'); +var ssh2 = require('ssh2'); +var utils = ssh2.utils; + +var pubKey = utils.genPublicKey(utils.parseKey(fs.readFileSync('user.pub'))); + +new ssh2.Server({ + hostKeys: [fs.readFileSync('host.key')] +}, function(client) { + console.log('Client connected!'); + + client.on('authentication', function(ctx) { + if (ctx.method === 'password' + && ctx.username === 'foo' + && ctx.password === 'bar') + ctx.accept(); + else if (ctx.method === 'publickey' + && ctx.key.algo === pubKey.fulltype + && buffersEqual(ctx.key.data, pubKey.public)) { + if (ctx.signature) { + var verifier = crypto.createVerify(ctx.sigAlgo); + verifier.update(ctx.blob); + if (verifier.verify(pubKey.publicOrig, ctx.signature)) + ctx.accept(); + else + ctx.reject(); + } else { + // if no signature present, that means the client is just checking + // the validity of the given public key + ctx.accept(); + } + } else + ctx.reject(); + }).on('ready', function() { + console.log('Client authenticated!'); + + client.on('session', function(accept, reject) { + var session = accept(); + session.once('exec', function(accept, reject, info) { + console.log('Client wants to execute: ' + inspect(info.command)); + var stream = accept(); + stream.stderr.write('Oh no, the dreaded errors!\n'); + stream.write('Just kidding about the errors!\n'); + stream.exit(0); + stream.end(); + }); + }); + }).on('end', function() { + console.log('Client disconnected'); + }); +}).listen(0, '127.0.0.1', function() { + console.log('Listening on port ' + this.address().port); +}); +``` + +* SFTP only server: + +```javascript +var fs = require('fs'); + +var ssh2 = require('ssh2'); +var OPEN_MODE = ssh2.SFTP_OPEN_MODE; +var STATUS_CODE = ssh2.SFTP_STATUS_CODE; + +new ssh2.Server({ + hostKeys: [fs.readFileSync('host.key')] +}, function(client) { + console.log('Client connected!'); + + client.on('authentication', function(ctx) { + if (ctx.method === 'password' + && ctx.username === 'foo' + && ctx.password === 'bar') + ctx.accept(); + else + ctx.reject(); + }).on('ready', function() { + console.log('Client authenticated!'); + + client.on('session', function(accept, reject) { + var session = accept(); + session.on('sftp', function(accept, reject) { + console.log('Client SFTP session'); + var openFiles = {}; + var handleCount = 0; + // `sftpStream` is an `SFTPStream` instance in server mode + // see: https://github.com/mscdex/ssh2-streams/blob/master/SFTPStream.md + var sftpStream = accept(); + sftpStream.on('OPEN', function(reqid, filename, flags, attrs) { + // only allow opening /tmp/foo.txt for writing + if (filename !== '/tmp/foo.txt' || !(flags & OPEN_MODE.WRITE)) + return sftpStream.status(reqid, STATUS_CODE.FAILURE); + // create a fake handle to return to the client, this could easily + // be a real file descriptor number for example if actually opening + // the file on the disk + var handle = new Buffer(4); + openFiles[handleCount] = true; + handle.writeUInt32BE(handleCount++, 0, true); + sftpStream.handle(reqid, handle); + console.log('Opening file for write') + }).on('WRITE', function(reqid, handle, offset, data) { + if (handle.length !== 4 || !openFiles[handle.readUInt32BE(0, true)]) + return sftpStream.status(reqid, STATUS_CODE.FAILURE); + // fake the write + sftpStream.status(reqid, STATUS_CODE.OK); + var inspected = require('util').inspect(data); + console.log('Write to file at offset %d: %s', offset, inspected); + }).on('CLOSE', function(reqid, handle) { + var fnum; + if (handle.length !== 4 || !openFiles[(fnum = handle.readUInt32BE(0, true))]) + return sftpStream.status(reqid, STATUS_CODE.FAILURE); + delete openFiles[fnum]; + sftpStream.status(reqid, STATUS_CODE.OK); + console.log('Closing file'); + }); + }); + }); + }).on('end', function() { + console.log('Client disconnected'); + }); +}).listen(0, '127.0.0.1', function() { + console.log('Listening on port ' + this.address().port); +}); +``` + +* You can find more examples in the `examples` directory of this repository. + +API +=== + +`require('ssh2').Client` returns a **_Client_** constructor. + +`require('ssh2').Server` returns a **_Server_** constructor. + +`require('ssh2').utils` returns the [utility methods from `ssh2-streams`](https://github.com/mscdex/ssh2-streams#utility-methods). + +`require('ssh2').SFTP_STATUS_CODE` returns the [`SFTPStream.STATUS_CODE` from `ssh2-streams`](https://github.com/mscdex/ssh2-streams/blob/master/SFTPStream.md#sftpstream-static-constants). + +`require('ssh2').SFTP_OPEN_MODE` returns the [`SFTPStream.OPEN_MODE` from `ssh2-streams`](https://github.com/mscdex/ssh2-streams/blob/master/SFTPStream.md#sftpstream-static-constants). + +Client events +------------- + +* **banner**(< _string_ >message, < _string_ >language) - A notice was sent by the server upon connection. + +* **ready**() - Authentication was successful. + +* **tcp connection**(< _object_ >details, < _function_ >accept, < _function_ >reject) - An incoming forwarded TCP connection is being requested. Calling `accept` accepts the connection and returns a `Channel` object. Calling `reject` rejects the connection and no further action is needed. `details` contains: + + * **srcIP** - _string_ - The originating IP of the connection. + + * **srcPort** - _integer_ - The originating port of the connection. + + * **destIP** - _string_ - The remote IP the connection was received on (given in earlier call to `forwardIn()`). + + * **destPort** - _integer_ - The remote port the connection was received on (given in earlier call to `forwardIn()`). + +* **x11**(< _object_ >details, < _function_ >accept, < _function_ >reject) - An incoming X11 connection is being requested. Calling `accept` accepts the connection and returns a `Channel` object. Calling `reject` rejects the connection and no further action is needed. `details` contains: + + * **srcIP** - _string_ - The originating IP of the connection. + + * **srcPort** - _integer_ - The originating port of the connection. + +* **keyboard-interactive**(< _string_ >name, < _string_ >instructions, < _string_ >instructionsLang, < _array_ >prompts, < _function_ >finish) - The server is asking for replies to the given `prompts` for keyboard-interactive user authentication. `name` is generally what you'd use as a window title (for GUI apps). `prompts` is an array of `{ prompt: 'Password: ', echo: false }` style objects (here `echo` indicates whether user input should be displayed on the screen). The answers for all prompts must be provided as an array of strings and passed to `finish` when you are ready to continue. Note: It's possible for the server to come back and ask more questions. + +* **change password**(< _string_ >message, < _string_ >language, < _function_ >done) - If using password-based user authentication, the server has requested that the user's password be changed. Call `done` with the new password. + +* **continue**() - Emitted when more requests/data can be sent to the server (after a `Client` method returned `false`). + +* **error**(< _Error_ >err) - An error occurred. A 'level' property indicates 'client-socket' for socket-level errors and 'client-ssh' for SSH disconnection messages. In the case of 'client-ssh' messages, there may be a 'description' property that provides more detail. + +* **end**() - The socket was disconnected. + +* **close**(< _boolean_ >hadError) - The socket was closed. `hadError` is set to `true` if this was due to error. + + +Client methods +-------------- + +* **(constructor)**() - Creates and returns a new Client instance. + +* **connect**(< _object_ >config) - _(void)_ - Attempts a connection to a server using the information given in `config`: + + * **host** - _string_ - Hostname or IP address of the server. **Default:** `'localhost'` + + * **port** - _integer_ - Port number of the server. **Default:** `22` + + * **forceIPv4** - _boolean_ - Only connect via resolved IPv4 address for `host`. **Default:** `false` + + * **forceIPv6** - _boolean_ - Only connect via resolved IPv6 address for `host`. **Default:** `false` + + * **hostHash** - _string_ - 'md5' or 'sha1'. The host's key is hashed using this method and passed to the **hostVerifier** function. **Default:** (none) + + * **hostVerifier** - _function_ - Function with parameters `(hashedKey[, callback])` where `hashedKey` is a string hex hash of the host's key for verification purposes. Return `true` to continue with the handshake or `false` to reject and disconnect, or call `callback()` with `true` or `false` if you need to perform asynchronous verification. **Default:** (auto-accept if `hostVerifier` is not set) + + * **username** - _string_ - Username for authentication. **Default:** (none) + + * **password** - _string_ - Password for password-based user authentication. **Default:** (none) + + * **agent** - _string_ - Path to ssh-agent's UNIX socket for ssh-agent-based user authentication. **Windows users: set to 'pageant' for authenticating with Pageant or (actual) path to a cygwin "UNIX socket."** **Default:** (none) + + * **agentForward** - _boolean_ - Set to `true` to use OpenSSH agent forwarding (`auth-agent@openssh.com`) for the life of the connection. `agent` must also be set to use this feature. **Default:** `false` + + * **privateKey** - _mixed_ - _Buffer_ or _string_ that contains a private key for either key-based or hostbased user authentication (OpenSSH format). **Default:** (none) + + * **passphrase** - _string_ - For an encrypted private key, this is the passphrase used to decrypt it. **Default:** (none) + + * **localHostname** - _string_ - Along with **localUsername** and **privateKey**, set this to a non-empty string for hostbased user authentication. **Default:** (none) + + * **localUsername** - _string_ - Along with **localHostname** and **privateKey**, set this to a non-empty string for hostbased user authentication. **Default:** (none) + + * **tryKeyboard** - _boolean_ - Try keyboard-interactive user authentication if primary user authentication method fails. If you set this to `true`, you need to handle the `keyboard-interactive` event. **Default:** `false` + + * **keepaliveInterval** - _integer_ - How often (in milliseconds) to send SSH-level keepalive packets to the server (in a similar way as OpenSSH's ServerAliveInterval config option). Set to 0 to disable. **Default:** `0` + + * **keepaliveCountMax** - _integer_ - How many consecutive, unanswered SSH-level keepalive packets that can be sent to the server before disconnection (similar to OpenSSH's ServerAliveCountMax config option). **Default:** `3` + + * **readyTimeout** - _integer_ - How long (in milliseconds) to wait for the SSH handshake to complete. **Default:** `20000` + + * **sock** - _ReadableStream_ - A _ReadableStream_ to use for communicating with the server instead of creating and using a new TCP connection (useful for connection hopping). + + * **strictVendor** - _boolean_ - Performs a strict server vendor check before sending vendor-specific requests, etc. (e.g. check for OpenSSH server when using `openssh_noMoreSessions()`) **Default:** `true` + + * **algorithms** - _object_ - This option allows you to explicitly override the default transport layer algorithms used for the connection. Each value must be an array of valid algorithms for that category. The order of the algorithms in the arrays are important, with the most favorable being first. For a list of valid and default algorithm names, please review the documentation for the version of `ssh2-streams` used by this module. Valid keys: + + * **kex** - _array_ - Key exchange algorithms. + + * **cipher** - _array_ - Ciphers. + + * **serverHostKey** - _array_ - Server host key formats. + + * **hmac** - _array_ - (H)MAC algorithms. + + * **compress** - _array_ - Compression algorithms. + + * **compress** - _mixed_ - Set to `true` to enable compression if server supports it, `'force'` to force compression (disconnecting if server does not support it), or `false` to explicitly opt out of compression all of the time. Note: this setting is overridden when explicitly setting a compression algorithm in the `algorithms` configuration option. **Default:** (only use compression if that is only what the server supports) + + * **debug** - _function_ - Set this to a function that receives a single string argument to get detailed (local) debug information. **Default:** (none) + +**Authentication method priorities:** Password -> Private Key -> Agent (-> keyboard-interactive if `tryKeyboard` is `true`) -> Hostbased -> None + +* **exec**(< _string_ >command[, < _object_ >options], < _function_ >callback) - _boolean_ - Executes `command` on the server. Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 2 parameters: < _Error_ >err, < _Channel_ >stream. Valid `options` properties are: + + * **env** - _object_ - An environment to use for the execution of the command. + + * **pty** - _mixed_ - Set to `true` to allocate a pseudo-tty with defaults, or an object containing specific pseudo-tty settings (see 'Pseudo-TTY settings'). Setting up a pseudo-tty can be useful when working with remote processes that expect input from an actual terminal (e.g. sudo's password prompt). + + * **x11** - _mixed_ - Set to `true` to use defaults below, set to a number to specify a specific screen number, or an object with the following valid properties: + + * **single** - _boolean_ - Allow just a single connection? **Default:** `false` + + * **screen** - _number_ - Screen number to use **Default:** `0` + +* **shell**([[< _mixed_ >window,] < _object_ >options]< _function_ >callback) - _boolean_ - Starts an interactive shell session on the server, with an optional `window` object containing pseudo-tty settings (see 'Pseudo-TTY settings'). If `window === false`, then no pseudo-tty is allocated. `options` supports the `x11` option as described in exec(). `callback` has 2 parameters: < _Error_ >err, < _Channel_ >stream. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **forwardIn**(< _string_ >remoteAddr, < _integer_ >remotePort, < _function_ >callback) - _boolean_ - Bind to `remoteAddr` on `remotePort` on the server and forward incoming TCP connections. `callback` has 2 parameters: < _Error_ >err, < _integer_ >port (`port` is the assigned port number if `remotePort` was 0). Returns `false` if you should wait for the `continue` event before sending any more traffic. Here are some special values for `remoteAddr` and their associated binding behaviors: + + * '' - Connections are to be accepted on all protocol families supported by the server. + + * '0.0.0.0' - Listen on all IPv4 addresses. + + * '::' - Listen on all IPv6 addresses. + + * 'localhost' - Listen on all protocol families supported by the server on loopback addresses only. + + * '127.0.0.1' and '::1' - Listen on the loopback interfaces for IPv4 and IPv6, respectively. + +* **unforwardIn**(< _string_ >remoteAddr, < _integer_ >remotePort, < _function_ >callback) - _boolean_ - Unbind from `remoteAddr` on `remotePort` on the server and stop forwarding incoming TCP connections. Until `callback` is called, more connections may still come in. `callback` has 1 parameter: < _Error_ >err. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **forwardOut**(< _string_ >srcIP, < _integer_ >srcPort, < _string_ >dstIP, < _integer_ >dstPort, < _function_ >callback) - _boolean_ - Open a connection with `srcIP` and `srcPort` as the originating address and port and `dstIP` and `dstPort` as the remote destination address and port. `callback` has 2 parameters: < _Error_ >err, < _Channel_ >stream. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **sftp**(< _function_ >callback) - _boolean_ - Starts an SFTP session. `callback` has 2 parameters: < _Error_ >err, < _SFTPStream_ >sftp. For methods available on `sftp`, see the [`SFTPStream` client documentation](https://github.com/mscdex/ssh2-streams/blob/master/SFTPStream.md) (except `read()` and `write()` are used instead of `readData()` and `writeData()` respectively, for convenience). Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **subsys**(< _string_ >subsystem, < _function_ >callback) - _boolean_ - Invokes `subsystem` on the server. `callback` has 2 parameters: < _Error_ >err, < _Channel_ >stream. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **end**() - _(void)_ - Disconnects the socket. + +* **openssh_noMoreSessions**(< _function_ >callback) - _boolean_ - OpenSSH extension that sends a request to reject any new sessions (e.g. exec, shell, sftp, subsys) for this connection. `callback` has 1 parameter: < _Error_ >err. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **openssh_forwardInStreamLocal**(< _string_ >socketPath, < _function_ >callback) - _boolean_ - OpenSSH extension that binds to a UNIX domain socket at `socketPath` on the server and forwards incoming connections. `callback` has 1 parameter: < _Error_ >err. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **openssh_unforwardInStreamLocal**(< _string_ >socketPath, < _function_ >callback) - _boolean_ - OpenSSH extension that unbinds from a UNIX domain socket at `socketPath` on the server and stops forwarding incoming connections. `callback` has 1 parameter: < _Error_ >err. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **openssh_forwardOutStreamLocal**(< _string_ >socketPath, < _function_ >callback) - _boolean_ - OpenSSH extension that opens a connection to a UNIX domain socket at `socketPath` on the server. `callback` has 2 parameters: < _Error_ >err, < _Channel_ >stream. Returns `false` if you should wait for the `continue` event before sending any more traffic. + + +Server events +------------- + +* **connection**(< _Connection_ >client, < _object_ >info) - A new client has connected. `info` contains the following properties: + + * **ip** - _string_ - The remoteAddress of the connection. + + * **header** - _object_ - Information about the client's header: + + * **identRaw** - _string_ - The raw client identification string. + + * **versions** - _object_ - Various version information: + + * **protocol** - _string_ - The SSH protocol version (always `1.99` or `2.0`). + + * **software** - _string_ - The software name and version of the client. + + * **comments** - _string_ - Any text that comes after the software name/version. + + Example: the identification string `SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2` would be parsed as: + +```javascript + { identRaw: 'SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2', + version: { + protocol: '2.0', + software: 'OpenSSH_6.6.1p1' + }, + comments: 'Ubuntu-2ubuntu2' } +``` + +Server methods +-------------- + +* **(constructor)**(< _object_ >config[, < _function_ >connectionListener]) - Creates and returns a new Server instance. Server instances also have the same methods/properties/events as [`net.Server`](http://nodejs.org/docs/latest/api/net.html#net_class_net_server). `connectionListener` if supplied, is added as a `connection` listener. Valid `config` properties: + + * **hostKeys** - _array_ - An array of either Buffers/strings that contain host private keys or objects in the format of `{ key: , passphrase: }` for encrypted private keys. (**Required**) **Default:** (none) + + * **algorithms** - _object_ - This option allows you to explicitly override the default transport layer algorithms used for incoming client connections. Each value must be an array of valid algorithms for that category. The order of the algorithms in the arrays are important, with the most favorable being first. For a list of valid and default algorithm names, please review the documentation for the version of `ssh2-streams` used by this module. Valid keys: + + * **kex** - _array_ - Key exchange algorithms. + + * **cipher** - _array_ - Ciphers. + + * **serverHostKey** - _array_ - Server host key formats. + + * **hmac** - _array_ - (H)MAC algorithms. + + * **compress** - _array_ - Compression algorithms. + + * **greeting** - _string_ - A message that is sent to clients immediately upon connection, before handshaking begins. **Note:** Most clients usually ignore this. **Default:** (none) + + * **banner** - _string_ - A message that is sent to clients once, right before authentication begins. **Default:** (none) + + * **ident** - _string_ - A custom server software name/version identifier. **Default:** `'ssh2js' + moduleVersion + 'srv'` + + * **highWaterMark** - _integer_ - This is the `highWaterMark` to use for the parser stream. **Default:** `32 * 1024` + + * **debug** - _function_ - Set this to a function that receives a single string argument to get detailed (local) debug information. **Default:** (none) + + +Connection events +----------------- + +* **authentication**(< _AuthContext_ >ctx) - The client has requested authentication. `ctx.username` contains the client username, `ctx.method` contains the requested authentication method, and `ctx.accept()` and `ctx.reject([< Array >authMethodsLeft[, < Boolean >isPartialSuccess]])` are used to accept or reject the authentication request respectively. `abort` is emitted if the client aborts the authentication request. Other properties/methods available on `ctx` depends on the `ctx.method` of authentication the client has requested: + + * `password`: + + * **password** - _string_ - This is the password sent by the client. + + * `publickey`: + + * **key** - _object_ - Contains information about the public key sent by the client: + + * **algo** - _string_ - The name of the key algorithm (e.g. `ssh-rsa`). + + * **data** - _Buffer_ - The actual key data. + + * **sigAlgo** - _mixed_ - If the value is `undefined`, the client is only checking the validity of the `key`. If the value is a _string_, then this contains the signature algorithm that is passed to [`crypto.createVerify()`](http://nodejs.org/docs/latest/api/crypto.html#crypto_crypto_createverify_algorithm). + + * **blob** - _mixed_ - If the value is `undefined`, the client is only checking the validity of the `key`. If the value is a _Buffer_, then this contains the data that is passed to [`verifier.update()`](http://nodejs.org/docs/latest/api/crypto.html#crypto_verifier_update_data). + + * **signature** - _mixed_ - If the value is `undefined`, the client is only checking the validity of the `key`. If the value is a _Buffer_, then this contains a signature that is passed to [`verifier.verify()`](http://nodejs.org/docs/latest/api/crypto.html#crypto_verifier_verify_object_signature_signature_format). + + * `keyboard-interactive`: + + * **submethods** - _array_ - A list of preferred authentication "sub-methods" sent by the client. This may be used to determine what (if any) prompts to send to the client. + + * **prompt**(< _array_ >prompts[, < _string_ >title[, < _string_ >instructions]], < _function_ >callback) - _boolean_ - Send prompts to the client. `prompts` is an array of `{ prompt: 'Prompt text', echo: true }` objects (`prompt` being the prompt text and `echo` indicating whether the client's response to the prompt should be echoed to their display). `callback` is called with `(err, responses)`, where `responses` is an array of string responses matching up to the `prompts`. + +* **ready**() - Emitted when the client has been successfully authenticated. + +* **session**(< _function_ >accept, < _function_ >reject) - Emitted when the client has requested a new session. Sessions are used to start interactive shells, execute commands, request X11 forwarding, etc. `accept()` returns a new _Session_ instance. `reject()` Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **tcpip**(< _function_ >accept, < _function_ >reject, < _object_ >info) - Emitted when the client has requested an outbound (TCP) connection. `accept()` returns a new _Channel_ instance representing the connection. `reject()` Returns `false` if you should wait for the `continue` event before sending any more traffic. `info` contains: + + * **srcIP** - _string_ - Source IP address of outgoing connection. + + * **srcPort** - _string_ - Source port of outgoing connection. + + * **destIP** - _string_ - Destination IP address of outgoing connection. + + * **destPort** - _string_ - Destination port of outgoing connection. + +* **openssh.streamlocal**(< _function_ >accept, < _function_ >reject, < _object_ >info) - Emitted when the client has requested a connection to a UNIX domain socket. `accept()` returns a new _Channel_ instance representing the connection. `reject()` Returns `false` if you should wait for the `continue` event before sending any more traffic. `info` contains: + + * **socketPath** - _string_ - Destination socket path of outgoing connection. + +* **request**(< _mixed_ >accept, < _mixed_ >reject, < _string_ >name, < _object_ >info) - Emitted when the client has sent a global request for `name` (e.g. `tcpip-forward` or `cancel-tcpip-forward`). `accept` and `reject` are functions if the client requested a response. If `bindPort === 0`, you should pass the chosen port to `accept()` so that the client will know what port was bound. `info` contains additional details about the request: + + * `tcpip-forward` and `cancel-tcpip-forward`: + + * **bindAddr** - _string_ - The IP address to start/stop binding to. + + * **bindPort** - _integer_ - The port to start/stop binding to. + + * `streamlocal-forward@openssh.com` and `cancel-streamlocal-forward@openssh.com`: + + * **socketPath** - _string_ - The socket path to start/stop binding to. + +* **rekey**() - Emitted when the client has finished rekeying (either client or server initiated). + +* **continue**() - Emitted when more requests/data can be sent to the client (after a `Connection` method returned `false`). + +* **error**(< _Error_ >err) - An error occurred. + +* **end**() - The client socket disconnected. + +* **close**(< _boolean_ >hadError) - The client socket was closed. `hadError` is set to `true` if this was due to error. + +Connection methods +------------------ + +* **end**() - _boolean_ - Closes the client connection. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **x11**(< _string_ >originAddr, < _integer_ >originPort, < _function_ >callback) - _boolean_ - Alert the client of an incoming X11 client connection from `originAddr` on port `originPort`. `callback` has 2 parameters: < _Error_ >err, < _Channel_ >stream. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **forwardOut**(< _string_ >boundAddr, < _integer_ >boundPort, < _string_ >remoteAddr, < _integer_ >remotePort, < _function_ >callback) - _boolean_ - Alert the client of an incoming TCP connection on `boundAddr` on port `boundPort` from `remoteAddr` on port `remotePort`. `callback` has 2 parameters: < _Error_ >err, < _Channel_ >stream. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **openssh_forwardOutStreamLocal**(< _string_ >socketPath, < _function_ >callback) - _boolean_ - Alert the client of an incoming UNIX domain socket connection on `socketPath`. `callback` has 2 parameters: < _Error_ >err, < _Channel_ >stream. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **rekey**([< _function_ >callback]) - _boolean_ - Initiates a rekeying with the client. If `callback` is supplied, it is added as a one-time handler for the `rekey` event. Returns `false` if you should wait for the `continue` event before sending any more traffic. + + +Session events +-------------- + +* **pty**(< _mixed_ >accept, < _mixed_ >reject, < _object_ >info) - The client requested allocation of a pseudo-TTY for this session. `accept` and `reject` are functions if the client requested a response and return `false` if you should wait for the `continue` event before sending any more traffic. `info` has these properties: + + * **cols** - _integer_ - The number of columns for the pseudo-TTY. + + * **rows** - _integer_ - The number of rows for the pseudo-TTY. + + * **width** - _integer_ - The width of the pseudo-TTY in pixels. + + * **height** - _integer_ - The height of the pseudo-TTY in pixels. + + * **modes** - _object_ - Contains the requested terminal modes of the pseudo-TTY keyed on the mode name with the value being the mode argument. (See the table at the end for valid names). + +* **window-change**(< _mixed_ >accept, < _mixed_ >reject, < _object_ >info) - The client reported a change in window dimensions during this session. `accept` and `reject` are functions if the client requested a response and return `false` if you should wait for the `continue` event before sending any more traffic. `info` has these properties: + + * **cols** - _integer_ - The new number of columns for the client window. + + * **rows** - _integer_ - The new number of rows for the client window. + + * **width** - _integer_ - The new width of the client window in pixels. + + * **height** - _integer_ - The new height of the client window in pixels. + +* **x11**(< _mixed_ >accept, < _mixed_ >reject, < _object_ >info) - The client requested X11 forwarding. `accept` and `reject` are functions if the client requested a response and return `false` if you should wait for the `continue` event before sending any more traffic. `info` has these properties: + + * **single** - _boolean_ - `true` if only a single connection should be forwarded. + + * **protocol** - _string_ - The name of the X11 authentication method used (e.g. `MIT-MAGIC-COOKIE-1`). + + * **cookie** - _string_ - The X11 authentication cookie encoded in hexadecimal. + + * **screen** - _integer_ - The screen number to forward X11 connections for. + +* **env**(< _mixed_ >accept, < _mixed_ >reject, < _object_ >info) - The client requested an environment variable to be set for this session. `accept` and `reject` are functions if the client requested a response and return `false` if you should wait for the `continue` event before sending any more traffic. `info` has these properties: + + * **key** - _string_ - The environment variable's name. + + * **value** - _string_ - The environment variable's value. + +* **signal**(< _mixed_ >accept, < _mixed_ >reject, < _object_ >info) - The client has sent a signal. `accept` and `reject` are functions if the client requested a response and return `false` if you should wait for the `continue` event before sending any more traffic. `info` has these properties: + + * **name** - _string_ - The signal name (e.g. `SIGUSR1`). + +* **auth-agent**(< _mixed_ >accept, < _mixed_ >reject) - The client has requested incoming ssh-agent requests be forwarded to them. `accept` and `reject` are functions if the client requested a response and return `false` if you should wait for the `continue` event before sending any more traffic. + +* **shell**(< _mixed_ >accept, < _mixed_ >reject) - The client has requested an interactive shell. `accept` and `reject` are functions if the client requested a response. `accept()` returns a _Channel_ for the interactive shell. `reject()` Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* **exec**(< _mixed_ >accept, < _mixed_ >reject, < _object_ >info) - The client has requested execution of a command string. `accept` and `reject` are functions if the client requested a response. `accept()` returns a _Channel_ for the command execution. `reject()` Returns `false` if you should wait for the `continue` event before sending any more traffic. `info` has these properties: + + * **command** - _string_ - The command line to be executed. + +* **sftp**(< _mixed_ >accept, < _mixed_ >reject) - The client has requested the SFTP subsystem. `accept` and `reject` are functions if the client requested a response. `accept()` returns an _SFTPStream_ in server mode (see the [`SFTPStream` documentation](https://github.com/mscdex/ssh2-streams/blob/master/SFTPStream.md) for details). `reject()` Returns `false` if you should wait for the `continue` event before sending any more traffic. `info` has these properties: + +* **subsystem**(< _mixed_ >accept, < _mixed_ >reject, < _object_ >info) - The client has requested an arbitrary subsystem. `accept` and `reject` are functions if the client requested a response. `accept()` returns a _Channel_ for the subsystem. `reject()` Returns `false` if you should wait for the `continue` event before sending any more traffic. `info` has these properties: + + * **name** - _string_ - The name of the subsystem. + +* **close**() - The session was closed. + + +Channel +------- + +This is a normal **streams2** Duplex Stream, with the following changes: + +* A boolean property `allowHalfOpen` exists and behaves similarly to the property of the same name for `net.Socket`. When the stream's end() is called, if `allowHalfOpen` is `true`, only EOF will be sent (the server can still send data if they have not already sent EOF). The default value for this property is `true`. + +* A `close` event is emitted once the channel is completely closed on both the client and server. + +* Client-only: + + + * For exec(): + + * An `exit` event *may* (the SSH2 spec says it is optional) be emitted when the process finishes. If the process finished normally, the process's return value is passed to the `exit` callback. If the process was interrupted by a signal, the following are passed to the `exit` callback: null, < _string_ >signalName, < _boolean_ >didCoreDump, < _string_ >description. + + * If there was an `exit` event, the `close` event will be passed the same arguments for convenience. + + * For shell() and exec(): + + * The readable side represents stdout and the writable side represents stdin. + + * A `stderr` property contains a Readable stream that represents output from stderr. + + * **signal**(< _string_ >signalName) - _boolean_ - Sends a POSIX signal to the current process on the server. Valid signal names are: 'ABRT', 'ALRM', 'FPE', 'HUP', 'ILL', 'INT', 'KILL', 'PIPE', 'QUIT', 'SEGV', 'TERM', 'USR1', and 'USR2'. Some server implementations may ignore this request if they do not support signals. Note: If you are trying to send SIGINT and you find `signal()` doesn't work, try writing `'\x03'` to the Channel stream instead. Returns `false` if you should wait for the `continue` event before sending any more traffic. + + * **setWindow**(< _integer_ >rows, < _integer_ >cols, < _integer_ >height, < _integer_ >width) - _boolean_ - Lets the server know that the local terminal window has been resized. The meaning of these arguments are described in the 'Pseudo-TTY settings' section. Returns `false` if you should wait for the `continue` event before sending any more traffic. + +* Server-only: + + * For exec-enabled channel instances there is an additional method available that may be called right before you close the channel. It has two different signatures: + + * **exit**(< _integer_ >exitCode) - _boolean_ - Sends an exit status code to the client. Returns `false` if you should wait for the `continue` event before sending any more traffic. + + * **exit**(< _string_ >signalName[, < _boolean_ >coreDumped[, < _string_ >errorMsg]]) - _boolean_ - Sends an exit status code to the client. Returns `false` if you should wait for the `continue` event before sending any more traffic. + + * For exec and shell-enabled channel instances, `channel.stderr` is a writable stream. + + +Pseudo-TTY settings +------------------- + +* **rows** - < _integer_ > - Number of rows **Default:** `24` + +* **cols** - < _integer_ > - Number of columns **Default:** `80` + +* **height** - < _integer_ > - Height in pixels **Default:** `480` + +* **width** - < _integer_ > - Width in pixels **Default:** `640` + +* **term** - < _string_ > - The value to use for $TERM **Default:** `'vt100'` + +`rows` and `cols` override `width` and `height` when `rows` and `cols` are non-zero. + +Pixel dimensions refer to the drawable area of the window. + +Zero dimension parameters are ignored. + + +Terminal modes +-------------- + +
          +Name           Description
          +------------------------------------------------------------
          +VINTR          Interrupt character; 255 if none.  Similarly
          +               for the other characters.  Not all of these
          +               characters are supported on all systems.
          +VQUIT          The quit character (sends SIGQUIT signal on
          +               POSIX systems).
          +VERASE         Erase the character to left of the cursor.
          +VKILL          Kill the current input line.
          +VEOF           End-of-file character (sends EOF from the
          +               terminal).
          +VEOL           End-of-line character in addition to
          +               carriage return and/or linefeed.
          +VEOL2          Additional end-of-line character.
          +VSTART         Continues paused output (normally
          +               control-Q).
          +VSTOP          Pauses output (normally control-S).
          +VSUSP          Suspends the current program.
          +VDSUSP         Another suspend character.
          +VREPRINT       Reprints the current input line.
          +VWERASE        Erases a word left of cursor.
          +VLNEXT         Enter the next character typed literally,
          +               even if it is a special character
          +VFLUSH         Character to flush output.
          +VSWTCH         Switch to a different shell layer.
          +VSTATUS        Prints system status line (load, command,
          +               pid, etc).
          +VDISCARD       Toggles the flushing of terminal output.
          +IGNPAR         The ignore parity flag.  The parameter
          +               SHOULD be 0 if this flag is FALSE,
          +               and 1 if it is TRUE.
          +PARMRK         Mark parity and framing errors.
          +INPCK          Enable checking of parity errors.
          +ISTRIP         Strip 8th bit off characters.
          +INLCR          Map NL into CR on input.
          +IGNCR          Ignore CR on input.
          +ICRNL          Map CR to NL on input.
          +IUCLC          Translate uppercase characters to
          +               lowercase.
          +IXON           Enable output flow control.
          +IXANY          Any char will restart after stop.
          +IXOFF          Enable input flow control.
          +IMAXBEL        Ring bell on input queue full.
          +ISIG           Enable signals INTR, QUIT, [D]SUSP.
          +ICANON         Canonicalize input lines.
          +XCASE          Enable input and output of uppercase
          +               characters by preceding their lowercase
          +               equivalents with "\".
          +ECHO           Enable echoing.
          +ECHOE          Visually erase chars.
          +ECHOK          Kill character discards current line.
          +ECHONL         Echo NL even if ECHO is off.
          +NOFLSH         Don't flush after interrupt.
          +TOSTOP         Stop background jobs from output.
          +IEXTEN         Enable extensions.
          +ECHOCTL        Echo control characters as ^(Char).
          +ECHOKE         Visual erase for line kill.
          +PENDIN         Retype pending input.
          +OPOST          Enable output processing.
          +OLCUC          Convert lowercase to uppercase.
          +ONLCR          Map NL to CR-NL.
          +OCRNL          Translate carriage return to newline
          +               (output).
          +ONOCR          Translate newline to carriage
          +               return-newline (output).
          +ONLRET         Newline performs a carriage return
          +               (output).
          +CS7            7 bit mode.
          +CS8            8 bit mode.
          +PARENB         Parity enable.
          +PARODD         Odd parity, else even.
          +TTY_OP_ISPEED  Specifies the input baud rate in
          +               bits per second.
          +TTY_OP_OSPEED  Specifies the output baud rate in
          +               bits per second.
          +
          diff --git a/node_modules/ssh2/examples/server-chat.js b/node_modules/ssh2/examples/server-chat.js new file mode 100644 index 0000000..18e5108 --- /dev/null +++ b/node_modules/ssh2/examples/server-chat.js @@ -0,0 +1,243 @@ +// **BEFORE RUNNING THIS SCRIPT:** +// 1. The server portion is best run on non-Windows systems because they have +// terminfo databases which are needed to properly work with different +// terminal types of client connections +// 2. Install `blessed`: `npm install blessed` +// 3. Create a server host key in this same directory and name it `host.key` + +var fs = require('fs'); + +var blessed = require('blessed'); +var Server = require('ssh2').Server; + +var RE_SPECIAL = /[\x00-\x1F\x7F]+|(?:\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K])/g; +var MAX_MSG_LEN = 128; +var MAX_NAME_LEN = 10; +var PROMPT_NAME = 'Enter a nickname to use (max ' + MAX_NAME_LEN + ' chars): '; + +var users = []; + +function formatMessage(msg, output) { + var output = output; + output.parseTags = true; + msg = output._parseTags(msg); + output.parseTags = false; + return msg; +} + +function userBroadcast(msg, source) { + var sourceMsg = '> ' + msg; + var name = '{cyan-fg}{bold}' + source.name + '{/}'; + msg = ': ' + msg; + for (var i = 0; i < users.length; ++i) { + var user = users[i]; + var output = user.output; + if (source === user) + output.add(sourceMsg); + else + output.add(formatMessage(name, output) + msg); + } +} + +function localMessage(msg, source) { + var output = source.output; + output.add(formatMessage(msg, output)); +} + +function noop(v) {} + +new Server({ + hostKeys: [fs.readFileSync('host.key')], +}, function(client) { + var stream; + var name; + + client.on('authentication', function(ctx) { + var nick = ctx.username; + var prompt = PROMPT_NAME; + var lowered; + // Try to use username as nickname + if (nick.length > 0 && nick.length <= MAX_NAME_LEN) { + lowered = nick.toLowerCase(); + var ok = true; + for (var i = 0; i < users.length; ++i) { + if (users[i].name.toLowerCase() === lowered) { + ok = false; + prompt = 'That nickname is already in use.\n' + PROMPT_NAME; + break; + } + } + if (ok) { + name = nick; + return ctx.accept(); + } + } else if (nick.length === 0) + prompt = 'A nickname is required.\n' + PROMPT_NAME; + else + prompt = 'That nickname is too long.\n' + PROMPT_NAME; + + if (ctx.method !== 'keyboard-interactive') + return ctx.reject(['keyboard-interactive']); + + ctx.prompt(prompt, function retryPrompt(answers) { + if (answers.length === 0) + return ctx.reject(['keyboard-interactive']); + nick = answers[0]; + if (nick.length > MAX_NAME_LEN) { + return ctx.prompt('That nickname is too long.\n' + PROMPT_NAME, + retryPrompt); + } else if (nick.length === 0) { + return ctx.prompt('A nickname is required.\n' + PROMPT_NAME, + retryPrompt); + } + lowered = nick.toLowerCase(); + for (var i = 0; i < users.length; ++i) { + if (users[i].name.toLowerCase() === lowered) { + return ctx.prompt('That nickname is already in use.\n' + PROMPT_NAME, + retryPrompt); + } + } + name = nick; + ctx.accept(); + }); + }).on('ready', function() { + var rows; + var cols; + var term; + client.once('session', function(accept, reject) { + accept().once('pty', function(accept, reject, info) { + rows = info.rows; + cols = info.cols; + term = info.term; + accept && accept(); + }).on('window-change', function(accept, reject, info) { + rows = info.rows; + cols = info.cols; + if (stream) { + stream.rows = rows; + stream.columns = cols; + stream.emit('resize'); + } + accept && accept(); + }).once('shell', function(accept, reject) { + stream = accept(); + users.push(stream); + + stream.name = name; + stream.rows = rows || 24; + stream.columns = cols || 80; + stream.isTTY = true; + stream.setRawMode = noop; + stream.on('error', noop); + + var screen = new blessed.screen({ + autoPadding: true, + smartCSR: true, + program: new blessed.program({ + input: stream, + output: stream + }), + terminal: term || 'ansi' + }); + + screen.title = 'SSH Chatting as ' + name; + // Disable local echo + screen.program.attr('invisible', true); + + var output = stream.output = new blessed.log({ + screen: screen, + top: 0, + left: 0, + width: '100%', + bottom: 2, + scrollOnInput: true + }) + screen.append(output); + + screen.append(new blessed.box({ + screen: screen, + height: 1, + bottom: 1, + left: 0, + width: '100%', + type: 'line', + ch: '=' + })); + + var input = new blessed.textbox({ + screen: screen, + bottom: 0, + height: 1, + width: '100%', + inputOnFocus: true + }); + screen.append(input); + + input.focus(); + + // Local greetings + localMessage('{blue-bg}{white-fg}{bold}Welcome to SSH Chat!{/}\n' + + 'There are {bold}' + + (users.length - 1) + + '{/} other user(s) connected.\n' + + 'Type /quit or /exit to exit the chat.', + stream); + + // Let everyone else know that this user just joined + for (var i = 0; i < users.length; ++i) { + var user = users[i]; + var output = user.output; + if (user === stream) + continue; + output.add(formatMessage('{green-fg}*** {bold}', output) + + name + + formatMessage('{/bold} has joined the chat{/}', output)); + } + + screen.render(); + // XXX This fake resize event is needed for some terminals in order to + // have everything display correctly + screen.program.emit('resize'); + + // Read a line of input from the user + input.on('submit', function(line) { + input.clearValue(); + screen.render(); + if (!input.focused) + input.focus(); + line = line.replace(RE_SPECIAL, '').trim(); + if (line.length > MAX_MSG_LEN) + line = line.substring(0, MAX_MSG_LEN); + if (line.length > 0) { + if (line === '/quit' || line === '/exit') + stream.end(); + else + userBroadcast(line, stream); + } + }); + }); + }); + }).on('end', function() { + if (stream !== undefined) { + spliceOne(users, users.indexOf(stream)); + // Let everyone else know that this user just left + for (var i = 0; i < users.length; ++i) { + var user = users[i]; + var output = user.output; + output.add(formatMessage('{magenta-fg}*** {bold}', output) + + name + + formatMessage('{/bold} has left the chat{/}', output)); + } + } + }).on('error', function(err) { + // Ignore errors + }); +}).listen(0, function() { + console.log('Listening on port ' + this.address().port); +}); + +function spliceOne(list, index) { + for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) + list[i] = list[k]; + list.pop(); +} diff --git a/node_modules/ssh2/examples/sftp-server-download-only.js b/node_modules/ssh2/examples/sftp-server-download-only.js new file mode 100644 index 0000000..8ea5a5a --- /dev/null +++ b/node_modules/ssh2/examples/sftp-server-download-only.js @@ -0,0 +1,96 @@ +var constants = require('constants'); +var fs = require('fs'); + +var ssh2 = require('ssh2'); +var OPEN_MODE = ssh2.SFTP_OPEN_MODE; +var STATUS_CODE = ssh2.SFTP_STATUS_CODE; + +new ssh2.Server({ + hostKeys: [fs.readFileSync('host.key')] +}, function(client) { + console.log('Client connected!'); + + client.on('authentication', function(ctx) { + if (ctx.method === 'password' + && ctx.username === 'foo' + && ctx.password === 'bar') + ctx.accept(); + else + ctx.reject(['password']); + }).on('ready', function() { + console.log('Client authenticated!'); + + client.on('session', function(accept, reject) { + var session = accept(); + session.on('sftp', function(accept, reject) { + console.log('Client SFTP session'); + var openFiles = {}; + var handleCount = 0; + // `sftpStream` is an `SFTPStream` instance in server mode + // see: https://github.com/mscdex/ssh2-streams/blob/master/SFTPStream.md + var sftpStream = accept(); + sftpStream.on('OPEN', function(reqid, filename, flags, attrs) { + console.log('OPEN', filename); + // only allow opening /tmp/foo.txt for writing + if (filename !== '/tmp/foo.txt' || !(flags & OPEN_MODE.READ)) + return sftpStream.status(reqid, STATUS_CODE.FAILURE); + // create a fake handle to return to the client, this could easily + // be a real file descriptor number for example if actually opening + // the file on the disk + var handle = new Buffer(4); + openFiles[handleCount] = { read: false }; + handle.writeUInt32BE(handleCount++, 0, true); + sftpStream.handle(reqid, handle); + console.log('Opening file for read') + }).on('READ', function(reqid, handle, offset, length) { + if (handle.length !== 4 || !openFiles[handle.readUInt32BE(0, true)]) + return sftpStream.status(reqid, STATUS_CODE.FAILURE); + // fake the read + var state = openFiles[handle.readUInt32BE(0, true)]; + if (state.read) + sftpStream.status(reqid, STATUS_CODE.EOF); + else { + state.read = true; + sftpStream.data(reqid, 'bar'); + console.log('Read from file at offset %d, length %d', offset, length); + } + }).on('CLOSE', function(reqid, handle) { + var fnum; + if (handle.length !== 4 || !openFiles[(fnum = handle.readUInt32BE(0, true))]) + return sftpStream.status(reqid, STATUS_CODE.FAILURE); + delete openFiles[fnum]; + sftpStream.status(reqid, STATUS_CODE.OK); + console.log('Closing file'); + }).on('REALPATH', function(reqid, path) { + var name = [{ + filename: '/tmp/foo.txt', + longname: '-rwxrwxrwx 1 foo foo 3 Dec 8 2009 foo.txt', + attrs: {} + }]; + sftpStream.name(reqid, name); + }).on('STAT', onSTAT) + .on('LSTAT', onSTAT); + function onSTAT(reqid, path) { + if (path !== '/tmp/foo.txt') + return sftpStream.status(reqid, STATUS_CODE.FAILURE); + var mode = constants.S_IFREG; // Regular file + mode |= constants.S_IRWXU; // read, write, execute for user + mode |= constants.S_IRWXG; // read, write, execute for group + mode |= constants.S_IRWXO; // read, write, execute for other + sftpStream.attrs(reqid, { + mode: mode, + uid: 0, + gid: 0, + size: 3, + atime: Date.now(), + mtime: Date.now() + }); + } + }); + }); + }).on('end', function() { + console.log('Client disconnected'); + }); +}).listen(0, '127.0.0.1', function() { + console.log('Listening on port ' + this.address().port); +}); diff --git a/node_modules/ssh2/lib/Channel.js b/node_modules/ssh2/lib/Channel.js new file mode 100644 index 0000000..1d8372d --- /dev/null +++ b/node_modules/ssh2/lib/Channel.js @@ -0,0 +1,506 @@ +var inherits = require('util').inherits; +var DuplexStream = require('stream').Duplex; +var ReadableStream = require('stream').Readable; +var WritableStream = require('stream').Writable; + +var STDERR = require('ssh2-streams').constants.CHANNEL_EXTENDED_DATATYPE.STDERR; + +var PACKET_SIZE = 32 * 1024; +var MAX_WINDOW = 1 * 1024 * 1024; +var WINDOW_THRESHOLD = MAX_WINDOW / 2; +var CUSTOM_EVENTS = [ + 'CHANNEL_EOF', + 'CHANNEL_CLOSE', + 'CHANNEL_DATA', + 'CHANNEL_EXTENDED_DATA', + 'CHANNEL_WINDOW_ADJUST', + 'CHANNEL_SUCCESS', + 'CHANNEL_FAILURE', + 'CHANNEL_REQUEST' +]; +var CUSTOM_EVENTS_LEN = CUSTOM_EVENTS.length; + +function Channel(info, client, opts) { + var streamOpts = { + highWaterMark: MAX_WINDOW, + allowHalfOpen: (!opts || (opts && opts.allowHalfOpen !== false)) + }; + + this.allowHalfOpen = streamOpts.allowHalfOpen; + + DuplexStream.call(this, streamOpts); + + var self = this; + var server = opts && opts.server; + + this.server = server; + this.type = info.type; + this.subtype = undefined; + /* + incoming and outgoing contain these properties: + { + id: undefined, + window: undefined, + packetSize: undefined, + state: 'closed' + } + */ + var incoming = this.incoming = info.incoming; + var incomingId = incoming.id; + var outgoing = this.outgoing = info.outgoing; + var callbacks = this._callbacks = []; + var exitCode; + var exitSignal; + var exitDump; + var exitDesc; + var exitLang; + + this._client = client; + this._hasX11 = false; + + var channels = client._channels; + var sshstream = client._sshstream; + + function ondrain() { + if (self._waitClientDrain) { + self._waitClientDrain = false; + if (!self._waitWindow) { + if (self._chunk) + self._write(self._chunk, null, self._chunkcb); + else if (self._chunkcb) + self._chunkcb(); + else if (self._chunkErr) + self.stderr._write(self._chunkErr, null, self._chunkcbErr); + else if (self._chunkcbErr) + self._chunkcbErr(); + } + } + } + client._sock.on('drain', ondrain); + + sshstream.once('CHANNEL_EOF:' + incomingId, function() { + if (incoming.state === 'closed' || incoming.state === 'eof') + return; + incoming.state = 'eof'; + + if (self.readable) + self.push(null); + if (!server && self.stderr.readable) + self.stderr.push(null); + }).once('CHANNEL_CLOSE:' + incomingId, function() { + if (incoming.state === 'closed') + return; + incoming.state = 'closed'; + + if (self.readable) + self.push(null); + if (server && self.stderr.writable) + self.stderr.end(); + else if (!server && self.stderr.readable) + self.stderr.push(null); + + if (outgoing.state === 'open' || outgoing.state === 'eof') + self.close(); + if (outgoing.state === 'closing') + outgoing.state = 'closed'; + + delete channels[incomingId]; + + var state = self._writableState; + client._sock.removeListener('drain', ondrain); + if (!state.ending && !state.finished) + self.end(); + + // Take care of any outstanding channel requests + self._callbacks = []; + for (var i = 0; i < callbacks.length; ++i) + callbacks[i](true); + callbacks = self._callbacks; + + if (!server) { + // align more with node child processes, where the close event gets the + // same arguments as the exit event + if (!self.readable) { + if (exitCode === null) { + self.emit('close', exitCode, exitSignal, exitDump, exitDesc, + exitLang); + } else + self.emit('close', exitCode); + } else { + self.once('end', function() { + if (exitCode === null) { + self.emit('close', exitCode, exitSignal, exitDump, exitDesc, + exitLang); + } else + self.emit('close', exitCode); + }); + } + + if (!self.stderr.readable) + self.stderr.emit('close'); + else { + self.stderr.once('end', function() { + self.stderr.emit('close'); + }); + } + } else { // Server mode + if (!self.readable) + self.emit('close'); + else { + self.once('end', function() { + self.emit('close'); + }); + } + } + + for (var i = 0; i < CUSTOM_EVENTS_LEN; ++i) + sshstream.removeAllListeners(CUSTOM_EVENTS[i] + ':' + incomingId); + }).on('CHANNEL_DATA:' + incomingId, function(data) { + // the remote party should not be sending us data if there is no window + // space available ... + if (incoming.window === 0) + return; + + incoming.window -= data.length; + + if (!self.push(data)) { + self._waitChanDrain = true; + return; + } + + if (incoming.window <= WINDOW_THRESHOLD) + windowAdjust(self); + }).on('CHANNEL_WINDOW_ADJUST:' + incomingId, function(amt) { + // the server is allowing us to send `amt` more bytes of data + outgoing.window += amt; + + if (self._waitWindow) { + self._waitWindow = false; + if (!self._waitClientDrain) { + if (self._chunk) + self._write(self._chunk, null, self._chunkcb); + else if (self._chunkcb) + self._chunkcb(); + else if (self._chunkErr) + self.stderr._write(self._chunkErr, null, self._chunkcbErr); + else if (self._chunkcbErr) + self._chunkcbErr(); + } + } + }).on('CHANNEL_SUCCESS:' + incomingId, function() { + if (server) { + sshstream._kalast = Date.now(); + sshstream._kacnt = 0; + } else + client._resetKA(); + if (callbacks.length) + callbacks.shift()(false); + }).on('CHANNEL_FAILURE:' + incomingId, function() { + if (server) { + sshstream._kalast = Date.now(); + sshstream._kacnt = 0; + } else + client._resetKA(); + if (callbacks.length) + callbacks.shift()(true); + }).on('CHANNEL_REQUEST:' + incomingId, function(info) { + if (!server) { + if (info.request === 'exit-status') { + self.emit('exit', exitCode = info.code); + return; + } else if (info.request === 'exit-signal') { + self.emit('exit', + exitCode = null, + exitSignal = 'SIG' + info.signal, + exitDump = info.coredump, + exitDesc = info.description, + exitLang = info.lang); + return; + } + } + + // keepalive request? OpenSSH will send one as a channel request if there + // is a channel open + + if (info.wantReply) + sshstream.channelFailure(outgoing.id); + }); + + this.stdin = this.stdout = this; + + if (server) + this.stderr = new ServerStderr(this); + else { + this.stderr = new ReadableStream(streamOpts); + this.stderr._read = function(n) { + if (self._waitChanDrain) { + self._waitChanDrain = false; + if (incoming.window <= WINDOW_THRESHOLD) + windowAdjust(self); + } + }; + + sshstream.on('CHANNEL_EXTENDED_DATA:' + incomingId, + function(type, data) { + // the remote party should not be sending us data if there is no window + // space available ... + if (incoming.window === 0) + return; + + incoming.window -= data.length; + + if (!self.stderr.push(data)) { + self._waitChanDrain = true; + return; + } + + if (incoming.window <= WINDOW_THRESHOLD) + windowAdjust(self); + } + ); + } + + // outgoing data + this._waitClientDrain = false; // Client stream-level backpressure + this._waitWindow = false; // SSH-level backpressure + + // incoming data + this._waitChanDrain = false; // Channel Readable side backpressure + + this._chunk = undefined; + this._chunkcb = undefined; + this._chunkErr = undefined; + this._chunkcbErr = undefined; + + function onFinish() { + self.eof(); + if (server || (!server && !self.allowHalfOpen)) + self.close(); + self.writable = false; + } + this.on('finish', onFinish) + .on('prefinish', onFinish); // for node v0.11+ + function onEnd() { + self.readable = false; + } + this.on('end', onEnd) + .on('close', onEnd); +} +inherits(Channel, DuplexStream); + +Channel.prototype.eof = function() { + var ret = true; + var outgoing = this.outgoing; + + if (outgoing.state === 'open') { + outgoing.state = 'eof'; + ret = this._client._sshstream.channelEOF(outgoing.id); + } + + return ret; +}; + +Channel.prototype.close = function() { + var ret = true; + var outgoing = this.outgoing; + + if (outgoing.state === 'open' || outgoing.state === 'eof') { + outgoing.state = 'closing'; + ret = this._client._sshstream.channelClose(outgoing.id); + } + + return ret; +}; + +Channel.prototype._read = function(n) { + if (this._waitChanDrain) { + this._waitChanDrain = false; + if (this.incoming.window <= WINDOW_THRESHOLD) + windowAdjust(this); + } +}; + +Channel.prototype._write = function(data, encoding, cb) { + var sshstream = this._client._sshstream; + var outgoing = this.outgoing; + var packetSize = outgoing.packetSize; + var id = outgoing.id; + var window = outgoing.window; + var len = data.length; + var p = 0; + var ret; + var buf; + var sliceLen; + + if (outgoing.state !== 'open') + return; + + while (len - p > 0 && window > 0) { + sliceLen = len - p; + if (sliceLen > window) + sliceLen = window; + if (sliceLen > packetSize) + sliceLen = packetSize; + + ret = sshstream.channelData(id, data.slice(p, p + sliceLen)); + + p += sliceLen; + window -= sliceLen; + + if (!ret) { + this._waitClientDrain = true; + this._chunk = undefined; + this._chunkcb = cb; + break; + } + } + + outgoing.window = window; + + if (len - p > 0) { + if (window === 0) + this._waitWindow = true; + if (p > 0) { + // partial + buf = new Buffer(len - p); + data.copy(buf, 0, p); + this._chunk = buf; + } else + this._chunk = data; + this._chunkcb = cb; + return; + } + + if (!this._waitClientDrain) + cb(); +}; + +Channel.prototype.destroy = function() { + this.end(); +}; + +// session type-specific methods +Channel.prototype.setWindow = function(rows, cols, height, width) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + if (this.type === 'session' + && (this.subtype === 'shell' || this.subtype === 'exec') + && this.writable + && this.outgoing.state === 'open') { + return this._client._sshstream.windowChange(this.outgoing.id, + rows, + cols, + height, + width); + } + + return true; +}; +Channel.prototype.signal = function(signalName) { + if (this.server) + throw new Error('Client-only method called in server mode'); + + if (this.type === 'session' + && this.writable + && this.outgoing.state === 'open') + return this._client._sshstream.signal(this.outgoing.id, signalName); + + return true; +}; +Channel.prototype.exit = function(name, coreDumped, msg) { + if (!this.server) + throw new Error('Server-only method called in client mode'); + + if (this.type === 'session' + && this.writable + && this.outgoing.state === 'open') { + if (typeof name === 'number') + return this._client._sshstream.exitStatus(this.outgoing.id, name); + else { + return this._client._sshstream.exitSignal(this.outgoing.id, + name, + coreDumped, + msg); + } + } + + return true; +}; + +Channel.MAX_WINDOW = MAX_WINDOW; +Channel.PACKET_SIZE = PACKET_SIZE; + +function windowAdjust(self) { + if (self.outgoing.state !== 'open') + return true; + var amt = MAX_WINDOW - self.incoming.window; + if (amt <= 0) + return true; + self.incoming.window += amt; + return self._client._sshstream.channelWindowAdjust(self.outgoing.id, amt); +} + +function ServerStderr(channel) { + WritableStream.call(this, { highWaterMark: MAX_WINDOW }); + this._channel = channel; +} +inherits(ServerStderr, WritableStream); + +ServerStderr.prototype._write = function(data, encoding, cb) { + var channel = this._channel; + var sshstream = channel._client._sshstream; + var outgoing = channel.outgoing; + var packetSize = outgoing.packetSize; + var id = outgoing.id; + var window = outgoing.window; + var len = data.length; + var p = 0; + var ret; + var buf; + var sliceLen; + + if (channel.outgoing.state !== 'open') + return; + + while (len - p > 0 && window > 0) { + sliceLen = len - p; + if (sliceLen > window) + sliceLen = window; + if (sliceLen > packetSize) + sliceLen = packetSize; + + ret = sshstream.channelExtData(id, data.slice(p, p + sliceLen), STDERR); + + p += sliceLen; + window -= sliceLen; + + if (!ret) { + channel._waitClientDrain = true; + channel._chunkErr = undefined; + channel._chunkcbErr = cb; + break; + } + } + + outgoing.window = window; + + if (len - p > 0) { + if (window === 0) + channel._waitWindow = true; + if (p > 0) { + // partial + buf = new Buffer(len - p); + data.copy(buf, 0, p); + channel._chunkErr = buf; + } else + channel._chunkErr = data; + channel._chunkcbErr = cb; + return; + } + + if (!channel._waitClientDrain) + cb(); +}; + +module.exports = Channel; diff --git a/node_modules/ssh2/lib/SFTPWrapper.js b/node_modules/ssh2/lib/SFTPWrapper.js new file mode 100644 index 0000000..a04a948 --- /dev/null +++ b/node_modules/ssh2/lib/SFTPWrapper.js @@ -0,0 +1,145 @@ +// This wrapper class is used to retain backwards compatibility with +// pre-v0.4 ssh2. If it weren't for `read()` and `write()` being used by the +// streams2/3 API, we could just pass the SFTPStream directly to the end user... + +var inherits = require('util').inherits, + EventEmitter = require('events').EventEmitter; + +function SFTPWrapper(stream) { + var self = this; + + EventEmitter.call(this); + + this._stream = stream; + + stream.on('error', function(err) { + self.emit('error', err); + }).on('end', function() { + self.emit('end'); + }).on('close', function() { + self.emit('close'); + }).on('continue', function() { + self.emit('continue'); + }); +} +inherits(SFTPWrapper, EventEmitter); + +// stream-related methods to pass on +SFTPWrapper.prototype.end = function() { + return this._stream.end(); +}; +// SFTPStream client methods +SFTPWrapper.prototype.createReadStream = function(path, options) { + return this._stream.createReadStream(path, options); +}; +SFTPWrapper.prototype.createWriteStream = function(path, options) { + return this._stream.createWriteStream(path, options); +}; +SFTPWrapper.prototype.open = function(path, flags, attrs, cb) { + return this._stream.open(path, flags, attrs, cb); +}; +SFTPWrapper.prototype.close = function(handle, cb) { + return this._stream.close(handle, cb); +}; +SFTPWrapper.prototype.read = function(handle, buf, off, len, position, cb) { + return this._stream.readData(handle, buf, off, len, position, cb); +}; +SFTPWrapper.prototype.write = function(handle, buf, off, len, position, cb) { + return this._stream.writeData(handle, buf, off, len, position, cb); +}; +SFTPWrapper.prototype.fastGet = function(remotePath, localPath, opts, cb) { + return this._stream.fastGet(remotePath, localPath, opts, cb); +}; +SFTPWrapper.prototype.fastPut = function(localPath, remotePath, opts, cb) { + return this._stream.fastPut(localPath, remotePath, opts, cb); +}; +SFTPWrapper.prototype.readFile = function(path, options, callback_) { + return this._stream.readFile(path, options, callback_); +}; +SFTPWrapper.prototype.writeFile = function(path, data, options, callback_) { + return this._stream.writeFile(path, data, options, callback_); +}; +SFTPWrapper.prototype.appendFile = function(path, data, options, callback_) { + return this._stream.appendFile(path, data, options, callback_); +}; +SFTPWrapper.prototype.exists = function(path, cb) { + return this._stream.exists(path, cb); +}; +SFTPWrapper.prototype.unlink = function(filename, cb) { + return this._stream.unlink(filename, cb); +}; +SFTPWrapper.prototype.rename = function(oldPath, newPath, cb) { + return this._stream.rename(oldPath, newPath, cb); +}; +SFTPWrapper.prototype.mkdir = function(path, attrs, cb) { + return this._stream.mkdir(path, attrs, cb); +}; +SFTPWrapper.prototype.rmdir = function(path, cb) { + return this._stream.rmdir(path, cb); +}; +SFTPWrapper.prototype.readdir = function(where, opts, cb) { + return this._stream.readdir(where, opts, cb); +}; +SFTPWrapper.prototype.fstat = function(handle, cb) { + return this._stream.fstat(handle, cb); +}; +SFTPWrapper.prototype.stat = function(path, cb) { + return this._stream.stat(path, cb); +}; +SFTPWrapper.prototype.lstat = function(path, cb) { + return this._stream.lstat(path, cb); +}; +SFTPWrapper.prototype.opendir = function(path, cb) { + return this._stream.opendir(path, cb); +}; +SFTPWrapper.prototype.setstat = function(path, attrs, cb) { + return this._stream.setstat(path, attrs, cb); +}; +SFTPWrapper.prototype.fsetstat = function(handle, attrs, cb) { + return this._stream.fsetstat(handle, attrs, cb); +}; +SFTPWrapper.prototype.futimes = function(handle, atime, mtime, cb) { + return this._stream.futimes(handle, atime, mtime, cb); +}; +SFTPWrapper.prototype.utimes = function(path, atime, mtime, cb) { + return this._stream.utimes(path, atime, mtime, cb); +}; +SFTPWrapper.prototype.fchown = function(handle, uid, gid, cb) { + return this._stream.fchown(handle, uid, gid, cb); +}; +SFTPWrapper.prototype.chown = function(path, uid, gid, cb) { + return this._stream.chown(path, uid, gid, cb); +}; +SFTPWrapper.prototype.fchmod = function(handle, mode, cb) { + return this._stream.fchmod(handle, mode, cb); +}; +SFTPWrapper.prototype.chmod = function(path, mode, cb) { + return this._stream.chmod(path, mode, cb); +}; +SFTPWrapper.prototype.readlink = function(path, cb) { + return this._stream.readlink(path, cb); +}; +SFTPWrapper.prototype.symlink = function(targetPath, linkPath, cb) { + return this._stream.symlink(targetPath, linkPath, cb); +}; +SFTPWrapper.prototype.realpath = function(path, cb) { + return this._stream.realpath(path, cb); +}; +// extended requests +SFTPWrapper.prototype.ext_openssh_rename = function(oldPath, newPath, cb) { + return this._stream.ext_openssh_rename(oldPath, newPath, cb); +}; +SFTPWrapper.prototype.ext_openssh_statvfs = function(path, cb) { + return this._stream.ext_openssh_statvfs(path, cb); +}; +SFTPWrapper.prototype.ext_openssh_fstatvfs = function(handle, cb) { + return this._stream.ext_openssh_fstatvfs(handle, cb); +}; +SFTPWrapper.prototype.ext_openssh_hardlink = function(oldPath, newPath, cb) { + return this._stream.ext_openssh_hardlink(oldPath, newPath, cb); +}; +SFTPWrapper.prototype.ext_openssh_fsync = function(handle, cb) { + return this._stream.ext_openssh_fsync(handle, cb); +}; + +module.exports = SFTPWrapper; diff --git a/node_modules/ssh2/lib/agent.js b/node_modules/ssh2/lib/agent.js new file mode 100644 index 0000000..56985f0 --- /dev/null +++ b/node_modules/ssh2/lib/agent.js @@ -0,0 +1,412 @@ +var Socket = require('net').Socket; +var EventEmitter = require('events').EventEmitter; +var inherits = require('util').inherits; +var path = require('path'); +var fs = require('fs'); +var cp = require('child_process'); + +var REQUEST_IDENTITIES = 11; +var IDENTITIES_ANSWER = 12; +var SIGN_REQUEST = 13; +var SIGN_RESPONSE = 14; +var FAILURE = 5; + +var RE_CYGWIN_SOCK = /^\!(\d+) s ([A-Z0-9]{8}\-[A-Z0-9]{8}\-[A-Z0-9]{8}\-[A-Z0-9]{8})/; + +module.exports = function(sockPath, key, keyType, data, cb) { + var sock; + var error; + var sig; + var datalen; + var keylen = 0; + var isSigning = Buffer.isBuffer(key); + var type; + var count = 0; + var siglen = 0; + var nkeys = 0; + var keys; + var comlen = 0; + var comment = false; + var accept; + var reject; + + if (typeof key === 'function' && typeof keyType === 'function') { + // agent forwarding + accept = key; + reject = keyType; + } else if (isSigning) { + keylen = key.length; + datalen = data.length; + } else { + cb = key; + key = undefined; + } + + function onconnect() { + var buf; + if (isSigning) { + /* + byte SSH2_AGENTC_SIGN_REQUEST + string key_blob + string data + uint32 flags + */ + var p = 9; + buf = new Buffer(4 + 1 + 4 + keylen + 4 + datalen + 4); + buf.writeUInt32BE(buf.length - 4, 0, true); + buf[4] = SIGN_REQUEST; + buf.writeUInt32BE(keylen, 5, true); + key.copy(buf, p); + buf.writeUInt32BE(datalen, p += keylen, true); + data.copy(buf, p += 4); + buf.writeUInt32BE(0, p += datalen, true); + sock.write(buf); + } else { + /* + byte SSH2_AGENTC_REQUEST_IDENTITIES + */ + sock.write(new Buffer([0, 0, 0, 1, REQUEST_IDENTITIES])); + } + } + function ondata(chunk) { + for (var i = 0, len = chunk.length; i < len; ++i) { + if (type === undefined) { + // skip over packet length + if (++count === 5) { + type = chunk[i]; + count = 0; + } + } else if (type === SIGN_RESPONSE) { + /* + byte SSH2_AGENT_SIGN_RESPONSE + string signature_blob + */ + if (!sig) { + siglen <<= 8; + siglen += chunk[i]; + if (++count === 4) { + sig = new Buffer(siglen); + count = 0; + } + } else { + sig[count] = chunk[i]; + if (++count === siglen) { + sock.removeAllListeners('data'); + return sock.destroy(); + } + } + } else if (type === IDENTITIES_ANSWER) { + /* + byte SSH2_AGENT_IDENTITIES_ANSWER + uint32 num_keys + + Followed by zero or more consecutive keys, encoded as: + + string public key blob + string public key comment + */ + if (keys === undefined) { + nkeys <<= 8; + nkeys += chunk[i]; + if (++count === 4) { + keys = new Array(nkeys); + count = 0; + if (nkeys === 0) { + sock.removeAllListeners('data'); + return sock.destroy(); + } + } + } else { + if (!key) { + keylen <<= 8; + keylen += chunk[i]; + if (++count === 4) { + key = new Buffer(keylen); + count = 0; + } + } else if (comment === false) { + key[count] = chunk[i]; + if (++count === keylen) { + keys[nkeys - 1] = key; + keylen = 0; + count = 0; + comment = true; + if (--nkeys === 0) { + key = undefined; + sock.removeAllListeners('data'); + return sock.destroy(); + } + } + } else if (comment === true) { + comlen <<= 8; + comlen += chunk[i]; + if (++count === 4) { + count = 0; + if (comlen > 0) + comment = comlen; + else { + key = undefined; + comment = false; + } + comlen = 0; + } + } else { + // skip comments + if (++count === comment) { + comment = false; + count = 0; + key = undefined; + } + } + } + } else if (type === FAILURE) { + if (isSigning) + error = new Error('Agent unable to sign data'); + else + error = new Error('Unable to retrieve list of keys from agent'); + sock.removeAllListeners('data'); + return sock.destroy(); + } + } + } + function onerror(err) { + error = err; + } + function onclose() { + if (error) + cb(error); + else if ((isSigning && !sig) || (!isSigning && !keys)) + cb(new Error('Unexpected disconnection from agent')); + else if (isSigning && sig) + cb(undefined, sig); + else if (!isSigning && keys) + cb(undefined, keys); + } + + if (process.platform === 'win32') { + if (sockPath === 'pageant') { + // Pageant (PuTTY authentication agent) + sock = new PageantSock(); + } else { + // cygwin ssh-agent instance + var triedCygpath = false; + fs.readFile(sockPath, function readCygsocket(err, data) { + if (err) { + if (triedCygpath) + return cb(new Error('Invalid cygwin unix socket path')); + // try using `cygpath` to convert a possible *nix-style path to the + // real Windows path before giving up ... + cp.exec('cygpath -w "' + sockPath + '"', + function(err, stdout, stderr) { + if (err || stdout.length === 0) + return cb(new Error('Invalid cygwin unix socket path')); + triedCygpath = true; + sockPath = stdout.toString().replace(/[\r\n]/g, ''); + fs.readFile(sockPath, readCygsocket); + }); + return; + } + + var m; + if (m = RE_CYGWIN_SOCK.exec(data.toString('ascii'))) { + var port; + var secret; + var secretbuf; + var state; + var bc = 0; + var isRetrying = false; + var inbuf = []; + var credsbuf = new Buffer(12); + var i; + var j; + + // use 0 for pid, uid, and gid to ensure we get an error and also + // a valid uid and gid from cygwin so that we don't have to figure it + // out ourselves + credsbuf.fill(0); + + // parse cygwin unix socket file contents + port = parseInt(m[1], 10); + secret = m[2].replace(/\-/g, ''); + secretbuf = new Buffer(16); + for (i = 0, j = 0; j < 32; ++i,j+=2) + secretbuf[i] = parseInt(secret.substring(j, j + 2), 16); + + // convert to host order (always LE for Windows) + for (i = 0; i < 16; i += 4) + secretbuf.writeUInt32LE(secretbuf.readUInt32BE(i, true), i, true); + + function _onconnect() { + bc = 0; + state = 'secret'; + sock.write(secretbuf); + } + function _ondata(data) { + bc += data.length; + if (state === 'secret') { + // the secret we sent is echoed back to us by cygwin, not sure of + // the reason for that, but we ignore it nonetheless ... + if (bc === 16) { + bc = 0; + state = 'creds'; + sock.write(credsbuf); + } + } else if (state === 'creds') { + // if this is the first attempt, make sure to gather the valid + // uid and gid for our next attempt + if (!isRetrying) + inbuf.push(data); + + if (bc === 12) { + sock.removeListener('connect', _onconnect); + sock.removeListener('data', _ondata); + sock.removeListener('close', _onclose); + if (isRetrying) { + addSockListeners(); + sock.emit('connect'); + } else { + isRetrying = true; + credsbuf = Buffer.concat(inbuf); + credsbuf.writeUInt32LE(process.pid, 0, true); + sock.destroy(); + tryConnect(); + } + } + } + } + function _onclose() { + cb(new Error('Problem negotiating cygwin unix socket security')); + } + function tryConnect() { + sock = new Socket(); + sock.once('connect', _onconnect); + sock.on('data', _ondata); + sock.once('close', _onclose); + sock.connect(port); + } + tryConnect(); + } else + cb(new Error('Malformed cygwin unix socket file')); + }); + return; + } + } else + sock = new Socket(); + + function addSockListeners() { + if (!accept && !reject) { + sock.once('connect', onconnect); + sock.on('data', ondata); + sock.once('error', onerror); + sock.once('close', onclose); + } else { + var chan; + sock.once('connect', function() { + chan = accept(); + var isDone = false; + function onDone() { + if (isDone) + return; + sock.destroy(); + isDone = true; + } + chan.once('end', onDone) + .once('close', onDone) + .on('data', function(data) { + sock.write(data); + }); + sock.on('data', function(data) { + chan.write(data); + }); + }); + sock.once('close', function() { + if (!chan) + reject(); + }); + } + } + addSockListeners(); + sock.connect(sockPath); +}; + + +// win32 only ------------------------------------------------------------------ +if (process.platform === 'win32') { + var RET_ERR_BADARGS = 10; + var RET_ERR_UNAVAILABLE = 11; + var RET_ERR_NOMAP = 12; + var RET_ERR_BINSTDIN = 13; + var RET_ERR_BINSTDOUT = 14; + var RET_ERR_BADLEN = 15; + + var ERROR = {}; + var EXEPATH = path.resolve(__dirname, '..', 'util/pagent.exe'); + ERROR[RET_ERR_BADARGS] = new Error('Invalid pagent.exe arguments'); + ERROR[RET_ERR_UNAVAILABLE] = new Error('Pageant is not running'); + ERROR[RET_ERR_NOMAP] = new Error('pagent.exe could not create an mmap'); + ERROR[RET_ERR_BINSTDIN] = new Error('pagent.exe could not set mode for stdin'); + ERROR[RET_ERR_BINSTDOUT] = new Error('pagent.exe could not set mode for stdout'); + ERROR[RET_ERR_BADLEN] = new Error('pagent.exe did not get expected input payload'); + + function PageantSock() { + this.proc = undefined; + this.buffer = null; + } + inherits(PageantSock, EventEmitter); + + PageantSock.prototype.write = function(buf) { + if (this.buffer === null) + this.buffer = buf; + else { + this.buffer = Buffer.concat([this.buffer, buf], + this.buffer.length + buf.length); + } + // Wait for at least all length bytes + if (this.buffer.length < 4) + return; + + var len = this.buffer.readUInt32BE(0, true); + // Make sure we have a full message before querying pageant + if ((this.buffer.length - 4) < len) + return; + + buf = this.buffer.slice(0, 4 + len); + if (this.buffer.length > (4 + len)) + this.buffer = this.buffer.slice(4 + len); + else + this.buffer = null; + + var self = this; + var proc; + var hadError = false; + proc = this.proc = cp.spawn(EXEPATH, [ buf.length ]); + proc.stdout.on('data', function(data) { + self.emit('data', data); + }); + proc.once('error', function(err) { + if (!hadError) { + hadError = true; + self.emit('error', err); + } + }); + proc.once('close', function(code) { + self.proc = undefined; + if (ERROR[code] && !hadError) { + hadError = true; + self.emit('error', ERROR[code]); + } + self.emit('close', hadError); + }); + proc.stdin.end(buf); + }; + PageantSock.prototype.end = PageantSock.prototype.destroy = function() { + this.buffer = null; + if (this.proc) { + this.proc.kill(); + this.proc = undefined; + } + }; + PageantSock.prototype.connect = function() { + this.emit('connect'); + }; +} diff --git a/node_modules/ssh2/lib/client.js b/node_modules/ssh2/lib/client.js new file mode 100644 index 0000000..1d49282 --- /dev/null +++ b/node_modules/ssh2/lib/client.js @@ -0,0 +1,1522 @@ +var crypto = require('crypto'); +var Socket = require('net').Socket; +var dnsLookup = require('dns').lookup; +var EventEmitter = require('events').EventEmitter; +var inherits = require('util').inherits; +var HASHES = crypto.getHashes(); + +var ssh2_streams = require('ssh2-streams'); +var SSH2Stream = ssh2_streams.SSH2Stream; +var SFTPStream = ssh2_streams.SFTPStream; +var consts = ssh2_streams.constants; +var BUGS = consts.BUGS; +var ALGORITHMS = consts.ALGORITHMS; +var parseKey = ssh2_streams.utils.parseKey; +var decryptKey = ssh2_streams.utils.decryptKey; +var genPublicKey = ssh2_streams.utils.genPublicKey; + +var Channel = require('./Channel'); +var agentQuery = require('./agent'); +var SFTPWrapper = require('./SFTPWrapper'); + +var MAX_CHANNEL = Math.pow(2, 32) - 1; +var RE_OPENSSH = /^OpenSSH_(?:(?![0-4])\d)|(?:\d{2,})/; +var DEBUG_NOOP = function(msg) {}; + +function Client() { + if (!(this instanceof Client)) + return new Client(); + + EventEmitter.call(this); + + this.config = { + host: undefined, + port: undefined, + forceIPv4: undefined, + forceIPv6: undefined, + keepaliveCountMax: undefined, + keepaliveInterval: undefined, + readyTimeout: undefined, + + username: undefined, + password: undefined, + privateKey: undefined, + publicKey: undefined, + tryKeyboard: undefined, + agent: undefined, + allowAgentFwd: undefined, + + hostHashAlgo: undefined, + hostHashCb: undefined, + strictVendor: undefined, + debug: undefined + }; + + this._readyTimeout = undefined; + this._channels = undefined; + this._callbacks = undefined; + this._forwarding = undefined; + this._acceptX11 = undefined; + this._agentFwdEnabled = undefined; + this._curChan = undefined; + this._remoteVer = undefined; + + this._sshstream = undefined; + this._sock = undefined; + this._resetKA = undefined; +} +inherits(Client, EventEmitter); + +Client.prototype.connect = function(cfg) { + var self = this; + + if (this._sock && this._sock.writable) { + this.once('close', function() { + self.connect(cfg); + }); + this.end(); + return; + } + + this.config.host = cfg.hostname || cfg.host || 'localhost'; + this.config.port = cfg.port || 22; + this.config.forceIPv4 = cfg.forceIPv4 || false; + this.config.forceIPv6 = cfg.forceIPv6 || false; + this.config.keepaliveCountMax = (typeof cfg.keepaliveCountMax === 'number' + && cfg.keepaliveCountMax >= 0 + ? cfg.keepaliveCountMax + : 3); + this.config.keepaliveInterval = (typeof cfg.keepaliveInterval === 'number' + && cfg.keepaliveInterval > 0 + ? cfg.keepaliveInterval + : 0); + this.config.readyTimeout = (typeof cfg.readyTimeout === 'number' + && cfg.readyTimeout >= 0 + ? cfg.readyTimeout + : 20000); + + var algorithms = { + kex: undefined, + kexBuf: undefined, + cipher: undefined, + cipherBuf: undefined, + serverHostKey: undefined, + serverHostKeyBuf: undefined, + hmac: undefined, + hmacBuf: undefined, + compress: undefined, + compressBuf: undefined + }; + var i; + if (typeof cfg.algorithms === 'object' && cfg.algorithms !== null) { + var algosSupported; + var algoList; + + algoList = cfg.algorithms.kex; + if (Array.isArray(algoList) && algoList.length > 0) { + algosSupported = ALGORITHMS.SUPPORTED_KEX; + for (i = 0; i < algoList.length; ++i) { + if (algosSupported.indexOf(algoList[i]) === -1) + throw new Error('Unsupported key exchange algorithm: ' + algoList[i]); + } + algorithms.kex = algoList; + } + + algoList = cfg.algorithms.cipher; + if (Array.isArray(algoList) && algoList.length > 0) { + algosSupported = ALGORITHMS.SUPPORTED_CIPHER; + for (i = 0; i < algoList.length; ++i) { + if (algosSupported.indexOf(algoList[i]) === -1) + throw new Error('Unsupported cipher algorithm: ' + algoList[i]); + } + algorithms.cipher = algoList; + } + + algoList = cfg.algorithms.serverHostKey; + if (Array.isArray(algoList) && algoList.length > 0) { + algosSupported = ALGORITHMS.SUPPORTED_SERVER_HOST_KEY; + for (i = 0; i < algoList.length; ++i) { + if (algosSupported.indexOf(algoList[i]) === -1) { + throw new Error('Unsupported server host key algorithm: ' + + algoList[i]); + } + } + algorithms.serverHostKey = algoList; + } + + algoList = cfg.algorithms.hmac; + if (Array.isArray(algoList) && algoList.length > 0) { + algosSupported = ALGORITHMS.SUPPORTED_HMAC; + for (i = 0; i < algoList.length; ++i) { + if (algosSupported.indexOf(algoList[i]) === -1) + throw new Error('Unsupported HMAC algorithm: ' + algoList[i]); + } + algorithms.hmac = algoList; + } + + algoList = cfg.algorithms.compress; + if (Array.isArray(algoList) && algoList.length > 0) { + algosSupported = ALGORITHMS.SUPPORTED_COMPRESS; + for (i = 0; i < algoList.length; ++i) { + if (algosSupported.indexOf(algoList[i]) === -1) + throw new Error('Unsupported compression algorithm: ' + algoList[i]); + } + algorithms.compress = algoList; + } + } + if (algorithms.compress === undefined) { + if (cfg.compress) { + algorithms.compress = ['zlib@openssh.com', 'zlib']; + if (cfg.compress !== 'force') + algorithms.compress.push('none'); + } else if (cfg.compress === false) + algorithms.compress = ['none']; + } + + this.config.username = cfg.username || cfg.user; + this.config.password = (typeof cfg.password === 'string' + ? cfg.password + : undefined); + this.config.privateKey = (typeof cfg.privateKey === 'string' + || Buffer.isBuffer(cfg.privateKey) + ? cfg.privateKey + : undefined); + this.config.publicKey = undefined; + this.config.localHostname = (typeof cfg.localHostname === 'string' + && cfg.localHostname.length + ? cfg.localHostname + : undefined); + this.config.localUsername = (typeof cfg.localUsername === 'string' + && cfg.localUsername.length + ? cfg.localUsername + : undefined); + this.config.tryKeyboard = (cfg.tryKeyboard === true); + this.config.agent = (typeof cfg.agent === 'string' && cfg.agent.length + ? cfg.agent + : undefined); + this.config.allowAgentFwd = (cfg.agentForward === true + && this.config.agent !== undefined); + + this.config.strictVendor = (typeof cfg.strictVendor === 'boolean' + ? cfg.strictVendor + : true); + + var debug = this.config.debug = (typeof cfg.debug === 'function' + ? cfg.debug + : DEBUG_NOOP); + + if (typeof this.config.username !== 'string') + throw new Error('Invalid username'); + + if (cfg.agentForward === true && !this.config.allowAgentFwd) + throw new Error('You must set a valid agent path to allow agent forwarding'); + + var callbacks = this._callbacks = []; + this._channels = {}; + this._forwarding = {}; + this._acceptX11 = 0; + this._agentFwdEnabled = false; + this._curChan = -1; + this._remoteVer = undefined; + + if (this.config.privateKey) { + var privKeyInfo = parseKey(this.config.privateKey); + if (privKeyInfo instanceof Error) + throw new Error('Cannot parse privateKey: ' + privKeyInfo.message); + if (!privKeyInfo.private) + throw new Error('privateKey value does not contain a (valid) private key'); + if (privKeyInfo.encryption) { + if (typeof cfg.passphrase !== 'string') + throw new Error('Encrypted private key detected, but no passphrase given'); + decryptKey(privKeyInfo, cfg.passphrase); + } + this.config.privateKey = privKeyInfo; + this.config.publicKey = genPublicKey(privKeyInfo); + } + + var stream = this._sshstream = new SSH2Stream({ + algorithms: algorithms, + debug: (debug === DEBUG_NOOP ? undefined : debug) + }); + var sock = this._sock = (cfg.sock || new Socket()); + + // drain stderr if we are connection hopping using an exec stream + if (this._sock.stderr) + this._sock.stderr.resume(); + + // keepalive-related + var kainterval = this.config.keepaliveInterval; + var kacountmax = this.config.keepaliveCountMax; + var kacount = 0; + var katimer; + function sendKA() { + if (++kacount > kacountmax) { + clearInterval(katimer); + if (sock.readable) { + var err = new Error('Keepalive timeout'); + err.level = 'client-timeout'; + self.emit('error', err); + sock.destroy(); + } + return; + } + if (sock.writable) { + // append dummy callback to keep correct callback order + callbacks.push(resetKA); + stream.ping(); + } else + clearInterval(katimer); + } + function resetKA() { + if (kainterval > 0) { + kacount = 0; + clearInterval(katimer); + if (sock.writable) + katimer = setInterval(sendKA, kainterval); + } + } + this._resetKA = resetKA; + + stream.on('USERAUTH_BANNER', function(msg) { + self.emit('banner', msg); + }); + + sock.on('connect', function() { + debug('DEBUG: Client: Connected'); + self.emit('connect'); + if (!cfg.sock) + stream.pipe(sock).pipe(stream); + }).on('timeout', function() { + self.emit('timeout'); + }).on('error', function(err) { + clearTimeout(self._readyTimeout); + err.level = 'client-socket'; + self.emit('error', err); + }).on('end', function() { + stream.unpipe(sock); + clearTimeout(self._readyTimeout); + clearInterval(katimer); + self.emit('end'); + }).on('close', function() { + stream.unpipe(sock); + clearTimeout(self._readyTimeout); + clearInterval(katimer); + self.emit('close'); + + // notify outstanding channel requests of disconnection ... + var callbacks_ = callbacks; + var err = new Error('No response from server'); + callbacks = self._callbacks = []; + for (i = 0; i < callbacks_.length; ++i) + callbacks_[i](err); + + // simulate error for any channels waiting to be opened. this is safe + // against successfully opened channels because the success and failure + // event handlers are automatically removed when a success/failure response + // is received + var chanNos = Object.keys(self._channels); + self._channels = {}; + for (i = 0; i < chanNos.length; ++i) { + stream.emit('CHANNEL_OPEN_FAILURE:' + chanNos[i], err); + // emitting CHANNEL_CLOSE should be safe too and should help for any + // special channels which might otherwise keep the process alive, such + // as agent forwarding channels which have open unix sockets ... + stream.emit('CHANNEL_CLOSE:' + chanNos[i]); + } + }); + stream.on('drain', function() { + self.emit('drain'); + }).once('header', function(header) { + self._remoteVer = header.versions.software; + if (header.greeting) + self.emit('greeting', header.greeting); + }).on('continue', function() { + self.emit('continue'); + }).on('error', function(err) { + err.level = 'protocol'; + self.emit('error', err); + }); + + if (typeof cfg.hostVerifier === 'function') { + if (HASHES.indexOf(cfg.hostHash) === -1) + throw new Error('Invalid host hash algorithm: ' + cfg.hostHash); + var hashCb = cfg.hostVerifier; + var hasher = crypto.createHash(cfg.hostHash); + stream.once('fingerprint', function(key, verify) { + hasher.update(key); + var ret = hashCb(hasher.digest('hex'), verify); + if (ret !== undefined) + verify(ret); + }); + } + + // begin authentication handling ============================================= + var auths = []; + var curAuth; + var agentKeys; + var agentKeyPos = 0; + if (this.config.password !== undefined) + auths.push('password'); + if (this.config.publicKey !== undefined) + auths.push('publickey'); + if (this.config.agent !== undefined) + auths.push('agent'); + if (this.config.tryKeyboard) + auths.push('keyboard-interactive'); + if (this.config.publicKey !== undefined + && this.config.localHostname !== undefined + && this.config.localUsername !== undefined) + auths.push('hostbased'); + auths.push('none'); + function tryNextAuth() { + // TODO: better shutdown + if (!auths.length) { + stream.removeListener('USERAUTH_FAILURE', onUSERAUTH_FAILURE); + stream.removeListener('USERAUTH_PK_OK', onUSERAUTH_PK_OK); + var err = new Error('All configured authentication methods failed'); + err.level = 'client-authentication'; + self.emit('error', err); + if (stream.writable) + self.end(); + return; + } + + curAuth = auths.shift(); + switch (curAuth) { + case 'password': + stream.authPassword(self.config.username, self.config.password); + break; + case 'publickey': + stream.authPK(self.config.username, self.config.publicKey); + stream.once('USERAUTH_PK_OK', onUSERAUTH_PK_OK); + break; + case 'hostbased': + function hostbasedCb(buf, cb) { + var algo; + switch (self.config.privateKey.fulltype) { + case 'ssh-rsa': + algo = 'RSA-SHA1'; + break; + case 'ssh-dss': + algo = 'DSA-SHA1'; + break; + case 'ecdsa-sha2-nistp256': + algo = 'sha256'; + break; + case 'ecdsa-sha2-nistp384': + algo = 'sha384'; + break; + case 'ecdsa-sha2-nistp521': + algo = 'sha512'; + break; + } + var signature = crypto.createSign(algo); + signature.update(buf); + signature = trySign(signature, self.config.privateKey.privateOrig); + if (signature instanceof Error) { + signature.message = 'Error while signing data with privateKey: ' + + signature.message; + signature.level = 'client-authentication'; + self.emit('error', signature); + return tryNextAuth(); + } + + cb(signature); + } + stream.authHostbased(self.config.username, + self.config.publicKey, + self.config.localHostname, + self.config.localUsername, + hostbasedCb); + break; + case 'agent': + agentQuery(self.config.agent, function(err, keys) { + if (err) { + err.level = 'agent'; + self.emit('error', err); + agentKeys = undefined; + return tryNextAuth(); + } else if (keys.length === 0) { + debug('DEBUG: Agent: No keys stored in agent'); + agentKeys = undefined; + return tryNextAuth(); + } + + agentKeys = keys; + agentKeyPos = 0; + + stream.authPK(self.config.username, keys[0]); + stream.once('USERAUTH_PK_OK', onUSERAUTH_PK_OK); + }); + break; + case 'keyboard-interactive': + stream.authKeyboard(self.config.username); + stream.on('USERAUTH_INFO_REQUEST', onUSERAUTH_INFO_REQUEST); + break; + case 'none': + stream.authNone(self.config.username); + break; + } + } + function tryNextAgentKey() { + if (curAuth === 'agent') { + if (agentKeyPos >= agentKeys.length) + return; + if (++agentKeyPos >= agentKeys.length) { + debug('DEBUG: Agent: No more keys left to try'); + debug('DEBUG: Client: agent auth failed'); + agentKeys = undefined; + tryNextAuth(); + } else { + debug('DEBUG: Agent: Trying key #' + (agentKeyPos + 1)); + stream.authPK(self.config.username, agentKeys[agentKeyPos]); + stream.once('USERAUTH_PK_OK', onUSERAUTH_PK_OK); + } + } + } + function onUSERAUTH_INFO_REQUEST(name, instructions, lang, prompts) { + var nprompts = (Array.isArray(prompts) ? prompts.length : 0); + if (nprompts === 0) { + debug('DEBUG: Client: Sending automatic USERAUTH_INFO_RESPONSE'); + return stream.authInfoRes(); + } + // we sent a keyboard-interactive user authentication request and now the + // server is sending us the prompts we need to present to the user + self.emit('keyboard-interactive', + name, + instructions, + lang, + prompts, + function(answers) { + stream.authInfoRes(answers); + }); + } + function onUSERAUTH_PK_OK() { + if (curAuth === 'agent') { + var agentKey = agentKeys[agentKeyPos]; + var keyLen = agentKey.readUInt32BE(0, true); + var pubKeyFullType = agentKey.toString('ascii', 4, 4 + keyLen); + var pubKeyType = pubKeyFullType.slice(4); + // Check that we support the key type first + switch (pubKeyFullType) { + case 'ssh-rsa': + case 'ssh-dss': + case 'ecdsa-sha2-nistp256': + case 'ecdsa-sha2-nistp384': + case 'ecdsa-sha2-nistp521': + break; + default: + debug('DEBUG: Agent: Skipping unsupported key type: ' + + pubKeyFullType); + return tryNextAgentKey(); + } + stream.authPK(self.config.username, + agentKey, + function(buf, cb) { + agentQuery(self.config.agent, + agentKey, + pubKeyType, + buf, + function(err, signed) { + if (err) { + err.level = 'agent'; + self.emit('error', err); + } else { + var sigFullTypeLen = signed.readUInt32BE(0, true); + if (4 + sigFullTypeLen + 4 < signed.length) { + var sigFullType = signed.toString('ascii', 4, 4 + sigFullTypeLen); + if (sigFullType !== pubKeyFullType) { + err = new Error('Agent key/signature type mismatch'); + err.level = 'agent'; + self.emit('error', err); + } else { + // skip algoLen + algo + sigLen + return cb(signed.slice(4 + sigFullTypeLen + 4)); + } + } + } + + tryNextAgentKey(); + }); + }); + } else if (curAuth === 'publickey') { + stream.authPK(self.config.username, + self.config.publicKey, + function(buf, cb) { + var algo; + switch (self.config.privateKey.fulltype) { + case 'ssh-rsa': + algo = 'RSA-SHA1'; + break; + case 'ssh-dss': + algo = 'DSA-SHA1'; + break; + case 'ecdsa-sha2-nistp256': + algo = 'sha256'; + break; + case 'ecdsa-sha2-nistp384': + algo = 'sha384'; + break; + case 'ecdsa-sha2-nistp521': + algo = 'sha512'; + break; + } + var signature = crypto.createSign(algo); + signature.update(buf); + signature = trySign(signature, self.config.privateKey.privateOrig); + if (signature instanceof Error) { + signature.message = 'Error while signing data with privateKey: ' + + signature.message; + signature.level = 'client-authentication'; + self.emit('error', signature); + return tryNextAuth(); + } + cb(signature); + }); + } + } + function onUSERAUTH_FAILURE(authsLeft, partial) { + stream.removeListener('USERAUTH_PK_OK', onUSERAUTH_PK_OK); + stream.removeListener('USERAUTH_INFO_REQUEST', onUSERAUTH_INFO_REQUEST); + if (curAuth === 'agent') { + debug('DEBUG: Client: Agent key #' + (agentKeyPos + 1) + ' failed'); + return tryNextAgentKey(); + } else + debug('DEBUG: Client: ' + curAuth + ' auth failed'); + + tryNextAuth(); + } + stream.once('USERAUTH_SUCCESS', function() { + auths = undefined; + stream.removeListener('USERAUTH_FAILURE', onUSERAUTH_FAILURE); + stream.removeListener('USERAUTH_INFO_REQUEST', onUSERAUTH_INFO_REQUEST); + /*if (self.config.agent && self._agentKeys) + self._agentKeys = undefined;*/ + + // start keepalive mechanism + resetKA(); + + clearTimeout(self._readyTimeout); + + self.emit('ready'); + }).on('USERAUTH_FAILURE', onUSERAUTH_FAILURE); + // end authentication handling =============================================== + + // handle initial handshake completion + stream.once('ready', function() { + stream.service('ssh-userauth'); + stream.once('SERVICE_ACCEPT', function(svcName) { + if (svcName === 'ssh-userauth') + tryNextAuth(); + }); + }); + + // handle incoming requests from server, typically a forwarded TCP or X11 + // connection + stream.on('CHANNEL_OPEN', function(info) { + onCHANNEL_OPEN(self, info); + }); + + // handle responses for tcpip-forward and other global requests + stream.on('REQUEST_SUCCESS', function(data) { + if (callbacks.length) + callbacks.shift()(false, data); + }).on('REQUEST_FAILURE', function() { + if (callbacks.length) + callbacks.shift()(true); + }); + + stream.on('GLOBAL_REQUEST', function(name, wantReply, data) { + // auto-reject all global requests, this can be especially useful if the + // server is sending us dummy keepalive global requests + if (wantReply) + stream.requestFailure(); + }); + + if (!cfg.sock) { + var host = this.config.host; + var forceIPv4 = this.config.forceIPv4; + var forceIPv6 = this.config.forceIPv6; + + debug('DEBUG: Client: Trying ' + + host + + ' on port ' + + this.config.port + + ' ...'); + + function doConnect() { + startTimeout(); + self._sock.connect(self.config.port, host); + self._sock.setNoDelay(true); + self._sock.setMaxListeners(0); + self._sock.setTimeout(typeof cfg.timeout === 'number' ? cfg.timeout : 0); + } + + if ((!forceIPv4 && !forceIPv6) || (forceIPv4 && forceIPv6)) + doConnect(); + else { + dnsLookup(host, (forceIPv4 ? 4 : 6), function(err, address, family) { + if (err) { + var error = new Error('Error while looking up ' + + (forceIPv4 ? 'IPv4' : 'IPv6') + + ' address for host ' + + host + + ': ' + err); + clearTimeout(self._readyTimeout); + error.level = 'client-dns'; + self.emit('error', error); + self.emit('close'); + return; + } + host = address; + doConnect(); + }); + } + } else { + startTimeout(); + stream.pipe(sock).pipe(stream); + } + + function startTimeout() { + if (self.config.readyTimeout > 0) { + self._readyTimeout = setTimeout(function() { + var err = new Error('Timed out while waiting for handshake'); + err.level = 'client-timeout'; + self.emit('error', err); + sock.destroy(); + }, self.config.readyTimeout); + } + } +}; + +Client.prototype.end = function() { + if (this._sock + && this._sock.writable + && this._sshstream + && this._sshstream.writable) + return this._sshstream.disconnect(); + return false; +}; + +Client.prototype.destroy = function() { + this._sock && this._sock.destroy(); +}; + +Client.prototype.exec = function(cmd, opts, cb) { + if (!this._sock + || !this._sock.writable + || !this._sshstream + || !this._sshstream.writable) + throw new Error('Not connected'); + + if (typeof opts === 'function') { + cb = opts; + opts = {}; + } + + var self = this; + var extraOpts = { allowHalfOpen: (opts.allowHalfOpen !== false) }; + + return openChannel(this, 'session', extraOpts, function(err, chan) { + if (err) + return cb(err); + + var todo = []; + + function reqCb(err) { + if (err) { + chan.close(); + return cb(err); + } + if (todo.length) + todo.shift()(); + } + + if (self.config.allowAgentFwd === true + || (opts + && opts.agentForward === true + && self.config.agent !== undefined)) { + todo.push(function() { + reqAgentFwd(chan, reqCb); + }); + } + + if (typeof opts === 'object') { + if (typeof opts.env === 'object') + reqEnv(chan, opts.env); + if (typeof opts.pty === 'object' || opts.pty === true) + todo.push(function() { reqPty(chan, opts.pty, reqCb); }); + if (typeof opts.x11 === 'object' + || opts.x11 === 'number' + || opts.x11 === true) + todo.push(function() { reqX11(chan, opts.x11, reqCb); }); + } + + todo.push(function() { reqExec(chan, cmd, opts, cb); }); + todo.shift()(); + }); +}; + +Client.prototype.shell = function(wndopts, opts, cb) { + if (!this._sock + || !this._sock.writable + || !this._sshstream + || !this._sshstream.writable) + throw new Error('Not connected'); + + // start an interactive terminal/shell session + var self = this; + + if (typeof wndopts === 'function') { + cb = wndopts; + wndopts = opts = undefined; + } else if (typeof opts === 'function') { + cb = opts; + opts = undefined; + } + if (wndopts && wndopts.x11 !== undefined) { + opts = wndopts; + wndopts = undefined; + } + + return openChannel(this, 'session', function(err, chan) { + if (err) + return cb(err); + + var todo = []; + + function reqCb(err) { + if (err) { + chan.close(); + return cb(err); + } + if (todo.length) + todo.shift()(); + } + + if (self.config.allowAgentFwd === true + || (opts + && opts.agentForward === true + && self.config.agent !== undefined)) { + todo.push(function() { + reqAgentFwd(chan, reqCb); + }); + } + + if (wndopts !== false) + todo.push(function() { reqPty(chan, wndopts, reqCb); }); + + if (typeof opts === 'object') { + if (typeof opts.x11 === 'object' + || opts.x11 === 'number' + || opts.x11 === true) + todo.push(function() { reqX11(chan, opts.x11, reqCb); }); + } + + todo.push(function() { reqShell(chan, cb); }); + todo.shift()(); + }); +}; + +Client.prototype.subsys = function(name, cb) { + if (!this._sock + || !this._sock.writable + || !this._sshstream + || !this._sshstream.writable) + throw new Error('Not connected'); + + return openChannel(this, 'session', function(err, chan) { + if (err) + return cb(err); + + reqSubsystem(chan, name, function(err, stream) { + if (err) + return cb(err); + + cb(undefined, stream); + }); + }); +}; + +Client.prototype.sftp = function(cb) { + if (!this._sock + || !this._sock.writable + || !this._sshstream + || !this._sshstream.writable) + throw new Error('Not connected'); + + var self = this; + + // start an SFTP session + return openChannel(this, 'session', function(err, chan) { + if (err) + return cb(err); + + reqSubsystem(chan, 'sftp', function(err, stream) { + if (err) + return cb(err); + + var serverIdentRaw = self._sshstream._state.incoming.identRaw; + var cfg = { debug: self.config.debug }; + var sftp = new SFTPStream(cfg, serverIdentRaw); + + function onError(err) { + sftp.removeListener('ready', onReady); + stream.removeListener('exit', onExit); + cb(err); + } + + function onReady() { + sftp.removeListener('error', onError); + stream.removeListener('exit', onExit); + cb(undefined, new SFTPWrapper(sftp)); + } + + function onExit(code, signal) { + sftp.removeListener('ready', onReady); + sftp.removeListener('error', onError); + var msg; + if (typeof code === 'number') { + msg = 'Received exit code ' + + code + + ' while establishing SFTP session'; + } else { + msg = 'Received signal ' + + signal + + ' while establishing SFTP session'; + } + var err = new Error(msg); + err.code = code; + err.signal = signal; + cb(err); + } + + sftp.once('error', onError) + .once('ready', onReady) + .once('close', function() { + stream.end(); + }); + + // OpenSSH server sends an exit-status if there was a problem spinning up + // an sftp server child process, so we listen for that here in order to + // properly raise an error. + stream.once('exit', onExit); + + sftp.pipe(stream).pipe(sftp); + }); + }); +}; + +Client.prototype.forwardIn = function(bindAddr, bindPort, cb) { + if (!this._sock + || !this._sock.writable + || !this._sshstream + || !this._sshstream.writable) + throw new Error('Not connected'); + + // send a request for the server to start forwarding TCP connections to us + // on a particular address and port + + var self = this; + var wantReply = (typeof cb === 'function'); + + if (wantReply) { + this._callbacks.push(function(had_err, data) { + if (had_err) { + return cb(had_err !== true + ? had_err + : new Error('Unable to bind to ' + bindAddr + ':' + bindPort)); + } + + var realPort = bindPort; + if (bindPort === 0 && data && data.length >= 4) { + realPort = data.readUInt32BE(0, true); + if (!(self._sshstream.remoteBugs & BUGS.DYN_RPORT_BUG)) + bindPort = realPort; + } + + self._forwarding[bindAddr + ':' + bindPort] = realPort; + + cb(undefined, realPort); + }); + } + + return this._sshstream.tcpipForward(bindAddr, bindPort, wantReply); +}; + +Client.prototype.unforwardIn = function(bindAddr, bindPort, cb) { + if (!this._sock + || !this._sock.writable + || !this._sshstream + || !this._sshstream.writable) + throw new Error('Not connected'); + + // send a request to stop forwarding us new connections for a particular + // address and port + + var self = this; + var wantReply = (typeof cb === 'function'); + + if (wantReply) { + this._callbacks.push(function(had_err) { + if (had_err) { + return cb(had_err !== true + ? had_err + : new Error('Unable to unbind from ' + + bindAddr + ':' + bindPort)); + } + + delete self._forwarding[bindAddr + ':' + bindPort]; + + cb(); + }); + } + + return this._sshstream.cancelTcpipForward(bindAddr, bindPort, wantReply); +}; + +Client.prototype.forwardOut = function(srcIP, srcPort, dstIP, dstPort, cb) { + if (!this._sock + || !this._sock.writable + || !this._sshstream + || !this._sshstream.writable) + throw new Error('Not connected'); + + // send a request to forward a TCP connection to the server + + var cfg = { + srcIP: srcIP, + srcPort: srcPort, + dstIP: dstIP, + dstPort: dstPort + }; + + return openChannel(this, 'direct-tcpip', cfg, cb); +}; + +Client.prototype.openssh_noMoreSessions = function(cb) { + if (!this._sock + || !this._sock.writable + || !this._sshstream + || !this._sshstream.writable) + throw new Error('Not connected'); + + var wantReply = (typeof cb === 'function'); + + if (!this.config.strictVendor + || (this.config.strictVendor && RE_OPENSSH.test(this._remoteVer))) { + if (wantReply) { + this._callbacks.push(function(had_err) { + if (had_err) { + return cb(had_err !== true + ? had_err + : new Error('Unable to disable future sessions')); + } + + cb(); + }); + } + + return this._sshstream.openssh_noMoreSessions(wantReply); + } else if (wantReply) { + process.nextTick(function() { + cb(new Error('strictVendor enabled and server is not OpenSSH or compatible version')); + }); + } + + return true; +}; + +Client.prototype.openssh_forwardInStreamLocal = function(socketPath, cb) { + if (!this._sock + || !this._sock.writable + || !this._sshstream + || !this._sshstream.writable) + throw new Error('Not connected'); + + var wantReply = (typeof cb === 'function'); + + if (!this.config.strictVendor + || (this.config.strictVendor && RE_OPENSSH.test(this._remoteVer))) { + if (wantReply) { + this._callbacks.push(function(had_err) { + if (had_err) { + return cb(had_err !== true + ? had_err + : new Error('Unable to bind to ' + socketPath)); + } + + cb(); + }); + } + + return this._sshstream.openssh_streamLocalForward(socketPath, wantReply); + } else if (wantReply) { + process.nextTick(function() { + cb(new Error('strictVendor enabled and server is not OpenSSH or compatible version')); + }); + } + + return true; +}; + +Client.prototype.openssh_unforwardInStreamLocal = function(socketPath, cb) { + if (!this._sock + || !this._sock.writable + || !this._sshstream + || !this._sshstream.writable) + throw new Error('Not connected'); + + var wantReply = (typeof cb === 'function'); + + if (!this.config.strictVendor + || (this.config.strictVendor && RE_OPENSSH.test(this._remoteVer))) { + if (wantReply) { + this._callbacks.push(function(had_err) { + if (had_err) { + return cb(had_err !== true + ? had_err + : new Error('Unable to unbind on ' + socketPath)); + } + + cb(); + }); + } + + return this._sshstream.openssh_cancelStreamLocalForward(socketPath, wantReply); + } else if (wantReply) { + process.nextTick(function() { + cb(new Error('strictVendor enabled and server is not OpenSSH or compatible version')); + }); + } + + return true; +}; + +Client.prototype.openssh_forwardOutStreamLocal = function(socketPath, cb) { + if (!this._sock + || !this._sock.writable + || !this._sshstream + || !this._sshstream.writable) + throw new Error('Not connected'); + + if (!this.config.strictVendor + || (this.config.strictVendor && RE_OPENSSH.test(this._remoteVer))) { + var cfg = { socketPath: socketPath }; + return openChannel(this, 'direct-streamlocal@openssh.com', cfg, cb); + } else { + process.nextTick(function() { + cb(new Error('strictVendor enabled and server is not OpenSSH or compatible version')); + }); + } + + return true; +}; + +function openChannel(self, type, opts, cb) { + // ask the server to open a channel for some purpose + // (e.g. session (sftp, exec, shell), or forwarding a TCP connection + var localChan = nextChannel(self); + var initWindow = Channel.MAX_WINDOW; + var maxPacket = Channel.PACKET_SIZE; + var ret = true; + + if (localChan === false) + return cb(new Error('No free channels available')); + + if (typeof opts === 'function') { + cb = opts; + opts = {}; + } + + self._channels[localChan] = true; + + var sshstream = self._sshstream; + sshstream.once('CHANNEL_OPEN_CONFIRMATION:' + localChan, onSuccess) + .once('CHANNEL_OPEN_FAILURE:' + localChan, onFailure) + .once('CHANNEL_CLOSE:' + localChan, onFailure); + + if (type === 'session') + ret = sshstream.session(localChan, initWindow, maxPacket); + else if (type === 'direct-tcpip') + ret = sshstream.directTcpip(localChan, initWindow, maxPacket, opts); + else if (type === 'direct-streamlocal@openssh.com') { + ret = sshstream.openssh_directStreamLocal(localChan, + initWindow, + maxPacket, + opts); + } + + return ret; + + function onSuccess(info) { + sshstream.removeListener('CHANNEL_OPEN_FAILURE:' + localChan, onFailure); + sshstream.removeListener('CHANNEL_CLOSE:' + localChan, onFailure); + + var chaninfo = { + type: type, + incoming: { + id: localChan, + window: initWindow, + packetSize: maxPacket, + state: 'open' + }, + outgoing: { + id: info.sender, + window: info.window, + packetSize: info.packetSize, + state: 'open' + } + }; + cb(undefined, new Channel(chaninfo, self)); + } + + function onFailure(info) { + sshstream.removeListener('CHANNEL_OPEN_CONFIRMATION:' + localChan, + onSuccess); + sshstream.removeListener('CHANNEL_OPEN_FAILURE:' + localChan, onFailure); + sshstream.removeListener('CHANNEL_CLOSE:' + localChan, onFailure); + + delete self._channels[localChan]; + + var err; + if (info instanceof Error) + err = info; + else if (typeof info === 'object' && info !== null) { + err = new Error('(SSH) Channel open failure: ' + info.description); + err.reason = info.reason; + err.lang = info.lang; + } else { + err = new Error('(SSH) Channel open failure: ' + + 'server closed channel unexpectedly'); + err.reason = err.lang = ''; + } + cb(err); + } +} + +function nextChannel(self) { + // get the next available channel number + + // optimized path + if (self._curChan < MAX_CHANNEL) + return ++self._curChan; + + // slower lookup path + for (var i = 0, channels = self._channels; i < MAX_CHANNEL; ++i) + if (!channels[i]) + return i; + + return false; +} + +function reqX11(chan, screen, cb) { + // asks server to start sending us X11 connections + var cfg = { + single: false, + protocol: 'MIT-MAGIC-COOKIE-1', + cookie: crypto.randomBytes(16).toString('hex'), + screen: (typeof screen === 'number' ? screen : 0) + }; + + if (typeof screen === 'function') + cb = screen; + else if (typeof screen === 'object') { + if (typeof screen.single === 'boolean') + cfg.single = screen.single; + if (typeof screen.screen === 'number') + cfg.screen = screen.screen; + } + + var wantReply = (typeof cb === 'function'); + + if (chan.outgoing.state !== 'open') { + wantReply && cb(new Error('Channel is not open')); + return true; + } + + if (wantReply) { + chan._callbacks.push(function(had_err) { + if (had_err) { + return cb(had_err !== true + ? had_err + : new Error('Unable to request X11')); + } + + chan._hasX11 = true; + ++chan._client._acceptX11; + chan.once('close', function() { + if (chan._client._acceptX11) + --chan._client._acceptX11; + }); + + cb(); + }); + } + + return chan._client._sshstream.x11Forward(chan.outgoing.id, cfg, wantReply); +} + +function reqPty(chan, opts, cb) { + var rows = 24; + var cols = 80; + var width = 640; + var height = 480; + var term = 'vt100'; + + if (typeof opts === 'function') + cb = opts; + else if (typeof opts === 'object') { + if (typeof opts.rows === 'number') + rows = opts.rows; + if (typeof opts.cols === 'number') + cols = opts.cols; + if (typeof opts.width === 'number') + width = opts.width; + if (typeof opts.height === 'number') + height = opts.height; + if (typeof opts.term === 'string') + term = opts.term; + } + + var wantReply = (typeof cb === 'function'); + + if (chan.outgoing.state !== 'open') { + wantReply && cb(new Error('Channel is not open')); + return true; + } + + if (wantReply) { + chan._callbacks.push(function(had_err) { + if (had_err) { + return cb(had_err !== true + ? had_err + : new Error('Unable to request a pseudo-terminal')); + } + cb(); + }); + } + + return chan._client._sshstream.pty(chan.outgoing.id, + rows, + cols, + height, + width, + term, + null, + wantReply); +} + +function reqAgentFwd(chan, cb) { + var wantReply = (typeof cb === 'function'); + + if (chan.outgoing.state !== 'open') { + wantReply && cb(new Error('Channel is not open')); + return true; + } else if (chan._client._agentFwdEnabled) { + wantReply && cb(false); + return true; + } + + chan._client._agentFwdEnabled = true; + + chan._callbacks.push(function(had_err) { + if (had_err) { + chan._client._agentFwdEnabled = false; + wantReply && cb(had_err !== true + ? had_err + : new Error('Unable to request agent forwarding')); + return; + } + + wantReply && cb(); + }); + + return chan._client._sshstream.openssh_agentForward(chan.outgoing.id, true); +} + +function reqShell(chan, cb) { + if (chan.outgoing.state !== 'open') { + cb(new Error('Channel is not open')); + return true; + } + chan._callbacks.push(function(had_err) { + if (had_err) { + return cb(had_err !== true + ? had_err + : new Error('Unable to open shell')); + } + chan.subtype = 'shell'; + cb(undefined, chan); + }); + + return chan._client._sshstream.shell(chan.outgoing.id, true); +} + +function reqExec(chan, cmd, opts, cb) { + if (chan.outgoing.state !== 'open') { + cb(new Error('Channel is not open')); + return true; + } + chan._callbacks.push(function(had_err) { + if (had_err) { + return cb(had_err !== true + ? had_err + : new Error('Unable to exec')); + } + chan.subtype = 'exec'; + chan.allowHalfOpen = (opts.allowHalfOpen !== false); + cb(undefined, chan); + }); + + return chan._client._sshstream.exec(chan.outgoing.id, cmd, true); +} + +function reqEnv(chan, env) { + if (chan.outgoing.state !== 'open') + return true; + var ret = true; + var keys = Object.keys(env || {}); + var key; + var val; + + for (var i = 0, len = keys.length; i < len; ++i) { + key = keys[i]; + val = env[key]; + ret = chan._client._sshstream.env(chan.outgoing.id, key, val, false); + } + + return ret; +} + +function reqSubsystem(chan, name, cb) { + if (chan.outgoing.state !== 'open') { + cb(new Error('Channel is not open')); + return true; + } + chan._callbacks.push(function(had_err) { + if (had_err) { + return cb(had_err !== true + ? had_err + : new Error('Unable to start subsystem: ' + name)); + } + chan.subtype = 'subsystem'; + cb(undefined, chan); + }); + + return chan._client._sshstream.subsystem(chan.outgoing.id, name, true); +} + +function onCHANNEL_OPEN(self, info) { + // the server is trying to open a channel with us, this is usually when + // we asked the server to forward us connections on some port and now they + // are asking us to accept/deny an incoming connection on their side + + var localChan = false; + var reason; + + function accept() { + var chaninfo = { + type: info.type, + incoming: { + id: localChan, + window: Channel.MAX_WINDOW, + packetSize: Channel.PACKET_SIZE, + state: 'open' + }, + outgoing: { + id: info.sender, + window: info.window, + packetSize: info.packetSize, + state: 'open' + } + }; + var stream = new Channel(chaninfo, self); + + self._sshstream.channelOpenConfirm(info.sender, + localChan, + Channel.MAX_WINDOW, + Channel.PACKET_SIZE); + return stream; + } + function reject() { + if (reason === undefined) { + if (localChan === false) + reason = consts.CHANNEL_OPEN_FAILURE.RESOURCE_SHORTAGE; + else + reason = consts.CHANNEL_OPEN_FAILURE.CONNECT_FAILED; + } + + self._sshstream.channelOpenFail(info.sender, reason, '', ''); + } + + if (info.type === 'forwarded-tcpip' + || info.type === 'x11' + || info.type === 'auth-agent@openssh.com') { + // check for conditions for automatic rejection + var rejectConn = ((info.type === 'forwarded-tcpip' + && self._forwarding[info.data.destIP + + ':' + + info.data.destPort] === undefined) + || (info.type === 'x11' && self._acceptX11 === 0) + || (info.type === 'auth-agent@openssh.com' + && !self._agentFwdEnabled)); + if (!rejectConn) { + localChan = nextChannel(self); + + if (localChan === false) { + self.config.debug('DEBUG: Client: Automatic rejection of incoming channel open: no channels available'); + rejectConn = true; + } else + self._channels[localChan] = true; + } else { + reason = consts.CHANNEL_OPEN_FAILURE.ADMINISTRATIVELY_PROHIBITED; + self.config.debug('DEBUG: Client: Automatic rejection of incoming channel open: unexpected channel open for: ' + + info.type); + } + + // TODO: automatic rejection after some timeout? + + if (rejectConn) + reject(); + + if (localChan !== false) { + if (info.type === 'forwarded-tcpip') { + if (info.data.destPort === 0) { + info.data.destPort = self._forwarding[info.data.destIP + + ':' + + info.data.destPort]; + } + self.emit('tcp connection', info.data, accept, reject); + } else if (info.type === 'x11') { + self.emit('x11', info.data, accept, reject); + } else { + agentQuery(self.config.agent, accept, reject); + } + } + } else { + // automatically reject any unsupported channel open requests + self.config.debug('DEBUG: Client: Automatic rejection of incoming channel open: unsupported type: ' + + info.type); + reason = consts.CHANNEL_OPEN_FAILURE.UNKNOWN_CHANNEL_TYPE; + reject(); + } +} + +function trySign(sig, key) { + try { + return sig.sign(key); + } catch (err) { + return err; + } +} + +Client.Client = Client; +Client.Server = require('./server'); +// pass some useful utilities on to end user (e.g. parseKey(), genPublicKey()) +Client.utils = ssh2_streams.utils; +// expose useful SFTPStream constants for sftp server usage +Client.SFTP_STATUS_CODE = SFTPStream.STATUS_CODE; +Client.SFTP_OPEN_MODE = SFTPStream.OPEN_MODE; + +module.exports = Client; // backwards compatibility diff --git a/node_modules/ssh2/lib/keepalivemgr.js b/node_modules/ssh2/lib/keepalivemgr.js new file mode 100644 index 0000000..28572ab --- /dev/null +++ b/node_modules/ssh2/lib/keepalivemgr.js @@ -0,0 +1,76 @@ +var spliceOne = require('./utils').spliceOne; + +function Manager(interval, streamInterval, kaCountMax) { + var streams = this._streams = []; + this._timer = undefined; + this._timerInterval = interval; + this._timerfn = function() { + var now = Date.now(); + for (var i = 0, len = streams.length, s, last; i < len; ++i) { + s = streams[i]; + last = s._kalast; + if (last && (now - last) >= streamInterval) { + if (++s._kacnt > kaCountMax) { + var err = new Error('Keepalive timeout'); + err.level = 'client-timeout'; + s.emit('error', err); + s.disconnect(); + spliceOne(streams, i); + --i; + len = streams.length; + } else { + s._kalast = now; + // XXX: if the server ever starts sending real global requests to the + // client, we will need to add a dummy callback here to keep the + // correct reply order + s.ping(); + } + } + } + }; +} + +Manager.prototype.start = function() { + if (this._timer) + this.stop(); + this._timer = setInterval(this._timerfn, this._timerInterval); +}; + +Manager.prototype.stop = function() { + if (this._timer) { + clearInterval(this._timer); + this._timer = undefined; + } +}; + +Manager.prototype.add = function(stream) { + var streams = this._streams, + self = this; + + stream.once('end', function() { + self.remove(stream); + }).on('packet', resetKA); + + streams[streams.length] = stream; + + resetKA(); + + if (!this._timer) + this.start(); + + function resetKA() { + stream._kalast = Date.now(); + stream._kacnt = 0; + } +}; + +Manager.prototype.remove = function(stream) { + var streams = this._streams, + index = streams.indexOf(stream); + if (index > -1) + spliceOne(streams, index); + if (!streams.length) + this.stop(); +}; + +module.exports = Manager; diff --git a/node_modules/ssh2/lib/server.js b/node_modules/ssh2/lib/server.js new file mode 100644 index 0000000..6d359d0 --- /dev/null +++ b/node_modules/ssh2/lib/server.js @@ -0,0 +1,1156 @@ +var net = require('net'); +var EventEmitter = require('events').EventEmitter; +var listenerCount = EventEmitter.listenerCount; +var inherits = require('util').inherits; + +var ssh2_streams = require('ssh2-streams'); +var parseKey = ssh2_streams.utils.parseKey; +var genPublicKey = ssh2_streams.utils.genPublicKey; +var decryptKey = ssh2_streams.utils.decryptKey; +var SSH2Stream = ssh2_streams.SSH2Stream; +var SFTPStream = ssh2_streams.SFTPStream; +var consts = ssh2_streams.constants; +var DISCONNECT_REASON = consts.DISCONNECT_REASON; +var CHANNEL_OPEN_FAILURE = consts.CHANNEL_OPEN_FAILURE; +var ALGORITHMS = consts.ALGORITHMS; + +var Channel = require('./Channel'); +var KeepaliveManager = require('./keepalivemgr'); + +var MAX_CHANNEL = Math.pow(2, 32) - 1; +var MAX_PENDING_AUTHS = 10; + +var kaMgr; + +function Server(cfg, listener) { + if (!(this instanceof Server)) + return new Server(cfg, listener); + + var hostKeys = { + 'ssh-rsa': null, + 'ssh-dss': null, + 'ecdsa-sha2-nistp256': null, + 'ecdsa-sha2-nistp384': null, + 'ecdsa-sha2-nistp521': null + }; + + var hostKeys_ = cfg.hostKeys; + if (!Array.isArray(hostKeys_)) + throw new Error('hostKeys must be an array'); + + var i; + for (i = 0; i < hostKeys_.length; ++i) { + var privateKey; + if (Buffer.isBuffer(hostKeys_[i]) || typeof hostKeys_[i] === 'string') + privateKey = parseKey(hostKeys_[i]); + else + privateKey = parseKey(hostKeys_[i].key); + if (privateKey instanceof Error) + throw new Error('Cannot parse privateKey: ' + privateKey.message); + if (!privateKey.private) + throw new Error('privateKey value contains an invalid private key'); + if (hostKeys[privateKey.fulltype]) + continue; + if (privateKey.encryption) { + if (typeof hostKeys_[i].passphrase !== 'string') + throw new Error('Missing passphrase for encrypted private key'); + decryptKey(privateKey, hostKeys_[i].passphrase); + } + hostKeys[privateKey.fulltype] = { + privateKey: privateKey, + publicKey: genPublicKey(privateKey) + }; + } + + var algorithms = { + kex: undefined, + kexBuf: undefined, + cipher: undefined, + cipherBuf: undefined, + serverHostKey: undefined, + serverHostKeyBuf: undefined, + hmac: undefined, + hmacBuf: undefined, + compress: undefined, + compressBuf: undefined + }; + if (typeof cfg.algorithms === 'object' && cfg.algorithms !== null) { + var algosSupported; + var algoList; + + algoList = cfg.algorithms.kex; + if (Array.isArray(algoList) && algoList.length > 0) { + algosSupported = ALGORITHMS.SUPPORTED_KEX; + for (i = 0; i < algoList.length; ++i) { + if (algosSupported.indexOf(algoList[i]) === -1) + throw new Error('Unsupported key exchange algorithm: ' + algoList[i]); + } + algorithms.kex = algoList; + } + + algoList = cfg.algorithms.cipher; + if (Array.isArray(algoList) && algoList.length > 0) { + algosSupported = ALGORITHMS.SUPPORTED_CIPHER; + for (i = 0; i < algoList.length; ++i) { + if (algosSupported.indexOf(algoList[i]) === -1) + throw new Error('Unsupported cipher algorithm: ' + algoList[i]); + } + algorithms.cipher = algoList; + } + + algoList = cfg.algorithms.serverHostKey; + var copied = false; + if (Array.isArray(algoList) && algoList.length > 0) { + algosSupported = ALGORITHMS.SUPPORTED_SERVER_HOST_KEY; + for (i = algoList.length - 1; i >= 0; --i) { + if (algosSupported.indexOf(algoList[i]) === -1) { + throw new Error('Unsupported server host key algorithm: ' + + algoList[i]); + } + if (!hostKeys[algoList[i]]) { + // Silently discard for now + if (!copied) { + algoList = algoList.slice(); + copied = true; + } + algoList.splice(i, 1); + } + } + if (algoList.length > 0) + algorithms.serverHostKey = algoList; + } + + algoList = cfg.algorithms.hmac; + if (Array.isArray(algoList) && algoList.length > 0) { + algosSupported = ALGORITHMS.SUPPORTED_HMAC; + for (i = 0; i < algoList.length; ++i) { + if (algosSupported.indexOf(algoList[i]) === -1) + throw new Error('Unsupported HMAC algorithm: ' + algoList[i]); + } + algorithms.hmac = algoList; + } + + algoList = cfg.algorithms.compress; + if (Array.isArray(algoList) && algoList.length > 0) { + algosSupported = ALGORITHMS.SUPPORTED_COMPRESS; + for (i = 0; i < algoList.length; ++i) { + if (algosSupported.indexOf(algoList[i]) === -1) + throw new Error('Unsupported compression algorithm: ' + algoList[i]); + } + algorithms.compress = algoList; + } + } + + // Make sure we at least have some kind of valid list of support key + // formats + if (algorithms.serverHostKey === undefined) { + var hostKeyAlgos = Object.keys(hostKeys); + for (i = hostKeyAlgos.length - 1; i >= 0; --i) { + if (!hostKeys[hostKeyAlgos[i]]) + hostKeyAlgos.splice(i, 1); + } + algorithms.serverHostKey = hostKeyAlgos; + } + + if (!kaMgr + && Server.KEEPALIVE_INTERVAL > 0 + && Server.KEEPALIVE_CLIENT_INTERVAL > 0 + && Server.KEEPALIVE_CLIENT_COUNT_MAX >= 0) { + kaMgr = new KeepaliveManager(Server.KEEPALIVE_INTERVAL, + Server.KEEPALIVE_CLIENT_INTERVAL, + Server.KEEPALIVE_CLIENT_COUNT_MAX); + } + + var self = this; + + EventEmitter.call(this); + + if (typeof listener === 'function') + self.on('connection', listener); + + var streamcfg = { + algorithms: algorithms, + hostKeys: hostKeys, + server: true + }; + var keys; + var len; + for (i = 0, keys = Object.keys(cfg), len = keys.length; i < len; ++i) { + var key = keys[i]; + if (key === 'privateKey' + || key === 'publicKey' + || key === 'passphrase' + || key === 'algorithms' + || key === 'hostKeys' + || key === 'server') { + continue; + } + streamcfg[key] = cfg[key]; + } + + if (typeof streamcfg.debug === 'function') { + var oldDebug = streamcfg.debug; + var cfgKeys = Object.keys(streamcfg); + } + + this._srv = new net.Server(function(socket) { + if (self._connections >= self.maxConnections) { + socket.destroy(); + return; + } + ++self._connections; + socket.once('close', function(had_err) { + --self._connections; + + // since joyent/node#993bb93e0a, we have to "read past EOF" in order to + // get an `end` event on streams. thankfully adding this does not + // negatively affect node versions pre-joyent/node#993bb93e0a. + sshstream.read(); + }).on('error', function(err) { + sshstream.reset(); + sshstream.emit('error', err); + }); + + var conncfg = streamcfg; + + // prepend debug output with a unique identifier in case there are multiple + // clients connected at the same time + if (oldDebug) { + conncfg = {}; + for (var i = 0, key; i < cfgKeys.length; ++i) { + key = cfgKeys[i]; + conncfg[key] = streamcfg[key]; + } + var debugPrefix = '[' + process.hrtime().join('.') + '] '; + conncfg.debug = function(msg) { + oldDebug(debugPrefix + msg); + }; + } + + var sshstream = new SSH2Stream(conncfg); + var client = new Client(sshstream, socket); + + socket.pipe(sshstream).pipe(socket); + + // silence pre-header errors + function onClientPreHeaderError(err) {} + client.on('error', onClientPreHeaderError); + + sshstream.once('header', function(header) { + if (sshstream._readableState.ended) { + // already disconnected internally in SSH2Stream due to incompatible + // protocol version + return; + } else if (!listenerCount(self, 'connection')) { + // auto reject + return sshstream.disconnect(DISCONNECT_REASON.BY_APPLICATION); + } + + client.removeListener('error', onClientPreHeaderError); + + self.emit('connection', + client, + { ip: socket.remoteAddress, header: header }); + }); + }).on('error', function(err) { + self.emit('error', err); + }).on('listening', function() { + self.emit('listening'); + }).on('close', function() { + self.emit('close'); + }); + this._connections = 0; + this.maxConnections = Infinity; +} +inherits(Server, EventEmitter); + +Server.prototype.listen = function() { + this._srv.listen.apply(this._srv, arguments); + return this; +}; + +Server.prototype.address = function() { + return this._srv.address(); +}; + +Server.prototype.getConnections = function(cb) { + this._srv.getConnections(cb); +}; + +Server.prototype.close = function(cb) { + this._srv.close(cb); + return this; +}; + +Server.prototype.ref = function() { + this._srv.ref(); +}; + +Server.prototype.unref = function() { + this._srv.unref(); +}; + + +function Client(stream, socket) { + EventEmitter.call(this); + + var self = this; + + this._sshstream = stream; + var channels = this._channels = {}; + this._curChan = -1; + this._sock = socket; + this.noMoreSessions = false; + this.authenticated = false; + + stream.on('end', function() { + self.emit('end'); + }).on('close', function(hasErr) { + self.emit('close', hasErr); + }).on('error', function(err) { + self.emit('error', err); + }).on('drain', function() { + self.emit('drain'); + }).on('continue', function() { + self.emit('continue'); + }); + + var exchanges = 0; + var acceptedAuthSvc = false; + var pendingAuths = []; + var authCtx; + + // begin service/auth-related ================================================ + stream.on('SERVICE_REQUEST', function(service) { + if (exchanges === 0 + || acceptedAuthSvc + || self.authenticated + || service !== 'ssh-userauth') + return stream.disconnect(DISCONNECT_REASON.SERVICE_NOT_AVAILABLE); + + acceptedAuthSvc = true; + stream.serviceAccept(service); + }).on('USERAUTH_REQUEST', onUSERAUTH_REQUEST); + function onUSERAUTH_REQUEST(username, service, method, methodData) { + if (exchanges === 0 + || (authCtx + && (authCtx.username !== username || authCtx.service !== service)) + // TODO: support hostbased auth + || (method !== 'password' + && method !== 'publickey' + && method !== 'hostbased' + && method !== 'keyboard-interactive' + && method !== 'none') + || pendingAuths.length === MAX_PENDING_AUTHS) + return stream.disconnect(DISCONNECT_REASON.PROTOCOL_ERROR); + else if (service !== 'ssh-connection') + return stream.disconnect(DISCONNECT_REASON.SERVICE_NOT_AVAILABLE); + + // XXX: this really shouldn't be reaching into private state ... + stream._state.authMethod = method; + + var ctx; + if (method === 'keyboard-interactive') { + ctx = new KeyboardAuthContext(stream, username, service, method, + methodData, onAuthDecide); + } else if (method === 'publickey') { + ctx = new PKAuthContext(stream, username, service, method, methodData, + onAuthDecide); + } else if (method === 'hostbased') { + ctx = new HostbasedAuthContext(stream, username, service, method, + methodData, onAuthDecide); + } else if (method === 'password') { + ctx = new PwdAuthContext(stream, username, service, method, methodData, + onAuthDecide); + } else if (method === 'none') + ctx = new AuthContext(stream, username, service, method, onAuthDecide); + + if (authCtx) { + if (!authCtx._initialResponse) + return pendingAuths.push(ctx); + else if (authCtx._multistep && !this._finalResponse) { + // RFC 4252 says to silently abort the current auth request if a new + // auth request comes in before the final response from an auth method + // that requires additional request/response exchanges -- this means + // keyboard-interactive for now ... + authCtx._cleanup && authCtx._cleanup(); + authCtx.emit('abort'); + } + } + + authCtx = ctx; + + if (listenerCount(self, 'authentication')) + self.emit('authentication', authCtx); + else + authCtx.reject(); + } + function onAuthDecide(ctx, allowed, methodsLeft, isPartial) { + if (authCtx === ctx && !self.authenticated) { + if (allowed) { + stream.removeListener('USERAUTH_REQUEST', onUSERAUTH_REQUEST); + authCtx = undefined; + self.authenticated = true; + stream.authSuccess(); + pendingAuths = []; + self.emit('ready'); + } else { + stream.authFailure(methodsLeft, isPartial); + if (pendingAuths.length) { + authCtx = pendingAuths.pop(); + if (listenerCount(self, 'authentication')) + self.emit('authentication', authCtx); + else + authCtx.reject(); + } + } + } + } + // end service/auth-related ================================================== + + var unsentGlobalRequestsReplies = []; + + function sendReplies() { + var reply; + while (unsentGlobalRequestsReplies.length > 0 + && unsentGlobalRequestsReplies[0].type) { + reply = unsentGlobalRequestsReplies.shift(); + if (reply.type === 'SUCCESS') + stream.requestSuccess(reply.buf); + if (reply.type === 'FAILURE') + stream.requestFailure(); + } + } + + stream.on('GLOBAL_REQUEST', function(name, wantReply, data) { + var reply = { + type: null, + buf: null + }; + + function setReply(type, buf) { + reply.type = type; + reply.buf = buf; + sendReplies(); + } + + if (wantReply) + unsentGlobalRequestsReplies.push(reply); + + if ((name === 'tcpip-forward' + || name === 'cancel-tcpip-forward' + || name === 'no-more-sessions@openssh.com' + || name === 'streamlocal-forward@openssh.com' + || name === 'cancel-streamlocal-forward@openssh.com') + && listenerCount(self, 'request') + && self.authenticated) { + var accept; + var reject; + + if (wantReply) { + var replied = false; + accept = function(chosenPort) { + if (replied) + return; + replied = true; + var bufPort; + if (name === 'tcpip-forward' + && data.bindPort === 0 + && typeof chosenPort === 'number') { + bufPort = new Buffer(4); + bufPort.writeUInt32BE(chosenPort, 0, true); + } + setReply('SUCCESS', bufPort); + }; + reject = function() { + if (replied) + return; + replied = true; + setReply('FAILURE'); + }; + } + + if (name === 'no-more-sessions@openssh.com') { + self.noMoreSessions = true; + accept && accept(); + return; + } + + self.emit('request', accept, reject, name, data); + } else if (wantReply) + setReply('FAILURE'); + }); + + stream.on('CHANNEL_OPEN', function(info) { + // do early reject in some cases to prevent wasteful channel allocation + if ((info.type === 'session' && self.noMoreSessions) + || !self.authenticated) { + var reasonCode = CHANNEL_OPEN_FAILURE.ADMINISTRATIVELY_PROHIBITED; + return stream.channelOpenFail(info.sender, reasonCode); + } + + var localChan = nextChannel(self); + var accept; + var reject; + var replied = false; + if (localChan === false) { + // auto-reject due to no channels available + return stream.channelOpenFail(info.sender, + CHANNEL_OPEN_FAILURE.RESOURCE_SHORTAGE); + } + + // be optimistic, reserve channel to prevent another request from trying to + // take the same channel + channels[localChan] = true; + + reject = function() { + if (replied) + return; + + replied = true; + + delete channels[localChan]; + + var reasonCode = CHANNEL_OPEN_FAILURE.ADMINISTRATIVELY_PROHIBITED; + return stream.channelOpenFail(info.sender, reasonCode); + }; + + switch (info.type) { + case 'session': + if (listenerCount(self, 'session')) { + accept = function() { + if (replied) + return; + + replied = true; + + stream.channelOpenConfirm(info.sender, + localChan, + Channel.MAX_WINDOW, + Channel.PACKET_SIZE); + + return new Session(self, info, localChan); + }; + + self.emit('session', accept, reject); + } else + reject(); + break; + case 'direct-tcpip': + if (listenerCount(self, 'tcpip')) { + accept = function() { + if (replied) + return; + + replied = true; + + stream.channelOpenConfirm(info.sender, + localChan, + Channel.MAX_WINDOW, + Channel.PACKET_SIZE); + + var chaninfo = { + type: undefined, + incoming: { + id: localChan, + window: Channel.MAX_WINDOW, + packetSize: Channel.PACKET_SIZE, + state: 'open' + }, + outgoing: { + id: info.sender, + window: info.window, + packetSize: info.packetSize, + state: 'open' + } + }; + + return new Channel(chaninfo, self); + }; + + self.emit('tcpip', accept, reject, info.data); + } else + reject(); + break; + case 'direct-streamlocal@openssh.com': + if (listenerCount(self, 'openssh.streamlocal')) { + accept = function() { + if (replied) + return; + + replied = true; + + stream.channelOpenConfirm(info.sender, + localChan, + Channel.MAX_WINDOW, + Channel.PACKET_SIZE); + + var chaninfo = { + type: undefined, + incoming: { + id: localChan, + window: Channel.MAX_WINDOW, + packetSize: Channel.PACKET_SIZE, + state: 'open' + }, + outgoing: { + id: info.sender, + window: info.window, + packetSize: info.packetSize, + state: 'open' + } + }; + + return new Channel(chaninfo, self); + }; + + self.emit('openssh.streamlocal', accept, reject, info.data); + } else + reject(); + break; + default: + // auto-reject unsupported channel types + reject(); + } + }); + + stream.on('NEWKEYS', function() { + if (++exchanges > 1) + self.emit('rekey'); + }); + + if (kaMgr) { + this.once('ready', function() { + kaMgr.add(stream); + }); + } +} +inherits(Client, EventEmitter); + +Client.prototype.end = function() { + return this._sshstream.disconnect(DISCONNECT_REASON.BY_APPLICATION); +}; + +Client.prototype.x11 = function(originAddr, originPort, cb) { + var opts = { + originAddr: originAddr, + originPort: originPort + }; + return openChannel(this, 'x11', opts, cb); +}; + +Client.prototype.forwardOut = function(boundAddr, boundPort, remoteAddr, + remotePort, cb) { + var opts = { + boundAddr: boundAddr, + boundPort: boundPort, + remoteAddr: remoteAddr, + remotePort: remotePort + }; + return openChannel(this, 'forwarded-tcpip', opts, cb); +}; + +Client.prototype.openssh_forwardOutStreamLocal = function(socketPath, cb) { + var opts = { + socketPath: socketPath + }; + return openChannel(this, 'forwarded-streamlocal@openssh.com', opts, cb); +}; + +Client.prototype.rekey = function(cb) { + var stream = this._sshstream; + var ret = true; + var error; + + try { + ret = stream.rekey(); + } catch (ex) { + error = ex; + } + + // TODO: re-throw error if no callback? + + if (typeof cb === 'function') { + if (error) { + process.nextTick(function() { + cb(error); + }); + } else + this.once('rekey', cb); + } + + return ret; +}; + +function Session(client, info, localChan) { + this.subtype = undefined; + + var ending = false; + var self = this; + var outgoingId = info.sender; + var channel; + + var chaninfo = { + type: 'session', + incoming: { + id: localChan, + window: Channel.MAX_WINDOW, + packetSize: Channel.PACKET_SIZE, + state: 'open' + }, + outgoing: { + id: info.sender, + window: info.window, + packetSize: info.packetSize, + state: 'open' + } + }; + + function onREQUEST(info) { + var replied = false; + var accept; + var reject; + + if (info.wantReply) { + // "real session" requests will have custom accept behaviors + if (info.request !== 'shell' + && info.request !== 'exec' + && info.request !== 'subsystem') { + accept = function() { + if (replied || ending || channel) + return; + + replied = true; + + return client._sshstream.channelSuccess(outgoingId); + }; + } + + reject = function() { + if (replied || ending || channel) + return; + + replied = true; + + return client._sshstream.channelFailure(outgoingId); + }; + } + + if (ending) { + reject && reject(); + return; + } + + switch (info.request) { + // "pre-real session start" requests + case 'env': + if (listenerCount(self, 'env')) { + self.emit('env', accept, reject, { + key: info.key, + val: info.val + }); + } else + reject && reject(); + break; + case 'pty-req': + if (listenerCount(self, 'pty')) { + self.emit('pty', accept, reject, { + cols: info.cols, + rows: info.rows, + width: info.width, + height: info.height, + term: info.term, + modes: info.modes, + }); + } else + reject && reject(); + break; + case 'window-change': + if (listenerCount(self, 'window-change')) { + self.emit('window-change', accept, reject, { + cols: info.cols, + rows: info.rows, + width: info.width, + height: info.height + }); + } else + reject && reject(); + break; + case 'x11-req': + if (listenerCount(self, 'x11')) { + self.emit('x11', accept, reject, { + single: info.single, + protocol: info.protocol, + cookie: info.cookie, + screen: info.screen + }); + } else + reject && reject(); + break; + // "post-real session start" requests + case 'signal': + if (listenerCount(self, 'signal')) { + self.emit('signal', accept, reject, { + name: info.signal + }); + } else + reject && reject(); + break; + // XXX: is `auth-agent-req@openssh.com` really "post-real session start"? + case 'auth-agent-req@openssh.com': + if (listenerCount(self, 'auth-agent')) + self.emit('auth-agent', accept, reject); + else + reject && reject(); + break; + // "real session start" requests + case 'shell': + if (listenerCount(self, 'shell')) { + accept = function() { + if (replied || ending || channel) + return; + + replied = true; + + if (info.wantReply) + client._sshstream.channelSuccess(outgoingId); + + channel = new Channel(chaninfo, client, { server: true }); + + channel.subtype = self.subtype = info.request; + + return channel; + }; + + self.emit('shell', accept, reject); + } else + reject && reject(); + break; + case 'exec': + if (listenerCount(self, 'exec')) { + accept = function() { + if (replied || ending || channel) + return; + + replied = true; + + if (info.wantReply) + client._sshstream.channelSuccess(outgoingId); + + channel = new Channel(chaninfo, client, { server: true }); + + channel.subtype = self.subtype = info.request; + + return channel; + }; + + self.emit('exec', accept, reject, { + command: info.command + }); + } else + reject && reject(); + break; + case 'subsystem': + accept = function() { + if (replied || ending || channel) + return; + + replied = true; + + if (info.wantReply) + client._sshstream.channelSuccess(outgoingId); + + channel = new Channel(chaninfo, client, { server: true }); + + channel.subtype = self.subtype = (info.request + ':' + info.subsystem); + + if (info.subsystem === 'sftp') { + var sftp = new SFTPStream({ + server: true, + debug: client._sshstream.debug + }); + channel.pipe(sftp).pipe(channel); + + return sftp; + } else + return channel; + }; + + if (info.subsystem === 'sftp' && listenerCount(self, 'sftp')) + self.emit('sftp', accept, reject); + else if (info.subsystem !== 'sftp' && listenerCount(self, 'subsystem')) { + self.emit('subsystem', accept, reject, { + name: info.subsystem + }); + } else + reject && reject(); + break; + default: + reject && reject(); + } + } + function onEOF() { + ending = true; + self.emit('eof'); + self.emit('end'); + } + function onCLOSE() { + ending = true; + self.emit('close'); + } + client._sshstream + .on('CHANNEL_REQUEST:' + localChan, onREQUEST) + .once('CHANNEL_EOF:' + localChan, onEOF) + .once('CHANNEL_CLOSE:' + localChan, onCLOSE); +} +inherits(Session, EventEmitter); + + +function AuthContext(stream, username, service, method, cb) { + EventEmitter.call(this); + + var self = this; + + this.username = this.user = username; + this.service = service; + this.method = method; + this._initialResponse = false; + this._finalResponse = false; + this._multistep = false; + this._cbfinal = function(allowed, methodsLeft, isPartial) { + if (!self._finalResponse) { + self._finalResponse = true; + cb(self, allowed, methodsLeft, isPartial); + } + }; + this._stream = stream; +} +inherits(AuthContext, EventEmitter); +AuthContext.prototype.accept = function() { + this._cleanup && this._cleanup(); + this._initialResponse = true; + this._cbfinal(true); +}; +AuthContext.prototype.reject = function(methodsLeft, isPartial) { + this._cleanup && this._cleanup(); + this._initialResponse = true; + this._cbfinal(false, methodsLeft, isPartial); +}; + +var RE_KBINT_SUBMETHODS = /[ \t\r\n]*,[ \t\r\n]*/g; +function KeyboardAuthContext(stream, username, service, method, submethods, cb) { + AuthContext.call(this, stream, username, service, method, cb); + this._multistep = true; + + var self = this; + + this._cb = undefined; + this._onInfoResponse = function(responses) { + if (self._cb) { + var callback = self._cb; + self._cb = undefined; + callback(responses); + } + }; + this.submethods = submethods.split(RE_KBINT_SUBMETHODS); + this.on('abort', function() { + self._cb && self._cb(new Error('Authentication request aborted')); + }); +} +inherits(KeyboardAuthContext, AuthContext); +KeyboardAuthContext.prototype._cleanup = function() { + this._stream.removeListener('USERAUTH_INFO_RESPONSE', this._onInfoResponse); +}; +KeyboardAuthContext.prototype.prompt = function(prompts, title, instructions, + cb) { + if (!Array.isArray(prompts)) + prompts = [ prompts ]; + + if (typeof title === 'function') { + cb = title; + title = instructions = undefined; + } else if (typeof instructions === 'function') { + cb = instructions; + instructions = undefined; + } + + for (var i = 0; i < prompts.length; ++i) { + if (typeof prompts[i] === 'string') { + prompts[i] = { + prompt: prompts[i], + echo: true + }; + } + } + + this._cb = cb; + this._initialResponse = true; + this._stream.once('USERAUTH_INFO_RESPONSE', this._onInfoResponse); + + return this._stream.authInfoReq(title, instructions, prompts); +}; + +function PKAuthContext(stream, username, service, method, pkInfo, cb) { + AuthContext.call(this, stream, username, service, method, cb); + + this.key = { algo: pkInfo.keyAlgo, data: pkInfo.key }; + this.signature = pkInfo.signature; + var sigAlgo; + if (this.signature) { + switch (pkInfo.keyAlgo) { + case 'ssh-rsa': + sigAlgo = 'RSA-SHA1'; + break; + case 'ssh-dss': + sigAlgo = 'DSA-SHA1'; + break; + case 'ecdsa-sha2-nistp256': + sigAlgo = 'sha256'; + break; + case 'ecdsa-sha2-nistp384': + sigAlgo = 'sha384'; + break; + case 'ecdsa-sha2-nistp521': + sigAlgo = 'sha512'; + break; + } + } + this.sigAlgo = sigAlgo; + this.blob = pkInfo.blob; +} +inherits(PKAuthContext, AuthContext); +PKAuthContext.prototype.accept = function() { + if (!this.signature) { + this._initialResponse = true; + this._stream.authPKOK(this.key.algo, this.key.data); + } else + AuthContext.prototype.accept.call(this); +}; + +function HostbasedAuthContext(stream, username, service, method, pkInfo, cb) { + AuthContext.call(this, stream, username, service, method, cb); + + this.key = { algo: pkInfo.keyAlgo, data: pkInfo.key }; + this.signature = pkInfo.signature; + var sigAlgo; + if (this.signature) { + switch (pkInfo.keyAlgo) { + case 'ssh-rsa': + sigAlgo = 'RSA-SHA1'; + break; + case 'ssh-dss': + sigAlgo = 'DSA-SHA1'; + break; + case 'ecdsa-sha2-nistp256': + sigAlgo = 'sha256'; + break; + case 'ecdsa-sha2-nistp384': + sigAlgo = 'sha384'; + break; + case 'ecdsa-sha2-nistp521': + sigAlgo = 'sha512'; + break; + } + } + this.sigAlgo = sigAlgo; + this.blob = pkInfo.blob; + this.localHostname = pkInfo.localHostname; + this.localUsername = pkInfo.localUsername; +} +inherits(HostbasedAuthContext, AuthContext); + +function PwdAuthContext(stream, username, service, method, password, cb) { + AuthContext.call(this, stream, username, service, method, cb); + + this.password = password; +} +inherits(PwdAuthContext, AuthContext); + + +function openChannel(self, type, opts, cb) { + // ask the client to open a channel for some purpose + // (e.g. a forwarded TCP connection) + var localChan = nextChannel(self); + var initWindow = Channel.MAX_WINDOW; + var maxPacket = Channel.PACKET_SIZE; + var ret = true; + + if (localChan === false) + return cb(new Error('No free channels available')); + + if (typeof opts === 'function') { + cb = opts; + opts = {}; + } + + self._channels[localChan] = true; + + var sshstream = self._sshstream; + sshstream.once('CHANNEL_OPEN_CONFIRMATION:' + localChan, function(info) { + sshstream.removeAllListeners('CHANNEL_OPEN_FAILURE:' + localChan); + + var chaninfo = { + type: type, + incoming: { + id: localChan, + window: initWindow, + packetSize: maxPacket, + state: 'open' + }, + outgoing: { + id: info.sender, + window: info.window, + packetSize: info.packetSize, + state: 'open' + } + }; + cb(undefined, new Channel(chaninfo, self, { server: true })); + }).once('CHANNEL_OPEN_FAILURE:' + localChan, function(info) { + sshstream.removeAllListeners('CHANNEL_OPEN_CONFIRMATION:' + localChan); + + delete self._channels[localChan]; + + var err = new Error('(SSH) Channel open failure: ' + info.description); + err.reason = info.reason; + err.lang = info.lang; + cb(err); + }); + + if (type === 'forwarded-tcpip') + ret = sshstream.forwardedTcpip(localChan, initWindow, maxPacket, opts); + else if (type === 'x11') + ret = sshstream.x11(localChan, initWindow, maxPacket, opts); + else if (type === 'forwarded-streamlocal@openssh.com') { + ret = sshstream.openssh_forwardedStreamLocal(localChan, + initWindow, + maxPacket, + opts); + } + + return ret; +} + +function nextChannel(self) { + // get the next available channel number + + // fast path + if (self._curChan < MAX_CHANNEL) + return ++self._curChan; + + // slower lookup path + for (var i = 0, channels = self._channels; i < MAX_CHANNEL; ++i) + if (!channels[i]) + return i; + + return false; +} + + +Server.createServer = function(cfg, listener) { + return new Server(cfg, listener); +}; +Server.KEEPALIVE_INTERVAL = 1000; +Server.KEEPALIVE_CLIENT_INTERVAL = 15000; +Server.KEEPALIVE_CLIENT_COUNT_MAX = 3; + +module.exports = Server; diff --git a/node_modules/ssh2/lib/utils.js b/node_modules/ssh2/lib/utils.js new file mode 100644 index 0000000..f513b95 --- /dev/null +++ b/node_modules/ssh2/lib/utils.js @@ -0,0 +1,5 @@ +exports.spliceOne = function(list, index) { + for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) + list[i] = list[k]; + list.pop(); +}; diff --git a/node_modules/ssh2/package.json b/node_modules/ssh2/package.json new file mode 100644 index 0000000..6335832 --- /dev/null +++ b/node_modules/ssh2/package.json @@ -0,0 +1,105 @@ +{ + "_args": [ + [ + { + "raw": "ssh2@^0.5.0", + "scope": null, + "escapedName": "ssh2", + "name": "ssh2", + "rawSpec": "^0.5.0", + "spec": ">=0.5.0 <0.6.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt-sftp-deploy" + ] + ], + "_from": "ssh2@>=0.5.0 <0.6.0", + "_id": "ssh2@0.5.4", + "_inCache": true, + "_location": "/ssh2", + "_nodeVersion": "6.9.1", + "_npmOperationalInternal": { + "host": "packages-18-east.internal.npmjs.com", + "tmp": "tmp/ssh2-0.5.4.tgz_1478644008315_0.4939819877035916" + }, + "_npmUser": { + "name": "mscdex", + "email": "mscdex@mscdex.net" + }, + "_npmVersion": "3.10.8", + "_phantomChildren": {}, + "_requested": { + "raw": "ssh2@^0.5.0", + "scope": null, + "escapedName": "ssh2", + "name": "ssh2", + "rawSpec": "^0.5.0", + "spec": ">=0.5.0 <0.6.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt-sftp-deploy" + ], + "_resolved": "https://registry.npmjs.org/ssh2/-/ssh2-0.5.4.tgz", + "_shasum": "1bf6b6b28c96eaef267f4d6c46a5a2517a599e27", + "_shrinkwrap": null, + "_spec": "ssh2@^0.5.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt-sftp-deploy", + "author": { + "name": "Brian White", + "email": "mscdex@mscdex.net" + }, + "bugs": { + "url": "https://github.com/mscdex/ssh2/issues" + }, + "dependencies": { + "ssh2-streams": "~0.1.15" + }, + "description": "SSH2 client and server modules written in pure JavaScript for node.js", + "devDependencies": { + "semver": "^5.1.0" + }, + "directories": {}, + "dist": { + "shasum": "1bf6b6b28c96eaef267f4d6c46a5a2517a599e27", + "tarball": "https://registry.npmjs.org/ssh2/-/ssh2-0.5.4.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "homepage": "https://github.com/mscdex/ssh2#readme", + "keywords": [ + "ssh", + "ssh2", + "sftp", + "secure", + "shell", + "exec", + "remote", + "client" + ], + "licenses": [ + { + "type": "MIT", + "url": "http://github.com/mscdex/ssh2/raw/master/LICENSE" + } + ], + "main": "./lib/client", + "maintainers": [ + { + "name": "mscdex", + "email": "mscdex@mscdex.net" + } + ], + "name": "ssh2", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/mscdex/ssh2.git" + }, + "scripts": { + "test": "node test/test.js" + }, + "version": "0.5.4" +} diff --git a/node_modules/ssh2/test/fixtures/bad_rsa_private_key b/node_modules/ssh2/test/fixtures/bad_rsa_private_key new file mode 100644 index 0000000..80fdc87 --- /dev/null +++ b/node_modules/ssh2/test/fixtures/bad_rsa_private_key @@ -0,0 +1,26 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAz7MF4vhgw6HxNf3KtVf3VULTYgrRSlv+cCZdB1xxI1p/nGyu +/eekUn5C+mGeDS488DX5ulzicxVpL7pamc/tFNcp91MrR7PiIMK2l+bwbZJubbLj +DHhNcBklnFOSKxtmQRfuorGakpy/kXmIxF5of0xXGns6DlHRq9dGCJIXvrkqhcEb +k4n2y4aV4VOiMHdo6FrFQVPzA8DlbJP2SjIFZ/0VdK7O7eiyiqV1p1xlbTQQ5rAX +LdsshBn/GvoBOTCVupMXurn2582vgGh26Mmovj2QGzScMGUVttkMlnxUmKT/aQka +mC0vR54QOW7lyWPjAitOV0qgmtGm3/cl7W7NjwIDAQABAoIBAFxH0C+951BEXWV9 +s1jLEqshG8YNxFtjcDLn+KFSoznv9Y7MgxtwlgPI8X1Jbe2xQ4X+lUwGBN7Y/nkk +NSjtxwphZtXqb+pVs/yWRoZLJzunucSnnFVoBg/uPFWuk9zvOYlmVrKWcnT9i+fY +tbl5sLgOdQzg/zRpidztssIQFti3o2jnpyrEGcepPWLkfCgqPfGmNv78BAIt/6iT +zYDB4GMSq/LnPTIOFsIOvlkZg3RCcLWeAPRC+lvFQVY+M/uJL5WIbA5il1IMMKH7 +MULWpRO3lnb1JVrkZlBldK5uew6AN3tHDQOmg+C2JuIbOZ35J9dcnwsE+IptWWBj +XiFRJCECgYEA8BeuufkslureqOycaPLMkqchMTue1OxbLJFvPN+dh/cW6Lng3b8+ +xAyzZrc0vccH/jl9WVHhIZ7TcKXDzSmmrtnZ/3m1c4gANGqIPwO+emL1ZzzkIKGd +FrLeBZKP4TWry9kjg4cG1SKGpcB5ngJMPXUxMZNe74tC4Hk820PkFjcCgYEA3XXn +ngRCgH9N1eKSD2daxxlBhTTSnTgjU+dDaDFQzPIhJCcS8HwyQBQmNTOSXXK9sShC +fdXAsmiBby5WEBq/K5+cXeDG2ZlFLyPovEgTUrLgraw42PYs0+A8Ls7dFk7PuMez +3G2gUPkY039JiyXKfcog9/dIRfbWCwzQ6s7TV2kCgYEArsme81cahhgg1zvCNokk +M1Omz2/HFt2nFpAeOmPVDGnu7Kh9sxGKgTF53bpclBh0kjiKL99zFYXKCoUzQYYk +CcEhemLBnYUSGRbBb5arMfAfFfR3Y+YkNaUsC0SCqILpOfMvbo57g+ipu7ufDlA/ +7rIFiUDvaVap7j909W+8egsCgYEAsuc/0DBixMmSyHl7QwRcmkC15HVSu32RVIOb +ub01KAtmaH1EWJAMTCW64/mggOtjgI0kgeE/BSFVhsqo7eOdkhEj0db27OxbroRU +zF1xdrpYtRRO7D6a4iLgm3OzuQS72+tASo8pFqDUxG6sq8NAvLOgRJE4ioSoT07w +KvAgXRkCgYEAmWgcsX/BdNcKOteSDtPkys5NRtWCBz7Coxb+xXXoXz1FVegBolpY +wXVePvXTIbU8VJOLunMyH5wpmMUiJbTX9v2o/yfpsH0ci4GaAeVtqpA= +-----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/node_modules/ssh2/test/fixtures/id_dsa b/node_modules/ssh2/test/fixtures/id_dsa new file mode 100644 index 0000000..d9c9b5b --- /dev/null +++ b/node_modules/ssh2/test/fixtures/id_dsa @@ -0,0 +1,12 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIBuwIBAAKBgQC3/2VIGHgqHuxvhPa6rryqqLy6sQmjeSIwyrIW5F/o8W4sz/mE +0noDSW4PaoXjgPQv5egj1EByws6dMOUqLaZHNWNn+Lh/jkKlwKyhbSCAjqoWH3v3 +uI1j58GO/eZ2+REijfyA0XJxdm7kqEexxbg0UpFr1F/eLBUxpLIbhhS1cwIVAKcB +B9DnAObuPJGTwYTCaIIBQDy9AoGAJicW0pIFwgoTYsIeywmUQopJ3FQ4M3eDwQ0U +T33pzWvBZFN2OsUDTFg64PNm9ow09wk042qMg168eKCUTp2iR/Y9R4xTj8dls8iv +aMGMZ/B32eURIjUREGiXYTyG1pfuB2znSvr/5pavhuz5yG9M0AJCiYiexdaQKO3N +oJp6T3ACgYEAsep79p4WljnawrJc928zGq6dLYjs+5apYhqx4vf2l3Z2u26VqVNG +i5zZkUzhWQYV3/qtEOpO43dyZTHW+d9L8ni6HbXFWRVx60WE+5WKkzkimHJ6gox2 +kDvOqPudiS34KJOCEYYLEnJmK8aUZBZzWFORXkN8QgA/h9ts8AU785UCFAVXZMWq +CteWCH2HzcY2x/65dMwL +-----END DSA PRIVATE KEY----- diff --git a/node_modules/ssh2/test/fixtures/id_ecdsa b/node_modules/ssh2/test/fixtures/id_ecdsa new file mode 100644 index 0000000..036e3b6 --- /dev/null +++ b/node_modules/ssh2/test/fixtures/id_ecdsa @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIPMZuWP7fMsZeyC1XXVUALVebJOX7PTwmsPql9qG25SeoAoGCCqGSM49 +AwEHoUQDQgAEB/B6mC5lrekKPWfGEkKpnCk08+dRnzFUg2jUHpaIrOTt4jGdvq6T +yAN57asB+PYmFyVIpi35NcmicF18qX3ayg== +-----END EC PRIVATE KEY----- diff --git a/node_modules/ssh2/test/fixtures/id_rsa b/node_modules/ssh2/test/fixtures/id_rsa new file mode 100644 index 0000000..90a6f72 --- /dev/null +++ b/node_modules/ssh2/test/fixtures/id_rsa @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDL0yFO4W4xbdrJk/i+CW3itPATvhRkS+x+gKmkdH739AqWYP6r +kTFAmFTw9gLJ/c2tN7ow0T0QUR9iUsv/3QzTuwsjBu0feo3CVxwMkaJTo5ks9XBo +OW0R3tyCcOLlAcQ1WjC7cv5Ifn4gXLLM+k8/y/m3u8ERtidNxbRqpQ/gPQIDAQAB +AoGABirSRC/ABNDdIOJQUXe5knWFGiPTPCGr+zvrZiV8PgZtV5WBvzE6e0jgsRXQ +icobMhWQla+PGHJL786vi4NlwuhwKcF7Pd908ofej1eeBOd1u/HQ/qsfxPdxI0zF +dcWPYgAOo9ydOMGcSx4v1zDIgFInELJzKbv64LJQD0/xhoUCQQD7KhJ7M8Nkwsr2 +iKCyWTFM2M8/VKltgaiSmsNKZETashk5tKOrM3EWX4RcB/DnvHe8VNyYpC6Sd1uQ +AHwPDfxDAkEAz7+7hDybH6Cfvmr8kUOlDXiJJWXp5lP37FLzMDU6a9wTKZFnh57F +e91zRmKlQTegFet93MXaFYljRkI+4lMpfwJBAPPLbNEF973Qjq4rBMDZbs9HDDRO ++35+AqD7dGC7X1Jg2bd3rf66GiU7ZgDm/GIUQK0gOlg31bT6AniO39zFGH0CQFBh +Yd9HR8nT7xrQ8EoQPzNYGNBUf0xz3rAcZCWZ4rHK48sojEMoBkbnputrzX7PU+xH +QlqCXuAIWVXc2dHd1WcCQQDIUJHPOsgeAfTLoRRRURp/m8zZ9IpbaPTyDstPVNYe +zARW3Oa/tzPqdO6NWaetCp17u7Kb6X9np7Vz17i/4KED +-----END RSA PRIVATE KEY----- diff --git a/node_modules/ssh2/test/fixtures/id_rsa.ppk b/node_modules/ssh2/test/fixtures/id_rsa.ppk new file mode 100644 index 0000000..4504f18 --- /dev/null +++ b/node_modules/ssh2/test/fixtures/id_rsa.ppk @@ -0,0 +1,26 @@ +PuTTY-User-Key-File-2: ssh-rsa +Encryption: none +Comment: rsa-key-20150522 +Public-Lines: 6 +AAAAB3NzaC1yc2EAAAABJQAAAQB1quqP0rhl78NOLD4lj+1x5FGAqZ3aqo6GiEPz +KOaQmy86FuJMK0nHj3gUKTa/Kvaa+8PZyeu+uVseHg47YrynCOcJEEnpqvbArc8M +xMWuUnTUMrjvokGDOBBiQu4UAE4bybpgXkNHJfbrcDVgivmv3Ikn8PVIZ1rLBMLZ +6Lzn0rjPjFD0X4WqsAJW2SFiZnsjMZtVL2TWadNTyyfjjm2NCRBvd32VLohkSe9Q +BZBD6MW8YQyBKUnEF/7WNY0eehDVrfx1YqPOV1bDwFUhRaAYpLDLDR0KCAPvx7qb +8G5Cq0TIBsEr3H8ztNRcOTQoaKgn0T18M7cyS4ykoNLYW4Zx +Private-Lines: 14 +AAABACyF3DZraF3sBLXLjSL4MFSblHXfUHxAiPSiQzlpa/9dUCPRTrUJddzOgHZU +yJtcXU9mLm4VDRe7wZyxbSs6Hd5WZUGzIuLLEUH8k4hKdE/MLDSdkhV7qhX5iaij +tAeRaammRoVUGXTd7rnzGx2cXnnkvkZ22VmqkQ6MLg1DTmWNfOO9cdwFGdQawf/n +yUV0nTkWsHXy5Qrozq9wRFk8eyw+pFllxqavsNftZX8VDiQt27JLZPTU4LGkH660 +3gq1KhNS/l05TlXnMZGjlcPN8UEaBzmCWRezhJSttjs5Kgp1K3yDf4ozMR/HWOCj +Jq8fd3VIgli6ML8yjr/c0A0T9MUAAACBAL1/byxHiCvY/2C+/L5T+ZZq13jdZuYK +MmOFaNITgEdNGWSIFYRzhLKGXj7awQWOIW6chj470GNOfQjFL1TvXhbwfqW6esDa +kETOYQPYQHZijABcn7uurMUm/bu5x/z9gYkAfniOCI5vmvMvJ09JcZ0iUmFWDZZY +fAutBvrt+n/vAAAAgQCe9jrA51wn1/wzKmWF+2+OWFUG9usheIcEbHB8mxLguLfU ++x4i+2vLo0FtXEPAw+Bt7Tge4t0m6USiVZXtW/QKsh0kMj4mNVHFz+XXw4l1QOYv +n5TjnLepiP7majXv4GHI2eOcHkyly4sIkj4jNLYqvT86hMxW4IC+jtJEWhn/nwAA +AIEAlJ8cExu2WrWukTDJQHrVegtvdJUhNjol2wLucPuWwSxKuB8FHYwaPRYRkf3d +DkZ53hhjJZ0BVkAaQ28uqM09xKD+q1H4/r0nnbtlV4uHLl3cCD5mGrH8I/iDPJX4 +fFIqCa0+n1D6RzvDqs1QIu+PGSp0K6vHOOS5fP0ZpuT025E= +Private-MAC: 4ca26008c85b901f4d2766b0924c25e527678d7e diff --git a/node_modules/ssh2/test/fixtures/id_rsa_enc b/node_modules/ssh2/test/fixtures/id_rsa_enc new file mode 100644 index 0000000..75a1e95 --- /dev/null +++ b/node_modules/ssh2/test/fixtures/id_rsa_enc @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,CCE70744FB28F2EFB1D74377281A780C + +1WiGnqpSGXFIg+WYr7T2XN72C1YrNQ1jmRISb32TB/Rh2Zo47fjyQnv9impz8b6m +91R/qF7uCLI0fswvT5oqwn1L0vUAA0YtW/E2IQJEx5GPiaexoDJYYfu2yy036Kca +e9VtCajgrV+kycg1CknCxQKMcKXNq8Czvq66PM4Bzknek5hhdmxHxOl0QAE+8EXt +pnasOGz3szTUKkD6givwWgvDXY3BnVG46fXff99Xqgb6fx5IDbAkVKaxWIN/c81E +b0rcfyoLb7yjPgNYn9vUI6Z+24NMYUYARzb3dG5geaeX0BYb/VlCtJUsP0Rp2P2P +jl+cdvBKaeOvA9gPo/jAtSOFexQRs7AzKzoOLYU1fokd8HhqxOKAljn9ujmEqif7 +qcimk2s7ff6tSSlxtRzDP+Uq9d1u5tyaONRV2lwj+GdP1gRoOmdZL5chdvoAi0I8 +5eMf58hEuN2d4h4FryO6z7K+XQ9oo6/N/xHU0U/t2Pco9oY2L6oWMDxKwbfPhaD5 +CcoEElsK4XFArYDielEq9Y1sXaEuwR5I0ksDDsANp74r9Bhcqz60gJa6hVz0ouEU +QA67wV9+TRmulKRxwANvqxQwqPuxqcTPeJjXSUN/ZCaDwYmI+d1poxMx2fQzT82M +onlgOWq+3HbCotyoeFpCameymwDQzmrYdMBr7oWLgnOrxmJ89zDc6+jkHFgQJvnU +atyeVDqe866ZvvIGWS+r/EsDjV3cTW/cJvdsC+5BpnoXoVF4LqxE3LFbEbQBvqio +4enCZpspQSMOJra37vSofbD+DyI5Wd+y8SBmfDLjyDFhT0spW9aN99uFqSc3UElA +SAmnFmpYBFEQrRGpvpu5sC0c/YjZeRXr0/F1xPpIT1SWzpRsbcsWRBDzWjLOKWQx +8ytwc2QS7eKedfqkPWpYKW0Qtps+XgnGWA6PBX42IYhLsKANRfhFXQv5LPqLNNOn +3EsG9pd+0dBpfxFQfyyAKAUuvpJNgJ6kNx8VSj8Ppj8lyUdGa9YucgB02m7gHC9U +A4YyJsIcjo6IcrjM+ez1govRRS0nE8AUb8ups9tn8mdBwqcPCrgcJhV7JkOYNJYh +NAh0vgmneOq8LSVs2SRaL3uuLNbjh1LR9iViwbIY8kMQXkiXa2/V+PFwt5oqeX5f +2x3yzCeGBiQW10InyBBnKutbPD85R4YJhQ55bOMDSFfGGqwOU1QURiO1NUzf9n/2 ++E8VE7J/IQoO0TrJpC+EV0ROKME9W6+AvEFdmdIigbq3bkdEgSixyLnrhV8V8T4N +nbKlLoqfXt8DmT+h8XPzgsu0Fq/PNi6xBaiUsaN9tK6OP2ZVjr9ihbeLTI0rcKDr +XX2cWPvTcboRLt+S4wmqchMf7Kxa2PfX5Tf+KCcdZNQO4YqS23wQZgk61kuOQCsS +uOop+ICI7yWZkjqCOzGOeHLl/7FyFeprsFDIwD1g20y9bzibbJlbQPhwXSalqDQT +MWLH3rdFuvgLH7ujtjxSakES+VzkOhbnmb/Wypbl1D7P7GT2seau16EEGQDhDzcJ +Q4d/BjR2WqqxmC79MOAvUWAu6fZQjPD30/gYPGpMaEuiLrDlzDqvf+oi4A9+EtRL +-----END RSA PRIVATE KEY----- diff --git a/node_modules/ssh2/test/fixtures/ssh_host_dsa_key b/node_modules/ssh2/test/fixtures/ssh_host_dsa_key new file mode 100644 index 0000000..5448947 --- /dev/null +++ b/node_modules/ssh2/test/fixtures/ssh_host_dsa_key @@ -0,0 +1,12 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIBuwIBAAKBgQDEK+daQ7RuajwxkmBmogb0iUSi/w2RYKuvC2EiviBu3S2s9Bfq +gROKscAnURrxpTOa+iYeI7hRzfuX0qFmnFwXIjKJBjqBdg9r76UR5UNytnWQkJ5x +lxsZThMeAMw38SvmRMw15kkgxycKGqu4yvNLGyVwN02bPVjLcEVLWLCM1wIVAK50 +5JqF0nmGXFkcmNtxR24/mNXTAoGBAIc2p8C8b08OTQPmfZI+Wq8a+CuEr5R36bMW +TAs5etqmO2aVo5zvR0MnTjoS2ZDbuznDG9RiSuIB+ivr/daEwi+K+Ha8pZfYjXCG +ldzvmr5I4x8rkH3zyn7BADnc+/q3pa8AnZvTme5eNsxn1Pu/rmC/8KKnhmzRggqP +N8ORhoQQAoGAMCvoMcsDAui2d/WVpgHZZEFlxfbf4dPUPYb5zf2xOiMG9OK+Cbv3 +NaLZwk/Hd2g4L3nwTKDASxfmRcrbuaOg/d7aDjQ2mJz18Js4IjY34QpgLspGCNX/ +6rJSQ+ov1Z2Etr95N4Tzm3qpxW5BH9TTgaC/ntb9NRqIzNPCvAHXmlcCFBxgZpyb +4GUgmqhTOMtmBkJ7QpL9 +-----END DSA PRIVATE KEY----- diff --git a/node_modules/ssh2/test/fixtures/ssh_host_ecdsa_key b/node_modules/ssh2/test/fixtures/ssh_host_ecdsa_key new file mode 100644 index 0000000..0476442 --- /dev/null +++ b/node_modules/ssh2/test/fixtures/ssh_host_ecdsa_key @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEICrdbIIYmW/XTK9hxaQZZ56IGwG0NhqD2eppYUJNZsECoAoGCCqGSM49 +AwEHoUQDQgAEa+MuLv++3ft5HPFIsM2hQnmHPF12q08/MaHoGud4yqp3evyomjZN +xbsSb39fv8t6XX1u1rm5oHQcBV5Mqomaeg== +-----END EC PRIVATE KEY----- diff --git a/node_modules/ssh2/test/fixtures/ssh_host_rsa_key b/node_modules/ssh2/test/fixtures/ssh_host_rsa_key new file mode 100644 index 0000000..9c2cc6f --- /dev/null +++ b/node_modules/ssh2/test/fixtures/ssh_host_rsa_key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQC57UB/5H0M+t+mopksrltCCIXghryzofJjau+8tuMT9CG6ta3S +O9aKApJUUG/xtc88giVhB7HFABX/oob+jrkSthR8s/whULC8E+GhvOBjHydRUZIs +aPYOMBb42HcbOsgq3li/hwOcDk0vY00hZDKCum9BgvRAb7dPEkw2dmiCQQIDAQAB +AoGAMG+HOwoaLbR5aR64yrQNYBF6Vvii1iUdURr9o2r9kygpVUuZIcim5kMvPbnK +v+w+NaQt+q4XeJvCH1uG0W/69FwnphfaOVmCCUtsoJ6sU3fWr9x59MtKL2Llh8xR +50lz6R+eDXoYRDq245hG9BFn/bu0vtqQqx06mlZJcjaRocECQQDjdYFmr+DSww3x +VNx0G0DUkaQZZ+iqZiT3Zund2pcBB4aLiewOrqj0GFct4+YNzgxIXPejmS0eSokN +N2lC3NxZAkEA0UGjN5TG5/LEK3zcYtx2kpXryenrYORo1n2L/WPMZ0mjLQyd4LJr +ibfgVUfwX/kV3vgGYLwjpgcaTiMsecv4KQJAYMmMgZSPdz+WvD1e/WznXkyG5mSn +xXJngnrhQw0TulVodBIBR5IcxJli510VdIRcB6K/oXa5ky0mOmB8wv3WKQJBAKEF +PxE//KbzWhyUogm4180IbD4dMDCI0ltqlFRRfTJlqZi6wqnq4XFB+u/kwYU4aKoA +dPfvDgduI8HIsyqt17ECQDI/HC8PiYsDIOyVpQuQdIAsbGmoavK7X1MVEWR2nj9t +7BbUVFSnVKynL4TWIJZ6xP8WQwkDBQc5WjognHDaUTQ= +-----END RSA PRIVATE KEY----- diff --git a/node_modules/ssh2/test/test-client-server.js b/node_modules/ssh2/test/test-client-server.js new file mode 100644 index 0000000..f8d3854 --- /dev/null +++ b/node_modules/ssh2/test/test-client-server.js @@ -0,0 +1,1902 @@ +var Client = require('../lib/client'); +var Server = require('../lib/server'); +var OPEN_MODE = require('ssh2-streams').SFTPStream.OPEN_MODE; +var STATUS_CODE = require('ssh2-streams').SFTPStream.STATUS_CODE; +var utils = require('ssh2-streams').utils; + +var semver = require('semver'); + +var net = require('net'); +var fs = require('fs'); +var crypto = require('crypto'); +var path = require('path'); +var join = path.join; +var inspect = require('util').inspect; +var assert = require('assert'); + +var t = -1; +var group = path.basename(__filename, '.js') + '/'; +var fixturesdir = join(__dirname, 'fixtures'); + +var USER = 'nodejs'; +var PASSWORD = 'FLUXCAPACITORISTHEPOWER'; +var MD5_HOST_FINGERPRINT = '64254520742d3d0792e918f3ce945a64'; +var KEY_RSA_BAD = fs.readFileSync(join(fixturesdir, 'bad_rsa_private_key')); +var HOST_KEY_RSA = fs.readFileSync(join(fixturesdir, 'ssh_host_rsa_key')); +var HOST_KEY_DSA = fs.readFileSync(join(fixturesdir, 'ssh_host_dsa_key')); +var HOST_KEY_ECDSA = fs.readFileSync(join(fixturesdir, 'ssh_host_ecdsa_key')); +var CLIENT_KEY_ENC_RSA = fs.readFileSync(join(fixturesdir, 'id_rsa_enc')); +var CLIENT_KEY_ENC_RSA_PUB = utils.parseKey(CLIENT_KEY_ENC_RSA); +utils.decryptKey(CLIENT_KEY_ENC_RSA_PUB, 'foobarbaz'); +CLIENT_KEY_ENC_RSA_PUB = utils.genPublicKey(CLIENT_KEY_ENC_RSA_PUB); +var CLIENT_KEY_PPK_RSA = fs.readFileSync(join(fixturesdir, 'id_rsa.ppk')); +var CLIENT_KEY_PPK_RSA_PUB = utils.parseKey(CLIENT_KEY_PPK_RSA); +var CLIENT_KEY_RSA = fs.readFileSync(join(fixturesdir, 'id_rsa')); +var CLIENT_KEY_RSA_PUB = utils.genPublicKey(utils.parseKey(CLIENT_KEY_RSA)); +var CLIENT_KEY_DSA = fs.readFileSync(join(fixturesdir, 'id_dsa')); +var CLIENT_KEY_DSA_PUB = utils.genPublicKey(utils.parseKey(CLIENT_KEY_DSA)); +if (semver.gte(process.version, '5.2.0')) { + var CLIENT_KEY_ECDSA = fs.readFileSync(join(fixturesdir, 'id_ecdsa')); + var CLIENT_KEY_ECDSA_PUB = utils.genPublicKey( + utils.parseKey(CLIENT_KEY_ECDSA) + ); +} +var DEBUG = false; + +var tests = [ + { run: function() { + var client; + var server; + var r; + + r = setup( + this, + { username: USER, + privateKey: CLIENT_KEY_RSA + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + assert(ctx.method === 'publickey', + makeMsg('Unexpected auth method: ' + ctx.method)); + assert(ctx.username === USER, + makeMsg('Unexpected username: ' + ctx.username)); + assert(ctx.key.algo === 'ssh-rsa', + makeMsg('Unexpected key algo: ' + ctx.key.algo)); + assert.deepEqual(CLIENT_KEY_RSA_PUB.public, + ctx.key.data, + makeMsg('Public key mismatch')); + if (ctx.signature) { + var verifier = crypto.createVerify('RSA-SHA1'); + var pem = CLIENT_KEY_RSA_PUB.publicOrig; + verifier.update(ctx.blob); + assert(verifier.verify(pem, ctx.signature), + makeMsg('Could not verify PK signature')); + ctx.accept(); + } else + ctx.accept(); + }).on('ready', function() { + conn.end(); + }); + }); + }, + what: 'Authenticate with an RSA key' + }, + { run: function() { + var client; + var server; + var r; + + r = setup( + this, + { username: USER, + privateKey: CLIENT_KEY_ENC_RSA, + passphrase: 'foobarbaz', + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + assert(ctx.method === 'publickey', + makeMsg('Unexpected auth method: ' + ctx.method)); + assert(ctx.username === USER, + makeMsg('Unexpected username: ' + ctx.username)); + assert(ctx.key.algo === 'ssh-rsa', + makeMsg('Unexpected key algo: ' + ctx.key.algo)); + assert.deepEqual(CLIENT_KEY_ENC_RSA_PUB.public, + ctx.key.data, + makeMsg('Public key mismatch')); + if (ctx.signature) { + var verifier = crypto.createVerify('RSA-SHA1'); + var pem = CLIENT_KEY_ENC_RSA_PUB.publicOrig; + verifier.update(ctx.blob); + assert(verifier.verify(pem, ctx.signature), + makeMsg('Could not verify PK signature')); + ctx.accept(); + } else + ctx.accept(); + }).on('ready', function() { + conn.end(); + }); + }); + }, + what: 'Authenticate with an encrypted RSA key' + }, + { run: function() { + var client; + var server; + var r; + + r = setup( + this, + { username: USER, + privateKey: CLIENT_KEY_PPK_RSA + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + assert(ctx.method === 'publickey', + makeMsg('Unexpected auth method: ' + ctx.method)); + assert(ctx.username === USER, + makeMsg('Unexpected username: ' + ctx.username)); + assert(ctx.key.algo === 'ssh-rsa', + makeMsg('Unexpected key algo: ' + ctx.key.algo)); + if (ctx.signature) { + var verifier = crypto.createVerify('RSA-SHA1'); + var pem = CLIENT_KEY_PPK_RSA_PUB.publicOrig; + verifier.update(ctx.blob); + assert(verifier.verify(pem, ctx.signature), + makeMsg('Could not verify PK signature')); + ctx.accept(); + } else + ctx.accept(); + }).on('ready', function() { + conn.end(); + }); + }); + }, + what: 'Authenticate with an RSA key (PPK)' + }, + { run: function() { + var client; + var server; + var r; + + r = setup( + this, + { username: USER, + privateKey: CLIENT_KEY_DSA + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + assert(ctx.method === 'publickey', + makeMsg('Unexpected auth method: ' + ctx.method)); + assert(ctx.username === USER, + makeMsg('Unexpected username: ' + ctx.username)); + assert(ctx.key.algo === 'ssh-dss', + makeMsg('Unexpected key algo: ' + ctx.key.algo)); + assert.deepEqual(CLIENT_KEY_DSA_PUB.public, + ctx.key.data, + makeMsg('Public key mismatch')); + if (ctx.signature) { + var verifier = crypto.createVerify('DSA-SHA1'); + var pem = CLIENT_KEY_DSA_PUB.publicOrig; + verifier.update(ctx.blob); + assert(verifier.verify(pem, ctx.signature), + makeMsg('Could not verify PK signature')); + ctx.accept(); + } else + ctx.accept(); + }).on('ready', function() { + conn.end(); + }); + }); + }, + what: 'Authenticate with a DSA key' + }, + { run: function() { + if (semver.lt(process.version, '5.2.0')) + return next(); + var client; + var server; + var r; + + r = setup( + this, + { username: USER, + privateKey: CLIENT_KEY_ECDSA + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + assert(ctx.method === 'publickey', + makeMsg('Unexpected auth method: ' + ctx.method)); + assert(ctx.username === USER, + makeMsg('Unexpected username: ' + ctx.username)); + assert(ctx.key.algo === 'ecdsa-sha2-nistp256', + makeMsg('Unexpected key algo: ' + ctx.key.algo)); + assert.deepEqual(CLIENT_KEY_ECDSA_PUB.public, + ctx.key.data, + makeMsg('Public key mismatch')); + if (ctx.signature) { + var verifier = crypto.createVerify('sha256'); + var pem = CLIENT_KEY_ECDSA_PUB.publicOrig; + verifier.update(ctx.blob); + assert(verifier.verify(pem, ctx.signature), + makeMsg('Could not verify PK signature')); + ctx.accept(); + } else + ctx.accept(); + }).on('ready', function() { + conn.end(); + }); + }); + }, + what: 'Authenticate with a ECDSA key' + }, + { run: function() { + var client; + var server; + var r; + + r = setup( + this, + { username: USER, + password: 'asdf', + algorithms: { + serverHostKey: ['ssh-dss'] + } + }, + { hostKeys: [HOST_KEY_DSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + assert(ctx.method === 'password', + makeMsg('Unexpected auth method: ' + ctx.method)); + assert(ctx.username === USER, + makeMsg('Unexpected username: ' + ctx.username)); + assert(ctx.password === 'asdf', + makeMsg('Unexpected password: ' + ctx.password)); + ctx.accept(); + }).on('ready', function() { + conn.end(); + }); + }); + }, + what: 'Server with DSA host key' + }, + { run: function() { + if (semver.lt(process.version, '5.2.0')) + return next(); + var client; + var server; + var r; + + r = setup( + this, + { username: USER, + password: 'asdf' + }, + { hostKeys: [HOST_KEY_ECDSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + assert(ctx.method === 'password', + makeMsg('Unexpected auth method: ' + ctx.method)); + assert(ctx.username === USER, + makeMsg('Unexpected username: ' + ctx.username)); + assert(ctx.password === 'asdf', + makeMsg('Unexpected password: ' + ctx.password)); + ctx.accept(); + }).on('ready', function() { + conn.end(); + }); + }); + }, + what: 'Server with ECDSA host key' + }, + { run: function() { + var client; + var server; + var r; + + r = setup( + this, + { username: USER, + password: 'asdf', + algorithms: { + serverHostKey: 'ssh-rsa' + } + }, + { hostKeys: [HOST_KEY_RSA, HOST_KEY_DSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + assert(ctx.method === 'password', + makeMsg('Unexpected auth method: ' + ctx.method)); + assert(ctx.username === USER, + makeMsg('Unexpected username: ' + ctx.username)); + assert(ctx.password === 'asdf', + makeMsg('Unexpected password: ' + ctx.password)); + ctx.accept(); + }).on('ready', function() { + conn.end(); + }); + }); + }, + what: 'Server with multiple host keys (RSA selected)' + }, + { run: function() { + var client; + var server; + var r; + + r = setup( + this, + { username: USER, + password: 'asdf', + algorithms: { + serverHostKey: 'ssh-dss' + } + }, + { hostKeys: [HOST_KEY_RSA, HOST_KEY_DSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + assert(ctx.method === 'password', + makeMsg('Unexpected auth method: ' + ctx.method)); + assert(ctx.username === USER, + makeMsg('Unexpected username: ' + ctx.username)); + assert(ctx.password === 'asdf', + makeMsg('Unexpected password: ' + ctx.password)); + ctx.accept(); + }).on('ready', function() { + conn.end(); + }); + }); + }, + what: 'Server with multiple host keys (DSA selected)' + }, + { run: function() { + var client; + var server; + var r; + var hostname = 'foo'; + var username = 'bar'; + + r = setup( + this, + { username: USER, + privateKey: CLIENT_KEY_RSA, + localHostname: hostname, + localUsername: username + }, + { hostKeys: [ HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + if (ctx.method === 'hostbased') { + assert(ctx.username === USER, + makeMsg('Unexpected username: ' + ctx.username)); + assert(ctx.key.algo === 'ssh-rsa', + makeMsg('Unexpected key algo: ' + ctx.key.algo)); + assert.deepEqual(CLIENT_KEY_RSA_PUB.public, + ctx.key.data, + makeMsg('Public key mismatch')); + assert(ctx.signature, + makeMsg('Expected signature')); + assert(ctx.localHostname === hostname, + makeMsg('Wrong local hostname')); + assert(ctx.localUsername === username, + makeMsg('Wrong local username')); + var verifier = crypto.createVerify('RSA-SHA1'); + var pem = CLIENT_KEY_RSA_PUB.publicOrig; + verifier.update(ctx.blob); + assert(verifier.verify(pem, ctx.signature), + makeMsg('Could not verify hostbased signature')); + ctx.accept(); + } else + ctx.reject(); + }).on('ready', function() { + conn.end(); + }); + }); + }, + what: 'Authenticate with hostbased' + }, + { run: function() { + var client; + var server; + var r; + + r = setup( + this, + { username: USER, + password: PASSWORD + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + assert(ctx.method === 'password', + makeMsg('Unexpected auth method: ' + ctx.method)); + assert(ctx.username === USER, + makeMsg('Unexpected username: ' + ctx.username)); + assert(ctx.password === PASSWORD, + makeMsg('Unexpected password: ' + ctx.password)); + ctx.accept(); + }).on('ready', function() { + conn.end(); + }); + }); + }, + what: 'Authenticate with a password' + }, + { run: function() { + var client; + var server; + var r; + var verified = false; + + r = setup( + this, + { username: USER, + password: PASSWORD, + hostHash: 'md5', + hostVerifier: function(hash) { + assert(hash === MD5_HOST_FINGERPRINT, + makeMsg('Host fingerprint mismatch')); + return (verified = true); + } + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() { + conn.end(); + }); + }).on('close', function() { + assert(verified, makeMsg('Failed to verify host fingerprint')); + }); + }, + what: 'Verify host fingerprint' + }, + { run: function() { + var client; + var server; + var r; + var out = ''; + var outErr = ''; + var exitArgs; + var closeArgs; + + r = setup( + this, + { username: USER, + password: PASSWORD + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() { + conn.once('session', function(accept, reject) { + var session = accept(); + session.once('exec', function(accept, reject, info) { + assert(info.command === 'foo --bar', + makeMsg('Wrong exec command: ' + info.command)); + var stream = accept(); + stream.stderr.write('stderr data!\n'); + stream.write('stdout data!\n'); + stream.exit(100); + stream.end(); + conn.end(); + }); + }); + }); + }); + client.on('ready', function() { + client.exec('foo --bar', function(err, stream) { + assert(!err, makeMsg('Unexpected exec error: ' + err)); + stream.on('data', function(d) { + out += d; + }).on('exit', function(code) { + exitArgs = new Array(arguments.length); + for (var i = 0; i < exitArgs.length; ++i) + exitArgs[i] = arguments[i]; + }).on('close', function(code) { + closeArgs = new Array(arguments.length); + for (var i = 0; i < closeArgs.length; ++i) + closeArgs[i] = arguments[i]; + }).stderr.on('data', function(d) { + outErr += d; + }); + }); + }).on('end', function() { + assert.deepEqual(exitArgs, + [100], + makeMsg('Wrong exit args: ' + inspect(exitArgs))); + assert.deepEqual(closeArgs, + [100], + makeMsg('Wrong close args: ' + inspect(closeArgs))); + assert(out === 'stdout data!\n', + makeMsg('Wrong stdout data: ' + inspect(out))); + assert(outErr === 'stderr data!\n', + makeMsg('Wrong stderr data: ' + inspect(outErr))); + }); + }, + what: 'Simple exec' + }, + { run: function() { + var client; + var server; + var r; + var out = ''; + + r = setup( + this, + { username: USER, + password: PASSWORD + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() { + conn.once('session', function(accept, reject) { + var session = accept(), + env = {}; + session.once('env', function(accept, reject, info) { + env[info.key] = info.val; + accept && accept(); + }).once('exec', function(accept, reject, info) { + assert(info.command === 'foo --bar', + makeMsg('Wrong exec command: ' + info.command)); + var stream = accept(); + stream.write(''+env.SSH2NODETEST); + stream.exit(100); + stream.end(); + conn.end(); + }); + }); + }); + }); + client.on('ready', function() { + client.exec('foo --bar', + { env: { SSH2NODETEST: 'foo' } }, + function(err, stream) { + assert(!err, makeMsg('Unexpected exec error: ' + err)); + stream.on('data', function(d) { + out += d; + }); + }); + }).on('end', function() { + assert(out === 'foo', + makeMsg('Wrong stdout data: ' + inspect(out))); + }); + }, + what: 'Exec with environment set' + }, + { run: function() { + var client; + var server; + var r; + var out = ''; + + r = setup( + this, + { username: USER, + password: PASSWORD + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() { + conn.once('session', function(accept, reject) { + var session = accept(); + var ptyInfo; + session.once('pty', function(accept, reject, info) { + ptyInfo = info; + accept && accept(); + }).once('exec', function(accept, reject, info) { + assert(info.command === 'foo --bar', + makeMsg('Wrong exec command: ' + info.command)); + var stream = accept(); + stream.write(JSON.stringify(ptyInfo)); + stream.exit(100); + stream.end(); + conn.end(); + }); + }); + }); + }); + var pty = { + rows: 2, + cols: 4, + width: 0, + height: 0, + term: 'vt220', + modes: {} + }; + client.on('ready', function() { + client.exec('foo --bar', + { pty: pty }, + function(err, stream) { + assert(!err, makeMsg('Unexpected exec error: ' + err)); + stream.on('data', function(d) { + out += d; + }); + }); + }).on('end', function() { + assert.deepEqual(JSON.parse(out), + pty, + makeMsg('Wrong stdout data: ' + inspect(out))); + }); + }, + what: 'Exec with pty set' + }, + { run: function() { + var client; + var server; + var r; + var out = ''; + + r = setup( + this, + { username: USER, + password: PASSWORD, + agent: '/foo/bar/baz' + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() { + conn.once('session', function(accept, reject) { + var session = accept(); + var authAgentReq = false; + session.once('auth-agent', function(accept, reject) { + authAgentReq = true; + accept && accept(); + }).once('exec', function(accept, reject, info) { + assert(info.command === 'foo --bar', + makeMsg('Wrong exec command: ' + info.command)); + var stream = accept(); + stream.write(inspect(authAgentReq)); + stream.exit(100); + stream.end(); + conn.end(); + }); + }); + }); + }); + client.on('ready', function() { + client.exec('foo --bar', + { agentForward: true }, + function(err, stream) { + assert(!err, makeMsg('Unexpected exec error: ' + err)); + stream.on('data', function(d) { + out += d; + }); + }); + }).on('end', function() { + assert(out === 'true', + makeMsg('Wrong stdout data: ' + inspect(out))); + }); + }, + what: 'Exec with OpenSSH agent forwarding' + }, + { run: function() { + var client; + var server; + var r; + var out = ''; + + r = setup( + this, + { username: USER, + password: PASSWORD + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() { + conn.once('session', function(accept, reject) { + var session = accept(); + var x11 = false; + session.once('x11', function(accept, reject, info) { + x11 = true; + accept && accept(); + }).once('exec', function(accept, reject, info) { + assert(info.command === 'foo --bar', + makeMsg('Wrong exec command: ' + info.command)); + var stream = accept(); + stream.write(inspect(x11)); + stream.exit(100); + stream.end(); + conn.end(); + }); + }); + }); + }); + client.on('ready', function() { + client.exec('foo --bar', + { x11: true }, + function(err, stream) { + assert(!err, makeMsg('Unexpected exec error: ' + err)); + stream.on('data', function(d) { + out += d; + }); + }); + }).on('end', function() { + assert(out === 'true', + makeMsg('Wrong stdout data: ' + inspect(out))); + }); + }, + what: 'Exec with X11 forwarding' + }, + { run: function() { + var client; + var server; + var r; + var out = ''; + + r = setup( + this, + { username: USER, + password: PASSWORD + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() { + conn.once('session', function(accept, reject) { + var session = accept(); + var sawPty = false; + session.once('pty', function(accept, reject, info) { + sawPty = true; + accept && accept(); + }).once('shell', function(accept, reject) { + var stream = accept(); + stream.write('Cowabunga dude! ' + inspect(sawPty)); + stream.end(); + conn.end(); + }); + }); + }); + }); + client.on('ready', function() { + client.shell(function(err, stream) { + assert(!err, makeMsg('Unexpected exec error: ' + err)); + stream.on('data', function(d) { + out += d; + }); + }); + }).on('end', function() { + assert(out === 'Cowabunga dude! true', + makeMsg('Wrong stdout data: ' + inspect(out))); + }); + }, + what: 'Simple shell' + }, + { run: function() { + var client; + var server; + var r; + var expHandle = new Buffer([1, 2, 3, 4]); + var sawOpenS = false; + var sawCloseS = false; + var sawOpenC = false; + var sawCloseC = false; + + r = setup( + this, + { username: USER, + password: PASSWORD + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() { + conn.once('session', function(accept, reject) { + var session = accept(); + session.once('sftp', function(accept, reject) { + if (accept) { + var sftp = accept(); + sftp.once('OPEN', function(id, filename, flags, attrs) { + assert(id === 0, + makeMsg('Unexpected sftp request ID: ' + id)); + assert(filename === 'node.js', + makeMsg('Unexpected filename: ' + filename)); + assert(flags === OPEN_MODE.READ, + makeMsg('Unexpected flags: ' + flags)); + sawOpenS = true; + sftp.handle(id, expHandle); + sftp.once('CLOSE', function(id, handle) { + assert(id === 1, + makeMsg('Unexpected sftp request ID: ' + id)); + assert.deepEqual(handle, + expHandle, + makeMsg('Wrong sftp file handle: ' + + inspect(handle))); + sawCloseS = true; + sftp.status(id, STATUS_CODE.OK); + conn.end(); + }); + }); + } + }); + }); + }); + }); + client.on('ready', function() { + client.sftp(function(err, sftp) { + assert(!err, makeMsg('Unexpected sftp error: ' + err)); + sftp.open('node.js', 'r', function(err, handle) { + assert(!err, makeMsg('Unexpected sftp error: ' + err)); + assert.deepEqual(handle, + expHandle, + makeMsg('Wrong sftp file handle: ' + + inspect(handle))); + sawOpenC = true; + sftp.close(handle, function(err) { + assert(!err, makeMsg('Unexpected sftp error: ' + err)); + sawCloseC = true; + }); + }); + }); + }).on('end', function() { + assert(sawOpenS, makeMsg('Expected sftp open()')); + assert(sawOpenC, makeMsg('Expected sftp open() callback')); + assert(sawCloseS, makeMsg('Expected sftp open()')); + assert(sawOpenC, makeMsg('Expected sftp close() callback')); + }); + }, + what: 'Simple SFTP' + }, + { run: function() { + var client; + var server; + var state = { + readies: 0, + closes: 0 + }; + var clientcfg = { + username: USER, + password: PASSWORD + }; + var servercfg = { + hostKeys: [HOST_KEY_RSA] + }; + var reconnect = false; + + client = new Client(), + server = new Server(servercfg); + + function onReady() { + assert(++state.readies <= 4, + makeMsg('Wrong ready count: ' + state.readies)); + } + function onClose() { + assert(++state.closes <= 3, + makeMsg('Wrong close count: ' + state.closes)); + if (state.closes === 2) + server.close(); + else if (state.closes === 3) + next(); + } + + server.listen(0, 'localhost', function() { + clientcfg.host = 'localhost'; + clientcfg.port = server.address().port; + client.connect(clientcfg); + }); + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', onReady); + }).on('close', onClose); + client.on('ready', function() { + onReady(); + if (reconnect) + client.end(); + else { + reconnect = true; + client.connect(clientcfg); + } + }).on('close', onClose); + }, + what: 'connect() on connected client' + }, + { run: function() { + var client = new Client({ + username: USER, + password: PASSWORD + }); + + assert.throws(function() { + client.exec('uptime', function(err, stream) { + assert(false, makeMsg('Callback unexpectedly called')); + }); + }); + next(); + }, + what: 'Throw when not connected' + }, + { run: function() { + var client; + var server; + var r; + var calledBack = 0; + + r = setup( + this, + { username: USER, + password: PASSWORD + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }); + }); + client.on('ready', function() { + function callback(err, stream) { + assert(err, makeMsg('Expected error')); + assert(err.message === 'No response from server', + makeMsg('Wrong error message: ' + err.message)); + ++calledBack; + } + client.exec('uptime', callback); + client.shell(callback); + client.sftp(callback); + client.end(); + }).on('close', function() { + // give the callbacks a chance to execute + process.nextTick(function() { + assert(calledBack === 3, + makeMsg('Only ' + + calledBack + + '/3 outstanding callbacks called')); + }); + }); + }, + what: 'Outstanding callbacks called on disconnect' + }, + { run: function() { + var client = new Client({ + username: USER, + password: PASSWORD + }); + + assert.throws(function() { + client.exec('uptime', function(err, stream) { + assert(false, makeMsg('Callback unexpectedly called')); + }); + }); + next(); + }, + what: 'Throw when not connected' + }, + { run: function() { + var client; + var server; + var r; + var calledBack = 0; + + r = setup( + this, + { username: USER, + password: PASSWORD + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() { + conn.on('session', function(accept, reject) { + var session = accept(); + session.once('exec', function(accept, reject, info) { + var stream = accept(); + stream.exit(0); + stream.end(); + }); + }); + }); + }); + client.on('ready', function() { + function callback(err, stream) { + assert(!err, makeMsg('Unexpected error: ' + err)); + stream.resume(); + if (++calledBack === 3) + client.end(); + } + client.exec('foo', callback); + client.exec('bar', callback); + client.exec('baz', callback); + }).on('end', function() { + assert(calledBack === 3, + makeMsg('Only ' + + calledBack + + '/3 callbacks called')); + }); + }, + what: 'Pipelined requests' + }, + { run: function() { + var client; + var server; + var r; + var calledBack = 0; + + r = setup( + this, + { username: USER, + password: PASSWORD, + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() { + var reqs = []; + conn.on('session', function(accept, reject) { + if (reqs.length === 0) { + conn.rekey(function(err) { + assert(!err, makeMsg('Unexpected rekey error: ' + err)); + reqs.forEach(function(accept) { + var session = accept(); + session.once('exec', function(accept, reject, info) { + var stream = accept(); + stream.exit(0); + stream.end(); + }); + }); + }); + } + reqs.push(accept); + }); + }); + }); + client.on('ready', function() { + function callback(err, stream) { + assert(!err, makeMsg('Unexpected error: ' + err)); + stream.resume(); + if (++calledBack === 3) + client.end(); + } + client.exec('foo', callback); + client.exec('bar', callback); + client.exec('baz', callback); + }).on('end', function() { + assert(calledBack === 3, + makeMsg('Only ' + + calledBack + + '/3 callbacks called')); + }); + }, + what: 'Pipelined requests with intermediate rekeying' + }, + { run: function() { + var client; + var server; + var r; + + r = setup( + this, + { username: USER, + password: PASSWORD + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() { + conn.on('session', function(accept, reject) { + var session = accept(); + session.once('exec', function(accept, reject, info) { + var stream = accept(); + stream.exit(0); + stream.end(); + }); + }); + }); + }); + client.on('ready', function() { + client.exec('foo', function(err, stream) { + assert(!err, makeMsg('Unexpected error: ' + err)); + stream.on('exit', function(code, signal) { + client.end(); + }); + }); + }); + }, + what: 'Ignore outgoing after stream close' + }, + { run: function() { + var client; + var server; + var r; + + r = setup( + this, + { username: USER, + password: PASSWORD + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() { + conn.on('session', function(accept, reject) { + accept().on('sftp', function(accept, reject) { + var sftp = accept(); + // XXX: hack to get channel ... + var channel = sftp._readableState.pipes; + + channel.unpipe(sftp); + sftp.unpipe(channel); + + channel.exit(127); + channel.close(); + }); + }); + }); + }); + client.on('ready', function() { + var timeout = setTimeout(function() { + assert(false, makeMsg('Unexpected SFTP timeout')); + }, 1000); + client.sftp(function(err, sftp) { + clearTimeout(timeout); + assert(err, makeMsg('Expected error')); + assert(err.code === 127, + makeMsg('Expected exit code 127, saw: ' + err.code)); + client.end(); + }); + }); + }, + what: 'SFTP server aborts with exit-status' + }, + { run: function() { + var client; + var server; + var r; + + r = setup( + this, + { username: USER, + password: PASSWORD, + sock: new net.Socket() + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() {}); + }); + client.on('ready', function() { + client.end(); + }); + }, + what: 'Double pipe on unconnected, passed in net.Socket' + }, + { run: function() { + var client; + var server; + var r; + + r = setup( + this, + { username: USER }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }); + conn.on('request', function(accept, reject, name, info) { + accept(); + conn.forwardOut('good', 0, 'remote', 12345, function(err, ch) { + if (err) { + assert(!err, makeMsg('Unexpected error: ' + err)); + } + conn.forwardOut('bad', 0, 'remote', 12345, function(err, ch) { + assert(err, makeMsg('Should receive error')); + client.end(); + }); + }); + }); + }); + + client.on('ready', function() { + // request forwarding + client.forwardIn('good', 0, function(err, port) { + if (err) { + assert(!err, makeMsg('Unexpected error: ' + err)); + } + }); + }); + client.on('tcp connection', function(details, accept, reject) { + accept(); + }); + }, + what: 'Client auto-rejects unrequested, allows requested forwarded-tcpip' + }, + { run: function() { + var client; + var server; + var r; + + r = setup( + this, + { username: USER, + password: PASSWORD + }, + { hostKeys: [HOST_KEY_RSA], + greeting: 'Hello world!' + } + ); + client = r.client; + server = r.server; + + var sawGreeting = false; + + client.on('greeting', function(greeting) { + assert.strictEqual(greeting, 'Hello world!\r\n'); + sawGreeting = true; + }); + client.on('banner', function(message) { + assert.fail(null, null, makeMsg('Unexpected banner')); + }); + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + assert(sawGreeting, makeMsg('Client did not see greeting')); + assert(ctx.method === 'password', + makeMsg('Unexpected auth method: ' + ctx.method)); + assert(ctx.username === USER, + makeMsg('Unexpected username: ' + ctx.username)); + assert(ctx.password === PASSWORD, + makeMsg('Unexpected password: ' + ctx.password)); + ctx.accept(); + }).on('ready', function() { + conn.end(); + }); + }); + }, + what: 'Server greeting' + }, + { run: function() { + var client; + var server; + var r; + + r = setup( + this, + { username: USER, + password: PASSWORD + }, + { hostKeys: [HOST_KEY_RSA], + banner: 'Hello world!' + } + ); + client = r.client; + server = r.server; + + var sawBanner = false; + + client.on('greeting', function(greeting) { + assert.fail(null, null, makeMsg('Unexpected greeting')); + }); + client.on('banner', function(message) { + assert.strictEqual(message, 'Hello world!\r\n'); + sawBanner = true; + }); + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + assert(sawBanner, makeMsg('Client did not see banner')); + assert(ctx.method === 'password', + makeMsg('Unexpected auth method: ' + ctx.method)); + assert(ctx.username === USER, + makeMsg('Unexpected username: ' + ctx.username)); + assert(ctx.password === PASSWORD, + makeMsg('Unexpected password: ' + ctx.password)); + ctx.accept(); + }).on('ready', function() { + conn.end(); + }); + }); + }, + what: 'Server banner' + }, + { run: function() { + var client; + var server; + var r; + var fastRejectSent = false; + + function sendAcceptLater(accept) { + if (fastRejectSent) + accept(); + else + setImmediate(sendAcceptLater, accept); + } + + r = setup( + this, + { username: USER }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }); + + conn.on('request', function(accept, reject, name, info) { + if (info.bindAddr === 'fastReject') { + // Will call reject on 'fastReject' soon + reject(); + fastRejectSent = true; + } else + // but accept on 'slowAccept' later + sendAcceptLater(accept); + }); + }); + + client.on('ready', function() { + var replyCnt = 0; + + client.forwardIn('slowAccept', 0, function(err) { + assert(!err, makeMsg('Unexpected error: ' + err)); + if (++replyCnt === 2) + client.end(); + }); + + client.forwardIn('fastReject', 0, function(err) { + assert(err, makeMsg('Should receive error')); + if (++replyCnt === 2) + client.end(); + }); + }); + }, + what: 'Server responds to global requests in the right order' + }, + { run: function() { + var client; + var server; + var r; + + r = setup( + this, + { username: USER, + password: PASSWORD + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + var timer; + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() { + conn.on('session', function(accept, reject) { + var session = accept(); + session.once('subsystem', function(accept, reject, info) { + assert.equal(info.name, 'netconf'); + + // Prevent success reply from being sent + conn._sshstream.channelSuccess = function() {}; + + var stream = accept(); + stream.close(); + timer = setTimeout(function() { + throw new Error(makeMsg('Expected client callback')); + }, 50); + }); + }); + }); + }); + client.on('ready', function() { + client.subsys('netconf', function(err, stream) { + clearTimeout(timer); + assert(err); + client.end(); + }); + }); + }, + what: 'Cleanup outstanding channel requests on channel close' + }, + { run: function() { + var client; + var server; + var r; + + r = setup( + this, + { username: USER, + password: PASSWORD + }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + var timer; + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() { + conn.on('session', function(accept, reject) { + var session = accept(); + session.once('exec', function(accept, reject, info) { + var stream = accept(); + // Write enough to bring the Client's channel window to 0 + // (currently 1MB) + var buf = new Buffer(2048); + for (var i = 0; i < 1000; ++i) + stream.write(buf); + stream.exit(0); + stream.close(); + }); + }); + }); + }); + client.on('ready', function() { + client.exec('foo', function(err, stream) { + var sawClose = false; + assert(!err, makeMsg('Unexpected error')); + client._sshstream.on('CHANNEL_CLOSE:' + stream.incoming.id, onClose); + function onClose() { + // This handler gets called *after* the internal handler, so we + // should have seen `stream`'s `close` event already if the bug + // exists + assert(!sawClose, makeMsg('Premature close event')); + client.end(); + } + stream.on('close', function() { + sawClose = true; + }); + }); + }); + }, + what: 'Channel emits close prematurely' + }, + { run: function() { + var client; + var server; + var r; + + r = setup( + this, + { username: USER }, + { hostKeys: [HOST_KEY_RSA], ident: 'OpenSSH_5.3' } + ); + client = r.client; + server = r.server; + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }); + conn.once('request', function(accept, reject, name, info) { + assert(name === 'tcpip-forward', + makeMsg('Unexpected request: ' + name)); + accept(1337); + conn.forwardOut('good', 0, 'remote', 12345, function(err, ch) { + assert(!err, makeMsg('Unexpected error: ' + err)); + client.end(); + }); + }); + }); + + client.on('ready', function() { + // request forwarding + client.forwardIn('good', 0, function(err, port) { + assert(!err, makeMsg('Unexpected error: ' + err)); + assert(port === 1337, makeMsg('Bad bound port: ' + port)); + }); + }); + client.on('tcp connection', function(details, accept, reject) { + assert(details.destIP === 'good', + makeMsg('Bad incoming destIP: ' + details.destIP)); + assert(details.destPort === 1337, + makeMsg('Bad incoming destPort: ' + details.destPort)); + assert(details.srcIP === 'remote', + makeMsg('Bad incoming srcIP: ' + details.srcIP)); + assert(details.srcPort === 12345, + makeMsg('Bad incoming srcPort: ' + details.srcPort)); + accept(); + }); + }, + what: 'OpenSSH 5.x workaround for binding on port 0' + }, + { run: function() { + var client; + var server; + var r; + var srvError; + var cliError; + + r = setup( + this, + { username: USER, + algorithms: { + cipher: [ 'aes128-cbc' ] + } + }, + { hostKeys: [HOST_KEY_RSA], + algorithms: { + cipher: [ 'aes128-ctr' ] + } + } + ); + client = r.client; + server = r.server; + + // Remove default client error handler added by `setup()` since we are + // expecting an error in this case + client.removeAllListeners('error'); + + function onError(err) { + if (this === client) { + assert(!cliError, makeMsg('Unexpected multiple client errors')); + cliError = err; + } else { + assert(!srvError, makeMsg('Unexpected multiple server errors')); + srvError = err; + } + assert(/handshake failed/i.test(err.message), + makeMsg('Wrong error message')); + } + + server.on('connection', function(conn) { + // Remove default server connection error handler added by `setup()` + // since we are expecting an error in this case + conn.removeAllListeners('error'); + + function onGoodHandshake() { + assert(false, makeMsg('Handshake should have failed')); + } + conn.on('authentication', onGoodHandshake); + conn.on('ready', onGoodHandshake); + + conn.on('error', onError); + }); + + client.on('ready', function() { + assert(false, makeMsg('Handshake should have failed')); + }); + client.on('error', onError); + client.on('close', function() { + assert(cliError, makeMsg('Expected client error')); + assert(srvError, makeMsg('Expected client error')); + }); + }, + what: 'Handshake errors are emitted' + }, + { run: function() { + var client; + var server; + var r; + var cliError; + + r = setup( + this, + { username: USER, privateKey: KEY_RSA_BAD }, + { hostKeys: [HOST_KEY_RSA] } + ); + client = r.client; + server = r.server; + + // Remove default client error handler added by `setup()` since we are + // expecting an error in this case + client.removeAllListeners('error'); + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + assert(ctx.method === 'publickey' || ctx.method === 'none', + makeMsg('Unexpected auth method: ' + ctx.method)); + assert(!ctx.signature, makeMsg('Unexpected signature')); + if (ctx.method === 'none') + return ctx.reject(); + ctx.accept(); + }); + conn.on('ready', function() { + assert(false, makeMsg('Authentication should have failed')); + }); + }); + + client.on('ready', function() { + assert(false, makeMsg('Authentication should have failed')); + }); + client.on('error', function(err) { + if (cliError) { + assert(/all configured/i.test(err.message), + makeMsg('Wrong error message')); + } else { + cliError = err; + assert(/signing/i.test(err.message), makeMsg('Wrong error message')); + } + }); + client.on('close', function() { + assert(cliError, makeMsg('Expected client error')); + }); + }, + what: 'Client signing errors are caught and emitted' + }, + { run: function() { + var client; + var server; + var r; + var srvError; + var cliError; + + r = setup( + this, + { username: USER, password: 'foo' }, + { hostKeys: [KEY_RSA_BAD] } + ); + client = r.client; + server = r.server; + + // Remove default client error handler added by `setup()` since we are + // expecting an error in this case + client.removeAllListeners('error'); + + server.on('connection', function(conn) { + // Remove default server connection error handler added by `setup()` + // since we are expecting an error in this case + conn.removeAllListeners('error'); + + conn.once('error', function(err) { + assert(/signing/i.test(err.message), makeMsg('Wrong error message')); + srvError = err; + }); + conn.on('authentication', function(ctx) { + assert(false, makeMsg('Handshake should have failed')); + }); + conn.on('ready', function() { + assert(false, makeMsg('Authentication should have failed')); + }); + }); + + client.on('ready', function() { + assert(false, makeMsg('Handshake should have failed')); + }); + client.on('error', function(err) { + assert(!cliError, makeMsg('Unexpected multiple client errors')); + assert(/KEY_EXCHANGE_FAILED/.test(err.message), + makeMsg('Wrong error message')); + cliError = err; + }); + client.on('close', function() { + assert(srvError, makeMsg('Expected server error')); + assert(cliError, makeMsg('Expected client error')); + }); + }, + what: 'Server signing errors are caught and emitted' + }, +]; + +function setup(self, clientcfg, servercfg) { + self.state = { + clientReady: false, + serverReady: false, + clientClose: false, + serverClose: false + }; + + if (DEBUG) { + console.log('========================================================\n' + + '[TEST] ' + + self.what + + '\n========================================================'); + clientcfg.debug = function(str) { + console.log('[CLIENT] ' + str); + }; + servercfg.debug = function(str) { + console.log('[SERVER] ' + str); + }; + } + + var client = new Client(); + var server = new Server(servercfg); + + server.on('error', onError) + .on('connection', function(conn) { + conn.on('error', onError) + .on('ready', onReady); + server.close(); + }) + .on('close', onClose); + client.on('error', onError) + .on('ready', onReady) + .on('close', onClose); + + function onError(err) { + var which = (this === client ? 'client' : 'server'); + assert(false, makeMsg('Unexpected ' + which + ' error: ' + err)); + } + function onReady() { + if (this === client) { + assert(!self.state.clientReady, + makeMsg('Received multiple ready events for client')); + self.state.clientReady = true; + } else { + assert(!self.state.serverReady, + makeMsg('Received multiple ready events for server')); + self.state.serverReady = true; + } + if (self.state.clientReady && self.state.serverReady) + self.onReady && self.onReady(); + } + function onClose() { + if (this === client) { + assert(!self.state.clientClose, + makeMsg('Received multiple close events for client')); + self.state.clientClose = true; + } else { + assert(!self.state.serverClose, + makeMsg('Received multiple close events for server')); + self.state.serverClose = true; + } + if (self.state.clientClose && self.state.serverClose) + next(); + } + + process.nextTick(function() { + server.listen(0, 'localhost', function() { + if (clientcfg.sock) + clientcfg.sock.connect(server.address().port, 'localhost'); + else { + clientcfg.host = 'localhost'; + clientcfg.port = server.address().port; + } + client.connect(clientcfg); + }); + }); + return { client: client, server: server }; +} + +function next() { + if (Array.isArray(process._events.exit)) + process._events.exit = process._events.exit[1]; + if (++t === tests.length) + return; + + var v = tests[t]; + v.run.call(v); +} + +function makeMsg(what, msg) { + if (msg === undefined) + msg = what; + if (tests[t]) + what = tests[t].what; + else + what = ''; + return '[' + group + what + ']: ' + msg; +} + +process.once('uncaughtException', function(err) { + if (t > -1 && !/(?:^|\n)AssertionError: /i.test(''+err)) + console.log(makeMsg('Unexpected Exception:')); + throw err; +}); +process.once('exit', function() { + assert(t === tests.length, + makeMsg('_exit', + 'Only finished ' + t + '/' + tests.length + ' tests')); +}); + +next(); diff --git a/node_modules/ssh2/test/test-openssh.js b/node_modules/ssh2/test/test-openssh.js new file mode 100644 index 0000000..ae2c4b0 --- /dev/null +++ b/node_modules/ssh2/test/test-openssh.js @@ -0,0 +1,459 @@ +var Server = require('../lib/server'); +var utils = require('ssh2-streams').utils; + +var semver = require('semver'); + +var fs = require('fs'); +var crypto = require('crypto'); +var path = require('path'); +var join = path.join; +var assert = require('assert'); +var spawn = require('child_process').spawn; +var exec = require('child_process').exec; + +var t = -1; +var group = path.basename(__filename, '.js') + '/'; +var fixturesdir = join(__dirname, 'fixtures'); + +var CLIENT_TIMEOUT = 5000; +var USER = 'nodejs'; +var HOST_KEY_RSA = fs.readFileSync(join(fixturesdir, 'ssh_host_rsa_key')); +var HOST_KEY_DSA = fs.readFileSync(join(fixturesdir, 'ssh_host_dsa_key')); +var HOST_KEY_ECDSA = fs.readFileSync(join(fixturesdir, 'ssh_host_ecdsa_key')); +var CLIENT_KEY_RSA_PATH = join(fixturesdir, 'id_rsa'); +var CLIENT_KEY_RSA = fs.readFileSync(CLIENT_KEY_RSA_PATH); +var CLIENT_KEY_RSA_PUB = utils.genPublicKey(utils.parseKey(CLIENT_KEY_RSA)); +var CLIENT_KEY_DSA_PATH = join(fixturesdir, 'id_dsa'); +var CLIENT_KEY_DSA = fs.readFileSync(CLIENT_KEY_DSA_PATH); +var CLIENT_KEY_DSA_PUB = utils.genPublicKey(utils.parseKey(CLIENT_KEY_DSA)); +if (semver.gte(process.version, '5.2.0')) { + var CLIENT_KEY_ECDSA_PATH = join(fixturesdir, 'id_ecdsa'); + var CLIENT_KEY_ECDSA = fs.readFileSync(CLIENT_KEY_ECDSA_PATH); + var CLIENT_KEY_ECDSA_PUB = utils.genPublicKey( + utils.parseKey(CLIENT_KEY_ECDSA) + ); +} +var opensshVer; +var DEBUG = false; + +// Fix file modes to avoid OpenSSH client complaints about keys' permissions +fs.readdirSync(fixturesdir).forEach(function(file) { + fs.chmodSync(join(fixturesdir, file), '0600'); +}); + +var tests = [ + { run: function() { + var what = this.what; + var server; + + server = setup( + this, + { privateKeyPath: CLIENT_KEY_RSA_PATH }, + { hostKeys: [HOST_KEY_RSA] } + ); + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + if (ctx.method === 'none') + return ctx.reject(); + assert(ctx.method === 'publickey', + makeMsg(what, 'Unexpected auth method: ' + ctx.method)); + assert(ctx.username === USER, + makeMsg(what, 'Unexpected username: ' + ctx.username)); + assert(ctx.key.algo === 'ssh-rsa', + makeMsg(what, 'Unexpected key algo: ' + ctx.key.algo)); + assert.deepEqual(CLIENT_KEY_RSA_PUB.public, + ctx.key.data, + makeMsg(what, 'Public key mismatch')); + if (ctx.signature) { + var verifier = crypto.createVerify('RSA-SHA1'); + var pem = CLIENT_KEY_RSA_PUB.publicOrig; + verifier.update(ctx.blob); + assert(verifier.verify(pem, ctx.signature), + makeMsg(what, 'Could not verify PK signature')); + ctx.accept(); + } else + ctx.accept(); + }).on('ready', function() { + conn.on('session', function(accept, reject) { + var session = accept(); + if (session) { + session.on('exec', function(accept, reject) { + var stream = accept(); + if (stream) { + stream.exit(0); + stream.end(); + } + }).on('pty', function(accept, reject) { + accept && accept(); + }); + } + }); + }); + }); + }, + what: 'Authenticate with an RSA key' + }, + { run: function() { + var what = this.what; + var server; + + server = setup( + this, + { privateKeyPath: CLIENT_KEY_DSA_PATH }, + { hostKeys: [HOST_KEY_RSA] } + ); + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + if (ctx.method === 'none') + return ctx.reject(); + assert(ctx.method === 'publickey', + makeMsg(what, 'Unexpected auth method: ' + ctx.method)); + assert(ctx.username === USER, + makeMsg(what, 'Unexpected username: ' + ctx.username)); + assert(ctx.key.algo === 'ssh-dss', + makeMsg(what, 'Unexpected key algo: ' + ctx.key.algo)); + assert.deepEqual(CLIENT_KEY_DSA_PUB.public, + ctx.key.data, + makeMsg(what, 'Public key mismatch')); + if (ctx.signature) { + var verifier = crypto.createVerify('DSA-SHA1'); + var pem = CLIENT_KEY_DSA_PUB.publicOrig; + verifier.update(ctx.blob); + assert(verifier.verify(pem, ctx.signature), + makeMsg(what, 'Could not verify PK signature')); + ctx.accept(); + } else + ctx.accept(); + }).on('ready', function() { + conn.on('session', function(accept, reject) { + var session = accept(); + if (session) { + session.on('exec', function(accept, reject) { + var stream = accept(); + if (stream) { + stream.exit(0); + stream.end(); + } + }).on('pty', function(accept, reject) { + accept && accept(); + }); + } + }); + }); + }); + }, + what: 'Authenticate with a DSA key' + }, + { run: function() { + if (semver.lt(process.version, '5.2.0')) + return next(); + var what = this.what; + var server; + + server = setup( + this, + { privateKeyPath: CLIENT_KEY_ECDSA_PATH }, + { hostKeys: [HOST_KEY_RSA] } + ); + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + if (ctx.method === 'none') + return ctx.reject(); + assert(ctx.method === 'publickey', + makeMsg(what, 'Unexpected auth method: ' + ctx.method)); + assert(ctx.username === USER, + makeMsg(what, 'Unexpected username: ' + ctx.username)); + assert(ctx.key.algo === 'ecdsa-sha2-nistp256', + makeMsg(what, 'Unexpected key algo: ' + ctx.key.algo)); + assert.deepEqual(CLIENT_KEY_ECDSA_PUB.public, + ctx.key.data, + makeMsg(what, 'Public key mismatch')); + if (ctx.signature) { + var verifier = crypto.createVerify('sha256'); + var pem = CLIENT_KEY_ECDSA_PUB.publicOrig; + verifier.update(ctx.blob); + assert(verifier.verify(pem, ctx.signature), + makeMsg(what, 'Could not verify PK signature')); + ctx.accept(); + } else + ctx.accept(); + }).on('ready', function() { + conn.on('session', function(accept, reject) { + var session = accept(); + if (session) { + session.on('exec', function(accept, reject) { + var stream = accept(); + if (stream) { + stream.exit(0); + stream.end(); + } + }).on('pty', function(accept, reject) { + accept && accept(); + }); + } + }); + }); + }); + }, + what: 'Authenticate with a ECDSA key' + }, + { run: function() { + var server; + + server = setup( + this, + { privateKeyPath: CLIENT_KEY_RSA_PATH }, + { hostKeys: [HOST_KEY_DSA] } + ); + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() { + conn.on('session', function(accept, reject) { + var session = accept(); + if (session) { + session.on('exec', function(accept, reject) { + var stream = accept(); + if (stream) { + stream.exit(0); + stream.end(); + } + }).on('pty', function(accept, reject) { + accept && accept(); + }); + } + }); + }); + }); + }, + what: 'Server with DSA host key' + }, + { run: function() { + if (semver.lt(process.version, '5.2.0')) + return next(); + var server; + + server = setup( + this, + { privateKeyPath: CLIENT_KEY_RSA_PATH }, + { hostKeys: [HOST_KEY_ECDSA] } + ); + + server.on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() { + conn.on('session', function(accept, reject) { + var session = accept(); + if (session) { + session.on('exec', function(accept, reject) { + var stream = accept(); + if (stream) { + stream.exit(0); + stream.end(); + } + }).on('pty', function(accept, reject) { + accept && accept(); + }); + } + }); + }); + }); + }, + what: 'Server with ECDSA host key' + }, + { run: function() { + var server; + var what = this.what; + + server = setup( + this, + { privateKeyPath: CLIENT_KEY_RSA_PATH }, + { hostKeys: [HOST_KEY_RSA] } + ); + + server.on('_child', function(childProc) { + childProc.stderr.once('data', function(data) { + childProc.stdin.end(); + }); + childProc.stdin.write('ping'); + }).on('connection', function(conn) { + conn.on('authentication', function(ctx) { + ctx.accept(); + }).on('ready', function() { + conn.on('session', function(accept, reject) { + var session = accept(); + assert(session, makeMsg(what, 'Missing session')); + session.on('exec', function(accept, reject) { + var stream = accept(); + assert(stream, makeMsg(what, 'Missing exec stream')); + stream.stdin.on('data', function(data) { + stream.stdout.write('pong on stdout'); + stream.stderr.write('pong on stderr'); + }).on('end', function() { + stream.stdout.write('pong on stdout'); + stream.stderr.write('pong on stderr'); + stream.exit(0); + stream.close(); + }); + }).on('pty', function(accept, reject) { + accept && accept(); + }); + }); + }); + }); + }, + what: 'Server closes stdin too early' + }, +]; + +function setup(self, clientcfg, servercfg) { + self.state = { + serverReady: false, + clientClose: false, + serverClose: false + }; + + var client; + var server = new Server(servercfg); + + server.on('error', onError) + .on('connection', function(conn) { + conn.on('error', onError) + .on('ready', onReady); + server.close(); + }) + .on('close', onClose); + + function onError(err) { + var which = (arguments.length >= 3 ? 'client' : 'server'); + assert(false, makeMsg(self.what, 'Unexpected ' + which + ' error: ' + err)); + } + function onReady() { + assert(!self.state.serverReady, + makeMsg(self.what, 'Received multiple ready events for server')); + self.state.serverReady = true; + self.onReady && self.onReady(); + } + function onClose() { + if (arguments.length >= 3) { + assert(!self.state.clientClose, + makeMsg(self.what, 'Received multiple close events for client')); + self.state.clientClose = true; + } else { + assert(!self.state.serverClose, + makeMsg(self.what, 'Received multiple close events for server')); + self.state.serverClose = true; + } + if (self.state.clientClose && self.state.serverClose) + next(); + } + + process.nextTick(function() { + server.listen(0, 'localhost', function() { + var cmd = 'ssh'; + var args = ['-o', 'UserKnownHostsFile=/dev/null', + '-o', 'StrictHostKeyChecking=no', + '-o', 'CheckHostIP=no', + '-o', 'ConnectTimeout=3', + '-o', 'GlobalKnownHostsFile=/dev/null', + '-o', 'GSSAPIAuthentication=no', + '-o', 'IdentitiesOnly=yes', + '-o', 'BatchMode=yes', + '-o', 'VerifyHostKeyDNS=no', + + '-vvvvvv', + '-T', + '-o', 'KbdInteractiveAuthentication=no', + '-o', 'HostbasedAuthentication=no', + '-o', 'PasswordAuthentication=no', + '-o', 'PubkeyAuthentication=yes', + '-o', 'PreferredAuthentications=publickey']; + if (clientcfg.privateKeyPath) + args.push('-o', 'IdentityFile=' + clientcfg.privateKeyPath); + if (!/^[0-6]\./.test(opensshVer)) { + // OpenSSH 7.0+ disables DSS/DSA host (and user) key support by + // default, so we explicitly enable it here + args.push('-o', 'HostKeyAlgorithms=+ssh-dss'); + } + args.push('-p', server.address().port.toString(), + '-l', USER, + 'localhost', + 'uptime'); + + client = spawn(cmd, args); + server.emit('_child', client); + if (DEBUG) { + client.stdout.pipe(process.stdout); + client.stderr.pipe(process.stderr); + } else { + client.stdout.resume(); + client.stderr.resume(); + } + client.on('error', function(err) { + onError(err, null, null); + }).on('exit', function(code) { + clearTimeout(client.timer); + if (code !== 0) + return onError(new Error('Non-zero exit code ' + code), null, null); + onClose(null, null, null); + }); + + client.timer = setTimeout(function() { + assert(false, makeMsg(self.what, 'Client timeout')); + }, CLIENT_TIMEOUT); + }); + }); + return server; +} + +function next() { + if (Array.isArray(process._events.exit)) + process._events.exit = process._events.exit[1]; + if (++t === tests.length) + return; + + var v = tests[t]; + v.run.call(v); +} + +function makeMsg(what, msg) { + return '[' + group + what + ']: ' + msg; +} + +process.once('uncaughtException', function(err) { + if (t > -1 && !/(?:^|\n)AssertionError: /i.test(''+err)) + console.log(makeMsg(tests[t].what, 'Unexpected Exception:')); + throw err; +}); +process.once('exit', function() { + assert(t === tests.length, + makeMsg('_exit', + 'Only finished ' + t + '/' + tests.length + ' tests')); +}); + + +// Get OpenSSH client version first +exec('ssh -V', function(err, stdout, stderr) { + if (err) { + console.log('OpenSSH client is required for these tests'); + process.exitCode = 5; + return; + } + var re = /^OpenSSH_([\d\.]+)/; + var m = re.exec(stdout.toString()); + if (!m || !m[1]) { + m = re.exec(stderr.toString()); + if (!m || !m[1]) { + console.log('OpenSSH client is required for these tests'); + process.exitCode = 5; + return; + } + } + opensshVer = m[1]; + next(); +}); diff --git a/node_modules/ssh2/test/test.js b/node_modules/ssh2/test/test.js new file mode 100644 index 0000000..4a91765 --- /dev/null +++ b/node_modules/ssh2/test/test.js @@ -0,0 +1,22 @@ +var spawn = require('child_process').spawn, + join = require('path').join; + +var files = require('fs').readdirSync(__dirname).filter(function(f) { + return (f.substr(0, 5) === 'test-'); + }).map(function(f) { + return join(__dirname, f); + }), + f = -1; + +function next() { + if (++f < files.length) { + spawn(process.argv[0], [ files[f] ], { stdio: 'inherit' }) + .on('exit', function(code) { + if (code === 0) + process.nextTick(next); + else + process.exit(code); + }); + } +} +next(); diff --git a/node_modules/ssh2/util/build_pagent.bat b/node_modules/ssh2/util/build_pagent.bat new file mode 100644 index 0000000..9f5aaf8 --- /dev/null +++ b/node_modules/ssh2/util/build_pagent.bat @@ -0,0 +1,2 @@ +@cl /Ox pagent.c User32.lib +@del /Q *.obj \ No newline at end of file diff --git a/node_modules/ssh2/util/pagent.c b/node_modules/ssh2/util/pagent.c new file mode 100644 index 0000000..e900491 --- /dev/null +++ b/node_modules/ssh2/util/pagent.c @@ -0,0 +1,88 @@ +#include +#include +#include + +#define AGENT_COPYDATA_ID 0x804e50ba +#define AGENT_MAX_MSGLEN 8192 + +#define GET_32BIT_MSB_FIRST(cp) \ + (((unsigned long)(unsigned char)(cp)[0] << 24) | \ + ((unsigned long)(unsigned char)(cp)[1] << 16) | \ + ((unsigned long)(unsigned char)(cp)[2] << 8) | \ + ((unsigned long)(unsigned char)(cp)[3])) + +#define GET_32BIT(cp) GET_32BIT_MSB_FIRST(cp) + +#define RET_ERR_BADARGS 10 +#define RET_ERR_UNAVAILABLE 11 +#define RET_ERR_NOMAP 12 +#define RET_ERR_BINSTDIN 13 +#define RET_ERR_BINSTDOUT 14 +#define RET_ERR_BADLEN 15 + +#define RET_NORESPONSE 1 +#define RET_RESPONSE 0 + +int main (int argc, const char* argv[]) { + HWND hwnd; + char *mapname; + HANDLE filemap; + unsigned char *p, *ret; + int id, retlen, inlen, n, rmode, r = RET_NORESPONSE; + COPYDATASTRUCT cds; + void *in; + + if (argc < 2) + return RET_ERR_BADARGS; + + hwnd = FindWindow("Pageant", "Pageant"); + if (!hwnd) + return RET_ERR_UNAVAILABLE; + + rmode = _setmode(_fileno(stdin), _O_BINARY); + if (rmode == -1) + return RET_ERR_BINSTDIN; + + rmode = _setmode(_fileno(stdout), _O_BINARY); + if (rmode == -1) + return RET_ERR_BINSTDOUT; + + inlen = atoi(argv[1]); + in = malloc(inlen); + n = fread(in, 1, inlen, stdin); + if (n != inlen) { + free(in); + return RET_ERR_BADLEN; + } + + mapname = malloc(32); + n = sprintf(mapname, "PageantRequest%08x", (unsigned)GetCurrentThreadId()); + + filemap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, + 0, AGENT_MAX_MSGLEN, mapname); + if (filemap == NULL || filemap == INVALID_HANDLE_VALUE) { + free(in); + free(mapname); + return RET_ERR_NOMAP; + } + + p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0); + memcpy(p, in, inlen); + cds.dwData = AGENT_COPYDATA_ID; + cds.cbData = 1 + n; + cds.lpData = mapname; + + id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &cds); + if (id > 0) { + r = RET_RESPONSE; + retlen = 4 + GET_32BIT(p); + fwrite(p, 1, retlen, stdout); + } + + free(in); + free(mapname); + UnmapViewOfFile(p); + CloseHandle(filemap); + + return r; +} diff --git a/node_modules/ssh2/util/pagent.exe b/node_modules/ssh2/util/pagent.exe new file mode 100644 index 0000000000000000000000000000000000000000..6e8a71ca581ecd0f3ad621efffc366f9f1edf9da GIT binary patch literal 50688 zcmeFaeSB0!mOp&^B}pggguk{jJ)UwrU@oNd;wqMz&KH}TJbU(hD;J5=04w3w>t@r zv(G+%JzYv*Pe`jfrRMED-jMP^q>3z-2BwjC+G6?yH4K8<6BSGaCh)z z0o_W}-<>m3TZoz6vwWJ6_2r;*su~Ty3y6|nMu-Eik1tCGO zP{gP!P?$Oi|7?P{fdf)L%FNwSha!cH{}hC|-1iTD`UGKi(mzNW7ya0C-x-VTf{<;Z zHV$gcd!=;yCJ8~u7W@!iA$&2s;p6{u(E2Ou*4`%FCJ5^;Mij~va`83d8~4wPs;@M` zgq~SQXvIfmK8tVMKQB_Qth@d0dwvLda3Y}(Upl@xF~Lj!yn=8&_xzuq|IhS*aw1#V zoSS3qu;&t0)hF-8{1B9b*=<3g)hh%Y_%SkFKl2J|ajqlWDktwv9R&yp0=qg{5d16w zzsf2wUz*zgh=IJmZw9?2(U2LG2pOfuZWUXQ&APmYjc>$VeDF$ zk(sgGEBJ#hG^v8UXC-K7MNr5Qgj%82j?X|FXQ8zK(^&W~Vq=tW`qmH|iIM?8|5=wC znNEUOmYaXGHWa923=IR;If%(ck&z|2IpqMn!FzK@ac=%A{-q(5J6m0qTL2W$li}7a z*NeMt`{?H+{rnaAXr2j5yPX}OPC~Z@YAuzl1%sqXxwDjm zt^j)kO{icG@`gAnjZ6oy0&;dj4h2-NT*G@I!0zIJx0`^7-b<5|r)kD=?Syi|SrMqz z>YZUjnyS>h1nGQD&Ik|4=d<5jAP618B!IKU@VZ;qtX_GjO)GPR4@sXXore3}!NEeG zYvYIFi}kL-5~maRsb#}zeZTf+$)S~GslFjSslzu!>qZzI`5KDSmO2|gbpTSjN-MF4 zTcw#|(~A^;*3(sI#ef^~uyHN>8HV|?Eq2R1^l9FoE%n3tO`htZx|>jSYJfcnq^dxV z^-BE^a!SeWceS=bc_{A;We>3R81^bZ`*kKCX3(Q_oA!>UW205;w3H3!eeCI|^K13} z`emALSlllJ{A?1)wW^9BFEf0@!2L!bA8y@B=mS|Hd`t{4FbqTUxqAOLVi?L&XO7m9 z*M>fjoxPvOV|@L(Uh51B|KSzb{>kXGfkN3SU05i)q-=Lnb zvZ!y_`-o{X0UrMo=%)d=5{W)DuvBO!aj~d@g?l zYK-{0{T;p@RI|0icj9`~#L}{`i#sh#Q2$UKD9P+b#)wj7YM9Et9BAmy412E zwR#w&d4W=&AxIhFL!is_v3C3xx#M&xXN3nO=O|rfY`9Q4Ye>$DTA`f%(^Z@j01zDm z*tiRXn-M46`o2-B?I)`3k5la*(fk;YRBY00k=XQC>i!tbdg_P8pZ)<6mBzJ1zVZ;; zcx8-!E%ifre@4e$RzIxO_w|MW<*DwkTcypxhd3?hgSNc(OfIW(}4%9vE3bReE(ocwP*IIl-d0m(JhV|S4yX+Ex zQ0&c0{jeZiq?HXBzM&=y5w?LT>gy+hz68Z1tGCgNap@;O^EpKGZvfmqpvpZ&@mGP~rOONDEcpsvx`@&PRQUTQ z=FGFEHu6c3beE;_mzG;{Mi#FGDE%=upF1!HcEV4;K;A^>D$MV4deXE`}mJ+%!6gIFi$Vq#tit4t(t|_fEgjV97 zQFV1&tt;py(s(fg6UOH(;t0(y;`m%qWTFGdj@bYQNM*4r02*7Uj!Z;nbQ-~kN z8e5(0pgRPf@VeGUy)@VCrBh}vX-VS#;(WW(ZIRxq zV2#&eD3sfW1uba+u@+AL6>K}Gx~d8kri-j)v_Pe-$A~YzG;UaW*@eKP4OmsME-K2T zJFKV}|4bI-Svhg1nvKASdR^6RduO(Kg|;2tC%i(SHe)q_(REg|CDGGfpQN?7P)aR0 zq;IIus+NPt`N}!1)*evjP#XL2oP>nh3s$VgM)We3t0(Lrc-3iDqB+U|d&B8x4|s*m zU)7GR21EfMDzyXX7|m{W%o*j&>CrC}HG2}R77kClggsfds#hcX^$n*VLx#<7uW`4o zZezd0E*>iK(qxem*a_fZ%%Qqi@)>lP+4um+lef>)S9ejvNE7Pbc!BnIUT5@lf)aI= zv%>{~(6H1=qhF<`DD61`BQqCMDZc)r_mrWG`bkQw%g=rZV315hsR@t%^ErtdGPA@c z2y*b2d!lvIi+F`u4YxXtt%i{oMMHT(n}2}ns@u%GGf`bUZ<&LNJe^TLF_woTS@!qf zZ_+=^!Ai8ysg=33dWRO(j@sHiBO4r^A@TmFz$G-CMze&vY^5j!dK9FIl>y~TQTamj zjI3TGC-hp-p1}?*QG%Qi?X@bO*_6|cy30;IW8^;iRJK>pI$ohfrPp5PRJv`pP9rz` z(iH5Txsjbn-VS#*xd#!~hc5$xi;p%ZHYGKeSeh1DnoF!GwrP=7X}2jIyznLvV-T4oB<}G+nUu*@oi1VNj#@;yZ}1i^}#n zR;+_5o8`}Wi`!>D)eG}K}YevF9&xKoIbDKl~EDC-60w*e*WWw8*A>&3o?~-h00rS2W=kgBcsE zudT{Ad=#3-L2e%hhZdlPu`&DFrhG#qE8ZW#zA!Ea%I*UWL-+(B=D_E|mxV6}pBo?g zIvahR4L1vJ7TgTD8E{>2U2vUnop2p+9dPY%?dOh-*+)xI-ZFe^@ol2A<6~1|Ll2A_ z3m!&m$BhHp1{gE$oUt>R$08@z7%SG8FD}O#gT4Ez%i=roeBx^`lWQ}Ax6-C^OFHoz zg>zbudj&Z)fMXKYlYC6@y=AuuLQNr~(u)>+Z)5x3!Oj=$AZmg$J5L)bL7n=?rhjOrq1jQc1O3EXWnUx}HE$rhN zaIqFAVH3C%-W@ZMvt<^3{KlLdIL4f8D$CPHOpOzqd!gJTC;Hh&K(k-sN54|@ozNUw zvRZcBU(UXojZ&~i-_A7OaeyoJJp#d36MQ{>Vp|*ddUj(Pb~V;K4=mrK*b4cWl+&^o zU{g*ThU#-_CC;j6?*}K|h@H^fZ|OWl`}9@l(r3L=8oQGxU4$vEe_r7}_N+ykq^`C< z>k=D(ia2elL+Kt-)726xOzHkc>9oQR2(bIl(Lqw4#oil2>soU>eUg)PaKG2nC#Qjn zWb;Af#AYQ0m_8p~@aJ@QcMs?3SsOV4s~VlEm37 z6^wG3(wT!=fwz92R)&4Rkftc7N2EzwROz0s9gUtzh;}F1?2i(sr6=t5zU~zUy!IR^ zqt;qcQO+JfA6}PjVZJDkDAzuWs6Cb%piAQgW=HbnH8h83u4& zvvPIp(6qM)hiulgKoE93+l~qQI#9&!L|ba5+fc)^{~MjZuYmvNrP<|PHW)l%%;eE z{Dw|r_JvMczbUsCK-LrS_51Z3#r;t~ zdxwY&!iwv(2-TT)*jDDkdBD>tKJW|*25h((@fChn0Z2?qP=wg{uw4)q8XOUQO0A{B z1oE@1#=-m;Fz!~rzcwLK)?Z$0iA1QNa=)>Q`XrXy$Sk1t_Js$;#v){>6(YQ~{s7^q zg{e`RfUYw#X9JLWJOyAHuUd-`wb-I+m}sYP7j=`kZ2+8xvX9y?h>dT75J$@d4&w@K z_w}cpQ}AzjMk>T2Zrh1~5vKADUV5*BlIB_@`&_Ghp}5EGKBSDGr=v=nRpH23)m_v+ zH9|GV0B<&U9BT#HRMmKRPm1BiR1YuI8pBh%tTt_hU*+lS=jQ-tb3CYhCN>b$6!QAS z`%mM<*y}*Lmfk$k#Ik9bI9p3si^YQ8Z$M4%LqwVdM4CGg4DBPD5mY`9V)$8FP&lO( zmVvgu1%!6kJ&?xP!x1`DCEom4ra0saT zKX1&jd8akQeg(!?=*D<8T(<7oK);n}_1s^7w+_0lnXUH=5l$V-$6(7^VRo zhjb~@lxJu{0Cy8}B3Z(HH6g!H+%wVkiS2C@e+BqoVA(~ZTAQ}AM$OWAvuy2_T~vhm zTcf&c?G5`VVuV_@_y1|j?!>(LZp&_?xbZDpL@m3KLz;7)&v62=;zUD-oZWU7kq(!pKSEyipJm(7VUWtx4eJVVnAt02vZbIVuw9wNwh zEBiQ%bVY5#>OwvRAxZo#)(vw@XD`F6=Iirg({mq!Rr=NO)rJ;xuOw=m3_}GM$aZ(D zp3Cm#`N1;@>^^vv94=>cY8;U~zErH#%7)jt-&)PKfpI!S0)o(gcm?(#z+*@JDU4P* z@(jQ<4z5!?HXD3OZcF>94TtvRc*84=I`&)1*dJ^Xw4jXHbQK_*D5SVIh zalsK)1A%>VfXzYwROwd**k%v~?NGB+~2laN&a(QBVmNGDPe<3k#&x8h9e7A_dTl zLhz$iRql7MSC`+(=B$G3f)LXgYjip!6jkQ*T*>}|g9-7bI92Tjfwu-~ zt?YG^LUGDkh1@7)1)SAp=NfaUYmLlhyj;mvZFEDFJ1U2zliZ6y=S^aF@Q-yM0FmtI z$bjFozqR)O4r~(_D5tNeI~ghci*kCxMl9GXAh5B&^(xY;+Y*YAuQt8P(>bN};;7Q< zsBUAwx{}UNa^l{cgI)o09!DG77LUp`qnu_v0rnZPL&s3AI@ta2R%w0gRk&(C<^dP; zjQ#{eSKxqa(5&K0HTCXXR|H>PH&kYvYOeMTyI=RKw=)Rlp-YO2s(BRyOS7}i!|4P$EA2}n()HINTP>?^e; z4`f7&AAlmMPZLPRbx6w4K4KY=c%f2DxOJ0v>mtoJq;;WI`R!1>AxODe;<+fikJBWf z5a1|W#|~21*Kf8C6SJRMs~7KN#w?U-mX=z6egV`=!CnvG17XU61+96Lu*BeNjgz*_mcd+ePP1F)QVh6nIta64@ zy3UG9EP9IOK*?S^CAP1wK42FH7C609qH-TpXt~B>`=(TFLX#ED_U=~Q3DJJJpWVq< zKrEtIDHGd_M3b`1vETG*AG2>T=LZ%!y)?eVQi`(GA;@;iH2ntl0aCDm=`+#DWAf`XpZt!+Xik*EKav%b~fBsbRiAhH2ST!?Yr@ zyD(tb*z#C5Dvlj#Upos1d*4nZ3sQ;}egPik)^*1>z)pQH9z}DVo(PL zytyGUd@p*%J>VG;8}ERx`F!^wbr)aickyL^*Gs^s>CtcS+xV{7SO|<3srzVMFXUk2 zwo4EdxxRbuijAVU|A4qZ=tPw7WX$s*CAM&6dkfxso|%P4@cmi9tQsdvEv~R zAS1NqqeCBoqweCJwTpM6xxeh9?Lyr}-PijFvY`%z$&;cwtDAx!Ds>qnEUz1PAYI&--^OKG#4Bde_(R-YtXzzj#u z9|g4!^2lB?6Vdp9-_@ET?tddv>^Nc)K<`)B>D67-vfe+#OT}JtZn2a`#kL|j)(5>W z!LRW>aD0Khl*f4~i>2kEGeN01bmnd;D|BX~7;Zqk*&YGD-Z}!Cf44koQ7jTF4s*DA zE0JXOj;r^^QGZVFeE6G_=3XmL3vIQ`ma`y1kL5)V#qv%8%v?8zxWj}a_fD~~m)v{A#!tzW#m0}x-6S?1C3l6`cnGe#i|9dlhQ=0~IL#}+xch*g zoxx5AX0JI+WLE`cZ-i!BgcBV5FU*(bq!YWNBK7V?1>BXlV3;KP?lwAF&(AYT>o(S2h0F+`3VDiy)8WI1IlN#j!j!aF(P zW$I)QjtS^OIpZjkFc2G`2dD1&L{8l?8*G6ZrbvzdcJMWa8qv!SE)3mHc0y?DeR+^W zU5c`)&5zNMa1#gY z;BXXaW;C(ty$Tg+w$W(-aj*xbQJ%M@*=F;Ig2mS$r=T`S8T?>6t`VdPk1Yg$CMGw3 zw7q_|&;yF;?L@RPv`&187!9%UIDVC(+r@3WdHfyXgR_a*8@f}vR~h=TG*cP6M-2ZP z(gye_g-o=8gdp7(8x6EwU#_`Fab~-5!Xs(abx;wS*>WUjjTWXQvqnvX7?gX}#IcU) zjZz2mHOFgKffW-+eVRdoQ6WUA{u-!iHm$<0v^jd;MnIkrI&+8oLzA2k7WB$OPFhRxiiA_m^FU^=s2Cv2>K#23Gs0hyiIrN;l;2?|-jU(EV)GpYoHGGbi zL6f9#M4=#z6<2A@DUHEaRfYD^6u$$OF2}|L6psPSze1i68w|7#)1HWjCJxk<{LNU)Y0;9ek6%6tL$EHkL>9{yIQ5a{zmJd-#16mERQp z08R(r!a)Q=?-IaZw2(mz-%KU9*$1LIQkK~r15t1|;%f_sbvwkAyTaff#~K%#1=}$uf7FI#tNU22@9Lf7=->i{uf2nO89J9H zw2ss^Iq^b{bVNR7ZY2g^Ofl7eP6_PDzCjHh8X%m<(bu8e1`rL2rEf@J5-o2RT}1rjsLb=^1b@}#WjdeQd+H^ zx8+lLd__7sq|f9_)!5WEmnuDJaR~D21TSF!X2O~^Df?cLmH`L9#yeKrljyHaB$;(2ydCBHZ-io-d2y2Ei>{ob zMJO64ok=DTN8%95hiQ)-)u$@_ux{uX1~1RVQaj9kLm+0Ggw0pR@PwX+5C1r9b8cj% ze~&FKB{<0%oF!!c-G$~n!{e$n&JZ>yHSrC*u@y4A$WwsUIDhOOXg<>0fiC(UF4tTw z>3qK0{nkph1QYa78xD3axxK>gul5R`<6CfzSBT(y4BsdC#MyNC57JbGeNpDESi9VZ zuqHnmZ6U)aEgCx)n?j^awiAbo7_VIcZ|@l*hZ5(rirDxKyw7^Y@R#ITrBqXW*4u@k z(rJO5%GBIJ5EaP92BRn7xT7W-8?uZIjsW}QIJ(o%?!azO(ls*v6dN_lOS+Q#;Q{l0 zzg!+*FA*g1Q%(4CsnP9spy)$_T2mD-Y+MS zp-B$7h%H&PE6bVG42P8doPZrhPUK1Voh^;l`AqIE>VTHG5tR)Bo9wl_#?(kOG?j4ktzkH^8f3s~tEBX@U!eHa67gFH!voes1~Qs!~|8BrO(nt+uH*R?4??p^v}(U zp?OS^>bNQL-A0)!R6im#rD|eip(Q2~X)jJsNRj-S*t{ft1_Apx@cbr+CVI^r1d1US z06HT@p20ycAyC+n!o)cv4hk?ZGz4}DtnVUajD+fbEym?E^wcZ0y0h30$pWV+Lx*YLgQ3q{s;&hh4XYa?WbieGrk@ z+SF>uUiv*CygDH4CAquQ%sctgc#@@CP?$i$Su)cDrJP~jTGtSc3Ya3 z)LdpXElEt!XLzdnaYNS<9 zXtn@(s6Bjr=mrZKDTa@r71V>BaBpl*Z9KFoabfQR2tao#?mnc8%8-5QL{wgvextZM z)f;-b09>jdvF3^5?l;8!Dg|Nlo5n6ULBx1Dvg-f5z|$$)ZC$!o69?oZLK76PuQ$&seAo+2nZWl7)F)`gwz0k3-S~rM!ccPU9_u$T+XM?;Niu=MoODL0gTI6V2&7}iC!2); z|2P3%Km;@yb6QHb43Q zy|u(!4*f_B-$I_-PYAuM;DJdvnN>iu)cGF}H_is^sAlQ&UURwbggdre??zXhqgi@2 z2DW1qj1|NCf3I2EOKUQ;byHfsumY81#oWS+nS@&OJryhkYvlLqo*sshaa8v-W328g z%yPa@_w)-SnYyQ&so2r&oGx*YPVP2nM+AuXK7vTBcG7BCB>x0Htz9qWYvCl^P^g;# zyKJoJ4mSBCUccUfDPgYGbO-=O9QF@@U7yY(RMJINszW=e|E_k@in!n$cVL{_l3aWE zUFlADYjbg~qp?+<)Nm$*BI?rPR*?z4Rj|gd)J`jB>~&WUeyn_Ilbm@+o07=fu-76F zXr0k+hb>Bu3(gy`lZ5e`lz8fS6r5theMNAnU=3XvvYTxV9*6AA$Xv&lZ7DPOCW6pV z+--&v&^+Tv%m;z8;#PZ?N(lP6;#!+16@t~hij4~5NJ0b8Eq{%^Y z*~2-g5a)vwjt@muvC2GHz0E}%g1Pu%I|yCC$jbtiLDwyaS#=F=*<~Ybe-3`Cv>{LX zdQnS4F;?S<(qZ?E)SXm{UZQ%|td^z($;W2KYQpG}xsH)ZvF=u=0CR$jCQH(n7+eRt zh`NB(qgbj76H37;ijBnRwG_kK>~sB^41rJ&9v)|L zUZmCNpfg5oh_z7O$K$akFT_+c3>_s!uz!vPc}c7nHB%-GvQTB-M|cq=@Fq`nw?et% zalXFk-@FimdzGO{bzjpUYWCMRBPv#J!--)OGEO>AlnFMP#AMo#`&gB_&yG4hXT`?5 z0a$BeOWZW-Ll&_y$&Bz&1c)w8DcX6!D3DY_XG?hj{)O=^{=2OCj9MS%S%o=&$z*)^_xCa5Dc7E>8+lkFyyl)1-wd@R3C)Q61DdEt@_V9d=_51xEF- zxORhuk5-oi%;oAfPA8NN2O7GL6DjLq7A$PAnSzlgO&T>HTSqSY4K$^(1HfW^#Z)IU`$gplcg5TV&Z*Yr>vYv|OX_b*J7Uks^fVO4J`4L|agwhs8b4rP@*DGrQyv_a9bz^YzIMpW0BV zlpneASE19B5xdc*^yVnhL!PpX^%nqdN1<=HZl;{zDI3B)w6ZKaUsEpDd|5X=>yUH! z3SxtPjJiu-sVyHCUtFGHI|{oAYJT&6klog2?edgoEpn04ZIzN6aE}WIjE%`?Xp77oo+Aki_SG?*lv`~==+@~W zLs~_O#!4&# z&B-|3OJxI5hn$KoYeJU+iz00hasaIZvJSf2HQTh_UxZt%p0k@DbRW}BQ4ze`NMmk5Y=gQJLrd);{oeKxdjpQ{3AF<& z^pwa#gUdf!|AsR8f;Xf!*L5o#-(qx|kWh_+A+Qe-^_zXVgMrH`e$4Cv7p%0iV8t#C)j|D0{hc~bEq|u11uh8f^ zk9P7q0uuA)*0svqd_&5Qua;Bu4oj}Zl4G$vv7)wLcU08=O}ACl4j7pNYSWSwXClrB zdM0c8Q~VIX4#TTv0R@;b#P(0DtLQ7-415u3N{+xD83hMibsMZD93D*Nm70IMn?oJ#icHp+zTbdoFD=;>xbp{>JgY$|2obDCTuyXQB`6e3vI%2Rmq-*vleQ>%N>^Kly~Y;_O_^+;2B+3_o1oT?(l1w=x* z)GxTwwiGzDfoSR-sKkd^I=02c)#9wq6JT+qfTL?b2fK!K&uXJR^R|?4q zE+%*Ldte9FtZq|sIUpvXeo`|kw5fziU_WJsjUp!hLXXex!wVAUelNxl5msbS@>7tc)-C%W^;rKr{P|1hyJ75EEf6}NjU$Ul||O~F->VF z&6ZZ(4=P?keMD1bnw-b`0&AJMV#?=NvL#VuWq%mWgpt)#)p>eSCA*rEzT5Lx0M|B@ zdKp%*vAGe5m@QN0;iTc6%gt->N$;UusEg>xI?$%NA(1eBpZZCGZvdLwWb2V>9QBK0oCrg<{ z7m|}+bP+j8xI_H7MNVLcA)o{|3!AB6(=sBfQWP35FTk3iX)y0hTtm#j(p9i5)1sAy zE(xMCXXNGWz#K0@eA5u+zUX>8l3<1dLQc~Bj_|wudd=SerJPBCiR7&g6z=Wq;Spd! zyWoMnT7|ayR(0vE(9P4eyf8_UYICc!EvuBZg%0Qooeig{{LO#S1Z~UOq6hI{j-1?4 zvQ|N)zNH9hX1IaEKQ8)NJlsg()kQy#hr<+JS`>+g@2Bv*qKD#PlB?=h7CjsfH&b|8 z(JpJOd}I{#^rDw24CTjKAR-tW*48?VcdOJbYhh!I29{G`^{p%UK8PE$MK9p|E}*aL z&c{hgn?qOFa2pBd1KKLNn0juJWLXqo-&}xc7LgJy&54lud{t{-RLQP@f`XP@wTLdT zVJSImmQbO)18hGsgyt1hMOIj(i*P%J8K*H*s#FqS%n#r+XPJqfr-P)t2ppB|R0xx+ z)8HtuNB3bJnnBnI%B4a_!c#yKgNy;H!pkRZ#vH1U-NT{COKJ$cCw{J+`9b_3T@DF+ zg}XJNCTV}wmODF0{wfsu98xj~41Er}IuT5CXx>FK?)!kJ|NTX{H&lWseXfy&N#ww6 zu)^Hg**p!W7=H;HxfI=i7ECmfNIC)=wK8XOqTzEkSxQg=s%tzZT|=)j$j^n&=HQ;y z*<|@wD9PS_y&=$X0L_F!5YT8&oSTE2G|6&eiGFIS{y9%Lf&>!i0YPvlgrLi?xQ{J# zAJVNQ3qtc&Nv8?hOGs%noj?BIjFdosaFJ}+`t&q+E0$P1dVv8)qbqwNy`I1DBZn zU@I|_khI)c(n}Xskv*y1Do~G623K!7BGHo7E74~*@K}Z={)Px1rXd!va4L}?D6lUh zE==h9kc0_MQ;&Z{ll}=z`WiZd4L4XAZ zO%V^h;~RE<&|+t)E>p2(Z2?9QH4ZWw(t~2B?5T*k{ZFN?Ygx zrphm4VxJ*K27Kc<)WPmN4aBrASPOo_<**xT3f&S^i&kj*<)N6{SE&^h04@*+R!MChmTdnJXKH4u329U>_D`G-&>H1wmIHY4*{I9Pp=4^lcX z14iZxR6p*i$y1CuJ$!h`SOyZ*IKWN{wy$p6LCgakM<&4<=ENu@1ea-)V(g&uC_Nn< z=1a(=r12Vht1vpXj$n`&hn4SwIcR!%{i$n`MN`gC4bZr`&k9!_m#A$2@!T=cs#5enSfUkA3X#{|a2(Uy}OYWxqdmSUMEV^Vlgv?dAW1N8!m8EtA)>Kfu*F*hK z$@~JSb zWR@Aa$PCRkLm6ght{F-+LtZm9w1?*_HbY;Tp;9w++zhQMqG6&+4pRiW>$lWPTza%6 zNDuy?39V=XdR=TVXv8G2WWOZfc%N6AqqK=KB92yWZOh%rdvPUOHvxm=DdL9O84ZT_ zE#!A9^C7mVWPhQwcp=k}E5J&qTvmR>Fo>M_@Rfq`#HhjVWOGfwQ8}L2=<%0iHXBO< zCRrQyMp85c4}uyijSqu+$!+PTf%`D{0uS){@L}+29^gazp;AN;kek!AXrXBUt$Yyy z;x!qih=2tCB1i5HnprKBvV&$rM*?M>e+#Wa1jX~36S5^XbIcda%xUO1J|sQtPBfOy zfPmkaL)o=CG>>71#;0lwS;H*PMAn>|Ehe(O4))L~ZX)+Xt%zoJP*_C-&D;5raik?a ztBd3Gd^x!G7(M5oOV0oYNlYPHo;8fVK8KdUXyFB&k6@aL`$);uW~GaGR7oc%vdxPt`e>v#M5+^&bdfy>W zjH~UXWIwwRd8+hx%$wVGeq1--v5DZhno!QSBu-imTOepUGlF|*Cf|S@%3*_RNV;R< zi)_~SCSr30_5oZ|<*Bu4@Ad8gHJl^D=#0Vr=O`TW!>b?VB8k49Lh!1P#jbQixXuZ+Tq(L0`@{&C zmZWJ=z)*mM97$LuxwIdaCc|{s8@G@!`dt`(p#E7625gjraMA5SCm9e)nT6FZ$yG2- zJ`Vt3ZxY;xYE)dYAbx|BQ6F1?afe|-;ff4-nhBIB?oJ0(LG>`n?1xO5y;na>U z(+>yH9bDvDkBnN=3kWKwEn8;bmh2ar1GUMRK}07>^8{9y~|}S4}mwf~moq z2z_|KtjCvxrn=cxJcBeskHAyv#?-> z5F+Coyo3gxlcN^vXDZRb^?m#Be3RtXJQnHd3RX^WAfw}acyRNaGZ}Py)vny$gTq1( z)XeMzYJk=Sm)_oiFNW3k++-~SQl>S5{RGW7WyWS4(gl8HjUI|zmWyX%axDFAnw!#7ES?iICwPnO%^$thxka9EFE>616>H`j8^r|8E#6{n+$7}G6 z0@u|om}`qR6!14|zQH42sc33VVQH55$N}xZIae0V{Gk2PxwcMm&w`AKfVk)0MEARu zxNAeNBTj+F3HNb5r|Xh2Dz=ZIcu%=rX`Klj3gah*bBZ%n&9x)JAyBq?7m{dL@GB=A zV;3NYZ~=1kwj*vrVhJapAau3@yPS8W9jn_iEK65V9Ii-Eil3*@l6{@#&5g3@gGWH) zvGsraok@OWvW>rH<9@e+Ui4|@EvLt9V&J3=AG>5}X1L;M46byM!tB!d3WH@`sbqs_ zXs_LlA>Vr*|Ft{FKY{$joojuZ^xQ_IB)ihjuKW|NPU4xgQk_RIXOhs@%2_%{`9Ee*g5Ax#`$fMyzHkvR_ zCtn!}Gl)t2#s)00J($CH9*_L6p@27dVb`|ZxA8w z?i6?1Je?aSz$RlZ#UYm0>yNm2&4?3F{T3}TLsmzC1?>0Ci;bCM#eSXwUpfDhW z`9U&fnEO}-;t>n3wsJJN5}7L4t5ay=6~_R;v5f)nTQ3~wUpY`N_1iWdRYU5n^w5&T zsjlX22~?~;fv$UJQdAB_p`fO1iPT|wQqvRMLv4LczuD}@j&Ki(`4td$AG(bDwMQu? z(wI(}Y)2xu z{9u}#!K@cRikSzoOMOUu>d+2;qjS+Z+{4&BF~|>1IqZ&4h|OqcR{*#T#}zAV z%FLB`V-U|vdFJqIpVwlNU4Wzi=*eZoJh=o|&wl`Z2LY*zf*OZLHh_*lchcgfKd8w) zsGyV4^2?_*b~lJZDrkFK@jA3rQ~SWYV=0xVbtI4%-GCGD3D6Ghu)f$9r_WVJzLn1# z55fSVA5%t#iIwQny!Np~{owfBS!*AYW#o(_R(h8eN1{r$7UKaEk^!~e;TeHNaT|LD z0|~2u9Y6*R!?wP+8;unkAh+`m43Yrf;Kop;$k%ifKviCvA?D5n9=v)1XU0v@iT+YM?XwHP{zebVo z!55LgX-;oEBsPKoU}aE(nR2N2IrzsFvk1kQ<_LEk%EvPYk>B>wAmPQZJiJYYNp_jI zdmdfBMVECqhmIrBQS6zD(kzQSLmR$=storHNH%!{183lEt#*e}-)%<;b-h{#aO+q| zk3Iu}!smJ<$yV zRQwjY)sc@*k1U+_@(4-`IUL@_@@Z|MolQWwC{?X+=r$F%$jvp&T&jLTOO^ibg>#5b z#PBi{49;uR`XptLPlSwM0Zjxa6dp=hx4{m9rzYd7l zNkfqXj+!O((7fovbF$nZh-DT;@hbdQh{QlpZudnta?KkxOir zOwdY#Mdm#5vseEe!0PH?g;qo}!}w^RWF1V}ze2Ww1e%=|G5jY4FhjP&?8=;i3+*ie zY!bAEjutz2oh=TycoYhRH>%Ps zC*Yb>KxXl98{U9+$SC@Kz$Z|VsAx=QPH50u-=y6j)M$+VUqcJ5KnHYGd=aJdltX*q zRp8}5R*7TOJw;78mq|hG0qQYCtS-!wZ_ys0E<@;igrLfs^$aH6Zpy_RP*^|#`2e+f z3?Ow3V9R6zFm_XU?9|hv85z8kvDM62jFP?D0|ybhf~GQF!T^Bwz?<-MMO|KppS{GR zjv$Iczu|?oBE)_HFOJgM1JwUTT{K!#3Lhh!2;Ig^thT!;iPZtHsw%Q&bZobpV>>}h z0`{pu0@AlK0xDcHjMoen*~g-(W+mR9 ztEH(RV4FtaYrW%kCH#Y``mM-Ff6yY{1KLjM4hc4Y*_- zIJYg>fV0^=ie7hjY#09YLn@%1{X24yXmvB}()bc!%pp;q(tbCdxIw@3_j}KogZlw3 z!(a*u?DGs9n-DGUtFp<6X3brL~7yd)|U>6P@Ll*HGC(y}Y6ChL&!`p!ncO& z$Qu1GFB=B&9^sgng49<}9zM#OpMXvW)TywHgOK zu+RlqaF8(r7ofy&EoFhF>|tr2YSCXdkH*T-KZ{{He|S!bjqAxhD?V@+Txv=IWZ`H^ z?@G!^Qb!UIjC+Xx=d^>8u^UJsKqukUR(U1{flkFv{561+S{EHK;r8Jn_qB-c)Y{3l z9n}}XzX~yACJ&gSy+@B7{px5}>LIy*@RZgED7-y^6xZMvwxf0F9>8sM)QKLzZb)95 zhlDB1ax>h=;B&y|9Q-3L#r{#y-q7CDKBjtBA8-jZ;y113FqYy*2J%+zfb!YaC`*!l z5FNeapM5-mS z*i|YID4&T^wsydMEc%sIa;TFdi|sc+vDIyp5}PJ3D3#BwT+ya=4IWe4TzRlHxmkM; zmi$PwEVw~F6V)jXO0wT558cwc9Ni6d#3ot}!Vr_O5=f~v?hIDHFU~UhG|wy*7A=Lt{+2j5PLAIi_3jdx88{R zoNcw%s=TOl5k3b#_~nJ{3>n#itLlQ{AcN#z%dn5{Clq(kkG|a4xJrA^d}TJW&Y>mh zS89jyLaO(_40ngX$Sr2llD_XchHZXvY(o|gMMPBV_>aG zUJowJ-3s;;<_jNUd<%WuauV!~mxJmH@qiX~gv-a*-G*W)W|o$=3EheJX0^1<@Yr~;u~C3MBzYOrjg4z7jOE=`xExgN&~RCRgje`066}>@z^aX> zor@Ms{o^=c$vC1eT8lp;(1gAjBZ8Ueg|Sg@nKc%qCv*61e%!LB`wOHBc^WR=Ul<1a z1cPt!{sthYjpUt;EVAReTAf_M3MV3_3*jnH*ZR`Ef&=_O*LwVs23wn_txkj}bC_+x zv4X^_@+5Hkh@Hn{gRxlYs;FW0M`rIecb^tsIoOjTu8{diO~ic>D0o{qGCl|2FHQAw z0Dr6|hrQoLrIT8ft73V64vc*=p*9Qe!NW)k5@On7_Y$36y$f?{GHC~BGJz?lb3Z+D zA0L8bY9%bo$^h8LhDhknmp_69(Q(UAycky+>qzB9?%1&qbEyJ^MJkX=6v_UGeU|QG zDMk6{YtS5%>x11-(d6j|4VtF~7l>agx*Or(`$z)MOlQ0^ga%hjfvXH2q=XhK#Q2E9 zJ9&8aX!sExE{KO)yzpVga0NG;B_dDDT*U35A6(%y2ip^s78RxutTZ1G#vJnEbu?Ty z0ar5%mJTxs8EJB)?09)CNtGe1hfN!z5(n_-VC3Y6GM6Ca2)cU*;o|Wz=`s|A^otDK zOF2P#cMw*T0&<`fhasQfiN+k>9*Tp^8vpkgayL(;Q64>+t?Q+e86N_E;s#Td1nC`? zj!c&J`}mIi+uvbHY3CxzG8e2jutw6e8h_G0tWmBLU=n`7dXwCbR(+XwRNP~!QSB)> zY}TM|+f6cVjG(v!$iV)9a^g3-{)1NvTPZwCmJz6gd9VwnP_Dw|PWil;kdUl6Ok^gq z5M|};LoP=~{}Xa>JgoW==n3LjS@rj^7o7!fq5U=Qq=`&=44F%TjDC@JGViajwNHfF zf~+H8o052wWV=z;$wHayJaDiG-v?sE5{81Hg>csTYt-T!MppE$MRbj7WhZ|-+LB(r z`_mo{0rHceAbTeskiX`7s}gKn=>w{b^JGXtyu`C?1^v7MMdWMIs* zD|jFdjg6Esb_)g`3nQ*V7ZF>uQG~I(7V5;DftF(ht_4>+qV*03$xYB?Zm8{N$LN?$ zCQ0Wt`y92_Cj1?k>eKDMGq|9i;y%<=J=E?yEi6DuxTLf$13Xm3H|#Gb^(o2$;j=!h zZ_2?O^nk0t*H7xCK2x2fXNY@z!x#IUA^KxBP_6VS(E5POi?PYXI57ZAw%8vV%E77vbgxm0=R^qxEnJ-ua7%e*1sYOS<5PQx+!BRp=&hY6Jxax(HckA z0r9^J;|;JMn$<(DIMTi0aDb84vx*hJIMybb#LSI|vA>P<`F{ZjH1`>sa!&kVGakmT zZ}9HoGz?8MaLHhONQ}|Z&*4q&(2Mb|f+7_JSk3de`2@R@*|<3nU`u}i$uC=*PJ;{b zzAphKK*&{+4N^(RaQ)UqK-Bu$gqxX3~Rl=_V?cD{eLNXe&B4lWiEQ zc``x3;x3KeV}nwbionJ|xU~h?QPj*&Z2?9+{rGK&OF-X8u>m&i2_(gK@#PLIMB^5n zR1{=R(ii`eCaLb`!z$aGtomnIU;3IIP0mDbBcGh7FccGDbjCgaYQaLC~2uxM>INhr^(i7Sa#5#kIsRQ^Ea=B=Bo?q_vq!81tdh7XQa!u+o;$ zZ)Pd|PA#V2IbQlLnv36>ZJ9ytq^;u4)B^4#%;wIFeC}K^3(gY{CEN-}^9e1>xNC1& z0T=Jqx2&Zwf8w+w;VEom^w{VQN^Dt%5bj0dHyICtb|fs}se-_H0rNf79b_3{zJ+SO zJlgUYfS@b;9az39^a{7q4L0%S7o&+v5djF8K^FEP!33%7a~>Fttth5;Z8=@C40eXl zeVB{ar3pecj+S^=^Y8V6*I>oT&`O8hoh%2E0_X!>nt$fanm_kumVr@F4m$o$9Y{(} zoV1qvq4+w2N@DMSn%vGoe*|lo`LZXVW|D4`w3>!=9sZKyEJI54;1Bd|xB^;D&G~y3 zs~)K}H~$`b&GSvYX7TSGY%!|V$g>6>eGeVsV^4&}6r1kWwHn$5dE9+=!U0=dxl_B@ zSy=9n6S%6gt)l!7>p(VoYRp3`ta_tEU1(SDaxO3Tuc)f7S_uuNaU?c{xUA+pJOS8H z@FxgRN%-S`7`;6<2gWgU%d^buH}7qkjzhop#^Qo3TygXq#-Zjx7tqLOB6y1e4gbN=5-iS)>5U445 z?iCi3kbPJ87gqO6FW~9Pe)Hj3x^|1&h_UQO-7r4>85qh6699AGX?#d#H*Kb=)XP+5 zxXcB!PhSp2zJNT1z9I3U78CL8@frCm3tBxc9c;ON9P-x^@}B6%Ni3Z(ANHJ;f*nbO zxzgd#FYvR?KmRWBcwo%xh7dxU4{IP)(Z}&O(ZgDNQAI^zb&hPWsL&H3J2qsP)(lmm zV{=Vm2U<|cvWT5WJ|@BgAxTx__8yuQWy9{bSni)kc}Z?4!I!#pYzBrr6RKM(DOPUQ zsI0@!{+k4N2Xnt~bt^9)qZLjloC>nXQ$h9^732^V&|f|zE@qSpvWW^n0?={mTer+@ zF#6~%o7v;X{!K6*-yQoRqSexXMAVvBAq$^QdAL;BF~f%H1Wbgu8w=kGsp*wcK67 zuH^12b_sWHWz)F3mQCVrkfn3?ZkEX1b!;R;EtJ>*cQ>)Gxx1Nt0hdtN9l}gvT@<^! zk-TqlZxeYBaPKzq?%`gNIkFeH_Yv~$;NHi``!C%41bH>?eTuvx?tPlPGWR}9-dgVE z68tsX+e)#^xc4A=7jthXdFOF2Cab{Q@N$$%2G3^j1X2yK3%Iw7ydw7=C$F7*yUBZc z8#S+oykB!KBk$+jdxE@O+{=aZZ*gxQ#U9|^e)8_&-XZe7z`eud-NC)Y__KfEUb5R1{w zm;z5iYb@qIGiI(Q;b1K04l~Bk*1(S1Nvs#%s)2+az~V{4T1ya8JuhU74?jhtV>%oN;_cv@9D@h2KnwC*&3c_hz7m-( zx$ZWLJR=1cW~0n?-2$sT8IcpNyUixMptZrDRZQu@K@#Vmw(V0|k9I4qmbSqIphW!f z%4REYK`~zf0c1Kpc)&{WPuFNjpz_~FY&(_zI?CS%0f^od$LN38KF#0_bK-CG@rIp@ zl%Rj9Wn+iI0Q0nAH0b_>e+R!YKLWAUK#0~{3tkc%vC7#4-eSA~hoN)$b7Cf|5@3}`{d=?Is&?2V(={(=C3^^?UPVVhQuPtZxPn7; zc6=7`F$2jdtddA0M__Z|ju}c4lIOg|lph1j90g;0e+B9H|KhKFJVnij8%)yQ_=F)7 znU2z#6Mx^c4aNLpTgU~d&$NXcqGHDSm%oQ7O~Ye?7tnt0_^Dwu)Hnyvl4J@8c03r5 z=MB;5_`t?ovL|)q;TEN6i%vO|8m;R6w-4w~%fw=n;<1g0r7WO_%0LC=6RC%!GEg=| zZhIE|{+8W2ME94Z^fV_)mx7uu1|{I_r0c${OT6y$jaKUy*LA?x24DMi-56}VsdUtR z=(=tx`DHB3MxAx=V=cOp{*vOG#*A)^@BjJt|IZ#M{jDJU%YO;N)A)AdYsYsS-(T@r zUlfFNd>7!m2Hy?%R^h9|w*}uL_@2hM8{fP5`taFz3PJ|HTzm!imf*Vu-#UDo@jZy| z*Z6kgYsL2=K8DW)Jf`8x$F~CCt@t+Mdl=sf_}cNki?18s*Z79;{a@`}3wRXO**>`- zsp4=!E!xm>nc3`R?z2_55QHk$ z3tp(=Z){OPK~N$h#TpA!O<^v^u_9bVZxrYhgQEm^X<||M zHXwq}B>F%+R)UN1;Kye4C}5=38(cRTWgF3(I6{7WQjI27i{7>(B>);Rm^eNwlb|Xfs#7`6# zQ8a4=krRe4Z0HU3(&V}csc|DtC1-*+llKJLrQVYUdAP#b|*J?MoICutB*ltNZO^7I3}B^5S!Bo7a ztkn+R)y|Raim3F|H_^7_T>|^8Mx69QvNv-~36rddztLZdU1auy>*|NalO?w!^&pTT zZ#xsZ>XWwp#;7p+L!;|RG;D^=k={)dKMr3(_b^%I&zD>b(r3s>)&XP zMiPzDf2TcXS9?*|q^bK^pcMnnB;*%@)OwE`Yb(A#Lh}^a%)g%R`84|>{(94Cf|O~NqnbxNt@Owl0MA}3CyQ7k2WHOR-Rh)#*(c$Gm~U29hr2vH2w779*C-GgJc)9X4C3z zQnu)J>!<&8{pdvl)x(_K z%{pXV-LfFtq8;(zTksw|{PvsiED3%ie7f_n!Ow@kd8wD3Na^rTqICEtQ~FK#PjmRw z;Nx{$mIwcI_)Bl}vhTt#gg+Gi?q7M?_b44cekO+PSmFhzpa*{#{FcSIr-NS&zZJd! z|6=$<;nQhb0epJb@zC{N+<(y6p!Jc)OufdUHfMzr_G4T&%#>u=WWna$RRuz| zs7cbMRv7wd-d~Nz8ZsJj1#%4D4^`WbGioz-2Ew_i@QrEVYY`@Wko#p?_`0<4qO|b!Y2n3b;TzJz^iwky&4<#$ zblO5X2R-8{{JE?QlADOn3fvRgA(v8wDv*o&^H97zrt9Qa>523Fp`;N$CoNnY3PtLu z>^NK!WY>gGx)UT9NL?c#iOSSPGhTpEN^9z3M$Q-`eTGIdfFsoZj5x5szN^9*QS>$hNaN>qxFj11cd3n&kEE0NUqqh54w*d9?6dC zFzY}r$S2Dp3$$!&0>ZTOuu@EZEgl)}%xTWXd-(=GM4Nc9+BW@gsvY9QY};zrYLm)Q zJ4A<8Ct4|K-ZXhHM=Y2YuLieNBA%93gZ2ZUK=-v)&1#fNk5@vjbhmBMtwMg!IJHeY zQG2vsp>`NEX;Yl&5${BYc%}OEcTQ4MlSDft*aqB4TP2*00|_&d}3r)S9nrgB0|YkdNg4r7AG5$aWFO^88T>0NQMnX7Dr=2Lx=uYouNOy zHkS0q%rgG45kxx-^cm<9O$J&-2MDuDe=7qG_%T+l*Rl!zFst$>lCc0X;L2k`BUIg( zjKx!FHF_Ydry|u!GgKJ~8@W}EwErxAtV`F1p-oTb< zv^g5>v0udiPVH4|g5f}u=DEwb_PCae#kkh|A^o;MFX&d(a9}GY1>>n16_|cC?jv76NKe^z-i+(zNhQGEhpw~Av27fj))D(_He;$h` zlCzpyS}(q2_MA&EVb|nG`gd9Nd-wj!rhL%|pq2`7SuIkmJDiWNBYhc{S-yY0?Jkwiy2ECOzLCjT+uV7V zUorp6s}@{+%`X;S`^)PVUBCE-CBM4yrlmLE^6O={-gf))6)W#pwffFAYkzas-Rti8 z?Y;Ni|G@eOAA0za4ZnNzv5k-a?-T7${{9b}o_hM3&0C&*ZtJ$^x9@o2#ho25?Rt6l zD|`O9_tihW*7^FM_w9e<&A0H#@-GM8eeeAbKK$t5p^rcL>*2rs{U4wH^Rv&{S6v|b zUI6;FKz!T%|F+xz%JToB1-kEiV}bs*`#K%{O3>YnZF~We%X+o`CHTSUp>>yJ_N{F^fT*E8qqU9y*}0Z z%9FFMbanB}be_B1}Iu5eDz{LFq1_VvuqQ?O@#X8S=r zA0yXS{dc21^V8eEH-Wz}1jt$SGxfD>R?qxQ{)V*t>-?K9?U|n`pR=y@vKhYx11Wb6 z!udGp@ZDpj;5p-Zgz4bo2=3_fRO~|`pCdg_ZO*RJ!-3T9tQi00%*wIvGdFF;Y-&~6 zlp_1+KnPppDXb(EiRET3mBMJn@V>Hes3z{H+2!scPpd#o&+ z&|@XBU?N!O4^?3=N}E$A=2YnZS$ePZD~;A7O-*3BA{f?-*-nERj;zx5u#BBGpavuj zR@sRIYJvg1q|qO%j#MT?iQw4QgwAd;DTU*akY3`$^Y65HWh8*Jgq@H`qamC?SxX&` z9>5v;4t5z^or@Ox&dwPhFV$<44GntC7t`Yq4SNSYtpi*JesXW#VYU7&vcZi0TQ5;53wyoT)|-j0;Pp31Eb#ZzaX&rlcz z&2!St6a#B!>}iS_rv5(U0bS$Nbfz8{AFhk()D&ZJ>Ia>$q(;YI(#ydtta58|CMWe+ zt51&^$1~wN-H;!w=LYIkb+B$`O7c(kwiFD*RztF_aU7ae2b=WbxFK_dSUqt-G0Pm; zaC5|zM2rzp!)mh1L&$*G9=F>Y&PIFN${y=d6-6x|f+b!qcU4GS8)8(JYNLFrLB z6(yK=Oidx)VUB#*8vgXMY|6y43TtLN!jkc=CQ;}8P<)0zMgKVt3lnE?0zDvs>%>>0 zE#KUs8BuzXrI({;J6XL_yAvp%aMT@@z?YSPWmn{%3Rt#8dmRer0`zPU$J2P4X}oV` zJZHk2RK|0ryp&JRo(2K*B#!dv*_f3_bg3@+Cjdm3%$(9r1WrnU(uV<*?gS`aoQjvE z;+SlVI#W{VRVg2nghBs&_|!H%7a%%KfDMQO^b8XVy1_sFG86IB1`yA4Q~o^o)R)Tv z%D)02I=E#u-aNZ46<-0L_*(@~dusqH_Xt3JdLE$smjTKj455&G2qYKFHD2#!(}4eU z_eE!1*%>Y;W=HuMVtbWI{QY9_ls%XV6zpwPZ^1p0(i;m@6^}kJ@eIJ^AQyhN%?eu8^sXLuMO~Cf`^Y#t4 z@E>jp^y7+I*|~YEaAPoIUhBMJDbd~eni*KJ+Vtn%-bt_eFz=;phQAi&pS)ww9X2z& z*XP{N%p`Bhf2g13i&NzvM)~b4_pdyiy|MD`l^66)|I!skjmfx?nY`zxdu(j_o}cZp z_b$J4_n$id#u$I8$r+uSm7vtnVHz-%A^ga9fZ04@ZofpLHrZ~%qCaKHu>01P;E8{YlO z?cOgOKzu*27w7=C0-J!1z&c z9l%E5K429<<(I-=2+Rf=foVV~zyXDT4HyLMUxxYsxvy)jq@UnScV9J5d}i{x;Q8)0 z7OjK~)<6bpy^MZPl76m{K;uZfrhg!Qm#pfhNpb5Om%`+1`1dw5WPXl@M`!~tp+9~x zE=##9P(F(CeS!K$eOe5DvO%BvPVHpM07?Jd4y)RJNZ`AijXRrrmpjN6@Gd^eZ{>IL z=NHvGLXJxvm9Bwqms@e4>wd!BC_F2?AvB9~#GAxB#r5J7;&ySD_=fnQ_?h^9$svuE zY9zmOmGr2zMS4;CL^@0UiM&u=CEqQtmp8~8<#zf1e3X=tCecww58hP z+Oyir+CJ@l?PG1A=LFB`9>1sF6ZPEXx!3csXQKz5vzhy=5j@A=%pc}|ZGX&ucTq>t zD95jzNmrSBmV2RloBM$KYT+?qpK!dyNwV})=^k*OC%-L!B!4ce;B&H4qbyPGQ+6tE zD#KJwU95(*gtkyyqkX1{o?_2=Xcuj9^bR6pRR@WNWHdlx1J=e!BoBQ|fm)vi;M+@bGPnaphg;wDz^n0`Ls_;MJkHuzjwYXJ$ zMSM*Z6pu1pnXmjpc}V%YlBJ%iUZggl*LSI#p@E^=XzfDnGHt%LR(nj_sU6hHJz>u^ zo;y7|J@iE;FAX&AI8Nlw;TpIoH=A3}ZR9p{S^Tm5sr(q;$Dhx)@z?T;`Q`j}eiz@# zf5d;sewzIZyVrh>eTF?@zu11c{YLwv_P^UF7KMvuJLWo`bG+af?kaN4bR}I6yPkAC z=i2Lf%e6+>AhZil3(pBJ2&z~jP8Y8dcY^=-#DijiG(?i5VyRN9lBP?#6qXXw9O-K5 zI_W0qR_Qm=z0yYMX=$spOFAqaFBi#ixmCVH{*8RE{1kMPqs)O--lhCmc}FQyMRk%| ztzM|sszEiP&QfQqSE#>G7pY6t73w|e1L`B{E*%#;bvilutvCFctm(ocm~?ugPG_Z z;h^wOArE@L2)5fQx5-z^JC#?Iead9DMyp|NGs zDruecAS`whEVe`1EA5vKNQb0PrCfQCTp$mXhs&tE9N)Qww}4;BcZj>i!IB_NgVnc4 zOQj8{*(ovECVS->kkmqXt^A<8L;gS>q~t3cX5lC-VG-uI9m)qvzRKDeqhEskTsQyx?{U`A|LHYuB7l{;XUyJ4A~%6{c-IwtPWLe>Tp=@NR?9^SV5MmYt;>yt9D}~=4pepe62tmjIn6LXe`u5 zVmvxDp=%xSX$vryFVdD^MOmgT*H&R(Tc>T%HfrtKCT+8}RokI;XuGw&S|@4hs5>fw SqY^kOfuj;QDuMrK3H(1XaR1u? literal 0 HcmV?d00001 diff --git a/node_modules/stack-trace/.npmignore b/node_modules/stack-trace/.npmignore new file mode 100644 index 0000000..b59f7e3 --- /dev/null +++ b/node_modules/stack-trace/.npmignore @@ -0,0 +1 @@ +test/ \ No newline at end of file diff --git a/node_modules/stack-trace/License b/node_modules/stack-trace/License new file mode 100644 index 0000000..11ec094 --- /dev/null +++ b/node_modules/stack-trace/License @@ -0,0 +1,19 @@ +Copyright (c) 2011 Felix Geisendörfer (felix@debuggable.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. diff --git a/node_modules/stack-trace/Makefile b/node_modules/stack-trace/Makefile new file mode 100644 index 0000000..a7ce31d --- /dev/null +++ b/node_modules/stack-trace/Makefile @@ -0,0 +1,11 @@ +SHELL := /bin/bash + +test: + @./test/run.js + +release: + git push + git push --tags + npm publish . + +.PHONY: test diff --git a/node_modules/stack-trace/Readme.md b/node_modules/stack-trace/Readme.md new file mode 100644 index 0000000..fcd1b97 --- /dev/null +++ b/node_modules/stack-trace/Readme.md @@ -0,0 +1,98 @@ +# stack-trace + +Get v8 stack traces as an array of CallSite objects. + +## Install + +``` bash +npm install stack-trace +``` + +## Usage + +The stack-trace module makes it easy for you to capture the current stack: + +``` javascript +var stackTrace = require('stack-trace'); +var trace = stackTrace.get(); + +require('assert').strictEqual(trace[0].getFileName(), __filename); +``` + +However, sometimes you have already popped the stack you are interested in, +and all you have left is an `Error` object. This module can help: + +``` javascript +var stackTrace = require('stack-trace'); +var err = new Error('something went wrong'); +var trace = stackTrace.parse(err); + +require('assert').strictEqual(trace[0].getFileName(), __filename); +``` + +Please note that parsing the `Error#stack` property is not perfect, only +certain properties can be retrieved with it as noted in the API docs below. + +## Long stack traces + +stack-trace works great with [long-stack-traces][], when parsing an `err.stack` +that has crossed the event loop boundary, a `CallSite` object returning +`'----------------------------------------'` for `getFileName()` is created. +All other methods of the event loop boundary call site return `null`. + +[long-stack-traces]: https://github.com/tlrobinson/long-stack-traces + +## API + +### stackTrace.get([belowFn]) + +Returns an array of `CallSite` objects, where element `0` is the current call +site. + +When passing a function on the current stack as the `belowFn` parameter, the +returned array will only include `CallSite` objects below this function. + +### stackTrace.parse(err) + +Parses the `err.stack` property of an `Error` object into an array compatible +with those returned by `stackTrace.get()`. However, only the following methods +are implemented on the returned `CallSite` objects. + +* getTypeName +* getFunctionName +* getMethodName +* getFileName +* getLineNumber +* getColumnNumber +* isNative + +Note: Except `getFunctionName()`, all of the above methods return exactly the +same values as you would get from `stackTrace.get()`. `getFunctionName()` +is sometimes a little different, but still useful. + +### CallSite + +The official v8 CallSite object API can be found [here][v8stackapi]. A quick +excerpt: + +> A CallSite object defines the following methods: +> +> * **getThis**: returns the value of this +> * **getTypeName**: returns the type of this as a string. This is the name of the function stored in the constructor field of this, if available, otherwise the object's [[Class]] internal property. +> * **getFunction**: returns the current function +> * **getFunctionName**: returns the name of the current function, typically its name property. If a name property is not available an attempt will be made to try to infer a name from the function's context. +> * **getMethodName**: returns the name of the property of this or one of its prototypes that holds the current function +> * **getFileName**: if this function was defined in a script returns the name of the script +> * **getLineNumber**: if this function was defined in a script returns the current line number +> * **getColumnNumber**: if this function was defined in a script returns the current column number +> * **getEvalOrigin**: if this function was created using a call to eval returns a CallSite object representing the location where eval was called +> * **isToplevel**: is this a toplevel invocation, that is, is this the global object? +> * **isEval**: does this call take place in code defined by a call to eval? +> * **isNative**: is this call in native V8 code? +> * **isConstructor**: is this a constructor call? + +[v8stackapi]: http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi + +## License + +stack-trace is licensed under the MIT license. diff --git a/node_modules/stack-trace/lib/stack-trace.js b/node_modules/stack-trace/lib/stack-trace.js new file mode 100644 index 0000000..a7c38aa --- /dev/null +++ b/node_modules/stack-trace/lib/stack-trace.js @@ -0,0 +1,111 @@ +exports.get = function(belowFn) { + var oldLimit = Error.stackTraceLimit; + Error.stackTraceLimit = Infinity; + + var dummyObject = {}; + + var v8Handler = Error.prepareStackTrace; + Error.prepareStackTrace = function(dummyObject, v8StackTrace) { + return v8StackTrace; + }; + Error.captureStackTrace(dummyObject, belowFn || exports.get); + + var v8StackTrace = dummyObject.stack; + Error.prepareStackTrace = v8Handler; + Error.stackTraceLimit = oldLimit; + + return v8StackTrace; +}; + +exports.parse = function(err) { + if (!err.stack) { + return []; + } + + var self = this; + var lines = err.stack.split('\n').slice(1); + + return lines + .map(function(line) { + if (line.match(/^\s*[-]{4,}$/)) { + return self._createParsedCallSite({ + fileName: line, + lineNumber: null, + functionName: null, + typeName: null, + methodName: null, + columnNumber: null, + 'native': null, + }); + } + + var lineMatch = line.match(/at (?:(.+)\s+)?\(?(?:(.+?):(\d+):(\d+)|([^)]+))\)?/); + if (!lineMatch) { + return; + } + + var object = null; + var method = null; + var functionName = null; + var typeName = null; + var methodName = null; + var isNative = (lineMatch[5] === 'native'); + + if (lineMatch[1]) { + var methodMatch = lineMatch[1].match(/([^\.]+)(?:\.(.+))?/); + object = methodMatch[1]; + method = methodMatch[2]; + functionName = lineMatch[1]; + typeName = 'Object'; + } + + if (method) { + typeName = object; + methodName = method; + } + + if (method === '') { + methodName = null; + functionName = ''; + } + + var properties = { + fileName: lineMatch[2] || null, + lineNumber: parseInt(lineMatch[3], 10) || null, + functionName: functionName, + typeName: typeName, + methodName: methodName, + columnNumber: parseInt(lineMatch[4], 10) || null, + 'native': isNative, + }; + + return self._createParsedCallSite(properties); + }) + .filter(function(callSite) { + return !!callSite; + }); +}; + +exports._createParsedCallSite = function(properties) { + var methods = {}; + for (var property in properties) { + var prefix = 'get'; + if (property === 'native') { + prefix = 'is'; + } + var method = prefix + property.substr(0, 1).toUpperCase() + property.substr(1); + + (function(property) { + methods[method] = function() { + return properties[property]; + } + })(property); + } + + var callSite = Object.create(methods); + for (var property in properties) { + callSite[property] = properties[property]; + } + + return callSite; +}; diff --git a/node_modules/stack-trace/package.json b/node_modules/stack-trace/package.json new file mode 100644 index 0000000..8913765 --- /dev/null +++ b/node_modules/stack-trace/package.json @@ -0,0 +1,89 @@ +{ + "_args": [ + [ + { + "raw": "stack-trace@0.0.x", + "scope": null, + "escapedName": "stack-trace", + "name": "stack-trace", + "rawSpec": "0.0.x", + "spec": ">=0.0.0 <0.1.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/winston" + ] + ], + "_from": "stack-trace@>=0.0.0 <0.1.0", + "_id": "stack-trace@0.0.9", + "_inCache": true, + "_location": "/stack-trace", + "_npmUser": { + "name": "sebastianhoitz", + "email": "hoitz@komola.de" + }, + "_npmVersion": "1.3.24", + "_phantomChildren": {}, + "_requested": { + "raw": "stack-trace@0.0.x", + "scope": null, + "escapedName": "stack-trace", + "name": "stack-trace", + "rawSpec": "0.0.x", + "spec": ">=0.0.0 <0.1.0", + "type": "range" + }, + "_requiredBy": [ + "/winston" + ], + "_resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz", + "_shasum": "a8f6eaeca90674c333e7c43953f275b451510695", + "_shrinkwrap": null, + "_spec": "stack-trace@0.0.x", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/winston", + "author": { + "name": "Felix Geisendörfer", + "email": "felix@debuggable.com", + "url": "http://debuggable.com/" + }, + "bugs": { + "url": "https://github.com/felixge/node-stack-trace/issues" + }, + "dependencies": {}, + "description": "Get v8 stack traces as an array of CallSite objects.", + "devDependencies": { + "far": "0.0.3", + "long-stack-traces": "0.1.2" + }, + "directories": {}, + "dist": { + "shasum": "a8f6eaeca90674c333e7c43953f275b451510695", + "tarball": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz" + }, + "engines": { + "node": "*" + }, + "homepage": "https://github.com/felixge/node-stack-trace", + "main": "./lib/stack-trace", + "maintainers": [ + { + "name": "felixge", + "email": "felix@debuggable.com" + }, + { + "name": "tim-smart", + "email": "tim@fostle.com" + }, + { + "name": "sebastianhoitz", + "email": "hoitz@komola.de" + } + ], + "name": "stack-trace", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/felixge/node-stack-trace.git" + }, + "version": "0.0.9" +} diff --git a/node_modules/stream-combiner/.npmignore b/node_modules/stream-combiner/.npmignore new file mode 100644 index 0000000..13abef4 --- /dev/null +++ b/node_modules/stream-combiner/.npmignore @@ -0,0 +1,3 @@ +node_modules +node_modules/* +npm_debug.log diff --git a/node_modules/stream-combiner/.travis.yml b/node_modules/stream-combiner/.travis.yml new file mode 100644 index 0000000..895dbd3 --- /dev/null +++ b/node_modules/stream-combiner/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - 0.6 + - 0.8 diff --git a/node_modules/stream-combiner/LICENSE b/node_modules/stream-combiner/LICENSE new file mode 100644 index 0000000..6d03581 --- /dev/null +++ b/node_modules/stream-combiner/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2012 'Dominic Tarr' + +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/stream-combiner/README.md b/node_modules/stream-combiner/README.md new file mode 100644 index 0000000..9c1b52e --- /dev/null +++ b/node_modules/stream-combiner/README.md @@ -0,0 +1,55 @@ +# stream-combiner + +[![npm version](https://img.shields.io/npm/v/stream-combiner.svg)](https://npmjs.org/package/stream-combiner) +[![Travis CI](https://travis-ci.org/dominictarr/stream-combiner.svg)](https://travis-ci.org/dominictarr/stream-combiner) + +## Combine (stream1,...,streamN) + +Turn a pipeline into a single stream. `Combine` returns a stream that writes to the first stream +and reads from the last stream. + +Listening for 'error' will recieve errors from all streams inside the pipe. + +```js +var Combine = require('stream-combiner') +var es = require('event-stream') + +Combine( // connect streams together with `pipe` + process.openStdin(), // open stdin + es.split(), // split stream to break on newlines + es.map(function (data, callback) { // turn this async function into a stream + var repr = util.inspect(JSON.parse(data)) // render it nicely + callback(null, repr) + }), + process.stdout // pipe it to stdout ! +) +``` + +Can also be called with an array: + +```js +var combinedStream = Combine([ + stream1, + stream2, +]); +``` + +Or to combine gulp plugins: + +```js +function coffeePipe() { + return Combine( + coffeescript(), + coffeelint.reporter('fail').on('error', function(){ + gutil.beep() + gulp.run('lint') + }) +} + +//usage: +gulp.src().pipe(coffeePipe()); +``` + +## License + +MIT diff --git a/node_modules/stream-combiner/index.js b/node_modules/stream-combiner/index.js new file mode 100644 index 0000000..e23374c --- /dev/null +++ b/node_modules/stream-combiner/index.js @@ -0,0 +1,45 @@ +var duplexer = require('duplexer') +var through = require('through') + +module.exports = function () { + var streams + + if(arguments.length == 1 && Array.isArray(arguments[0])) { + streams = arguments[0] + } else { + streams = [].slice.call(arguments) + } + + if(streams.length == 0) + return through() + else if(streams.length == 1) + return streams[0] + + var first = streams[0] + , last = streams[streams.length - 1] + , thepipe = duplexer(first, last) + + //pipe all the streams together + + function recurse (streams) { + if(streams.length < 2) + return + streams[0].pipe(streams[1]) + recurse(streams.slice(1)) + } + + recurse(streams) + + function onerror () { + var args = [].slice.call(arguments) + args.unshift('error') + thepipe.emit.apply(thepipe, args) + } + + //es.duplex already reemits the error from the first and last stream. + //add a listener for the inner streams in the pipeline. + for(var i = 1; i < streams.length - 1; i ++) + streams[i].on('error', onerror) + + return thepipe +} diff --git a/node_modules/stream-combiner/package.json b/node_modules/stream-combiner/package.json new file mode 100644 index 0000000..7f5abde --- /dev/null +++ b/node_modules/stream-combiner/package.json @@ -0,0 +1,86 @@ +{ + "_args": [ + [ + { + "raw": "stream-combiner@^0.2.2", + "scope": null, + "escapedName": "stream-combiner", + "name": "stream-combiner", + "rawSpec": "^0.2.2", + "spec": ">=0.2.2 <0.3.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/jsftp" + ] + ], + "_from": "stream-combiner@>=0.2.2 <0.3.0", + "_id": "stream-combiner@0.2.2", + "_inCache": true, + "_location": "/stream-combiner", + "_nodeVersion": "0.12.4", + "_npmUser": { + "name": "dominictarr", + "email": "dominic.tarr@gmail.com" + }, + "_npmVersion": "2.11.0", + "_phantomChildren": {}, + "_requested": { + "raw": "stream-combiner@^0.2.2", + "scope": null, + "escapedName": "stream-combiner", + "name": "stream-combiner", + "rawSpec": "^0.2.2", + "spec": ">=0.2.2 <0.3.0", + "type": "range" + }, + "_requiredBy": [ + "/jsftp" + ], + "_resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "_shasum": "aec8cbac177b56b6f4fa479ced8c1912cee52858", + "_shrinkwrap": null, + "_spec": "stream-combiner@^0.2.2", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/jsftp", + "author": { + "name": "'Dominic Tarr'", + "email": "dominic.tarr@gmail.com", + "url": "http://dominictarr.com" + }, + "bugs": { + "url": "https://github.com/dominictarr/stream-combiner/issues" + }, + "dependencies": { + "duplexer": "~0.1.1", + "through": "~2.3.4" + }, + "description": "[![npm version](https://img.shields.io/npm/v/stream-combiner.svg)](https://npmjs.org/package/stream-combiner) [![Travis CI](https://travis-ci.org/dominictarr/stream-combiner.svg)](https://travis-ci.org/dominictarr/stream-combiner)", + "devDependencies": { + "event-stream": "~3.0.7", + "tape": "~2.3.0" + }, + "directories": {}, + "dist": { + "shasum": "aec8cbac177b56b6f4fa479ced8c1912cee52858", + "tarball": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz" + }, + "gitHead": "5a8ab6f1843d08d89801eecd91ff10be65b667a0", + "homepage": "https://github.com/dominictarr/stream-combiner", + "license": "MIT", + "maintainers": [ + { + "name": "dominictarr", + "email": "dominic.tarr@gmail.com" + } + ], + "name": "stream-combiner", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/dominictarr/stream-combiner.git" + }, + "scripts": { + "test": "set -e; for t in test/*.js; do node $t; done" + }, + "version": "0.2.2" +} diff --git a/node_modules/stream-combiner/test/index.js b/node_modules/stream-combiner/test/index.js new file mode 100644 index 0000000..97cd73e --- /dev/null +++ b/node_modules/stream-combiner/test/index.js @@ -0,0 +1,65 @@ +var es = require('event-stream') +var combine = require('..') +var test = require('tape') + +test('do not duplicate errors', function (test) { + + var errors = 0; + var pipe = combine( + es.through(function(data) { + return this.emit('data', data); + }), + es.through(function(data) { + return this.emit('error', new Error(data)); + }) + ) + + pipe.on('error', function(err) { + errors++ + test.ok(errors, 'expected error count') + process.nextTick(function () { + return test.end(); + }) + }) + + return pipe.write('meh'); +}) + +test('3 pipe do not duplicate errors', function (test) { + + var errors = 0; + var pipe = combine( + es.through(function(data) { + return this.emit('data', data); + }), + es.through(function(data) { + return this.emit('error', new Error(data)); + }), + es.through() + ) + + pipe.on('error', function(err) { + errors++ + test.ok(errors, 'expected error count') + process.nextTick(function () { + return test.end(); + }) + }) + + return pipe.write('meh'); + +}) + +test('0 argument through stream', function (test) { + test.plan(3) + var pipe = combine() + , expected = [ 'beep', 'boop', 'robots' ] + + pipe.pipe(es.through(function(data) { + test.equal(data, expected.shift()) + })) + pipe.write('beep') + pipe.write('boop') + pipe.end('robots') +}) + diff --git a/node_modules/streamsearch/LICENSE b/node_modules/streamsearch/LICENSE new file mode 100644 index 0000000..290762e --- /dev/null +++ b/node_modules/streamsearch/LICENSE @@ -0,0 +1,19 @@ +Copyright Brian White. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/streamsearch/README.md b/node_modules/streamsearch/README.md new file mode 100644 index 0000000..6310c20 --- /dev/null +++ b/node_modules/streamsearch/README.md @@ -0,0 +1,87 @@ +Description +=========== + +streamsearch is a module for [node.js](http://nodejs.org/) that allows searching a stream using the Boyer-Moore-Horspool algorithm. + +This module is based heavily on the Streaming Boyer-Moore-Horspool C++ implementation by Hongli Lai [here](https://github.com/FooBarWidget/boyer-moore-horspool). + + +Requirements +============ + +* [node.js](http://nodejs.org/) -- v0.8.0 or newer + + +Installation +============ + + npm install streamsearch + +Example +======= + +```javascript + var StreamSearch = require('streamsearch'), + inspect = require('util').inspect; + + var needle = new Buffer([13, 10]), // CRLF + s = new StreamSearch(needle), + chunks = [ + new Buffer('foo'), + new Buffer(' bar'), + new Buffer('\r'), + new Buffer('\n'), + new Buffer('baz, hello\r'), + new Buffer('\n world.'), + new Buffer('\r\n Node.JS rules!!\r\n\r\n') + ]; + s.on('info', function(isMatch, data, start, end) { + if (data) + console.log('data: ' + inspect(data.toString('ascii', start, end))); + if (isMatch) + console.log('match!'); + }); + for (var i = 0, len = chunks.length; i < len; ++i) + s.push(chunks[i]); + + // output: + // + // data: 'foo' + // data: ' bar' + // match! + // data: 'baz, hello' + // match! + // data: ' world.' + // match! + // data: ' Node.JS rules!!' + // match! + // data: '' + // match! +``` + + +API +=== + +Events +------ + +* **info**(< _boolean_ >isMatch[, < _Buffer_ >chunk, < _integer_ >start, < _integer_ >end]) - A match _may_ or _may not_ have been made. In either case, a preceding `chunk` of data _may_ be available that did not match the needle. Data (if available) is in `chunk` between `start` (inclusive) and `end` (exclusive). + + +Properties +---------- + +* **maxMatches** - < _integer_ > - The maximum number of matches. Defaults to Infinity. + +* **matches** - < _integer_ > - The current match count. + + +Functions +--------- + +* **(constructor)**(< _mixed_ >needle) - Creates and returns a new instance for searching for a _Buffer_ or _string_ `needle`. + +* **push**(< _Buffer_ >chunk) - _integer_ - Processes `chunk`. The return value is the last processed index in `chunk` + 1. + +* **reset**() - _(void)_ - Resets internal state. Useful for when you wish to start searching a new/different stream for example. diff --git a/node_modules/streamsearch/lib/sbmh.js b/node_modules/streamsearch/lib/sbmh.js new file mode 100644 index 0000000..dbefbc1 --- /dev/null +++ b/node_modules/streamsearch/lib/sbmh.js @@ -0,0 +1,213 @@ +/* + Based heavily on the Streaming Boyer-Moore-Horspool C++ implementation + by Hongli Lai at: https://github.com/FooBarWidget/boyer-moore-horspool +*/ +var EventEmitter = require('events').EventEmitter, + inherits = require('util').inherits; + +function jsmemcmp(buf1, pos1, buf2, pos2, num) { + for (var i = 0; i < num; ++i, ++pos1, ++pos2) + if (buf1[pos1] !== buf2[pos2]) + return false; + return true; +} + +function SBMH(needle) { + if (typeof needle === 'string') + needle = new Buffer(needle); + var i, j, needle_len = needle.length; + + this.maxMatches = Infinity; + this.matches = 0; + + this._occ = new Array(256); + this._lookbehind_size = 0; + this._needle = needle; + this._bufpos = 0; + + this._lookbehind = new Buffer(needle_len); + + // Initialize occurrence table. + for (j = 0; j < 256; ++j) + this._occ[j] = needle_len; + + // Populate occurrence table with analysis of the needle, + // ignoring last letter. + if (needle_len >= 1) { + for (i = 0; i < needle_len - 1; ++i) + this._occ[needle[i]] = needle_len - 1 - i; + } +} +inherits(SBMH, EventEmitter); + +SBMH.prototype.reset = function() { + this._lookbehind_size = 0; + this.matches = 0; + this._bufpos = 0; +}; + +SBMH.prototype.push = function(chunk, pos) { + var r, chlen; + if (!Buffer.isBuffer(chunk)) + chunk = new Buffer(chunk, 'binary'); + chlen = chunk.length; + this._bufpos = pos || 0; + while (r !== chlen && this.matches < this.maxMatches) + r = this._sbmh_feed(chunk); + return r; +}; + +SBMH.prototype._sbmh_feed = function(data) { + var len = data.length, needle = this._needle, needle_len = needle.length; + + // Positive: points to a position in `data` + // pos == 3 points to data[3] + // Negative: points to a position in the lookbehind buffer + // pos == -2 points to lookbehind[lookbehind_size - 2] + var pos = -this._lookbehind_size, + last_needle_char = needle[needle_len - 1], + occ = this._occ, + lookbehind = this._lookbehind; + + if (pos < 0) { + // Lookbehind buffer is not empty. Perform Boyer-Moore-Horspool + // search with character lookup code that considers both the + // lookbehind buffer and the current round's haystack data. + // + // Loop until + // there is a match. + // or until + // we've moved past the position that requires the + // lookbehind buffer. In this case we switch to the + // optimized loop. + // or until + // the character to look at lies outside the haystack. + while (pos < 0 && pos <= len - needle_len) { + var ch = this._sbmh_lookup_char(data, pos + needle_len - 1); + + if (ch === last_needle_char + && this._sbmh_memcmp(data, pos, needle_len - 1)) { + this._lookbehind_size = 0; + ++this.matches; + if (pos > -this._lookbehind_size) + this.emit('info', true, lookbehind, 0, this._lookbehind_size + pos); + else + this.emit('info', true); + + this._bufpos = pos + needle_len; + return pos + needle_len; + } else + pos += occ[ch]; + } + + // No match. + + if (pos < 0) { + // There's too few data for Boyer-Moore-Horspool to run, + // so let's use a different algorithm to skip as much as + // we can. + // Forward pos until + // the trailing part of lookbehind + data + // looks like the beginning of the needle + // or until + // pos == 0 + while (pos < 0 && !this._sbmh_memcmp(data, pos, len - pos)) + pos++; + } + + if (pos >= 0) { + // Discard lookbehind buffer. + this.emit('info', false, lookbehind, 0, this._lookbehind_size); + this._lookbehind_size = 0; + } else { + // Cut off part of the lookbehind buffer that has + // been processed and append the entire haystack + // into it. + var bytesToCutOff = this._lookbehind_size + pos; + + if (bytesToCutOff > 0) { + // The cut off data is guaranteed not to contain the needle. + this.emit('info', false, lookbehind, 0, bytesToCutOff); + } + + lookbehind.copy(lookbehind, 0, bytesToCutOff, + this._lookbehind_size - bytesToCutOff); + this._lookbehind_size -= bytesToCutOff; + + data.copy(lookbehind, this._lookbehind_size); + this._lookbehind_size += len; + + this._bufpos = len; + return len; + } + } + + if (pos >= 0) + pos += this._bufpos; + + // Lookbehind buffer is now empty. Perform Boyer-Moore-Horspool + // search with optimized character lookup code that only considers + // the current round's haystack data. + while (pos <= len - needle_len) { + var ch = data[pos + needle_len - 1]; + + if (ch === last_needle_char + && data[pos] === needle[0] + && jsmemcmp(needle, 0, data, pos, needle_len - 1)) { + ++this.matches; + if (pos > 0) + this.emit('info', true, data, this._bufpos, pos); + else + this.emit('info', true); + + this._bufpos = pos + needle_len; + return pos + needle_len; + } else + pos += occ[ch]; + } + + // There was no match. If there's trailing haystack data that we cannot + // match yet using the Boyer-Moore-Horspool algorithm (because the trailing + // data is less than the needle size) then match using a modified + // algorithm that starts matching from the beginning instead of the end. + // Whatever trailing data is left after running this algorithm is added to + // the lookbehind buffer. + if (pos < len) { + while (pos < len && (data[pos] !== needle[0] + || !jsmemcmp(data, pos, needle, 0, len - pos))) { + ++pos; + } + if (pos < len) { + data.copy(lookbehind, 0, pos, pos + (len - pos)); + this._lookbehind_size = len - pos; + } + } + + // Everything until pos is guaranteed not to contain needle data. + if (pos > 0) + this.emit('info', false, data, this._bufpos, pos < len ? pos : len); + + this._bufpos = len; + return len; +}; + +SBMH.prototype._sbmh_lookup_char = function(data, pos) { + if (pos < 0) + return this._lookbehind[this._lookbehind_size + pos]; + else + return data[pos]; +} + +SBMH.prototype._sbmh_memcmp = function(data, pos, len) { + var i = 0; + + while (i < len) { + if (this._sbmh_lookup_char(data, pos + i) === this._needle[i]) + ++i; + else + return false; + } + return true; +} + +module.exports = SBMH; diff --git a/node_modules/streamsearch/package.json b/node_modules/streamsearch/package.json new file mode 100644 index 0000000..f92c102 --- /dev/null +++ b/node_modules/streamsearch/package.json @@ -0,0 +1,92 @@ +{ + "_args": [ + [ + { + "raw": "streamsearch@~0.1.2", + "scope": null, + "escapedName": "streamsearch", + "name": "streamsearch", + "rawSpec": "~0.1.2", + "spec": ">=0.1.2 <0.2.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/ssh2-streams" + ] + ], + "_from": "streamsearch@>=0.1.2 <0.2.0", + "_id": "streamsearch@0.1.2", + "_inCache": true, + "_location": "/streamsearch", + "_npmUser": { + "name": "mscdex", + "email": "mscdex@mscdex.net" + }, + "_npmVersion": "1.2.18", + "_phantomChildren": {}, + "_requested": { + "raw": "streamsearch@~0.1.2", + "scope": null, + "escapedName": "streamsearch", + "name": "streamsearch", + "rawSpec": "~0.1.2", + "spec": ">=0.1.2 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/ssh2-streams" + ], + "_resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "_shasum": "808b9d0e56fc273d809ba57338e929919a1a9f1a", + "_shrinkwrap": null, + "_spec": "streamsearch@~0.1.2", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/ssh2-streams", + "author": { + "name": "Brian White", + "email": "mscdex@mscdex.net" + }, + "bugs": { + "url": "https://github.com/mscdex/streamsearch/issues" + }, + "dependencies": {}, + "description": "Streaming Boyer-Moore-Horspool searching for node.js", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "808b9d0e56fc273d809ba57338e929919a1a9f1a", + "tarball": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz" + }, + "engines": { + "node": ">=0.8.0" + }, + "homepage": "https://github.com/mscdex/streamsearch#readme", + "keywords": [ + "stream", + "horspool", + "boyer-moore-horspool", + "boyer-moore", + "search" + ], + "licenses": [ + { + "type": "MIT", + "url": "http://github.com/mscdex/streamsearch/raw/master/LICENSE" + } + ], + "main": "./lib/sbmh", + "maintainers": [ + { + "name": "mscdex", + "email": "mscdex@mscdex.net" + } + ], + "name": "streamsearch", + "optionalDependencies": {}, + "readme": "Description\n===========\n\nstreamsearch is a module for [node.js](http://nodejs.org/) that allows searching a stream using the Boyer-Moore-Horspool algorithm.\n\nThis module is based heavily on the Streaming Boyer-Moore-Horspool C++ implementation by Hongli Lai [here](https://github.com/FooBarWidget/boyer-moore-horspool).\n\n\nRequirements\n============\n\n* [node.js](http://nodejs.org/) -- v0.8.0 or newer\n\n\nInstallation\n============\n\n npm install streamsearch\n\nExample\n=======\n\n```javascript\n var StreamSearch = require('streamsearch'),\n inspect = require('util').inspect;\n\n var needle = new Buffer([13, 10]), // CRLF\n s = new StreamSearch(needle),\n chunks = [\n new Buffer('foo'),\n new Buffer(' bar'),\n new Buffer('\\r'),\n new Buffer('\\n'),\n new Buffer('baz, hello\\r'),\n new Buffer('\\n world.'),\n new Buffer('\\r\\n Node.JS rules!!\\r\\n\\r\\n')\n ];\n s.on('info', function(isMatch, data, start, end) {\n if (data)\n console.log('data: ' + inspect(data.toString('ascii', start, end)));\n if (isMatch)\n console.log('match!');\n });\n for (var i = 0, len = chunks.length; i < len; ++i)\n s.push(chunks[i]);\n\n // output:\n //\n // data: 'foo'\n // data: ' bar'\n // match!\n // data: 'baz, hello'\n // match!\n // data: ' world.'\n // match!\n // data: ' Node.JS rules!!'\n // match!\n // data: ''\n // match!\n```\n\n\nAPI\n===\n\nEvents\n------\n\n* **info**(< _boolean_ >isMatch[, < _Buffer_ >chunk, < _integer_ >start, < _integer_ >end]) - A match _may_ or _may not_ have been made. In either case, a preceding `chunk` of data _may_ be available that did not match the needle. Data (if available) is in `chunk` between `start` (inclusive) and `end` (exclusive).\n\n\nProperties\n----------\n\n* **maxMatches** - < _integer_ > - The maximum number of matches. Defaults to Infinity.\n\n* **matches** - < _integer_ > - The current match count.\n\n\nFunctions\n---------\n\n* **(constructor)**(< _mixed_ >needle) - Creates and returns a new instance for searching for a _Buffer_ or _string_ `needle`.\n\n* **push**(< _Buffer_ >chunk) - _integer_ - Processes `chunk`. The return value is the last processed index in `chunk` + 1.\n\n* **reset**() - _(void)_ - Resets internal state. Useful for when you wish to start searching a new/different stream for example.\n", + "readmeFilename": "README.md", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/mscdex/streamsearch.git" + }, + "scripts": {}, + "version": "0.1.2" +} diff --git a/node_modules/string_decoder/.npmignore b/node_modules/string_decoder/.npmignore new file mode 100644 index 0000000..206320c --- /dev/null +++ b/node_modules/string_decoder/.npmignore @@ -0,0 +1,2 @@ +build +test diff --git a/node_modules/string_decoder/LICENSE b/node_modules/string_decoder/LICENSE new file mode 100644 index 0000000..6de584a --- /dev/null +++ b/node_modules/string_decoder/LICENSE @@ -0,0 +1,20 @@ +Copyright Joyent, Inc. and other Node contributors. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/string_decoder/README.md b/node_modules/string_decoder/README.md new file mode 100644 index 0000000..4d2aa00 --- /dev/null +++ b/node_modules/string_decoder/README.md @@ -0,0 +1,7 @@ +**string_decoder.js** (`require('string_decoder')`) from Node.js core + +Copyright Joyent, Inc. and other Node contributors. See LICENCE file for details. + +Version numbers match the versions found in Node core, e.g. 0.10.24 matches Node 0.10.24, likewise 0.11.10 matches Node 0.11.10. **Prefer the stable version over the unstable.** + +The *build/* directory contains a build script that will scrape the source from the [joyent/node](https://github.com/joyent/node) repo given a specific Node version. \ No newline at end of file diff --git a/node_modules/string_decoder/index.js b/node_modules/string_decoder/index.js new file mode 100644 index 0000000..b00e54f --- /dev/null +++ b/node_modules/string_decoder/index.js @@ -0,0 +1,221 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var Buffer = require('buffer').Buffer; + +var isBufferEncoding = Buffer.isEncoding + || function(encoding) { + switch (encoding && encoding.toLowerCase()) { + case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; + default: return false; + } + } + + +function assertEncoding(encoding) { + if (encoding && !isBufferEncoding(encoding)) { + throw new Error('Unknown encoding: ' + encoding); + } +} + +// StringDecoder provides an interface for efficiently splitting a series of +// buffers into a series of JS strings without breaking apart multi-byte +// characters. CESU-8 is handled as part of the UTF-8 encoding. +// +// @TODO Handling all encodings inside a single object makes it very difficult +// to reason about this code, so it should be split up in the future. +// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code +// points as used by CESU-8. +var StringDecoder = exports.StringDecoder = function(encoding) { + this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); + assertEncoding(encoding); + switch (this.encoding) { + case 'utf8': + // CESU-8 represents each of Surrogate Pair by 3-bytes + this.surrogateSize = 3; + break; + case 'ucs2': + case 'utf16le': + // UTF-16 represents each of Surrogate Pair by 2-bytes + this.surrogateSize = 2; + this.detectIncompleteChar = utf16DetectIncompleteChar; + break; + case 'base64': + // Base-64 stores 3 bytes in 4 chars, and pads the remainder. + this.surrogateSize = 3; + this.detectIncompleteChar = base64DetectIncompleteChar; + break; + default: + this.write = passThroughWrite; + return; + } + + // Enough space to store all bytes of a single character. UTF-8 needs 4 + // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). + this.charBuffer = new Buffer(6); + // Number of bytes received for the current incomplete multi-byte character. + this.charReceived = 0; + // Number of bytes expected for the current incomplete multi-byte character. + this.charLength = 0; +}; + + +// write decodes the given buffer and returns it as JS string that is +// guaranteed to not contain any partial multi-byte characters. Any partial +// character found at the end of the buffer is buffered up, and will be +// returned when calling write again with the remaining bytes. +// +// Note: Converting a Buffer containing an orphan surrogate to a String +// currently works, but converting a String to a Buffer (via `new Buffer`, or +// Buffer#write) will replace incomplete surrogates with the unicode +// replacement character. See https://codereview.chromium.org/121173009/ . +StringDecoder.prototype.write = function(buffer) { + var charStr = ''; + // if our last write ended with an incomplete multibyte character + while (this.charLength) { + // determine how many remaining bytes this buffer has to offer for this char + var available = (buffer.length >= this.charLength - this.charReceived) ? + this.charLength - this.charReceived : + buffer.length; + + // add the new bytes to the char buffer + buffer.copy(this.charBuffer, this.charReceived, 0, available); + this.charReceived += available; + + if (this.charReceived < this.charLength) { + // still not enough chars in this buffer? wait for more ... + return ''; + } + + // remove bytes belonging to the current character from the buffer + buffer = buffer.slice(available, buffer.length); + + // get the character that was split + charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); + + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + var charCode = charStr.charCodeAt(charStr.length - 1); + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + this.charLength += this.surrogateSize; + charStr = ''; + continue; + } + this.charReceived = this.charLength = 0; + + // if there are no more bytes in this buffer, just emit our char + if (buffer.length === 0) { + return charStr; + } + break; + } + + // determine and set charLength / charReceived + this.detectIncompleteChar(buffer); + + var end = buffer.length; + if (this.charLength) { + // buffer the incomplete character bytes we got + buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); + end -= this.charReceived; + } + + charStr += buffer.toString(this.encoding, 0, end); + + var end = charStr.length - 1; + var charCode = charStr.charCodeAt(end); + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + var size = this.surrogateSize; + this.charLength += size; + this.charReceived += size; + this.charBuffer.copy(this.charBuffer, size, 0, size); + buffer.copy(this.charBuffer, 0, 0, size); + return charStr.substring(0, end); + } + + // or just emit the charStr + return charStr; +}; + +// detectIncompleteChar determines if there is an incomplete UTF-8 character at +// the end of the given buffer. If so, it sets this.charLength to the byte +// length that character, and sets this.charReceived to the number of bytes +// that are available for this character. +StringDecoder.prototype.detectIncompleteChar = function(buffer) { + // determine how many bytes we have to check at the end of this buffer + var i = (buffer.length >= 3) ? 3 : buffer.length; + + // Figure out if one of the last i bytes of our buffer announces an + // incomplete char. + for (; i > 0; i--) { + var c = buffer[buffer.length - i]; + + // See http://en.wikipedia.org/wiki/UTF-8#Description + + // 110XXXXX + if (i == 1 && c >> 5 == 0x06) { + this.charLength = 2; + break; + } + + // 1110XXXX + if (i <= 2 && c >> 4 == 0x0E) { + this.charLength = 3; + break; + } + + // 11110XXX + if (i <= 3 && c >> 3 == 0x1E) { + this.charLength = 4; + break; + } + } + this.charReceived = i; +}; + +StringDecoder.prototype.end = function(buffer) { + var res = ''; + if (buffer && buffer.length) + res = this.write(buffer); + + if (this.charReceived) { + var cr = this.charReceived; + var buf = this.charBuffer; + var enc = this.encoding; + res += buf.slice(0, cr).toString(enc); + } + + return res; +}; + +function passThroughWrite(buffer) { + return buffer.toString(this.encoding); +} + +function utf16DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 2; + this.charLength = this.charReceived ? 2 : 0; +} + +function base64DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 3; + this.charLength = this.charReceived ? 3 : 0; +} diff --git a/node_modules/string_decoder/package.json b/node_modules/string_decoder/package.json new file mode 100644 index 0000000..4611d66 --- /dev/null +++ b/node_modules/string_decoder/package.json @@ -0,0 +1,88 @@ +{ + "_args": [ + [ + { + "raw": "string_decoder@~0.10.x", + "scope": null, + "escapedName": "string_decoder", + "name": "string_decoder", + "rawSpec": "~0.10.x", + "spec": ">=0.10.0 <0.11.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/readable-stream" + ] + ], + "_from": "string_decoder@>=0.10.0 <0.11.0", + "_id": "string_decoder@0.10.31", + "_inCache": true, + "_location": "/string_decoder", + "_npmUser": { + "name": "rvagg", + "email": "rod@vagg.org" + }, + "_npmVersion": "1.4.23", + "_phantomChildren": {}, + "_requested": { + "raw": "string_decoder@~0.10.x", + "scope": null, + "escapedName": "string_decoder", + "name": "string_decoder", + "rawSpec": "~0.10.x", + "spec": ">=0.10.0 <0.11.0", + "type": "range" + }, + "_requiredBy": [ + "/concat-stream/readable-stream", + "/readable-stream" + ], + "_resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "_shasum": "62e203bc41766c6c28c9fc84301dab1c5310fa94", + "_shrinkwrap": null, + "_spec": "string_decoder@~0.10.x", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/readable-stream", + "bugs": { + "url": "https://github.com/rvagg/string_decoder/issues" + }, + "dependencies": {}, + "description": "The string_decoder module from Node core", + "devDependencies": { + "tap": "~0.4.8" + }, + "directories": {}, + "dist": { + "shasum": "62e203bc41766c6c28c9fc84301dab1c5310fa94", + "tarball": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "gitHead": "d46d4fd87cf1d06e031c23f1ba170ca7d4ade9a0", + "homepage": "https://github.com/rvagg/string_decoder", + "keywords": [ + "string", + "decoder", + "browser", + "browserify" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "substack", + "email": "mail@substack.net" + }, + { + "name": "rvagg", + "email": "rod@vagg.org" + } + ], + "name": "string_decoder", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/rvagg/string_decoder.git" + }, + "scripts": { + "test": "tap test/simple/*.js" + }, + "version": "0.10.31" +} diff --git a/node_modules/strip-ansi/index.js b/node_modules/strip-ansi/index.js new file mode 100644 index 0000000..099480f --- /dev/null +++ b/node_modules/strip-ansi/index.js @@ -0,0 +1,6 @@ +'use strict'; +var ansiRegex = require('ansi-regex')(); + +module.exports = function (str) { + return typeof str === 'string' ? str.replace(ansiRegex, '') : str; +}; diff --git a/node_modules/strip-ansi/license b/node_modules/strip-ansi/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/strip-ansi/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/strip-ansi/package.json b/node_modules/strip-ansi/package.json new file mode 100644 index 0000000..4b80c15 --- /dev/null +++ b/node_modules/strip-ansi/package.json @@ -0,0 +1,123 @@ +{ + "_args": [ + [ + { + "raw": "strip-ansi@^3.0.0", + "scope": null, + "escapedName": "strip-ansi", + "name": "strip-ansi", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/chalk" + ] + ], + "_from": "strip-ansi@>=3.0.0 <4.0.0", + "_id": "strip-ansi@3.0.1", + "_inCache": true, + "_location": "/strip-ansi", + "_nodeVersion": "0.12.7", + "_npmOperationalInternal": { + "host": "packages-9-west.internal.npmjs.com", + "tmp": "tmp/strip-ansi-3.0.1.tgz_1456057278183_0.28958667791448534" + }, + "_npmUser": { + "name": "jbnicolai", + "email": "jappelman@xebia.com" + }, + "_npmVersion": "2.11.3", + "_phantomChildren": {}, + "_requested": { + "raw": "strip-ansi@^3.0.0", + "scope": null, + "escapedName": "strip-ansi", + "name": "strip-ansi", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/chalk" + ], + "_resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "_shasum": "6a385fb8853d952d5ff05d0e8aaf94278dc63dcf", + "_shrinkwrap": null, + "_spec": "strip-ansi@^3.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/chalk", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/chalk/strip-ansi/issues" + }, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "description": "Strip ANSI escape codes", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "6a385fb8853d952d5ff05d0e8aaf94278dc63dcf", + "tarball": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "8270705c704956da865623e564eba4875c3ea17f", + "homepage": "https://github.com/chalk/strip-ansi", + "keywords": [ + "strip", + "trim", + "remove", + "ansi", + "styles", + "color", + "colour", + "colors", + "terminal", + "console", + "string", + "tty", + "escape", + "formatting", + "rgb", + "256", + "shell", + "xterm", + "log", + "logging", + "command-line", + "text" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + { + "name": "jbnicolai", + "email": "jappelman@xebia.com" + } + ], + "name": "strip-ansi", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/chalk/strip-ansi.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "3.0.1" +} diff --git a/node_modules/strip-ansi/readme.md b/node_modules/strip-ansi/readme.md new file mode 100644 index 0000000..cb7d9ff --- /dev/null +++ b/node_modules/strip-ansi/readme.md @@ -0,0 +1,33 @@ +# strip-ansi [![Build Status](https://travis-ci.org/chalk/strip-ansi.svg?branch=master)](https://travis-ci.org/chalk/strip-ansi) + +> Strip [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code) + + +## Install + +``` +$ npm install --save strip-ansi +``` + + +## Usage + +```js +var stripAnsi = require('strip-ansi'); + +stripAnsi('\u001b[4mcake\u001b[0m'); +//=> 'cake' +``` + + +## Related + +- [strip-ansi-cli](https://github.com/chalk/strip-ansi-cli) - CLI for this module +- [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes +- [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes +- [chalk](https://github.com/chalk/chalk) - Terminal string styling done right + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/strip-bom/index.js b/node_modules/strip-bom/index.js new file mode 100644 index 0000000..5695c5c --- /dev/null +++ b/node_modules/strip-bom/index.js @@ -0,0 +1,17 @@ +'use strict'; +var isUtf8 = require('is-utf8'); + +module.exports = function (x) { + // Catches EFBBBF (UTF-8 BOM) because the buffer-to-string + // conversion translates it to FEFF (UTF-16 BOM) + if (typeof x === 'string' && x.charCodeAt(0) === 0xFEFF) { + return x.slice(1); + } + + if (Buffer.isBuffer(x) && isUtf8(x) && + x[0] === 0xEF && x[1] === 0xBB && x[2] === 0xBF) { + return x.slice(3); + } + + return x; +}; diff --git a/node_modules/strip-bom/license b/node_modules/strip-bom/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/strip-bom/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/strip-bom/package.json b/node_modules/strip-bom/package.json new file mode 100644 index 0000000..5a93fa1 --- /dev/null +++ b/node_modules/strip-bom/package.json @@ -0,0 +1,105 @@ +{ + "_args": [ + [ + { + "raw": "strip-bom@^2.0.0", + "scope": null, + "escapedName": "strip-bom", + "name": "strip-bom", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/load-json-file" + ] + ], + "_from": "strip-bom@>=2.0.0 <3.0.0", + "_id": "strip-bom@2.0.0", + "_inCache": true, + "_location": "/strip-bom", + "_nodeVersion": "0.12.5", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.11.2", + "_phantomChildren": {}, + "_requested": { + "raw": "strip-bom@^2.0.0", + "scope": null, + "escapedName": "strip-bom", + "name": "strip-bom", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/load-json-file" + ], + "_resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "_shasum": "6219a85616520491f35788bdbf1447a99c7e6b0e", + "_shrinkwrap": null, + "_spec": "strip-bom@^2.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/load-json-file", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/strip-bom/issues" + }, + "dependencies": { + "is-utf8": "^0.2.0" + }, + "description": "Strip UTF-8 byte order mark (BOM) from a string/buffer", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "6219a85616520491f35788bdbf1447a99c7e6b0e", + "tarball": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "851b9c126dba9561cc14ef3dc2634dcc11df4d11", + "homepage": "https://github.com/sindresorhus/strip-bom", + "keywords": [ + "bom", + "strip", + "byte", + "mark", + "unicode", + "utf8", + "utf-8", + "remove", + "delete", + "trim", + "text", + "buffer", + "string" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "strip-bom", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/strip-bom.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "2.0.0" +} diff --git a/node_modules/strip-bom/readme.md b/node_modules/strip-bom/readme.md new file mode 100644 index 0000000..8ecf258 --- /dev/null +++ b/node_modules/strip-bom/readme.md @@ -0,0 +1,39 @@ +# strip-bom [![Build Status](https://travis-ci.org/sindresorhus/strip-bom.svg?branch=master)](https://travis-ci.org/sindresorhus/strip-bom) + +> Strip UTF-8 [byte order mark](http://en.wikipedia.org/wiki/Byte_order_mark#UTF-8) (BOM) from a string/buffer + +From Wikipedia: + +> The Unicode Standard permits the BOM in UTF-8, but does not require nor recommend its use. Byte order has no meaning in UTF-8. + + +## Install + +``` +$ npm install --save strip-bom +``` + + +## Usage + +```js +var fs = require('fs'); +var stripBom = require('strip-bom'); + +stripBom('\uFEFFunicorn'); +//=> 'unicorn' + +stripBom(fs.readFileSync('unicorn.txt')); +//=> 'unicorn' +``` + + +## Related + +- [strip-bom-cli](https://github.com/sindresorhus/strip-bom-cli) - CLI for this module +- [strip-bom-stream](https://github.com/sindresorhus/strip-bom-stream) - Stream version of this module + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/strip-indent/cli.js b/node_modules/strip-indent/cli.js new file mode 100644 index 0000000..bcd5f8d --- /dev/null +++ b/node_modules/strip-indent/cli.js @@ -0,0 +1,49 @@ +#!/usr/bin/env node +'use strict'; +var fs = require('fs'); +var stdin = require('get-stdin'); +var pkg = require('./package.json'); +var stripIndent = require('./'); +var argv = process.argv.slice(2); +var input = argv[0]; + +function help() { + console.log([ + '', + ' ' + pkg.description, + '', + ' Usage', + ' strip-indent ', + ' echo | strip-indent', + '', + ' Example', + ' echo \'\\tunicorn\\n\\t\\tcake\' | strip-indent', + ' unicorn', + ' \tcake' + ].join('\n')); +} + +function init(data) { + console.log(stripIndent(data)); +} + +if (argv.indexOf('--help') !== -1) { + help(); + return; +} + +if (argv.indexOf('--version') !== -1) { + console.log(pkg.version); + return; +} + +if (process.stdin.isTTY) { + if (!input) { + help(); + return; + } + + init(fs.readFileSync(input, 'utf8')); +} else { + stdin(init); +} diff --git a/node_modules/strip-indent/index.js b/node_modules/strip-indent/index.js new file mode 100644 index 0000000..8f8f4f4 --- /dev/null +++ b/node_modules/strip-indent/index.js @@ -0,0 +1,16 @@ +'use strict'; +module.exports = function (str) { + var match = str.match(/^[ \t]*(?=\S)/gm); + + if (!match) { + return str; + } + + var indent = Math.min.apply(Math, match.map(function (el) { + return el.length; + })); + + var re = new RegExp('^[ \\t]{' + indent + '}', 'gm'); + + return indent > 0 ? str.replace(re, '') : str; +}; diff --git a/node_modules/strip-indent/license b/node_modules/strip-indent/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/strip-indent/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/strip-indent/package.json b/node_modules/strip-indent/package.json new file mode 100644 index 0000000..d689860 --- /dev/null +++ b/node_modules/strip-indent/package.json @@ -0,0 +1,109 @@ +{ + "_args": [ + [ + { + "raw": "strip-indent@^1.0.1", + "scope": null, + "escapedName": "strip-indent", + "name": "strip-indent", + "rawSpec": "^1.0.1", + "spec": ">=1.0.1 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/redent" + ] + ], + "_from": "strip-indent@>=1.0.1 <2.0.0", + "_id": "strip-indent@1.0.1", + "_inCache": true, + "_location": "/strip-indent", + "_nodeVersion": "0.12.0", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.5.1", + "_phantomChildren": {}, + "_requested": { + "raw": "strip-indent@^1.0.1", + "scope": null, + "escapedName": "strip-indent", + "name": "strip-indent", + "rawSpec": "^1.0.1", + "spec": ">=1.0.1 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/redent" + ], + "_resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "_shasum": "0c7962a6adefa7bbd4ac366460a638552ae1a0a2", + "_shrinkwrap": null, + "_spec": "strip-indent@^1.0.1", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/redent", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bin": { + "strip-indent": "cli.js" + }, + "bugs": { + "url": "https://github.com/sindresorhus/strip-indent/issues" + }, + "dependencies": { + "get-stdin": "^4.0.1" + }, + "description": "Strip leading whitespace from every line in a string", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "0c7962a6adefa7bbd4ac366460a638552ae1a0a2", + "tarball": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js", + "cli.js" + ], + "gitHead": "addcf90a56001ea122e9f1254987016bc87e5b5f", + "homepage": "https://github.com/sindresorhus/strip-indent", + "keywords": [ + "cli", + "bin", + "browser", + "strip", + "normalize", + "remove", + "indent", + "indentation", + "whitespace", + "space", + "tab", + "string", + "str" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "strip-indent", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/strip-indent.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "1.0.1" +} diff --git a/node_modules/strip-indent/readme.md b/node_modules/strip-indent/readme.md new file mode 100644 index 0000000..d622f03 --- /dev/null +++ b/node_modules/strip-indent/readme.md @@ -0,0 +1,61 @@ +# strip-indent [![Build Status](https://travis-ci.org/sindresorhus/strip-indent.svg?branch=master)](https://travis-ci.org/sindresorhus/strip-indent) + +> Strip leading whitespace from every line in a string + +The line with the least number of leading whitespace, ignoring empty lines, determines the number to remove. + +Useful for removing redundant indentation. + + +## Install + +```sh +$ npm install --save strip-indent +``` + + +## Usage + +```js +var str = '\tunicorn\n\t\tcake'; +/* + unicorn + cake +*/ + +stripIndent('\tunicorn\n\t\tcake'); +/* +unicorn + cake +*/ +``` + + +## CLI + +```sh +$ npm install --global strip-indent +``` + +```sh +$ strip-indent --help + + Usage + strip-indent + echo | strip-indent + + Example + echo '\tunicorn\n\t\tcake' | strip-indent + unicorn + cake +``` + + +## Related + +- [indent-string](https://github.com/sindresorhus/indent-string) - Indent each line in a string + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/strip-json-comments/cli.js b/node_modules/strip-json-comments/cli.js new file mode 100644 index 0000000..aec5aa2 --- /dev/null +++ b/node_modules/strip-json-comments/cli.js @@ -0,0 +1,41 @@ +#!/usr/bin/env node +'use strict'; +var fs = require('fs'); +var strip = require('./strip-json-comments'); +var input = process.argv[2]; + + +function getStdin(cb) { + var ret = ''; + + process.stdin.setEncoding('utf8'); + + process.stdin.on('data', function (data) { + ret += data; + }); + + process.stdin.on('end', function () { + cb(ret); + }); +} + +if (process.argv.indexOf('-h') !== -1 || process.argv.indexOf('--help') !== -1) { + console.log('strip-json-comments input-file > output-file'); + console.log('or'); + console.log('strip-json-comments < input-file > output-file'); + return; +} + +if (process.argv.indexOf('-v') !== -1 || process.argv.indexOf('--version') !== -1) { + console.log(require('./package').version); + return; +} + +if (input) { + process.stdout.write(strip(fs.readFileSync(input, 'utf8'))); + return; +} + +getStdin(function (data) { + process.stdout.write(strip(data)); +}); diff --git a/node_modules/strip-json-comments/license b/node_modules/strip-json-comments/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/strip-json-comments/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/strip-json-comments/package.json b/node_modules/strip-json-comments/package.json new file mode 100644 index 0000000..501b624 --- /dev/null +++ b/node_modules/strip-json-comments/package.json @@ -0,0 +1,112 @@ +{ + "_args": [ + [ + { + "raw": "strip-json-comments@1.0.x", + "scope": null, + "escapedName": "strip-json-comments", + "name": "strip-json-comments", + "rawSpec": "1.0.x", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/jshint" + ] + ], + "_from": "strip-json-comments@>=1.0.0 <1.1.0", + "_id": "strip-json-comments@1.0.4", + "_inCache": true, + "_location": "/strip-json-comments", + "_nodeVersion": "0.12.5", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.11.2", + "_phantomChildren": {}, + "_requested": { + "raw": "strip-json-comments@1.0.x", + "scope": null, + "escapedName": "strip-json-comments", + "name": "strip-json-comments", + "rawSpec": "1.0.x", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/jshint" + ], + "_resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "_shasum": "1e15fbcac97d3ee99bf2d73b4c656b082bbafb91", + "_shrinkwrap": null, + "_spec": "strip-json-comments@1.0.x", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/jshint", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bin": { + "strip-json-comments": "cli.js" + }, + "bugs": { + "url": "https://github.com/sindresorhus/strip-json-comments/issues" + }, + "dependencies": {}, + "description": "Strip comments from JSON. Lets you use comments in your JSON files!", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "1e15fbcac97d3ee99bf2d73b4c656b082bbafb91", + "tarball": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz" + }, + "engines": { + "node": ">=0.8.0" + }, + "files": [ + "cli.js", + "strip-json-comments.js" + ], + "gitHead": "f58348696368583cc5bb18525fe31eacc9bd00e1", + "homepage": "https://github.com/sindresorhus/strip-json-comments", + "keywords": [ + "json", + "strip", + "remove", + "delete", + "trim", + "comments", + "multiline", + "parse", + "config", + "configuration", + "conf", + "settings", + "util", + "env", + "environment", + "cli", + "bin" + ], + "license": "MIT", + "main": "strip-json-comments", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "strip-json-comments", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/strip-json-comments.git" + }, + "scripts": { + "test": "mocha --ui tdd" + }, + "version": "1.0.4" +} diff --git a/node_modules/strip-json-comments/readme.md b/node_modules/strip-json-comments/readme.md new file mode 100644 index 0000000..63ce165 --- /dev/null +++ b/node_modules/strip-json-comments/readme.md @@ -0,0 +1,80 @@ +# strip-json-comments [![Build Status](https://travis-ci.org/sindresorhus/strip-json-comments.svg?branch=master)](https://travis-ci.org/sindresorhus/strip-json-comments) + +> Strip comments from JSON. Lets you use comments in your JSON files! + +This is now possible: + +```js +{ + // rainbows + "unicorn": /* ❤ */ "cake" +} +``` + +It will remove single-line comments `//` and multi-line comments `/**/`. + +Also available as a [gulp](https://github.com/sindresorhus/gulp-strip-json-comments)/[grunt](https://github.com/sindresorhus/grunt-strip-json-comments)/[broccoli](https://github.com/sindresorhus/broccoli-strip-json-comments) plugin. + +- + +*There's also [`json-comments`](https://npmjs.org/package/json-comments), but it's only for Node.js, inefficient, bloated as it also minifies, and comes with a `require` hook, which is :(* + + +## Install + +```sh +$ npm install --save strip-json-comments +``` + +```sh +$ bower install --save strip-json-comments +``` + +```sh +$ component install sindresorhus/strip-json-comments +``` + + +## Usage + +```js +var json = '{/*rainbows*/"unicorn":"cake"}'; +JSON.parse(stripJsonComments(json)); +//=> {unicorn: 'cake'} +``` + + +## API + +### stripJsonComments(input) + +#### input + +Type: `string` + +Accepts a string with JSON and returns a string without comments. + + +## CLI + +```sh +$ npm install --global strip-json-comments +``` + +```sh +$ strip-json-comments --help + +strip-json-comments input-file > output-file +# or +strip-json-comments < input-file > output-file +``` + + +## Related + +- [`strip-css-comments`](https://github.com/sindresorhus/strip-css-comments) + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/strip-json-comments/strip-json-comments.js b/node_modules/strip-json-comments/strip-json-comments.js new file mode 100644 index 0000000..eb77ce7 --- /dev/null +++ b/node_modules/strip-json-comments/strip-json-comments.js @@ -0,0 +1,73 @@ +/*! + strip-json-comments + Strip comments from JSON. Lets you use comments in your JSON files! + https://github.com/sindresorhus/strip-json-comments + by Sindre Sorhus + MIT License +*/ +(function () { + 'use strict'; + + var singleComment = 1; + var multiComment = 2; + + function stripJsonComments(str) { + var currentChar; + var nextChar; + var insideString = false; + var insideComment = false; + var ret = ''; + + for (var i = 0; i < str.length; i++) { + currentChar = str[i]; + nextChar = str[i + 1]; + + if (!insideComment && currentChar === '"') { + var escaped = str[i - 1] === '\\' && str[i - 2] !== '\\'; + if (!insideComment && !escaped && currentChar === '"') { + insideString = !insideString; + } + } + + if (insideString) { + ret += currentChar; + continue; + } + + if (!insideComment && currentChar + nextChar === '//') { + insideComment = singleComment; + i++; + } else if (insideComment === singleComment && currentChar + nextChar === '\r\n') { + insideComment = false; + i++; + ret += currentChar; + ret += nextChar; + continue; + } else if (insideComment === singleComment && currentChar === '\n') { + insideComment = false; + } else if (!insideComment && currentChar + nextChar === '/*') { + insideComment = multiComment; + i++; + continue; + } else if (insideComment === multiComment && currentChar + nextChar === '*/') { + insideComment = false; + i++; + continue; + } + + if (insideComment) { + continue; + } + + ret += currentChar; + } + + return ret; + } + + if (typeof module !== 'undefined' && module.exports) { + module.exports = stripJsonComments; + } else { + window.stripJsonComments = stripJsonComments; + } +})(); diff --git a/node_modules/supports-color/index.js b/node_modules/supports-color/index.js new file mode 100644 index 0000000..4346e27 --- /dev/null +++ b/node_modules/supports-color/index.js @@ -0,0 +1,50 @@ +'use strict'; +var argv = process.argv; + +var terminator = argv.indexOf('--'); +var hasFlag = function (flag) { + flag = '--' + flag; + var pos = argv.indexOf(flag); + return pos !== -1 && (terminator !== -1 ? pos < terminator : true); +}; + +module.exports = (function () { + if ('FORCE_COLOR' in process.env) { + return true; + } + + if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false')) { + return false; + } + + if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + return true; + } + + if (process.stdout && !process.stdout.isTTY) { + return false; + } + + if (process.platform === 'win32') { + return true; + } + + if ('COLORTERM' in process.env) { + return true; + } + + if (process.env.TERM === 'dumb') { + return false; + } + + if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) { + return true; + } + + return false; +})(); diff --git a/node_modules/supports-color/license b/node_modules/supports-color/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/supports-color/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/supports-color/package.json b/node_modules/supports-color/package.json new file mode 100644 index 0000000..499d410 --- /dev/null +++ b/node_modules/supports-color/package.json @@ -0,0 +1,113 @@ +{ + "_args": [ + [ + { + "raw": "supports-color@^2.0.0", + "scope": null, + "escapedName": "supports-color", + "name": "supports-color", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/chalk" + ] + ], + "_from": "supports-color@>=2.0.0 <3.0.0", + "_id": "supports-color@2.0.0", + "_inCache": true, + "_location": "/supports-color", + "_nodeVersion": "0.12.5", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.11.2", + "_phantomChildren": {}, + "_requested": { + "raw": "supports-color@^2.0.0", + "scope": null, + "escapedName": "supports-color", + "name": "supports-color", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/chalk" + ], + "_resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "_shasum": "535d045ce6b6363fa40117084629995e9df324c7", + "_shrinkwrap": null, + "_spec": "supports-color@^2.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/chalk", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/chalk/supports-color/issues" + }, + "dependencies": {}, + "description": "Detect whether a terminal supports color", + "devDependencies": { + "mocha": "*", + "require-uncached": "^1.0.2" + }, + "directories": {}, + "dist": { + "shasum": "535d045ce6b6363fa40117084629995e9df324c7", + "tarball": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" + }, + "engines": { + "node": ">=0.8.0" + }, + "files": [ + "index.js" + ], + "gitHead": "8400d98ade32b2adffd50902c06d9e725a5c6588", + "homepage": "https://github.com/chalk/supports-color", + "keywords": [ + "color", + "colour", + "colors", + "terminal", + "console", + "cli", + "ansi", + "styles", + "tty", + "rgb", + "256", + "shell", + "xterm", + "command-line", + "support", + "supports", + "capability", + "detect" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + { + "name": "jbnicolai", + "email": "jappelman@xebia.com" + } + ], + "name": "supports-color", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/chalk/supports-color.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "2.0.0" +} diff --git a/node_modules/supports-color/readme.md b/node_modules/supports-color/readme.md new file mode 100644 index 0000000..b4761f1 --- /dev/null +++ b/node_modules/supports-color/readme.md @@ -0,0 +1,36 @@ +# supports-color [![Build Status](https://travis-ci.org/chalk/supports-color.svg?branch=master)](https://travis-ci.org/chalk/supports-color) + +> Detect whether a terminal supports color + + +## Install + +``` +$ npm install --save supports-color +``` + + +## Usage + +```js +var supportsColor = require('supports-color'); + +if (supportsColor) { + console.log('Terminal supports color'); +} +``` + +It obeys the `--color` and `--no-color` CLI flags. + +For situations where using `--color` is not possible, add an environment variable `FORCE_COLOR` with any value to force color. Trumps `--no-color`. + + +## Related + +- [supports-color-cli](https://github.com/chalk/supports-color-cli) - CLI for this module +- [chalk](https://github.com/chalk/chalk) - Terminal string styling done right + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/through/.travis.yml b/node_modules/through/.travis.yml new file mode 100644 index 0000000..c693a93 --- /dev/null +++ b/node_modules/through/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - 0.6 + - 0.8 + - "0.10" diff --git a/node_modules/through/LICENSE.APACHE2 b/node_modules/through/LICENSE.APACHE2 new file mode 100644 index 0000000..6366c04 --- /dev/null +++ b/node_modules/through/LICENSE.APACHE2 @@ -0,0 +1,15 @@ +Apache License, Version 2.0 + +Copyright (c) 2011 Dominic Tarr + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/node_modules/through/LICENSE.MIT b/node_modules/through/LICENSE.MIT new file mode 100644 index 0000000..6eafbd7 --- /dev/null +++ b/node_modules/through/LICENSE.MIT @@ -0,0 +1,24 @@ +The MIT License + +Copyright (c) 2011 Dominic Tarr + +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/through/index.js b/node_modules/through/index.js new file mode 100644 index 0000000..ca5fc59 --- /dev/null +++ b/node_modules/through/index.js @@ -0,0 +1,108 @@ +var Stream = require('stream') + +// through +// +// a stream that does nothing but re-emit the input. +// useful for aggregating a series of changing but not ending streams into one stream) + +exports = module.exports = through +through.through = through + +//create a readable writable stream. + +function through (write, end, opts) { + write = write || function (data) { this.queue(data) } + end = end || function () { this.queue(null) } + + var ended = false, destroyed = false, buffer = [], _ended = false + var stream = new Stream() + stream.readable = stream.writable = true + stream.paused = false + +// stream.autoPause = !(opts && opts.autoPause === false) + stream.autoDestroy = !(opts && opts.autoDestroy === false) + + stream.write = function (data) { + write.call(this, data) + return !stream.paused + } + + function drain() { + while(buffer.length && !stream.paused) { + var data = buffer.shift() + if(null === data) + return stream.emit('end') + else + stream.emit('data', data) + } + } + + stream.queue = stream.push = function (data) { +// console.error(ended) + if(_ended) return stream + if(data === null) _ended = true + buffer.push(data) + drain() + return stream + } + + //this will be registered as the first 'end' listener + //must call destroy next tick, to make sure we're after any + //stream piped from here. + //this is only a problem if end is not emitted synchronously. + //a nicer way to do this is to make sure this is the last listener for 'end' + + stream.on('end', function () { + stream.readable = false + if(!stream.writable && stream.autoDestroy) + process.nextTick(function () { + stream.destroy() + }) + }) + + function _end () { + stream.writable = false + end.call(stream) + if(!stream.readable && stream.autoDestroy) + stream.destroy() + } + + stream.end = function (data) { + if(ended) return + ended = true + if(arguments.length) stream.write(data) + _end() // will emit or queue + return stream + } + + stream.destroy = function () { + if(destroyed) return + destroyed = true + ended = true + buffer.length = 0 + stream.writable = stream.readable = false + stream.emit('close') + return stream + } + + stream.pause = function () { + if(stream.paused) return + stream.paused = true + return stream + } + + stream.resume = function () { + if(stream.paused) { + stream.paused = false + stream.emit('resume') + } + drain() + //may have become paused again, + //as drain emits 'data'. + if(!stream.paused) + stream.emit('drain') + return stream + } + return stream +} + diff --git a/node_modules/through/package.json b/node_modules/through/package.json new file mode 100644 index 0000000..1c08c7c --- /dev/null +++ b/node_modules/through/package.json @@ -0,0 +1,100 @@ +{ + "_args": [ + [ + { + "raw": "through@~2.3.4", + "scope": null, + "escapedName": "through", + "name": "through", + "rawSpec": "~2.3.4", + "spec": ">=2.3.4 <2.4.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/stream-combiner" + ] + ], + "_from": "through@>=2.3.4 <2.4.0", + "_id": "through@2.3.8", + "_inCache": true, + "_location": "/through", + "_nodeVersion": "2.3.1", + "_npmUser": { + "name": "dominictarr", + "email": "dominic.tarr@gmail.com" + }, + "_npmVersion": "2.12.0", + "_phantomChildren": {}, + "_requested": { + "raw": "through@~2.3.4", + "scope": null, + "escapedName": "through", + "name": "through", + "rawSpec": "~2.3.4", + "spec": ">=2.3.4 <2.4.0", + "type": "range" + }, + "_requiredBy": [ + "/stream-combiner" + ], + "_resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "_shasum": "0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5", + "_shrinkwrap": null, + "_spec": "through@~2.3.4", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/stream-combiner", + "author": { + "name": "Dominic Tarr", + "email": "dominic.tarr@gmail.com", + "url": "dominictarr.com" + }, + "bugs": { + "url": "https://github.com/dominictarr/through/issues" + }, + "dependencies": {}, + "description": "simplified stream construction", + "devDependencies": { + "from": "~0.1.3", + "stream-spec": "~0.3.5", + "tape": "~2.3.2" + }, + "directories": {}, + "dist": { + "shasum": "0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5", + "tarball": "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + }, + "gitHead": "2c5a6f9a0cc54da759b6e10964f2081c358e49dc", + "homepage": "https://github.com/dominictarr/through", + "keywords": [ + "stream", + "streams", + "user-streams", + "pipe" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "dominictarr", + "email": "dominic.tarr@gmail.com" + } + ], + "name": "through", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/dominictarr/through.git" + }, + "scripts": { + "test": "set -e; for t in test/*.js; do node $t; done" + }, + "testling": { + "browsers": [ + "ie/8..latest", + "ff/15..latest", + "chrome/20..latest", + "safari/5.1..latest" + ], + "files": "test/*.js" + }, + "version": "2.3.8" +} diff --git a/node_modules/through/readme.markdown b/node_modules/through/readme.markdown new file mode 100644 index 0000000..cb34c81 --- /dev/null +++ b/node_modules/through/readme.markdown @@ -0,0 +1,64 @@ +#through + +[![build status](https://secure.travis-ci.org/dominictarr/through.png)](http://travis-ci.org/dominictarr/through) +[![testling badge](https://ci.testling.com/dominictarr/through.png)](https://ci.testling.com/dominictarr/through) + +Easy way to create a `Stream` that is both `readable` and `writable`. + +* Pass in optional `write` and `end` methods. +* `through` takes care of pause/resume logic if you use `this.queue(data)` instead of `this.emit('data', data)`. +* Use `this.pause()` and `this.resume()` to manage flow. +* Check `this.paused` to see current flow state. (`write` always returns `!this.paused`). + +This function is the basis for most of the synchronous streams in +[event-stream](http://github.com/dominictarr/event-stream). + +``` js +var through = require('through') + +through(function write(data) { + this.queue(data) //data *must* not be null + }, + function end () { //optional + this.queue(null) + }) +``` + +Or, can also be used _without_ buffering on pause, use `this.emit('data', data)`, +and this.emit('end') + +``` js +var through = require('through') + +through(function write(data) { + this.emit('data', data) + //this.pause() + }, + function end () { //optional + this.emit('end') + }) +``` + +## Extended Options + +You will probably not need these 99% of the time. + +### autoDestroy=false + +By default, `through` emits close when the writable +and readable side of the stream has ended. +If that is not desired, set `autoDestroy=false`. + +``` js +var through = require('through') + +//like this +var ts = through(write, end, {autoDestroy: false}) +//or like this +var ts = through(write, end) +ts.autoDestroy = false +``` + +## License + +MIT / Apache2 diff --git a/node_modules/through/test/async.js b/node_modules/through/test/async.js new file mode 100644 index 0000000..46bdbae --- /dev/null +++ b/node_modules/through/test/async.js @@ -0,0 +1,28 @@ +var from = require('from') +var through = require('../') + +var tape = require('tape') + +tape('simple async example', function (t) { + + var n = 0, expected = [1,2,3,4,5], actual = [] + from(expected) + .pipe(through(function(data) { + this.pause() + n ++ + setTimeout(function(){ + console.log('pushing data', data) + this.push(data) + this.resume() + }.bind(this), 300) + })).pipe(through(function(data) { + console.log('pushing data second time', data); + this.push(data) + })).on('data', function (d) { + actual.push(d) + }).on('end', function() { + t.deepEqual(actual, expected) + t.end() + }) + +}) diff --git a/node_modules/through/test/auto-destroy.js b/node_modules/through/test/auto-destroy.js new file mode 100644 index 0000000..9a8fd00 --- /dev/null +++ b/node_modules/through/test/auto-destroy.js @@ -0,0 +1,30 @@ +var test = require('tape') +var through = require('../') + +// must emit end before close. + +test('end before close', function (assert) { + var ts = through() + ts.autoDestroy = false + var ended = false, closed = false + + ts.on('end', function () { + assert.ok(!closed) + ended = true + }) + ts.on('close', function () { + assert.ok(ended) + closed = true + }) + + ts.write(1) + ts.write(2) + ts.write(3) + ts.end() + assert.ok(ended) + assert.notOk(closed) + ts.destroy() + assert.ok(closed) + assert.end() +}) + diff --git a/node_modules/through/test/buffering.js b/node_modules/through/test/buffering.js new file mode 100644 index 0000000..b0084bf --- /dev/null +++ b/node_modules/through/test/buffering.js @@ -0,0 +1,71 @@ +var test = require('tape') +var through = require('../') + +// must emit end before close. + +test('buffering', function(assert) { + var ts = through(function (data) { + this.queue(data) + }, function () { + this.queue(null) + }) + + var ended = false, actual = [] + + ts.on('data', actual.push.bind(actual)) + ts.on('end', function () { + ended = true + }) + + ts.write(1) + ts.write(2) + ts.write(3) + assert.deepEqual(actual, [1, 2, 3]) + ts.pause() + ts.write(4) + ts.write(5) + ts.write(6) + assert.deepEqual(actual, [1, 2, 3]) + ts.resume() + assert.deepEqual(actual, [1, 2, 3, 4, 5, 6]) + ts.pause() + ts.end() + assert.ok(!ended) + ts.resume() + assert.ok(ended) + assert.end() +}) + +test('buffering has data in queue, when ends', function (assert) { + + /* + * If stream ends while paused with data in the queue, + * stream should still emit end after all data is written + * on resume. + */ + + var ts = through(function (data) { + this.queue(data) + }, function () { + this.queue(null) + }) + + var ended = false, actual = [] + + ts.on('data', actual.push.bind(actual)) + ts.on('end', function () { + ended = true + }) + + ts.pause() + ts.write(1) + ts.write(2) + ts.write(3) + ts.end() + assert.deepEqual(actual, [], 'no data written yet, still paused') + assert.ok(!ended, 'end not emitted yet, still paused') + ts.resume() + assert.deepEqual(actual, [1, 2, 3], 'resumed, all data should be delivered') + assert.ok(ended, 'end should be emitted once all data was delivered') + assert.end(); +}) diff --git a/node_modules/through/test/end.js b/node_modules/through/test/end.js new file mode 100644 index 0000000..fa113f5 --- /dev/null +++ b/node_modules/through/test/end.js @@ -0,0 +1,45 @@ +var test = require('tape') +var through = require('../') + +// must emit end before close. + +test('end before close', function (assert) { + var ts = through() + var ended = false, closed = false + + ts.on('end', function () { + assert.ok(!closed) + ended = true + }) + ts.on('close', function () { + assert.ok(ended) + closed = true + }) + + ts.write(1) + ts.write(2) + ts.write(3) + ts.end() + assert.ok(ended) + assert.ok(closed) + assert.end() +}) + +test('end only once', function (t) { + + var ts = through() + var ended = false, closed = false + + ts.on('end', function () { + t.equal(ended, false) + ended = true + }) + + ts.queue(null) + ts.queue(null) + ts.queue(null) + + ts.resume() + + t.end() +}) diff --git a/node_modules/through/test/index.js b/node_modules/through/test/index.js new file mode 100644 index 0000000..96da82f --- /dev/null +++ b/node_modules/through/test/index.js @@ -0,0 +1,133 @@ + +var test = require('tape') +var spec = require('stream-spec') +var through = require('../') + +/* + I'm using these two functions, and not streams and pipe + so there is less to break. if this test fails it must be + the implementation of _through_ +*/ + +function write(array, stream) { + array = array.slice() + function next() { + while(array.length) + if(stream.write(array.shift()) === false) + return stream.once('drain', next) + + stream.end() + } + + next() +} + +function read(stream, callback) { + var actual = [] + stream.on('data', function (data) { + actual.push(data) + }) + stream.once('end', function () { + callback(null, actual) + }) + stream.once('error', function (err) { + callback(err) + }) +} + +test('simple defaults', function(assert) { + + var l = 1000 + , expected = [] + + while(l--) expected.push(l * Math.random()) + + var t = through() + var s = spec(t).through().pausable() + + read(t, function (err, actual) { + assert.ifError(err) + assert.deepEqual(actual, expected) + assert.end() + }) + + t.on('close', s.validate) + + write(expected, t) +}); + +test('simple functions', function(assert) { + + var l = 1000 + , expected = [] + + while(l--) expected.push(l * Math.random()) + + var t = through(function (data) { + this.emit('data', data*2) + }) + var s = spec(t).through().pausable() + + + read(t, function (err, actual) { + assert.ifError(err) + assert.deepEqual(actual, expected.map(function (data) { + return data*2 + })) + assert.end() + }) + + t.on('close', s.validate) + + write(expected, t) +}) + +test('pauses', function(assert) { + + var l = 1000 + , expected = [] + + while(l--) expected.push(l) //Math.random()) + + var t = through() + + var s = spec(t) + .through() + .pausable() + + t.on('data', function () { + if(Math.random() > 0.1) return + t.pause() + process.nextTick(function () { + t.resume() + }) + }) + + read(t, function (err, actual) { + assert.ifError(err) + assert.deepEqual(actual, expected) + }) + + t.on('close', function () { + s.validate() + assert.end() + }) + + write(expected, t) +}) + +test('does not soft-end on `undefined`', function(assert) { + var stream = through() + , count = 0 + + stream.on('data', function (data) { + count++ + }) + + stream.write(undefined) + stream.write(undefined) + + assert.equal(count, 2) + + assert.end() +}) diff --git a/node_modules/trim-newlines/index.js b/node_modules/trim-newlines/index.js new file mode 100644 index 0000000..da31efd --- /dev/null +++ b/node_modules/trim-newlines/index.js @@ -0,0 +1,13 @@ +'use strict'; + +var fn = module.exports = function (x) { + return fn.end(fn.start(x)); +}; + +fn.start = function (x) { + return x.replace(/^[\r\n]+/, ''); +}; + +fn.end = function (x) { + return x.replace(/[\r\n]+$/, ''); +}; diff --git a/node_modules/trim-newlines/license b/node_modules/trim-newlines/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/trim-newlines/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/trim-newlines/package.json b/node_modules/trim-newlines/package.json new file mode 100644 index 0000000..9626376 --- /dev/null +++ b/node_modules/trim-newlines/package.json @@ -0,0 +1,106 @@ +{ + "_args": [ + [ + { + "raw": "trim-newlines@^1.0.0", + "scope": null, + "escapedName": "trim-newlines", + "name": "trim-newlines", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/meow" + ] + ], + "_from": "trim-newlines@>=1.0.0 <2.0.0", + "_id": "trim-newlines@1.0.0", + "_inCache": true, + "_location": "/trim-newlines", + "_nodeVersion": "4.1.1", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.14.4", + "_phantomChildren": {}, + "_requested": { + "raw": "trim-newlines@^1.0.0", + "scope": null, + "escapedName": "trim-newlines", + "name": "trim-newlines", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/meow" + ], + "_resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "_shasum": "5887966bb582a4503a41eb524f7d35011815a613", + "_shrinkwrap": null, + "_spec": "trim-newlines@^1.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/meow", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/trim-newlines/issues" + }, + "dependencies": {}, + "description": "Trim newlines from the start and/or end of a string", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "5887966bb582a4503a41eb524f7d35011815a613", + "tarball": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "f651a2d4cbf382c2936e6e53edee9316602e4ce7", + "homepage": "https://github.com/sindresorhus/trim-newlines", + "keywords": [ + "trim", + "newline", + "newlines", + "linebreak", + "lf", + "crlf", + "left", + "right", + "start", + "end", + "string", + "str", + "remove", + "delete", + "strip" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "trim-newlines", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/trim-newlines.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "1.0.0" +} diff --git a/node_modules/trim-newlines/readme.md b/node_modules/trim-newlines/readme.md new file mode 100644 index 0000000..fedb3ca --- /dev/null +++ b/node_modules/trim-newlines/readme.md @@ -0,0 +1,46 @@ +# trim-newlines [![Build Status](https://travis-ci.org/sindresorhus/trim-newlines.svg?branch=master)](https://travis-ci.org/sindresorhus/trim-newlines) + +> Trim [newlines](https://en.wikipedia.org/wiki/Newline) from the start and/or end of a string + + +## Install + +``` +$ npm install --save trim-newlines +``` + + +## Usage + +```js +var trimNewlines = require('trim-newlines'); + +trimNewlines('\nunicorn\r\n'); +//=> 'unicorn' +``` + + +## API + +### trimNewlines(input) + +Trim from the start and end of a string. + +### trimNewlines.start(input) + +Trim from the start of a string. + +### trimNewlines.end(input) + +Trim from the end of a string. + + +## Related + +- [trim-left](https://github.com/sindresorhus/trim-left) - Similar to `String#trim()` but removes only whitespace on the left +- [trim-right](https://github.com/sindresorhus/trim-right) - Similar to `String#trim()` but removes only whitespace on the right. + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/typedarray/.travis.yml b/node_modules/typedarray/.travis.yml new file mode 100644 index 0000000..cc4dba2 --- /dev/null +++ b/node_modules/typedarray/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "0.8" + - "0.10" diff --git a/node_modules/typedarray/LICENSE b/node_modules/typedarray/LICENSE new file mode 100644 index 0000000..11adfae --- /dev/null +++ b/node_modules/typedarray/LICENSE @@ -0,0 +1,35 @@ +/* + Copyright (c) 2010, Linden Research, Inc. + Copyright (c) 2012, Joshua Bell + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + $/LicenseInfo$ + */ + +// Original can be found at: +// https://bitbucket.org/lindenlab/llsd +// Modifications by Joshua Bell inexorabletash@gmail.com +// https://github.com/inexorabletash/polyfill + +// ES3/ES5 implementation of the Krhonos Typed Array Specification +// Ref: http://www.khronos.org/registry/typedarray/specs/latest/ +// Date: 2011-02-01 +// +// Variations: +// * Allows typed_array.get/set() as alias for subscripts (typed_array[]) diff --git a/node_modules/typedarray/example/tarray.js b/node_modules/typedarray/example/tarray.js new file mode 100644 index 0000000..8423d7c --- /dev/null +++ b/node_modules/typedarray/example/tarray.js @@ -0,0 +1,4 @@ +var Uint8Array = require('../').Uint8Array; +var ua = new Uint8Array(5); +ua[1] = 256 + 55; +console.log(ua[1]); diff --git a/node_modules/typedarray/index.js b/node_modules/typedarray/index.js new file mode 100644 index 0000000..5e54084 --- /dev/null +++ b/node_modules/typedarray/index.js @@ -0,0 +1,630 @@ +var undefined = (void 0); // Paranoia + +// Beyond this value, index getters/setters (i.e. array[0], array[1]) are so slow to +// create, and consume so much memory, that the browser appears frozen. +var MAX_ARRAY_LENGTH = 1e5; + +// Approximations of internal ECMAScript conversion functions +var ECMAScript = (function() { + // Stash a copy in case other scripts modify these + var opts = Object.prototype.toString, + ophop = Object.prototype.hasOwnProperty; + + return { + // Class returns internal [[Class]] property, used to avoid cross-frame instanceof issues: + Class: function(v) { return opts.call(v).replace(/^\[object *|\]$/g, ''); }, + HasProperty: function(o, p) { return p in o; }, + HasOwnProperty: function(o, p) { return ophop.call(o, p); }, + IsCallable: function(o) { return typeof o === 'function'; }, + ToInt32: function(v) { return v >> 0; }, + ToUint32: function(v) { return v >>> 0; } + }; +}()); + +// Snapshot intrinsics +var LN2 = Math.LN2, + abs = Math.abs, + floor = Math.floor, + log = Math.log, + min = Math.min, + pow = Math.pow, + round = Math.round; + +// ES5: lock down object properties +function configureProperties(obj) { + if (getOwnPropNames && defineProp) { + var props = getOwnPropNames(obj), i; + for (i = 0; i < props.length; i += 1) { + defineProp(obj, props[i], { + value: obj[props[i]], + writable: false, + enumerable: false, + configurable: false + }); + } + } +} + +// emulate ES5 getter/setter API using legacy APIs +// http://blogs.msdn.com/b/ie/archive/2010/09/07/transitioning-existing-code-to-the-es5-getter-setter-apis.aspx +// (second clause tests for Object.defineProperty() in IE<9 that only supports extending DOM prototypes, but +// note that IE<9 does not support __defineGetter__ or __defineSetter__ so it just renders the method harmless) +var defineProp +if (Object.defineProperty && (function() { + try { + Object.defineProperty({}, 'x', {}); + return true; + } catch (e) { + return false; + } + })()) { + defineProp = Object.defineProperty; +} else { + defineProp = function(o, p, desc) { + if (!o === Object(o)) throw new TypeError("Object.defineProperty called on non-object"); + if (ECMAScript.HasProperty(desc, 'get') && Object.prototype.__defineGetter__) { Object.prototype.__defineGetter__.call(o, p, desc.get); } + if (ECMAScript.HasProperty(desc, 'set') && Object.prototype.__defineSetter__) { Object.prototype.__defineSetter__.call(o, p, desc.set); } + if (ECMAScript.HasProperty(desc, 'value')) { o[p] = desc.value; } + return o; + }; +} + +var getOwnPropNames = Object.getOwnPropertyNames || function (o) { + if (o !== Object(o)) throw new TypeError("Object.getOwnPropertyNames called on non-object"); + var props = [], p; + for (p in o) { + if (ECMAScript.HasOwnProperty(o, p)) { + props.push(p); + } + } + return props; +}; + +// ES5: Make obj[index] an alias for obj._getter(index)/obj._setter(index, value) +// for index in 0 ... obj.length +function makeArrayAccessors(obj) { + if (!defineProp) { return; } + + if (obj.length > MAX_ARRAY_LENGTH) throw new RangeError("Array too large for polyfill"); + + function makeArrayAccessor(index) { + defineProp(obj, index, { + 'get': function() { return obj._getter(index); }, + 'set': function(v) { obj._setter(index, v); }, + enumerable: true, + configurable: false + }); + } + + var i; + for (i = 0; i < obj.length; i += 1) { + makeArrayAccessor(i); + } +} + +// Internal conversion functions: +// pack() - take a number (interpreted as Type), output a byte array +// unpack() - take a byte array, output a Type-like number + +function as_signed(value, bits) { var s = 32 - bits; return (value << s) >> s; } +function as_unsigned(value, bits) { var s = 32 - bits; return (value << s) >>> s; } + +function packI8(n) { return [n & 0xff]; } +function unpackI8(bytes) { return as_signed(bytes[0], 8); } + +function packU8(n) { return [n & 0xff]; } +function unpackU8(bytes) { return as_unsigned(bytes[0], 8); } + +function packU8Clamped(n) { n = round(Number(n)); return [n < 0 ? 0 : n > 0xff ? 0xff : n & 0xff]; } + +function packI16(n) { return [(n >> 8) & 0xff, n & 0xff]; } +function unpackI16(bytes) { return as_signed(bytes[0] << 8 | bytes[1], 16); } + +function packU16(n) { return [(n >> 8) & 0xff, n & 0xff]; } +function unpackU16(bytes) { return as_unsigned(bytes[0] << 8 | bytes[1], 16); } + +function packI32(n) { return [(n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff]; } +function unpackI32(bytes) { return as_signed(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], 32); } + +function packU32(n) { return [(n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff]; } +function unpackU32(bytes) { return as_unsigned(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], 32); } + +function packIEEE754(v, ebits, fbits) { + + var bias = (1 << (ebits - 1)) - 1, + s, e, f, ln, + i, bits, str, bytes; + + function roundToEven(n) { + var w = floor(n), f = n - w; + if (f < 0.5) + return w; + if (f > 0.5) + return w + 1; + return w % 2 ? w + 1 : w; + } + + // Compute sign, exponent, fraction + if (v !== v) { + // NaN + // http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping + e = (1 << ebits) - 1; f = pow(2, fbits - 1); s = 0; + } else if (v === Infinity || v === -Infinity) { + e = (1 << ebits) - 1; f = 0; s = (v < 0) ? 1 : 0; + } else if (v === 0) { + e = 0; f = 0; s = (1 / v === -Infinity) ? 1 : 0; + } else { + s = v < 0; + v = abs(v); + + if (v >= pow(2, 1 - bias)) { + e = min(floor(log(v) / LN2), 1023); + f = roundToEven(v / pow(2, e) * pow(2, fbits)); + if (f / pow(2, fbits) >= 2) { + e = e + 1; + f = 1; + } + if (e > bias) { + // Overflow + e = (1 << ebits) - 1; + f = 0; + } else { + // Normalized + e = e + bias; + f = f - pow(2, fbits); + } + } else { + // Denormalized + e = 0; + f = roundToEven(v / pow(2, 1 - bias - fbits)); + } + } + + // Pack sign, exponent, fraction + bits = []; + for (i = fbits; i; i -= 1) { bits.push(f % 2 ? 1 : 0); f = floor(f / 2); } + for (i = ebits; i; i -= 1) { bits.push(e % 2 ? 1 : 0); e = floor(e / 2); } + bits.push(s ? 1 : 0); + bits.reverse(); + str = bits.join(''); + + // Bits to bytes + bytes = []; + while (str.length) { + bytes.push(parseInt(str.substring(0, 8), 2)); + str = str.substring(8); + } + return bytes; +} + +function unpackIEEE754(bytes, ebits, fbits) { + + // Bytes to bits + var bits = [], i, j, b, str, + bias, s, e, f; + + for (i = bytes.length; i; i -= 1) { + b = bytes[i - 1]; + for (j = 8; j; j -= 1) { + bits.push(b % 2 ? 1 : 0); b = b >> 1; + } + } + bits.reverse(); + str = bits.join(''); + + // Unpack sign, exponent, fraction + bias = (1 << (ebits - 1)) - 1; + s = parseInt(str.substring(0, 1), 2) ? -1 : 1; + e = parseInt(str.substring(1, 1 + ebits), 2); + f = parseInt(str.substring(1 + ebits), 2); + + // Produce number + if (e === (1 << ebits) - 1) { + return f !== 0 ? NaN : s * Infinity; + } else if (e > 0) { + // Normalized + return s * pow(2, e - bias) * (1 + f / pow(2, fbits)); + } else if (f !== 0) { + // Denormalized + return s * pow(2, -(bias - 1)) * (f / pow(2, fbits)); + } else { + return s < 0 ? -0 : 0; + } +} + +function unpackF64(b) { return unpackIEEE754(b, 11, 52); } +function packF64(v) { return packIEEE754(v, 11, 52); } +function unpackF32(b) { return unpackIEEE754(b, 8, 23); } +function packF32(v) { return packIEEE754(v, 8, 23); } + + +// +// 3 The ArrayBuffer Type +// + +(function() { + + /** @constructor */ + var ArrayBuffer = function ArrayBuffer(length) { + length = ECMAScript.ToInt32(length); + if (length < 0) throw new RangeError('ArrayBuffer size is not a small enough positive integer'); + + this.byteLength = length; + this._bytes = []; + this._bytes.length = length; + + var i; + for (i = 0; i < this.byteLength; i += 1) { + this._bytes[i] = 0; + } + + configureProperties(this); + }; + + exports.ArrayBuffer = exports.ArrayBuffer || ArrayBuffer; + + // + // 4 The ArrayBufferView Type + // + + // NOTE: this constructor is not exported + /** @constructor */ + var ArrayBufferView = function ArrayBufferView() { + //this.buffer = null; + //this.byteOffset = 0; + //this.byteLength = 0; + }; + + // + // 5 The Typed Array View Types + // + + function makeConstructor(bytesPerElement, pack, unpack) { + // Each TypedArray type requires a distinct constructor instance with + // identical logic, which this produces. + + var ctor; + ctor = function(buffer, byteOffset, length) { + var array, sequence, i, s; + + if (!arguments.length || typeof arguments[0] === 'number') { + // Constructor(unsigned long length) + this.length = ECMAScript.ToInt32(arguments[0]); + if (length < 0) throw new RangeError('ArrayBufferView size is not a small enough positive integer'); + + this.byteLength = this.length * this.BYTES_PER_ELEMENT; + this.buffer = new ArrayBuffer(this.byteLength); + this.byteOffset = 0; + } else if (typeof arguments[0] === 'object' && arguments[0].constructor === ctor) { + // Constructor(TypedArray array) + array = arguments[0]; + + this.length = array.length; + this.byteLength = this.length * this.BYTES_PER_ELEMENT; + this.buffer = new ArrayBuffer(this.byteLength); + this.byteOffset = 0; + + for (i = 0; i < this.length; i += 1) { + this._setter(i, array._getter(i)); + } + } else if (typeof arguments[0] === 'object' && + !(arguments[0] instanceof ArrayBuffer || ECMAScript.Class(arguments[0]) === 'ArrayBuffer')) { + // Constructor(sequence array) + sequence = arguments[0]; + + this.length = ECMAScript.ToUint32(sequence.length); + this.byteLength = this.length * this.BYTES_PER_ELEMENT; + this.buffer = new ArrayBuffer(this.byteLength); + this.byteOffset = 0; + + for (i = 0; i < this.length; i += 1) { + s = sequence[i]; + this._setter(i, Number(s)); + } + } else if (typeof arguments[0] === 'object' && + (arguments[0] instanceof ArrayBuffer || ECMAScript.Class(arguments[0]) === 'ArrayBuffer')) { + // Constructor(ArrayBuffer buffer, + // optional unsigned long byteOffset, optional unsigned long length) + this.buffer = buffer; + + this.byteOffset = ECMAScript.ToUint32(byteOffset); + if (this.byteOffset > this.buffer.byteLength) { + throw new RangeError("byteOffset out of range"); + } + + if (this.byteOffset % this.BYTES_PER_ELEMENT) { + // The given byteOffset must be a multiple of the element + // size of the specific type, otherwise an exception is raised. + throw new RangeError("ArrayBuffer length minus the byteOffset is not a multiple of the element size."); + } + + if (arguments.length < 3) { + this.byteLength = this.buffer.byteLength - this.byteOffset; + + if (this.byteLength % this.BYTES_PER_ELEMENT) { + throw new RangeError("length of buffer minus byteOffset not a multiple of the element size"); + } + this.length = this.byteLength / this.BYTES_PER_ELEMENT; + } else { + this.length = ECMAScript.ToUint32(length); + this.byteLength = this.length * this.BYTES_PER_ELEMENT; + } + + if ((this.byteOffset + this.byteLength) > this.buffer.byteLength) { + throw new RangeError("byteOffset and length reference an area beyond the end of the buffer"); + } + } else { + throw new TypeError("Unexpected argument type(s)"); + } + + this.constructor = ctor; + + configureProperties(this); + makeArrayAccessors(this); + }; + + ctor.prototype = new ArrayBufferView(); + ctor.prototype.BYTES_PER_ELEMENT = bytesPerElement; + ctor.prototype._pack = pack; + ctor.prototype._unpack = unpack; + ctor.BYTES_PER_ELEMENT = bytesPerElement; + + // getter type (unsigned long index); + ctor.prototype._getter = function(index) { + if (arguments.length < 1) throw new SyntaxError("Not enough arguments"); + + index = ECMAScript.ToUint32(index); + if (index >= this.length) { + return undefined; + } + + var bytes = [], i, o; + for (i = 0, o = this.byteOffset + index * this.BYTES_PER_ELEMENT; + i < this.BYTES_PER_ELEMENT; + i += 1, o += 1) { + bytes.push(this.buffer._bytes[o]); + } + return this._unpack(bytes); + }; + + // NONSTANDARD: convenience alias for getter: type get(unsigned long index); + ctor.prototype.get = ctor.prototype._getter; + + // setter void (unsigned long index, type value); + ctor.prototype._setter = function(index, value) { + if (arguments.length < 2) throw new SyntaxError("Not enough arguments"); + + index = ECMAScript.ToUint32(index); + if (index >= this.length) { + return undefined; + } + + var bytes = this._pack(value), i, o; + for (i = 0, o = this.byteOffset + index * this.BYTES_PER_ELEMENT; + i < this.BYTES_PER_ELEMENT; + i += 1, o += 1) { + this.buffer._bytes[o] = bytes[i]; + } + }; + + // void set(TypedArray array, optional unsigned long offset); + // void set(sequence array, optional unsigned long offset); + ctor.prototype.set = function(index, value) { + if (arguments.length < 1) throw new SyntaxError("Not enough arguments"); + var array, sequence, offset, len, + i, s, d, + byteOffset, byteLength, tmp; + + if (typeof arguments[0] === 'object' && arguments[0].constructor === this.constructor) { + // void set(TypedArray array, optional unsigned long offset); + array = arguments[0]; + offset = ECMAScript.ToUint32(arguments[1]); + + if (offset + array.length > this.length) { + throw new RangeError("Offset plus length of array is out of range"); + } + + byteOffset = this.byteOffset + offset * this.BYTES_PER_ELEMENT; + byteLength = array.length * this.BYTES_PER_ELEMENT; + + if (array.buffer === this.buffer) { + tmp = []; + for (i = 0, s = array.byteOffset; i < byteLength; i += 1, s += 1) { + tmp[i] = array.buffer._bytes[s]; + } + for (i = 0, d = byteOffset; i < byteLength; i += 1, d += 1) { + this.buffer._bytes[d] = tmp[i]; + } + } else { + for (i = 0, s = array.byteOffset, d = byteOffset; + i < byteLength; i += 1, s += 1, d += 1) { + this.buffer._bytes[d] = array.buffer._bytes[s]; + } + } + } else if (typeof arguments[0] === 'object' && typeof arguments[0].length !== 'undefined') { + // void set(sequence array, optional unsigned long offset); + sequence = arguments[0]; + len = ECMAScript.ToUint32(sequence.length); + offset = ECMAScript.ToUint32(arguments[1]); + + if (offset + len > this.length) { + throw new RangeError("Offset plus length of array is out of range"); + } + + for (i = 0; i < len; i += 1) { + s = sequence[i]; + this._setter(offset + i, Number(s)); + } + } else { + throw new TypeError("Unexpected argument type(s)"); + } + }; + + // TypedArray subarray(long begin, optional long end); + ctor.prototype.subarray = function(start, end) { + function clamp(v, min, max) { return v < min ? min : v > max ? max : v; } + + start = ECMAScript.ToInt32(start); + end = ECMAScript.ToInt32(end); + + if (arguments.length < 1) { start = 0; } + if (arguments.length < 2) { end = this.length; } + + if (start < 0) { start = this.length + start; } + if (end < 0) { end = this.length + end; } + + start = clamp(start, 0, this.length); + end = clamp(end, 0, this.length); + + var len = end - start; + if (len < 0) { + len = 0; + } + + return new this.constructor( + this.buffer, this.byteOffset + start * this.BYTES_PER_ELEMENT, len); + }; + + return ctor; + } + + var Int8Array = makeConstructor(1, packI8, unpackI8); + var Uint8Array = makeConstructor(1, packU8, unpackU8); + var Uint8ClampedArray = makeConstructor(1, packU8Clamped, unpackU8); + var Int16Array = makeConstructor(2, packI16, unpackI16); + var Uint16Array = makeConstructor(2, packU16, unpackU16); + var Int32Array = makeConstructor(4, packI32, unpackI32); + var Uint32Array = makeConstructor(4, packU32, unpackU32); + var Float32Array = makeConstructor(4, packF32, unpackF32); + var Float64Array = makeConstructor(8, packF64, unpackF64); + + exports.Int8Array = exports.Int8Array || Int8Array; + exports.Uint8Array = exports.Uint8Array || Uint8Array; + exports.Uint8ClampedArray = exports.Uint8ClampedArray || Uint8ClampedArray; + exports.Int16Array = exports.Int16Array || Int16Array; + exports.Uint16Array = exports.Uint16Array || Uint16Array; + exports.Int32Array = exports.Int32Array || Int32Array; + exports.Uint32Array = exports.Uint32Array || Uint32Array; + exports.Float32Array = exports.Float32Array || Float32Array; + exports.Float64Array = exports.Float64Array || Float64Array; +}()); + +// +// 6 The DataView View Type +// + +(function() { + function r(array, index) { + return ECMAScript.IsCallable(array.get) ? array.get(index) : array[index]; + } + + var IS_BIG_ENDIAN = (function() { + var u16array = new(exports.Uint16Array)([0x1234]), + u8array = new(exports.Uint8Array)(u16array.buffer); + return r(u8array, 0) === 0x12; + }()); + + // Constructor(ArrayBuffer buffer, + // optional unsigned long byteOffset, + // optional unsigned long byteLength) + /** @constructor */ + var DataView = function DataView(buffer, byteOffset, byteLength) { + if (arguments.length === 0) { + buffer = new exports.ArrayBuffer(0); + } else if (!(buffer instanceof exports.ArrayBuffer || ECMAScript.Class(buffer) === 'ArrayBuffer')) { + throw new TypeError("TypeError"); + } + + this.buffer = buffer || new exports.ArrayBuffer(0); + + this.byteOffset = ECMAScript.ToUint32(byteOffset); + if (this.byteOffset > this.buffer.byteLength) { + throw new RangeError("byteOffset out of range"); + } + + if (arguments.length < 3) { + this.byteLength = this.buffer.byteLength - this.byteOffset; + } else { + this.byteLength = ECMAScript.ToUint32(byteLength); + } + + if ((this.byteOffset + this.byteLength) > this.buffer.byteLength) { + throw new RangeError("byteOffset and length reference an area beyond the end of the buffer"); + } + + configureProperties(this); + }; + + function makeGetter(arrayType) { + return function(byteOffset, littleEndian) { + + byteOffset = ECMAScript.ToUint32(byteOffset); + + if (byteOffset + arrayType.BYTES_PER_ELEMENT > this.byteLength) { + throw new RangeError("Array index out of range"); + } + byteOffset += this.byteOffset; + + var uint8Array = new exports.Uint8Array(this.buffer, byteOffset, arrayType.BYTES_PER_ELEMENT), + bytes = [], i; + for (i = 0; i < arrayType.BYTES_PER_ELEMENT; i += 1) { + bytes.push(r(uint8Array, i)); + } + + if (Boolean(littleEndian) === Boolean(IS_BIG_ENDIAN)) { + bytes.reverse(); + } + + return r(new arrayType(new exports.Uint8Array(bytes).buffer), 0); + }; + } + + DataView.prototype.getUint8 = makeGetter(exports.Uint8Array); + DataView.prototype.getInt8 = makeGetter(exports.Int8Array); + DataView.prototype.getUint16 = makeGetter(exports.Uint16Array); + DataView.prototype.getInt16 = makeGetter(exports.Int16Array); + DataView.prototype.getUint32 = makeGetter(exports.Uint32Array); + DataView.prototype.getInt32 = makeGetter(exports.Int32Array); + DataView.prototype.getFloat32 = makeGetter(exports.Float32Array); + DataView.prototype.getFloat64 = makeGetter(exports.Float64Array); + + function makeSetter(arrayType) { + return function(byteOffset, value, littleEndian) { + + byteOffset = ECMAScript.ToUint32(byteOffset); + if (byteOffset + arrayType.BYTES_PER_ELEMENT > this.byteLength) { + throw new RangeError("Array index out of range"); + } + + // Get bytes + var typeArray = new arrayType([value]), + byteArray = new exports.Uint8Array(typeArray.buffer), + bytes = [], i, byteView; + + for (i = 0; i < arrayType.BYTES_PER_ELEMENT; i += 1) { + bytes.push(r(byteArray, i)); + } + + // Flip if necessary + if (Boolean(littleEndian) === Boolean(IS_BIG_ENDIAN)) { + bytes.reverse(); + } + + // Write them + byteView = new exports.Uint8Array(this.buffer, byteOffset, arrayType.BYTES_PER_ELEMENT); + byteView.set(bytes); + }; + } + + DataView.prototype.setUint8 = makeSetter(exports.Uint8Array); + DataView.prototype.setInt8 = makeSetter(exports.Int8Array); + DataView.prototype.setUint16 = makeSetter(exports.Uint16Array); + DataView.prototype.setInt16 = makeSetter(exports.Int16Array); + DataView.prototype.setUint32 = makeSetter(exports.Uint32Array); + DataView.prototype.setInt32 = makeSetter(exports.Int32Array); + DataView.prototype.setFloat32 = makeSetter(exports.Float32Array); + DataView.prototype.setFloat64 = makeSetter(exports.Float64Array); + + exports.DataView = exports.DataView || DataView; + +}()); diff --git a/node_modules/typedarray/package.json b/node_modules/typedarray/package.json new file mode 100644 index 0000000..066dd11 --- /dev/null +++ b/node_modules/typedarray/package.json @@ -0,0 +1,113 @@ +{ + "_args": [ + [ + { + "raw": "typedarray@~0.0.5", + "scope": null, + "escapedName": "typedarray", + "name": "typedarray", + "rawSpec": "~0.0.5", + "spec": ">=0.0.5 <0.1.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/concat-stream" + ] + ], + "_from": "typedarray@>=0.0.5 <0.1.0", + "_id": "typedarray@0.0.6", + "_inCache": true, + "_location": "/typedarray", + "_npmUser": { + "name": "substack", + "email": "mail@substack.net" + }, + "_npmVersion": "1.4.3", + "_phantomChildren": {}, + "_requested": { + "raw": "typedarray@~0.0.5", + "scope": null, + "escapedName": "typedarray", + "name": "typedarray", + "rawSpec": "~0.0.5", + "spec": ">=0.0.5 <0.1.0", + "type": "range" + }, + "_requiredBy": [ + "/concat-stream" + ], + "_resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "_shasum": "867ac74e3864187b1d3d47d996a78ec5c8830777", + "_shrinkwrap": null, + "_spec": "typedarray@~0.0.5", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/concat-stream", + "author": { + "name": "James Halliday", + "email": "mail@substack.net", + "url": "http://substack.net" + }, + "bugs": { + "url": "https://github.com/substack/typedarray/issues" + }, + "dependencies": {}, + "description": "TypedArray polyfill for old browsers", + "devDependencies": { + "tape": "~2.3.2" + }, + "directories": {}, + "dist": { + "shasum": "867ac74e3864187b1d3d47d996a78ec5c8830777", + "tarball": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" + }, + "homepage": "https://github.com/substack/typedarray", + "keywords": [ + "ArrayBuffer", + "DataView", + "Float32Array", + "Float64Array", + "Int8Array", + "Int16Array", + "Int32Array", + "Uint8Array", + "Uint8ClampedArray", + "Uint16Array", + "Uint32Array", + "typed", + "array", + "polyfill" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "substack", + "email": "mail@substack.net" + } + ], + "name": "typedarray", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/substack/typedarray.git" + }, + "scripts": { + "test": "tape test/*.js test/server/*.js" + }, + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/6..latest", + "firefox/16..latest", + "firefox/nightly", + "chrome/22..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + }, + "version": "0.0.6" +} diff --git a/node_modules/typedarray/readme.markdown b/node_modules/typedarray/readme.markdown new file mode 100644 index 0000000..d18f6f7 --- /dev/null +++ b/node_modules/typedarray/readme.markdown @@ -0,0 +1,61 @@ +# typedarray + +TypedArray polyfill ripped from [this +module](https://raw.github.com/inexorabletash/polyfill). + +[![build status](https://secure.travis-ci.org/substack/typedarray.png)](http://travis-ci.org/substack/typedarray) + +[![testling badge](https://ci.testling.com/substack/typedarray.png)](https://ci.testling.com/substack/typedarray) + +# example + +``` js +var Uint8Array = require('typedarray').Uint8Array; +var ua = new Uint8Array(5); +ua[1] = 256 + 55; +console.log(ua[1]); +``` + +output: + +``` +55 +``` + +# methods + +``` js +var TA = require('typedarray') +``` + +The `TA` object has the following constructors: + +* TA.ArrayBuffer +* TA.DataView +* TA.Float32Array +* TA.Float64Array +* TA.Int8Array +* TA.Int16Array +* TA.Int32Array +* TA.Uint8Array +* TA.Uint8ClampedArray +* TA.Uint16Array +* TA.Uint32Array + +# install + +With [npm](https://npmjs.org) do: + +``` +npm install typedarray +``` + +To use this module in the browser, compile with +[browserify](http://browserify.org) +or download a UMD build from browserify CDN: + +http://wzrd.in/standalone/typedarray@latest + +# license + +MIT diff --git a/node_modules/typedarray/test/server/undef_globals.js b/node_modules/typedarray/test/server/undef_globals.js new file mode 100644 index 0000000..425950f --- /dev/null +++ b/node_modules/typedarray/test/server/undef_globals.js @@ -0,0 +1,19 @@ +var test = require('tape'); +var vm = require('vm'); +var fs = require('fs'); +var src = fs.readFileSync(__dirname + '/../../index.js', 'utf8'); + +test('u8a without globals', function (t) { + var c = { + module: { exports: {} }, + }; + c.exports = c.module.exports; + vm.runInNewContext(src, c); + var TA = c.module.exports; + var ua = new(TA.Uint8Array)(5); + + t.equal(ua.length, 5); + ua[1] = 256 + 55; + t.equal(ua[1], 55); + t.end(); +}); diff --git a/node_modules/typedarray/test/tarray.js b/node_modules/typedarray/test/tarray.js new file mode 100644 index 0000000..df596a3 --- /dev/null +++ b/node_modules/typedarray/test/tarray.js @@ -0,0 +1,10 @@ +var TA = require('../'); +var test = require('tape'); + +test('tiny u8a test', function (t) { + var ua = new(TA.Uint8Array)(5); + t.equal(ua.length, 5); + ua[1] = 256 + 55; + t.equal(ua[1], 55); + t.end(); +}); diff --git a/node_modules/uglify-js/LICENSE b/node_modules/uglify-js/LICENSE new file mode 100644 index 0000000..dd7706f --- /dev/null +++ b/node_modules/uglify-js/LICENSE @@ -0,0 +1,29 @@ +UglifyJS is released under the BSD license: + +Copyright 2012-2013 (c) Mihai Bazon + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/node_modules/uglify-js/README.md b/node_modules/uglify-js/README.md new file mode 100644 index 0000000..eb3305b --- /dev/null +++ b/node_modules/uglify-js/README.md @@ -0,0 +1,939 @@ +UglifyJS 2 +========== +[![Build Status](https://travis-ci.org/mishoo/UglifyJS2.svg)](https://travis-ci.org/mishoo/UglifyJS2) + +UglifyJS is a JavaScript parser, minifier, compressor or beautifier toolkit. + +This page documents the command line utility. For +[API and internals documentation see my website](http://lisperator.net/uglifyjs/). +There's also an +[in-browser online demo](http://lisperator.net/uglifyjs/#demo) (for Firefox, +Chrome and probably Safari). + +Install +------- + +First make sure you have installed the latest version of [node.js](http://nodejs.org/) +(You may need to restart your computer after this step). + +From NPM for use as a command line app: + + npm install uglify-js -g + +From NPM for programmatic use: + + npm install uglify-js + +From Git: + + git clone git://github.com/mishoo/UglifyJS2.git + cd UglifyJS2 + npm link . + +Usage +----- + + uglifyjs [input files] [options] + +UglifyJS2 can take multiple input files. It's recommended that you pass the +input files first, then pass the options. UglifyJS will parse input files +in sequence and apply any compression options. The files are parsed in the +same global scope, that is, a reference from a file to some +variable/function declared in another file will be matched properly. + +If you want to read from STDIN instead, pass a single dash instead of input +files. + +If you wish to pass your options before the input files, separate the two with +a double dash to prevent input files being used as option arguments: + + uglifyjs --compress --mangle -- input.js + +The available options are: + +``` + --source-map Specify an output file where to generate source + map. + --source-map-root The path to the original source to be included + in the source map. + --source-map-url The path to the source map to be added in //# + sourceMappingURL. Defaults to the value passed + with --source-map. + --source-map-include-sources Pass this flag if you want to include the + content of source files in the source map as + sourcesContent property. + --source-map-inline Write base64-encoded source map to the end of js output. + --in-source-map Input source map, useful if you're compressing + JS that was generated from some other original + code. + --screw-ie8 Use this flag if you don't wish to support + Internet Explorer 6-8 quirks. + By default UglifyJS will not try to be IE-proof. + --support-ie8 Use this flag to support Internet Explorer 6-8 quirks. + Note: may break standards compliant `catch` identifiers. + --expr Parse a single expression, rather than a + program (for parsing JSON) + -p, --prefix Skip prefix for original filenames that appear + in source maps. For example -p 3 will drop 3 + directories from file names and ensure they are + relative paths. You can also specify -p + relative, which will make UglifyJS figure out + itself the relative paths between original + sources, the source map and the output file. + -o, --output Output file (default STDOUT). + -b, --beautify Beautify output/specify output options. + -m, --mangle Mangle names/pass mangler options. + -r, --reserved Reserved names to exclude from mangling. + -c, --compress Enable compressor/pass compressor options. Pass + options like -c + hoist_vars=false,if_return=false. Use -c with + no argument to use the default compression + options. + -d, --define Global definitions + -e, --enclose Embed everything in a big function, with a + configurable parameter/argument list. + --comments Preserve copyright comments in the output. By + default this works like Google Closure, keeping + JSDoc-style comments that contain "@license" or + "@preserve". You can optionally pass one of the + following arguments to this flag: + - "all" to keep all comments + - a valid JS RegExp like `/foo/` or `/^!/` to + keep only matching comments. + Note that currently not *all* comments can be + kept when compression is on, because of dead + code removal or cascading statements into + sequences. + --preamble Preamble to prepend to the output. You can use + this to insert a comment, for example for + licensing information. This will not be + parsed, but the source map will adjust for its + presence. + --stats Display operations run time on STDERR. + --acorn Use Acorn for parsing. + --spidermonkey Assume input files are SpiderMonkey AST format + (as JSON). + --self Build itself (UglifyJS2) as a library (implies + --wrap=UglifyJS --export-all) + --wrap Embed everything in a big function, making the + “exports” and “global” variables available. You + need to pass an argument to this option to + specify the name that your module will take + when included in, say, a browser. + --export-all Only used when --wrap, this tells UglifyJS to + add code to automatically export all globals. + --lint Display some scope warnings + -v, --verbose Verbose + -V, --version Print version number and exit. + --noerr Don't throw an error for unknown options in -c, + -b or -m. + --bare-returns Allow return outside of functions. Useful when + minifying CommonJS modules and Userscripts that + may be anonymous function wrapped (IIFE) by the + .user.js engine `caller`. + --keep-fnames Do not mangle/drop function names. Useful for + code relying on Function.prototype.name. + --reserved-file File containing reserved names + --reserve-domprops Make (most?) DOM properties reserved for + --mangle-props + --mangle-props Mangle property names (default `0`). Set to + `true` or `1` to mangle all property names. Set + to `unquoted` or `2` to only mangle unquoted + property names. Mode `2` also enables the + `keep_quoted_props` beautifier option to + preserve the quotes around property names and + disables the `properties` compressor option to + prevent rewriting quoted properties with dot + notation. You can override these by setting + them explicitly on the command line. + --mangle-regex Only mangle property names matching the regex + --name-cache File to hold mangled names mappings + --pure-funcs List of functions that can be safely removed if + their return value is not used [array] +``` + +Specify `--output` (`-o`) to declare the output file. Otherwise the output +goes to STDOUT. + +## Source map options + +UglifyJS2 can generate a source map file, which is highly useful for +debugging your compressed JavaScript. To get a source map, pass +`--source-map output.js.map` (full path to the file where you want the +source map dumped). + +Additionally you might need `--source-map-root` to pass the URL where the +original files can be found. In case you are passing full paths to input +files to UglifyJS, you can use `--prefix` (`-p`) to specify the number of +directories to drop from the path prefix when declaring files in the source +map. + +For example: + + uglifyjs /home/doe/work/foo/src/js/file1.js \ + /home/doe/work/foo/src/js/file2.js \ + -o foo.min.js \ + --source-map foo.min.js.map \ + --source-map-root http://foo.com/src \ + -p 5 -c -m + +The above will compress and mangle `file1.js` and `file2.js`, will drop the +output in `foo.min.js` and the source map in `foo.min.js.map`. The source +mapping will refer to `http://foo.com/src/js/file1.js` and +`http://foo.com/src/js/file2.js` (in fact it will list `http://foo.com/src` +as the source map root, and the original files as `js/file1.js` and +`js/file2.js`). + +### Composed source map + +When you're compressing JS code that was output by a compiler such as +CoffeeScript, mapping to the JS code won't be too helpful. Instead, you'd +like to map back to the original code (i.e. CoffeeScript). UglifyJS has an +option to take an input source map. Assuming you have a mapping from +CoffeeScript → compiled JS, UglifyJS can generate a map from CoffeeScript → +compressed JS by mapping every token in the compiled JS to its original +location. + +To use this feature you need to pass `--in-source-map +/path/to/input/source.map`. Normally the input source map should also point +to the file containing the generated JS, so if that's correct you can omit +input files from the command line. + +## Mangler options + +To enable the mangler you need to pass `--mangle` (`-m`). The following +(comma-separated) options are supported: + +- `toplevel` — mangle names declared in the toplevel scope (disabled by + default). + +- `eval` — mangle names visible in scopes where `eval` or `with` are used + (disabled by default). + +When mangling is enabled but you want to prevent certain names from being +mangled, you can declare those names with `--reserved` (`-r`) — pass a +comma-separated list of names. For example: + + uglifyjs ... -m -r '$,require,exports' + +to prevent the `require`, `exports` and `$` names from being changed. + +### Mangling property names (`--mangle-props`) + +**Note:** this will probably break your code. Mangling property names is a +separate step, different from variable name mangling. Pass +`--mangle-props`. It will mangle all properties that are seen in some +object literal, or that are assigned to. For example: + +```js +var x = { + foo: 1 +}; + +x.bar = 2; +x["baz"] = 3; +x[condition ? "moo" : "boo"] = 4; +console.log(x.something()); +``` + +In the above code, `foo`, `bar`, `baz`, `moo` and `boo` will be replaced +with single characters, while `something()` will be left as is. + +In order for this to be of any use, we should avoid mangling standard JS +names. For instance, if your code would contain `x.length = 10`, then +`length` becomes a candidate for mangling and it will be mangled throughout +the code, regardless if it's being used as part of your own objects or +accessing an array's length. To avoid that, you can use `--reserved-file` +to pass a filename that should contain the names to be excluded from +mangling. This file can be used both for excluding variable names and +property names. It could look like this, for example: + +```js +{ + "vars": [ "define", "require", ... ], + "props": [ "length", "prototype", ... ] +} +``` + +`--reserved-file` can be an array of file names (either a single +comma-separated argument, or you can pass multiple `--reserved-file` +arguments) — in this case it will exclude names from all those files. + +A default exclusion file is provided in `tools/domprops.json` which should +cover most standard JS and DOM properties defined in various browsers. Pass +`--reserve-domprops` to read that in. + +You can also use a regular expression to define which property names should be +mangled. For example, `--mangle-regex="/^_/"` will only mangle property names +that start with an underscore. + +When you compress multiple files using this option, in order for them to +work together in the end we need to ensure somehow that one property gets +mangled to the same name in all of them. For this, pass `--name-cache +filename.json` and UglifyJS will maintain these mappings in a file which can +then be reused. It should be initially empty. Example: + +``` +rm -f /tmp/cache.json # start fresh +uglifyjs file1.js file2.js --mangle-props --name-cache /tmp/cache.json -o part1.js +uglifyjs file3.js file4.js --mangle-props --name-cache /tmp/cache.json -o part2.js +``` + +Now, `part1.js` and `part2.js` will be consistent with each other in terms +of mangled property names. + +Using the name cache is not necessary if you compress all your files in a +single call to UglifyJS. + +#### Debugging property name mangling + +You can also pass `--mangle-props-debug` in order to mangle property names +without completely obscuring them. For example the property `o.foo` +would mangle to `o._$foo$_` with this option. This allows property mangling +of a large codebase while still being able to debug the code and identify +where mangling is breaking things. + +You can also pass a custom suffix using `--mangle-props-debug=XYZ`. This would then +mangle `o.foo` to `o._$foo$XYZ_`. You can change this each time you compile a +script to identify how a property got mangled. One technique is to pass a +random number on every compile to simulate mangling changing with different +inputs (e.g. as you update the input script with new properties), and to help +identify mistakes like writing mangled keys to storage. + +## Compressor options + +You need to pass `--compress` (`-c`) to enable the compressor. Optionally +you can pass a comma-separated list of options. Options are in the form +`foo=bar`, or just `foo` (the latter implies a boolean option that you want +to set `true`; it's effectively a shortcut for `foo=true`). + +- `sequences` (default: true) -- join consecutive simple statements using the + comma operator. May be set to a positive integer to specify the maximum number + of consecutive comma sequences that will be generated. If this option is set to + `true` then the default `sequences` limit is `200`. Set option to `false` or `0` + to disable. The smallest `sequences` length is `2`. A `sequences` value of `1` + is grandfathered to be equivalent to `true` and as such means `200`. On rare + occasions the default sequences limit leads to very slow compress times in which + case a value of `20` or less is recommended. + +- `properties` -- rewrite property access using the dot notation, for + example `foo["bar"] → foo.bar` + +- `dead_code` -- remove unreachable code + +- `drop_debugger` -- remove `debugger;` statements + +- `unsafe` (default: false) -- apply "unsafe" transformations (discussion below) + +- `unsafe_comps` (default: false) -- Reverse `<` and `<=` to `>` and `>=` to + allow improved compression. This might be unsafe when an at least one of two + operands is an object with computed values due the use of methods like `get`, + or `valueOf`. This could cause change in execution order after operands in the + comparison are switching. Compression only works if both `comparisons` and + `unsafe_comps` are both set to true. + +- `conditionals` -- apply optimizations for `if`-s and conditional + expressions + +- `comparisons` -- apply certain optimizations to binary nodes, for example: + `!(a <= b) → a > b` (only when `unsafe_comps`), attempts to negate binary + nodes, e.g. `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc. + +- `evaluate` -- attempt to evaluate constant expressions + +- `booleans` -- various optimizations for boolean context, for example `!!a + ? b : c → a ? b : c` + +- `loops` -- optimizations for `do`, `while` and `for` loops when we can + statically determine the condition + +- `unused` -- drop unreferenced functions and variables + +- `hoist_funs` -- hoist function declarations + +- `hoist_vars` (default: false) -- hoist `var` declarations (this is `false` + by default because it seems to increase the size of the output in general) + +- `if_return` -- optimizations for if/return and if/continue + +- `join_vars` -- join consecutive `var` statements + +- `cascade` -- small optimization for sequences, transform `x, x` into `x` + and `x = something(), x` into `x = something()` + +- `collapse_vars` -- default `false`. Collapse single-use `var` and `const` + definitions when possible. + +- `reduce_vars` -- default `false`. Improve optimization on variables assigned + with and used as constant values. + +- `warnings` -- display warnings when dropping unreachable code or unused + declarations etc. + +- `negate_iife` -- negate "Immediately-Called Function Expressions" + where the return value is discarded, to avoid the parens that the + code generator would insert. + +- `pure_getters` -- the default is `false`. If you pass `true` for + this, UglifyJS will assume that object property access + (e.g. `foo.bar` or `foo["bar"]`) doesn't have any side effects. + +- `pure_funcs` -- default `null`. You can pass an array of names and + UglifyJS will assume that those functions do not produce side + effects. DANGER: will not check if the name is redefined in scope. + An example case here, for instance `var q = Math.floor(a/b)`. If + variable `q` is not used elsewhere, UglifyJS will drop it, but will + still keep the `Math.floor(a/b)`, not knowing what it does. You can + pass `pure_funcs: [ 'Math.floor' ]` to let it know that this + function won't produce any side effect, in which case the whole + statement would get discarded. The current implementation adds some + overhead (compression will be slower). + +- `drop_console` -- default `false`. Pass `true` to discard calls to + `console.*` functions. + +- `keep_fargs` -- default `true`. Prevents the + compressor from discarding unused function arguments. You need this + for code which relies on `Function.length`. + +- `keep_fnames` -- default `false`. Pass `true` to prevent the + compressor from discarding function names. Useful for code relying on + `Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle). + +- `passes` -- default `1`. Number of times to run compress. Use an + integer argument larger than 1 to further reduce code size in some cases. + Note: raising the number of passes will increase uglify compress time. + +### The `unsafe` option + +It enables some transformations that *might* break code logic in certain +contrived cases, but should be fine for most code. You might want to try it +on your own code, it should reduce the minified size. Here's what happens +when this flag is on: + +- `new Array(1, 2, 3)` or `Array(1, 2, 3)` → `[ 1, 2, 3 ]` +- `new Object()` → `{}` +- `String(exp)` or `exp.toString()` → `"" + exp` +- `new Object/RegExp/Function/Error/Array (...)` → we discard the `new` +- `typeof foo == "undefined"` → `foo === void 0` +- `void 0` → `undefined` (if there is a variable named "undefined" in + scope; we do it because the variable name will be mangled, typically + reduced to a single character) + +### Conditional compilation + +You can use the `--define` (`-d`) switch in order to declare global +variables that UglifyJS will assume to be constants (unless defined in +scope). For example if you pass `--define DEBUG=false` then, coupled with +dead code removal UglifyJS will discard the following from the output: +```javascript +if (DEBUG) { + console.log("debug stuff"); +} +``` + +UglifyJS will warn about the condition being always false and about dropping +unreachable code; for now there is no option to turn off only this specific +warning, you can pass `warnings=false` to turn off *all* warnings. + +Another way of doing that is to declare your globals as constants in a +separate file and include it into the build. For example you can have a +`build/defines.js` file with the following: +```javascript +const DEBUG = false; +const PRODUCTION = true; +// Alternative for environments that don't support `const` +/** @const */ var STAGING = false; +// etc. +``` + +and build your code like this: + + uglifyjs build/defines.js js/foo.js js/bar.js... -c + +UglifyJS will notice the constants and, since they cannot be altered, it +will evaluate references to them to the value itself and drop unreachable +code as usual. The build will contain the `const` declarations if you use +them. If you are targeting < ES6 environments, use `/** @const */ var`. + + + +#### Conditional compilation, API +You can also use conditional compilation via the programmatic API. With the difference that the +property name is `global_defs` and is a compressor property: + +```js +uglifyJS.minify([ "input.js"], { + compress: { + dead_code: true, + global_defs: { + DEBUG: false + } + } +}); +``` + +## Beautifier options + +The code generator tries to output shortest code possible by default. In +case you want beautified output, pass `--beautify` (`-b`). Optionally you +can pass additional arguments that control the code output: + +- `beautify` (default `true`) -- whether to actually beautify the output. + Passing `-b` will set this to true, but you might need to pass `-b` even + when you want to generate minified code, in order to specify additional + arguments, so you can use `-b beautify=false` to override it. +- `indent-level` (default 4) +- `indent-start` (default 0) -- prefix all lines by that many spaces +- `quote-keys` (default `false`) -- pass `true` to quote all keys in literal + objects +- `space-colon` (default `true`) -- insert a space after the colon signs +- `ascii-only` (default `false`) -- escape Unicode characters in strings and + regexps (affects directives with non-ascii characters becoming invalid) +- `inline-script` (default `false`) -- escape the slash in occurrences of + ` 0) { + print_error("WARN: Ignoring input files since --self was passed"); + } + files = UglifyJS.FILES; + if (!ARGS.wrap) ARGS.wrap = "UglifyJS"; +} + +var ORIG_MAP = ARGS.in_source_map; + +if (ORIG_MAP) { + ORIG_MAP = JSON.parse(fs.readFileSync(ORIG_MAP)); + if (files.length == 0) { + print_error("INFO: Using file from the input source map: " + ORIG_MAP.file); + files = [ ORIG_MAP.file ]; + } + if (ARGS.source_map_root == null) { + ARGS.source_map_root = ORIG_MAP.sourceRoot; + } +} + +if (files.length == 0) { + files = [ "-" ]; +} + +if (files.indexOf("-") >= 0 && ARGS.source_map) { + print_error("ERROR: Source map doesn't work with input from STDIN"); + process.exit(1); +} + +if (files.filter(function(el){ return el == "-" }).length > 1) { + print_error("ERROR: Can read a single file from STDIN (two or more dashes specified)"); + process.exit(1); +} + +var STATS = {}; +var OUTPUT_FILE = ARGS.o; +var TOPLEVEL = null; +var P_RELATIVE = ARGS.p && ARGS.p == "relative"; +var SOURCES_CONTENT = {}; + +var SOURCE_MAP = (ARGS.source_map || ARGS.source_map_inline) ? UglifyJS.SourceMap({ + file: P_RELATIVE ? path.relative(path.dirname(ARGS.source_map), OUTPUT_FILE) : OUTPUT_FILE, + root: ARGS.source_map_root, + orig: ORIG_MAP, +}) : null; + +OUTPUT_OPTIONS.source_map = SOURCE_MAP; + +try { + var output = UglifyJS.OutputStream(OUTPUT_OPTIONS); + var compressor = COMPRESS && UglifyJS.Compressor(COMPRESS); +} catch(ex) { + if (ex instanceof UglifyJS.DefaultsError) { + print_error(ex.msg); + print_error("Supported options:"); + print_error(sys.inspect(ex.defs)); + process.exit(1); + } +} + +async.eachLimit(files, 1, function (file, cb) { + read_whole_file(file, function (err, code) { + if (err) { + print_error("ERROR: can't read file: " + file); + process.exit(1); + } + if (ARGS.p != null) { + if (P_RELATIVE) { + file = path.relative(path.dirname(ARGS.source_map), file).replace(/\\/g, '/'); + } else { + var p = parseInt(ARGS.p, 10); + if (!isNaN(p)) { + file = file.replace(/^\/+/, "").split(/\/+/).slice(ARGS.p).join("/"); + } + } + } + SOURCES_CONTENT[file] = code; + time_it("parse", function(){ + if (ARGS.spidermonkey) { + var program = JSON.parse(code); + if (!TOPLEVEL) TOPLEVEL = program; + else TOPLEVEL.body = TOPLEVEL.body.concat(program.body); + } + else if (ARGS.acorn) { + TOPLEVEL = acorn.parse(code, { + locations : true, + sourceFile : file, + program : TOPLEVEL + }); + } + else { + try { + TOPLEVEL = UglifyJS.parse(code, { + filename : file, + toplevel : TOPLEVEL, + expression : ARGS.expr, + bare_returns : ARGS.bare_returns, + }); + } catch(ex) { + if (ex instanceof UglifyJS.JS_Parse_Error) { + print_error("Parse error at " + file + ":" + ex.line + "," + ex.col); + print_error(ex.message); + print_error(ex.stack); + process.exit(1); + } + throw ex; + } + }; + }); + cb(); + }); +}, function () { + if (ARGS.acorn || ARGS.spidermonkey) time_it("convert_ast", function(){ + TOPLEVEL = UglifyJS.AST_Node.from_mozilla_ast(TOPLEVEL); + }); + + if (ARGS.wrap != null) { + TOPLEVEL = TOPLEVEL.wrap_commonjs(ARGS.wrap, ARGS.export_all); + } + + if (ARGS.enclose != null) { + var arg_parameter_list = ARGS.enclose; + if (arg_parameter_list === true) { + arg_parameter_list = []; + } + else if (!(arg_parameter_list instanceof Array)) { + arg_parameter_list = [arg_parameter_list]; + } + TOPLEVEL = TOPLEVEL.wrap_enclose(arg_parameter_list); + } + + if (ARGS.mangle_props || ARGS.name_cache) (function(){ + var reserved = RESERVED ? RESERVED.props : null; + var cache = readNameCache("props"); + var regex; + + try { + regex = ARGS.mangle_regex ? extractRegex(ARGS.mangle_regex) : null; + } catch (e) { + print_error("ERROR: Invalid --mangle-regex: " + e.message); + process.exit(1); + } + + TOPLEVEL = UglifyJS.mangle_properties(TOPLEVEL, { + reserved : reserved, + cache : cache, + only_cache : !ARGS.mangle_props, + regex : regex, + ignore_quoted : ARGS.mangle_props == 2, + debug : typeof ARGS.mangle_props_debug === "undefined" ? false : ARGS.mangle_props_debug + }); + writeNameCache("props", cache); + })(); + + var SCOPE_IS_NEEDED = COMPRESS || MANGLE || ARGS.lint + var TL_CACHE = readNameCache("vars"); + + if (SCOPE_IS_NEEDED) { + time_it("scope", function(){ + TOPLEVEL.figure_out_scope({ screw_ie8: screw_ie8, cache: TL_CACHE }); + if (ARGS.lint) { + TOPLEVEL.scope_warnings(); + } + }); + } + + if (COMPRESS) { + time_it("squeeze", function(){ + TOPLEVEL = compressor.compress(TOPLEVEL); + }); + } + + if (SCOPE_IS_NEEDED) { + time_it("scope", function(){ + TOPLEVEL.figure_out_scope({ screw_ie8: screw_ie8, cache: TL_CACHE }); + if (MANGLE && !TL_CACHE) { + TOPLEVEL.compute_char_frequency(MANGLE); + } + }); + } + + if (MANGLE) time_it("mangle", function(){ + MANGLE.cache = TL_CACHE; + TOPLEVEL.mangle_names(MANGLE); + }); + + writeNameCache("vars", TL_CACHE); + + if (ARGS.source_map_include_sources) { + for (var file in SOURCES_CONTENT) { + if (SOURCES_CONTENT.hasOwnProperty(file)) { + SOURCE_MAP.get().setSourceContent(file, SOURCES_CONTENT[file]); + } + } + } + + if (ARGS.dump_spidermonkey_ast) { + print(JSON.stringify(TOPLEVEL.to_mozilla_ast(), null, 2)); + } else { + time_it("generate", function(){ + TOPLEVEL.print(output); + }); + + output = output.get(); + + if (SOURCE_MAP) { + if (ARGS.source_map_inline) { + var base64_string = new Buffer(SOURCE_MAP.toString()).toString('base64'); + output += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + base64_string; + } else { + fs.writeFileSync(ARGS.source_map, SOURCE_MAP, "utf8"); + var source_map_url = ARGS.source_map_url || ( + P_RELATIVE + ? path.relative(path.dirname(OUTPUT_FILE), ARGS.source_map) + : ARGS.source_map + ); + output += "\n//# sourceMappingURL=" + source_map_url; + } + } + + if (OUTPUT_FILE) { + fs.writeFileSync(OUTPUT_FILE, output, "utf8"); + } else { + print(output); + } + } + + if (ARGS.stats) { + print_error(UglifyJS.string_template("Timing information (compressed {count} files):", { + count: files.length + })); + for (var i in STATS) if (STATS.hasOwnProperty(i)) { + print_error(UglifyJS.string_template("- {name}: {time}s", { + name: i, + time: (STATS[i] / 1000).toFixed(3) + })); + } + } +}); + +/* -----[ functions ]----- */ + +function normalize(o) { + for (var i in o) if (o.hasOwnProperty(i) && /-/.test(i)) { + o[i.replace(/-/g, "_")] = o[i]; + delete o[i]; + } +} + +function getOptions(flag, constants) { + var x = ARGS[flag]; + if (x == null || x === false) return null; + var ret = {}; + if (x !== "") { + if (Array.isArray(x)) x = x.map(function (v) { return "(" + v + ")"; }).join(", "); + + var ast; + try { + ast = UglifyJS.parse(x, { expression: true }); + } catch(ex) { + if (ex instanceof UglifyJS.JS_Parse_Error) { + print_error("Error parsing arguments for flag `" + flag + "': " + x); + process.exit(1); + } + } + ast.walk(new UglifyJS.TreeWalker(function(node){ + if (node instanceof UglifyJS.AST_Seq) return; // descend + if (node instanceof UglifyJS.AST_Assign) { + var name = node.left.print_to_string({ beautify: false }).replace(/-/g, "_"); + var value = node.right; + if (constants) + value = new Function("return (" + value.print_to_string() + ")")(); + ret[name] = value; + return true; // no descend + } + if (node instanceof UglifyJS.AST_Symbol || node instanceof UglifyJS.AST_Binary) { + var name = node.print_to_string({ beautify: false }).replace(/-/g, "_"); + ret[name] = true; + return true; // no descend + } + print_error(node.TYPE) + print_error("Error parsing arguments for flag `" + flag + "': " + x); + process.exit(1); + })); + } + return ret; +} + +function read_whole_file(filename, cb) { + if (filename == "-") { + var chunks = []; + process.stdin.setEncoding('utf-8'); + process.stdin.on('data', function (chunk) { + chunks.push(chunk); + }).on('end', function () { + cb(null, chunks.join("")); + }); + process.openStdin(); + } else { + fs.readFile(filename, "utf-8", cb); + } +} + +function time_it(name, cont) { + var t1 = new Date().getTime(); + var ret = cont(); + if (ARGS.stats) { + var spent = new Date().getTime() - t1; + if (STATS[name]) STATS[name] += spent; + else STATS[name] = spent; + } + return ret; +} + +function print_error(msg) { + console.error("%s", msg); +} + +function print(txt) { + console.log("%s", txt); +} diff --git a/node_modules/uglify-js/lib/ast.js b/node_modules/uglify-js/lib/ast.js new file mode 100644 index 0000000..42506cb --- /dev/null +++ b/node_modules/uglify-js/lib/ast.js @@ -0,0 +1,1021 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +function DEFNODE(type, props, methods, base) { + if (arguments.length < 4) base = AST_Node; + if (!props) props = []; + else props = props.split(/\s+/); + var self_props = props; + if (base && base.PROPS) + props = props.concat(base.PROPS); + var code = "return function AST_" + type + "(props){ if (props) { "; + for (var i = props.length; --i >= 0;) { + code += "this." + props[i] + " = props." + props[i] + ";"; + } + var proto = base && new base; + if (proto && proto.initialize || (methods && methods.initialize)) + code += "this.initialize();"; + code += "}}"; + var ctor = new Function(code)(); + if (proto) { + ctor.prototype = proto; + ctor.BASE = base; + } + if (base) base.SUBCLASSES.push(ctor); + ctor.prototype.CTOR = ctor; + ctor.PROPS = props || null; + ctor.SELF_PROPS = self_props; + ctor.SUBCLASSES = []; + if (type) { + ctor.prototype.TYPE = ctor.TYPE = type; + } + if (methods) for (i in methods) if (HOP(methods, i)) { + if (/^\$/.test(i)) { + ctor[i.substr(1)] = methods[i]; + } else { + ctor.prototype[i] = methods[i]; + } + } + ctor.DEFMETHOD = function(name, method) { + this.prototype[name] = method; + }; + exports["AST_" + type] = ctor; + return ctor; +}; + +var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before file raw", { +}, null); + +var AST_Node = DEFNODE("Node", "start end", { + clone: function() { + return new this.CTOR(this); + }, + $documentation: "Base class of all AST nodes", + $propdoc: { + start: "[AST_Token] The first token of this node", + end: "[AST_Token] The last token of this node" + }, + _walk: function(visitor) { + return visitor._visit(this); + }, + walk: function(visitor) { + return this._walk(visitor); // not sure the indirection will be any help + } +}, null); + +AST_Node.warn_function = null; +AST_Node.warn = function(txt, props) { + if (AST_Node.warn_function) + AST_Node.warn_function(string_template(txt, props)); +}; + +/* -----[ statements ]----- */ + +var AST_Statement = DEFNODE("Statement", null, { + $documentation: "Base class of all statements", +}); + +var AST_Debugger = DEFNODE("Debugger", null, { + $documentation: "Represents a debugger statement", +}, AST_Statement); + +var AST_Directive = DEFNODE("Directive", "value scope quote", { + $documentation: "Represents a directive, like \"use strict\";", + $propdoc: { + value: "[string] The value of this directive as a plain string (it's not an AST_String!)", + scope: "[AST_Scope/S] The scope that this directive affects", + quote: "[string] the original quote character" + }, +}, AST_Statement); + +var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", { + $documentation: "A statement consisting of an expression, i.e. a = 1 + 2", + $propdoc: { + body: "[AST_Node] an expression node (should not be instanceof AST_Statement)" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.body._walk(visitor); + }); + } +}, AST_Statement); + +function walk_body(node, visitor) { + if (node.body instanceof AST_Statement) { + node.body._walk(visitor); + } + else node.body.forEach(function(stat){ + stat._walk(visitor); + }); +}; + +var AST_Block = DEFNODE("Block", "body", { + $documentation: "A body of statements (usually bracketed)", + $propdoc: { + body: "[AST_Statement*] an array of statements" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + walk_body(this, visitor); + }); + } +}, AST_Statement); + +var AST_BlockStatement = DEFNODE("BlockStatement", null, { + $documentation: "A block statement", +}, AST_Block); + +var AST_EmptyStatement = DEFNODE("EmptyStatement", null, { + $documentation: "The empty statement (empty block or simply a semicolon)", + _walk: function(visitor) { + return visitor._visit(this); + } +}, AST_Statement); + +var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", { + $documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`", + $propdoc: { + body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.body._walk(visitor); + }); + } +}, AST_Statement); + +var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", { + $documentation: "Statement with a label", + $propdoc: { + label: "[AST_Label] a label definition" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.label._walk(visitor); + this.body._walk(visitor); + }); + } +}, AST_StatementWithBody); + +var AST_IterationStatement = DEFNODE("IterationStatement", null, { + $documentation: "Internal class. All loops inherit from it." +}, AST_StatementWithBody); + +var AST_DWLoop = DEFNODE("DWLoop", "condition", { + $documentation: "Base class for do/while statements", + $propdoc: { + condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement" + } +}, AST_IterationStatement); + +var AST_Do = DEFNODE("Do", null, { + $documentation: "A `do` statement", + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.body._walk(visitor); + this.condition._walk(visitor); + }); + } +}, AST_DWLoop); + +var AST_While = DEFNODE("While", null, { + $documentation: "A `while` statement", + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.condition._walk(visitor); + this.body._walk(visitor); + }); + } +}, AST_DWLoop); + +var AST_For = DEFNODE("For", "init condition step", { + $documentation: "A `for` statement", + $propdoc: { + init: "[AST_Node?] the `for` initialization code, or null if empty", + condition: "[AST_Node?] the `for` termination clause, or null if empty", + step: "[AST_Node?] the `for` update clause, or null if empty" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + if (this.init) this.init._walk(visitor); + if (this.condition) this.condition._walk(visitor); + if (this.step) this.step._walk(visitor); + this.body._walk(visitor); + }); + } +}, AST_IterationStatement); + +var AST_ForIn = DEFNODE("ForIn", "init name object", { + $documentation: "A `for ... in` statement", + $propdoc: { + init: "[AST_Node] the `for/in` initialization code", + name: "[AST_SymbolRef?] the loop variable, only if `init` is AST_Var", + object: "[AST_Node] the object that we're looping through" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.init._walk(visitor); + this.object._walk(visitor); + this.body._walk(visitor); + }); + } +}, AST_IterationStatement); + +var AST_With = DEFNODE("With", "expression", { + $documentation: "A `with` statement", + $propdoc: { + expression: "[AST_Node] the `with` expression" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.expression._walk(visitor); + this.body._walk(visitor); + }); + } +}, AST_StatementWithBody); + +/* -----[ scope and functions ]----- */ + +var AST_Scope = DEFNODE("Scope", "directives variables functions uses_with uses_eval parent_scope enclosed cname", { + $documentation: "Base class for all statements introducing a lexical scope", + $propdoc: { + directives: "[string*/S] an array of directives declared in this scope", + variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope", + functions: "[Object/S] like `variables`, but only lists function declarations", + uses_with: "[boolean/S] tells whether this scope uses the `with` statement", + uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`", + parent_scope: "[AST_Scope?/S] link to the parent scope", + enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes", + cname: "[integer/S] current index for mangling variables (used internally by the mangler)", + }, +}, AST_Block); + +var AST_Toplevel = DEFNODE("Toplevel", "globals", { + $documentation: "The toplevel scope", + $propdoc: { + globals: "[Object/S] a map of name -> SymbolDef for all undeclared names", + }, + wrap_enclose: function(arg_parameter_pairs) { + var self = this; + var args = []; + var parameters = []; + + arg_parameter_pairs.forEach(function(pair) { + var splitAt = pair.lastIndexOf(":"); + + args.push(pair.substr(0, splitAt)); + parameters.push(pair.substr(splitAt + 1)); + }); + + var wrapped_tl = "(function(" + parameters.join(",") + "){ '$ORIG'; })(" + args.join(",") + ")"; + wrapped_tl = parse(wrapped_tl); + wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){ + if (node instanceof AST_Directive && node.value == "$ORIG") { + return MAP.splice(self.body); + } + })); + return wrapped_tl; + }, + wrap_commonjs: function(name, export_all) { + var self = this; + var to_export = []; + if (export_all) { + self.figure_out_scope(); + self.walk(new TreeWalker(function(node){ + if (node instanceof AST_SymbolDeclaration && node.definition().global) { + if (!find_if(function(n){ return n.name == node.name }, to_export)) + to_export.push(node); + } + })); + } + var wrapped_tl = "(function(exports, global){ '$ORIG'; '$EXPORTS'; global['" + name + "'] = exports; }({}, (function(){return this}())))"; + wrapped_tl = parse(wrapped_tl); + wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){ + if (node instanceof AST_Directive) { + switch (node.value) { + case "$ORIG": + return MAP.splice(self.body); + case "$EXPORTS": + var body = []; + to_export.forEach(function(sym){ + body.push(new AST_SimpleStatement({ + body: new AST_Assign({ + left: new AST_Sub({ + expression: new AST_SymbolRef({ name: "exports" }), + property: new AST_String({ value: sym.name }), + }), + operator: "=", + right: new AST_SymbolRef(sym), + }), + })); + }); + return MAP.splice(body); + } + } + })); + return wrapped_tl; + } +}, AST_Scope); + +var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", { + $documentation: "Base class for functions", + $propdoc: { + name: "[AST_SymbolDeclaration?] the name of this function", + argnames: "[AST_SymbolFunarg*] array of function arguments", + uses_arguments: "[boolean/S] tells whether this function accesses the arguments array" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + if (this.name) this.name._walk(visitor); + this.argnames.forEach(function(arg){ + arg._walk(visitor); + }); + walk_body(this, visitor); + }); + } +}, AST_Scope); + +var AST_Accessor = DEFNODE("Accessor", null, { + $documentation: "A setter/getter function. The `name` property is always null." +}, AST_Lambda); + +var AST_Function = DEFNODE("Function", null, { + $documentation: "A function expression" +}, AST_Lambda); + +var AST_Defun = DEFNODE("Defun", null, { + $documentation: "A function definition" +}, AST_Lambda); + +/* -----[ JUMPS ]----- */ + +var AST_Jump = DEFNODE("Jump", null, { + $documentation: "Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)" +}, AST_Statement); + +var AST_Exit = DEFNODE("Exit", "value", { + $documentation: "Base class for “exits” (`return` and `throw`)", + $propdoc: { + value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return" + }, + _walk: function(visitor) { + return visitor._visit(this, this.value && function(){ + this.value._walk(visitor); + }); + } +}, AST_Jump); + +var AST_Return = DEFNODE("Return", null, { + $documentation: "A `return` statement" +}, AST_Exit); + +var AST_Throw = DEFNODE("Throw", null, { + $documentation: "A `throw` statement" +}, AST_Exit); + +var AST_LoopControl = DEFNODE("LoopControl", "label", { + $documentation: "Base class for loop control statements (`break` and `continue`)", + $propdoc: { + label: "[AST_LabelRef?] the label, or null if none", + }, + _walk: function(visitor) { + return visitor._visit(this, this.label && function(){ + this.label._walk(visitor); + }); + } +}, AST_Jump); + +var AST_Break = DEFNODE("Break", null, { + $documentation: "A `break` statement" +}, AST_LoopControl); + +var AST_Continue = DEFNODE("Continue", null, { + $documentation: "A `continue` statement" +}, AST_LoopControl); + +/* -----[ IF ]----- */ + +var AST_If = DEFNODE("If", "condition alternative", { + $documentation: "A `if` statement", + $propdoc: { + condition: "[AST_Node] the `if` condition", + alternative: "[AST_Statement?] the `else` part, or null if not present" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.condition._walk(visitor); + this.body._walk(visitor); + if (this.alternative) this.alternative._walk(visitor); + }); + } +}, AST_StatementWithBody); + +/* -----[ SWITCH ]----- */ + +var AST_Switch = DEFNODE("Switch", "expression", { + $documentation: "A `switch` statement", + $propdoc: { + expression: "[AST_Node] the `switch` “discriminant”" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.expression._walk(visitor); + walk_body(this, visitor); + }); + } +}, AST_Block); + +var AST_SwitchBranch = DEFNODE("SwitchBranch", null, { + $documentation: "Base class for `switch` branches", +}, AST_Block); + +var AST_Default = DEFNODE("Default", null, { + $documentation: "A `default` switch branch", +}, AST_SwitchBranch); + +var AST_Case = DEFNODE("Case", "expression", { + $documentation: "A `case` switch branch", + $propdoc: { + expression: "[AST_Node] the `case` expression" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.expression._walk(visitor); + walk_body(this, visitor); + }); + } +}, AST_SwitchBranch); + +/* -----[ EXCEPTIONS ]----- */ + +var AST_Try = DEFNODE("Try", "bcatch bfinally", { + $documentation: "A `try` statement", + $propdoc: { + bcatch: "[AST_Catch?] the catch block, or null if not present", + bfinally: "[AST_Finally?] the finally block, or null if not present" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + walk_body(this, visitor); + if (this.bcatch) this.bcatch._walk(visitor); + if (this.bfinally) this.bfinally._walk(visitor); + }); + } +}, AST_Block); + +var AST_Catch = DEFNODE("Catch", "argname", { + $documentation: "A `catch` node; only makes sense as part of a `try` statement", + $propdoc: { + argname: "[AST_SymbolCatch] symbol for the exception" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.argname._walk(visitor); + walk_body(this, visitor); + }); + } +}, AST_Block); + +var AST_Finally = DEFNODE("Finally", null, { + $documentation: "A `finally` node; only makes sense as part of a `try` statement" +}, AST_Block); + +/* -----[ VAR/CONST ]----- */ + +var AST_Definitions = DEFNODE("Definitions", "definitions", { + $documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)", + $propdoc: { + definitions: "[AST_VarDef*] array of variable definitions" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.definitions.forEach(function(def){ + def._walk(visitor); + }); + }); + } +}, AST_Statement); + +var AST_Var = DEFNODE("Var", null, { + $documentation: "A `var` statement" +}, AST_Definitions); + +var AST_Const = DEFNODE("Const", null, { + $documentation: "A `const` statement" +}, AST_Definitions); + +var AST_VarDef = DEFNODE("VarDef", "name value", { + $documentation: "A variable declaration; only appears in a AST_Definitions node", + $propdoc: { + name: "[AST_SymbolVar|AST_SymbolConst] name of the variable", + value: "[AST_Node?] initializer, or null of there's no initializer" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.name._walk(visitor); + if (this.value) this.value._walk(visitor); + }); + } +}); + +/* -----[ OTHER ]----- */ + +var AST_Call = DEFNODE("Call", "expression args", { + $documentation: "A function call expression", + $propdoc: { + expression: "[AST_Node] expression to invoke as function", + args: "[AST_Node*] array of arguments" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.expression._walk(visitor); + this.args.forEach(function(arg){ + arg._walk(visitor); + }); + }); + } +}); + +var AST_New = DEFNODE("New", null, { + $documentation: "An object instantiation. Derives from a function call since it has exactly the same properties" +}, AST_Call); + +var AST_Seq = DEFNODE("Seq", "car cdr", { + $documentation: "A sequence expression (two comma-separated expressions)", + $propdoc: { + car: "[AST_Node] first element in sequence", + cdr: "[AST_Node] second element in sequence" + }, + $cons: function(x, y) { + var seq = new AST_Seq(x); + seq.car = x; + seq.cdr = y; + return seq; + }, + $from_array: function(array) { + if (array.length == 0) return null; + if (array.length == 1) return array[0].clone(); + var list = null; + for (var i = array.length; --i >= 0;) { + list = AST_Seq.cons(array[i], list); + } + var p = list; + while (p) { + if (p.cdr && !p.cdr.cdr) { + p.cdr = p.cdr.car; + break; + } + p = p.cdr; + } + return list; + }, + to_array: function() { + var p = this, a = []; + while (p) { + a.push(p.car); + if (p.cdr && !(p.cdr instanceof AST_Seq)) { + a.push(p.cdr); + break; + } + p = p.cdr; + } + return a; + }, + add: function(node) { + var p = this; + while (p) { + if (!(p.cdr instanceof AST_Seq)) { + var cell = AST_Seq.cons(p.cdr, node); + return p.cdr = cell; + } + p = p.cdr; + } + }, + len: function() { + if (this.cdr instanceof AST_Seq) { + return this.cdr.len() + 1; + } else { + return 2; + } + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.car._walk(visitor); + if (this.cdr) this.cdr._walk(visitor); + }); + } +}); + +var AST_PropAccess = DEFNODE("PropAccess", "expression property", { + $documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`", + $propdoc: { + expression: "[AST_Node] the “container” expression", + property: "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node" + } +}); + +var AST_Dot = DEFNODE("Dot", null, { + $documentation: "A dotted property access expression", + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.expression._walk(visitor); + }); + } +}, AST_PropAccess); + +var AST_Sub = DEFNODE("Sub", null, { + $documentation: "Index-style property access, i.e. `a[\"foo\"]`", + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.expression._walk(visitor); + this.property._walk(visitor); + }); + } +}, AST_PropAccess); + +var AST_Unary = DEFNODE("Unary", "operator expression", { + $documentation: "Base class for unary expressions", + $propdoc: { + operator: "[string] the operator", + expression: "[AST_Node] expression that this unary operator applies to" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.expression._walk(visitor); + }); + } +}); + +var AST_UnaryPrefix = DEFNODE("UnaryPrefix", null, { + $documentation: "Unary prefix expression, i.e. `typeof i` or `++i`" +}, AST_Unary); + +var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, { + $documentation: "Unary postfix expression, i.e. `i++`" +}, AST_Unary); + +var AST_Binary = DEFNODE("Binary", "left operator right", { + $documentation: "Binary expression, i.e. `a + b`", + $propdoc: { + left: "[AST_Node] left-hand side expression", + operator: "[string] the operator", + right: "[AST_Node] right-hand side expression" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.left._walk(visitor); + this.right._walk(visitor); + }); + } +}); + +var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative", { + $documentation: "Conditional expression using the ternary operator, i.e. `a ? b : c`", + $propdoc: { + condition: "[AST_Node]", + consequent: "[AST_Node]", + alternative: "[AST_Node]" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.condition._walk(visitor); + this.consequent._walk(visitor); + this.alternative._walk(visitor); + }); + } +}); + +var AST_Assign = DEFNODE("Assign", null, { + $documentation: "An assignment expression — `a = b + 5`", +}, AST_Binary); + +/* -----[ LITERALS ]----- */ + +var AST_Array = DEFNODE("Array", "elements", { + $documentation: "An array literal", + $propdoc: { + elements: "[AST_Node*] array of elements" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.elements.forEach(function(el){ + el._walk(visitor); + }); + }); + } +}); + +var AST_Object = DEFNODE("Object", "properties", { + $documentation: "An object literal", + $propdoc: { + properties: "[AST_ObjectProperty*] array of properties" + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.properties.forEach(function(prop){ + prop._walk(visitor); + }); + }); + } +}); + +var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", { + $documentation: "Base class for literal object properties", + $propdoc: { + key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an arbitrary AST_Node.", + value: "[AST_Node] property value. For setters and getters this is an AST_Function." + }, + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.value._walk(visitor); + }); + } +}); + +var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", "quote", { + $documentation: "A key: value object property", + $propdoc: { + quote: "[string] the original quote character" + } +}, AST_ObjectProperty); + +var AST_ObjectSetter = DEFNODE("ObjectSetter", null, { + $documentation: "An object setter property", +}, AST_ObjectProperty); + +var AST_ObjectGetter = DEFNODE("ObjectGetter", null, { + $documentation: "An object getter property", +}, AST_ObjectProperty); + +var AST_Symbol = DEFNODE("Symbol", "scope name thedef", { + $propdoc: { + name: "[string] name of this symbol", + scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)", + thedef: "[SymbolDef/S] the definition of this symbol" + }, + $documentation: "Base class for all symbols", +}); + +var AST_SymbolAccessor = DEFNODE("SymbolAccessor", null, { + $documentation: "The name of a property accessor (setter/getter function)" +}, AST_Symbol); + +var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", { + $documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)", + $propdoc: { + init: "[AST_Node*/S] array of initializers for this declaration." + } +}, AST_Symbol); + +var AST_SymbolVar = DEFNODE("SymbolVar", null, { + $documentation: "Symbol defining a variable", +}, AST_SymbolDeclaration); + +var AST_SymbolConst = DEFNODE("SymbolConst", null, { + $documentation: "A constant declaration" +}, AST_SymbolDeclaration); + +var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, { + $documentation: "Symbol naming a function argument", +}, AST_SymbolVar); + +var AST_SymbolDefun = DEFNODE("SymbolDefun", null, { + $documentation: "Symbol defining a function", +}, AST_SymbolDeclaration); + +var AST_SymbolLambda = DEFNODE("SymbolLambda", null, { + $documentation: "Symbol naming a function expression", +}, AST_SymbolDeclaration); + +var AST_SymbolCatch = DEFNODE("SymbolCatch", null, { + $documentation: "Symbol naming the exception in catch", +}, AST_SymbolDeclaration); + +var AST_Label = DEFNODE("Label", "references", { + $documentation: "Symbol naming a label (declaration)", + $propdoc: { + references: "[AST_LoopControl*] a list of nodes referring to this label" + }, + initialize: function() { + this.references = []; + this.thedef = this; + } +}, AST_Symbol); + +var AST_SymbolRef = DEFNODE("SymbolRef", null, { + $documentation: "Reference to some symbol (not definition/declaration)", +}, AST_Symbol); + +var AST_LabelRef = DEFNODE("LabelRef", null, { + $documentation: "Reference to a label symbol", +}, AST_Symbol); + +var AST_This = DEFNODE("This", null, { + $documentation: "The `this` symbol", +}, AST_Symbol); + +var AST_Constant = DEFNODE("Constant", null, { + $documentation: "Base class for all constants", + getValue: function() { + return this.value; + } +}); + +var AST_String = DEFNODE("String", "value quote", { + $documentation: "A string literal", + $propdoc: { + value: "[string] the contents of this string", + quote: "[string] the original quote character" + } +}, AST_Constant); + +var AST_Number = DEFNODE("Number", "value literal", { + $documentation: "A number literal", + $propdoc: { + value: "[number] the numeric value", + literal: "[string] numeric value as string (optional)" + } +}, AST_Constant); + +var AST_RegExp = DEFNODE("RegExp", "value", { + $documentation: "A regexp literal", + $propdoc: { + value: "[RegExp] the actual regexp" + } +}, AST_Constant); + +var AST_Atom = DEFNODE("Atom", null, { + $documentation: "Base class for atoms", +}, AST_Constant); + +var AST_Null = DEFNODE("Null", null, { + $documentation: "The `null` atom", + value: null +}, AST_Atom); + +var AST_NaN = DEFNODE("NaN", null, { + $documentation: "The impossible value", + value: 0/0 +}, AST_Atom); + +var AST_Undefined = DEFNODE("Undefined", null, { + $documentation: "The `undefined` value", + value: (function(){}()) +}, AST_Atom); + +var AST_Hole = DEFNODE("Hole", null, { + $documentation: "A hole in an array", + value: (function(){}()) +}, AST_Atom); + +var AST_Infinity = DEFNODE("Infinity", null, { + $documentation: "The `Infinity` value", + value: 1/0 +}, AST_Atom); + +var AST_Boolean = DEFNODE("Boolean", null, { + $documentation: "Base class for booleans", +}, AST_Atom); + +var AST_False = DEFNODE("False", null, { + $documentation: "The `false` atom", + value: false +}, AST_Boolean); + +var AST_True = DEFNODE("True", null, { + $documentation: "The `true` atom", + value: true +}, AST_Boolean); + +/* -----[ TreeWalker ]----- */ + +function TreeWalker(callback) { + this.visit = callback; + this.stack = []; + this.directives = Object.create(null); +}; +TreeWalker.prototype = { + _visit: function(node, descend) { + this.push(node); + var ret = this.visit(node, descend ? function(){ + descend.call(node); + } : noop); + if (!ret && descend) { + descend.call(node); + } + this.pop(node); + return ret; + }, + parent: function(n) { + return this.stack[this.stack.length - 2 - (n || 0)]; + }, + push: function (node) { + if (node instanceof AST_Lambda) { + this.directives = Object.create(this.directives); + } else if (node instanceof AST_Directive) { + this.directives[node.value] = this.directives[node.value] ? "up" : true; + } + this.stack.push(node); + }, + pop: function(node) { + this.stack.pop(); + if (node instanceof AST_Lambda) { + this.directives = Object.getPrototypeOf(this.directives); + } + }, + self: function() { + return this.stack[this.stack.length - 1]; + }, + find_parent: function(type) { + var stack = this.stack; + for (var i = stack.length; --i >= 0;) { + var x = stack[i]; + if (x instanceof type) return x; + } + }, + has_directive: function(type) { + var dir = this.directives[type]; + if (dir) return dir; + var node = this.stack[this.stack.length - 1]; + if (node instanceof AST_Scope) { + for (var i = 0; i < node.body.length; ++i) { + var st = node.body[i]; + if (!(st instanceof AST_Directive)) break; + if (st.value == type) return true; + } + } + }, + in_boolean_context: function() { + var stack = this.stack; + var i = stack.length, self = stack[--i]; + while (i > 0) { + var p = stack[--i]; + if ((p instanceof AST_If && p.condition === self) || + (p instanceof AST_Conditional && p.condition === self) || + (p instanceof AST_DWLoop && p.condition === self) || + (p instanceof AST_For && p.condition === self) || + (p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self)) + { + return true; + } + if (!(p instanceof AST_Binary && (p.operator == "&&" || p.operator == "||"))) + return false; + self = p; + } + }, + loopcontrol_target: function(label) { + var stack = this.stack; + if (label) for (var i = stack.length; --i >= 0;) { + var x = stack[i]; + if (x instanceof AST_LabeledStatement && x.label.name == label.name) { + return x.body; + } + } else for (var i = stack.length; --i >= 0;) { + var x = stack[i]; + if (x instanceof AST_Switch || x instanceof AST_IterationStatement) + return x; + } + } +}; diff --git a/node_modules/uglify-js/lib/compress.js b/node_modules/uglify-js/lib/compress.js new file mode 100644 index 0000000..5879b93 --- /dev/null +++ b/node_modules/uglify-js/lib/compress.js @@ -0,0 +1,2929 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +function Compressor(options, false_by_default) { + if (!(this instanceof Compressor)) + return new Compressor(options, false_by_default); + TreeTransformer.call(this, this.before, this.after); + this.options = defaults(options, { + sequences : !false_by_default, + properties : !false_by_default, + dead_code : !false_by_default, + drop_debugger : !false_by_default, + unsafe : false, + unsafe_comps : false, + conditionals : !false_by_default, + comparisons : !false_by_default, + evaluate : !false_by_default, + booleans : !false_by_default, + loops : !false_by_default, + unused : !false_by_default, + hoist_funs : !false_by_default, + keep_fargs : true, + keep_fnames : false, + hoist_vars : false, + if_return : !false_by_default, + join_vars : !false_by_default, + collapse_vars : false, + reduce_vars : false, + cascade : !false_by_default, + side_effects : !false_by_default, + pure_getters : false, + pure_funcs : null, + negate_iife : !false_by_default, + screw_ie8 : true, + drop_console : false, + angular : false, + warnings : true, + global_defs : {}, + passes : 1, + }, true); + var sequences = this.options["sequences"]; + this.sequences_limit = sequences == 1 ? 200 : sequences | 0; + this.warnings_produced = {}; +}; + +Compressor.prototype = new TreeTransformer; +merge(Compressor.prototype, { + option: function(key) { return this.options[key] }, + compress: function(node) { + var passes = +this.options.passes || 1; + for (var pass = 0; pass < passes && pass < 3; ++pass) { + if (pass > 0) node.clear_opt_flags(); + node = node.transform(this); + } + return node; + }, + warn: function(text, props) { + if (this.options.warnings) { + // only emit unique warnings + var message = string_template(text, props); + if (!(message in this.warnings_produced)) { + this.warnings_produced[message] = true; + AST_Node.warn.apply(AST_Node, arguments); + } + } + }, + clear_warnings: function() { + this.warnings_produced = {}; + }, + before: function(node, descend, in_list) { + if (node._squeezed) return node; + var was_scope = false; + if (node instanceof AST_Scope) { + node = node.hoist_declarations(this); + was_scope = true; + } + descend(node, this); + node = node.optimize(this); + if (was_scope && node instanceof AST_Scope) { + node.drop_unused(this); + descend(node, this); + } + node._squeezed = true; + return node; + } +}); + +(function(){ + + function OPT(node, optimizer) { + node.DEFMETHOD("optimize", function(compressor){ + var self = this; + if (self._optimized) return self; + if (compressor.has_directive("use asm")) return self; + var opt = optimizer(self, compressor); + opt._optimized = true; + if (opt === self) return opt; + return opt.transform(compressor); + }); + }; + + OPT(AST_Node, function(self, compressor){ + return self; + }); + + AST_Node.DEFMETHOD("equivalent_to", function(node){ + // XXX: this is a rather expensive way to test two node's equivalence: + return this.print_to_string() == node.print_to_string(); + }); + + AST_Node.DEFMETHOD("clear_opt_flags", function(){ + this.walk(new TreeWalker(function(node){ + if (!(node instanceof AST_Directive || node instanceof AST_Constant)) { + node._squeezed = false; + node._optimized = false; + } + })); + }); + + function make_node(ctor, orig, props) { + if (!props) props = {}; + if (orig) { + if (!props.start) props.start = orig.start; + if (!props.end) props.end = orig.end; + } + return new ctor(props); + }; + + function make_node_from_constant(compressor, val, orig) { + // XXX: WIP. + // if (val instanceof AST_Node) return val.transform(new TreeTransformer(null, function(node){ + // if (node instanceof AST_SymbolRef) { + // var scope = compressor.find_parent(AST_Scope); + // var def = scope.find_variable(node); + // node.thedef = def; + // return node; + // } + // })).transform(compressor); + + if (val instanceof AST_Node) return val.transform(compressor); + switch (typeof val) { + case "string": + return make_node(AST_String, orig, { + value: val + }).optimize(compressor); + case "number": + if (isNaN(val)) { + return make_node(AST_NaN, orig); + } + + if ((1 / val) < 0) { + return make_node(AST_UnaryPrefix, orig, { + operator: "-", + expression: make_node(AST_Number, orig, { value: -val }) + }); + } + + return make_node(AST_Number, orig, { value: val }).optimize(compressor); + case "boolean": + return make_node(val ? AST_True : AST_False, orig).optimize(compressor); + case "undefined": + return make_node(AST_Undefined, orig).optimize(compressor); + default: + if (val === null) { + return make_node(AST_Null, orig, { value: null }).optimize(compressor); + } + if (val instanceof RegExp) { + return make_node(AST_RegExp, orig, { value: val }).optimize(compressor); + } + throw new Error(string_template("Can't handle constant of type: {type}", { + type: typeof val + })); + } + }; + + // we shouldn't compress (1,func)(something) to + // func(something) because that changes the meaning of + // the func (becomes lexical instead of global). + function maintain_this_binding(parent, orig, val) { + if (parent instanceof AST_Call && parent.expression === orig) { + if (val instanceof AST_PropAccess || val instanceof AST_SymbolRef && val.name === "eval") { + return make_node(AST_Seq, orig, { + car: make_node(AST_Number, orig, { + value: 0 + }), + cdr: val + }); + } + } + return val; + } + + function as_statement_array(thing) { + if (thing === null) return []; + if (thing instanceof AST_BlockStatement) return thing.body; + if (thing instanceof AST_EmptyStatement) return []; + if (thing instanceof AST_Statement) return [ thing ]; + throw new Error("Can't convert thing to statement array"); + }; + + function is_empty(thing) { + if (thing === null) return true; + if (thing instanceof AST_EmptyStatement) return true; + if (thing instanceof AST_BlockStatement) return thing.body.length == 0; + return false; + }; + + function loop_body(x) { + if (x instanceof AST_Switch) return x; + if (x instanceof AST_For || x instanceof AST_ForIn || x instanceof AST_DWLoop) { + return (x.body instanceof AST_BlockStatement ? x.body : x); + } + return x; + }; + + function tighten_body(statements, compressor) { + var CHANGED, max_iter = 10; + do { + CHANGED = false; + if (compressor.option("angular")) { + statements = process_for_angular(statements); + } + statements = eliminate_spurious_blocks(statements); + if (compressor.option("dead_code")) { + statements = eliminate_dead_code(statements, compressor); + } + if (compressor.option("if_return")) { + statements = handle_if_return(statements, compressor); + } + if (compressor.sequences_limit > 0) { + statements = sequencesize(statements, compressor); + } + if (compressor.option("join_vars")) { + statements = join_consecutive_vars(statements, compressor); + } + if (compressor.option("collapse_vars")) { + statements = collapse_single_use_vars(statements, compressor); + } + } while (CHANGED && max_iter-- > 0); + + if (compressor.option("negate_iife")) { + negate_iifes(statements, compressor); + } + + return statements; + + function collapse_single_use_vars(statements, compressor) { + // Iterate statements backwards looking for a statement with a var/const + // declaration immediately preceding it. Grab the rightmost var definition + // and if it has exactly one reference then attempt to replace its reference + // in the statement with the var value and then erase the var definition. + + var self = compressor.self(); + var var_defs_removed = false; + for (var stat_index = statements.length; --stat_index >= 0;) { + var stat = statements[stat_index]; + if (stat instanceof AST_Definitions) continue; + + // Process child blocks of statement if present. + [stat, stat.body, stat.alternative, stat.bcatch, stat.bfinally].forEach(function(node) { + node && node.body && collapse_single_use_vars(node.body, compressor); + }); + + // The variable definition must precede a statement. + if (stat_index <= 0) break; + var prev_stat_index = stat_index - 1; + var prev_stat = statements[prev_stat_index]; + if (!(prev_stat instanceof AST_Definitions)) continue; + var var_defs = prev_stat.definitions; + if (var_defs == null) continue; + + var var_names_seen = {}; + var side_effects_encountered = false; + var lvalues_encountered = false; + var lvalues = {}; + + // Scan variable definitions from right to left. + for (var var_defs_index = var_defs.length; --var_defs_index >= 0;) { + + // Obtain var declaration and var name with basic sanity check. + var var_decl = var_defs[var_defs_index]; + if (var_decl.value == null) break; + var var_name = var_decl.name.name; + if (!var_name || !var_name.length) break; + + // Bail if we've seen a var definition of same name before. + if (var_name in var_names_seen) break; + var_names_seen[var_name] = true; + + // Only interested in cases with just one reference to the variable. + var def = self.find_variable && self.find_variable(var_name); + if (!def || !def.references || def.references.length !== 1 || var_name == "arguments") { + side_effects_encountered = true; + continue; + } + var ref = def.references[0]; + + // Don't replace ref if eval() or with statement in scope. + if (ref.scope.uses_eval || ref.scope.uses_with) break; + + // Constant single use vars can be replaced in any scope. + if (!(var_decl.value instanceof AST_RegExp) && var_decl.value.is_constant(compressor)) { + var ctt = new TreeTransformer(function(node) { + if (node === ref) + return replace_var(node, ctt.parent(), true); + }); + stat.transform(ctt); + continue; + } + + // Restrict var replacement to constants if side effects encountered. + if (side_effects_encountered |= lvalues_encountered) continue; + + // Non-constant single use vars can only be replaced in same scope. + if (ref.scope !== self) { + side_effects_encountered |= var_decl.value.has_side_effects(compressor); + continue; + } + + // Detect lvalues in var value. + var tw = new TreeWalker(function(node){ + if (node instanceof AST_SymbolRef && is_lvalue(node, tw.parent())) { + lvalues[node.name] = lvalues_encountered = true; + } + }); + var_decl.value.walk(tw); + + // Replace the non-constant single use var in statement if side effect free. + var unwind = false; + var tt = new TreeTransformer( + function preorder(node) { + if (unwind) return node; + var parent = tt.parent(); + if (node instanceof AST_Lambda + || node instanceof AST_Try + || node instanceof AST_With + || node instanceof AST_Case + || node instanceof AST_IterationStatement + || (parent instanceof AST_If && node !== parent.condition) + || (parent instanceof AST_Conditional && node !== parent.condition) + || (parent instanceof AST_Binary + && (parent.operator == "&&" || parent.operator == "||") + && node === parent.right) + || (parent instanceof AST_Switch && node !== parent.expression)) { + return side_effects_encountered = unwind = true, node; + } + }, + function postorder(node) { + if (unwind) return node; + if (node === ref) + return unwind = true, replace_var(node, tt.parent(), false); + if (side_effects_encountered |= node.has_side_effects(compressor)) + return unwind = true, node; + if (lvalues_encountered && node instanceof AST_SymbolRef && node.name in lvalues) { + side_effects_encountered = true; + return unwind = true, node; + } + } + ); + stat.transform(tt); + } + } + + // Remove extraneous empty statments in block after removing var definitions. + // Leave at least one statement in `statements`. + if (var_defs_removed) for (var i = statements.length; --i >= 0;) { + if (statements.length > 1 && statements[i] instanceof AST_EmptyStatement) + statements.splice(i, 1); + } + + return statements; + + function is_lvalue(node, parent) { + return node instanceof AST_SymbolRef && ( + (parent instanceof AST_Assign && node === parent.left) + || (parent instanceof AST_Unary && parent.expression === node + && (parent.operator == "++" || parent.operator == "--"))); + } + function replace_var(node, parent, is_constant) { + if (is_lvalue(node, parent)) return node; + + // Remove var definition and return its value to the TreeTransformer to replace. + var value = maintain_this_binding(parent, node, var_decl.value); + var_decl.value = null; + + var_defs.splice(var_defs_index, 1); + if (var_defs.length === 0) { + statements[prev_stat_index] = make_node(AST_EmptyStatement, self); + var_defs_removed = true; + } + // Further optimize statement after substitution. + stat.clear_opt_flags(); + + compressor.warn("Replacing " + (is_constant ? "constant" : "variable") + + " " + var_name + " [{file}:{line},{col}]", node.start); + CHANGED = true; + return value; + } + } + + function process_for_angular(statements) { + function has_inject(comment) { + return /@ngInject/.test(comment.value); + } + function make_arguments_names_list(func) { + return func.argnames.map(function(sym){ + return make_node(AST_String, sym, { value: sym.name }); + }); + } + function make_array(orig, elements) { + return make_node(AST_Array, orig, { elements: elements }); + } + function make_injector(func, name) { + return make_node(AST_SimpleStatement, func, { + body: make_node(AST_Assign, func, { + operator: "=", + left: make_node(AST_Dot, name, { + expression: make_node(AST_SymbolRef, name, name), + property: "$inject" + }), + right: make_array(func, make_arguments_names_list(func)) + }) + }); + } + function check_expression(body) { + if (body && body.args) { + // if this is a function call check all of arguments passed + body.args.forEach(function(argument, index, array) { + var comments = argument.start.comments_before; + // if the argument is function preceded by @ngInject + if (argument instanceof AST_Lambda && comments.length && has_inject(comments[0])) { + // replace the function with an array of names of its parameters and function at the end + array[index] = make_array(argument, make_arguments_names_list(argument).concat(argument)); + } + }); + // if this is chained call check previous one recursively + if (body.expression && body.expression.expression) { + check_expression(body.expression.expression); + } + } + } + return statements.reduce(function(a, stat){ + a.push(stat); + + if (stat.body && stat.body.args) { + check_expression(stat.body); + } else { + var token = stat.start; + var comments = token.comments_before; + if (comments && comments.length > 0) { + var last = comments.pop(); + if (has_inject(last)) { + // case 1: defun + if (stat instanceof AST_Defun) { + a.push(make_injector(stat, stat.name)); + } + else if (stat instanceof AST_Definitions) { + stat.definitions.forEach(function(def) { + if (def.value && def.value instanceof AST_Lambda) { + a.push(make_injector(def.value, def.name)); + } + }); + } + else { + compressor.warn("Unknown statement marked with @ngInject [{file}:{line},{col}]", token); + } + } + } + } + + return a; + }, []); + } + + function eliminate_spurious_blocks(statements) { + var seen_dirs = []; + return statements.reduce(function(a, stat){ + if (stat instanceof AST_BlockStatement) { + CHANGED = true; + a.push.apply(a, eliminate_spurious_blocks(stat.body)); + } else if (stat instanceof AST_EmptyStatement) { + CHANGED = true; + } else if (stat instanceof AST_Directive) { + if (seen_dirs.indexOf(stat.value) < 0) { + a.push(stat); + seen_dirs.push(stat.value); + } else { + CHANGED = true; + } + } else { + a.push(stat); + } + return a; + }, []); + }; + + function handle_if_return(statements, compressor) { + var self = compressor.self(); + var multiple_if_returns = has_multiple_if_returns(statements); + var in_lambda = self instanceof AST_Lambda; + var ret = []; + loop: for (var i = statements.length; --i >= 0;) { + var stat = statements[i]; + switch (true) { + case (in_lambda && stat instanceof AST_Return && !stat.value && ret.length == 0): + CHANGED = true; + // note, ret.length is probably always zero + // because we drop unreachable code before this + // step. nevertheless, it's good to check. + continue loop; + case stat instanceof AST_If: + if (stat.body instanceof AST_Return) { + //--- + // pretty silly case, but: + // if (foo()) return; return; ==> foo(); return; + if (((in_lambda && ret.length == 0) + || (ret[0] instanceof AST_Return && !ret[0].value)) + && !stat.body.value && !stat.alternative) { + CHANGED = true; + var cond = make_node(AST_SimpleStatement, stat.condition, { + body: stat.condition + }); + ret.unshift(cond); + continue loop; + } + //--- + // if (foo()) return x; return y; ==> return foo() ? x : y; + if (ret[0] instanceof AST_Return && stat.body.value && ret[0].value && !stat.alternative) { + CHANGED = true; + stat = stat.clone(); + stat.alternative = ret[0]; + ret[0] = stat.transform(compressor); + continue loop; + } + //--- + // if (foo()) return x; [ return ; ] ==> return foo() ? x : undefined; + if (multiple_if_returns && (ret.length == 0 || ret[0] instanceof AST_Return) + && stat.body.value && !stat.alternative && in_lambda) { + CHANGED = true; + stat = stat.clone(); + stat.alternative = ret[0] || make_node(AST_Return, stat, { + value: make_node(AST_Undefined, stat) + }); + ret[0] = stat.transform(compressor); + continue loop; + } + //--- + // if (foo()) return; [ else x... ]; y... ==> if (!foo()) { x...; y... } + if (!stat.body.value && in_lambda) { + CHANGED = true; + stat = stat.clone(); + stat.condition = stat.condition.negate(compressor); + var body = as_statement_array(stat.alternative).concat(ret); + var funs = extract_functions_from_statement_array(body); + stat.body = make_node(AST_BlockStatement, stat, { + body: body + }); + stat.alternative = null; + ret = funs.concat([ stat.transform(compressor) ]); + continue loop; + } + //--- + // XXX: what was the intention of this case? + // if sequences is not enabled, this can lead to an endless loop (issue #866). + // however, with sequences on this helps producing slightly better output for + // the example code. + if (compressor.option("sequences") + && ret.length == 1 && in_lambda && ret[0] instanceof AST_SimpleStatement + && (!stat.alternative || stat.alternative instanceof AST_SimpleStatement)) { + CHANGED = true; + ret.push(make_node(AST_Return, ret[0], { + value: make_node(AST_Undefined, ret[0]) + }).transform(compressor)); + ret = as_statement_array(stat.alternative).concat(ret); + ret.unshift(stat); + continue loop; + } + } + + var ab = aborts(stat.body); + var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab.label) : null; + if (ab && ((ab instanceof AST_Return && !ab.value && in_lambda) + || (ab instanceof AST_Continue && self === loop_body(lct)) + || (ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct))) { + if (ab.label) { + remove(ab.label.thedef.references, ab); + } + CHANGED = true; + var body = as_statement_array(stat.body).slice(0, -1); + stat = stat.clone(); + stat.condition = stat.condition.negate(compressor); + stat.body = make_node(AST_BlockStatement, stat, { + body: as_statement_array(stat.alternative).concat(ret) + }); + stat.alternative = make_node(AST_BlockStatement, stat, { + body: body + }); + ret = [ stat.transform(compressor) ]; + continue loop; + } + + var ab = aborts(stat.alternative); + var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab.label) : null; + if (ab && ((ab instanceof AST_Return && !ab.value && in_lambda) + || (ab instanceof AST_Continue && self === loop_body(lct)) + || (ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct))) { + if (ab.label) { + remove(ab.label.thedef.references, ab); + } + CHANGED = true; + stat = stat.clone(); + stat.body = make_node(AST_BlockStatement, stat.body, { + body: as_statement_array(stat.body).concat(ret) + }); + stat.alternative = make_node(AST_BlockStatement, stat.alternative, { + body: as_statement_array(stat.alternative).slice(0, -1) + }); + ret = [ stat.transform(compressor) ]; + continue loop; + } + + ret.unshift(stat); + break; + default: + ret.unshift(stat); + break; + } + } + return ret; + + function has_multiple_if_returns(statements) { + var n = 0; + for (var i = statements.length; --i >= 0;) { + var stat = statements[i]; + if (stat instanceof AST_If && stat.body instanceof AST_Return) { + if (++n > 1) return true; + } + } + return false; + } + }; + + function eliminate_dead_code(statements, compressor) { + var has_quit = false; + var orig = statements.length; + var self = compressor.self(); + statements = statements.reduce(function(a, stat){ + if (has_quit) { + extract_declarations_from_unreachable_code(compressor, stat, a); + } else { + if (stat instanceof AST_LoopControl) { + var lct = compressor.loopcontrol_target(stat.label); + if ((stat instanceof AST_Break + && lct instanceof AST_BlockStatement + && loop_body(lct) === self) || (stat instanceof AST_Continue + && loop_body(lct) === self)) { + if (stat.label) { + remove(stat.label.thedef.references, stat); + } + } else { + a.push(stat); + } + } else { + a.push(stat); + } + if (aborts(stat)) has_quit = true; + } + return a; + }, []); + CHANGED = statements.length != orig; + return statements; + }; + + function sequencesize(statements, compressor) { + if (statements.length < 2) return statements; + var seq = [], ret = []; + function push_seq() { + seq = AST_Seq.from_array(seq); + if (seq) ret.push(make_node(AST_SimpleStatement, seq, { + body: seq + })); + seq = []; + }; + statements.forEach(function(stat){ + if (stat instanceof AST_SimpleStatement && seqLength(seq) < compressor.sequences_limit) { + seq.push(stat.body); + } else { + push_seq(); + ret.push(stat); + } + }); + push_seq(); + ret = sequencesize_2(ret, compressor); + CHANGED = ret.length != statements.length; + return ret; + }; + + function seqLength(a) { + for (var len = 0, i = 0; i < a.length; ++i) { + var stat = a[i]; + if (stat instanceof AST_Seq) { + len += stat.len(); + } else { + len++; + } + } + return len; + }; + + function sequencesize_2(statements, compressor) { + function cons_seq(right) { + ret.pop(); + var left = prev.body; + if (left instanceof AST_Seq) { + left.add(right); + } else { + left = AST_Seq.cons(left, right); + } + return left.transform(compressor); + }; + var ret = [], prev = null; + statements.forEach(function(stat){ + if (prev) { + if (stat instanceof AST_For) { + var opera = {}; + try { + prev.body.walk(new TreeWalker(function(node){ + if (node instanceof AST_Binary && node.operator == "in") + throw opera; + })); + if (stat.init && !(stat.init instanceof AST_Definitions)) { + stat.init = cons_seq(stat.init); + } + else if (!stat.init) { + stat.init = prev.body; + ret.pop(); + } + } catch(ex) { + if (ex !== opera) throw ex; + } + } + else if (stat instanceof AST_If) { + stat.condition = cons_seq(stat.condition); + } + else if (stat instanceof AST_With) { + stat.expression = cons_seq(stat.expression); + } + else if (stat instanceof AST_Exit && stat.value) { + stat.value = cons_seq(stat.value); + } + else if (stat instanceof AST_Exit) { + stat.value = cons_seq(make_node(AST_Undefined, stat)); + } + else if (stat instanceof AST_Switch) { + stat.expression = cons_seq(stat.expression); + } + } + ret.push(stat); + prev = stat instanceof AST_SimpleStatement ? stat : null; + }); + return ret; + }; + + function join_consecutive_vars(statements, compressor) { + var prev = null; + return statements.reduce(function(a, stat){ + if (stat instanceof AST_Definitions && prev && prev.TYPE == stat.TYPE) { + prev.definitions = prev.definitions.concat(stat.definitions); + CHANGED = true; + } + else if (stat instanceof AST_For + && prev instanceof AST_Var + && (!stat.init || stat.init.TYPE == prev.TYPE)) { + CHANGED = true; + a.pop(); + if (stat.init) { + stat.init.definitions = prev.definitions.concat(stat.init.definitions); + } else { + stat.init = prev; + } + a.push(stat); + prev = stat; + } + else { + prev = stat; + a.push(stat); + } + return a; + }, []); + }; + + function negate_iifes(statements, compressor) { + function is_iife_call(node) { + if (node instanceof AST_Call) { + return node.expression instanceof AST_Function || is_iife_call(node.expression); + } + return false; + } + + statements.forEach(function(stat){ + if (stat instanceof AST_SimpleStatement) { + stat.body = (function transform(thing) { + return thing.transform(new TreeTransformer(function(node){ + if (node instanceof AST_New) { + return node; + } + if (is_iife_call(node)) { + return make_node(AST_UnaryPrefix, node, { + operator: "!", + expression: node + }); + } + else if (node instanceof AST_Call) { + node.expression = transform(node.expression); + } + else if (node instanceof AST_Seq) { + node.car = transform(node.car); + } + else if (node instanceof AST_Conditional) { + var expr = transform(node.condition); + if (expr !== node.condition) { + // it has been negated, reverse + node.condition = expr; + var tmp = node.consequent; + node.consequent = node.alternative; + node.alternative = tmp; + } + } + return node; + })); + })(stat.body); + } + }); + }; + + }; + + function extract_functions_from_statement_array(statements) { + var funs = []; + for (var i = statements.length - 1; i >= 0; --i) { + var stat = statements[i]; + if (stat instanceof AST_Defun) { + statements.splice(i, 1); + funs.unshift(stat); + } + } + return funs; + } + + function extract_declarations_from_unreachable_code(compressor, stat, target) { + if (!(stat instanceof AST_Defun)) { + compressor.warn("Dropping unreachable code [{file}:{line},{col}]", stat.start); + } + stat.walk(new TreeWalker(function(node){ + if (node instanceof AST_Definitions) { + compressor.warn("Declarations in unreachable code! [{file}:{line},{col}]", node.start); + node.remove_initializers(); + target.push(node); + return true; + } + if (node instanceof AST_Defun) { + target.push(node); + return true; + } + if (node instanceof AST_Scope) { + return true; + } + })); + }; + + /* -----[ boolean/negation helpers ]----- */ + + // methods to determine whether an expression has a boolean result type + (function (def){ + var unary_bool = [ "!", "delete" ]; + var binary_bool = [ "in", "instanceof", "==", "!=", "===", "!==", "<", "<=", ">=", ">" ]; + def(AST_Node, return_false); + def(AST_UnaryPrefix, function(){ + return member(this.operator, unary_bool); + }); + def(AST_Binary, function(){ + return member(this.operator, binary_bool) || + ( (this.operator == "&&" || this.operator == "||") && + this.left.is_boolean() && this.right.is_boolean() ); + }); + def(AST_Conditional, function(){ + return this.consequent.is_boolean() && this.alternative.is_boolean(); + }); + def(AST_Assign, function(){ + return this.operator == "=" && this.right.is_boolean(); + }); + def(AST_Seq, function(){ + return this.cdr.is_boolean(); + }); + def(AST_True, return_true); + def(AST_False, return_true); + })(function(node, func){ + node.DEFMETHOD("is_boolean", func); + }); + + // methods to determine if an expression has a string result type + (function (def){ + def(AST_Node, return_false); + def(AST_String, return_true); + def(AST_UnaryPrefix, function(){ + return this.operator == "typeof"; + }); + def(AST_Binary, function(compressor){ + return this.operator == "+" && + (this.left.is_string(compressor) || this.right.is_string(compressor)); + }); + def(AST_Assign, function(compressor){ + return (this.operator == "=" || this.operator == "+=") && this.right.is_string(compressor); + }); + def(AST_Seq, function(compressor){ + return this.cdr.is_string(compressor); + }); + def(AST_Conditional, function(compressor){ + return this.consequent.is_string(compressor) && this.alternative.is_string(compressor); + }); + def(AST_Call, function(compressor){ + return compressor.option("unsafe") + && this.expression instanceof AST_SymbolRef + && this.expression.name == "String" + && this.expression.undeclared(); + }); + })(function(node, func){ + node.DEFMETHOD("is_string", func); + }); + + function best_of(ast1, ast2) { + return ast1.print_to_string().length > + ast2.print_to_string().length + ? ast2 : ast1; + }; + + // methods to evaluate a constant expression + (function (def){ + // The evaluate method returns an array with one or two + // elements. If the node has been successfully reduced to a + // constant, then the second element tells us the value; + // otherwise the second element is missing. The first element + // of the array is always an AST_Node descendant; if + // evaluation was successful it's a node that represents the + // constant; otherwise it's the original or a replacement node. + AST_Node.DEFMETHOD("evaluate", function(compressor){ + if (!compressor.option("evaluate")) return [ this ]; + try { + var val = this._eval(compressor); + return [ best_of(make_node_from_constant(compressor, val, this), this), val ]; + } catch(ex) { + if (ex !== def) throw ex; + return [ this ]; + } + }); + AST_Node.DEFMETHOD("is_constant", function(compressor){ + // Accomodate when compress option evaluate=false + // as well as the common constant expressions !0 and !1 + return this instanceof AST_Constant + || (this instanceof AST_UnaryPrefix && this.operator == "!" + && this.expression instanceof AST_Constant) + || this.evaluate(compressor).length > 1; + }); + // Obtain the constant value of an expression already known to be constant. + // Result only valid iff this.is_constant(compressor) is true. + AST_Node.DEFMETHOD("constant_value", function(compressor){ + // Accomodate when option evaluate=false. + if (this instanceof AST_Constant) return this.value; + // Accomodate the common constant expressions !0 and !1 when option evaluate=false. + if (this instanceof AST_UnaryPrefix + && this.operator == "!" + && this.expression instanceof AST_Constant) { + return !this.expression.value; + } + var result = this.evaluate(compressor) + if (result.length > 1) { + return result[1]; + } + // should never be reached + return undefined; + }); + def(AST_Statement, function(){ + throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start)); + }); + def(AST_Function, function(){ + // XXX: AST_Function inherits from AST_Scope, which itself + // inherits from AST_Statement; however, an AST_Function + // isn't really a statement. This could byte in other + // places too. :-( Wish JS had multiple inheritance. + throw def; + }); + function ev(node, compressor) { + if (!compressor) throw new Error("Compressor must be passed"); + + return node._eval(compressor); + }; + def(AST_Node, function(){ + throw def; // not constant + }); + def(AST_Constant, function(){ + return this.getValue(); + }); + def(AST_UnaryPrefix, function(compressor){ + var e = this.expression; + switch (this.operator) { + case "!": return !ev(e, compressor); + case "typeof": + // Function would be evaluated to an array and so typeof would + // incorrectly return 'object'. Hence making is a special case. + if (e instanceof AST_Function) return typeof function(){}; + + e = ev(e, compressor); + + // typeof returns "object" or "function" on different platforms + // so cannot evaluate reliably + if (e instanceof RegExp) throw def; + + return typeof e; + case "void": return void ev(e, compressor); + case "~": return ~ev(e, compressor); + case "-": return -ev(e, compressor); + case "+": return +ev(e, compressor); + } + throw def; + }); + def(AST_Binary, function(c){ + var left = this.left, right = this.right, result; + switch (this.operator) { + case "&&" : result = ev(left, c) && ev(right, c); break; + case "||" : result = ev(left, c) || ev(right, c); break; + case "|" : result = ev(left, c) | ev(right, c); break; + case "&" : result = ev(left, c) & ev(right, c); break; + case "^" : result = ev(left, c) ^ ev(right, c); break; + case "+" : result = ev(left, c) + ev(right, c); break; + case "*" : result = ev(left, c) * ev(right, c); break; + case "/" : result = ev(left, c) / ev(right, c); break; + case "%" : result = ev(left, c) % ev(right, c); break; + case "-" : result = ev(left, c) - ev(right, c); break; + case "<<" : result = ev(left, c) << ev(right, c); break; + case ">>" : result = ev(left, c) >> ev(right, c); break; + case ">>>" : result = ev(left, c) >>> ev(right, c); break; + case "==" : result = ev(left, c) == ev(right, c); break; + case "===" : result = ev(left, c) === ev(right, c); break; + case "!=" : result = ev(left, c) != ev(right, c); break; + case "!==" : result = ev(left, c) !== ev(right, c); break; + case "<" : result = ev(left, c) < ev(right, c); break; + case "<=" : result = ev(left, c) <= ev(right, c); break; + case ">" : result = ev(left, c) > ev(right, c); break; + case ">=" : result = ev(left, c) >= ev(right, c); break; + default: + throw def; + } + if (isNaN(result) && c.find_parent(AST_With)) { + // leave original expression as is + throw def; + } + return result; + }); + def(AST_Conditional, function(compressor){ + return ev(this.condition, compressor) + ? ev(this.consequent, compressor) + : ev(this.alternative, compressor); + }); + def(AST_SymbolRef, function(compressor){ + if (this._evaluating) throw def; + this._evaluating = true; + try { + var d = this.definition(); + if (d && (d.constant || compressor.option("reduce_vars") && !d.modified) && d.init) { + return ev(d.init, compressor); + } + } finally { + this._evaluating = false; + } + throw def; + }); + def(AST_Dot, function(compressor){ + if (compressor.option("unsafe") && this.property == "length") { + var str = ev(this.expression, compressor); + if (typeof str == "string") + return str.length; + } + throw def; + }); + })(function(node, func){ + node.DEFMETHOD("_eval", func); + }); + + // method to negate an expression + (function(def){ + function basic_negation(exp) { + return make_node(AST_UnaryPrefix, exp, { + operator: "!", + expression: exp + }); + }; + def(AST_Node, function(){ + return basic_negation(this); + }); + def(AST_Statement, function(){ + throw new Error("Cannot negate a statement"); + }); + def(AST_Function, function(){ + return basic_negation(this); + }); + def(AST_UnaryPrefix, function(){ + if (this.operator == "!") + return this.expression; + return basic_negation(this); + }); + def(AST_Seq, function(compressor){ + var self = this.clone(); + self.cdr = self.cdr.negate(compressor); + return self; + }); + def(AST_Conditional, function(compressor){ + var self = this.clone(); + self.consequent = self.consequent.negate(compressor); + self.alternative = self.alternative.negate(compressor); + return best_of(basic_negation(this), self); + }); + def(AST_Binary, function(compressor){ + var self = this.clone(), op = this.operator; + if (compressor.option("unsafe_comps")) { + switch (op) { + case "<=" : self.operator = ">" ; return self; + case "<" : self.operator = ">=" ; return self; + case ">=" : self.operator = "<" ; return self; + case ">" : self.operator = "<=" ; return self; + } + } + switch (op) { + case "==" : self.operator = "!="; return self; + case "!=" : self.operator = "=="; return self; + case "===": self.operator = "!=="; return self; + case "!==": self.operator = "==="; return self; + case "&&": + self.operator = "||"; + self.left = self.left.negate(compressor); + self.right = self.right.negate(compressor); + return best_of(basic_negation(this), self); + case "||": + self.operator = "&&"; + self.left = self.left.negate(compressor); + self.right = self.right.negate(compressor); + return best_of(basic_negation(this), self); + } + return basic_negation(this); + }); + })(function(node, func){ + node.DEFMETHOD("negate", function(compressor){ + return func.call(this, compressor); + }); + }); + + // determine if expression has side effects + (function(def){ + def(AST_Node, return_true); + + def(AST_EmptyStatement, return_false); + def(AST_Constant, return_false); + def(AST_This, return_false); + + def(AST_Call, function(compressor){ + var pure = compressor.option("pure_funcs"); + if (!pure) return true; + if (typeof pure == "function") return pure(this); + return pure.indexOf(this.expression.print_to_string()) < 0; + }); + + def(AST_Block, function(compressor){ + for (var i = this.body.length; --i >= 0;) { + if (this.body[i].has_side_effects(compressor)) + return true; + } + return false; + }); + + def(AST_SimpleStatement, function(compressor){ + return this.body.has_side_effects(compressor); + }); + def(AST_Defun, return_true); + def(AST_Function, return_false); + def(AST_Binary, function(compressor){ + return this.left.has_side_effects(compressor) + || this.right.has_side_effects(compressor); + }); + def(AST_Assign, return_true); + def(AST_Conditional, function(compressor){ + return this.condition.has_side_effects(compressor) + || this.consequent.has_side_effects(compressor) + || this.alternative.has_side_effects(compressor); + }); + def(AST_Unary, function(compressor){ + return this.operator == "delete" + || this.operator == "++" + || this.operator == "--" + || this.expression.has_side_effects(compressor); + }); + def(AST_SymbolRef, function(compressor){ + return this.global() && this.undeclared(); + }); + def(AST_Object, function(compressor){ + for (var i = this.properties.length; --i >= 0;) + if (this.properties[i].has_side_effects(compressor)) + return true; + return false; + }); + def(AST_ObjectProperty, function(compressor){ + return this.value.has_side_effects(compressor); + }); + def(AST_Array, function(compressor){ + for (var i = this.elements.length; --i >= 0;) + if (this.elements[i].has_side_effects(compressor)) + return true; + return false; + }); + def(AST_Dot, function(compressor){ + if (!compressor.option("pure_getters")) return true; + return this.expression.has_side_effects(compressor); + }); + def(AST_Sub, function(compressor){ + if (!compressor.option("pure_getters")) return true; + return this.expression.has_side_effects(compressor) + || this.property.has_side_effects(compressor); + }); + def(AST_PropAccess, function(compressor){ + return !compressor.option("pure_getters"); + }); + def(AST_Seq, function(compressor){ + return this.car.has_side_effects(compressor) + || this.cdr.has_side_effects(compressor); + }); + })(function(node, func){ + node.DEFMETHOD("has_side_effects", func); + }); + + // tell me if a statement aborts + function aborts(thing) { + return thing && thing.aborts(); + }; + (function(def){ + def(AST_Statement, function(){ return null }); + def(AST_Jump, function(){ return this }); + function block_aborts(){ + var n = this.body.length; + return n > 0 && aborts(this.body[n - 1]); + }; + def(AST_BlockStatement, block_aborts); + def(AST_SwitchBranch, block_aborts); + def(AST_If, function(){ + return this.alternative && aborts(this.body) && aborts(this.alternative) && this; + }); + })(function(node, func){ + node.DEFMETHOD("aborts", func); + }); + + /* -----[ optimizers ]----- */ + + OPT(AST_Directive, function(self, compressor){ + if (compressor.has_directive(self.value) === "up") { + return make_node(AST_EmptyStatement, self); + } + return self; + }); + + OPT(AST_Debugger, function(self, compressor){ + if (compressor.option("drop_debugger")) + return make_node(AST_EmptyStatement, self); + return self; + }); + + OPT(AST_LabeledStatement, function(self, compressor){ + if (self.body instanceof AST_Break + && compressor.loopcontrol_target(self.body.label) === self.body) { + return make_node(AST_EmptyStatement, self); + } + return self.label.references.length == 0 ? self.body : self; + }); + + OPT(AST_Block, function(self, compressor){ + self.body = tighten_body(self.body, compressor); + return self; + }); + + OPT(AST_BlockStatement, function(self, compressor){ + self.body = tighten_body(self.body, compressor); + switch (self.body.length) { + case 1: return self.body[0]; + case 0: return make_node(AST_EmptyStatement, self); + } + return self; + }); + + AST_Scope.DEFMETHOD("drop_unused", function(compressor){ + var self = this; + if (compressor.has_directive("use asm")) return self; + if (compressor.option("unused") + && !(self instanceof AST_Toplevel) + && !self.uses_eval + && !self.uses_with + ) { + var in_use = []; + var in_use_ids = {}; // avoid expensive linear scans of in_use + var initializations = new Dictionary(); + // pass 1: find out which symbols are directly used in + // this scope (not in nested scopes). + var scope = this; + var tw = new TreeWalker(function(node, descend){ + if (node !== self) { + if (node instanceof AST_Defun) { + initializations.add(node.name.name, node); + return true; // don't go in nested scopes + } + if (node instanceof AST_Definitions && scope === self) { + node.definitions.forEach(function(def){ + if (def.value) { + initializations.add(def.name.name, def.value); + if (def.value.has_side_effects(compressor)) { + def.value.walk(tw); + } + } + }); + return true; + } + if (node instanceof AST_SymbolRef) { + var node_def = node.definition(); + if (!(node_def.id in in_use_ids)) { + in_use_ids[node_def.id] = true; + in_use.push(node_def); + } + return true; + } + if (node instanceof AST_Scope) { + var save_scope = scope; + scope = node; + descend(); + scope = save_scope; + return true; + } + } + }); + self.walk(tw); + // pass 2: for every used symbol we need to walk its + // initialization code to figure out if it uses other + // symbols (that may not be in_use). + for (var i = 0; i < in_use.length; ++i) { + in_use[i].orig.forEach(function(decl){ + // undeclared globals will be instanceof AST_SymbolRef + var init = initializations.get(decl.name); + if (init) init.forEach(function(init){ + var tw = new TreeWalker(function(node){ + if (node instanceof AST_SymbolRef) { + var node_def = node.definition(); + if (!(node_def.id in in_use_ids)) { + in_use_ids[node_def.id] = true; + in_use.push(node_def); + } + } + }); + init.walk(tw); + }); + }); + } + // pass 3: we should drop declarations not in_use + var tt = new TreeTransformer( + function before(node, descend, in_list) { + if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) { + if (!compressor.option("keep_fargs")) { + for (var a = node.argnames, i = a.length; --i >= 0;) { + var sym = a[i]; + if (sym.unreferenced()) { + a.pop(); + compressor.warn("Dropping unused function argument {name} [{file}:{line},{col}]", { + name : sym.name, + file : sym.start.file, + line : sym.start.line, + col : sym.start.col + }); + } + else break; + } + } + } + if (node instanceof AST_Defun && node !== self) { + if (!(node.name.definition().id in in_use_ids)) { + compressor.warn("Dropping unused function {name} [{file}:{line},{col}]", { + name : node.name.name, + file : node.name.start.file, + line : node.name.start.line, + col : node.name.start.col + }); + return make_node(AST_EmptyStatement, node); + } + return node; + } + if (node instanceof AST_Definitions && !(tt.parent() instanceof AST_ForIn)) { + var def = node.definitions.filter(function(def){ + if (def.name.definition().id in in_use_ids) return true; + var w = { + name : def.name.name, + file : def.name.start.file, + line : def.name.start.line, + col : def.name.start.col + }; + if (def.value && def.value.has_side_effects(compressor)) { + def._unused_side_effects = true; + compressor.warn("Side effects in initialization of unused variable {name} [{file}:{line},{col}]", w); + return true; + } + compressor.warn("Dropping unused variable {name} [{file}:{line},{col}]", w); + return false; + }); + // place uninitialized names at the start + def = mergeSort(def, function(a, b){ + if (!a.value && b.value) return -1; + if (!b.value && a.value) return 1; + return 0; + }); + // for unused names whose initialization has + // side effects, we can cascade the init. code + // into the next one, or next statement. + var side_effects = []; + for (var i = 0; i < def.length;) { + var x = def[i]; + if (x._unused_side_effects) { + side_effects.push(x.value); + def.splice(i, 1); + } else { + if (side_effects.length > 0) { + side_effects.push(x.value); + x.value = AST_Seq.from_array(side_effects); + side_effects = []; + } + ++i; + } + } + if (side_effects.length > 0) { + side_effects = make_node(AST_BlockStatement, node, { + body: [ make_node(AST_SimpleStatement, node, { + body: AST_Seq.from_array(side_effects) + }) ] + }); + } else { + side_effects = null; + } + if (def.length == 0 && !side_effects) { + return make_node(AST_EmptyStatement, node); + } + if (def.length == 0) { + return in_list ? MAP.splice(side_effects.body) : side_effects; + } + node.definitions = def; + if (side_effects) { + side_effects.body.unshift(node); + return in_list ? MAP.splice(side_effects.body) : side_effects; + } + return node; + } + if (node instanceof AST_For) { + descend(node, this); + + if (node.init instanceof AST_BlockStatement) { + // certain combination of unused name + side effect leads to: + // https://github.com/mishoo/UglifyJS2/issues/44 + // that's an invalid AST. + // We fix it at this stage by moving the `var` outside the `for`. + + var body = node.init.body.slice(0, -1); + node.init = node.init.body.slice(-1)[0].body; + body.push(node); + + return in_list ? MAP.splice(body) : make_node(AST_BlockStatement, node, { + body: body + }); + } + } + if (node instanceof AST_Scope && node !== self) + return node; + } + ); + self.transform(tt); + } + }); + + AST_Scope.DEFMETHOD("hoist_declarations", function(compressor){ + var self = this; + if (compressor.has_directive("use asm")) return self; + var hoist_funs = compressor.option("hoist_funs"); + var hoist_vars = compressor.option("hoist_vars"); + if (hoist_funs || hoist_vars) { + var dirs = []; + var hoisted = []; + var vars = new Dictionary(), vars_found = 0, var_decl = 0; + // let's count var_decl first, we seem to waste a lot of + // space if we hoist `var` when there's only one. + self.walk(new TreeWalker(function(node){ + if (node instanceof AST_Scope && node !== self) + return true; + if (node instanceof AST_Var) { + ++var_decl; + return true; + } + })); + hoist_vars = hoist_vars && var_decl > 1; + var tt = new TreeTransformer( + function before(node) { + if (node !== self) { + if (node instanceof AST_Directive) { + dirs.push(node); + return make_node(AST_EmptyStatement, node); + } + if (node instanceof AST_Defun && hoist_funs) { + hoisted.push(node); + return make_node(AST_EmptyStatement, node); + } + if (node instanceof AST_Var && hoist_vars) { + node.definitions.forEach(function(def){ + vars.set(def.name.name, def); + ++vars_found; + }); + var seq = node.to_assignments(); + var p = tt.parent(); + if (p instanceof AST_ForIn && p.init === node) { + if (seq == null) { + var def = node.definitions[0].name; + return make_node(AST_SymbolRef, def, def); + } + return seq; + } + if (p instanceof AST_For && p.init === node) { + return seq; + } + if (!seq) return make_node(AST_EmptyStatement, node); + return make_node(AST_SimpleStatement, node, { + body: seq + }); + } + if (node instanceof AST_Scope) + return node; // to avoid descending in nested scopes + } + } + ); + self = self.transform(tt); + if (vars_found > 0) { + // collect only vars which don't show up in self's arguments list + var defs = []; + vars.each(function(def, name){ + if (self instanceof AST_Lambda + && find_if(function(x){ return x.name == def.name.name }, + self.argnames)) { + vars.del(name); + } else { + def = def.clone(); + def.value = null; + defs.push(def); + vars.set(name, def); + } + }); + if (defs.length > 0) { + // try to merge in assignments + for (var i = 0; i < self.body.length;) { + if (self.body[i] instanceof AST_SimpleStatement) { + var expr = self.body[i].body, sym, assign; + if (expr instanceof AST_Assign + && expr.operator == "=" + && (sym = expr.left) instanceof AST_Symbol + && vars.has(sym.name)) + { + var def = vars.get(sym.name); + if (def.value) break; + def.value = expr.right; + remove(defs, def); + defs.push(def); + self.body.splice(i, 1); + continue; + } + if (expr instanceof AST_Seq + && (assign = expr.car) instanceof AST_Assign + && assign.operator == "=" + && (sym = assign.left) instanceof AST_Symbol + && vars.has(sym.name)) + { + var def = vars.get(sym.name); + if (def.value) break; + def.value = assign.right; + remove(defs, def); + defs.push(def); + self.body[i].body = expr.cdr; + continue; + } + } + if (self.body[i] instanceof AST_EmptyStatement) { + self.body.splice(i, 1); + continue; + } + if (self.body[i] instanceof AST_BlockStatement) { + var tmp = [ i, 1 ].concat(self.body[i].body); + self.body.splice.apply(self.body, tmp); + continue; + } + break; + } + defs = make_node(AST_Var, self, { + definitions: defs + }); + hoisted.push(defs); + }; + } + self.body = dirs.concat(hoisted, self.body); + } + return self; + }); + + OPT(AST_SimpleStatement, function(self, compressor){ + if (compressor.option("side_effects")) { + if (!self.body.has_side_effects(compressor)) { + compressor.warn("Dropping side-effect-free statement [{file}:{line},{col}]", self.start); + return make_node(AST_EmptyStatement, self); + } + } + return self; + }); + + OPT(AST_DWLoop, function(self, compressor){ + var cond = self.condition.evaluate(compressor); + self.condition = cond[0]; + if (!compressor.option("loops")) return self; + if (cond.length > 1) { + if (cond[1]) { + return make_node(AST_For, self, { + body: self.body + }); + } else if (self instanceof AST_While) { + if (compressor.option("dead_code")) { + var a = []; + extract_declarations_from_unreachable_code(compressor, self.body, a); + return make_node(AST_BlockStatement, self, { body: a }); + } + } + } + return self; + }); + + function if_break_in_loop(self, compressor) { + function drop_it(rest) { + rest = as_statement_array(rest); + if (self.body instanceof AST_BlockStatement) { + self.body = self.body.clone(); + self.body.body = rest.concat(self.body.body.slice(1)); + self.body = self.body.transform(compressor); + } else { + self.body = make_node(AST_BlockStatement, self.body, { + body: rest + }).transform(compressor); + } + if_break_in_loop(self, compressor); + } + var first = self.body instanceof AST_BlockStatement ? self.body.body[0] : self.body; + if (first instanceof AST_If) { + if (first.body instanceof AST_Break + && compressor.loopcontrol_target(first.body.label) === self) { + if (self.condition) { + self.condition = make_node(AST_Binary, self.condition, { + left: self.condition, + operator: "&&", + right: first.condition.negate(compressor), + }); + } else { + self.condition = first.condition.negate(compressor); + } + drop_it(first.alternative); + } + else if (first.alternative instanceof AST_Break + && compressor.loopcontrol_target(first.alternative.label) === self) { + if (self.condition) { + self.condition = make_node(AST_Binary, self.condition, { + left: self.condition, + operator: "&&", + right: first.condition, + }); + } else { + self.condition = first.condition; + } + drop_it(first.body); + } + } + }; + + OPT(AST_While, function(self, compressor) { + if (!compressor.option("loops")) return self; + self = AST_DWLoop.prototype.optimize.call(self, compressor); + if (self instanceof AST_While) { + if_break_in_loop(self, compressor); + self = make_node(AST_For, self, self).transform(compressor); + } + return self; + }); + + OPT(AST_For, function(self, compressor){ + var cond = self.condition; + if (cond) { + cond = cond.evaluate(compressor); + self.condition = cond[0]; + } + if (!compressor.option("loops")) return self; + if (cond) { + if (cond.length > 1 && !cond[1]) { + if (compressor.option("dead_code")) { + var a = []; + if (self.init instanceof AST_Statement) { + a.push(self.init); + } + else if (self.init) { + a.push(make_node(AST_SimpleStatement, self.init, { + body: self.init + })); + } + extract_declarations_from_unreachable_code(compressor, self.body, a); + return make_node(AST_BlockStatement, self, { body: a }); + } + } + } + if_break_in_loop(self, compressor); + return self; + }); + + OPT(AST_If, function(self, compressor){ + if (!compressor.option("conditionals")) return self; + // if condition can be statically determined, warn and drop + // one of the blocks. note, statically determined implies + // “has no side effects”; also it doesn't work for cases like + // `x && true`, though it probably should. + var cond = self.condition.evaluate(compressor); + self.condition = cond[0]; + if (cond.length > 1) { + if (cond[1]) { + compressor.warn("Condition always true [{file}:{line},{col}]", self.condition.start); + if (compressor.option("dead_code")) { + var a = []; + if (self.alternative) { + extract_declarations_from_unreachable_code(compressor, self.alternative, a); + } + a.push(self.body); + return make_node(AST_BlockStatement, self, { body: a }).transform(compressor); + } + } else { + compressor.warn("Condition always false [{file}:{line},{col}]", self.condition.start); + if (compressor.option("dead_code")) { + var a = []; + extract_declarations_from_unreachable_code(compressor, self.body, a); + if (self.alternative) a.push(self.alternative); + return make_node(AST_BlockStatement, self, { body: a }).transform(compressor); + } + } + } + if (is_empty(self.alternative)) self.alternative = null; + var negated = self.condition.negate(compressor); + var self_condition_length = self.condition.print_to_string().length; + var negated_length = negated.print_to_string().length; + var negated_is_best = negated_length < self_condition_length; + if (self.alternative && negated_is_best) { + negated_is_best = false; // because we already do the switch here. + // no need to swap values of self_condition_length and negated_length + // here because they are only used in an equality comparison later on. + self.condition = negated; + var tmp = self.body; + self.body = self.alternative || make_node(AST_EmptyStatement); + self.alternative = tmp; + } + if (is_empty(self.body) && is_empty(self.alternative)) { + return make_node(AST_SimpleStatement, self.condition, { + body: self.condition + }).transform(compressor); + } + if (self.body instanceof AST_SimpleStatement + && self.alternative instanceof AST_SimpleStatement) { + return make_node(AST_SimpleStatement, self, { + body: make_node(AST_Conditional, self, { + condition : self.condition, + consequent : self.body.body, + alternative : self.alternative.body + }) + }).transform(compressor); + } + if (is_empty(self.alternative) && self.body instanceof AST_SimpleStatement) { + if (self_condition_length === negated_length && !negated_is_best + && self.condition instanceof AST_Binary && self.condition.operator == "||") { + // although the code length of self.condition and negated are the same, + // negated does not require additional surrounding parentheses. + // see https://github.com/mishoo/UglifyJS2/issues/979 + negated_is_best = true; + } + if (negated_is_best) return make_node(AST_SimpleStatement, self, { + body: make_node(AST_Binary, self, { + operator : "||", + left : negated, + right : self.body.body + }) + }).transform(compressor); + return make_node(AST_SimpleStatement, self, { + body: make_node(AST_Binary, self, { + operator : "&&", + left : self.condition, + right : self.body.body + }) + }).transform(compressor); + } + if (self.body instanceof AST_EmptyStatement + && self.alternative + && self.alternative instanceof AST_SimpleStatement) { + return make_node(AST_SimpleStatement, self, { + body: make_node(AST_Binary, self, { + operator : "||", + left : self.condition, + right : self.alternative.body + }) + }).transform(compressor); + } + if (self.body instanceof AST_Exit + && self.alternative instanceof AST_Exit + && self.body.TYPE == self.alternative.TYPE) { + return make_node(self.body.CTOR, self, { + value: make_node(AST_Conditional, self, { + condition : self.condition, + consequent : self.body.value || make_node(AST_Undefined, self.body).optimize(compressor), + alternative : self.alternative.value || make_node(AST_Undefined, self.alternative).optimize(compressor) + }) + }).transform(compressor); + } + if (self.body instanceof AST_If + && !self.body.alternative + && !self.alternative) { + self.condition = make_node(AST_Binary, self.condition, { + operator: "&&", + left: self.condition, + right: self.body.condition + }).transform(compressor); + self.body = self.body.body; + } + if (aborts(self.body)) { + if (self.alternative) { + var alt = self.alternative; + self.alternative = null; + return make_node(AST_BlockStatement, self, { + body: [ self, alt ] + }).transform(compressor); + } + } + if (aborts(self.alternative)) { + var body = self.body; + self.body = self.alternative; + self.condition = negated_is_best ? negated : self.condition.negate(compressor); + self.alternative = null; + return make_node(AST_BlockStatement, self, { + body: [ self, body ] + }).transform(compressor); + } + return self; + }); + + OPT(AST_Switch, function(self, compressor){ + if (self.body.length == 0 && compressor.option("conditionals")) { + return make_node(AST_SimpleStatement, self, { + body: self.expression + }).transform(compressor); + } + for(;;) { + var last_branch = self.body[self.body.length - 1]; + if (last_branch) { + var stat = last_branch.body[last_branch.body.length - 1]; // last statement + if (stat instanceof AST_Break && loop_body(compressor.loopcontrol_target(stat.label)) === self) + last_branch.body.pop(); + if (last_branch instanceof AST_Default && last_branch.body.length == 0) { + self.body.pop(); + continue; + } + } + break; + } + var exp = self.expression.evaluate(compressor); + out: if (exp.length == 2) try { + // constant expression + self.expression = exp[0]; + if (!compressor.option("dead_code")) break out; + var value = exp[1]; + var in_if = false; + var in_block = false; + var started = false; + var stopped = false; + var ruined = false; + var tt = new TreeTransformer(function(node, descend, in_list){ + if (node instanceof AST_Lambda || node instanceof AST_SimpleStatement) { + // no need to descend these node types + return node; + } + else if (node instanceof AST_Switch && node === self) { + node = node.clone(); + descend(node, this); + return ruined ? node : make_node(AST_BlockStatement, node, { + body: node.body.reduce(function(a, branch){ + return a.concat(branch.body); + }, []) + }).transform(compressor); + } + else if (node instanceof AST_If || node instanceof AST_Try) { + var save = in_if; + in_if = !in_block; + descend(node, this); + in_if = save; + return node; + } + else if (node instanceof AST_StatementWithBody || node instanceof AST_Switch) { + var save = in_block; + in_block = true; + descend(node, this); + in_block = save; + return node; + } + else if (node instanceof AST_Break && this.loopcontrol_target(node.label) === self) { + if (in_if) { + ruined = true; + return node; + } + if (in_block) return node; + stopped = true; + return in_list ? MAP.skip : make_node(AST_EmptyStatement, node); + } + else if (node instanceof AST_SwitchBranch && this.parent() === self) { + if (stopped) return MAP.skip; + if (node instanceof AST_Case) { + var exp = node.expression.evaluate(compressor); + if (exp.length < 2) { + // got a case with non-constant expression, baling out + throw self; + } + if (exp[1] === value || started) { + started = true; + if (aborts(node)) stopped = true; + descend(node, this); + return node; + } + return MAP.skip; + } + descend(node, this); + return node; + } + }); + tt.stack = compressor.stack.slice(); // so that's able to see parent nodes + self = self.transform(tt); + } catch(ex) { + if (ex !== self) throw ex; + } + return self; + }); + + OPT(AST_Case, function(self, compressor){ + self.body = tighten_body(self.body, compressor); + return self; + }); + + OPT(AST_Try, function(self, compressor){ + self.body = tighten_body(self.body, compressor); + return self; + }); + + AST_Definitions.DEFMETHOD("remove_initializers", function(){ + this.definitions.forEach(function(def){ def.value = null }); + }); + + AST_Definitions.DEFMETHOD("to_assignments", function(){ + var assignments = this.definitions.reduce(function(a, def){ + if (def.value) { + var name = make_node(AST_SymbolRef, def.name, def.name); + a.push(make_node(AST_Assign, def, { + operator : "=", + left : name, + right : def.value + })); + } + return a; + }, []); + if (assignments.length == 0) return null; + return AST_Seq.from_array(assignments); + }); + + OPT(AST_Definitions, function(self, compressor){ + if (self.definitions.length == 0) + return make_node(AST_EmptyStatement, self); + return self; + }); + + OPT(AST_Function, function(self, compressor){ + self = AST_Lambda.prototype.optimize.call(self, compressor); + if (compressor.option("unused") && !compressor.option("keep_fnames")) { + if (self.name && self.name.unreferenced()) { + self.name = null; + } + } + return self; + }); + + OPT(AST_Call, function(self, compressor){ + if (compressor.option("unsafe")) { + var exp = self.expression; + if (exp instanceof AST_SymbolRef && exp.undeclared()) { + switch (exp.name) { + case "Array": + if (self.args.length != 1) { + return make_node(AST_Array, self, { + elements: self.args + }).transform(compressor); + } + break; + case "Object": + if (self.args.length == 0) { + return make_node(AST_Object, self, { + properties: [] + }); + } + break; + case "String": + if (self.args.length == 0) return make_node(AST_String, self, { + value: "" + }); + if (self.args.length <= 1) return make_node(AST_Binary, self, { + left: self.args[0], + operator: "+", + right: make_node(AST_String, self, { value: "" }) + }).transform(compressor); + break; + case "Number": + if (self.args.length == 0) return make_node(AST_Number, self, { + value: 0 + }); + if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, { + expression: self.args[0], + operator: "+" + }).transform(compressor); + case "Boolean": + if (self.args.length == 0) return make_node(AST_False, self); + if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, { + expression: make_node(AST_UnaryPrefix, null, { + expression: self.args[0], + operator: "!" + }), + operator: "!" + }).transform(compressor); + break; + case "Function": + // new Function() => function(){} + if (self.args.length == 0) return make_node(AST_Function, self, { + argnames: [], + body: [] + }); + if (all(self.args, function(x){ return x instanceof AST_String })) { + // quite a corner-case, but we can handle it: + // https://github.com/mishoo/UglifyJS2/issues/203 + // if the code argument is a constant, then we can minify it. + try { + var code = "(function(" + self.args.slice(0, -1).map(function(arg){ + return arg.value; + }).join(",") + "){" + self.args[self.args.length - 1].value + "})()"; + var ast = parse(code); + ast.figure_out_scope({ screw_ie8: compressor.option("screw_ie8") }); + var comp = new Compressor(compressor.options); + ast = ast.transform(comp); + ast.figure_out_scope({ screw_ie8: compressor.option("screw_ie8") }); + ast.mangle_names(); + var fun; + try { + ast.walk(new TreeWalker(function(node){ + if (node instanceof AST_Lambda) { + fun = node; + throw ast; + } + })); + } catch(ex) { + if (ex !== ast) throw ex; + }; + if (!fun) return self; + var args = fun.argnames.map(function(arg, i){ + return make_node(AST_String, self.args[i], { + value: arg.print_to_string() + }); + }); + var code = OutputStream(); + AST_BlockStatement.prototype._codegen.call(fun, fun, code); + code = code.toString().replace(/^\{|\}$/g, ""); + args.push(make_node(AST_String, self.args[self.args.length - 1], { + value: code + })); + self.args = args; + return self; + } catch(ex) { + if (ex instanceof JS_Parse_Error) { + compressor.warn("Error parsing code passed to new Function [{file}:{line},{col}]", self.args[self.args.length - 1].start); + compressor.warn(ex.toString()); + } else { + console.log(ex); + throw ex; + } + } + } + break; + } + } + else if (exp instanceof AST_Dot && exp.property == "toString" && self.args.length == 0) { + return make_node(AST_Binary, self, { + left: make_node(AST_String, self, { value: "" }), + operator: "+", + right: exp.expression + }).transform(compressor); + } + else if (exp instanceof AST_Dot && exp.expression instanceof AST_Array && exp.property == "join") EXIT: { + var separator = self.args.length == 0 ? "," : self.args[0].evaluate(compressor)[1]; + if (separator == null) break EXIT; // not a constant + var elements = exp.expression.elements.reduce(function(a, el){ + el = el.evaluate(compressor); + if (a.length == 0 || el.length == 1) { + a.push(el); + } else { + var last = a[a.length - 1]; + if (last.length == 2) { + // it's a constant + var val = "" + last[1] + separator + el[1]; + a[a.length - 1] = [ make_node_from_constant(compressor, val, last[0]), val ]; + } else { + a.push(el); + } + } + return a; + }, []); + if (elements.length == 0) return make_node(AST_String, self, { value: "" }); + if (elements.length == 1) return elements[0][0]; + if (separator == "") { + var first; + if (elements[0][0] instanceof AST_String + || elements[1][0] instanceof AST_String) { + first = elements.shift()[0]; + } else { + first = make_node(AST_String, self, { value: "" }); + } + return elements.reduce(function(prev, el){ + return make_node(AST_Binary, el[0], { + operator : "+", + left : prev, + right : el[0], + }); + }, first).transform(compressor); + } + // need this awkward cloning to not affect original element + // best_of will decide which one to get through. + var node = self.clone(); + node.expression = node.expression.clone(); + node.expression.expression = node.expression.expression.clone(); + node.expression.expression.elements = elements.map(function(el){ + return el[0]; + }); + return best_of(self, node); + } + } + if (compressor.option("side_effects")) { + if (self.expression instanceof AST_Function + && self.args.length == 0 + && !AST_Block.prototype.has_side_effects.call(self.expression, compressor)) { + return make_node(AST_Undefined, self).transform(compressor); + } + } + if (compressor.option("drop_console")) { + if (self.expression instanceof AST_PropAccess) { + var name = self.expression.expression; + while (name.expression) { + name = name.expression; + } + if (name instanceof AST_SymbolRef + && name.name == "console" + && name.undeclared()) { + return make_node(AST_Undefined, self).transform(compressor); + } + } + } + return self.evaluate(compressor)[0]; + }); + + OPT(AST_New, function(self, compressor){ + if (compressor.option("unsafe")) { + var exp = self.expression; + if (exp instanceof AST_SymbolRef && exp.undeclared()) { + switch (exp.name) { + case "Object": + case "RegExp": + case "Function": + case "Error": + case "Array": + return make_node(AST_Call, self, self).transform(compressor); + } + } + } + return self; + }); + + OPT(AST_Seq, function(self, compressor){ + if (!compressor.option("side_effects")) + return self; + if (!self.car.has_side_effects(compressor)) { + return maintain_this_binding(compressor.parent(), self, self.cdr); + } + if (compressor.option("cascade")) { + if (self.car instanceof AST_Assign + && !self.car.left.has_side_effects(compressor)) { + if (self.car.left.equivalent_to(self.cdr)) { + return self.car; + } + if (self.cdr instanceof AST_Call + && self.cdr.expression.equivalent_to(self.car.left)) { + self.cdr.expression = self.car; + return self.cdr; + } + } + if (!self.car.has_side_effects(compressor) + && !self.cdr.has_side_effects(compressor) + && self.car.equivalent_to(self.cdr)) { + return self.car; + } + } + if (self.cdr instanceof AST_UnaryPrefix + && self.cdr.operator == "void" + && !self.cdr.expression.has_side_effects(compressor)) { + self.cdr.expression = self.car; + return self.cdr; + } + if (self.cdr instanceof AST_Undefined) { + return make_node(AST_UnaryPrefix, self, { + operator : "void", + expression : self.car + }); + } + return self; + }); + + AST_Unary.DEFMETHOD("lift_sequences", function(compressor){ + if (compressor.option("sequences")) { + if (this.expression instanceof AST_Seq) { + var seq = this.expression; + var x = seq.to_array(); + this.expression = x.pop(); + x.push(this); + seq = AST_Seq.from_array(x).transform(compressor); + return seq; + } + } + return this; + }); + + OPT(AST_UnaryPostfix, function(self, compressor){ + return self.lift_sequences(compressor); + }); + + OPT(AST_UnaryPrefix, function(self, compressor){ + self = self.lift_sequences(compressor); + var e = self.expression; + if (compressor.option("booleans") && compressor.in_boolean_context()) { + switch (self.operator) { + case "!": + if (e instanceof AST_UnaryPrefix && e.operator == "!") { + // !!foo ==> foo, if we're in boolean context + return e.expression; + } + break; + case "typeof": + // typeof always returns a non-empty string, thus it's + // always true in booleans + compressor.warn("Boolean expression always true [{file}:{line},{col}]", self.start); + if (self.expression.has_side_effects(compressor)) { + return make_node(AST_Seq, self, { + car: self.expression, + cdr: make_node(AST_True, self) + }); + } + return make_node(AST_True, self); + } + if (e instanceof AST_Binary && self.operator == "!") { + self = best_of(self, e.negate(compressor)); + } + } + return self.evaluate(compressor)[0]; + }); + + function has_side_effects_or_prop_access(node, compressor) { + var save_pure_getters = compressor.option("pure_getters"); + compressor.options.pure_getters = false; + var ret = node.has_side_effects(compressor); + compressor.options.pure_getters = save_pure_getters; + return ret; + } + + AST_Binary.DEFMETHOD("lift_sequences", function(compressor){ + if (compressor.option("sequences")) { + if (this.left instanceof AST_Seq) { + var seq = this.left; + var x = seq.to_array(); + this.left = x.pop(); + x.push(this); + seq = AST_Seq.from_array(x).transform(compressor); + return seq; + } + if (this.right instanceof AST_Seq + && this instanceof AST_Assign + && !has_side_effects_or_prop_access(this.left, compressor)) { + var seq = this.right; + var x = seq.to_array(); + this.right = x.pop(); + x.push(this); + seq = AST_Seq.from_array(x).transform(compressor); + return seq; + } + } + return this; + }); + + var commutativeOperators = makePredicate("== === != !== * & | ^"); + + OPT(AST_Binary, function(self, compressor){ + function reverse(op, force) { + if (force || !(self.left.has_side_effects(compressor) || self.right.has_side_effects(compressor))) { + if (op) self.operator = op; + var tmp = self.left; + self.left = self.right; + self.right = tmp; + } + } + if (commutativeOperators(self.operator)) { + if (self.right instanceof AST_Constant + && !(self.left instanceof AST_Constant)) { + // if right is a constant, whatever side effects the + // left side might have could not influence the + // result. hence, force switch. + + if (!(self.left instanceof AST_Binary + && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) { + reverse(null, true); + } + } + if (/^[!=]==?$/.test(self.operator)) { + if (self.left instanceof AST_SymbolRef && self.right instanceof AST_Conditional) { + if (self.right.consequent instanceof AST_SymbolRef + && self.right.consequent.definition() === self.left.definition()) { + if (/^==/.test(self.operator)) return self.right.condition; + if (/^!=/.test(self.operator)) return self.right.condition.negate(compressor); + } + if (self.right.alternative instanceof AST_SymbolRef + && self.right.alternative.definition() === self.left.definition()) { + if (/^==/.test(self.operator)) return self.right.condition.negate(compressor); + if (/^!=/.test(self.operator)) return self.right.condition; + } + } + if (self.right instanceof AST_SymbolRef && self.left instanceof AST_Conditional) { + if (self.left.consequent instanceof AST_SymbolRef + && self.left.consequent.definition() === self.right.definition()) { + if (/^==/.test(self.operator)) return self.left.condition; + if (/^!=/.test(self.operator)) return self.left.condition.negate(compressor); + } + if (self.left.alternative instanceof AST_SymbolRef + && self.left.alternative.definition() === self.right.definition()) { + if (/^==/.test(self.operator)) return self.left.condition.negate(compressor); + if (/^!=/.test(self.operator)) return self.left.condition; + } + } + } + } + self = self.lift_sequences(compressor); + if (compressor.option("comparisons")) switch (self.operator) { + case "===": + case "!==": + if ((self.left.is_string(compressor) && self.right.is_string(compressor)) || + (self.left.is_boolean() && self.right.is_boolean())) { + self.operator = self.operator.substr(0, 2); + } + // XXX: intentionally falling down to the next case + case "==": + case "!=": + if (self.left instanceof AST_String + && self.left.value == "undefined" + && self.right instanceof AST_UnaryPrefix + && self.right.operator == "typeof" + && compressor.option("unsafe")) { + if (!(self.right.expression instanceof AST_SymbolRef) + || !self.right.expression.undeclared()) { + self.right = self.right.expression; + self.left = make_node(AST_Undefined, self.left).optimize(compressor); + if (self.operator.length == 2) self.operator += "="; + } + } + break; + } + if (compressor.option("conditionals")) { + if (self.operator == "&&") { + var ll = self.left.evaluate(compressor); + if (ll.length > 1) { + if (ll[1]) { + compressor.warn("Condition left of && always true [{file}:{line},{col}]", self.start); + return maintain_this_binding(compressor.parent(), self, self.right.evaluate(compressor)[0]); + } else { + compressor.warn("Condition left of && always false [{file}:{line},{col}]", self.start); + return maintain_this_binding(compressor.parent(), self, ll[0]); + } + } + } + else if (self.operator == "||") { + var ll = self.left.evaluate(compressor); + if (ll.length > 1) { + if (ll[1]) { + compressor.warn("Condition left of || always true [{file}:{line},{col}]", self.start); + return maintain_this_binding(compressor.parent(), self, ll[0]); + } else { + compressor.warn("Condition left of || always false [{file}:{line},{col}]", self.start); + return maintain_this_binding(compressor.parent(), self, self.right.evaluate(compressor)[0]); + } + } + } + } + if (compressor.option("booleans") && compressor.in_boolean_context()) switch (self.operator) { + case "&&": + var ll = self.left.evaluate(compressor); + var rr = self.right.evaluate(compressor); + if ((ll.length > 1 && !ll[1]) || (rr.length > 1 && !rr[1])) { + compressor.warn("Boolean && always false [{file}:{line},{col}]", self.start); + if (self.left.has_side_effects(compressor)) { + return make_node(AST_Seq, self, { + car: self.left, + cdr: make_node(AST_False) + }).optimize(compressor); + } + return make_node(AST_False, self); + } + if (ll.length > 1 && ll[1]) { + return rr[0]; + } + if (rr.length > 1 && rr[1]) { + return ll[0]; + } + break; + case "||": + var ll = self.left.evaluate(compressor); + var rr = self.right.evaluate(compressor); + if ((ll.length > 1 && ll[1]) || (rr.length > 1 && rr[1])) { + compressor.warn("Boolean || always true [{file}:{line},{col}]", self.start); + if (self.left.has_side_effects(compressor)) { + return make_node(AST_Seq, self, { + car: self.left, + cdr: make_node(AST_True) + }).optimize(compressor); + } + return make_node(AST_True, self); + } + if (ll.length > 1 && !ll[1]) { + return rr[0]; + } + if (rr.length > 1 && !rr[1]) { + return ll[0]; + } + break; + case "+": + var ll = self.left.evaluate(compressor); + var rr = self.right.evaluate(compressor); + if ((ll.length > 1 && ll[0] instanceof AST_String && ll[1] && !self.right.has_side_effects(compressor)) || + (rr.length > 1 && rr[0] instanceof AST_String && rr[1] && !self.left.has_side_effects(compressor))) { + compressor.warn("+ in boolean context always true [{file}:{line},{col}]", self.start); + return make_node(AST_True, self); + } + break; + } + if (compressor.option("comparisons") && self.is_boolean()) { + if (!(compressor.parent() instanceof AST_Binary) + || compressor.parent() instanceof AST_Assign) { + var negated = make_node(AST_UnaryPrefix, self, { + operator: "!", + expression: self.negate(compressor) + }); + self = best_of(self, negated); + } + if (compressor.option("unsafe_comps")) { + switch (self.operator) { + case "<": reverse(">"); break; + case "<=": reverse(">="); break; + } + } + } + if (self.operator == "+" && self.right instanceof AST_String + && self.right.getValue() === "" && self.left instanceof AST_Binary + && self.left.operator == "+" && self.left.is_string(compressor)) { + return self.left; + } + if (compressor.option("evaluate")) { + if (self.operator == "+") { + if (self.left instanceof AST_Constant + && self.right instanceof AST_Binary + && self.right.operator == "+" + && self.right.left instanceof AST_Constant + && self.right.is_string(compressor)) { + self = make_node(AST_Binary, self, { + operator: "+", + left: make_node(AST_String, null, { + value: "" + self.left.getValue() + self.right.left.getValue(), + start: self.left.start, + end: self.right.left.end + }), + right: self.right.right + }); + } + if (self.right instanceof AST_Constant + && self.left instanceof AST_Binary + && self.left.operator == "+" + && self.left.right instanceof AST_Constant + && self.left.is_string(compressor)) { + self = make_node(AST_Binary, self, { + operator: "+", + left: self.left.left, + right: make_node(AST_String, null, { + value: "" + self.left.right.getValue() + self.right.getValue(), + start: self.left.right.start, + end: self.right.end + }) + }); + } + if (self.left instanceof AST_Binary + && self.left.operator == "+" + && self.left.is_string(compressor) + && self.left.right instanceof AST_Constant + && self.right instanceof AST_Binary + && self.right.operator == "+" + && self.right.left instanceof AST_Constant + && self.right.is_string(compressor)) { + self = make_node(AST_Binary, self, { + operator: "+", + left: make_node(AST_Binary, self.left, { + operator: "+", + left: self.left.left, + right: make_node(AST_String, null, { + value: "" + self.left.right.getValue() + self.right.left.getValue(), + start: self.left.right.start, + end: self.right.left.end + }) + }), + right: self.right.right + }); + } + } + } + // x && (y && z) ==> x && y && z + // x || (y || z) ==> x || y || z + if (self.right instanceof AST_Binary + && self.right.operator == self.operator + && (self.operator == "&&" || self.operator == "||")) + { + self.left = make_node(AST_Binary, self.left, { + operator : self.operator, + left : self.left, + right : self.right.left + }); + self.right = self.right.right; + return self.transform(compressor); + } + return self.evaluate(compressor)[0]; + }); + + OPT(AST_SymbolRef, function(self, compressor){ + function isLHS(symbol, parent) { + return ( + parent instanceof AST_Binary && + parent.operator === '=' && + parent.left === symbol + ); + } + + if (self.undeclared() && !isLHS(self, compressor.parent())) { + var defines = compressor.option("global_defs"); + if (defines && HOP(defines, self.name)) { + return make_node_from_constant(compressor, defines[self.name], self); + } + // testing against !self.scope.uses_with first is an optimization + if (!self.scope.uses_with || !compressor.find_parent(AST_With)) { + switch (self.name) { + case "undefined": + return make_node(AST_Undefined, self); + case "NaN": + return make_node(AST_NaN, self).transform(compressor); + case "Infinity": + return make_node(AST_Infinity, self).transform(compressor); + } + } + } + return self; + }); + + OPT(AST_Infinity, function (self, compressor) { + return make_node(AST_Binary, self, { + operator : '/', + left : make_node(AST_Number, self, {value: 1}), + right : make_node(AST_Number, self, {value: 0}) + }); + }); + + OPT(AST_Undefined, function(self, compressor){ + if (compressor.option("unsafe")) { + var scope = compressor.find_parent(AST_Scope); + var undef = scope.find_variable("undefined"); + if (undef) { + var ref = make_node(AST_SymbolRef, self, { + name : "undefined", + scope : scope, + thedef : undef + }); + ref.reference(); + return ref; + } + } + return self; + }); + + var ASSIGN_OPS = [ '+', '-', '/', '*', '%', '>>', '<<', '>>>', '|', '^', '&' ]; + var ASSIGN_OPS_COMMUTATIVE = [ '*', '|', '^', '&' ]; + OPT(AST_Assign, function(self, compressor){ + self = self.lift_sequences(compressor); + if (self.operator == "=" && self.left instanceof AST_SymbolRef && self.right instanceof AST_Binary) { + // x = expr1 OP expr2 + if (self.right.left instanceof AST_SymbolRef + && self.right.left.name == self.left.name + && member(self.right.operator, ASSIGN_OPS)) { + // x = x - 2 ---> x -= 2 + self.operator = self.right.operator + "="; + self.right = self.right.right; + } + else if (self.right.right instanceof AST_SymbolRef + && self.right.right.name == self.left.name + && member(self.right.operator, ASSIGN_OPS_COMMUTATIVE) + && !self.right.left.has_side_effects(compressor)) { + // x = 2 & x ---> x &= 2 + self.operator = self.right.operator + "="; + self.right = self.right.left; + } + } + return self; + }); + + OPT(AST_Conditional, function(self, compressor){ + if (!compressor.option("conditionals")) return self; + if (self.condition instanceof AST_Seq) { + var car = self.condition.car; + self.condition = self.condition.cdr; + return AST_Seq.cons(car, self); + } + var cond = self.condition.evaluate(compressor); + if (cond.length > 1) { + if (cond[1]) { + compressor.warn("Condition always true [{file}:{line},{col}]", self.start); + return maintain_this_binding(compressor.parent(), self, self.consequent); + } else { + compressor.warn("Condition always false [{file}:{line},{col}]", self.start); + return maintain_this_binding(compressor.parent(), self, self.alternative); + } + } + var negated = cond[0].negate(compressor); + if (best_of(cond[0], negated) === negated) { + self = make_node(AST_Conditional, self, { + condition: negated, + consequent: self.alternative, + alternative: self.consequent + }); + } + var consequent = self.consequent; + var alternative = self.alternative; + if (consequent instanceof AST_Assign + && alternative instanceof AST_Assign + && consequent.operator == alternative.operator + && consequent.left.equivalent_to(alternative.left) + && !consequent.left.has_side_effects(compressor) + ) { + /* + * Stuff like this: + * if (foo) exp = something; else exp = something_else; + * ==> + * exp = foo ? something : something_else; + */ + return make_node(AST_Assign, self, { + operator: consequent.operator, + left: consequent.left, + right: make_node(AST_Conditional, self, { + condition: self.condition, + consequent: consequent.right, + alternative: alternative.right + }) + }); + } + if (consequent instanceof AST_Call + && alternative.TYPE === consequent.TYPE + && consequent.args.length == alternative.args.length + && !consequent.expression.has_side_effects(compressor) + && consequent.expression.equivalent_to(alternative.expression)) { + if (consequent.args.length == 0) { + return make_node(AST_Seq, self, { + car: self.condition, + cdr: consequent + }); + } + if (consequent.args.length == 1) { + consequent.args[0] = make_node(AST_Conditional, self, { + condition: self.condition, + consequent: consequent.args[0], + alternative: alternative.args[0] + }); + return consequent; + } + } + // x?y?z:a:a --> x&&y?z:a + if (consequent instanceof AST_Conditional + && consequent.alternative.equivalent_to(alternative)) { + return make_node(AST_Conditional, self, { + condition: make_node(AST_Binary, self, { + left: self.condition, + operator: "&&", + right: consequent.condition + }), + consequent: consequent.consequent, + alternative: alternative + }); + } + // y?1:1 --> 1 + if (consequent.is_constant(compressor) + && alternative.is_constant(compressor) + && consequent.equivalent_to(alternative)) { + var consequent_value = consequent.constant_value(compressor); + if (self.condition.has_side_effects(compressor)) { + return AST_Seq.from_array([self.condition, make_node_from_constant(compressor, consequent_value, self)]); + } else { + return make_node_from_constant(compressor, consequent_value, self); + } + } + + if (is_true(self.consequent)) { + if (is_false(self.alternative)) { + // c ? true : false ---> !!c + return booleanize(self.condition); + } + // c ? true : x ---> !!c || x + return make_node(AST_Binary, self, { + operator: "||", + left: booleanize(self.condition), + right: self.alternative + }); + } + if (is_false(self.consequent)) { + if (is_true(self.alternative)) { + // c ? false : true ---> !c + return booleanize(self.condition.negate(compressor)); + } + // c ? false : x ---> !c && x + return make_node(AST_Binary, self, { + operator: "&&", + left: booleanize(self.condition.negate(compressor)), + right: self.alternative + }); + } + if (is_true(self.alternative)) { + // c ? x : true ---> !c || x + return make_node(AST_Binary, self, { + operator: "||", + left: booleanize(self.condition.negate(compressor)), + right: self.consequent + }); + } + if (is_false(self.alternative)) { + // c ? x : false ---> !!c && x + return make_node(AST_Binary, self, { + operator: "&&", + left: booleanize(self.condition), + right: self.consequent + }); + } + + return self; + + function booleanize(node) { + if (node.is_boolean()) return node; + // !!expression + return make_node(AST_UnaryPrefix, node, { + operator: "!", + expression: node.negate(compressor) + }); + } + + // AST_True or !0 + function is_true(node) { + return node instanceof AST_True + || (node instanceof AST_UnaryPrefix + && node.operator == "!" + && node.expression instanceof AST_Constant + && !node.expression.value); + } + // AST_False or !1 + function is_false(node) { + return node instanceof AST_False + || (node instanceof AST_UnaryPrefix + && node.operator == "!" + && node.expression instanceof AST_Constant + && !!node.expression.value); + } + }); + + OPT(AST_Boolean, function(self, compressor){ + if (compressor.option("booleans")) { + var p = compressor.parent(); + if (p instanceof AST_Binary && (p.operator == "==" + || p.operator == "!=")) { + compressor.warn("Non-strict equality against boolean: {operator} {value} [{file}:{line},{col}]", { + operator : p.operator, + value : self.value, + file : p.start.file, + line : p.start.line, + col : p.start.col, + }); + return make_node(AST_Number, self, { + value: +self.value + }); + } + return make_node(AST_UnaryPrefix, self, { + operator: "!", + expression: make_node(AST_Number, self, { + value: 1 - self.value + }) + }); + } + return self; + }); + + OPT(AST_Sub, function(self, compressor){ + var prop = self.property; + if (prop instanceof AST_String && compressor.option("properties")) { + prop = prop.getValue(); + if (RESERVED_WORDS(prop) ? compressor.option("screw_ie8") : is_identifier_string(prop)) { + return make_node(AST_Dot, self, { + expression : self.expression, + property : prop + }).optimize(compressor); + } + var v = parseFloat(prop); + if (!isNaN(v) && v.toString() == prop) { + self.property = make_node(AST_Number, self.property, { + value: v + }); + } + } + return self; + }); + + OPT(AST_Dot, function(self, compressor){ + var prop = self.property; + if (RESERVED_WORDS(prop) && !compressor.option("screw_ie8")) { + return make_node(AST_Sub, self, { + expression : self.expression, + property : make_node(AST_String, self, { + value: prop + }) + }).optimize(compressor); + } + return self.evaluate(compressor)[0]; + }); + + function literals_in_boolean_context(self, compressor) { + if (compressor.option("booleans") && compressor.in_boolean_context() && !self.has_side_effects(compressor)) { + return make_node(AST_True, self); + } + return self; + }; + OPT(AST_Array, literals_in_boolean_context); + OPT(AST_Object, literals_in_boolean_context); + OPT(AST_RegExp, literals_in_boolean_context); + + OPT(AST_Return, function(self, compressor){ + if (self.value instanceof AST_Undefined) { + self.value = null; + } + return self; + }); + +})(); diff --git a/node_modules/uglify-js/lib/mozilla-ast.js b/node_modules/uglify-js/lib/mozilla-ast.js new file mode 100644 index 0000000..12b55dc --- /dev/null +++ b/node_modules/uglify-js/lib/mozilla-ast.js @@ -0,0 +1,609 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +(function(){ + + var normalize_directives = function(body) { + var in_directive = true; + + for (var i = 0; i < body.length; i++) { + if (in_directive && body[i] instanceof AST_Statement && body[i].body instanceof AST_String) { + body[i] = new AST_Directive({ + start: body[i].start, + end: body[i].end, + value: body[i].body.value + }); + } else if (in_directive && !(body[i] instanceof AST_Statement && body[i].body instanceof AST_String)) { + in_directive = false; + } + } + + return body; + }; + + var MOZ_TO_ME = { + Program: function(M) { + return new AST_Toplevel({ + start: my_start_token(M), + end: my_end_token(M), + body: normalize_directives(M.body.map(from_moz)) + }); + }, + FunctionDeclaration: function(M) { + return new AST_Defun({ + start: my_start_token(M), + end: my_end_token(M), + name: from_moz(M.id), + argnames: M.params.map(from_moz), + body: normalize_directives(from_moz(M.body).body) + }); + }, + FunctionExpression: function(M) { + return new AST_Function({ + start: my_start_token(M), + end: my_end_token(M), + name: from_moz(M.id), + argnames: M.params.map(from_moz), + body: normalize_directives(from_moz(M.body).body) + }); + }, + ExpressionStatement: function(M) { + return new AST_SimpleStatement({ + start: my_start_token(M), + end: my_end_token(M), + body: from_moz(M.expression) + }); + }, + TryStatement: function(M) { + var handlers = M.handlers || [M.handler]; + if (handlers.length > 1 || M.guardedHandlers && M.guardedHandlers.length) { + throw new Error("Multiple catch clauses are not supported."); + } + return new AST_Try({ + start : my_start_token(M), + end : my_end_token(M), + body : from_moz(M.block).body, + bcatch : from_moz(handlers[0]), + bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null + }); + }, + Property: function(M) { + var key = M.key; + var name = key.type == "Identifier" ? key.name : key.value; + var args = { + start : my_start_token(key), + end : my_end_token(M.value), + key : name, + value : from_moz(M.value) + }; + switch (M.kind) { + case "init": + return new AST_ObjectKeyVal(args); + case "set": + args.value.name = from_moz(key); + return new AST_ObjectSetter(args); + case "get": + args.value.name = from_moz(key); + return new AST_ObjectGetter(args); + } + }, + ArrayExpression: function(M) { + return new AST_Array({ + start : my_start_token(M), + end : my_end_token(M), + elements : M.elements.map(function(elem){ + return elem === null ? new AST_Hole() : from_moz(elem); + }) + }); + }, + ObjectExpression: function(M) { + return new AST_Object({ + start : my_start_token(M), + end : my_end_token(M), + properties : M.properties.map(function(prop){ + prop.type = "Property"; + return from_moz(prop) + }) + }); + }, + SequenceExpression: function(M) { + return AST_Seq.from_array(M.expressions.map(from_moz)); + }, + MemberExpression: function(M) { + return new (M.computed ? AST_Sub : AST_Dot)({ + start : my_start_token(M), + end : my_end_token(M), + property : M.computed ? from_moz(M.property) : M.property.name, + expression : from_moz(M.object) + }); + }, + SwitchCase: function(M) { + return new (M.test ? AST_Case : AST_Default)({ + start : my_start_token(M), + end : my_end_token(M), + expression : from_moz(M.test), + body : M.consequent.map(from_moz) + }); + }, + VariableDeclaration: function(M) { + return new (M.kind === "const" ? AST_Const : AST_Var)({ + start : my_start_token(M), + end : my_end_token(M), + definitions : M.declarations.map(from_moz) + }); + }, + Literal: function(M) { + var val = M.value, args = { + start : my_start_token(M), + end : my_end_token(M) + }; + if (val === null) return new AST_Null(args); + switch (typeof val) { + case "string": + args.value = val; + return new AST_String(args); + case "number": + args.value = val; + return new AST_Number(args); + case "boolean": + return new (val ? AST_True : AST_False)(args); + default: + var rx = M.regex; + if (rx && rx.pattern) { + // RegExpLiteral as per ESTree AST spec + args.value = new RegExp(rx.pattern, rx.flags).toString(); + } else { + // support legacy RegExp + args.value = M.regex && M.raw ? M.raw : val; + } + return new AST_RegExp(args); + } + }, + Identifier: function(M) { + var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2]; + return new ( p.type == "LabeledStatement" ? AST_Label + : p.type == "VariableDeclarator" && p.id === M ? (p.kind == "const" ? AST_SymbolConst : AST_SymbolVar) + : p.type == "FunctionExpression" ? (p.id === M ? AST_SymbolLambda : AST_SymbolFunarg) + : p.type == "FunctionDeclaration" ? (p.id === M ? AST_SymbolDefun : AST_SymbolFunarg) + : p.type == "CatchClause" ? AST_SymbolCatch + : p.type == "BreakStatement" || p.type == "ContinueStatement" ? AST_LabelRef + : AST_SymbolRef)({ + start : my_start_token(M), + end : my_end_token(M), + name : M.name + }); + } + }; + + MOZ_TO_ME.UpdateExpression = + MOZ_TO_ME.UnaryExpression = function To_Moz_Unary(M) { + var prefix = "prefix" in M ? M.prefix + : M.type == "UnaryExpression" ? true : false; + return new (prefix ? AST_UnaryPrefix : AST_UnaryPostfix)({ + start : my_start_token(M), + end : my_end_token(M), + operator : M.operator, + expression : from_moz(M.argument) + }); + }; + + map("EmptyStatement", AST_EmptyStatement); + map("BlockStatement", AST_BlockStatement, "body@body"); + map("IfStatement", AST_If, "test>condition, consequent>body, alternate>alternative"); + map("LabeledStatement", AST_LabeledStatement, "label>label, body>body"); + map("BreakStatement", AST_Break, "label>label"); + map("ContinueStatement", AST_Continue, "label>label"); + map("WithStatement", AST_With, "object>expression, body>body"); + map("SwitchStatement", AST_Switch, "discriminant>expression, cases@body"); + map("ReturnStatement", AST_Return, "argument>value"); + map("ThrowStatement", AST_Throw, "argument>value"); + map("WhileStatement", AST_While, "test>condition, body>body"); + map("DoWhileStatement", AST_Do, "test>condition, body>body"); + map("ForStatement", AST_For, "init>init, test>condition, update>step, body>body"); + map("ForInStatement", AST_ForIn, "left>init, right>object, body>body"); + map("DebuggerStatement", AST_Debugger); + map("VariableDeclarator", AST_VarDef, "id>name, init>value"); + map("CatchClause", AST_Catch, "param>argname, body%body"); + + map("ThisExpression", AST_This); + map("BinaryExpression", AST_Binary, "operator=operator, left>left, right>right"); + map("LogicalExpression", AST_Binary, "operator=operator, left>left, right>right"); + map("AssignmentExpression", AST_Assign, "operator=operator, left>left, right>right"); + map("ConditionalExpression", AST_Conditional, "test>condition, consequent>consequent, alternate>alternative"); + map("NewExpression", AST_New, "callee>expression, arguments@args"); + map("CallExpression", AST_Call, "callee>expression, arguments@args"); + + def_to_moz(AST_Toplevel, function To_Moz_Program(M) { + return { + type: "Program", + body: M.body.map(to_moz) + }; + }); + + def_to_moz(AST_Defun, function To_Moz_FunctionDeclaration(M) { + return { + type: "FunctionDeclaration", + id: to_moz(M.name), + params: M.argnames.map(to_moz), + body: to_moz_block(M) + } + }); + + def_to_moz(AST_Function, function To_Moz_FunctionExpression(M) { + return { + type: "FunctionExpression", + id: to_moz(M.name), + params: M.argnames.map(to_moz), + body: to_moz_block(M) + } + }); + + def_to_moz(AST_Directive, function To_Moz_Directive(M) { + return { + type: "ExpressionStatement", + expression: { + type: "Literal", + value: M.value + } + }; + }); + + def_to_moz(AST_SimpleStatement, function To_Moz_ExpressionStatement(M) { + return { + type: "ExpressionStatement", + expression: to_moz(M.body) + }; + }); + + def_to_moz(AST_SwitchBranch, function To_Moz_SwitchCase(M) { + return { + type: "SwitchCase", + test: to_moz(M.expression), + consequent: M.body.map(to_moz) + }; + }); + + def_to_moz(AST_Try, function To_Moz_TryStatement(M) { + return { + type: "TryStatement", + block: to_moz_block(M), + handler: to_moz(M.bcatch), + guardedHandlers: [], + finalizer: to_moz(M.bfinally) + }; + }); + + def_to_moz(AST_Catch, function To_Moz_CatchClause(M) { + return { + type: "CatchClause", + param: to_moz(M.argname), + guard: null, + body: to_moz_block(M) + }; + }); + + def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) { + return { + type: "VariableDeclaration", + kind: M instanceof AST_Const ? "const" : "var", + declarations: M.definitions.map(to_moz) + }; + }); + + def_to_moz(AST_Seq, function To_Moz_SequenceExpression(M) { + return { + type: "SequenceExpression", + expressions: M.to_array().map(to_moz) + }; + }); + + def_to_moz(AST_PropAccess, function To_Moz_MemberExpression(M) { + var isComputed = M instanceof AST_Sub; + return { + type: "MemberExpression", + object: to_moz(M.expression), + computed: isComputed, + property: isComputed ? to_moz(M.property) : {type: "Identifier", name: M.property} + }; + }); + + def_to_moz(AST_Unary, function To_Moz_Unary(M) { + return { + type: M.operator == "++" || M.operator == "--" ? "UpdateExpression" : "UnaryExpression", + operator: M.operator, + prefix: M instanceof AST_UnaryPrefix, + argument: to_moz(M.expression) + }; + }); + + def_to_moz(AST_Binary, function To_Moz_BinaryExpression(M) { + return { + type: M.operator == "&&" || M.operator == "||" ? "LogicalExpression" : "BinaryExpression", + left: to_moz(M.left), + operator: M.operator, + right: to_moz(M.right) + }; + }); + + def_to_moz(AST_Array, function To_Moz_ArrayExpression(M) { + return { + type: "ArrayExpression", + elements: M.elements.map(to_moz) + }; + }); + + def_to_moz(AST_Object, function To_Moz_ObjectExpression(M) { + return { + type: "ObjectExpression", + properties: M.properties.map(to_moz) + }; + }); + + def_to_moz(AST_ObjectProperty, function To_Moz_Property(M) { + var key = ( + is_identifier(M.key) + ? {type: "Identifier", name: M.key} + : {type: "Literal", value: M.key} + ); + var kind; + if (M instanceof AST_ObjectKeyVal) { + kind = "init"; + } else + if (M instanceof AST_ObjectGetter) { + kind = "get"; + } else + if (M instanceof AST_ObjectSetter) { + kind = "set"; + } + return { + type: "Property", + kind: kind, + key: key, + value: to_moz(M.value) + }; + }); + + def_to_moz(AST_Symbol, function To_Moz_Identifier(M) { + var def = M.definition(); + return { + type: "Identifier", + name: def ? def.mangled_name || def.name : M.name + }; + }); + + def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) { + var value = M.value; + return { + type: "Literal", + value: value, + raw: value.toString(), + regex: { + pattern: value.source, + flags: value.toString().match(/[gimuy]*$/)[0] + } + }; + }); + + def_to_moz(AST_Constant, function To_Moz_Literal(M) { + var value = M.value; + if (typeof value === 'number' && (value < 0 || (value === 0 && 1 / value < 0))) { + return { + type: "UnaryExpression", + operator: "-", + prefix: true, + argument: { + type: "Literal", + value: -value, + raw: M.start.raw + } + }; + } + return { + type: "Literal", + value: value, + raw: M.start.raw + }; + }); + + def_to_moz(AST_Atom, function To_Moz_Atom(M) { + return { + type: "Identifier", + name: String(M.value) + }; + }); + + AST_Boolean.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast); + AST_Null.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast); + AST_Hole.DEFMETHOD("to_mozilla_ast", function To_Moz_ArrayHole() { return null }); + + AST_Block.DEFMETHOD("to_mozilla_ast", AST_BlockStatement.prototype.to_mozilla_ast); + AST_Lambda.DEFMETHOD("to_mozilla_ast", AST_Function.prototype.to_mozilla_ast); + + /* -----[ tools ]----- */ + + function raw_token(moznode) { + if (moznode.type == "Literal") { + return moznode.raw != null ? moznode.raw : moznode.value + ""; + } + } + + function my_start_token(moznode) { + var loc = moznode.loc, start = loc && loc.start; + var range = moznode.range; + return new AST_Token({ + file : loc && loc.source, + line : start && start.line, + col : start && start.column, + pos : range ? range[0] : moznode.start, + endline : start && start.line, + endcol : start && start.column, + endpos : range ? range[0] : moznode.start, + raw : raw_token(moznode), + }); + }; + + function my_end_token(moznode) { + var loc = moznode.loc, end = loc && loc.end; + var range = moznode.range; + return new AST_Token({ + file : loc && loc.source, + line : end && end.line, + col : end && end.column, + pos : range ? range[1] : moznode.end, + endline : end && end.line, + endcol : end && end.column, + endpos : range ? range[1] : moznode.end, + raw : raw_token(moznode), + }); + }; + + function map(moztype, mytype, propmap) { + var moz_to_me = "function From_Moz_" + moztype + "(M){\n"; + moz_to_me += "return new U2." + mytype.name + "({\n" + + "start: my_start_token(M),\n" + + "end: my_end_token(M)"; + + var me_to_moz = "function To_Moz_" + moztype + "(M){\n"; + me_to_moz += "return {\n" + + "type: " + JSON.stringify(moztype); + + if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop){ + var m = /([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop); + if (!m) throw new Error("Can't understand property map: " + prop); + var moz = m[1], how = m[2], my = m[3]; + moz_to_me += ",\n" + my + ": "; + me_to_moz += ",\n" + moz + ": "; + switch (how) { + case "@": + moz_to_me += "M." + moz + ".map(from_moz)"; + me_to_moz += "M." + my + ".map(to_moz)"; + break; + case ">": + moz_to_me += "from_moz(M." + moz + ")"; + me_to_moz += "to_moz(M." + my + ")"; + break; + case "=": + moz_to_me += "M." + moz; + me_to_moz += "M." + my; + break; + case "%": + moz_to_me += "from_moz(M." + moz + ").body"; + me_to_moz += "to_moz_block(M)"; + break; + default: + throw new Error("Can't understand operator in propmap: " + prop); + } + }); + + moz_to_me += "\n})\n}"; + me_to_moz += "\n}\n}"; + + //moz_to_me = parse(moz_to_me).print_to_string({ beautify: true }); + //me_to_moz = parse(me_to_moz).print_to_string({ beautify: true }); + //console.log(moz_to_me); + + moz_to_me = new Function("U2", "my_start_token", "my_end_token", "from_moz", "return(" + moz_to_me + ")")( + exports, my_start_token, my_end_token, from_moz + ); + me_to_moz = new Function("to_moz", "to_moz_block", "return(" + me_to_moz + ")")( + to_moz, to_moz_block + ); + MOZ_TO_ME[moztype] = moz_to_me; + def_to_moz(mytype, me_to_moz); + }; + + var FROM_MOZ_STACK = null; + + function from_moz(node) { + FROM_MOZ_STACK.push(node); + var ret = node != null ? MOZ_TO_ME[node.type](node) : null; + FROM_MOZ_STACK.pop(); + return ret; + }; + + AST_Node.from_mozilla_ast = function(node){ + var save_stack = FROM_MOZ_STACK; + FROM_MOZ_STACK = []; + var ast = from_moz(node); + FROM_MOZ_STACK = save_stack; + return ast; + }; + + function set_moz_loc(mynode, moznode, myparent) { + var start = mynode.start; + var end = mynode.end; + if (start.pos != null && end.endpos != null) { + moznode.range = [start.pos, end.endpos]; + } + if (start.line) { + moznode.loc = { + start: {line: start.line, column: start.col}, + end: end.endline ? {line: end.endline, column: end.endcol} : null + }; + if (start.file) { + moznode.loc.source = start.file; + } + } + return moznode; + }; + + function def_to_moz(mytype, handler) { + mytype.DEFMETHOD("to_mozilla_ast", function() { + return set_moz_loc(this, handler(this)); + }); + }; + + function to_moz(node) { + return node != null ? node.to_mozilla_ast() : null; + }; + + function to_moz_block(node) { + return { + type: "BlockStatement", + body: node.body.map(to_moz) + }; + }; + +})(); diff --git a/node_modules/uglify-js/lib/output.js b/node_modules/uglify-js/lib/output.js new file mode 100644 index 0000000..50e5aa4 --- /dev/null +++ b/node_modules/uglify-js/lib/output.js @@ -0,0 +1,1458 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +var EXPECT_DIRECTIVE = /^$|[;{][\s\n]*$/; + +function is_some_comments(comment) { + var text = comment.value; + var type = comment.type; + if (type == "comment2") { + // multiline comment + return /@preserve|@license|@cc_on/i.test(text); + } + return type == "comment5"; +} + +function is_comment5(comment) { + return comment.type == "comment5"; +} + +function OutputStream(options) { + + options = defaults(options, { + indent_start : 0, + indent_level : 4, + quote_keys : false, + space_colon : true, + ascii_only : false, + unescape_regexps : false, + inline_script : false, + width : 80, + max_line_len : 32000, + beautify : false, + source_map : null, + bracketize : false, + semicolons : true, + comments : false, + shebang : true, + preserve_line : false, + screw_ie8 : true, + preamble : null, + quote_style : 0, + keep_quoted_props: false, + wrap_iife : false, + }, true); + + // Convert comment option to RegExp if neccessary and set up comments filter + var comment_filter = options.shebang ? is_comment5 : return_false; // Default case, throw all comments away except shebangs + if (options.comments) { + var comments = options.comments; + if (typeof options.comments === "string" && /^\/.*\/[a-zA-Z]*$/.test(options.comments)) { + var regex_pos = options.comments.lastIndexOf("/"); + comments = new RegExp( + options.comments.substr(1, regex_pos - 1), + options.comments.substr(regex_pos + 1) + ); + } + if (comments instanceof RegExp) { + comment_filter = function(comment) { + return comment.type == "comment5" || comments.test(comment.value); + }; + } + else if (typeof comments === "function") { + comment_filter = function(comment) { + return comment.type == "comment5" || comments(this, comment); + }; + } + else if (comments === "some") { + comment_filter = is_some_comments; + } else { // NOTE includes "all" option + comment_filter = return_true; + } + } + + var indentation = 0; + var current_col = 0; + var current_line = 1; + var current_pos = 0; + var OUTPUT = ""; + + function to_ascii(str, identifier) { + return str.replace(/[\u0000-\u001f\u007f-\uffff]/g, function(ch) { + var code = ch.charCodeAt(0).toString(16); + if (code.length <= 2 && !identifier) { + while (code.length < 2) code = "0" + code; + return "\\x" + code; + } else { + while (code.length < 4) code = "0" + code; + return "\\u" + code; + } + }); + }; + + function make_string(str, quote) { + var dq = 0, sq = 0; + str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g, + function(s, i){ + switch (s) { + case '"': ++dq; return '"'; + case "'": ++sq; return "'"; + case "\\": return "\\\\"; + case "\n": return "\\n"; + case "\r": return "\\r"; + case "\t": return "\\t"; + case "\b": return "\\b"; + case "\f": return "\\f"; + case "\x0B": return options.screw_ie8 ? "\\v" : "\\x0B"; + case "\u2028": return "\\u2028"; + case "\u2029": return "\\u2029"; + case "\ufeff": return "\\ufeff"; + case "\0": + return /[0-7]/.test(str.charAt(i+1)) ? "\\x00" : "\\0"; + } + return s; + }); + function quote_single() { + return "'" + str.replace(/\x27/g, "\\'") + "'"; + } + function quote_double() { + return '"' + str.replace(/\x22/g, '\\"') + '"'; + } + if (options.ascii_only) str = to_ascii(str); + switch (options.quote_style) { + case 1: + return quote_single(); + case 2: + return quote_double(); + case 3: + return quote == "'" ? quote_single() : quote_double(); + default: + return dq > sq ? quote_single() : quote_double(); + } + }; + + function encode_string(str, quote) { + var ret = make_string(str, quote); + if (options.inline_script) { + ret = ret.replace(/<\x2fscript([>\/\t\n\f\r ])/gi, "<\\/script$1"); + ret = ret.replace(/\x3c!--/g, "\\x3c!--"); + ret = ret.replace(/--\x3e/g, "--\\x3e"); + } + return ret; + }; + + function make_name(name) { + name = name.toString(); + if (options.ascii_only) + name = to_ascii(name, true); + return name; + }; + + function make_indent(back) { + return repeat_string(" ", options.indent_start + indentation - back * options.indent_level); + }; + + /* -----[ beautification/minification ]----- */ + + var might_need_space = false; + var might_need_semicolon = false; + var last = null; + + function last_char() { + return last.charAt(last.length - 1); + }; + + function maybe_newline() { + if (options.max_line_len && current_col > options.max_line_len) + print("\n"); + }; + + var requireSemicolonChars = makePredicate("( [ + * / - , ."); + + function print(str) { + str = String(str); + var ch = str.charAt(0); + if (might_need_semicolon) { + might_need_semicolon = false; + + if ((!ch || ";}".indexOf(ch) < 0) && !/[;]$/.test(last)) { + if (options.semicolons || requireSemicolonChars(ch)) { + OUTPUT += ";"; + current_col++; + current_pos++; + } else { + OUTPUT += "\n"; + current_pos++; + current_line++; + current_col = 0; + + if (/^\s+$/.test(str)) { + // reset the semicolon flag, since we didn't print one + // now and might still have to later + might_need_semicolon = true; + } + } + + if (!options.beautify) + might_need_space = false; + } + } + + if (!options.beautify && options.preserve_line && stack[stack.length - 1]) { + var target_line = stack[stack.length - 1].start.line; + while (current_line < target_line) { + OUTPUT += "\n"; + current_pos++; + current_line++; + current_col = 0; + might_need_space = false; + } + } + + if (might_need_space) { + var prev = last_char(); + if ((is_identifier_char(prev) + && (is_identifier_char(ch) || ch == "\\")) + || (/^[\+\-\/]$/.test(ch) && ch == prev)) + { + OUTPUT += " "; + current_col++; + current_pos++; + } + might_need_space = false; + } + var a = str.split(/\r?\n/), n = a.length - 1; + current_line += n; + if (n == 0) { + current_col += a[n].length; + } else { + current_col = a[n].length; + } + current_pos += str.length; + last = str; + OUTPUT += str; + }; + + var space = options.beautify ? function() { + print(" "); + } : function() { + might_need_space = true; + }; + + var indent = options.beautify ? function(half) { + if (options.beautify) { + print(make_indent(half ? 0.5 : 0)); + } + } : noop; + + var with_indent = options.beautify ? function(col, cont) { + if (col === true) col = next_indent(); + var save_indentation = indentation; + indentation = col; + var ret = cont(); + indentation = save_indentation; + return ret; + } : function(col, cont) { return cont() }; + + var newline = options.beautify ? function() { + print("\n"); + } : maybe_newline; + + var semicolon = options.beautify ? function() { + print(";"); + } : function() { + might_need_semicolon = true; + }; + + function force_semicolon() { + might_need_semicolon = false; + print(";"); + }; + + function next_indent() { + return indentation + options.indent_level; + }; + + function with_block(cont) { + var ret; + print("{"); + newline(); + with_indent(next_indent(), function(){ + ret = cont(); + }); + indent(); + print("}"); + return ret; + }; + + function with_parens(cont) { + print("("); + //XXX: still nice to have that for argument lists + //var ret = with_indent(current_col, cont); + var ret = cont(); + print(")"); + return ret; + }; + + function with_square(cont) { + print("["); + //var ret = with_indent(current_col, cont); + var ret = cont(); + print("]"); + return ret; + }; + + function comma() { + print(","); + space(); + }; + + function colon() { + print(":"); + if (options.space_colon) space(); + }; + + var add_mapping = options.source_map ? function(token, name) { + try { + if (token) options.source_map.add( + token.file || "?", + current_line, current_col, + token.line, token.col, + (!name && token.type == "name") ? token.value : name + ); + } catch(ex) { + AST_Node.warn("Couldn't figure out mapping for {file}:{line},{col} → {cline},{ccol} [{name}]", { + file: token.file, + line: token.line, + col: token.col, + cline: current_line, + ccol: current_col, + name: name || "" + }) + } + } : noop; + + function get() { + return OUTPUT; + }; + + if (options.preamble) { + print(options.preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n")); + } + + var stack = []; + return { + get : get, + toString : get, + indent : indent, + indentation : function() { return indentation }, + current_width : function() { return current_col - indentation }, + should_break : function() { return options.width && this.current_width() >= options.width }, + newline : newline, + print : print, + space : space, + comma : comma, + colon : colon, + last : function() { return last }, + semicolon : semicolon, + force_semicolon : force_semicolon, + to_ascii : to_ascii, + print_name : function(name) { print(make_name(name)) }, + print_string : function(str, quote, escape_directive) { + var encoded = encode_string(str, quote); + if (escape_directive === true && encoded.indexOf("\\") === -1) { + // Insert semicolons to break directive prologue + if (!EXPECT_DIRECTIVE.test(OUTPUT)) { + force_semicolon(); + } + force_semicolon(); + } + print(encoded); + }, + encode_string : encode_string, + next_indent : next_indent, + with_indent : with_indent, + with_block : with_block, + with_parens : with_parens, + with_square : with_square, + add_mapping : add_mapping, + option : function(opt) { return options[opt] }, + comment_filter : comment_filter, + line : function() { return current_line }, + col : function() { return current_col }, + pos : function() { return current_pos }, + push_node : function(node) { stack.push(node) }, + pop_node : function() { return stack.pop() }, + stack : function() { return stack }, + parent : function(n) { + return stack[stack.length - 2 - (n || 0)]; + } + }; + +}; + +/* -----[ code generators ]----- */ + +(function(){ + + /* -----[ utils ]----- */ + + function DEFPRINT(nodetype, generator) { + nodetype.DEFMETHOD("_codegen", generator); + }; + + var use_asm = false; + var in_directive = false; + + AST_Node.DEFMETHOD("print", function(stream, force_parens){ + var self = this, generator = self._codegen, prev_use_asm = use_asm; + if (self instanceof AST_Directive && self.value == "use asm" && stream.parent() instanceof AST_Scope) { + use_asm = true; + } + function doit() { + self.add_comments(stream); + self.add_source_map(stream); + generator(self, stream); + } + stream.push_node(self); + if (force_parens || self.needs_parens(stream)) { + stream.with_parens(doit); + } else { + doit(); + } + stream.pop_node(); + if (self instanceof AST_Scope) { + use_asm = prev_use_asm; + } + }); + + AST_Node.DEFMETHOD("print_to_string", function(options){ + var s = OutputStream(options); + if (!options) s._readonly = true; + this.print(s); + return s.get(); + }); + + /* -----[ comments ]----- */ + + AST_Node.DEFMETHOD("add_comments", function(output){ + if (output._readonly) return; + var self = this; + var start = self.start; + if (start && !start._comments_dumped) { + start._comments_dumped = true; + var comments = start.comments_before || []; + + // XXX: ugly fix for https://github.com/mishoo/UglifyJS2/issues/112 + // and https://github.com/mishoo/UglifyJS2/issues/372 + if (self instanceof AST_Exit && self.value) { + self.value.walk(new TreeWalker(function(node){ + if (node.start && node.start.comments_before) { + comments = comments.concat(node.start.comments_before); + node.start.comments_before = []; + } + if (node instanceof AST_Function || + node instanceof AST_Array || + node instanceof AST_Object) + { + return true; // don't go inside. + } + })); + } + + comments = comments.filter(output.comment_filter, self); + + // Keep single line comments after nlb, after nlb + if (!output.option("beautify") && comments.length > 0 && + /comment[134]/.test(comments[0].type) && + output.col() !== 0 && comments[0].nlb) + { + output.print("\n"); + } + + comments.forEach(function(c){ + if (/comment[134]/.test(c.type)) { + output.print("//" + c.value + "\n"); + output.indent(); + } + else if (c.type == "comment2") { + output.print("/*" + c.value + "*/"); + if (start.nlb) { + output.print("\n"); + output.indent(); + } else { + output.space(); + } + } + else if (output.pos() === 0 && c.type == "comment5" && output.option("shebang")) { + output.print("#!" + c.value + "\n"); + output.indent(); + } + }); + } + }); + + /* -----[ PARENTHESES ]----- */ + + function PARENS(nodetype, func) { + if (Array.isArray(nodetype)) { + nodetype.forEach(function(nodetype){ + PARENS(nodetype, func); + }); + } else { + nodetype.DEFMETHOD("needs_parens", func); + } + }; + + PARENS(AST_Node, function(){ + return false; + }); + + // a function expression needs parens around it when it's provably + // the first token to appear in a statement. + PARENS(AST_Function, function(output){ + if (first_in_statement(output)) { + return true; + } + + if (output.option('wrap_iife')) { + var p = output.parent(); + return p instanceof AST_Call && p.expression === this; + } + + return false; + }); + + // same goes for an object literal, because otherwise it would be + // interpreted as a block of code. + PARENS(AST_Object, function(output){ + return first_in_statement(output); + }); + + PARENS([ AST_Unary, AST_Undefined ], function(output){ + var p = output.parent(); + return p instanceof AST_PropAccess && p.expression === this + || p instanceof AST_Call && p.expression === this; + }); + + PARENS(AST_Seq, function(output){ + var p = output.parent(); + return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4) + || p instanceof AST_Unary // !(foo, bar, baz) + || p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8 + || p instanceof AST_VarDef // var a = (1, 2), b = a + a; ==> b == 4 + || p instanceof AST_PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2 + || p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ] + || p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2 + || p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30) + * ==> 20 (side effect, set a := 10 and b := 20) */ + ; + }); + + PARENS(AST_Binary, function(output){ + var p = output.parent(); + // (foo && bar)() + if (p instanceof AST_Call && p.expression === this) + return true; + // typeof (foo && bar) + if (p instanceof AST_Unary) + return true; + // (foo && bar)["prop"], (foo && bar).prop + if (p instanceof AST_PropAccess && p.expression === this) + return true; + // this deals with precedence: 3 * (2 + 1) + if (p instanceof AST_Binary) { + var po = p.operator, pp = PRECEDENCE[po]; + var so = this.operator, sp = PRECEDENCE[so]; + if (pp > sp + || (pp == sp + && this === p.right)) { + return true; + } + } + }); + + PARENS(AST_PropAccess, function(output){ + var p = output.parent(); + if (p instanceof AST_New && p.expression === this) { + // i.e. new (foo.bar().baz) + // + // if there's one call into this subtree, then we need + // parens around it too, otherwise the call will be + // interpreted as passing the arguments to the upper New + // expression. + try { + this.walk(new TreeWalker(function(node){ + if (node instanceof AST_Call) throw p; + })); + } catch(ex) { + if (ex !== p) throw ex; + return true; + } + } + }); + + PARENS(AST_Call, function(output){ + var p = output.parent(), p1; + if (p instanceof AST_New && p.expression === this) + return true; + + // workaround for Safari bug. + // https://bugs.webkit.org/show_bug.cgi?id=123506 + return this.expression instanceof AST_Function + && p instanceof AST_PropAccess + && p.expression === this + && (p1 = output.parent(1)) instanceof AST_Assign + && p1.left === p; + }); + + PARENS(AST_New, function(output){ + var p = output.parent(); + if (!need_constructor_parens(this, output) + && (p instanceof AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]() + || p instanceof AST_Call && p.expression === this)) // (new foo)(bar) + return true; + }); + + PARENS(AST_Number, function(output){ + var p = output.parent(); + if (p instanceof AST_PropAccess && p.expression === this) { + var value = this.getValue(); + if (value < 0 || /^0/.test(make_num(value))) { + return true; + } + } + }); + + PARENS([ AST_Assign, AST_Conditional ], function (output){ + var p = output.parent(); + // !(a = false) → true + if (p instanceof AST_Unary) + return true; + // 1 + (a = 2) + 3 → 6, side effect setting a = 2 + if (p instanceof AST_Binary && !(p instanceof AST_Assign)) + return true; + // (a = func)() —or— new (a = Object)() + if (p instanceof AST_Call && p.expression === this) + return true; + // (a = foo) ? bar : baz + if (p instanceof AST_Conditional && p.condition === this) + return true; + // (a = foo)["prop"] —or— (a = foo).prop + if (p instanceof AST_PropAccess && p.expression === this) + return true; + }); + + /* -----[ PRINTERS ]----- */ + + DEFPRINT(AST_Directive, function(self, output){ + output.print_string(self.value, self.quote); + output.semicolon(); + }); + DEFPRINT(AST_Debugger, function(self, output){ + output.print("debugger"); + output.semicolon(); + }); + + /* -----[ statements ]----- */ + + function display_body(body, is_toplevel, output, allow_directives) { + var last = body.length - 1; + in_directive = allow_directives; + body.forEach(function(stmt, i){ + if (in_directive === true && !(stmt instanceof AST_Directive || + stmt instanceof AST_EmptyStatement || + (stmt instanceof AST_SimpleStatement && stmt.body instanceof AST_String) + )) { + in_directive = false; + } + if (!(stmt instanceof AST_EmptyStatement)) { + output.indent(); + stmt.print(output); + if (!(i == last && is_toplevel)) { + output.newline(); + if (is_toplevel) output.newline(); + } + } + if (in_directive === true && + stmt instanceof AST_SimpleStatement && + stmt.body instanceof AST_String + ) { + in_directive = false; + } + }); + in_directive = false; + }; + + AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output){ + force_statement(this.body, output); + }); + + DEFPRINT(AST_Statement, function(self, output){ + self.body.print(output); + output.semicolon(); + }); + DEFPRINT(AST_Toplevel, function(self, output){ + display_body(self.body, true, output, true); + output.print(""); + }); + DEFPRINT(AST_LabeledStatement, function(self, output){ + self.label.print(output); + output.colon(); + self.body.print(output); + }); + DEFPRINT(AST_SimpleStatement, function(self, output){ + self.body.print(output); + output.semicolon(); + }); + function print_bracketed(body, output, allow_directives) { + if (body.length > 0) output.with_block(function(){ + display_body(body, false, output, allow_directives); + }); + else output.print("{}"); + }; + DEFPRINT(AST_BlockStatement, function(self, output){ + print_bracketed(self.body, output); + }); + DEFPRINT(AST_EmptyStatement, function(self, output){ + output.semicolon(); + }); + DEFPRINT(AST_Do, function(self, output){ + output.print("do"); + output.space(); + self._do_print_body(output); + output.space(); + output.print("while"); + output.space(); + output.with_parens(function(){ + self.condition.print(output); + }); + output.semicolon(); + }); + DEFPRINT(AST_While, function(self, output){ + output.print("while"); + output.space(); + output.with_parens(function(){ + self.condition.print(output); + }); + output.space(); + self._do_print_body(output); + }); + DEFPRINT(AST_For, function(self, output){ + output.print("for"); + output.space(); + output.with_parens(function(){ + if (self.init && !(self.init instanceof AST_EmptyStatement)) { + if (self.init instanceof AST_Definitions) { + self.init.print(output); + } else { + parenthesize_for_noin(self.init, output, true); + } + output.print(";"); + output.space(); + } else { + output.print(";"); + } + if (self.condition) { + self.condition.print(output); + output.print(";"); + output.space(); + } else { + output.print(";"); + } + if (self.step) { + self.step.print(output); + } + }); + output.space(); + self._do_print_body(output); + }); + DEFPRINT(AST_ForIn, function(self, output){ + output.print("for"); + output.space(); + output.with_parens(function(){ + self.init.print(output); + output.space(); + output.print("in"); + output.space(); + self.object.print(output); + }); + output.space(); + self._do_print_body(output); + }); + DEFPRINT(AST_With, function(self, output){ + output.print("with"); + output.space(); + output.with_parens(function(){ + self.expression.print(output); + }); + output.space(); + self._do_print_body(output); + }); + + /* -----[ functions ]----- */ + AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword){ + var self = this; + if (!nokeyword) { + output.print("function"); + } + if (self.name) { + output.space(); + self.name.print(output); + } + output.with_parens(function(){ + self.argnames.forEach(function(arg, i){ + if (i) output.comma(); + arg.print(output); + }); + }); + output.space(); + print_bracketed(self.body, output, true); + }); + DEFPRINT(AST_Lambda, function(self, output){ + self._do_print(output); + }); + + /* -----[ exits ]----- */ + AST_Exit.DEFMETHOD("_do_print", function(output, kind){ + output.print(kind); + if (this.value) { + output.space(); + this.value.print(output); + } + output.semicolon(); + }); + DEFPRINT(AST_Return, function(self, output){ + self._do_print(output, "return"); + }); + DEFPRINT(AST_Throw, function(self, output){ + self._do_print(output, "throw"); + }); + + /* -----[ loop control ]----- */ + AST_LoopControl.DEFMETHOD("_do_print", function(output, kind){ + output.print(kind); + if (this.label) { + output.space(); + this.label.print(output); + } + output.semicolon(); + }); + DEFPRINT(AST_Break, function(self, output){ + self._do_print(output, "break"); + }); + DEFPRINT(AST_Continue, function(self, output){ + self._do_print(output, "continue"); + }); + + /* -----[ if ]----- */ + function make_then(self, output) { + if (output.option("bracketize")) { + make_block(self.body, output); + return; + } + // The squeezer replaces "block"-s that contain only a single + // statement with the statement itself; technically, the AST + // is correct, but this can create problems when we output an + // IF having an ELSE clause where the THEN clause ends in an + // IF *without* an ELSE block (then the outer ELSE would refer + // to the inner IF). This function checks for this case and + // adds the block brackets if needed. + if (!self.body) + return output.force_semicolon(); + if (self.body instanceof AST_Do) { + // Unconditionally use the if/do-while workaround for all browsers. + // https://github.com/mishoo/UglifyJS/issues/#issue/57 IE + // croaks with "syntax error" on code like this: if (foo) + // do ... while(cond); else ... we need block brackets + // around do/while + make_block(self.body, output); + return; + } + var b = self.body; + while (true) { + if (b instanceof AST_If) { + if (!b.alternative) { + make_block(self.body, output); + return; + } + b = b.alternative; + } + else if (b instanceof AST_StatementWithBody) { + b = b.body; + } + else break; + } + force_statement(self.body, output); + }; + DEFPRINT(AST_If, function(self, output){ + output.print("if"); + output.space(); + output.with_parens(function(){ + self.condition.print(output); + }); + output.space(); + if (self.alternative) { + make_then(self, output); + output.space(); + output.print("else"); + output.space(); + force_statement(self.alternative, output); + } else { + self._do_print_body(output); + } + }); + + /* -----[ switch ]----- */ + DEFPRINT(AST_Switch, function(self, output){ + output.print("switch"); + output.space(); + output.with_parens(function(){ + self.expression.print(output); + }); + output.space(); + if (self.body.length > 0) output.with_block(function(){ + self.body.forEach(function(stmt, i){ + if (i) output.newline(); + output.indent(true); + stmt.print(output); + }); + }); + else output.print("{}"); + }); + AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output){ + if (this.body.length > 0) { + output.newline(); + this.body.forEach(function(stmt){ + output.indent(); + stmt.print(output); + output.newline(); + }); + } + }); + DEFPRINT(AST_Default, function(self, output){ + output.print("default:"); + self._do_print_body(output); + }); + DEFPRINT(AST_Case, function(self, output){ + output.print("case"); + output.space(); + self.expression.print(output); + output.print(":"); + self._do_print_body(output); + }); + + /* -----[ exceptions ]----- */ + DEFPRINT(AST_Try, function(self, output){ + output.print("try"); + output.space(); + print_bracketed(self.body, output); + if (self.bcatch) { + output.space(); + self.bcatch.print(output); + } + if (self.bfinally) { + output.space(); + self.bfinally.print(output); + } + }); + DEFPRINT(AST_Catch, function(self, output){ + output.print("catch"); + output.space(); + output.with_parens(function(){ + self.argname.print(output); + }); + output.space(); + print_bracketed(self.body, output); + }); + DEFPRINT(AST_Finally, function(self, output){ + output.print("finally"); + output.space(); + print_bracketed(self.body, output); + }); + + /* -----[ var/const ]----- */ + AST_Definitions.DEFMETHOD("_do_print", function(output, kind){ + output.print(kind); + output.space(); + this.definitions.forEach(function(def, i){ + if (i) output.comma(); + def.print(output); + }); + var p = output.parent(); + var in_for = p instanceof AST_For || p instanceof AST_ForIn; + var avoid_semicolon = in_for && p.init === this; + if (!avoid_semicolon) + output.semicolon(); + }); + DEFPRINT(AST_Var, function(self, output){ + self._do_print(output, "var"); + }); + DEFPRINT(AST_Const, function(self, output){ + self._do_print(output, "const"); + }); + + function parenthesize_for_noin(node, output, noin) { + if (!noin) node.print(output); + else try { + // need to take some precautions here: + // https://github.com/mishoo/UglifyJS2/issues/60 + node.walk(new TreeWalker(function(node){ + if (node instanceof AST_Binary && node.operator == "in") + throw output; + })); + node.print(output); + } catch(ex) { + if (ex !== output) throw ex; + node.print(output, true); + } + }; + + DEFPRINT(AST_VarDef, function(self, output){ + self.name.print(output); + if (self.value) { + output.space(); + output.print("="); + output.space(); + var p = output.parent(1); + var noin = p instanceof AST_For || p instanceof AST_ForIn; + parenthesize_for_noin(self.value, output, noin); + } + }); + + /* -----[ other expressions ]----- */ + DEFPRINT(AST_Call, function(self, output){ + self.expression.print(output); + if (self instanceof AST_New && !need_constructor_parens(self, output)) + return; + output.with_parens(function(){ + self.args.forEach(function(expr, i){ + if (i) output.comma(); + expr.print(output); + }); + }); + }); + DEFPRINT(AST_New, function(self, output){ + output.print("new"); + output.space(); + AST_Call.prototype._codegen(self, output); + }); + + AST_Seq.DEFMETHOD("_do_print", function(output){ + this.car.print(output); + if (this.cdr) { + output.comma(); + if (output.should_break()) { + output.newline(); + output.indent(); + } + this.cdr.print(output); + } + }); + DEFPRINT(AST_Seq, function(self, output){ + self._do_print(output); + // var p = output.parent(); + // if (p instanceof AST_Statement) { + // output.with_indent(output.next_indent(), function(){ + // self._do_print(output); + // }); + // } else { + // self._do_print(output); + // } + }); + DEFPRINT(AST_Dot, function(self, output){ + var expr = self.expression; + expr.print(output); + if (expr instanceof AST_Number && expr.getValue() >= 0) { + if (!/[xa-f.)]/i.test(output.last())) { + output.print("."); + } + } + output.print("."); + // the name after dot would be mapped about here. + output.add_mapping(self.end); + output.print_name(self.property); + }); + DEFPRINT(AST_Sub, function(self, output){ + self.expression.print(output); + output.print("["); + self.property.print(output); + output.print("]"); + }); + DEFPRINT(AST_UnaryPrefix, function(self, output){ + var op = self.operator; + output.print(op); + if (/^[a-z]/i.test(op) + || (/[+-]$/.test(op) + && self.expression instanceof AST_UnaryPrefix + && /^[+-]/.test(self.expression.operator))) { + output.space(); + } + self.expression.print(output); + }); + DEFPRINT(AST_UnaryPostfix, function(self, output){ + self.expression.print(output); + output.print(self.operator); + }); + DEFPRINT(AST_Binary, function(self, output){ + var op = self.operator; + self.left.print(output); + if (op[0] == ">" /* ">>" ">>>" ">" ">=" */ + && self.left instanceof AST_UnaryPostfix + && self.left.operator == "--") { + // space is mandatory to avoid outputting --> + output.print(" "); + } else { + // the space is optional depending on "beautify" + output.space(); + } + output.print(op); + if ((op == "<" || op == "<<") + && self.right instanceof AST_UnaryPrefix + && self.right.operator == "!" + && self.right.expression instanceof AST_UnaryPrefix + && self.right.expression.operator == "--") { + // space is mandatory to avoid outputting ") && S.newline_before) { + forward(3); + skip_line_comment("comment4"); + continue; + } + } + var ch = peek(); + if (!ch) return token("eof"); + var code = ch.charCodeAt(0); + switch (code) { + case 34: case 39: return read_string(ch); + case 46: return handle_dot(); + case 47: { + var tok = handle_slash(); + if (tok === next_token) continue; + return tok; + } + } + if (is_digit(code)) return read_num(); + if (PUNC_CHARS(ch)) return token("punc", next()); + if (OPERATOR_CHARS(ch)) return read_operator(); + if (code == 92 || is_identifier_start(code)) return read_word(); + if (shebang) { + if (S.pos == 0 && looking_at("#!")) { + forward(2); + skip_line_comment("comment5"); + continue; + } + } + break; + } + parse_error("SyntaxError: Unexpected character '" + ch + "'"); + }; + + next_token.context = function(nc) { + if (nc) S = nc; + return S; + }; + + next_token.add_directive = function(directive) { + S.directive_stack[S.directive_stack.length - 1].push(directive); + + if (S.directives[directive] === undefined) { + S.directives[directive] = 1; + } else { + S.directives[directive]++; + } + } + + next_token.push_directives_stack = function() { + S.directive_stack.push([]); + } + + next_token.pop_directives_stack = function() { + var directives = S.directive_stack[S.directive_stack.length - 1]; + + for (var i = 0; i < directives.length; i++) { + S.directives[directives[i]]--; + } + + S.directive_stack.pop(); + } + + next_token.has_directive = function(directive) { + return S.directives[directive] !== undefined && + S.directives[directive] > 0; + } + + return next_token; + +}; + +/* -----[ Parser (constants) ]----- */ + +var UNARY_PREFIX = makePredicate([ + "typeof", + "void", + "delete", + "--", + "++", + "!", + "~", + "-", + "+" +]); + +var UNARY_POSTFIX = makePredicate([ "--", "++" ]); + +var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]); + +var PRECEDENCE = (function(a, ret){ + for (var i = 0; i < a.length; ++i) { + var b = a[i]; + for (var j = 0; j < b.length; ++j) { + ret[b[j]] = i + 1; + } + } + return ret; +})( + [ + ["||"], + ["&&"], + ["|"], + ["^"], + ["&"], + ["==", "===", "!=", "!=="], + ["<", ">", "<=", ">=", "in", "instanceof"], + [">>", "<<", ">>>"], + ["+", "-"], + ["*", "/", "%"] + ], + {} +); + +var STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ]); + +var ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]); + +/* -----[ Parser ]----- */ + +function parse($TEXT, options) { + + options = defaults(options, { + strict : false, + filename : null, + toplevel : null, + expression : false, + html5_comments : true, + bare_returns : false, + shebang : true, + }); + + var S = { + input : (typeof $TEXT == "string" + ? tokenizer($TEXT, options.filename, + options.html5_comments, options.shebang) + : $TEXT), + token : null, + prev : null, + peeked : null, + in_function : 0, + in_directives : true, + in_loop : 0, + labels : [] + }; + + S.token = next(); + + function is(type, value) { + return is_token(S.token, type, value); + }; + + function peek() { return S.peeked || (S.peeked = S.input()); }; + + function next() { + S.prev = S.token; + if (S.peeked) { + S.token = S.peeked; + S.peeked = null; + } else { + S.token = S.input(); + } + S.in_directives = S.in_directives && ( + S.token.type == "string" || is("punc", ";") + ); + return S.token; + }; + + function prev() { + return S.prev; + }; + + function croak(msg, line, col, pos) { + var ctx = S.input.context(); + js_error(msg, + ctx.filename, + line != null ? line : ctx.tokline, + col != null ? col : ctx.tokcol, + pos != null ? pos : ctx.tokpos); + }; + + function token_error(token, msg) { + croak(msg, token.line, token.col); + }; + + function unexpected(token) { + if (token == null) + token = S.token; + token_error(token, "SyntaxError: Unexpected token: " + token.type + " (" + token.value + ")"); + }; + + function expect_token(type, val) { + if (is(type, val)) { + return next(); + } + token_error(S.token, "SyntaxError: Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»"); + }; + + function expect(punc) { return expect_token("punc", punc); }; + + function can_insert_semicolon() { + return !options.strict && ( + S.token.nlb || is("eof") || is("punc", "}") + ); + }; + + function semicolon(optional) { + if (is("punc", ";")) next(); + else if (!optional && !can_insert_semicolon()) unexpected(); + }; + + function parenthesised() { + expect("("); + var exp = expression(true); + expect(")"); + return exp; + }; + + function embed_tokens(parser) { + return function() { + var start = S.token; + var expr = parser(); + var end = prev(); + expr.start = start; + expr.end = end; + return expr; + }; + }; + + function handle_regexp() { + if (is("operator", "/") || is("operator", "/=")) { + S.peeked = null; + S.token = S.input(S.token.value.substr(1)); // force regexp + } + }; + + var statement = embed_tokens(function() { + var tmp; + handle_regexp(); + switch (S.token.type) { + case "string": + var dir = false; + if (S.in_directives === true) { + if ((is_token(peek(), "punc", ";") || peek().nlb) && S.token.raw.indexOf("\\") === -1) { + S.input.add_directive(S.token.value); + } else { + S.in_directives = false; + } + } + var dir = S.in_directives, stat = simple_statement(); + if (dir) { + return new AST_Directive({ + start : stat.body.start, + end : stat.body.end, + quote : stat.body.quote, + value : stat.body.value, + }); + } + return stat; + case "num": + case "regexp": + case "operator": + case "atom": + return simple_statement(); + + case "name": + return is_token(peek(), "punc", ":") + ? labeled_statement() + : simple_statement(); + + case "punc": + switch (S.token.value) { + case "{": + return new AST_BlockStatement({ + start : S.token, + body : block_(), + end : prev() + }); + case "[": + case "(": + return simple_statement(); + case ";": + S.in_directives = false; + next(); + return new AST_EmptyStatement(); + default: + unexpected(); + } + + case "keyword": + switch (tmp = S.token.value, next(), tmp) { + case "break": + return break_cont(AST_Break); + + case "continue": + return break_cont(AST_Continue); + + case "debugger": + semicolon(); + return new AST_Debugger(); + + case "do": + return new AST_Do({ + body : in_loop(statement), + condition : (expect_token("keyword", "while"), tmp = parenthesised(), semicolon(true), tmp) + }); + + case "while": + return new AST_While({ + condition : parenthesised(), + body : in_loop(statement) + }); + + case "for": + return for_(); + + case "function": + return function_(AST_Defun); + + case "if": + return if_(); + + case "return": + if (S.in_function == 0 && !options.bare_returns) + croak("SyntaxError: 'return' outside of function"); + return new AST_Return({ + value: ( is("punc", ";") + ? (next(), null) + : can_insert_semicolon() + ? null + : (tmp = expression(true), semicolon(), tmp) ) + }); + + case "switch": + return new AST_Switch({ + expression : parenthesised(), + body : in_loop(switch_body_) + }); + + case "throw": + if (S.token.nlb) + croak("SyntaxError: Illegal newline after 'throw'"); + return new AST_Throw({ + value: (tmp = expression(true), semicolon(), tmp) + }); + + case "try": + return try_(); + + case "var": + return tmp = var_(), semicolon(), tmp; + + case "const": + return tmp = const_(), semicolon(), tmp; + + case "with": + if (S.input.has_directive("use strict")) { + croak("SyntaxError: Strict mode may not include a with statement"); + } + return new AST_With({ + expression : parenthesised(), + body : statement() + }); + + default: + unexpected(); + } + } + }); + + function labeled_statement() { + var label = as_symbol(AST_Label); + if (find_if(function(l){ return l.name == label.name }, S.labels)) { + // ECMA-262, 12.12: An ECMAScript program is considered + // syntactically incorrect if it contains a + // LabelledStatement that is enclosed by a + // LabelledStatement with the same Identifier as label. + croak("SyntaxError: Label " + label.name + " defined twice"); + } + expect(":"); + S.labels.push(label); + var stat = statement(); + S.labels.pop(); + if (!(stat instanceof AST_IterationStatement)) { + // check for `continue` that refers to this label. + // those should be reported as syntax errors. + // https://github.com/mishoo/UglifyJS2/issues/287 + label.references.forEach(function(ref){ + if (ref instanceof AST_Continue) { + ref = ref.label.start; + croak("SyntaxError: Continue label `" + label.name + "` refers to non-IterationStatement.", + ref.line, ref.col, ref.pos); + } + }); + } + return new AST_LabeledStatement({ body: stat, label: label }); + }; + + function simple_statement(tmp) { + return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) }); + }; + + function break_cont(type) { + var label = null, ldef; + if (!can_insert_semicolon()) { + label = as_symbol(AST_LabelRef, true); + } + if (label != null) { + ldef = find_if(function(l){ return l.name == label.name }, S.labels); + if (!ldef) + croak("SyntaxError: Undefined label " + label.name); + label.thedef = ldef; + } + else if (S.in_loop == 0) + croak("SyntaxError: " + type.TYPE + " not inside a loop or switch"); + semicolon(); + var stat = new type({ label: label }); + if (ldef) ldef.references.push(stat); + return stat; + }; + + function for_() { + expect("("); + var init = null; + if (!is("punc", ";")) { + init = is("keyword", "var") + ? (next(), var_(true)) + : expression(true, true); + if (is("operator", "in")) { + if (init instanceof AST_Var && init.definitions.length > 1) + croak("SyntaxError: Only one variable declaration allowed in for..in loop"); + next(); + return for_in(init); + } + } + return regular_for(init); + }; + + function regular_for(init) { + expect(";"); + var test = is("punc", ";") ? null : expression(true); + expect(";"); + var step = is("punc", ")") ? null : expression(true); + expect(")"); + return new AST_For({ + init : init, + condition : test, + step : step, + body : in_loop(statement) + }); + }; + + function for_in(init) { + var lhs = init instanceof AST_Var ? init.definitions[0].name : null; + var obj = expression(true); + expect(")"); + return new AST_ForIn({ + init : init, + name : lhs, + object : obj, + body : in_loop(statement) + }); + }; + + var function_ = function(ctor) { + var in_statement = ctor === AST_Defun; + var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null; + if (in_statement && !name) + unexpected(); + expect("("); + return new ctor({ + name: name, + argnames: (function(first, a){ + while (!is("punc", ")")) { + if (first) first = false; else expect(","); + a.push(as_symbol(AST_SymbolFunarg)); + } + next(); + return a; + })(true, []), + body: (function(loop, labels){ + ++S.in_function; + S.in_directives = true; + S.input.push_directives_stack(); + S.in_loop = 0; + S.labels = []; + var a = block_(); + S.input.pop_directives_stack(); + --S.in_function; + S.in_loop = loop; + S.labels = labels; + return a; + })(S.in_loop, S.labels) + }); + }; + + function if_() { + var cond = parenthesised(), body = statement(), belse = null; + if (is("keyword", "else")) { + next(); + belse = statement(); + } + return new AST_If({ + condition : cond, + body : body, + alternative : belse + }); + }; + + function block_() { + expect("{"); + var a = []; + while (!is("punc", "}")) { + if (is("eof")) unexpected(); + a.push(statement()); + } + next(); + return a; + }; + + function switch_body_() { + expect("{"); + var a = [], cur = null, branch = null, tmp; + while (!is("punc", "}")) { + if (is("eof")) unexpected(); + if (is("keyword", "case")) { + if (branch) branch.end = prev(); + cur = []; + branch = new AST_Case({ + start : (tmp = S.token, next(), tmp), + expression : expression(true), + body : cur + }); + a.push(branch); + expect(":"); + } + else if (is("keyword", "default")) { + if (branch) branch.end = prev(); + cur = []; + branch = new AST_Default({ + start : (tmp = S.token, next(), expect(":"), tmp), + body : cur + }); + a.push(branch); + } + else { + if (!cur) unexpected(); + cur.push(statement()); + } + } + if (branch) branch.end = prev(); + next(); + return a; + }; + + function try_() { + var body = block_(), bcatch = null, bfinally = null; + if (is("keyword", "catch")) { + var start = S.token; + next(); + expect("("); + var name = as_symbol(AST_SymbolCatch); + expect(")"); + bcatch = new AST_Catch({ + start : start, + argname : name, + body : block_(), + end : prev() + }); + } + if (is("keyword", "finally")) { + var start = S.token; + next(); + bfinally = new AST_Finally({ + start : start, + body : block_(), + end : prev() + }); + } + if (!bcatch && !bfinally) + croak("SyntaxError: Missing catch/finally blocks"); + return new AST_Try({ + body : body, + bcatch : bcatch, + bfinally : bfinally + }); + }; + + function vardefs(no_in, in_const) { + var a = []; + for (;;) { + a.push(new AST_VarDef({ + start : S.token, + name : as_symbol(in_const ? AST_SymbolConst : AST_SymbolVar), + value : is("operator", "=") ? (next(), expression(false, no_in)) : null, + end : prev() + })); + if (!is("punc", ",")) + break; + next(); + } + return a; + }; + + var var_ = function(no_in) { + return new AST_Var({ + start : prev(), + definitions : vardefs(no_in, false), + end : prev() + }); + }; + + var const_ = function() { + return new AST_Const({ + start : prev(), + definitions : vardefs(false, true), + end : prev() + }); + }; + + var new_ = function(allow_calls) { + var start = S.token; + expect_token("operator", "new"); + var newexp = expr_atom(false), args; + if (is("punc", "(")) { + next(); + args = expr_list(")"); + } else { + args = []; + } + return subscripts(new AST_New({ + start : start, + expression : newexp, + args : args, + end : prev() + }), allow_calls); + }; + + function as_atom_node() { + var tok = S.token, ret; + switch (tok.type) { + case "name": + case "keyword": + ret = _make_symbol(AST_SymbolRef); + break; + case "num": + ret = new AST_Number({ start: tok, end: tok, value: tok.value }); + break; + case "string": + ret = new AST_String({ + start : tok, + end : tok, + value : tok.value, + quote : tok.quote + }); + break; + case "regexp": + ret = new AST_RegExp({ start: tok, end: tok, value: tok.value }); + break; + case "atom": + switch (tok.value) { + case "false": + ret = new AST_False({ start: tok, end: tok }); + break; + case "true": + ret = new AST_True({ start: tok, end: tok }); + break; + case "null": + ret = new AST_Null({ start: tok, end: tok }); + break; + } + break; + case "operator": + if (!is_identifier_string(tok.value)) { + croak("SyntaxError: Invalid getter/setter name: " + tok.value, + tok.line, tok.col, tok.pos); + } + ret = _make_symbol(AST_SymbolRef); + break; + } + next(); + return ret; + }; + + var expr_atom = function(allow_calls) { + if (is("operator", "new")) { + return new_(allow_calls); + } + var start = S.token; + if (is("punc")) { + switch (start.value) { + case "(": + next(); + var ex = expression(true); + ex.start = start; + ex.end = S.token; + expect(")"); + return subscripts(ex, allow_calls); + case "[": + return subscripts(array_(), allow_calls); + case "{": + return subscripts(object_(), allow_calls); + } + unexpected(); + } + if (is("keyword", "function")) { + next(); + var func = function_(AST_Function); + func.start = start; + func.end = prev(); + return subscripts(func, allow_calls); + } + if (ATOMIC_START_TOKEN[S.token.type]) { + return subscripts(as_atom_node(), allow_calls); + } + unexpected(); + }; + + function expr_list(closing, allow_trailing_comma, allow_empty) { + var first = true, a = []; + while (!is("punc", closing)) { + if (first) first = false; else expect(","); + if (allow_trailing_comma && is("punc", closing)) break; + if (is("punc", ",") && allow_empty) { + a.push(new AST_Hole({ start: S.token, end: S.token })); + } else { + a.push(expression(false)); + } + } + next(); + return a; + }; + + var array_ = embed_tokens(function() { + expect("["); + return new AST_Array({ + elements: expr_list("]", !options.strict, true) + }); + }); + + var object_ = embed_tokens(function() { + expect("{"); + var first = true, a = []; + while (!is("punc", "}")) { + if (first) first = false; else expect(","); + if (!options.strict && is("punc", "}")) + // allow trailing comma + break; + var start = S.token; + var type = start.type; + var name = as_property_name(); + if (type == "name" && !is("punc", ":")) { + if (name == "get") { + a.push(new AST_ObjectGetter({ + start : start, + key : as_atom_node(), + value : function_(AST_Accessor), + end : prev() + })); + continue; + } + if (name == "set") { + a.push(new AST_ObjectSetter({ + start : start, + key : as_atom_node(), + value : function_(AST_Accessor), + end : prev() + })); + continue; + } + } + expect(":"); + a.push(new AST_ObjectKeyVal({ + start : start, + quote : start.quote, + key : name, + value : expression(false), + end : prev() + })); + } + next(); + return new AST_Object({ properties: a }); + }); + + function as_property_name() { + var tmp = S.token; + next(); + switch (tmp.type) { + case "num": + case "string": + case "name": + case "operator": + case "keyword": + case "atom": + return tmp.value; + default: + unexpected(); + } + }; + + function as_name() { + var tmp = S.token; + next(); + switch (tmp.type) { + case "name": + case "operator": + case "keyword": + case "atom": + return tmp.value; + default: + unexpected(); + } + }; + + function _make_symbol(type) { + var name = S.token.value; + return new (name == "this" ? AST_This : type)({ + name : String(name), + start : S.token, + end : S.token + }); + }; + + function as_symbol(type, noerror) { + if (!is("name")) { + if (!noerror) croak("SyntaxError: Name expected"); + return null; + } + var sym = _make_symbol(type); + next(); + return sym; + }; + + var subscripts = function(expr, allow_calls) { + var start = expr.start; + if (is("punc", ".")) { + next(); + return subscripts(new AST_Dot({ + start : start, + expression : expr, + property : as_name(), + end : prev() + }), allow_calls); + } + if (is("punc", "[")) { + next(); + var prop = expression(true); + expect("]"); + return subscripts(new AST_Sub({ + start : start, + expression : expr, + property : prop, + end : prev() + }), allow_calls); + } + if (allow_calls && is("punc", "(")) { + next(); + return subscripts(new AST_Call({ + start : start, + expression : expr, + args : expr_list(")"), + end : prev() + }), true); + } + return expr; + }; + + var maybe_unary = function(allow_calls) { + var start = S.token; + if (is("operator") && UNARY_PREFIX(start.value)) { + next(); + handle_regexp(); + var ex = make_unary(AST_UnaryPrefix, start.value, maybe_unary(allow_calls)); + ex.start = start; + ex.end = prev(); + return ex; + } + var val = expr_atom(allow_calls); + while (is("operator") && UNARY_POSTFIX(S.token.value) && !S.token.nlb) { + val = make_unary(AST_UnaryPostfix, S.token.value, val); + val.start = start; + val.end = S.token; + next(); + } + return val; + }; + + function make_unary(ctor, op, expr) { + if ((op == "++" || op == "--") && !is_assignable(expr)) + croak("SyntaxError: Invalid use of " + op + " operator"); + return new ctor({ operator: op, expression: expr }); + }; + + var expr_op = function(left, min_prec, no_in) { + var op = is("operator") ? S.token.value : null; + if (op == "in" && no_in) op = null; + var prec = op != null ? PRECEDENCE[op] : null; + if (prec != null && prec > min_prec) { + next(); + var right = expr_op(maybe_unary(true), prec, no_in); + return expr_op(new AST_Binary({ + start : left.start, + left : left, + operator : op, + right : right, + end : right.end + }), min_prec, no_in); + } + return left; + }; + + function expr_ops(no_in) { + return expr_op(maybe_unary(true), 0, no_in); + }; + + var maybe_conditional = function(no_in) { + var start = S.token; + var expr = expr_ops(no_in); + if (is("operator", "?")) { + next(); + var yes = expression(false); + expect(":"); + return new AST_Conditional({ + start : start, + condition : expr, + consequent : yes, + alternative : expression(false, no_in), + end : prev() + }); + } + return expr; + }; + + function is_assignable(expr) { + if (!options.strict) return true; + if (expr instanceof AST_This) return false; + return (expr instanceof AST_PropAccess || expr instanceof AST_Symbol); + }; + + var maybe_assign = function(no_in) { + var start = S.token; + var left = maybe_conditional(no_in), val = S.token.value; + if (is("operator") && ASSIGNMENT(val)) { + if (is_assignable(left)) { + next(); + return new AST_Assign({ + start : start, + left : left, + operator : val, + right : maybe_assign(no_in), + end : prev() + }); + } + croak("SyntaxError: Invalid assignment"); + } + return left; + }; + + var expression = function(commas, no_in) { + var start = S.token; + var expr = maybe_assign(no_in); + if (commas && is("punc", ",")) { + next(); + return new AST_Seq({ + start : start, + car : expr, + cdr : expression(true, no_in), + end : peek() + }); + } + return expr; + }; + + function in_loop(cont) { + ++S.in_loop; + var ret = cont(); + --S.in_loop; + return ret; + }; + + if (options.expression) { + return expression(true); + } + + return (function(){ + var start = S.token; + var body = []; + S.input.push_directives_stack(); + while (!is("eof")) + body.push(statement()); + S.input.pop_directives_stack(); + var end = prev(); + var toplevel = options.toplevel; + if (toplevel) { + toplevel.body = toplevel.body.concat(body); + toplevel.end = end; + } else { + toplevel = new AST_Toplevel({ start: start, body: body, end: end }); + } + return toplevel; + })(); + +}; diff --git a/node_modules/uglify-js/lib/propmangle.js b/node_modules/uglify-js/lib/propmangle.js new file mode 100644 index 0000000..f277747 --- /dev/null +++ b/node_modules/uglify-js/lib/propmangle.js @@ -0,0 +1,256 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +function find_builtins() { + var a = []; + [ Object, Array, Function, Number, + String, Boolean, Error, Math, + Date, RegExp + ].forEach(function(ctor){ + Object.getOwnPropertyNames(ctor).map(add); + if (ctor.prototype) { + Object.getOwnPropertyNames(ctor.prototype).map(add); + } + }); + function add(name) { + push_uniq(a, name); + } + return a; +} + +function mangle_properties(ast, options) { + options = defaults(options, { + reserved : null, + cache : null, + only_cache : false, + regex : null, + ignore_quoted : false, + debug : false + }); + + var reserved = options.reserved; + if (reserved == null) + reserved = find_builtins(); + + var cache = options.cache; + if (cache == null) { + cache = { + cname: -1, + props: new Dictionary() + }; + } + + var regex = options.regex; + var ignore_quoted = options.ignore_quoted; + + // note debug is either false (disabled), or a string of the debug suffix to use (enabled). + // note debug may be enabled as an empty string, which is falsey. Also treat passing 'true' + // the same as passing an empty string. + var debug = (options.debug !== false); + var debug_name_suffix; + if (debug) { + debug_name_suffix = (options.debug === true ? "" : options.debug); + } + + var names_to_mangle = []; + var unmangleable = []; + var ignored = {}; + + // step 1: find candidates to mangle + ast.walk(new TreeWalker(function(node){ + if (node instanceof AST_ObjectKeyVal) { + add(node.key, ignore_quoted && node.quote); + } + else if (node instanceof AST_ObjectProperty) { + // setter or getter, since KeyVal is handled above + add(node.key.name); + } + else if (node instanceof AST_Dot) { + add(node.property); + } + else if (node instanceof AST_Sub) { + addStrings(node.property, ignore_quoted); + } + })); + + // step 2: transform the tree, renaming properties + return ast.transform(new TreeTransformer(function(node){ + if (node instanceof AST_ObjectKeyVal) { + if (!(ignore_quoted && node.quote)) + node.key = mangle(node.key); + } + else if (node instanceof AST_ObjectProperty) { + // setter or getter + node.key.name = mangle(node.key.name); + } + else if (node instanceof AST_Dot) { + node.property = mangle(node.property); + } + else if (node instanceof AST_Sub) { + if (!ignore_quoted) + node.property = mangleStrings(node.property); + } + // else if (node instanceof AST_String) { + // if (should_mangle(node.value)) { + // AST_Node.warn( + // "Found \"{prop}\" property candidate for mangling in an arbitrary string [{file}:{line},{col}]", { + // file : node.start.file, + // line : node.start.line, + // col : node.start.col, + // prop : node.value + // } + // ); + // } + // } + })); + + // only function declarations after this line + + function can_mangle(name) { + if (unmangleable.indexOf(name) >= 0) return false; + if (reserved.indexOf(name) >= 0) return false; + if (options.only_cache) { + return cache.props.has(name); + } + if (/^[0-9.]+$/.test(name)) return false; + return true; + } + + function should_mangle(name) { + if (ignore_quoted && name in ignored) return false; + if (regex && !regex.test(name)) return false; + if (reserved.indexOf(name) >= 0) return false; + return cache.props.has(name) + || names_to_mangle.indexOf(name) >= 0; + } + + function add(name, ignore) { + if (ignore) { + ignored[name] = true; + return; + } + + if (can_mangle(name)) + push_uniq(names_to_mangle, name); + + if (!should_mangle(name)) { + push_uniq(unmangleable, name); + } + } + + function mangle(name) { + if (!should_mangle(name)) { + return name; + } + + var mangled = cache.props.get(name); + if (!mangled) { + if (debug) { + // debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_. + var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_"; + + if (can_mangle(debug_mangled) && !(ignore_quoted && debug_mangled in ignored)) { + mangled = debug_mangled; + } + } + + // either debug mode is off, or it is on and we could not use the mangled name + if (!mangled) { + // note can_mangle() does not check if the name collides with the 'ignored' set + // (filled with quoted properties when ignore_quoted set). Make sure we add this + // check so we don't collide with a quoted name. + do { + mangled = base54(++cache.cname); + } while (!can_mangle(mangled) || (ignore_quoted && mangled in ignored)); + } + + cache.props.set(name, mangled); + } + return mangled; + } + + function addStrings(node, ignore) { + var out = {}; + try { + (function walk(node){ + node.walk(new TreeWalker(function(node){ + if (node instanceof AST_Seq) { + walk(node.cdr); + return true; + } + if (node instanceof AST_String) { + add(node.value, ignore); + return true; + } + if (node instanceof AST_Conditional) { + walk(node.consequent); + walk(node.alternative); + return true; + } + throw out; + })); + })(node); + } catch(ex) { + if (ex !== out) throw ex; + } + } + + function mangleStrings(node) { + return node.transform(new TreeTransformer(function(node){ + if (node instanceof AST_Seq) { + node.cdr = mangleStrings(node.cdr); + } + else if (node instanceof AST_String) { + node.value = mangle(node.value); + } + else if (node instanceof AST_Conditional) { + node.consequent = mangleStrings(node.consequent); + node.alternative = mangleStrings(node.alternative); + } + return node; + })); + } + +} diff --git a/node_modules/uglify-js/lib/scope.js b/node_modules/uglify-js/lib/scope.js new file mode 100644 index 0000000..4943b56 --- /dev/null +++ b/node_modules/uglify-js/lib/scope.js @@ -0,0 +1,644 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +function SymbolDef(scope, index, orig) { + this.name = orig.name; + this.orig = [ orig ]; + this.scope = scope; + this.references = []; + this.global = false; + this.mangled_name = null; + this.undeclared = false; + this.constant = false; + this.index = index; + this.id = SymbolDef.next_id++; +}; + +SymbolDef.next_id = 1; + +SymbolDef.prototype = { + unmangleable: function(options) { + if (!options) options = {}; + + return (this.global && !options.toplevel) + || this.undeclared + || (!options.eval && (this.scope.uses_eval || this.scope.uses_with)) + || (options.keep_fnames + && (this.orig[0] instanceof AST_SymbolLambda + || this.orig[0] instanceof AST_SymbolDefun)); + }, + mangle: function(options) { + var cache = options.cache && options.cache.props; + if (this.global && cache && cache.has(this.name)) { + this.mangled_name = cache.get(this.name); + } + else if (!this.mangled_name && !this.unmangleable(options)) { + var s = this.scope; + if (!options.screw_ie8 && this.orig[0] instanceof AST_SymbolLambda) + s = s.parent_scope; + this.mangled_name = s.next_mangled(options, this); + if (this.global && cache) { + cache.set(this.name, this.mangled_name); + } + } + } +}; + +AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ + options = defaults(options, { + screw_ie8: true, + cache: null + }); + + // pass 1: setup scope chaining and handle definitions + var self = this; + var scope = self.parent_scope = null; + var labels = new Dictionary(); + var defun = null; + var last_var_had_const_pragma = false; + var nesting = 0; + var tw = new TreeWalker(function(node, descend){ + if (options.screw_ie8 && node instanceof AST_Catch) { + var save_scope = scope; + scope = new AST_Scope(node); + scope.init_scope_vars(nesting); + scope.parent_scope = save_scope; + descend(); + scope = save_scope; + return true; + } + if (node instanceof AST_Scope) { + node.init_scope_vars(nesting); + var save_scope = node.parent_scope = scope; + var save_defun = defun; + var save_labels = labels; + defun = scope = node; + labels = new Dictionary(); + ++nesting; descend(); --nesting; + scope = save_scope; + defun = save_defun; + labels = save_labels; + return true; // don't descend again in TreeWalker + } + if (node instanceof AST_LabeledStatement) { + var l = node.label; + if (labels.has(l.name)) { + throw new Error(string_template("Label {name} defined twice", l)); + } + labels.set(l.name, l); + descend(); + labels.del(l.name); + return true; // no descend again + } + if (node instanceof AST_With) { + for (var s = scope; s; s = s.parent_scope) + s.uses_with = true; + return; + } + if (node instanceof AST_Symbol) { + node.scope = scope; + } + if (node instanceof AST_Label) { + node.thedef = node; + node.references = []; + } + if (node instanceof AST_SymbolLambda) { + defun.def_function(node); + } + else if (node instanceof AST_SymbolDefun) { + // Careful here, the scope where this should be defined is + // the parent scope. The reason is that we enter a new + // scope when we encounter the AST_Defun node (which is + // instanceof AST_Scope) but we get to the symbol a bit + // later. + (node.scope = defun.parent_scope).def_function(node); + } + else if (node instanceof AST_Var) { + last_var_had_const_pragma = node.has_const_pragma(); + } + else if (node instanceof AST_SymbolVar + || node instanceof AST_SymbolConst) { + var def = defun.def_variable(node); + def.constant = node instanceof AST_SymbolConst || last_var_had_const_pragma; + def.init = tw.parent().value; + } + else if (node instanceof AST_SymbolCatch) { + (options.screw_ie8 ? scope : defun) + .def_variable(node); + } + else if (node instanceof AST_LabelRef) { + var sym = labels.get(node.name); + if (!sym) throw new Error(string_template("Undefined label {name} [{line},{col}]", { + name: node.name, + line: node.start.line, + col: node.start.col + })); + node.thedef = sym; + } + }); + self.walk(tw); + + // pass 2: find back references and eval + var func = null; + var globals = self.globals = new Dictionary(); + var tw = new TreeWalker(function(node, descend){ + if (node instanceof AST_Lambda) { + var prev_func = func; + func = node; + descend(); + func = prev_func; + return true; + } + if (node instanceof AST_LoopControl && node.label) { + node.label.thedef.references.push(node); + return true; + } + if (node instanceof AST_SymbolRef) { + var name = node.name; + var parent = tw.parent(); + if (name == "eval" && parent instanceof AST_Call) { + for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) { + s.uses_eval = true; + } + } + var sym = node.scope.find_variable(name); + if (node.scope instanceof AST_Lambda && name == "arguments") { + node.scope.uses_arguments = true; + } + if (!sym) { + var g; + if (globals.has(name)) { + g = globals.get(name); + } else { + g = new SymbolDef(self, globals.size(), node); + g.undeclared = true; + g.global = true; + globals.set(name, g); + } + sym = g; + } + node.thedef = sym; + if (parent instanceof AST_Unary && (parent.operator === '++' || parent.operator === '--') + || parent instanceof AST_Assign && parent.left === node) { + sym.modified = true; + } + node.reference(); + return true; + } + }); + self.walk(tw); + + if (options.cache) { + this.cname = options.cache.cname; + } +}); + +AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){ + this.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions) + this.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope) + this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement + this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval` + this.parent_scope = null; // the parent scope + this.enclosed = []; // a list of variables from this or outer scope(s) that are referenced from this or inner scopes + this.cname = -1; // the current index for mangling functions/variables + this.nesting = nesting; // the nesting level of this scope (0 means toplevel) +}); + +AST_Lambda.DEFMETHOD("init_scope_vars", function(){ + AST_Scope.prototype.init_scope_vars.apply(this, arguments); + this.uses_arguments = false; + + var symbol = new AST_VarDef({ name: "arguments", start: this.start, end: this.end }); + var def = new SymbolDef(this, this.variables.size(), symbol); + this.variables.set(symbol.name, def); +}); + +AST_SymbolRef.DEFMETHOD("reference", function() { + var def = this.definition(); + def.references.push(this); + var s = this.scope; + while (s) { + push_uniq(s.enclosed, def); + if (s === def.scope) break; + s = s.parent_scope; + } + this.frame = this.scope.nesting - def.scope.nesting; +}); + +AST_Scope.DEFMETHOD("find_variable", function(name){ + if (name instanceof AST_Symbol) name = name.name; + return this.variables.get(name) + || (this.parent_scope && this.parent_scope.find_variable(name)); +}); + +AST_Scope.DEFMETHOD("def_function", function(symbol){ + this.functions.set(symbol.name, this.def_variable(symbol)); +}); + +AST_Scope.DEFMETHOD("def_variable", function(symbol){ + var def; + if (!this.variables.has(symbol.name)) { + def = new SymbolDef(this, this.variables.size(), symbol); + this.variables.set(symbol.name, def); + def.global = !this.parent_scope; + } else { + def = this.variables.get(symbol.name); + def.orig.push(symbol); + } + return symbol.thedef = def; +}); + +AST_Scope.DEFMETHOD("next_mangled", function(options){ + var ext = this.enclosed; + out: while (true) { + var m = base54(++this.cname); + if (!is_identifier(m)) continue; // skip over "do" + + // https://github.com/mishoo/UglifyJS2/issues/242 -- do not + // shadow a name excepted from mangling. + if (options.except.indexOf(m) >= 0) continue; + + // we must ensure that the mangled name does not shadow a name + // from some parent scope that is referenced in this or in + // inner scopes. + for (var i = ext.length; --i >= 0;) { + var sym = ext[i]; + var name = sym.mangled_name || (sym.unmangleable(options) && sym.name); + if (m == name) continue out; + } + return m; + } +}); + +AST_Function.DEFMETHOD("next_mangled", function(options, def){ + // #179, #326 + // in Safari strict mode, something like (function x(x){...}) is a syntax error; + // a function expression's argument cannot shadow the function expression's name + + var tricky_def = def.orig[0] instanceof AST_SymbolFunarg && this.name && this.name.definition(); + + // the function's mangled_name is null when keep_fnames is true + var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null; + + while (true) { + var name = AST_Lambda.prototype.next_mangled.call(this, options, def); + if (!tricky_name || tricky_name != name) + return name; + } +}); + +AST_Scope.DEFMETHOD("references", function(sym){ + if (sym instanceof AST_Symbol) sym = sym.definition(); + return this.enclosed.indexOf(sym) < 0 ? null : sym; +}); + +AST_Symbol.DEFMETHOD("unmangleable", function(options){ + return this.definition().unmangleable(options); +}); + +// property accessors are not mangleable +AST_SymbolAccessor.DEFMETHOD("unmangleable", function(){ + return true; +}); + +// labels are always mangleable +AST_Label.DEFMETHOD("unmangleable", function(){ + return false; +}); + +AST_Symbol.DEFMETHOD("unreferenced", function(){ + return this.definition().references.length == 0 + && !(this.scope.uses_eval || this.scope.uses_with); +}); + +AST_Symbol.DEFMETHOD("undeclared", function(){ + return this.definition().undeclared; +}); + +AST_LabelRef.DEFMETHOD("undeclared", function(){ + return false; +}); + +AST_Label.DEFMETHOD("undeclared", function(){ + return false; +}); + +AST_Symbol.DEFMETHOD("definition", function(){ + return this.thedef; +}); + +AST_Symbol.DEFMETHOD("global", function(){ + return this.definition().global; +}); + +AST_Var.DEFMETHOD("has_const_pragma", function() { + var comments_before = this.start && this.start.comments_before; + var lastComment = comments_before && comments_before[comments_before.length - 1]; + return lastComment && /@const\b/.test(lastComment.value); +}); + +AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){ + return defaults(options, { + except : [], + eval : false, + sort : false, // Ignored. Flag retained for backwards compatibility. + toplevel : false, + screw_ie8 : true, + keep_fnames : false + }); +}); + +AST_Toplevel.DEFMETHOD("mangle_names", function(options){ + options = this._default_mangler_options(options); + + // Never mangle arguments + options.except.push('arguments'); + + // We only need to mangle declaration nodes. Special logic wired + // into the code generator will display the mangled name if it's + // present (and for AST_SymbolRef-s it'll use the mangled name of + // the AST_SymbolDeclaration that it points to). + var lname = -1; + var to_mangle = []; + + if (options.cache) { + this.globals.each(function(symbol){ + if (options.except.indexOf(symbol.name) < 0) { + to_mangle.push(symbol); + } + }); + } + + var tw = new TreeWalker(function(node, descend){ + if (node instanceof AST_LabeledStatement) { + // lname is incremented when we get to the AST_Label + var save_nesting = lname; + descend(); + lname = save_nesting; + return true; // don't descend again in TreeWalker + } + if (node instanceof AST_Scope) { + var p = tw.parent(), a = []; + node.variables.each(function(symbol){ + if (options.except.indexOf(symbol.name) < 0) { + a.push(symbol); + } + }); + to_mangle.push.apply(to_mangle, a); + return; + } + if (node instanceof AST_Label) { + var name; + do name = base54(++lname); while (!is_identifier(name)); + node.mangled_name = name; + return true; + } + if (options.screw_ie8 && node instanceof AST_SymbolCatch) { + to_mangle.push(node.definition()); + return; + } + }); + this.walk(tw); + to_mangle.forEach(function(def){ def.mangle(options) }); + + if (options.cache) { + options.cache.cname = this.cname; + } +}); + +AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){ + options = this._default_mangler_options(options); + var tw = new TreeWalker(function(node){ + if (node instanceof AST_Constant) + base54.consider(node.print_to_string()); + else if (node instanceof AST_Return) + base54.consider("return"); + else if (node instanceof AST_Throw) + base54.consider("throw"); + else if (node instanceof AST_Continue) + base54.consider("continue"); + else if (node instanceof AST_Break) + base54.consider("break"); + else if (node instanceof AST_Debugger) + base54.consider("debugger"); + else if (node instanceof AST_Directive) + base54.consider(node.value); + else if (node instanceof AST_While) + base54.consider("while"); + else if (node instanceof AST_Do) + base54.consider("do while"); + else if (node instanceof AST_If) { + base54.consider("if"); + if (node.alternative) base54.consider("else"); + } + else if (node instanceof AST_Var) + base54.consider("var"); + else if (node instanceof AST_Const) + base54.consider("const"); + else if (node instanceof AST_Lambda) + base54.consider("function"); + else if (node instanceof AST_For) + base54.consider("for"); + else if (node instanceof AST_ForIn) + base54.consider("for in"); + else if (node instanceof AST_Switch) + base54.consider("switch"); + else if (node instanceof AST_Case) + base54.consider("case"); + else if (node instanceof AST_Default) + base54.consider("default"); + else if (node instanceof AST_With) + base54.consider("with"); + else if (node instanceof AST_ObjectSetter) + base54.consider("set" + node.key); + else if (node instanceof AST_ObjectGetter) + base54.consider("get" + node.key); + else if (node instanceof AST_ObjectKeyVal) + base54.consider(node.key); + else if (node instanceof AST_New) + base54.consider("new"); + else if (node instanceof AST_This) + base54.consider("this"); + else if (node instanceof AST_Try) + base54.consider("try"); + else if (node instanceof AST_Catch) + base54.consider("catch"); + else if (node instanceof AST_Finally) + base54.consider("finally"); + else if (node instanceof AST_Symbol && node.unmangleable(options)) + base54.consider(node.name); + else if (node instanceof AST_Unary || node instanceof AST_Binary) + base54.consider(node.operator); + else if (node instanceof AST_Dot) + base54.consider(node.property); + }); + this.walk(tw); + base54.sort(); +}); + +var base54 = (function() { + var string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789"; + var chars, frequency; + function reset() { + frequency = Object.create(null); + chars = string.split("").map(function(ch){ return ch.charCodeAt(0) }); + chars.forEach(function(ch){ frequency[ch] = 0 }); + } + base54.consider = function(str){ + for (var i = str.length; --i >= 0;) { + var code = str.charCodeAt(i); + if (code in frequency) ++frequency[code]; + } + }; + base54.sort = function() { + chars = mergeSort(chars, function(a, b){ + if (is_digit(a) && !is_digit(b)) return 1; + if (is_digit(b) && !is_digit(a)) return -1; + return frequency[b] - frequency[a]; + }); + }; + base54.reset = reset; + reset(); + base54.get = function(){ return chars }; + base54.freq = function(){ return frequency }; + function base54(num) { + var ret = "", base = 54; + num++; + do { + num--; + ret += String.fromCharCode(chars[num % base]); + num = Math.floor(num / base); + base = 64; + } while (num > 0); + return ret; + }; + return base54; +})(); + +AST_Toplevel.DEFMETHOD("scope_warnings", function(options){ + options = defaults(options, { + undeclared : false, // this makes a lot of noise + unreferenced : true, + assign_to_global : true, + func_arguments : true, + nested_defuns : true, + eval : true + }); + var tw = new TreeWalker(function(node){ + if (options.undeclared + && node instanceof AST_SymbolRef + && node.undeclared()) + { + // XXX: this also warns about JS standard names, + // i.e. Object, Array, parseInt etc. Should add a list of + // exceptions. + AST_Node.warn("Undeclared symbol: {name} [{file}:{line},{col}]", { + name: node.name, + file: node.start.file, + line: node.start.line, + col: node.start.col + }); + } + if (options.assign_to_global) + { + var sym = null; + if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) + sym = node.left; + else if (node instanceof AST_ForIn && node.init instanceof AST_SymbolRef) + sym = node.init; + if (sym + && (sym.undeclared() + || (sym.global() && sym.scope !== sym.definition().scope))) { + AST_Node.warn("{msg}: {name} [{file}:{line},{col}]", { + msg: sym.undeclared() ? "Accidental global?" : "Assignment to global", + name: sym.name, + file: sym.start.file, + line: sym.start.line, + col: sym.start.col + }); + } + } + if (options.eval + && node instanceof AST_SymbolRef + && node.undeclared() + && node.name == "eval") { + AST_Node.warn("Eval is used [{file}:{line},{col}]", node.start); + } + if (options.unreferenced + && (node instanceof AST_SymbolDeclaration || node instanceof AST_Label) + && !(node instanceof AST_SymbolCatch) + && node.unreferenced()) { + AST_Node.warn("{type} {name} is declared but not referenced [{file}:{line},{col}]", { + type: node instanceof AST_Label ? "Label" : "Symbol", + name: node.name, + file: node.start.file, + line: node.start.line, + col: node.start.col + }); + } + if (options.func_arguments + && node instanceof AST_Lambda + && node.uses_arguments) { + AST_Node.warn("arguments used in function {name} [{file}:{line},{col}]", { + name: node.name ? node.name.name : "anonymous", + file: node.start.file, + line: node.start.line, + col: node.start.col + }); + } + if (options.nested_defuns + && node instanceof AST_Defun + && !(tw.parent() instanceof AST_Scope)) { + AST_Node.warn("Function {name} declared in nested statement \"{type}\" [{file}:{line},{col}]", { + name: node.name.name, + type: tw.parent().TYPE, + file: node.start.file, + line: node.start.line, + col: node.start.col + }); + } + }); + this.walk(tw); +}); diff --git a/node_modules/uglify-js/lib/sourcemap.js b/node_modules/uglify-js/lib/sourcemap.js new file mode 100644 index 0000000..0be16bf --- /dev/null +++ b/node_modules/uglify-js/lib/sourcemap.js @@ -0,0 +1,97 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +// a small wrapper around fitzgen's source-map library +function SourceMap(options) { + options = defaults(options, { + file : null, + root : null, + orig : null, + + orig_line_diff : 0, + dest_line_diff : 0, + }); + var generator = new MOZ_SourceMap.SourceMapGenerator({ + file : options.file, + sourceRoot : options.root + }); + var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig); + + if (orig_map && Array.isArray(options.orig.sources)) { + orig_map._sources.toArray().forEach(function(source) { + var sourceContent = orig_map.sourceContentFor(source, true); + if (sourceContent) { + generator.setSourceContent(source, sourceContent); + } + }); + } + + function add(source, gen_line, gen_col, orig_line, orig_col, name) { + if (orig_map) { + var info = orig_map.originalPositionFor({ + line: orig_line, + column: orig_col + }); + if (info.source === null) { + return; + } + source = info.source; + orig_line = info.line; + orig_col = info.column; + name = info.name || name; + } + generator.addMapping({ + generated : { line: gen_line + options.dest_line_diff, column: gen_col }, + original : { line: orig_line + options.orig_line_diff, column: orig_col }, + source : source, + name : name + }); + }; + return { + add : add, + get : function() { return generator }, + toString : function() { return JSON.stringify(generator.toJSON()); } + }; +}; diff --git a/node_modules/uglify-js/lib/transform.js b/node_modules/uglify-js/lib/transform.js new file mode 100644 index 0000000..3018e8f --- /dev/null +++ b/node_modules/uglify-js/lib/transform.js @@ -0,0 +1,218 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +// Tree transformer helpers. + +function TreeTransformer(before, after) { + TreeWalker.call(this); + this.before = before; + this.after = after; +} +TreeTransformer.prototype = new TreeWalker; + +(function(undefined){ + + function _(node, descend) { + node.DEFMETHOD("transform", function(tw, in_list){ + var x, y; + tw.push(this); + if (tw.before) x = tw.before(this, descend, in_list); + if (x === undefined) { + if (!tw.after) { + x = this; + descend(x, tw); + } else { + tw.stack[tw.stack.length - 1] = x = this; + descend(x, tw); + y = tw.after(x, in_list); + if (y !== undefined) x = y; + } + } + tw.pop(this); + return x; + }); + }; + + function do_list(list, tw) { + return MAP(list, function(node){ + return node.transform(tw, true); + }); + }; + + _(AST_Node, noop); + + _(AST_LabeledStatement, function(self, tw){ + self.label = self.label.transform(tw); + self.body = self.body.transform(tw); + }); + + _(AST_SimpleStatement, function(self, tw){ + self.body = self.body.transform(tw); + }); + + _(AST_Block, function(self, tw){ + self.body = do_list(self.body, tw); + }); + + _(AST_DWLoop, function(self, tw){ + self.condition = self.condition.transform(tw); + self.body = self.body.transform(tw); + }); + + _(AST_For, function(self, tw){ + if (self.init) self.init = self.init.transform(tw); + if (self.condition) self.condition = self.condition.transform(tw); + if (self.step) self.step = self.step.transform(tw); + self.body = self.body.transform(tw); + }); + + _(AST_ForIn, function(self, tw){ + self.init = self.init.transform(tw); + self.object = self.object.transform(tw); + self.body = self.body.transform(tw); + }); + + _(AST_With, function(self, tw){ + self.expression = self.expression.transform(tw); + self.body = self.body.transform(tw); + }); + + _(AST_Exit, function(self, tw){ + if (self.value) self.value = self.value.transform(tw); + }); + + _(AST_LoopControl, function(self, tw){ + if (self.label) self.label = self.label.transform(tw); + }); + + _(AST_If, function(self, tw){ + self.condition = self.condition.transform(tw); + self.body = self.body.transform(tw); + if (self.alternative) self.alternative = self.alternative.transform(tw); + }); + + _(AST_Switch, function(self, tw){ + self.expression = self.expression.transform(tw); + self.body = do_list(self.body, tw); + }); + + _(AST_Case, function(self, tw){ + self.expression = self.expression.transform(tw); + self.body = do_list(self.body, tw); + }); + + _(AST_Try, function(self, tw){ + self.body = do_list(self.body, tw); + if (self.bcatch) self.bcatch = self.bcatch.transform(tw); + if (self.bfinally) self.bfinally = self.bfinally.transform(tw); + }); + + _(AST_Catch, function(self, tw){ + self.argname = self.argname.transform(tw); + self.body = do_list(self.body, tw); + }); + + _(AST_Definitions, function(self, tw){ + self.definitions = do_list(self.definitions, tw); + }); + + _(AST_VarDef, function(self, tw){ + self.name = self.name.transform(tw); + if (self.value) self.value = self.value.transform(tw); + }); + + _(AST_Lambda, function(self, tw){ + if (self.name) self.name = self.name.transform(tw); + self.argnames = do_list(self.argnames, tw); + self.body = do_list(self.body, tw); + }); + + _(AST_Call, function(self, tw){ + self.expression = self.expression.transform(tw); + self.args = do_list(self.args, tw); + }); + + _(AST_Seq, function(self, tw){ + self.car = self.car.transform(tw); + self.cdr = self.cdr.transform(tw); + }); + + _(AST_Dot, function(self, tw){ + self.expression = self.expression.transform(tw); + }); + + _(AST_Sub, function(self, tw){ + self.expression = self.expression.transform(tw); + self.property = self.property.transform(tw); + }); + + _(AST_Unary, function(self, tw){ + self.expression = self.expression.transform(tw); + }); + + _(AST_Binary, function(self, tw){ + self.left = self.left.transform(tw); + self.right = self.right.transform(tw); + }); + + _(AST_Conditional, function(self, tw){ + self.condition = self.condition.transform(tw); + self.consequent = self.consequent.transform(tw); + self.alternative = self.alternative.transform(tw); + }); + + _(AST_Array, function(self, tw){ + self.elements = do_list(self.elements, tw); + }); + + _(AST_Object, function(self, tw){ + self.properties = do_list(self.properties, tw); + }); + + _(AST_ObjectProperty, function(self, tw){ + self.value = self.value.transform(tw); + }); + +})(); diff --git a/node_modules/uglify-js/lib/utils.js b/node_modules/uglify-js/lib/utils.js new file mode 100644 index 0000000..d0a21ac --- /dev/null +++ b/node_modules/uglify-js/lib/utils.js @@ -0,0 +1,322 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +function array_to_hash(a) { + var ret = Object.create(null); + for (var i = 0; i < a.length; ++i) + ret[a[i]] = true; + return ret; +}; + +function slice(a, start) { + return Array.prototype.slice.call(a, start || 0); +}; + +function characters(str) { + return str.split(""); +}; + +function member(name, array) { + return array.indexOf(name) >= 0; +}; + +function find_if(func, array) { + for (var i = 0, n = array.length; i < n; ++i) { + if (func(array[i])) + return array[i]; + } +}; + +function repeat_string(str, i) { + if (i <= 0) return ""; + if (i == 1) return str; + var d = repeat_string(str, i >> 1); + d += d; + if (i & 1) d += str; + return d; +}; + +function DefaultsError(msg, defs) { + Error.call(this, msg); + this.msg = msg; + this.defs = defs; +}; +DefaultsError.prototype = Object.create(Error.prototype); +DefaultsError.prototype.constructor = DefaultsError; + +DefaultsError.croak = function(msg, defs) { + throw new DefaultsError(msg, defs); +}; + +function defaults(args, defs, croak) { + if (args === true) + args = {}; + var ret = args || {}; + if (croak) for (var i in ret) if (HOP(ret, i) && !HOP(defs, i)) + DefaultsError.croak("`" + i + "` is not a supported option", defs); + for (var i in defs) if (HOP(defs, i)) { + ret[i] = (args && HOP(args, i)) ? args[i] : defs[i]; + } + return ret; +}; + +function merge(obj, ext) { + var count = 0; + for (var i in ext) if (HOP(ext, i)) { + obj[i] = ext[i]; + count++; + } + return count; +}; + +function noop() {}; +function return_false() { return false; } +function return_true() { return true; } + +var MAP = (function(){ + function MAP(a, f, backwards) { + var ret = [], top = [], i; + function doit() { + var val = f(a[i], i); + var is_last = val instanceof Last; + if (is_last) val = val.v; + if (val instanceof AtTop) { + val = val.v; + if (val instanceof Splice) { + top.push.apply(top, backwards ? val.v.slice().reverse() : val.v); + } else { + top.push(val); + } + } + else if (val !== skip) { + if (val instanceof Splice) { + ret.push.apply(ret, backwards ? val.v.slice().reverse() : val.v); + } else { + ret.push(val); + } + } + return is_last; + }; + if (a instanceof Array) { + if (backwards) { + for (i = a.length; --i >= 0;) if (doit()) break; + ret.reverse(); + top.reverse(); + } else { + for (i = 0; i < a.length; ++i) if (doit()) break; + } + } + else { + for (i in a) if (HOP(a, i)) if (doit()) break; + } + return top.concat(ret); + }; + MAP.at_top = function(val) { return new AtTop(val) }; + MAP.splice = function(val) { return new Splice(val) }; + MAP.last = function(val) { return new Last(val) }; + var skip = MAP.skip = {}; + function AtTop(val) { this.v = val }; + function Splice(val) { this.v = val }; + function Last(val) { this.v = val }; + return MAP; +})(); + +function push_uniq(array, el) { + if (array.indexOf(el) < 0) + array.push(el); +}; + +function string_template(text, props) { + return text.replace(/\{(.+?)\}/g, function(str, p){ + return props[p]; + }); +}; + +function remove(array, el) { + for (var i = array.length; --i >= 0;) { + if (array[i] === el) array.splice(i, 1); + } +}; + +function mergeSort(array, cmp) { + if (array.length < 2) return array.slice(); + function merge(a, b) { + var r = [], ai = 0, bi = 0, i = 0; + while (ai < a.length && bi < b.length) { + cmp(a[ai], b[bi]) <= 0 + ? r[i++] = a[ai++] + : r[i++] = b[bi++]; + } + if (ai < a.length) r.push.apply(r, a.slice(ai)); + if (bi < b.length) r.push.apply(r, b.slice(bi)); + return r; + }; + function _ms(a) { + if (a.length <= 1) + return a; + var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m); + left = _ms(left); + right = _ms(right); + return merge(left, right); + }; + return _ms(array); +}; + +function set_difference(a, b) { + return a.filter(function(el){ + return b.indexOf(el) < 0; + }); +}; + +function set_intersection(a, b) { + return a.filter(function(el){ + return b.indexOf(el) >= 0; + }); +}; + +// this function is taken from Acorn [1], written by Marijn Haverbeke +// [1] https://github.com/marijnh/acorn +function makePredicate(words) { + if (!(words instanceof Array)) words = words.split(" "); + var f = "", cats = []; + out: for (var i = 0; i < words.length; ++i) { + for (var j = 0; j < cats.length; ++j) + if (cats[j][0].length == words[i].length) { + cats[j].push(words[i]); + continue out; + } + cats.push([words[i]]); + } + function quote(word) { + return JSON.stringify(word).replace(/[\u2028\u2029]/g, function(s) { + switch (s) { + case "\u2028": return "\\u2028"; + case "\u2029": return "\\u2029"; + } + return s; + }); + } + function compareTo(arr) { + if (arr.length == 1) return f += "return str === " + quote(arr[0]) + ";"; + f += "switch(str){"; + for (var i = 0; i < arr.length; ++i) f += "case " + quote(arr[i]) + ":"; + f += "return true}return false;"; + } + // When there are more than three length categories, an outer + // switch first dispatches on the lengths, to save on comparisons. + if (cats.length > 3) { + cats.sort(function(a, b) {return b.length - a.length;}); + f += "switch(str.length){"; + for (var i = 0; i < cats.length; ++i) { + var cat = cats[i]; + f += "case " + cat[0].length + ":"; + compareTo(cat); + } + f += "}"; + // Otherwise, simply generate a flat `switch` statement. + } else { + compareTo(words); + } + return new Function("str", f); +}; + +function all(array, predicate) { + for (var i = array.length; --i >= 0;) + if (!predicate(array[i])) + return false; + return true; +}; + +function Dictionary() { + this._values = Object.create(null); + this._size = 0; +}; +Dictionary.prototype = { + set: function(key, val) { + if (!this.has(key)) ++this._size; + this._values["$" + key] = val; + return this; + }, + add: function(key, val) { + if (this.has(key)) { + this.get(key).push(val); + } else { + this.set(key, [ val ]); + } + return this; + }, + get: function(key) { return this._values["$" + key] }, + del: function(key) { + if (this.has(key)) { + --this._size; + delete this._values["$" + key]; + } + return this; + }, + has: function(key) { return ("$" + key) in this._values }, + each: function(f) { + for (var i in this._values) + f(this._values[i], i.substr(1)); + }, + size: function() { + return this._size; + }, + map: function(f) { + var ret = []; + for (var i in this._values) + ret.push(f(this._values[i], i.substr(1))); + return ret; + }, + toObject: function() { return this._values } +}; +Dictionary.fromObject = function(obj) { + var dict = new Dictionary(); + dict._size = merge(dict._values, obj); + return dict; +}; + +function HOP(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} diff --git a/node_modules/uglify-js/node_modules/async/LICENSE b/node_modules/uglify-js/node_modules/async/LICENSE new file mode 100644 index 0000000..b7f9d50 --- /dev/null +++ b/node_modules/uglify-js/node_modules/async/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010 Caolan McMahon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/uglify-js/node_modules/async/README.md b/node_modules/uglify-js/node_modules/async/README.md new file mode 100644 index 0000000..951f76e --- /dev/null +++ b/node_modules/uglify-js/node_modules/async/README.md @@ -0,0 +1,1425 @@ +# Async.js + +Async is a utility module which provides straight-forward, powerful functions +for working with asynchronous JavaScript. Although originally designed for +use with [node.js](http://nodejs.org), it can also be used directly in the +browser. Also supports [component](https://github.com/component/component). + +Async provides around 20 functions that include the usual 'functional' +suspects (map, reduce, filter, each…) as well as some common patterns +for asynchronous control flow (parallel, series, waterfall…). All these +functions assume you follow the node.js convention of providing a single +callback as the last argument of your async function. + + +## Quick Examples + +```javascript +async.map(['file1','file2','file3'], fs.stat, function(err, results){ + // results is now an array of stats for each file +}); + +async.filter(['file1','file2','file3'], fs.exists, function(results){ + // results now equals an array of the existing files +}); + +async.parallel([ + function(){ ... }, + function(){ ... } +], callback); + +async.series([ + function(){ ... }, + function(){ ... } +]); +``` + +There are many more functions available so take a look at the docs below for a +full list. This module aims to be comprehensive, so if you feel anything is +missing please create a GitHub issue for it. + +## Common Pitfalls + +### Binding a context to an iterator + +This section is really about bind, not about async. If you are wondering how to +make async execute your iterators in a given context, or are confused as to why +a method of another library isn't working as an iterator, study this example: + +```js +// Here is a simple object with an (unnecessarily roundabout) squaring method +var AsyncSquaringLibrary = { + squareExponent: 2, + square: function(number, callback){ + var result = Math.pow(number, this.squareExponent); + setTimeout(function(){ + callback(null, result); + }, 200); + } +}; + +async.map([1, 2, 3], AsyncSquaringLibrary.square, function(err, result){ + // result is [NaN, NaN, NaN] + // This fails because the `this.squareExponent` expression in the square + // function is not evaluated in the context of AsyncSquaringLibrary, and is + // therefore undefined. +}); + +async.map([1, 2, 3], AsyncSquaringLibrary.square.bind(AsyncSquaringLibrary), function(err, result){ + // result is [1, 4, 9] + // With the help of bind we can attach a context to the iterator before + // passing it to async. Now the square function will be executed in its + // 'home' AsyncSquaringLibrary context and the value of `this.squareExponent` + // will be as expected. +}); +``` + +## Download + +The source is available for download from +[GitHub](http://github.com/caolan/async). +Alternatively, you can install using Node Package Manager (npm): + + npm install async + +__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 29.6kb Uncompressed + +## In the Browser + +So far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage: + +```html + + +``` + +## Documentation + +### Collections + +* [each](#each) +* [eachSeries](#eachSeries) +* [eachLimit](#eachLimit) +* [map](#map) +* [mapSeries](#mapSeries) +* [mapLimit](#mapLimit) +* [filter](#filter) +* [filterSeries](#filterSeries) +* [reject](#reject) +* [rejectSeries](#rejectSeries) +* [reduce](#reduce) +* [reduceRight](#reduceRight) +* [detect](#detect) +* [detectSeries](#detectSeries) +* [sortBy](#sortBy) +* [some](#some) +* [every](#every) +* [concat](#concat) +* [concatSeries](#concatSeries) + +### Control Flow + +* [series](#series) +* [parallel](#parallel) +* [parallelLimit](#parallellimittasks-limit-callback) +* [whilst](#whilst) +* [doWhilst](#doWhilst) +* [until](#until) +* [doUntil](#doUntil) +* [forever](#forever) +* [waterfall](#waterfall) +* [compose](#compose) +* [applyEach](#applyEach) +* [applyEachSeries](#applyEachSeries) +* [queue](#queue) +* [cargo](#cargo) +* [auto](#auto) +* [iterator](#iterator) +* [apply](#apply) +* [nextTick](#nextTick) +* [times](#times) +* [timesSeries](#timesSeries) + +### Utils + +* [memoize](#memoize) +* [unmemoize](#unmemoize) +* [log](#log) +* [dir](#dir) +* [noConflict](#noConflict) + + +## Collections + + + +### each(arr, iterator, callback) + +Applies an iterator function to each item in an array, in parallel. +The iterator is called with an item from the list and a callback for when it +has finished. If the iterator passes an error to this callback, the main +callback for the each function is immediately called with the error. + +Note, that since this function applies the iterator to each item in parallel +there is no guarantee that the iterator functions will complete in order. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err) which must be called once it has + completed. If no error has occured, the callback should be run without + arguments or with an explicit null argument. +* callback(err) - A callback which is called after all the iterator functions + have finished, or an error has occurred. + +__Example__ + +```js +// assuming openFiles is an array of file names and saveFile is a function +// to save the modified contents of that file: + +async.each(openFiles, saveFile, function(err){ + // if any of the saves produced an error, err would equal that error +}); +``` + +--------------------------------------- + + + +### eachSeries(arr, iterator, callback) + +The same as each only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. This means the iterator functions will complete in order. + + +--------------------------------------- + + + +### eachLimit(arr, limit, iterator, callback) + +The same as each only no more than "limit" iterators will be simultaneously +running at any time. + +Note that the items are not processed in batches, so there is no guarantee that + the first "limit" iterator functions will complete before any others are +started. + +__Arguments__ + +* arr - An array to iterate over. +* limit - The maximum number of iterators to run at any time. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err) which must be called once it has + completed. If no error has occured, the callback should be run without + arguments or with an explicit null argument. +* callback(err) - A callback which is called after all the iterator functions + have finished, or an error has occurred. + +__Example__ + +```js +// Assume documents is an array of JSON objects and requestApi is a +// function that interacts with a rate-limited REST api. + +async.eachLimit(documents, 20, requestApi, function(err){ + // if any of the saves produced an error, err would equal that error +}); +``` + +--------------------------------------- + + +### map(arr, iterator, callback) + +Produces a new array of values by mapping each value in the given array through +the iterator function. The iterator is called with an item from the array and a +callback for when it has finished processing. The callback takes 2 arguments, +an error and the transformed item from the array. If the iterator passes an +error to this callback, the main callback for the map function is immediately +called with the error. + +Note, that since this function applies the iterator to each item in parallel +there is no guarantee that the iterator functions will complete in order, however +the results array will be in the same order as the original array. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err, transformed) which must be called once + it has completed with an error (which can be null) and a transformed item. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is an array of the + transformed items from the original array. + +__Example__ + +```js +async.map(['file1','file2','file3'], fs.stat, function(err, results){ + // results is now an array of stats for each file +}); +``` + +--------------------------------------- + + +### mapSeries(arr, iterator, callback) + +The same as map only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. The results array will be in the same order as the original. + + +--------------------------------------- + + +### mapLimit(arr, limit, iterator, callback) + +The same as map only no more than "limit" iterators will be simultaneously +running at any time. + +Note that the items are not processed in batches, so there is no guarantee that + the first "limit" iterator functions will complete before any others are +started. + +__Arguments__ + +* arr - An array to iterate over. +* limit - The maximum number of iterators to run at any time. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err, transformed) which must be called once + it has completed with an error (which can be null) and a transformed item. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is an array of the + transformed items from the original array. + +__Example__ + +```js +async.mapLimit(['file1','file2','file3'], 1, fs.stat, function(err, results){ + // results is now an array of stats for each file +}); +``` + +--------------------------------------- + + +### filter(arr, iterator, callback) + +__Alias:__ select + +Returns a new array of all the values which pass an async truth test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like fs.exists. This operation is +performed in parallel, but the results array will be in the same order as the +original. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback(truthValue) which must be called with a + boolean argument once it has completed. +* callback(results) - A callback which is called after all the iterator + functions have finished. + +__Example__ + +```js +async.filter(['file1','file2','file3'], fs.exists, function(results){ + // results now equals an array of the existing files +}); +``` + +--------------------------------------- + + +### filterSeries(arr, iterator, callback) + +__alias:__ selectSeries + +The same as filter only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. The results array will be in the same order as the original. + +--------------------------------------- + + +### reject(arr, iterator, callback) + +The opposite of filter. Removes values that pass an async truth test. + +--------------------------------------- + + +### rejectSeries(arr, iterator, callback) + +The same as reject, only the iterator is applied to each item in the array +in series. + + +--------------------------------------- + + +### reduce(arr, memo, iterator, callback) + +__aliases:__ inject, foldl + +Reduces a list of values into a single value using an async iterator to return +each successive step. Memo is the initial state of the reduction. This +function only operates in series. For performance reasons, it may make sense to +split a call to this function into a parallel map, then use the normal +Array.prototype.reduce on the results. This function is for situations where +each step in the reduction needs to be async, if you can get the data before +reducing it then it's probably a good idea to do so. + +__Arguments__ + +* arr - An array to iterate over. +* memo - The initial state of the reduction. +* iterator(memo, item, callback) - A function applied to each item in the + array to produce the next step in the reduction. The iterator is passed a + callback(err, reduction) which accepts an optional error as its first + argument, and the state of the reduction as the second. If an error is + passed to the callback, the reduction is stopped and the main callback is + immediately called with the error. +* callback(err, result) - A callback which is called after all the iterator + functions have finished. Result is the reduced value. + +__Example__ + +```js +async.reduce([1,2,3], 0, function(memo, item, callback){ + // pointless async: + process.nextTick(function(){ + callback(null, memo + item) + }); +}, function(err, result){ + // result is now equal to the last value of memo, which is 6 +}); +``` + +--------------------------------------- + + +### reduceRight(arr, memo, iterator, callback) + +__Alias:__ foldr + +Same as reduce, only operates on the items in the array in reverse order. + + +--------------------------------------- + + +### detect(arr, iterator, callback) + +Returns the first value in a list that passes an async truth test. The +iterator is applied in parallel, meaning the first iterator to return true will +fire the detect callback with that result. That means the result might not be +the first item in the original array (in terms of order) that passes the test. + +If order within the original array is important then look at detectSeries. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback(truthValue) which must be called with a + boolean argument once it has completed. +* callback(result) - A callback which is called as soon as any iterator returns + true, or after all the iterator functions have finished. Result will be + the first item in the array that passes the truth test (iterator) or the + value undefined if none passed. + +__Example__ + +```js +async.detect(['file1','file2','file3'], fs.exists, function(result){ + // result now equals the first file in the list that exists +}); +``` + +--------------------------------------- + + +### detectSeries(arr, iterator, callback) + +The same as detect, only the iterator is applied to each item in the array +in series. This means the result is always the first in the original array (in +terms of array order) that passes the truth test. + + +--------------------------------------- + + +### sortBy(arr, iterator, callback) + +Sorts a list by the results of running each value through an async iterator. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err, sortValue) which must be called once it + has completed with an error (which can be null) and a value to use as the sort + criteria. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is the items from + the original array sorted by the values returned by the iterator calls. + +__Example__ + +```js +async.sortBy(['file1','file2','file3'], function(file, callback){ + fs.stat(file, function(err, stats){ + callback(err, stats.mtime); + }); +}, function(err, results){ + // results is now the original array of files sorted by + // modified date +}); +``` + +--------------------------------------- + + +### some(arr, iterator, callback) + +__Alias:__ any + +Returns true if at least one element in the array satisfies an async test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like fs.exists. Once any iterator +call returns true, the main callback is immediately called. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback(truthValue) which must be called with a + boolean argument once it has completed. +* callback(result) - A callback which is called as soon as any iterator returns + true, or after all the iterator functions have finished. Result will be + either true or false depending on the values of the async tests. + +__Example__ + +```js +async.some(['file1','file2','file3'], fs.exists, function(result){ + // if result is true then at least one of the files exists +}); +``` + +--------------------------------------- + + +### every(arr, iterator, callback) + +__Alias:__ all + +Returns true if every element in the array satisfies an async test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like fs.exists. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback(truthValue) which must be called with a + boolean argument once it has completed. +* callback(result) - A callback which is called after all the iterator + functions have finished. Result will be either true or false depending on + the values of the async tests. + +__Example__ + +```js +async.every(['file1','file2','file3'], fs.exists, function(result){ + // if result is true then every file exists +}); +``` + +--------------------------------------- + + +### concat(arr, iterator, callback) + +Applies an iterator to each item in a list, concatenating the results. Returns the +concatenated list. The iterators are called in parallel, and the results are +concatenated as they return. There is no guarantee that the results array will +be returned in the original order of the arguments passed to the iterator function. + +__Arguments__ + +* arr - An array to iterate over +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err, results) which must be called once it + has completed with an error (which can be null) and an array of results. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is an array containing + the concatenated results of the iterator function. + +__Example__ + +```js +async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){ + // files is now a list of filenames that exist in the 3 directories +}); +``` + +--------------------------------------- + + +### concatSeries(arr, iterator, callback) + +Same as async.concat, but executes in series instead of parallel. + + +## Control Flow + + +### series(tasks, [callback]) + +Run an array of functions in series, each one running once the previous +function has completed. If any functions in the series pass an error to its +callback, no more functions are run and the callback for the series is +immediately called with the value of the error. Once the tasks have completed, +the results are passed to the final callback as an array. + +It is also possible to use an object instead of an array. Each property will be +run as a function and the results will be passed to the final callback as an object +instead of an array. This can be a more readable way of handling results from +async.series. + + +__Arguments__ + +* tasks - An array or object containing functions to run, each function is passed + a callback(err, result) it must call on completion with an error (which can + be null) and an optional result value. +* callback(err, results) - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the task callbacks. + +__Example__ + +```js +async.series([ + function(callback){ + // do some stuff ... + callback(null, 'one'); + }, + function(callback){ + // do some more stuff ... + callback(null, 'two'); + } +], +// optional callback +function(err, results){ + // results is now equal to ['one', 'two'] +}); + + +// an example using an object instead of an array +async.series({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + } +}, +function(err, results) { + // results is now equal to: {one: 1, two: 2} +}); +``` + +--------------------------------------- + + +### parallel(tasks, [callback]) + +Run an array of functions in parallel, without waiting until the previous +function has completed. If any of the functions pass an error to its +callback, the main callback is immediately called with the value of the error. +Once the tasks have completed, the results are passed to the final callback as an +array. + +It is also possible to use an object instead of an array. Each property will be +run as a function and the results will be passed to the final callback as an object +instead of an array. This can be a more readable way of handling results from +async.parallel. + + +__Arguments__ + +* tasks - An array or object containing functions to run, each function is passed + a callback(err, result) it must call on completion with an error (which can + be null) and an optional result value. +* callback(err, results) - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the task callbacks. + +__Example__ + +```js +async.parallel([ + function(callback){ + setTimeout(function(){ + callback(null, 'one'); + }, 200); + }, + function(callback){ + setTimeout(function(){ + callback(null, 'two'); + }, 100); + } +], +// optional callback +function(err, results){ + // the results array will equal ['one','two'] even though + // the second function had a shorter timeout. +}); + + +// an example using an object instead of an array +async.parallel({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + } +}, +function(err, results) { + // results is now equals to: {one: 1, two: 2} +}); +``` + +--------------------------------------- + + +### parallelLimit(tasks, limit, [callback]) + +The same as parallel only the tasks are executed in parallel with a maximum of "limit" +tasks executing at any time. + +Note that the tasks are not executed in batches, so there is no guarantee that +the first "limit" tasks will complete before any others are started. + +__Arguments__ + +* tasks - An array or object containing functions to run, each function is passed + a callback(err, result) it must call on completion with an error (which can + be null) and an optional result value. +* limit - The maximum number of tasks to run at any time. +* callback(err, results) - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the task callbacks. + +--------------------------------------- + + +### whilst(test, fn, callback) + +Repeatedly call fn, while test returns true. Calls the callback when stopped, +or an error occurs. + +__Arguments__ + +* test() - synchronous truth test to perform before each execution of fn. +* fn(callback) - A function to call each time the test passes. The function is + passed a callback(err) which must be called once it has completed with an + optional error argument. +* callback(err) - A callback which is called after the test fails and repeated + execution of fn has stopped. + +__Example__ + +```js +var count = 0; + +async.whilst( + function () { return count < 5; }, + function (callback) { + count++; + setTimeout(callback, 1000); + }, + function (err) { + // 5 seconds have passed + } +); +``` + +--------------------------------------- + + +### doWhilst(fn, test, callback) + +The post check version of whilst. To reflect the difference in the order of operations `test` and `fn` arguments are switched. `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. + +--------------------------------------- + + +### until(test, fn, callback) + +Repeatedly call fn, until test returns true. Calls the callback when stopped, +or an error occurs. + +The inverse of async.whilst. + +--------------------------------------- + + +### doUntil(fn, test, callback) + +Like doWhilst except the test is inverted. Note the argument ordering differs from `until`. + +--------------------------------------- + + +### forever(fn, callback) + +Calls the asynchronous function 'fn' repeatedly, in series, indefinitely. +If an error is passed to fn's callback then 'callback' is called with the +error, otherwise it will never be called. + +--------------------------------------- + + +### waterfall(tasks, [callback]) + +Runs an array of functions in series, each passing their results to the next in +the array. However, if any of the functions pass an error to the callback, the +next function is not executed and the main callback is immediately called with +the error. + +__Arguments__ + +* tasks - An array of functions to run, each function is passed a + callback(err, result1, result2, ...) it must call on completion. The first + argument is an error (which can be null) and any further arguments will be + passed as arguments in order to the next task. +* callback(err, [results]) - An optional callback to run once all the functions + have completed. This will be passed the results of the last task's callback. + + + +__Example__ + +```js +async.waterfall([ + function(callback){ + callback(null, 'one', 'two'); + }, + function(arg1, arg2, callback){ + callback(null, 'three'); + }, + function(arg1, callback){ + // arg1 now equals 'three' + callback(null, 'done'); + } +], function (err, result) { + // result now equals 'done' +}); +``` + +--------------------------------------- + +### compose(fn1, fn2...) + +Creates a function which is a composition of the passed asynchronous +functions. Each function consumes the return value of the function that +follows. Composing functions f(), g() and h() would produce the result of +f(g(h())), only this version uses callbacks to obtain the return values. + +Each function is executed with the `this` binding of the composed function. + +__Arguments__ + +* functions... - the asynchronous functions to compose + + +__Example__ + +```js +function add1(n, callback) { + setTimeout(function () { + callback(null, n + 1); + }, 10); +} + +function mul3(n, callback) { + setTimeout(function () { + callback(null, n * 3); + }, 10); +} + +var add1mul3 = async.compose(mul3, add1); + +add1mul3(4, function (err, result) { + // result now equals 15 +}); +``` + +--------------------------------------- + +### applyEach(fns, args..., callback) + +Applies the provided arguments to each function in the array, calling the +callback after all functions have completed. If you only provide the first +argument then it will return a function which lets you pass in the +arguments as if it were a single function call. + +__Arguments__ + +* fns - the asynchronous functions to all call with the same arguments +* args... - any number of separate arguments to pass to the function +* callback - the final argument should be the callback, called when all + functions have completed processing + + +__Example__ + +```js +async.applyEach([enableSearch, updateSchema], 'bucket', callback); + +// partial application example: +async.each( + buckets, + async.applyEach([enableSearch, updateSchema]), + callback +); +``` + +--------------------------------------- + + +### applyEachSeries(arr, iterator, callback) + +The same as applyEach only the functions are applied in series. + +--------------------------------------- + + +### queue(worker, concurrency) + +Creates a queue object with the specified concurrency. Tasks added to the +queue will be processed in parallel (up to the concurrency limit). If all +workers are in progress, the task is queued until one is available. Once +a worker has completed a task, the task's callback is called. + +__Arguments__ + +* worker(task, callback) - An asynchronous function for processing a queued + task, which must call its callback(err) argument when finished, with an + optional error as an argument. +* concurrency - An integer for determining how many worker functions should be + run in parallel. + +__Queue objects__ + +The queue object returned by this function has the following properties and +methods: + +* length() - a function returning the number of items waiting to be processed. +* concurrency - an integer for determining how many worker functions should be + run in parallel. This property can be changed after a queue is created to + alter the concurrency on-the-fly. +* push(task, [callback]) - add a new task to the queue, the callback is called + once the worker has finished processing the task. + instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list. +* unshift(task, [callback]) - add a new task to the front of the queue. +* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued +* empty - a callback that is called when the last item from the queue is given to a worker +* drain - a callback that is called when the last item from the queue has returned from the worker + +__Example__ + +```js +// create a queue object with concurrency 2 + +var q = async.queue(function (task, callback) { + console.log('hello ' + task.name); + callback(); +}, 2); + + +// assign a callback +q.drain = function() { + console.log('all items have been processed'); +} + +// add some items to the queue + +q.push({name: 'foo'}, function (err) { + console.log('finished processing foo'); +}); +q.push({name: 'bar'}, function (err) { + console.log('finished processing bar'); +}); + +// add some items to the queue (batch-wise) + +q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) { + console.log('finished processing bar'); +}); + +// add some items to the front of the queue + +q.unshift({name: 'bar'}, function (err) { + console.log('finished processing bar'); +}); +``` + +--------------------------------------- + + +### cargo(worker, [payload]) + +Creates a cargo object with the specified payload. Tasks added to the +cargo will be processed altogether (up to the payload limit). If the +worker is in progress, the task is queued until it is available. Once +the worker has completed some tasks, each callback of those tasks is called. + +__Arguments__ + +* worker(tasks, callback) - An asynchronous function for processing an array of + queued tasks, which must call its callback(err) argument when finished, with + an optional error as an argument. +* payload - An optional integer for determining how many tasks should be + processed per round; if omitted, the default is unlimited. + +__Cargo objects__ + +The cargo object returned by this function has the following properties and +methods: + +* length() - a function returning the number of items waiting to be processed. +* payload - an integer for determining how many tasks should be + process per round. This property can be changed after a cargo is created to + alter the payload on-the-fly. +* push(task, [callback]) - add a new task to the queue, the callback is called + once the worker has finished processing the task. + instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list. +* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued +* empty - a callback that is called when the last item from the queue is given to a worker +* drain - a callback that is called when the last item from the queue has returned from the worker + +__Example__ + +```js +// create a cargo object with payload 2 + +var cargo = async.cargo(function (tasks, callback) { + for(var i=0; i +### auto(tasks, [callback]) + +Determines the best order for running functions based on their requirements. +Each function can optionally depend on other functions being completed first, +and each function is run as soon as its requirements are satisfied. If any of +the functions pass an error to their callback, that function will not complete +(so any other functions depending on it will not run) and the main callback +will be called immediately with the error. Functions also receive an object +containing the results of functions which have completed so far. + +Note, all functions are called with a results object as a second argument, +so it is unsafe to pass functions in the tasks object which cannot handle the +extra argument. For example, this snippet of code: + +```js +async.auto({ + readData: async.apply(fs.readFile, 'data.txt', 'utf-8') +}, callback); +``` + +will have the effect of calling readFile with the results object as the last +argument, which will fail: + +```js +fs.readFile('data.txt', 'utf-8', cb, {}); +``` + +Instead, wrap the call to readFile in a function which does not forward the +results object: + +```js +async.auto({ + readData: function(cb, results){ + fs.readFile('data.txt', 'utf-8', cb); + } +}, callback); +``` + +__Arguments__ + +* tasks - An object literal containing named functions or an array of + requirements, with the function itself the last item in the array. The key + used for each function or array is used when specifying requirements. The + function receives two arguments: (1) a callback(err, result) which must be + called when finished, passing an error (which can be null) and the result of + the function's execution, and (2) a results object, containing the results of + the previously executed functions. +* callback(err, results) - An optional callback which is called when all the + tasks have been completed. The callback will receive an error as an argument + if any tasks pass an error to their callback. Results will always be passed + but if an error occurred, no other tasks will be performed, and the results + object will only contain partial results. + + +__Example__ + +```js +async.auto({ + get_data: function(callback){ + // async code to get some data + }, + make_folder: function(callback){ + // async code to create a directory to store a file in + // this is run at the same time as getting the data + }, + write_file: ['get_data', 'make_folder', function(callback){ + // once there is some data and the directory exists, + // write the data to a file in the directory + callback(null, filename); + }], + email_link: ['write_file', function(callback, results){ + // once the file is written let's email a link to it... + // results.write_file contains the filename returned by write_file. + }] +}); +``` + +This is a fairly trivial example, but to do this using the basic parallel and +series functions would look like this: + +```js +async.parallel([ + function(callback){ + // async code to get some data + }, + function(callback){ + // async code to create a directory to store a file in + // this is run at the same time as getting the data + } +], +function(err, results){ + async.series([ + function(callback){ + // once there is some data and the directory exists, + // write the data to a file in the directory + }, + function(callback){ + // once the file is written let's email a link to it... + } + ]); +}); +``` + +For a complicated series of async tasks using the auto function makes adding +new tasks much easier and makes the code more readable. + + +--------------------------------------- + + +### iterator(tasks) + +Creates an iterator function which calls the next function in the array, +returning a continuation to call the next one after that. It's also possible to +'peek' the next iterator by doing iterator.next(). + +This function is used internally by the async module but can be useful when +you want to manually control the flow of functions in series. + +__Arguments__ + +* tasks - An array of functions to run. + +__Example__ + +```js +var iterator = async.iterator([ + function(){ sys.p('one'); }, + function(){ sys.p('two'); }, + function(){ sys.p('three'); } +]); + +node> var iterator2 = iterator(); +'one' +node> var iterator3 = iterator2(); +'two' +node> iterator3(); +'three' +node> var nextfn = iterator2.next(); +node> nextfn(); +'three' +``` + +--------------------------------------- + + +### apply(function, arguments..) + +Creates a continuation function with some arguments already applied, a useful +shorthand when combined with other control flow functions. Any arguments +passed to the returned function are added to the arguments originally passed +to apply. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to automatically apply when the + continuation is called. + +__Example__ + +```js +// using apply + +async.parallel([ + async.apply(fs.writeFile, 'testfile1', 'test1'), + async.apply(fs.writeFile, 'testfile2', 'test2'), +]); + + +// the same process without using apply + +async.parallel([ + function(callback){ + fs.writeFile('testfile1', 'test1', callback); + }, + function(callback){ + fs.writeFile('testfile2', 'test2', callback); + } +]); +``` + +It's possible to pass any number of additional arguments when calling the +continuation: + +```js +node> var fn = async.apply(sys.puts, 'one'); +node> fn('two', 'three'); +one +two +three +``` + +--------------------------------------- + + +### nextTick(callback) + +Calls the callback on a later loop around the event loop. In node.js this just +calls process.nextTick, in the browser it falls back to setImmediate(callback) +if available, otherwise setTimeout(callback, 0), which means other higher priority +events may precede the execution of the callback. + +This is used internally for browser-compatibility purposes. + +__Arguments__ + +* callback - The function to call on a later loop around the event loop. + +__Example__ + +```js +var call_order = []; +async.nextTick(function(){ + call_order.push('two'); + // call_order now equals ['one','two'] +}); +call_order.push('one') +``` + + +### times(n, callback) + +Calls the callback n times and accumulates results in the same manner +you would use with async.map. + +__Arguments__ + +* n - The number of times to run the function. +* callback - The function to call n times. + +__Example__ + +```js +// Pretend this is some complicated async factory +var createUser = function(id, callback) { + callback(null, { + id: 'user' + id + }) +} +// generate 5 users +async.times(5, function(n, next){ + createUser(n, function(err, user) { + next(err, user) + }) +}, function(err, users) { + // we should now have 5 users +}); +``` + + +### timesSeries(n, callback) + +The same as times only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. The results array will be in the same order as the original. + + +## Utils + + +### memoize(fn, [hasher]) + +Caches the results of an async function. When creating a hash to store function +results against, the callback is omitted from the hash and an optional hash +function can be used. + +The cache of results is exposed as the `memo` property of the function returned +by `memoize`. + +__Arguments__ + +* fn - the function you to proxy and cache results from. +* hasher - an optional function for generating a custom hash for storing + results, it has all the arguments applied to it apart from the callback, and + must be synchronous. + +__Example__ + +```js +var slow_fn = function (name, callback) { + // do something + callback(null, result); +}; +var fn = async.memoize(slow_fn); + +// fn can now be used as if it were slow_fn +fn('some name', function () { + // callback +}); +``` + + +### unmemoize(fn) + +Undoes a memoized function, reverting it to the original, unmemoized +form. Comes handy in tests. + +__Arguments__ + +* fn - the memoized function + + +### log(function, arguments) + +Logs the result of an async function to the console. Only works in node.js or +in browsers that support console.log and console.error (such as FF and Chrome). +If multiple arguments are returned from the async function, console.log is +called on each argument in order. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to apply to the function. + +__Example__ + +```js +var hello = function(name, callback){ + setTimeout(function(){ + callback(null, 'hello ' + name); + }, 1000); +}; +``` +```js +node> async.log(hello, 'world'); +'hello world' +``` + +--------------------------------------- + + +### dir(function, arguments) + +Logs the result of an async function to the console using console.dir to +display the properties of the resulting object. Only works in node.js or +in browsers that support console.dir and console.error (such as FF and Chrome). +If multiple arguments are returned from the async function, console.dir is +called on each argument in order. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to apply to the function. + +__Example__ + +```js +var hello = function(name, callback){ + setTimeout(function(){ + callback(null, {hello: name}); + }, 1000); +}; +``` +```js +node> async.dir(hello, 'world'); +{hello: 'world'} +``` + +--------------------------------------- + + +### noConflict() + +Changes the value of async back to its original value, returning a reference to the +async object. diff --git a/node_modules/uglify-js/node_modules/async/component.json b/node_modules/uglify-js/node_modules/async/component.json new file mode 100644 index 0000000..bbb0115 --- /dev/null +++ b/node_modules/uglify-js/node_modules/async/component.json @@ -0,0 +1,11 @@ +{ + "name": "async", + "repo": "caolan/async", + "description": "Higher-order functions and common patterns for asynchronous code", + "version": "0.1.23", + "keywords": [], + "dependencies": {}, + "development": {}, + "main": "lib/async.js", + "scripts": [ "lib/async.js" ] +} diff --git a/node_modules/uglify-js/node_modules/async/lib/async.js b/node_modules/uglify-js/node_modules/async/lib/async.js new file mode 100644 index 0000000..1eebb15 --- /dev/null +++ b/node_modules/uglify-js/node_modules/async/lib/async.js @@ -0,0 +1,958 @@ +/*global setImmediate: false, setTimeout: false, console: false */ +(function () { + + var async = {}; + + // global on the server, window in the browser + var root, previous_async; + + root = this; + if (root != null) { + previous_async = root.async; + } + + async.noConflict = function () { + root.async = previous_async; + return async; + }; + + function only_once(fn) { + var called = false; + return function() { + if (called) throw new Error("Callback was already called."); + called = true; + fn.apply(root, arguments); + } + } + + //// cross-browser compatiblity functions //// + + var _each = function (arr, iterator) { + if (arr.forEach) { + return arr.forEach(iterator); + } + for (var i = 0; i < arr.length; i += 1) { + iterator(arr[i], i, arr); + } + }; + + var _map = function (arr, iterator) { + if (arr.map) { + return arr.map(iterator); + } + var results = []; + _each(arr, function (x, i, a) { + results.push(iterator(x, i, a)); + }); + return results; + }; + + var _reduce = function (arr, iterator, memo) { + if (arr.reduce) { + return arr.reduce(iterator, memo); + } + _each(arr, function (x, i, a) { + memo = iterator(memo, x, i, a); + }); + return memo; + }; + + var _keys = function (obj) { + if (Object.keys) { + return Object.keys(obj); + } + var keys = []; + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + keys.push(k); + } + } + return keys; + }; + + //// exported async module functions //// + + //// nextTick implementation with browser-compatible fallback //// + if (typeof process === 'undefined' || !(process.nextTick)) { + if (typeof setImmediate === 'function') { + async.nextTick = function (fn) { + // not a direct alias for IE10 compatibility + setImmediate(fn); + }; + async.setImmediate = async.nextTick; + } + else { + async.nextTick = function (fn) { + setTimeout(fn, 0); + }; + async.setImmediate = async.nextTick; + } + } + else { + async.nextTick = process.nextTick; + if (typeof setImmediate !== 'undefined') { + async.setImmediate = function (fn) { + // not a direct alias for IE10 compatibility + setImmediate(fn); + }; + } + else { + async.setImmediate = async.nextTick; + } + } + + async.each = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); + } + var completed = 0; + _each(arr, function (x) { + iterator(x, only_once(function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed >= arr.length) { + callback(null); + } + } + })); + }); + }; + async.forEach = async.each; + + async.eachSeries = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); + } + var completed = 0; + var iterate = function () { + iterator(arr[completed], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed >= arr.length) { + callback(null); + } + else { + iterate(); + } + } + }); + }; + iterate(); + }; + async.forEachSeries = async.eachSeries; + + async.eachLimit = function (arr, limit, iterator, callback) { + var fn = _eachLimit(limit); + fn.apply(null, [arr, iterator, callback]); + }; + async.forEachLimit = async.eachLimit; + + var _eachLimit = function (limit) { + + return function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length || limit <= 0) { + return callback(); + } + var completed = 0; + var started = 0; + var running = 0; + + (function replenish () { + if (completed >= arr.length) { + return callback(); + } + + while (running < limit && started < arr.length) { + started += 1; + running += 1; + iterator(arr[started - 1], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + running -= 1; + if (completed >= arr.length) { + callback(); + } + else { + replenish(); + } + } + }); + } + })(); + }; + }; + + + var doParallel = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.each].concat(args)); + }; + }; + var doParallelLimit = function(limit, fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [_eachLimit(limit)].concat(args)); + }; + }; + var doSeries = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.eachSeries].concat(args)); + }; + }; + + + var _asyncMap = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (err, v) { + results[x.index] = v; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + }; + async.map = doParallel(_asyncMap); + async.mapSeries = doSeries(_asyncMap); + async.mapLimit = function (arr, limit, iterator, callback) { + return _mapLimit(limit)(arr, iterator, callback); + }; + + var _mapLimit = function(limit) { + return doParallelLimit(limit, _asyncMap); + }; + + // reduce only has a series version, as doing reduce in parallel won't + // work in many situations. + async.reduce = function (arr, memo, iterator, callback) { + async.eachSeries(arr, function (x, callback) { + iterator(memo, x, function (err, v) { + memo = v; + callback(err); + }); + }, function (err) { + callback(err, memo); + }); + }; + // inject alias + async.inject = async.reduce; + // foldl alias + async.foldl = async.reduce; + + async.reduceRight = function (arr, memo, iterator, callback) { + var reversed = _map(arr, function (x) { + return x; + }).reverse(); + async.reduce(reversed, memo, iterator, callback); + }; + // foldr alias + async.foldr = async.reduceRight; + + var _filter = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.filter = doParallel(_filter); + async.filterSeries = doSeries(_filter); + // select alias + async.select = async.filter; + async.selectSeries = async.filterSeries; + + var _reject = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (!v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.reject = doParallel(_reject); + async.rejectSeries = doSeries(_reject); + + var _detect = function (eachfn, arr, iterator, main_callback) { + eachfn(arr, function (x, callback) { + iterator(x, function (result) { + if (result) { + main_callback(x); + main_callback = function () {}; + } + else { + callback(); + } + }); + }, function (err) { + main_callback(); + }); + }; + async.detect = doParallel(_detect); + async.detectSeries = doSeries(_detect); + + async.some = function (arr, iterator, main_callback) { + async.each(arr, function (x, callback) { + iterator(x, function (v) { + if (v) { + main_callback(true); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(false); + }); + }; + // any alias + async.any = async.some; + + async.every = function (arr, iterator, main_callback) { + async.each(arr, function (x, callback) { + iterator(x, function (v) { + if (!v) { + main_callback(false); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(true); + }); + }; + // all alias + async.all = async.every; + + async.sortBy = function (arr, iterator, callback) { + async.map(arr, function (x, callback) { + iterator(x, function (err, criteria) { + if (err) { + callback(err); + } + else { + callback(null, {value: x, criteria: criteria}); + } + }); + }, function (err, results) { + if (err) { + return callback(err); + } + else { + var fn = function (left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }; + callback(null, _map(results.sort(fn), function (x) { + return x.value; + })); + } + }); + }; + + async.auto = function (tasks, callback) { + callback = callback || function () {}; + var keys = _keys(tasks); + if (!keys.length) { + return callback(null); + } + + var results = {}; + + var listeners = []; + var addListener = function (fn) { + listeners.unshift(fn); + }; + var removeListener = function (fn) { + for (var i = 0; i < listeners.length; i += 1) { + if (listeners[i] === fn) { + listeners.splice(i, 1); + return; + } + } + }; + var taskComplete = function () { + _each(listeners.slice(0), function (fn) { + fn(); + }); + }; + + addListener(function () { + if (_keys(results).length === keys.length) { + callback(null, results); + callback = function () {}; + } + }); + + _each(keys, function (k) { + var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; + var taskCallback = function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + if (err) { + var safeResults = {}; + _each(_keys(results), function(rkey) { + safeResults[rkey] = results[rkey]; + }); + safeResults[k] = args; + callback(err, safeResults); + // stop subsequent errors hitting callback multiple times + callback = function () {}; + } + else { + results[k] = args; + async.setImmediate(taskComplete); + } + }; + var requires = task.slice(0, Math.abs(task.length - 1)) || []; + var ready = function () { + return _reduce(requires, function (a, x) { + return (a && results.hasOwnProperty(x)); + }, true) && !results.hasOwnProperty(k); + }; + if (ready()) { + task[task.length - 1](taskCallback, results); + } + else { + var listener = function () { + if (ready()) { + removeListener(listener); + task[task.length - 1](taskCallback, results); + } + }; + addListener(listener); + } + }); + }; + + async.waterfall = function (tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor !== Array) { + var err = new Error('First argument to waterfall must be an array of functions'); + return callback(err); + } + if (!tasks.length) { + return callback(); + } + var wrapIterator = function (iterator) { + return function (err) { + if (err) { + callback.apply(null, arguments); + callback = function () {}; + } + else { + var args = Array.prototype.slice.call(arguments, 1); + var next = iterator.next(); + if (next) { + args.push(wrapIterator(next)); + } + else { + args.push(callback); + } + async.setImmediate(function () { + iterator.apply(null, args); + }); + } + }; + }; + wrapIterator(async.iterator(tasks))(); + }; + + var _parallel = function(eachfn, tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor === Array) { + eachfn.map(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + eachfn.each(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.parallel = function (tasks, callback) { + _parallel({ map: async.map, each: async.each }, tasks, callback); + }; + + async.parallelLimit = function(tasks, limit, callback) { + _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback); + }; + + async.series = function (tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor === Array) { + async.mapSeries(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + async.eachSeries(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.iterator = function (tasks) { + var makeCallback = function (index) { + var fn = function () { + if (tasks.length) { + tasks[index].apply(null, arguments); + } + return fn.next(); + }; + fn.next = function () { + return (index < tasks.length - 1) ? makeCallback(index + 1): null; + }; + return fn; + }; + return makeCallback(0); + }; + + async.apply = function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + return function () { + return fn.apply( + null, args.concat(Array.prototype.slice.call(arguments)) + ); + }; + }; + + var _concat = function (eachfn, arr, fn, callback) { + var r = []; + eachfn(arr, function (x, cb) { + fn(x, function (err, y) { + r = r.concat(y || []); + cb(err); + }); + }, function (err) { + callback(err, r); + }); + }; + async.concat = doParallel(_concat); + async.concatSeries = doSeries(_concat); + + async.whilst = function (test, iterator, callback) { + if (test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.whilst(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.doWhilst = function (iterator, test, callback) { + iterator(function (err) { + if (err) { + return callback(err); + } + if (test()) { + async.doWhilst(iterator, test, callback); + } + else { + callback(); + } + }); + }; + + async.until = function (test, iterator, callback) { + if (!test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.until(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.doUntil = function (iterator, test, callback) { + iterator(function (err) { + if (err) { + return callback(err); + } + if (!test()) { + async.doUntil(iterator, test, callback); + } + else { + callback(); + } + }); + }; + + async.queue = function (worker, concurrency) { + if (concurrency === undefined) { + concurrency = 1; + } + function _insert(q, data, pos, callback) { + if(data.constructor !== Array) { + data = [data]; + } + _each(data, function(task) { + var item = { + data: task, + callback: typeof callback === 'function' ? callback : null + }; + + if (pos) { + q.tasks.unshift(item); + } else { + q.tasks.push(item); + } + + if (q.saturated && q.tasks.length === concurrency) { + q.saturated(); + } + async.setImmediate(q.process); + }); + } + + var workers = 0; + var q = { + tasks: [], + concurrency: concurrency, + saturated: null, + empty: null, + drain: null, + push: function (data, callback) { + _insert(q, data, false, callback); + }, + unshift: function (data, callback) { + _insert(q, data, true, callback); + }, + process: function () { + if (workers < q.concurrency && q.tasks.length) { + var task = q.tasks.shift(); + if (q.empty && q.tasks.length === 0) { + q.empty(); + } + workers += 1; + var next = function () { + workers -= 1; + if (task.callback) { + task.callback.apply(task, arguments); + } + if (q.drain && q.tasks.length + workers === 0) { + q.drain(); + } + q.process(); + }; + var cb = only_once(next); + worker(task.data, cb); + } + }, + length: function () { + return q.tasks.length; + }, + running: function () { + return workers; + } + }; + return q; + }; + + async.cargo = function (worker, payload) { + var working = false, + tasks = []; + + var cargo = { + tasks: tasks, + payload: payload, + saturated: null, + empty: null, + drain: null, + push: function (data, callback) { + if(data.constructor !== Array) { + data = [data]; + } + _each(data, function(task) { + tasks.push({ + data: task, + callback: typeof callback === 'function' ? callback : null + }); + if (cargo.saturated && tasks.length === payload) { + cargo.saturated(); + } + }); + async.setImmediate(cargo.process); + }, + process: function process() { + if (working) return; + if (tasks.length === 0) { + if(cargo.drain) cargo.drain(); + return; + } + + var ts = typeof payload === 'number' + ? tasks.splice(0, payload) + : tasks.splice(0); + + var ds = _map(ts, function (task) { + return task.data; + }); + + if(cargo.empty) cargo.empty(); + working = true; + worker(ds, function () { + working = false; + + var args = arguments; + _each(ts, function (data) { + if (data.callback) { + data.callback.apply(null, args); + } + }); + + process(); + }); + }, + length: function () { + return tasks.length; + }, + running: function () { + return working; + } + }; + return cargo; + }; + + var _console_fn = function (name) { + return function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + fn.apply(null, args.concat([function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (typeof console !== 'undefined') { + if (err) { + if (console.error) { + console.error(err); + } + } + else if (console[name]) { + _each(args, function (x) { + console[name](x); + }); + } + } + }])); + }; + }; + async.log = _console_fn('log'); + async.dir = _console_fn('dir'); + /*async.info = _console_fn('info'); + async.warn = _console_fn('warn'); + async.error = _console_fn('error');*/ + + async.memoize = function (fn, hasher) { + var memo = {}; + var queues = {}; + hasher = hasher || function (x) { + return x; + }; + var memoized = function () { + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + var key = hasher.apply(null, args); + if (key in memo) { + callback.apply(null, memo[key]); + } + else if (key in queues) { + queues[key].push(callback); + } + else { + queues[key] = [callback]; + fn.apply(null, args.concat([function () { + memo[key] = arguments; + var q = queues[key]; + delete queues[key]; + for (var i = 0, l = q.length; i < l; i++) { + q[i].apply(null, arguments); + } + }])); + } + }; + memoized.memo = memo; + memoized.unmemoized = fn; + return memoized; + }; + + async.unmemoize = function (fn) { + return function () { + return (fn.unmemoized || fn).apply(null, arguments); + }; + }; + + async.times = function (count, iterator, callback) { + var counter = []; + for (var i = 0; i < count; i++) { + counter.push(i); + } + return async.map(counter, iterator, callback); + }; + + async.timesSeries = function (count, iterator, callback) { + var counter = []; + for (var i = 0; i < count; i++) { + counter.push(i); + } + return async.mapSeries(counter, iterator, callback); + }; + + async.compose = function (/* functions... */) { + var fns = Array.prototype.reverse.call(arguments); + return function () { + var that = this; + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + async.reduce(fns, args, function (newargs, fn, cb) { + fn.apply(that, newargs.concat([function () { + var err = arguments[0]; + var nextargs = Array.prototype.slice.call(arguments, 1); + cb(err, nextargs); + }])) + }, + function (err, results) { + callback.apply(that, [err].concat(results)); + }); + }; + }; + + var _applyEach = function (eachfn, fns /*args...*/) { + var go = function () { + var that = this; + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + return eachfn(fns, function (fn, cb) { + fn.apply(that, args.concat([cb])); + }, + callback); + }; + if (arguments.length > 2) { + var args = Array.prototype.slice.call(arguments, 2); + return go.apply(this, args); + } + else { + return go; + } + }; + async.applyEach = doParallel(_applyEach); + async.applyEachSeries = doSeries(_applyEach); + + async.forever = function (fn, callback) { + function next(err) { + if (err) { + if (callback) { + return callback(err); + } + throw err; + } + fn(next); + } + next(); + }; + + // AMD / RequireJS + if (typeof define !== 'undefined' && define.amd) { + define([], function () { + return async; + }); + } + // Node.js + else if (typeof module !== 'undefined' && module.exports) { + module.exports = async; + } + // included directly via + + diff --git a/node_modules/uglify-to-browserify/.npmignore b/node_modules/uglify-to-browserify/.npmignore new file mode 100644 index 0000000..66d015b --- /dev/null +++ b/node_modules/uglify-to-browserify/.npmignore @@ -0,0 +1,14 @@ +lib-cov +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz +pids +logs +results +npm-debug.log +node_modules +/test/output.js diff --git a/node_modules/uglify-to-browserify/.travis.yml b/node_modules/uglify-to-browserify/.travis.yml new file mode 100644 index 0000000..9a61f6b --- /dev/null +++ b/node_modules/uglify-to-browserify/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "0.10" \ No newline at end of file diff --git a/node_modules/uglify-to-browserify/LICENSE b/node_modules/uglify-to-browserify/LICENSE new file mode 100644 index 0000000..dfb0b19 --- /dev/null +++ b/node_modules/uglify-to-browserify/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013 Forbes Lindesay + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/uglify-to-browserify/README.md b/node_modules/uglify-to-browserify/README.md new file mode 100644 index 0000000..99685da --- /dev/null +++ b/node_modules/uglify-to-browserify/README.md @@ -0,0 +1,15 @@ +# uglify-to-browserify + +A transform to make UglifyJS work in browserify. + +[![Build Status](https://travis-ci.org/ForbesLindesay/uglify-to-browserify.png?branch=master)](https://travis-ci.org/ForbesLindesay/uglify-to-browserify) +[![Dependency Status](https://gemnasium.com/ForbesLindesay/uglify-to-browserify.png)](https://gemnasium.com/ForbesLindesay/uglify-to-browserify) +[![NPM version](https://badge.fury.io/js/uglify-to-browserify.png)](http://badge.fury.io/js/uglify-to-browserify) + +## Installation + + npm install uglify-to-browserify + +## License + + MIT \ No newline at end of file diff --git a/node_modules/uglify-to-browserify/index.js b/node_modules/uglify-to-browserify/index.js new file mode 100644 index 0000000..2cea629 --- /dev/null +++ b/node_modules/uglify-to-browserify/index.js @@ -0,0 +1,49 @@ +'use strict' + +var fs = require('fs') +var PassThrough = require('stream').PassThrough +var Transform = require('stream').Transform + +if (typeof Transform === 'undefined') { + throw new Error('UglifyJS only supports browserify when using node >= 0.10.x') +} + +var cache = {} +module.exports = transform +function transform(file) { + if (!/tools\/node\.js$/.test(file.replace(/\\/g,'/'))) return new PassThrough(); + if (cache[file]) return makeStream(cache[file]) + var uglify = require(file) + var src = 'var sys = require("util");\nvar MOZ_SourceMap = require("source-map");\nvar UglifyJS = exports;\n' + uglify.FILES.map(function (path) { return fs.readFileSync(path, 'utf8') }).join('\n') + + var ast = uglify.parse(src) + ast.figure_out_scope() + + var variables = ast.variables + .map(function (node, name) { + return name + }) + + src += '\n\n' + variables.map(function (v) { return 'exports.' + v + ' = ' + v + ';' }).join('\n') + '\n\n' + + src += 'exports.AST_Node.warn_function = function (txt) { if (typeof console != "undefined" && typeof console.warn === "function") console.warn(txt) }\n\n' + + src += 'exports.minify = ' + uglify.minify.toString() + ';\n\n' + src += 'exports.describe_ast = ' + uglify.describe_ast.toString() + ';' + + // TODO: remove once https://github.com/substack/node-browserify/issues/631 is resolved + src = src.replace(/"for"/g, '"fo" + "r"') + + cache[file] = src + return makeStream(src); +} + +function makeStream(src) { + var res = new Transform(); + res._transform = function (chunk, encoding, callback) { callback() } + res._flush = function (callback) { + res.push(src) + callback() + } + return res; +} diff --git a/node_modules/uglify-to-browserify/package.json b/node_modules/uglify-to-browserify/package.json new file mode 100644 index 0000000..62f49de --- /dev/null +++ b/node_modules/uglify-to-browserify/package.json @@ -0,0 +1,80 @@ +{ + "_args": [ + [ + { + "raw": "uglify-to-browserify@~1.0.0", + "scope": null, + "escapedName": "uglify-to-browserify", + "name": "uglify-to-browserify", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/uglify-js" + ] + ], + "_from": "uglify-to-browserify@>=1.0.0 <1.1.0", + "_id": "uglify-to-browserify@1.0.2", + "_inCache": true, + "_location": "/uglify-to-browserify", + "_npmUser": { + "name": "forbeslindesay", + "email": "forbes@lindeay.co.uk" + }, + "_npmVersion": "1.3.14", + "_phantomChildren": {}, + "_requested": { + "raw": "uglify-to-browserify@~1.0.0", + "scope": null, + "escapedName": "uglify-to-browserify", + "name": "uglify-to-browserify", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/uglify-js" + ], + "_resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "_shasum": "6e0924d6bda6b5afe349e39a6d632850a0f882b7", + "_shrinkwrap": null, + "_spec": "uglify-to-browserify@~1.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/uglify-js", + "author": { + "name": "ForbesLindesay" + }, + "bugs": { + "url": "https://github.com/ForbesLindesay/uglify-to-browserify/issues" + }, + "dependencies": {}, + "description": "A transform to make UglifyJS work in browserify.", + "devDependencies": { + "source-map": "~0.1.27", + "uglify-js": "~2.4.0" + }, + "directories": {}, + "dist": { + "shasum": "6e0924d6bda6b5afe349e39a6d632850a0f882b7", + "tarball": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz" + }, + "homepage": "https://github.com/ForbesLindesay/uglify-to-browserify", + "keywords": [], + "license": "MIT", + "maintainers": [ + { + "name": "forbeslindesay", + "email": "forbes@lindesay.co.uk" + } + ], + "name": "uglify-to-browserify", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/ForbesLindesay/uglify-to-browserify.git" + }, + "scripts": { + "test": "node test/index.js" + }, + "version": "1.0.2" +} diff --git a/node_modules/uglify-to-browserify/test/index.js b/node_modules/uglify-to-browserify/test/index.js new file mode 100644 index 0000000..4117894 --- /dev/null +++ b/node_modules/uglify-to-browserify/test/index.js @@ -0,0 +1,22 @@ +var fs = require('fs') +var br = require('../') +var test = fs.readFileSync(require.resolve('uglify-js/test/run-tests.js'), 'utf8') + .replace(/^#.*\n/, '') + +var transform = br(require.resolve('uglify-js')) +transform.pipe(fs.createWriteStream(__dirname + '/output.js')) + .on('close', function () { + Function('module,require', test)({ + filename: require.resolve('uglify-js/test/run-tests.js') + }, + function (name) { + if (name === '../tools/node') { + return require('./output.js') + } else if (/^[a-z]+$/.test(name)) { + return require(name) + } else { + throw new Error('I didn\'t expect you to require ' + name) + } + }) + }) +transform.end(fs.readFileSync(require.resolve('uglify-js'), 'utf8')) \ No newline at end of file diff --git a/node_modules/underscore.deferred/.npmignore b/node_modules/underscore.deferred/.npmignore new file mode 100644 index 0000000..471e727 --- /dev/null +++ b/node_modules/underscore.deferred/.npmignore @@ -0,0 +1,8 @@ +.DS_Store +.rvmrc +.bundle/* +tmp/ +node_modules/ +.DS_Store? +**/*/.DS_Store +dist/underscore.deferred* \ No newline at end of file diff --git a/node_modules/underscore.deferred/.travis.yml b/node_modules/underscore.deferred/.travis.yml new file mode 100644 index 0000000..6430fe5 --- /dev/null +++ b/node_modules/underscore.deferred/.travis.yml @@ -0,0 +1,7 @@ +language: node_js +node_js: + - 0.6 + - 0.8 +before_script: + - "export DISPLAY=:99.0" + - "sh -e /etc/init.d/xvfb start" diff --git a/node_modules/underscore.deferred/LICENSE-MIT b/node_modules/underscore.deferred/LICENSE-MIT new file mode 100644 index 0000000..1217c7e --- /dev/null +++ b/node_modules/underscore.deferred/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) 2012 Sam Breed + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/underscore.deferred/build.js b/node_modules/underscore.deferred/build.js new file mode 100644 index 0000000..5620295 --- /dev/null +++ b/node_modules/underscore.deferred/build.js @@ -0,0 +1 @@ +require('grunt').cli(); diff --git a/node_modules/underscore.deferred/dist/.gitkeep b/node_modules/underscore.deferred/dist/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/underscore.deferred/examples/commonjs-dfd.js b/node_modules/underscore.deferred/examples/commonjs-dfd.js new file mode 100644 index 0000000..31a24f2 --- /dev/null +++ b/node_modules/underscore.deferred/examples/commonjs-dfd.js @@ -0,0 +1,23 @@ +var _ = require('underscore')._; +_.mixin( require('../underscore.deferred') ); + +function asyncEvent(){ + var dfd = new _.Deferred(); + setTimeout(function(){ + dfd.resolve("hurray"); + }, Math.floor(Math.random()*100)); + setTimeout(function(){ + dfd.reject("sorry"); + }, Math.floor(Math.random()*100)); + return dfd.promise(); +} +// Attach a done and fail handler for the asyncEvent +_.when( asyncEvent() ).then( + function(status){ + console.log( status+', things are going well' ); + }, + function(status){ + console.log( status+', you fail this time' ); + } +); + diff --git a/node_modules/underscore.deferred/grunt.js b/node_modules/underscore.deferred/grunt.js new file mode 100644 index 0000000..b7bccd8 --- /dev/null +++ b/node_modules/underscore.deferred/grunt.js @@ -0,0 +1,58 @@ +module.exports = function(grunt) { + + // Project configuration. + grunt.initConfig({ + pkg: '', + meta: { + banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' + + '<%= grunt.template.today("yyyy-mm-dd") %>\n' + + '<%= pkg.homepage ? "* " + pkg.homepage + "\n" : "" %>' + + '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' + + ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */' + }, + concat: { + dist: { + src: ['', '.js>'], + dest: 'dist/<%= pkg.name %>.js' + } + }, + min: { + dist: { + src: ['', ''], + dest: 'dist/<%= pkg.name %>.min.js' + } + }, + qunit: { + files: ['test/*.html'] + }, + lint: { + files: ['grunt.js', 'underscore.deferred.js'] + }, + watch: { + files: '', + tasks: 'lint test' + }, + jshint: { + options: { + curly: true, + eqeqeq: true, + latedef: true, + newcap: true, + noarg: true, + sub: true, + undef: true, + boss: true, + eqnull: true + }, + globals: { + exports: true, + module: false + } + }, + uglify: {} + }); + + // Default task. + grunt.registerTask('default', 'lint qunit concat min'); + +}; diff --git a/node_modules/underscore.deferred/lib/ender.js b/node_modules/underscore.deferred/lib/ender.js new file mode 100644 index 0000000..e53e778 --- /dev/null +++ b/node_modules/underscore.deferred/lib/ender.js @@ -0,0 +1,2 @@ +var dfd = require('underscore.deferred'); +ender.ender(dfd, true); diff --git a/node_modules/underscore.deferred/package.json b/node_modules/underscore.deferred/package.json new file mode 100644 index 0000000..5ad3d53 --- /dev/null +++ b/node_modules/underscore.deferred/package.json @@ -0,0 +1,95 @@ +{ + "_args": [ + [ + { + "raw": "underscore.deferred@~0.1.4", + "scope": null, + "escapedName": "underscore.deferred", + "name": "underscore.deferred", + "rawSpec": "~0.1.4", + "spec": ">=0.1.4 <0.2.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt-s3" + ] + ], + "_from": "underscore.deferred@>=0.1.4 <0.2.0", + "_id": "underscore.deferred@0.1.5", + "_inCache": true, + "_location": "/underscore.deferred", + "_phantomChildren": {}, + "_requested": { + "raw": "underscore.deferred@~0.1.4", + "scope": null, + "escapedName": "underscore.deferred", + "name": "underscore.deferred", + "rawSpec": "~0.1.4", + "spec": ">=0.1.4 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt-s3" + ], + "_resolved": "https://registry.npmjs.org/underscore.deferred/-/underscore.deferred-0.1.5.tgz", + "_shasum": "47ead60c988bf0cf3220bf8843f362e0e824e689", + "_shrinkwrap": null, + "_spec": "underscore.deferred@~0.1.4", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt-s3", + "author": { + "name": "Sam Breed", + "email": "sam@quickleft.com" + }, + "bugs": { + "url": "https://github.com/wookiehangover/underscore.deferred/issues" + }, + "dependencies": {}, + "description": "jQuery style Deferreds", + "devDependencies": { + "grunt": "~0.3.9", + "mocha": "*", + "rimraf": "~2.0.1", + "underscore": "*" + }, + "directories": {}, + "dist": { + "shasum": "47ead60c988bf0cf3220bf8843f362e0e824e689", + "tarball": "https://registry.npmjs.org/underscore.deferred/-/underscore.deferred-0.1.5.tgz" + }, + "ender": "./lib/ender.js", + "engines": { + "node": "*" + }, + "homepage": "https://github.com/wookiehangover/underscore.deferred", + "keywords": [ + "underscore deferreds", + "deferreds", + "underscore", + "flow-control", + "deferred", + "ender" + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/wookiehangover/underscore.deferred/blob/master/LICENSE-MIT" + } + ], + "main": "./underscore.deferred.js", + "maintainers": [ + { + "name": "wookiehangover", + "email": "sam@quickleft.com" + } + ], + "name": "underscore.deferred", + "optionalDependencies": {}, + "readme": "# Underscore.Deferred\n\n[![Build Status](https://secure.travis-ci.org/wookiehangover/underscore.deferred.png?branch=master)](http://travis-ci.org/wookiehangover/underscore.deferred)\n\nv0.1.5\n\n**Please note that as of 0.1.4 underscore.deferred will be ALL LOWERCASE on\nnpm.** The camelcasing was a mistake from the outset, please update your\n`package.json` appropriately.\n\nThis is a port of jQuery.Deferred as an Underscore mixin, but it can be\nused without any depencencies. It currently matches the Deferred specifications\nand implementation from jQuery 1.7.2, with all the associated helpers.\n\n## Deferred's are great, let's take them everywhere\n\njQuery offers a robust, consistent and well documented API; this project aims\nto make it portable. jQuery added a handful of helper methods to their\nimplementation of the [Common.js Promises Spec][promise], and they're faithfully\nreproduced without any dependencies.\n\nunderscore.deferred provides complete pairity with the jQuery Deferred\nAPI. Here are some of the method implemented:\n\n* [always](http://api.jquery.com/deferred.always/)\n* [done](http://api.jquery.com/deferred.done/)\n* [fail](http://api.jquery.com/deferred.fail/)\n* [notify](http://api.jquery.com/deferred.notify/)\n* [notifyWith](http://api.jquery.com/deferred.notifywith/)\n* [pipe](http://api.jquery.com/deferred.pipe/)\n* [promise](http://api.jquery.com/deferred.promise/)\n* [resolve](http://api.jquery.com/deferred.resolve/)\n* [reject](http://api.jquery.com/deferred.reject/)\n* [state](http://api.jquery.com/deferred.notifywith/)\n* [then](http://api.jquery.com/deferred.then/)\n\nFor the complete API documentation, look to the [jQuery Docs][jquery-docs].\n\n## Usage\n\nunderscore.deferred works on the server and in the browser.\n\nIn the browser, just require it like you would any other file. If you're\nincluding Underscore on the page, make sure you include it before\nunderscore.deferred. If you don't have Underscore, the plugin attaches to\n`window._`.\n\nAddionally, underscore.Deferred can be used with the [Ender.js build\ntool][ender], if you're into that sort of thing.\n\nOn the server, simply install via npm and require normally. If you'd like to\nuse it as an Underscore module, just do this:\n\n var _ = require('underscore')._\n _.mixin( require('underscore.deferred') );\n\nBut keep in mind that Underscore is not a strict requirement, and assigning it\nto another namespace will always work.\n\n## Build\n\nOne time setup command:\n\n```\n$ npm install\n```\n\nTo build with [grunt](https://github.com/cowboy/grunt)\n\n```\n$ node build\n```\n\nTo run headless Qunit tests (must have phantomjs in your path)\n\n```\n$ node build qunit\n```\n\n## Contributors\n\n* [rwldrn](https://github.com/rwldrn)\n* [tbranyen](https://github.com/tbranyen)\n* [taxillian](https://github.com/taxilian)\n* [danheberden](https://github.com/danheberden)\n\n## Roadmap\n\nThe goal is to slim the code footprint for robust deferreds as much as\npossible while maintaining mixin integration with Underscore and faithfullness\nto the jQuery API.\n\nThis is a work in progress, feel free to contribute.\n\nMIT License.\n\n[promise]: http://wiki.commonjs.org/wiki/Promises\n[jquery-docs]: http://api.jquery.com/category/deferred-object/\n[ender]: http://ender.no.de/\n", + "repository": { + "type": "git", + "url": "git://github.com/wookiehangover/underscore.deferred.git" + }, + "scripts": { + "test": "grunt qunit" + }, + "version": "0.1.5" +} diff --git a/node_modules/underscore.deferred/readme.md b/node_modules/underscore.deferred/readme.md new file mode 100644 index 0000000..c18d249 --- /dev/null +++ b/node_modules/underscore.deferred/readme.md @@ -0,0 +1,99 @@ +# Underscore.Deferred + +[![Build Status](https://secure.travis-ci.org/wookiehangover/underscore.deferred.png?branch=master)](http://travis-ci.org/wookiehangover/underscore.deferred) + +v0.1.5 + +**Please note that as of 0.1.4 underscore.deferred will be ALL LOWERCASE on +npm.** The camelcasing was a mistake from the outset, please update your +`package.json` appropriately. + +This is a port of jQuery.Deferred as an Underscore mixin, but it can be +used without any depencencies. It currently matches the Deferred specifications +and implementation from jQuery 1.7.2, with all the associated helpers. + +## Deferred's are great, let's take them everywhere + +jQuery offers a robust, consistent and well documented API; this project aims +to make it portable. jQuery added a handful of helper methods to their +implementation of the [Common.js Promises Spec][promise], and they're faithfully +reproduced without any dependencies. + +underscore.deferred provides complete pairity with the jQuery Deferred +API. Here are some of the method implemented: + +* [always](http://api.jquery.com/deferred.always/) +* [done](http://api.jquery.com/deferred.done/) +* [fail](http://api.jquery.com/deferred.fail/) +* [notify](http://api.jquery.com/deferred.notify/) +* [notifyWith](http://api.jquery.com/deferred.notifywith/) +* [pipe](http://api.jquery.com/deferred.pipe/) +* [promise](http://api.jquery.com/deferred.promise/) +* [resolve](http://api.jquery.com/deferred.resolve/) +* [reject](http://api.jquery.com/deferred.reject/) +* [state](http://api.jquery.com/deferred.notifywith/) +* [then](http://api.jquery.com/deferred.then/) + +For the complete API documentation, look to the [jQuery Docs][jquery-docs]. + +## Usage + +underscore.deferred works on the server and in the browser. + +In the browser, just require it like you would any other file. If you're +including Underscore on the page, make sure you include it before +underscore.deferred. If you don't have Underscore, the plugin attaches to +`window._`. + +Addionally, underscore.Deferred can be used with the [Ender.js build +tool][ender], if you're into that sort of thing. + +On the server, simply install via npm and require normally. If you'd like to +use it as an Underscore module, just do this: + + var _ = require('underscore')._ + _.mixin( require('underscore.deferred') ); + +But keep in mind that Underscore is not a strict requirement, and assigning it +to another namespace will always work. + +## Build + +One time setup command: + +``` +$ npm install +``` + +To build with [grunt](https://github.com/cowboy/grunt) + +``` +$ node build +``` + +To run headless Qunit tests (must have phantomjs in your path) + +``` +$ node build qunit +``` + +## Contributors + +* [rwldrn](https://github.com/rwldrn) +* [tbranyen](https://github.com/tbranyen) +* [taxillian](https://github.com/taxilian) +* [danheberden](https://github.com/danheberden) + +## Roadmap + +The goal is to slim the code footprint for robust deferreds as much as +possible while maintaining mixin integration with Underscore and faithfullness +to the jQuery API. + +This is a work in progress, feel free to contribute. + +MIT License. + +[promise]: http://wiki.commonjs.org/wiki/Promises +[jquery-docs]: http://api.jquery.com/category/deferred-object/ +[ender]: http://ender.no.de/ diff --git a/node_modules/underscore.deferred/test/deferred.js b/node_modules/underscore.deferred/test/deferred.js new file mode 100644 index 0000000..84c1d72 --- /dev/null +++ b/node_modules/underscore.deferred/test/deferred.js @@ -0,0 +1,573 @@ +test("its should be part of Underscore", function() { + ok( _.VERSION ); + equal( typeof _.Deferred, 'function' ); +}); + +_.each( [ "", " - new operator" ], function( withNew ) { + + function createDeferred( fn ) { + return withNew ? new _.Deferred( fn ) : _.Deferred( fn ); + } + + test("_.Deferred" + withNew, function() { + + expect( 22 ); + + createDeferred().resolve().then( function() { + ok( true , "Success on resolve" ); + ok( this.isResolved(), "Deferred is resolved" ); + strictEqual( this.state(), "resolved", "Deferred is resolved (state)" ); + }, function() { + ok( false , "Error on resolve" ); + }).always( function() { + ok( true , "Always callback on resolve" ); + }); + + createDeferred().reject().then( function() { + ok( false , "Success on reject" ); + }, function() { + ok( true , "Error on reject" ); + ok( this.isRejected(), "Deferred is rejected" ); + strictEqual( this.state(), "rejected", "Deferred is rejected (state)" ); + }).always( function() { + ok( true , "Always callback on reject" ); + }); + + createDeferred( function( defer ) { + ok( this === defer , "Defer passed as this & first argument" ); + this.resolve( "done" ); + }).then( function( value ) { + strictEqual( value , "done" , "Passed function executed" ); + }); + + _.each( "resolve reject".split( " " ), function( change ) { + createDeferred( function( defer ) { + strictEqual( defer.state(), "pending", "pending after creation" ); + var checked = 0; + defer.progress(function( value ) { + strictEqual( value, checked, "Progress: right value (" + value + ") received" ); + }); + for( checked = 0; checked < 3 ; checked++ ) { + defer.notify( checked ); + } + strictEqual( defer.state(), "pending", "pending after notification" ); + defer[ change ](); + notStrictEqual( defer.state(), "pending", "not pending after " + change ); + defer.notify(); + }); + }); + }); + +} ); + + +test( "_.Deferred - chainability", function() { + + var methods = "resolve reject notify resolveWith rejectWith notifyWith done fail progress then always".split( " " ), + defer = _.Deferred(); + + expect( methods.length ); + + _.each( methods, function( method ) { + var object = { m: defer[ method ] }; + strictEqual( object.m(), object, method + " is chainable" ); + }); +}); + + +test( "_.Deferred.pipe - filtering (done)", function() { + + expect(4); + + var defer = _.Deferred(), + piped = defer.pipe(function( a, b ) { + return a * b; + }), + value1, + value2, + value3; + + piped.done(function( result ) { + value3 = result; + }); + + defer.done(function( a, b ) { + value1 = a; + value2 = b; + }); + + defer.resolve( 2, 3 ); + + strictEqual( value1, 2, "first resolve value ok" ); + strictEqual( value2, 3, "second resolve value ok" ); + strictEqual( value3, 6, "result of filter ok" ); + + _.Deferred().reject().pipe(function() { + ok( false, "pipe should not be called on reject" ); + }); + + _.Deferred().resolve().pipe( _.noop ).done(function( value ) { + strictEqual( value, undefined, "pipe done callback can return undefined/null" ); + }); +}); + +test( "_.Deferred.pipe - filtering (fail)", function() { + + expect(4); + + var defer = _.Deferred(), + piped = defer.pipe( null, function( a, b ) { + return a * b; + } ), + value1, + value2, + value3; + + piped.fail(function( result ) { + value3 = result; + }); + + defer.fail(function( a, b ) { + value1 = a; + value2 = b; + }); + + defer.reject( 2, 3 ); + + strictEqual( value1, 2, "first reject value ok" ); + strictEqual( value2, 3, "second reject value ok" ); + strictEqual( value3, 6, "result of filter ok" ); + + _.Deferred().resolve().pipe( null, function() { + ok( false, "pipe should not be called on resolve" ); + } ); + + _.Deferred().reject().pipe( null, _.noop ).fail(function( value ) { + strictEqual( value, undefined, "pipe fail callback can return undefined/null" ); + }); +}); + +test( "_.Deferred.pipe - filtering (progress)", function() { + + expect(3); + + var defer = _.Deferred(), + piped = defer.pipe( null, null, function( a, b ) { + return a * b; + } ), + value1, + value2, + value3; + + piped.progress(function( result ) { + value3 = result; + }); + + defer.progress(function( a, b ) { + value1 = a; + value2 = b; + }); + + defer.notify( 2, 3 ); + + strictEqual( value1, 2, "first progress value ok" ); + strictEqual( value2, 3, "second progress value ok" ); + strictEqual( value3, 6, "result of filter ok" ); +}); + +test( "_.Deferred.pipe - deferred (done)", function() { + + expect(3); + + var defer = _.Deferred(), + piped = defer.pipe(function( a, b ) { + return _.Deferred(function( defer ) { + defer.reject( a * b ); + }); + }), + value1, + value2, + value3; + + piped.fail(function( result ) { + value3 = result; + }); + + defer.done(function( a, b ) { + value1 = a; + value2 = b; + }); + + defer.resolve( 2, 3 ); + + strictEqual( value1, 2, "first resolve value ok" ); + strictEqual( value2, 3, "second resolve value ok" ); + strictEqual( value3, 6, "result of filter ok" ); +}); + +test( "_.Deferred.pipe - deferred (fail)", function() { + + expect(3); + + var defer = _.Deferred(), + piped = defer.pipe( null, function( a, b ) { + return _.Deferred(function( defer ) { + defer.resolve( a * b ); + }); + } ), + value1, + value2, + value3; + + piped.done(function( result ) { + value3 = result; + }); + + defer.fail(function( a, b ) { + value1 = a; + value2 = b; + }); + + defer.reject( 2, 3 ); + + strictEqual( value1, 2, "first reject value ok" ); + strictEqual( value2, 3, "second reject value ok" ); + strictEqual( value3, 6, "result of filter ok" ); +}); + +test( "_.Deferred.pipe - deferred (progress)", function() { + + expect(3); + + var defer = _.Deferred(), + piped = defer.pipe( null, null, function( a, b ) { + return _.Deferred(function( defer ) { + defer.resolve( a * b ); + }); + } ), + value1, + value2, + value3; + + piped.done(function( result ) { + value3 = result; + }); + + defer.progress(function( a, b ) { + value1 = a; + value2 = b; + }); + + defer.notify( 2, 3 ); + + strictEqual( value1, 2, "first progress value ok" ); + strictEqual( value2, 3, "second progress value ok" ); + strictEqual( value3, 6, "result of filter ok" ); +}); + +test( "_.Deferred.pipe - context", function() { + + expect(4); + + var context = {}; + + _.Deferred().resolveWith( context, [ 2 ] ).pipe(function( value ) { + return value * 3; + }).done(function( value ) { + strictEqual( this, context, "custom context correctly propagated" ); + strictEqual( value, 6, "proper value received" ); + }); + + var defer = _.Deferred(), + piped = defer.pipe(function( value ) { + return value * 3; + }); + + defer.resolve( 2 ); + + piped.done(function( value ) { + strictEqual( this.promise(), piped, "default context gets updated to latest defer in the chain" ); + strictEqual( value, 6, "proper value received" ); + }); +}); + +test( "_.when" , function() { + + expect( 23 ); + + // Some other objects + _.each( { + + "an empty string": "", + "a non-empty string": "some string", + "zero": 0, + "a number other than zero": 1, + "true": true, + "false": false, + "null": null, + "undefined": undefined, + "a plain object": {} + + } , function( value, message ) { + + ok( _.isFunction( _.when( value ).done(function( resolveValue ) { + strictEqual( resolveValue , value , "Test the promise was resolved with " + message ); + }).promise ) , "Test " + message + " triggers the creation of a new Promise" ); + + } ); + + ok( _.isFunction( _.when().done(function( resolveValue ) { + strictEqual( resolveValue , undefined , "Test the promise was resolved with no parameter" ); + }).promise ) , "Test calling when with no parameter triggers the creation of a new Promise" ); + + var cache, i; + + for( i = 1 ; i < 4 ; i++ ) { + _.when( cache || _.Deferred( function() { + this.resolve( i ); + }) ).done(function( value ) { + strictEqual( value , 1 , "Function executed" + ( i > 1 ? " only once" : "" ) ); + cache = value; + }); + } +}); + +test("_.when - joined", function() { + + expect(53); + + var deferreds = { + value: 1, + success: _.Deferred().resolve( 1 ), + error: _.Deferred().reject( 0 ), + futureSuccess: _.Deferred().notify( true ), + futureError: _.Deferred().notify( true ), + notify: _.Deferred().notify( true ) + }, + willSucceed = { + value: true, + success: true, + futureSuccess: true + }, + willError = { + error: true, + futureError: true + }, + willNotify = { + futureSuccess: true, + futureError: true, + notify: true + }; + + _.each( deferreds, function( defer1, id1 ) { + _.each( deferreds, function( defer2, id2 ) { + var shouldResolve = willSucceed[ id1 ] && willSucceed[ id2 ], + shouldError = willError[ id1 ] || willError[ id2 ], + shouldNotify = willNotify[ id1 ] || willNotify[ id2 ], + expected = shouldResolve ? [ 1, 1 ] : [ 0, undefined ], + expectedNotify = shouldNotify && [ willNotify[ id1 ], willNotify[ id2 ] ], + code = id1 + "/" + id2; + + var promise = _.when( defer1, defer2 ).done(function( a, b ) { + if ( shouldResolve ) { + deepEqual( [ a, b ], expected, code + " => resolve" ); + } else { + ok( false , code + " => resolve" ); + } + }).fail(function( a, b ) { + if ( shouldError ) { + deepEqual( [ a, b ], expected, code + " => reject" ); + } else { + ok( false , code + " => reject" ); + } + }).progress(function progress( a, b ) { + deepEqual( [ a, b ], expectedNotify, code + " => progress" ); + }); + } ); + } ); + deferreds.futureSuccess.resolve( 1 ); + deferreds.futureError.reject( 0 ); +}); + + +(function() { + +var output, + addToOutput = function( string ) { + return function() { + output += string; + }; + }, + outputA = addToOutput( "A" ), + outputB = addToOutput( "B" ), + outputC = addToOutput( "C" ), + tests = { + "": "XABC X XABCABCC X XBB X XABA X", + "once": "XABC X X X X X XABA X", + "memory": "XABC XABC XABCABCCC XA XBB XB XABA XC", + "unique": "XABC X XABCA X XBB X XAB X", + "stopOnFalse": "XABC X XABCABCC X XBB X XA X", + "once memory": "XABC XABC X XA X XA XABA XC", + "once unique": "XABC X X X X X XAB X", + "once stopOnFalse": "XABC X X X X X XA X", + "memory unique": "XABC XA XABCA XA XBB XB XAB XC", + "memory stopOnFalse": "XABC XABC XABCABCCC XA XBB XB XA X", + "unique stopOnFalse": "XABC X XABCA X XBB X XA X" + }, + filters = { + "no filter": undefined, + "filter": function( fn ) { + return function() { + return fn.apply( this, arguments ); + }; + } + }; + +_.each( tests, function( resultString, flags ) { + + _.each( filters, function( filter, filterLabel ) { + + test( "_.Callbacks( \"" + flags + "\" ) - " + filterLabel, function() { + + expect( 20 ); + + // Give qunit a little breathing room + stop(); + setTimeout( start, 0 ); + + var cblist; + results = resultString.split( /\s+/ ); + + // Basic binding and firing + output = "X"; + cblist = _.Callbacks( flags ); + cblist.add(function( str ) { + output += str; + }); + cblist.fire( "A" ); + strictEqual( output, "XA", "Basic binding and firing" ); + strictEqual( cblist.fired(), true, ".fired() detects firing" ); + output = "X"; + cblist.disable(); + cblist.add(function( str ) { + output += str; + }); + strictEqual( output, "X", "Adding a callback after disabling" ); + cblist.fire( "A" ); + strictEqual( output, "X", "Firing after disabling" ); + + // Basic binding and firing (context, arguments) + output = "X"; + cblist = _.Callbacks( flags ); + cblist.add(function() { + equal( this, window, "Basic binding and firing (context)" ); + output += Array.prototype.join.call( arguments, "" ); + }); + cblist.fireWith( window, [ "A", "B" ] ); + strictEqual( output, "XAB", "Basic binding and firing (arguments)" ); + + // fireWith with no arguments + output = ""; + cblist = _.Callbacks( flags ); + cblist.add(function() { + equal( this, window, "fireWith with no arguments (context is window)" ); + strictEqual( arguments.length, 0, "fireWith with no arguments (no arguments)" ); + }); + cblist.fireWith(); + + // Basic binding, removing and firing + output = "X"; + cblist = _.Callbacks( flags ); + cblist.add( outputA, outputB, outputC ); + cblist.remove( outputB, outputC ); + cblist.fire(); + strictEqual( output, "XA", "Basic binding, removing and firing" ); + + // Empty + output = "X"; + cblist = _.Callbacks( flags ); + cblist.add( outputA ); + cblist.add( outputB ); + cblist.add( outputC ); + cblist.empty(); + cblist.fire(); + strictEqual( output, "X", "Empty" ); + + // Locking + output = "X"; + cblist = _.Callbacks( flags ); + cblist.add( function( str ) { + output += str; + }); + cblist.lock(); + cblist.add( function( str ) { + output += str; + }); + cblist.fire( "A" ); + cblist.add( function( str ) { + output += str; + }); + strictEqual( output, "X", "Lock early" ); + + // Ordering + output = "X"; + cblist = _.Callbacks( flags ); + cblist.add( function() { + cblist.add( outputC ); + outputA(); + }, outputB ); + cblist.fire(); + strictEqual( output, results.shift(), "Proper ordering" ); + + // Add and fire again + output = "X"; + cblist.add( function() { + cblist.add( outputC ); + outputA(); + }, outputB ); + strictEqual( output, results.shift(), "Add after fire" ); + + output = "X"; + cblist.fire(); + strictEqual( output, results.shift(), "Fire again" ); + + // Multiple fire + output = "X"; + cblist = _.Callbacks( flags ); + cblist.add( function( str ) { + output += str; + } ); + cblist.fire( "A" ); + strictEqual( output, "XA", "Multiple fire (first fire)" ); + output = "X"; + cblist.add( function( str ) { + output += str; + } ); + strictEqual( output, results.shift(), "Multiple fire (first new callback)" ); + output = "X"; + cblist.fire( "B" ); + strictEqual( output, results.shift(), "Multiple fire (second fire)" ); + output = "X"; + cblist.add( function( str ) { + output += str; + } ); + strictEqual( output, results.shift(), "Multiple fire (second new callback)" ); + + // Return false + output = "X"; + cblist = _.Callbacks( flags ); + cblist.add( outputA, function() { return false; }, outputB ); + cblist.add( outputA ); + cblist.fire(); + strictEqual( output, results.shift(), "Callback returning false" ); + + // Add another callback (to control lists with memory do not fire anymore) + output = "X"; + cblist.add( outputC ); + strictEqual( output, results.shift(), "Adding a callback after one returned false" ); + + }); + }); +}); + +})(); diff --git a/node_modules/underscore.deferred/test/index.html b/node_modules/underscore.deferred/test/index.html new file mode 100644 index 0000000..5b5d3a3 --- /dev/null +++ b/node_modules/underscore.deferred/test/index.html @@ -0,0 +1,29 @@ + + + + QUnit Tests + + + + + + + + + + + + + + + + + +

          QUnit Test Suite

          +

          +
          +

          +
            +
            test markup
            + + diff --git a/node_modules/underscore.deferred/test/qunit/qunit.css b/node_modules/underscore.deferred/test/qunit/qunit.css new file mode 100644 index 0000000..fbf194d --- /dev/null +++ b/node_modules/underscore.deferred/test/qunit/qunit.css @@ -0,0 +1,226 @@ +/** + * QUnit v1.3.0pre - A JavaScript Unit Testing Framework + * + * http://docs.jquery.com/QUnit + * + * Copyright (c) 2011 John Resig, Jörn Zaefferer + * Dual licensed under the MIT (MIT-LICENSE.txt) + * or GPL (GPL-LICENSE.txt) licenses. + */ + +/** Font Family and Sizes */ + +#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { + font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; +} + +#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } +#qunit-tests { font-size: smaller; } + + +/** Resets */ + +#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult { + margin: 0; + padding: 0; +} + + +/** Header */ + +#qunit-header { + padding: 0.5em 0 0.5em 1em; + + color: #8699a4; + background-color: #0d3349; + + font-size: 1.5em; + line-height: 1em; + font-weight: normal; + + border-radius: 15px 15px 0 0; + -moz-border-radius: 15px 15px 0 0; + -webkit-border-top-right-radius: 15px; + -webkit-border-top-left-radius: 15px; +} + +#qunit-header a { + text-decoration: none; + color: #c2ccd1; +} + +#qunit-header a:hover, +#qunit-header a:focus { + color: #fff; +} + +#qunit-banner { + height: 5px; +} + +#qunit-testrunner-toolbar { + padding: 0.5em 0 0.5em 2em; + color: #5E740B; + background-color: #eee; +} + +#qunit-userAgent { + padding: 0.5em 0 0.5em 2.5em; + background-color: #2b81af; + color: #fff; + text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; +} + + +/** Tests: Pass/Fail */ + +#qunit-tests { + list-style-position: inside; +} + +#qunit-tests li { + padding: 0.4em 0.5em 0.4em 2.5em; + border-bottom: 1px solid #fff; + list-style-position: inside; +} + +#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { + display: none; +} + +#qunit-tests li strong { + cursor: pointer; +} + +#qunit-tests li a { + padding: 0.5em; + color: #c2ccd1; + text-decoration: none; +} +#qunit-tests li a:hover, +#qunit-tests li a:focus { + color: #000; +} + +#qunit-tests ol { + margin-top: 0.5em; + padding: 0.5em; + + background-color: #fff; + + border-radius: 15px; + -moz-border-radius: 15px; + -webkit-border-radius: 15px; + + box-shadow: inset 0px 2px 13px #999; + -moz-box-shadow: inset 0px 2px 13px #999; + -webkit-box-shadow: inset 0px 2px 13px #999; +} + +#qunit-tests table { + border-collapse: collapse; + margin-top: .2em; +} + +#qunit-tests th { + text-align: right; + vertical-align: top; + padding: 0 .5em 0 0; +} + +#qunit-tests td { + vertical-align: top; +} + +#qunit-tests pre { + margin: 0; + white-space: pre-wrap; + word-wrap: break-word; +} + +#qunit-tests del { + background-color: #e0f2be; + color: #374e0c; + text-decoration: none; +} + +#qunit-tests ins { + background-color: #ffcaca; + color: #500; + text-decoration: none; +} + +/*** Test Counts */ + +#qunit-tests b.counts { color: black; } +#qunit-tests b.passed { color: #5E740B; } +#qunit-tests b.failed { color: #710909; } + +#qunit-tests li li { + margin: 0.5em; + padding: 0.4em 0.5em 0.4em 0.5em; + background-color: #fff; + border-bottom: none; + list-style-position: inside; +} + +/*** Passing Styles */ + +#qunit-tests li li.pass { + color: #5E740B; + background-color: #fff; + border-left: 26px solid #C6E746; +} + +#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } +#qunit-tests .pass .test-name { color: #366097; } + +#qunit-tests .pass .test-actual, +#qunit-tests .pass .test-expected { color: #999999; } + +#qunit-banner.qunit-pass { background-color: #C6E746; } + +/*** Failing Styles */ + +#qunit-tests li li.fail { + color: #710909; + background-color: #fff; + border-left: 26px solid #EE5757; + white-space: pre; +} + +#qunit-tests > li:last-child { + border-radius: 0 0 15px 15px; + -moz-border-radius: 0 0 15px 15px; + -webkit-border-bottom-right-radius: 15px; + -webkit-border-bottom-left-radius: 15px; +} + +#qunit-tests .fail { color: #000000; background-color: #EE5757; } +#qunit-tests .fail .test-name, +#qunit-tests .fail .module-name { color: #000000; } + +#qunit-tests .fail .test-actual { color: #EE5757; } +#qunit-tests .fail .test-expected { color: green; } + +#qunit-banner.qunit-fail { background-color: #EE5757; } + + +/** Result */ + +#qunit-testresult { + padding: 0.5em 0.5em 0.5em 2.5em; + + color: #2b81af; + background-color: #D2E0E6; + + border-bottom: 1px solid white; +} + +/** Fixture */ + +#qunit-fixture { + position: absolute; + top: -10000px; + left: -10000px; +} diff --git a/node_modules/underscore.deferred/test/qunit/qunit.js b/node_modules/underscore.deferred/test/qunit/qunit.js new file mode 100644 index 0000000..c3908d5 --- /dev/null +++ b/node_modules/underscore.deferred/test/qunit/qunit.js @@ -0,0 +1,1598 @@ +/** + * QUnit v1.3.0pre - A JavaScript Unit Testing Framework + * + * http://docs.jquery.com/QUnit + * + * Copyright (c) 2011 John Resig, Jörn Zaefferer + * Dual licensed under the MIT (MIT-LICENSE.txt) + * or GPL (GPL-LICENSE.txt) licenses. + */ + +(function(window) { + +var defined = { + setTimeout: typeof window.setTimeout !== "undefined", + sessionStorage: (function() { + try { + return !!sessionStorage.getItem; + } catch(e) { + return false; + } + })() +}; + +var testId = 0, + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty; + +var Test = function(name, testName, expected, testEnvironmentArg, async, callback) { + this.name = name; + this.testName = testName; + this.expected = expected; + this.testEnvironmentArg = testEnvironmentArg; + this.async = async; + this.callback = callback; + this.assertions = []; +}; +Test.prototype = { + init: function() { + var tests = id("qunit-tests"); + if (tests) { + var b = document.createElement("strong"); + b.innerHTML = "Running " + this.name; + var li = document.createElement("li"); + li.appendChild( b ); + li.className = "running"; + li.id = this.id = "test-output" + testId++; + tests.appendChild( li ); + } + }, + setup: function() { + if (this.module != config.previousModule) { + if ( config.previousModule ) { + runLoggingCallbacks('moduleDone', QUnit, { + name: config.previousModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + } ); + } + config.previousModule = this.module; + config.moduleStats = { all: 0, bad: 0 }; + runLoggingCallbacks( 'moduleStart', QUnit, { + name: this.module + } ); + } + + config.current = this; + this.testEnvironment = extend({ + setup: function() {}, + teardown: function() {} + }, this.moduleTestEnvironment); + if (this.testEnvironmentArg) { + extend(this.testEnvironment, this.testEnvironmentArg); + } + + runLoggingCallbacks( 'testStart', QUnit, { + name: this.testName, + module: this.module + }); + + // allow utility functions to access the current test environment + // TODO why?? + QUnit.current_testEnvironment = this.testEnvironment; + + try { + if ( !config.pollution ) { + saveGlobal(); + } + + this.testEnvironment.setup.call(this.testEnvironment); + } catch(e) { + QUnit.ok( false, "Setup failed on " + this.testName + ": " + e.message ); + } + }, + run: function() { + config.current = this; + if ( this.async ) { + QUnit.stop(); + } + + if ( config.notrycatch ) { + this.callback.call(this.testEnvironment); + return; + } + try { + this.callback.call(this.testEnvironment); + } catch(e) { + fail("Test " + this.testName + " died, exception and test follows", e, this.callback); + QUnit.ok( false, "Died on test #" + (this.assertions.length + 1) + ": " + e.message + " - " + QUnit.jsDump.parse(e) ); + // else next test will carry the responsibility + saveGlobal(); + + // Restart the tests if they're blocking + if ( config.blocking ) { + QUnit.start(); + } + } + }, + teardown: function() { + config.current = this; + try { + this.testEnvironment.teardown.call(this.testEnvironment); + checkPollution(); + } catch(e) { + QUnit.ok( false, "Teardown failed on " + this.testName + ": " + e.message ); + } + }, + finish: function() { + config.current = this; + if ( this.expected != null && this.expected != this.assertions.length ) { + QUnit.ok( false, "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run" ); + } + + var good = 0, bad = 0, + tests = id("qunit-tests"); + + config.stats.all += this.assertions.length; + config.moduleStats.all += this.assertions.length; + + if ( tests ) { + var ol = document.createElement("ol"); + + for ( var i = 0; i < this.assertions.length; i++ ) { + var assertion = this.assertions[i]; + + var li = document.createElement("li"); + li.className = assertion.result ? "pass" : "fail"; + li.innerHTML = assertion.message || (assertion.result ? "okay" : "failed"); + ol.appendChild( li ); + + if ( assertion.result ) { + good++; + } else { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + + // store result when possible + if ( QUnit.config.reorder && defined.sessionStorage ) { + if (bad) { + sessionStorage.setItem("qunit-" + this.module + "-" + this.testName, bad); + } else { + sessionStorage.removeItem("qunit-" + this.module + "-" + this.testName); + } + } + + if (bad == 0) { + ol.style.display = "none"; + } + + var b = document.createElement("strong"); + b.innerHTML = this.name + " (" + bad + ", " + good + ", " + this.assertions.length + ")"; + + var a = document.createElement("a"); + a.innerHTML = "Rerun"; + a.href = QUnit.url({ filter: getText([b]).replace(/\([^)]+\)$/, "").replace(/(^\s*|\s*$)/g, "") }); + + addEvent(b, "click", function() { + var next = b.nextSibling.nextSibling, + display = next.style.display; + next.style.display = display === "none" ? "block" : "none"; + }); + + addEvent(b, "dblclick", function(e) { + var target = e && e.target ? e.target : window.event.srcElement; + if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) { + target = target.parentNode; + } + if ( window.location && target.nodeName.toLowerCase() === "strong" ) { + window.location = QUnit.url({ filter: getText([target]).replace(/\([^)]+\)$/, "").replace(/(^\s*|\s*$)/g, "") }); + } + }); + + var li = id(this.id); + li.className = bad ? "fail" : "pass"; + li.removeChild( li.firstChild ); + li.appendChild( b ); + li.appendChild( a ); + li.appendChild( ol ); + + } else { + for ( var i = 0; i < this.assertions.length; i++ ) { + if ( !this.assertions[i].result ) { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + } + + try { + QUnit.reset(); + } catch(e) { + fail("reset() failed, following Test " + this.testName + ", exception and reset fn follows", e, QUnit.reset); + } + + runLoggingCallbacks( 'testDone', QUnit, { + name: this.testName, + module: this.module, + failed: bad, + passed: this.assertions.length - bad, + total: this.assertions.length + } ); + }, + + queue: function() { + var test = this; + synchronize(function() { + test.init(); + }); + function run() { + // each of these can by async + synchronize(function() { + test.setup(); + }); + synchronize(function() { + test.run(); + }); + synchronize(function() { + test.teardown(); + }); + synchronize(function() { + test.finish(); + }); + } + // defer when previous test run passed, if storage is available + var bad = QUnit.config.reorder && defined.sessionStorage && +sessionStorage.getItem("qunit-" + this.module + "-" + this.testName); + if (bad) { + run(); + } else { + synchronize(run, true); + }; + } + +}; + +var QUnit = { + + // call on start of module test to prepend name to all tests + module: function(name, testEnvironment) { + config.currentModule = name; + config.currentModuleTestEnviroment = testEnvironment; + }, + + asyncTest: function(testName, expected, callback) { + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + + QUnit.test(testName, expected, callback, true); + }, + + test: function(testName, expected, callback, async) { + var name = '' + escapeInnerText(testName) + '', testEnvironmentArg; + + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + // is 2nd argument a testEnvironment? + if ( expected && typeof expected === 'object') { + testEnvironmentArg = expected; + expected = null; + } + + if ( config.currentModule ) { + name = '' + config.currentModule + ": " + name; + } + + if ( !validTest(config.currentModule + ": " + testName) ) { + return; + } + + var test = new Test(name, testName, expected, testEnvironmentArg, async, callback); + test.module = config.currentModule; + test.moduleTestEnvironment = config.currentModuleTestEnviroment; + test.queue(); + }, + + /** + * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through. + */ + expect: function(asserts) { + config.current.expected = asserts; + }, + + /** + * Asserts true. + * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); + */ + ok: function(a, msg) { + a = !!a; + var details = { + result: a, + message: msg + }; + msg = escapeInnerText(msg); + runLoggingCallbacks( 'log', QUnit, details ); + config.current.assertions.push({ + result: a, + message: msg + }); + }, + + /** + * Checks that the first two arguments are equal, with an optional message. + * Prints out both actual and expected values. + * + * Prefered to ok( actual == expected, message ) + * + * @example equal( format("Received {0} bytes.", 2), "Received 2 bytes." ); + * + * @param Object actual + * @param Object expected + * @param String message (optional) + */ + equal: function(actual, expected, message) { + QUnit.push(expected == actual, actual, expected, message); + }, + + notEqual: function(actual, expected, message) { + QUnit.push(expected != actual, actual, expected, message); + }, + + deepEqual: function(actual, expected, message) { + QUnit.push(QUnit.equiv(actual, expected), actual, expected, message); + }, + + notDeepEqual: function(actual, expected, message) { + QUnit.push(!QUnit.equiv(actual, expected), actual, expected, message); + }, + + strictEqual: function(actual, expected, message) { + QUnit.push(expected === actual, actual, expected, message); + }, + + notStrictEqual: function(actual, expected, message) { + QUnit.push(expected !== actual, actual, expected, message); + }, + + raises: function(block, expected, message) { + var actual, ok = false; + + if (typeof expected === 'string') { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + if (actual) { + // we don't want to validate thrown error + if (!expected) { + ok = true; + // expected is a regexp + } else if (QUnit.objectType(expected) === "regexp") { + ok = expected.test(actual); + // expected is a constructor + } else if (actual instanceof expected) { + ok = true; + // expected is a validation function which returns true is validation passed + } else if (expected.call({}, actual) === true) { + ok = true; + } + } + + QUnit.ok(ok, message); + }, + + start: function(count) { + config.semaphore -= count || 1; + if (config.semaphore > 0) { + // don't start until equal number of stop-calls + return; + } + if (config.semaphore < 0) { + // ignore if start is called more often then stop + config.semaphore = 0; + } + // A slight delay, to avoid any current callbacks + if ( defined.setTimeout ) { + window.setTimeout(function() { + if (config.semaphore > 0) { + return; + } + if ( config.timeout ) { + clearTimeout(config.timeout); + } + + config.blocking = false; + process(true); + }, 13); + } else { + config.blocking = false; + process(true); + } + }, + + stop: function(count) { + config.semaphore += count || 1; + config.blocking = true; + + if ( config.testTimeout && defined.setTimeout ) { + clearTimeout(config.timeout); + config.timeout = window.setTimeout(function() { + QUnit.ok( false, "Test timed out" ); + config.semaphore = 1; + QUnit.start(); + }, config.testTimeout); + } + } +}; + +//We want access to the constructor's prototype +(function() { + function F(){}; + F.prototype = QUnit; + QUnit = new F(); + //Make F QUnit's constructor so that we can add to the prototype later + QUnit.constructor = F; +})(); + +// Backwards compatibility, deprecated +QUnit.equals = QUnit.equal; +QUnit.same = QUnit.deepEqual; + +// Maintain internal state +var config = { + // The queue of tests to run + queue: [], + + // block until document ready + blocking: true, + + // when enabled, show only failing tests + // gets persisted through sessionStorage and can be changed in UI via checkbox + hidepassed: false, + + // by default, run previously failed tests first + // very useful in combination with "Hide passed tests" checked + reorder: true, + + // by default, modify document.title when suite is done + altertitle: true, + + urlConfig: ['noglobals', 'notrycatch'], + + //logging callback queues + begin: [], + done: [], + log: [], + testStart: [], + testDone: [], + moduleStart: [], + moduleDone: [] +}; + +// Load paramaters +(function() { + var location = window.location || { search: "", protocol: "file:" }, + params = location.search.slice( 1 ).split( "&" ), + length = params.length, + urlParams = {}, + current; + + if ( params[ 0 ] ) { + for ( var i = 0; i < length; i++ ) { + current = params[ i ].split( "=" ); + current[ 0 ] = decodeURIComponent( current[ 0 ] ); + // allow just a key to turn on a flag, e.g., test.html?noglobals + current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true; + urlParams[ current[ 0 ] ] = current[ 1 ]; + } + } + + QUnit.urlParams = urlParams; + config.filter = urlParams.filter; + + // Figure out if we're running the tests from a server or not + QUnit.isLocal = !!(location.protocol === 'file:'); +})(); + +// Expose the API as global variables, unless an 'exports' +// object exists, in that case we assume we're in CommonJS +if ( typeof exports === "undefined" || typeof require === "undefined" ) { + extend(window, QUnit); + window.QUnit = QUnit; +} else { + extend(exports, QUnit); + exports.QUnit = QUnit; +} + +// define these after exposing globals to keep them in these QUnit namespace only +extend(QUnit, { + config: config, + + // Initialize the configuration options + init: function() { + extend(config, { + stats: { all: 0, bad: 0 }, + moduleStats: { all: 0, bad: 0 }, + started: +new Date, + updateRate: 1000, + blocking: false, + autostart: true, + autorun: false, + filter: "", + queue: [], + semaphore: 0 + }); + + var tests = id( "qunit-tests" ), + banner = id( "qunit-banner" ), + result = id( "qunit-testresult" ); + + if ( tests ) { + tests.innerHTML = ""; + } + + if ( banner ) { + banner.className = ""; + } + + if ( result ) { + result.parentNode.removeChild( result ); + } + + if ( tests ) { + result = document.createElement( "p" ); + result.id = "qunit-testresult"; + result.className = "result"; + tests.parentNode.insertBefore( result, tests ); + result.innerHTML = 'Running...
             '; + } + }, + + /** + * Resets the test setup. Useful for tests that modify the DOM. + * + * If jQuery is available, uses jQuery's html(), otherwise just innerHTML. + */ + reset: function() { + if ( window.jQuery ) { + jQuery( "#qunit-fixture" ).html( config.fixture ); + } else { + var main = id( 'qunit-fixture' ); + if ( main ) { + main.innerHTML = config.fixture; + } + } + }, + + /** + * Trigger an event on an element. + * + * @example triggerEvent( document.body, "click" ); + * + * @param DOMElement elem + * @param String type + */ + triggerEvent: function( elem, type, event ) { + if ( document.createEvent ) { + event = document.createEvent("MouseEvents"); + event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + elem.dispatchEvent( event ); + + } else if ( elem.fireEvent ) { + elem.fireEvent("on"+type); + } + }, + + // Safe object type checking + is: function( type, obj ) { + return QUnit.objectType( obj ) == type; + }, + + objectType: function( obj ) { + if (typeof obj === "undefined") { + return "undefined"; + + // consider: typeof null === object + } + if (obj === null) { + return "null"; + } + + var type = toString.call( obj ).match(/^\[object\s(.*)\]$/)[1] || ''; + + switch (type) { + case 'Number': + if (isNaN(obj)) { + return "nan"; + } else { + return "number"; + } + case 'String': + case 'Boolean': + case 'Array': + case 'Date': + case 'RegExp': + case 'Function': + return type.toLowerCase(); + } + if (typeof obj === "object") { + return "object"; + } + return undefined; + }, + + push: function(result, actual, expected, message) { + var details = { + result: result, + message: message, + actual: actual, + expected: expected + }; + + message = escapeInnerText(message) || (result ? "okay" : "failed"); + message = '' + message + ""; + expected = escapeInnerText(QUnit.jsDump.parse(expected)); + actual = escapeInnerText(QUnit.jsDump.parse(actual)); + var output = message + ''; + if (actual != expected) { + output += ''; + output += ''; + } + if (!result) { + var source = sourceFromStacktrace(); + if (source) { + details.source = source; + output += ''; + } + } + output += "
            Expected:
            ' + expected + '
            Result:
            ' + actual + '
            Diff:
            ' + QUnit.diff(expected, actual) +'
            Source:
            ' + escapeInnerText(source) + '
            "; + + runLoggingCallbacks( 'log', QUnit, details ); + + config.current.assertions.push({ + result: !!result, + message: output + }); + }, + + url: function( params ) { + params = extend( extend( {}, QUnit.urlParams ), params ); + var querystring = "?", + key; + for ( key in params ) { + if ( !hasOwn.call( params, key ) ) { + continue; + } + querystring += encodeURIComponent( key ) + "=" + + encodeURIComponent( params[ key ] ) + "&"; + } + return window.location.pathname + querystring.slice( 0, -1 ); + }, + + extend: extend, + id: id, + addEvent: addEvent +}); + +//QUnit.constructor is set to the empty F() above so that we can add to it's prototype later +//Doing this allows us to tell if the following methods have been overwritten on the actual +//QUnit object, which is a deprecated way of using the callbacks. +extend(QUnit.constructor.prototype, { + // Logging callbacks; all receive a single argument with the listed properties + // run test/logs.html for any related changes + begin: registerLoggingCallback('begin'), + // done: { failed, passed, total, runtime } + done: registerLoggingCallback('done'), + // log: { result, actual, expected, message } + log: registerLoggingCallback('log'), + // testStart: { name } + testStart: registerLoggingCallback('testStart'), + // testDone: { name, failed, passed, total } + testDone: registerLoggingCallback('testDone'), + // moduleStart: { name } + moduleStart: registerLoggingCallback('moduleStart'), + // moduleDone: { name, failed, passed, total } + moduleDone: registerLoggingCallback('moduleDone') +}); + +if ( typeof document === "undefined" || document.readyState === "complete" ) { + config.autorun = true; +} + +QUnit.load = function() { + runLoggingCallbacks( 'begin', QUnit, {} ); + + // Initialize the config, saving the execution queue + var oldconfig = extend({}, config); + QUnit.init(); + extend(config, oldconfig); + + config.blocking = false; + + var urlConfigHtml = '', len = config.urlConfig.length; + for ( var i = 0, val; i < len, val = config.urlConfig[i]; i++ ) { + config[val] = QUnit.urlParams[val]; + urlConfigHtml += ''; + } + + var userAgent = id("qunit-userAgent"); + if ( userAgent ) { + userAgent.innerHTML = navigator.userAgent; + } + var banner = id("qunit-header"); + if ( banner ) { + banner.innerHTML = '
            ' + banner.innerHTML + ' ' + urlConfigHtml; + addEvent( banner, "change", function( event ) { + var params = {}; + params[ event.target.name ] = event.target.checked ? true : undefined; + window.location = QUnit.url( params ); + }); + } + + var toolbar = id("qunit-testrunner-toolbar"); + if ( toolbar ) { + var filter = document.createElement("input"); + filter.type = "checkbox"; + filter.id = "qunit-filter-pass"; + addEvent( filter, "click", function() { + var ol = document.getElementById("qunit-tests"); + if ( filter.checked ) { + ol.className = ol.className + " hidepass"; + } else { + var tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " "; + ol.className = tmp.replace(/ hidepass /, " "); + } + if ( defined.sessionStorage ) { + if (filter.checked) { + sessionStorage.setItem("qunit-filter-passed-tests", "true"); + } else { + sessionStorage.removeItem("qunit-filter-passed-tests"); + } + } + }); + if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) { + filter.checked = true; + var ol = document.getElementById("qunit-tests"); + ol.className = ol.className + " hidepass"; + } + toolbar.appendChild( filter ); + + var label = document.createElement("label"); + label.setAttribute("for", "qunit-filter-pass"); + label.innerHTML = "Hide passed tests"; + toolbar.appendChild( label ); + } + + var main = id('qunit-fixture'); + if ( main ) { + config.fixture = main.innerHTML; + } + + if (config.autostart) { + QUnit.start(); + } +}; + +addEvent(window, "load", QUnit.load); + +// addEvent(window, "error") gives us a useless event object +window.onerror = function( message, file, line ) { + if ( QUnit.config.current ) { + ok( false, message + ", " + file + ":" + line ); + } else { + test( "global failure", function() { + ok( false, message + ", " + file + ":" + line ); + }); + } +}; + +function done() { + config.autorun = true; + + // Log the last module results + if ( config.currentModule ) { + runLoggingCallbacks( 'moduleDone', QUnit, { + name: config.currentModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + } ); + } + + var banner = id("qunit-banner"), + tests = id("qunit-tests"), + runtime = +new Date - config.started, + passed = config.stats.all - config.stats.bad, + html = [ + 'Tests completed in ', + runtime, + ' milliseconds.
            ', + '', + passed, + ' tests of ', + config.stats.all, + ' passed, ', + config.stats.bad, + ' failed.' + ].join(''); + + if ( banner ) { + banner.className = (config.stats.bad ? "qunit-fail" : "qunit-pass"); + } + + if ( tests ) { + id( "qunit-testresult" ).innerHTML = html; + } + + if ( config.altertitle && typeof document !== "undefined" && document.title ) { + // show ✖ for good, ✔ for bad suite result in title + // use escape sequences in case file gets loaded with non-utf-8-charset + document.title = [ + (config.stats.bad ? "\u2716" : "\u2714"), + document.title.replace(/^[\u2714\u2716] /i, "") + ].join(" "); + } + + runLoggingCallbacks( 'done', QUnit, { + failed: config.stats.bad, + passed: passed, + total: config.stats.all, + runtime: runtime + } ); +} + +function validTest( name ) { + var filter = config.filter, + run = false; + + if ( !filter ) { + return true; + } + + var not = filter.charAt( 0 ) === "!"; + if ( not ) { + filter = filter.slice( 1 ); + } + + if ( name.indexOf( filter ) !== -1 ) { + return !not; + } + + if ( not ) { + run = true; + } + + return run; +} + +// so far supports only Firefox, Chrome and Opera (buggy) +// could be extended in the future to use something like https://github.com/csnover/TraceKit +function sourceFromStacktrace() { + try { + throw new Error(); + } catch ( e ) { + if (e.stacktrace) { + // Opera + return e.stacktrace.split("\n")[6]; + } else if (e.stack) { + // Firefox, Chrome + return e.stack.split("\n")[4]; + } else if (e.sourceURL) { + // Safari, PhantomJS + // TODO sourceURL points at the 'throw new Error' line above, useless + //return e.sourceURL + ":" + e.line; + } + } +} + +function escapeInnerText(s) { + if (!s) { + return ""; + } + s = s + ""; + return s.replace(/[\&<>]/g, function(s) { + switch(s) { + case "&": return "&"; + case "<": return "<"; + case ">": return ">"; + default: return s; + } + }); +} + +function synchronize( callback, last ) { + config.queue.push( callback ); + + if ( config.autorun && !config.blocking ) { + process(last); + } +} + +function process( last ) { + var start = new Date().getTime(); + config.depth = config.depth ? config.depth + 1 : 1; + + while ( config.queue.length && !config.blocking ) { + if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) { + config.queue.shift()(); + } else { + window.setTimeout( function(){ + process( last ); + }, 13 ); + break; + } + } + config.depth--; + if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) { + done(); + } +} + +function saveGlobal() { + config.pollution = []; + + if ( config.noglobals ) { + for ( var key in window ) { + if ( !hasOwn.call( window, key ) ) { + continue; + } + config.pollution.push( key ); + } + } +} + +function checkPollution( name ) { + var old = config.pollution; + saveGlobal(); + + var newGlobals = diff( config.pollution, old ); + if ( newGlobals.length > 0 ) { + ok( false, "Introduced global variable(s): " + newGlobals.join(", ") ); + } + + var deletedGlobals = diff( old, config.pollution ); + if ( deletedGlobals.length > 0 ) { + ok( false, "Deleted global variable(s): " + deletedGlobals.join(", ") ); + } +} + +// returns a new Array with the elements that are in a but not in b +function diff( a, b ) { + var result = a.slice(); + for ( var i = 0; i < result.length; i++ ) { + for ( var j = 0; j < b.length; j++ ) { + if ( result[i] === b[j] ) { + result.splice(i, 1); + i--; + break; + } + } + } + return result; +} + +function fail(message, exception, callback) { + if ( typeof console !== "undefined" && console.error && console.warn ) { + console.error(message); + console.error(exception); + console.error(exception.stack); + console.warn(callback.toString()); + + } else if ( window.opera && opera.postError ) { + opera.postError(message, exception, callback.toString); + } +} + +function extend(a, b) { + for ( var prop in b ) { + if ( b[prop] === undefined ) { + delete a[prop]; + + // Avoid "Member not found" error in IE8 caused by setting window.constructor + } else if ( prop !== "constructor" || a !== window ) { + a[prop] = b[prop]; + } + } + + return a; +} + +function addEvent(elem, type, fn) { + if ( elem.addEventListener ) { + elem.addEventListener( type, fn, false ); + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, fn ); + } else { + fn(); + } +} + +function id(name) { + return !!(typeof document !== "undefined" && document && document.getElementById) && + document.getElementById( name ); +} + +function registerLoggingCallback(key){ + return function(callback){ + config[key].push( callback ); + }; +} + +// Supports deprecated method of completely overwriting logging callbacks +function runLoggingCallbacks(key, scope, args) { + //debugger; + var callbacks; + if ( QUnit.hasOwnProperty(key) ) { + QUnit[key].call(scope, args); + } else { + callbacks = config[key]; + for( var i = 0; i < callbacks.length; i++ ) { + callbacks[i].call( scope, args ); + } + } +} + +// Test for equality any JavaScript type. +// Author: Philippe Rathé +QUnit.equiv = function () { + + var innerEquiv; // the real equiv function + var callers = []; // stack to decide between skip/abort functions + var parents = []; // stack to avoiding loops from circular referencing + + // Call the o related callback with the given arguments. + function bindCallbacks(o, callbacks, args) { + var prop = QUnit.objectType(o); + if (prop) { + if (QUnit.objectType(callbacks[prop]) === "function") { + return callbacks[prop].apply(callbacks, args); + } else { + return callbacks[prop]; // or undefined + } + } + } + + var getProto = Object.getPrototypeOf || function (obj) { + return obj.__proto__; + }; + + var callbacks = function () { + + // for string, boolean, number and null + function useStrictEquality(b, a) { + if (b instanceof a.constructor || a instanceof b.constructor) { + // to catch short annotaion VS 'new' annotation of a + // declaration + // e.g. var i = 1; + // var j = new Number(1); + return a == b; + } else { + return a === b; + } + } + + return { + "string" : useStrictEquality, + "boolean" : useStrictEquality, + "number" : useStrictEquality, + "null" : useStrictEquality, + "undefined" : useStrictEquality, + + "nan" : function(b) { + return isNaN(b); + }, + + "date" : function(b, a) { + return QUnit.objectType(b) === "date" + && a.valueOf() === b.valueOf(); + }, + + "regexp" : function(b, a) { + return QUnit.objectType(b) === "regexp" + && a.source === b.source && // the regex itself + a.global === b.global && // and its modifers + // (gmi) ... + a.ignoreCase === b.ignoreCase + && a.multiline === b.multiline; + }, + + // - skip when the property is a method of an instance (OOP) + // - abort otherwise, + // initial === would have catch identical references anyway + "function" : function() { + var caller = callers[callers.length - 1]; + return caller !== Object && typeof caller !== "undefined"; + }, + + "array" : function(b, a) { + var i, j, loop; + var len; + + // b could be an object literal here + if (!(QUnit.objectType(b) === "array")) { + return false; + } + + len = a.length; + if (len !== b.length) { // safe and faster + return false; + } + + // track reference to avoid circular references + parents.push(a); + for (i = 0; i < len; i++) { + loop = false; + for (j = 0; j < parents.length; j++) { + if (parents[j] === a[i]) { + loop = true;// dont rewalk array + } + } + if (!loop && !innerEquiv(a[i], b[i])) { + parents.pop(); + return false; + } + } + parents.pop(); + return true; + }, + + "object" : function(b, a) { + var i, j, loop; + var eq = true; // unless we can proove it + var aProperties = [], bProperties = []; // collection of + // strings + + // comparing constructors is more strict than using + // instanceof + if (a.constructor !== b.constructor) { + // Allow objects with no prototype to be equivalent to + // objects with Object as their constructor. + if (!((getProto(a) === null && getProto(b) === Object.prototype) || + (getProto(b) === null && getProto(a) === Object.prototype))) + { + return false; + } + } + + // stack constructor before traversing properties + callers.push(a.constructor); + // track reference to avoid circular references + parents.push(a); + + for (i in a) { // be strict: don't ensures hasOwnProperty + // and go deep + loop = false; + for (j = 0; j < parents.length; j++) { + if (parents[j] === a[i]) + loop = true; // don't go down the same path + // twice + } + aProperties.push(i); // collect a's properties + + if (!loop && !innerEquiv(a[i], b[i])) { + eq = false; + break; + } + } + + callers.pop(); // unstack, we are done + parents.pop(); + + for (i in b) { + bProperties.push(i); // collect b's properties + } + + // Ensures identical properties name + return eq + && innerEquiv(aProperties.sort(), bProperties + .sort()); + } + }; + }(); + + innerEquiv = function() { // can take multiple arguments + var args = Array.prototype.slice.apply(arguments); + if (args.length < 2) { + return true; // end transition + } + + return (function(a, b) { + if (a === b) { + return true; // catch the most you can + } else if (a === null || b === null || typeof a === "undefined" + || typeof b === "undefined" + || QUnit.objectType(a) !== QUnit.objectType(b)) { + return false; // don't lose time with error prone cases + } else { + return bindCallbacks(a, callbacks, [ b, a ]); + } + + // apply transition with (1..n) arguments + })(args[0], args[1]) + && arguments.callee.apply(this, args.splice(1, + args.length - 1)); + }; + + return innerEquiv; + +}(); + +/** + * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | + * http://flesler.blogspot.com Licensed under BSD + * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008 + * + * @projectDescription Advanced and extensible data dumping for Javascript. + * @version 1.0.0 + * @author Ariel Flesler + * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html} + */ +QUnit.jsDump = (function() { + function quote( str ) { + return '"' + str.toString().replace(/"/g, '\\"') + '"'; + }; + function literal( o ) { + return o + ''; + }; + function join( pre, arr, post ) { + var s = jsDump.separator(), + base = jsDump.indent(), + inner = jsDump.indent(1); + if ( arr.join ) + arr = arr.join( ',' + s + inner ); + if ( !arr ) + return pre + post; + return [ pre, inner + arr, base + post ].join(s); + }; + function array( arr, stack ) { + var i = arr.length, ret = Array(i); + this.up(); + while ( i-- ) + ret[i] = this.parse( arr[i] , undefined , stack); + this.down(); + return join( '[', ret, ']' ); + }; + + var reName = /^function (\w+)/; + + var jsDump = { + parse:function( obj, type, stack ) { //type is used mostly internally, you can fix a (custom)type in advance + stack = stack || [ ]; + var parser = this.parsers[ type || this.typeOf(obj) ]; + type = typeof parser; + var inStack = inArray(obj, stack); + if (inStack != -1) { + return 'recursion('+(inStack - stack.length)+')'; + } + //else + if (type == 'function') { + stack.push(obj); + var res = parser.call( this, obj, stack ); + stack.pop(); + return res; + } + // else + return (type == 'string') ? parser : this.parsers.error; + }, + typeOf:function( obj ) { + var type; + if ( obj === null ) { + type = "null"; + } else if (typeof obj === "undefined") { + type = "undefined"; + } else if (QUnit.is("RegExp", obj)) { + type = "regexp"; + } else if (QUnit.is("Date", obj)) { + type = "date"; + } else if (QUnit.is("Function", obj)) { + type = "function"; + } else if (typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined") { + type = "window"; + } else if (obj.nodeType === 9) { + type = "document"; + } else if (obj.nodeType) { + type = "node"; + } else if ( + // native arrays + toString.call( obj ) === "[object Array]" || + // NodeList objects + ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) ) + ) { + type = "array"; + } else { + type = typeof obj; + } + return type; + }, + separator:function() { + return this.multiline ? this.HTML ? '
            ' : '\n' : this.HTML ? ' ' : ' '; + }, + indent:function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing + if ( !this.multiline ) + return ''; + var chr = this.indentChar; + if ( this.HTML ) + chr = chr.replace(/\t/g,' ').replace(/ /g,' '); + return Array( this._depth_ + (extra||0) ).join(chr); + }, + up:function( a ) { + this._depth_ += a || 1; + }, + down:function( a ) { + this._depth_ -= a || 1; + }, + setParser:function( name, parser ) { + this.parsers[name] = parser; + }, + // The next 3 are exposed so you can use them + quote:quote, + literal:literal, + join:join, + // + _depth_: 1, + // This is the list of parsers, to modify them, use jsDump.setParser + parsers:{ + window: '[Window]', + document: '[Document]', + error:'[ERROR]', //when no parser is found, shouldn't happen + unknown: '[Unknown]', + 'null':'null', + 'undefined':'undefined', + 'function':function( fn ) { + var ret = 'function', + name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE + if ( name ) + ret += ' ' + name; + ret += '('; + + ret = [ ret, QUnit.jsDump.parse( fn, 'functionArgs' ), '){'].join(''); + return join( ret, QUnit.jsDump.parse(fn,'functionCode'), '}' ); + }, + array: array, + nodelist: array, + arguments: array, + object:function( map, stack ) { + var ret = [ ]; + QUnit.jsDump.up(); + for ( var key in map ) { + var val = map[key]; + ret.push( QUnit.jsDump.parse(key,'key') + ': ' + QUnit.jsDump.parse(val, undefined, stack)); + } + QUnit.jsDump.down(); + return join( '{', ret, '}' ); + }, + node:function( node ) { + var open = QUnit.jsDump.HTML ? '<' : '<', + close = QUnit.jsDump.HTML ? '>' : '>'; + + var tag = node.nodeName.toLowerCase(), + ret = open + tag; + + for ( var a in QUnit.jsDump.DOMAttrs ) { + var val = node[QUnit.jsDump.DOMAttrs[a]]; + if ( val ) + ret += ' ' + a + '=' + QUnit.jsDump.parse( val, 'attribute' ); + } + return ret + close + open + '/' + tag + close; + }, + functionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function + var l = fn.length; + if ( !l ) return ''; + + var args = Array(l); + while ( l-- ) + args[l] = String.fromCharCode(97+l);//97 is 'a' + return ' ' + args.join(', ') + ' '; + }, + key:quote, //object calls it internally, the key part of an item in a map + functionCode:'[code]', //function calls it internally, it's the content of the function + attribute:quote, //node calls it internally, it's an html attribute value + string:quote, + date:quote, + regexp:literal, //regex + number:literal, + 'boolean':literal + }, + DOMAttrs:{//attributes to dump from nodes, name=>realName + id:'id', + name:'name', + 'class':'className' + }, + HTML:false,//if true, entities are escaped ( <, >, \t, space and \n ) + indentChar:' ',//indentation unit + multiline:true //if true, items in a collection, are separated by a \n, else just a space. + }; + + return jsDump; +})(); + +// from Sizzle.js +function getText( elems ) { + var ret = "", elem; + + for ( var i = 0; elems[i]; i++ ) { + elem = elems[i]; + + // Get the text from text nodes and CDATA nodes + if ( elem.nodeType === 3 || elem.nodeType === 4 ) { + ret += elem.nodeValue; + + // Traverse everything else, except comment nodes + } else if ( elem.nodeType !== 8 ) { + ret += getText( elem.childNodes ); + } + } + + return ret; +}; + +//from jquery.js +function inArray( elem, array ) { + if ( array.indexOf ) { + return array.indexOf( elem ); + } + + for ( var i = 0, length = array.length; i < length; i++ ) { + if ( array[ i ] === elem ) { + return i; + } + } + + return -1; +} + +/* + * Javascript Diff Algorithm + * By John Resig (http://ejohn.org/) + * Modified by Chu Alan "sprite" + * + * Released under the MIT license. + * + * More Info: + * http://ejohn.org/projects/javascript-diff-algorithm/ + * + * Usage: QUnit.diff(expected, actual) + * + * QUnit.diff("the quick brown fox jumped over", "the quick fox jumps over") == "the quick brown fox jumped jumps over" + */ +QUnit.diff = (function() { + function diff(o, n) { + var ns = {}; + var os = {}; + + for (var i = 0; i < n.length; i++) { + if (ns[n[i]] == null) + ns[n[i]] = { + rows: [], + o: null + }; + ns[n[i]].rows.push(i); + } + + for (var i = 0; i < o.length; i++) { + if (os[o[i]] == null) + os[o[i]] = { + rows: [], + n: null + }; + os[o[i]].rows.push(i); + } + + for (var i in ns) { + if ( !hasOwn.call( ns, i ) ) { + continue; + } + if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) { + n[ns[i].rows[0]] = { + text: n[ns[i].rows[0]], + row: os[i].rows[0] + }; + o[os[i].rows[0]] = { + text: o[os[i].rows[0]], + row: ns[i].rows[0] + }; + } + } + + for (var i = 0; i < n.length - 1; i++) { + if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null && + n[i + 1] == o[n[i].row + 1]) { + n[i + 1] = { + text: n[i + 1], + row: n[i].row + 1 + }; + o[n[i].row + 1] = { + text: o[n[i].row + 1], + row: i + 1 + }; + } + } + + for (var i = n.length - 1; i > 0; i--) { + if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null && + n[i - 1] == o[n[i].row - 1]) { + n[i - 1] = { + text: n[i - 1], + row: n[i].row - 1 + }; + o[n[i].row - 1] = { + text: o[n[i].row - 1], + row: i - 1 + }; + } + } + + return { + o: o, + n: n + }; + } + + return function(o, n) { + o = o.replace(/\s+$/, ''); + n = n.replace(/\s+$/, ''); + var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/)); + + var str = ""; + + var oSpace = o.match(/\s+/g); + if (oSpace == null) { + oSpace = [" "]; + } + else { + oSpace.push(" "); + } + var nSpace = n.match(/\s+/g); + if (nSpace == null) { + nSpace = [" "]; + } + else { + nSpace.push(" "); + } + + if (out.n.length == 0) { + for (var i = 0; i < out.o.length; i++) { + str += '' + out.o[i] + oSpace[i] + ""; + } + } + else { + if (out.n[0].text == null) { + for (n = 0; n < out.o.length && out.o[n].text == null; n++) { + str += '' + out.o[n] + oSpace[n] + ""; + } + } + + for (var i = 0; i < out.n.length; i++) { + if (out.n[i].text == null) { + str += '' + out.n[i] + nSpace[i] + ""; + } + else { + var pre = ""; + + for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) { + pre += '' + out.o[n] + oSpace[n] + ""; + } + str += " " + out.n[i].text + nSpace[i] + pre; + } + } + } + + return str; + }; +})(); + +})(this); diff --git a/node_modules/underscore.deferred/underscore.deferred.js b/node_modules/underscore.deferred/underscore.deferred.js new file mode 100644 index 0000000..b7067e1 --- /dev/null +++ b/node_modules/underscore.deferred/underscore.deferred.js @@ -0,0 +1,427 @@ +(function(root){ + + // Let's borrow a couple of things from Underscore that we'll need + + // _.each + var breaker = {}, + AP = Array.prototype, + OP = Object.prototype, + + hasOwn = OP.hasOwnProperty, + toString = OP.toString, + forEach = AP.forEach, + slice = AP.slice; + + var _each = function( obj, iterator, context ) { + var key, i, l; + + if ( !obj ) { + return; + } + if ( forEach && obj.forEach === forEach ) { + obj.forEach( iterator, context ); + } else if ( obj.length === +obj.length ) { + for ( i = 0, l = obj.length; i < l; i++ ) { + if ( i in obj && iterator.call( context, obj[i], i, obj ) === breaker ) { + return; + } + } + } else { + for ( key in obj ) { + if ( hasOwn.call( obj, key ) ) { + if ( iterator.call( context, obj[key], key, obj) === breaker ) { + return; + } + } + } + } + }; + + // _.isFunction + var _isFunction = function( obj ) { + return !!(obj && obj.constructor && obj.call && obj.apply); + }; + + // _.extend + var _extend = function( obj ) { + + _each( slice.call( arguments, 1), function( source ) { + var prop; + + for ( prop in source ) { + if ( source[prop] !== void 0 ) { + obj[ prop ] = source[ prop ]; + } + } + }); + return obj; + }; + + // And some jQuery specific helpers + + var class2type = { "[object Array]": "array", "[object Function]": "function" }; + + var _type = function( obj ) { + return !obj ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }; + + // Now start the jQuery-cum-Underscore implementation. Some very + // minor changes to the jQuery source to get this working. + + // Internal Deferred namespace + var _d = {}; + + var flagsCache = {}; + // Convert String-formatted flags into Object-formatted ones and store in cache + function createFlags( flags ) { + var object = flagsCache[ flags ] = {}, + i, length; + flags = flags.split( /\s+/ ); + for ( i = 0, length = flags.length; i < length; i++ ) { + object[ flags[i] ] = true; + } + return object; + } + + _d.Callbacks = function( flags ) { + + // Convert flags from String-formatted to Object-formatted + // (we check in cache first) + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + + var // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = [], + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Add one or several callbacks to the list + add = function( args ) { + var i, + length, + elem, + type, + actual; + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = _type( elem ); + if ( type === "array" ) { + // Inspect recursively + add( elem ); + } else if ( type === "function" ) { + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + list.push( elem ); + } + } + } + }, + // Fire callbacks + fire = function( context, args ) { + args = args || []; + memory = !flags.memory || [ context, args ]; + fired = true; + firing = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { + memory = true; // Mark as halted + break; + } + } + firing = false; + if ( list ) { + if ( !flags.once ) { + if ( stack && stack.length ) { + memory = stack.shift(); + self.fireWith( memory[ 0 ], memory[ 1 ] ); + } + } else if ( memory === true ) { + self.disable(); + } else { + list = []; + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + var length = list.length; + add( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away, unless previous + // firing was halted (stopOnFalse) + } else if ( memory && memory !== true ) { + firingStart = length; + fire( memory[ 0 ], memory[ 1 ] ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + var args = arguments, + argIndex = 0, + argLength = args.length; + for ( ; argIndex < argLength ; argIndex++ ) { + for ( var i = 0; i < list.length; i++ ) { + if ( args[ argIndex ] === list[ i ] ) { + // Handle firingIndex and firingLength + if ( firing ) { + if ( i <= firingLength ) { + firingLength--; + if ( i <= firingIndex ) { + firingIndex--; + } + } + } + // Remove the element + list.splice( i--, 1 ); + // If we have some unicity property then + // we only need to do this once + if ( flags.unique ) { + break; + } + } + } + } + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + if ( list ) { + var i = 0, + length = list.length; + for ( ; i < length; i++ ) { + if ( fn === list[ i ] ) { + return true; + } + } + } + return false; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory || memory === true ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( stack ) { + if ( firing ) { + if ( !flags.once ) { + stack.push( [ context, args ] ); + } + } else if ( !( flags.once && memory ) ) { + fire( context, args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; + }; + + _d.Deferred = function( func ) { + var doneList = _d.Callbacks( "once memory" ), + failList = _d.Callbacks( "once memory" ), + progressList = _d.Callbacks( "memory" ), + state = "pending", + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { + done: doneList.add, + fail: failList.add, + progress: progressList.add, + + state: function() { + return state; + }, + + // Deprecated + isResolved: doneList.fired, + isRejected: failList.fired, + + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, + always: function() { + deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + return this; + }, + pipe: function( fnDone, fnFail, fnProgress ) { + return _d.Deferred(function( newDefer ) { + _each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ], + progress: [ fnProgress, "notify" ] + }, function( data, handler ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( _isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && _isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( !obj ) { + obj = promise; + } else { + for ( var key in promise ) { + obj[ key ] = promise[ key ]; + } + } + return obj; + } + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + "With" ] = lists[ key ].fireWith; + } + + // Handle state + deferred.done( function() { + state = "resolved"; + }, failList.disable, progressList.lock ).fail( function() { + state = "rejected"; + }, doneList.disable, progressList.lock ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }; + + // Deferred helper + _d.when = function( firstParam ) { + var args = slice.call( arguments, 0 ), + i = 0, + length = args.length, + pValues = new Array( length ), + count = length, + pCount = length, + deferred = length <= 1 && firstParam && _isFunction( firstParam.promise ) ? + firstParam : + _d.Deferred(), + promise = deferred.promise(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? slice.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( deferred, args ); + } + }; + } + function progressFunc( i ) { + return function( value ) { + pValues[ i ] = arguments.length > 1 ? slice.call( arguments, 0 ) : value; + deferred.notifyWith( promise, pValues ); + }; + } + if ( length > 1 ) { + for ( ; i < length; i++ ) { + if ( args[ i ] && args[ i ].promise && _isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return promise; + }; + + // Try exporting as a Common.js Module + if ( typeof module !== "undefined" && module.exports ) { + module.exports = _d; + + // Or mixin to Underscore.js + } else if ( typeof root._ !== "undefined" ) { + root._.mixin(_d); + + // Or assign it to window._ + } else { + root._ = _d; + } + +})(this); diff --git a/node_modules/underscore.string/.travis.yml b/node_modules/underscore.string/.travis.yml new file mode 100644 index 0000000..ab27b29 --- /dev/null +++ b/node_modules/underscore.string/.travis.yml @@ -0,0 +1,8 @@ +language: ruby +rvm: + - 1.9.3 + +before_script: + - "export DISPLAY=:99.0" + - "sh -e /etc/init.d/xvfb start" + - sleep 2 \ No newline at end of file diff --git a/node_modules/underscore.string/Gemfile b/node_modules/underscore.string/Gemfile new file mode 100644 index 0000000..f024827 --- /dev/null +++ b/node_modules/underscore.string/Gemfile @@ -0,0 +1,5 @@ +source :rubygems + +gem 'serve' +gem 'uglifier' +gem 'rake' \ No newline at end of file diff --git a/node_modules/underscore.string/Gemfile.lock b/node_modules/underscore.string/Gemfile.lock new file mode 100644 index 0000000..a6bb1e7 --- /dev/null +++ b/node_modules/underscore.string/Gemfile.lock @@ -0,0 +1,34 @@ +GEM + remote: http://rubygems.org/ + specs: + activesupport (3.2.3) + i18n (~> 0.6) + multi_json (~> 1.0) + execjs (1.3.0) + multi_json (~> 1.0) + i18n (0.6.0) + multi_json (1.2.0) + rack (1.4.1) + rack-test (0.6.1) + rack (>= 1.0) + rake (0.9.2.2) + serve (1.5.1) + activesupport (~> 3.0) + i18n + rack (~> 1.2) + rack-test (~> 0.5) + tilt (~> 1.3) + tzinfo + tilt (1.3.3) + tzinfo (0.3.33) + uglifier (1.2.4) + execjs (>= 0.3.0) + multi_json (>= 1.0.2) + +PLATFORMS + ruby + +DEPENDENCIES + rake + serve + uglifier diff --git a/node_modules/underscore.string/README.markdown b/node_modules/underscore.string/README.markdown new file mode 100644 index 0000000..d2244b5 --- /dev/null +++ b/node_modules/underscore.string/README.markdown @@ -0,0 +1,668 @@ +# Underscore.string [![Build Status](https://secure.travis-ci.org/epeli/underscore.string.png?branch=master)](http://travis-ci.org/epeli/underscore.string) # + + + +Javascript lacks complete string manipulation operations. +This an attempt to fill that gap. List of build-in methods can be found +for example from [Dive Into JavaScript][d]. + +[d]: http://www.diveintojavascript.com/core-javascript-reference/the-string-object + + +As name states this an extension for [Underscore.js][u], but it can be used +independently from **_s**-global variable. But with Underscore.js you can +use Object-Oriented style and chaining: + +[u]: http://documentcloud.github.com/underscore/ + +```javascript +_(" epeli ").chain().trim().capitalize().value() +=> "Epeli" +``` + +## Download ## + + * [Development version](https://raw.github.com/epeli/underscore.string/master/lib/underscore.string.js) *Uncompressed with Comments 18kb* + * [Production version](https://github.com/epeli/underscore.string/raw/master/dist/underscore.string.min.js) *Minified 7kb* + + +## Node.js installation ## + +**npm package** + + npm install underscore.string + +**Standalone usage**: + +```javascript +var _s = require('underscore.string'); +``` + +**Integrate with Underscore.js**: + +```javascript +var _ = require('underscore'); + +// Import Underscore.string to separate object, because there are conflict functions (include, reverse, contains) +_.str = require('underscore.string'); + +// Mix in non-conflict functions to Underscore namespace if you want +_.mixin(_.str.exports()); + +// All functions, include conflict, will be available through _.str object +_.str.include('Underscore.string', 'string'); // => true +``` + +## String Functions ## + +For availability of functions in this way you need to mix in Underscore.string functions: + +```javascript +_.mixin(_.string.exports()); +``` + +otherwise functions from examples will be available through _.string or _.str objects: + +```javascript +_.str.capitalize('epeli') +=> "Epeli" +``` + +**capitalize** _.capitalize(string) + +Converts first letter of the string to uppercase. + +```javascript +_.capitalize("foo Bar") +=> "Foo Bar" +``` + +**chop** _.chop(string, step) + +```javascript +_.chop('whitespace', 3) +=> ['whi','tes','pac','e'] +``` + +**clean** _.clean(str) + +Compress some whitespaces to one. + +```javascript +_.clean(" foo bar ") +=> 'foo bar' +``` + +**chars** _.chars(str) + +```javascript +_.chars('Hello') +=> ['H','e','l','l','o'] +``` + +**includes** _.includes(string, substring) + +Tests if string contains a substring. + +```javascript +_.includes("foobar", "ob") +=> true +``` + +**include** available only through _.str object, because Underscore has function with the same name. + +```javascript +_.str.include("foobar", "ob") +=> true +``` + +**includes** function was removed + +But you can create it in this way, for compatibility with previous versions: + +```javascript +_.includes = _.str.include +``` + +**count** _.count(string, substring) + +```javascript +_('Hello world').count('l') +=> 3 +``` + +**escapeHTML** _.escapeHTML(string) + +Converts HTML special characters to their entity equivalents. + +```javascript +_('
            Blah blah blah
            ').escapeHTML(); +=> '<div>Blah blah blah</div>' +``` + +**unescapeHTML** _.unescapeHTML(string) + +Converts entity characters to HTML equivalents. + +```javascript +_('<div>Blah blah blah</div>').unescapeHTML(); +=> '
            Blah blah blah
            ' +``` + +**insert** _.insert(string, index, substing) + +```javascript +_('Hello ').insert(6, 'world') +=> 'Hello world' +``` + +**isBlank** _.isBlank(string) + +```javascript +_('').isBlank(); // => true +_('\n').isBlank(); // => true +_(' ').isBlank(); // => true +_('a').isBlank(); // => false +``` + +**join** _.join(separator, *strings) + +Joins strings together with given separator + +```javascript +_.join(" ", "foo", "bar") +=> "foo bar" +``` + +**lines** _.lines(str) + +```javascript +_.lines("Hello\nWorld") +=> ["Hello", "World"] +``` + +**reverse** available only through _.str object, because Underscore has function with the same name. + +Return reversed string: + +```javascript +_.str.reverse("foobar") +=> 'raboof' +``` + +**splice** _.splice(string, index, howmany, substring) + +Like a array splice. + +```javascript +_('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli') +=> 'https://edtsech@bitbucket.org/epeli/underscore.strings' +``` + +**startsWith** _.startsWith(string, starts) + +This method checks whether string starts with starts. + +```javascript +_("image.gif").startsWith("image") +=> true +``` + +**endsWith** _.endsWith(string, ends) + +This method checks whether string ends with ends. + +```javascript +_("image.gif").endsWith("gif") +=> true +``` + +**succ** _.succ(str) + +Returns the successor to str. + +```javascript +_('a').succ() +=> 'b' + +_('A').succ() +=> 'B' +``` + +**supplant** + +Supplant function was removed, use Underscore.js [template function][p]. + +[p]: http://documentcloud.github.com/underscore/#template + +**strip** alias for *trim* + +**lstrip** alias for *ltrim* + +**rstrip** alias for *rtrim* + +**titleize** _.titleize(string) + +```javascript +_('my name is epeli').titleize() +=> 'My Name Is Epeli' +``` + +**camelize** _.camelize(string) + +Converts underscored or dasherized string to a camelized one + +```javascript +_('-moz-transform').camelize() +=> 'MozTransform' +``` + +**classify** _.classify(string) + +Converts string to camelized class name + +```javascript +_('some_class_name').classify() +=> 'SomeClassName' +``` + +**underscored** _.underscored(string) + +Converts a camelized or dasherized string into an underscored one + +```javascript +_('MozTransform').underscored() +=> 'moz_transform' +``` + +**dasherize** _.dasherize(string) + +Converts a underscored or camelized string into an dasherized one + +```javascript +_('MozTransform').dasherize() +=> '-moz-transform' +``` + +**humanize** _.humanize(string) + +Converts an underscored, camelized, or dasherized string into a humanized one. +Also removes beginning and ending whitespace, and removes the postfix '_id'. + +```javascript +_(' capitalize dash-CamelCase_underscore trim ').humanize() +=> 'Capitalize dash camel case underscore trim' +``` + +**trim** _.trim(string, [characters]) + +trims defined characters from begining and ending of the string. +Defaults to whitespace characters. + +```javascript +_.trim(" foobar ") +=> "foobar" + +_.trim("_-foobar-_", "_-") +=> "foobar" +``` + + +**ltrim** _.ltrim(string, [characters]) + +Left trim. Similar to trim, but only for left side. + + +**rtrim** _.rtrim(string, [characters]) + +Right trim. Similar to trim, but only for right side. + +**truncate** _.truncate(string, length, truncateString) + +```javascript +_('Hello world').truncate(5) +=> 'Hello...' + +_('Hello').truncate(10) +=> 'Hello' +``` + +**prune** _.prune(string, length, pruneString) + +Elegant version of truncate. +Makes sure the pruned string does not exceed the original length. +Avoid half-chopped words when truncating. + +```javascript +_('Hello, world').prune(5) +=> 'Hello...' + +_('Hello, world').prune(8) +=> 'Hello...' + +_('Hello, world').prune(5, ' (read a lot more)') +=> 'Hello, world' (as adding "(read a lot more)" would be longer than the original string) + +_('Hello, cruel world').prune(15) +=> 'Hello, cruel...' + +_('Hello').prune(10) +=> 'Hello' +``` + +**words** _.words(str, delimiter=" ") + +Split string by delimiter (String or RegExp), ' ' by default. + +```javascript +_.words("I love you") +=> ["I","love","you"] + +_.words("I_love_you", "_") +=> ["I","love","you"] + +_.words("I-love-you", /-/) +=> ["I","love","you"] +``` + +**sprintf** _.sprintf(string format, *arguments) + +C like string formatting. +Credits goes to [Alexandru Marasteanu][o]. +For more detailed documentation, see the [original page][o]. + +[o]: http://www.diveintojavascript.com/projects/sprintf-for-javascript + +```javascript +_.sprintf("%.1f", 1.17) +"1.2" +``` + +**pad** _.pad(str, length, [padStr, type]) + +pads the `str` 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. + +```javascript +_.pad("1", 8) +-> " 1"; + +_.pad("1", 8, '0') +-> "00000001"; + +_.pad("1", 8, '0', 'right') +-> "10000000"; + +_.pad("1", 8, '0', 'both') +-> "00001000"; + +_.pad("1", 8, 'bleepblorp', 'both') +-> "bbbb1bbb"; +``` + +**lpad** _.lpad(str, length, [padStr]) + +left-pad a string. Alias for `pad(str, length, padStr, 'left')` + +```javascript +_.lpad("1", 8, '0') +-> "00000001"; +``` + +**rpad** _.rpad(str, length, [padStr]) + +right-pad a string. Alias for `pad(str, length, padStr, 'right')` + +```javascript +_.rpad("1", 8, '0') +-> "10000000"; +``` + +**lrpad** _.lrpad(str, length, [padStr]) + +left/right-pad a string. Alias for `pad(str, length, padStr, 'both')` + +```javascript +_.lrpad("1", 8, '0') +-> "00001000"; +``` + +**center** alias for **lrpad** + +**ljust** alias for *rpad* + +**rjust** alias for *lpad* + +**toNumber** _.toNumber(string, [decimals]) + +Parse string to number. Returns NaN if string can't be parsed to number. + +```javascript +_('2.556').toNumber() +=> 3 + +_('2.556').toNumber(1) +=> 2.6 +``` + +**strRight** _.strRight(string, pattern) + +Searches a string from left to right for a pattern and returns a substring consisting of the characters in the string that are to the right of the pattern or all string if no match found. + +```javascript +_('This_is_a_test_string').strRight('_') +=> "is_a_test_string"; +``` + +**strRightBack** _.strRightBack(string, pattern) + +Searches a string from right to left for a pattern and returns a substring consisting of the characters in the string that are to the right of the pattern or all string if no match found. + +```javascript +_('This_is_a_test_string').strRightBack('_') +=> "string"; +``` + +**strLeft** _.strLeft(string, pattern) + +Searches a string from left to right for a pattern and returns a substring consisting of the characters in the string that are to the left of the pattern or all string if no match found. + +```javascript +_('This_is_a_test_string').strLeft('_') +=> "This"; +``` + +**strLeftBack** _.strLeftBack(string, pattern) + +Searches a string from right to left for a pattern and returns a substring consisting of the characters in the string that are to the left of the pattern or all string if no match found. + +```javascript +_('This_is_a_test_string').strLeftBack('_') +=> "This_is_a_test"; +``` + +**stripTags** + +Removes all html tags from string. + +```javascript +_('a link').stripTags() +=> 'a link' + +_('a link').stripTags() +=> 'a linkalert("hello world!")' +``` + +**toSentence** _.toSentence(array, [delimiter, lastDelimiter]) + +Join an array into a human readable sentence. + +```javascript +_.toSentence(['jQuery', 'Mootools', 'Prototype']) +=> 'jQuery, Mootools and Prototype'; + +_.toSentence(['jQuery', 'Mootools', 'Prototype'], ', ', ' unt ') +=> 'jQuery, Mootools unt Prototype'; +``` + +**repeat** _.repeat(string, count, [separator]) + +Repeats a string count times. + +```javascript +_.repeat("foo", 3) +=> 'foofoofoo'; + +_.repeat("foo", 3, "bar") +=> 'foobarfoobarfoo' +``` + +**slugify** _.slugify(string) + +Transform text into a URL slug. Replaces whitespaces, accentuated, and special characters with a dash. + +```javascript +_.slugify("Un éléphant à l'orée du bois") +=> 'un-elephant-a-loree-du-bois'; +``` + +***Caution: this function is charset dependent*** + +## Roadmap ## + +Any suggestions or bug reports are welcome. Just email me or more preferably open an issue. + +## Changelog ## + +### 2.0.0 ### + +* Added prune, humanize functions +* Added _.string (_.str) namespace for Underscore.string library +* Removed includes function + +#### Problems + +We lose two things for `include` and `reverse` methods from `_.string`: + +* Calls like `_('foobar').include('bar')` aren't available; +* Chaining isn't available too. + +But if you need this functionality you can create aliases for conflict functions which will be convenient for you: + +```javascript +_.mixin({ + includeString: _.str.include, + reverseString: _.str.reverse +}) + +// Now wrapper calls and chaining are available. +_('foobar').chain().reverseString().includeString('rab').value() +``` + +#### Standalone Usage + +If you are using Underscore.string without Underscore. You also have `_.string` namespace for it and `_.str` alias +But of course you can just reassign `_` variable with `_.string` + +```javascript +_ = _.string +``` +### 2.2.0 ### + +* Capitalize method behavior changed +* Various perfomance tweaks + +### 2.1.1### + +* Fixed words method bug +* Added classify method + +### 2.1.0 ### + +* AMD support +* Added toSentence method +* Added slugify method +* Lots of speed optimizations + +### 2.0.0 ### + +For upgrading to this version you need to mix in Underscore.string library to Underscore object: + +```javascript +_.mixin(_.string.exports()); +``` + +and all non-conflict Underscore.string functions will be available through Underscore object. +Also function `includes` has been removed, you should replace this function by `_.str.include` +or create alias `_.includes = _.str.include` and all your code will work fine. + +### 1.1.6 ### + +* Fixed reverse and truncate +* Added isBlank, stripTags, inlude(alias for includes) +* Added uglifier compression + +### 1.1.5 ### + +* Added strRight, strRightBack, strLeft, strLeftBack + +### 1.1.4 ### + +* Added pad, lpad, rpad, lrpad methods and aliases center, ljust, rjust +* Integration with Underscore 1.1.6 + +### 1.1.3 ### + +* Added methods: underscored, camelize, dasherize +* Support newer version of npm + +### 1.1.2 ### + +* Created functions: lines, chars, words functions + +### 1.0.2 ### + +* Created integration test suite with underscore.js 1.1.4 (now it's absolutely compatible) +* Removed 'reverse' function, because this function override underscore.js 'reverse' + +## Contribute ## + +* Fork & pull request. Don't forget about tests. +* If you planning add some feature please create issue before. + +Otherwise changes will be rejected. + +## Contributors list ## + +* Esa-Matti Suuronen (), +* Edward Tsech , +* Sasha Koss (), +* Vladimir Dronnikov , +* Pete Kruckenberg (), +* Paul Chavard (), +* Ed Finkler () +* Pavel Pravosud +* Anton Lindqvist () + +## Licence ## + +The MIT License + +Copyright (c) 2011 Esa-Matti Suuronen esa-matti@suuronen.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/underscore.string/Rakefile b/node_modules/underscore.string/Rakefile new file mode 100644 index 0000000..baa164c --- /dev/null +++ b/node_modules/underscore.string/Rakefile @@ -0,0 +1,28 @@ +# encoding: utf-8 +task default: :test + +desc 'Use UglifyJS to compress Underscore.string' +task :build do + require 'uglifier' + source = File.read('lib/underscore.string.js') + compressed = Uglifier.compile(source, copyright: false) + File.open('dist/underscore.string.min.js', 'w'){ |f| f.write compressed } + compression_rate = compressed.length.to_f/source.length + puts "compressed dist/underscore.string.min.js: #{compressed.length}/#{source.length} #{(compression_rate * 100).round}%" +end + +desc 'Run tests' +task :test do + pid = spawn('bundle exec serve', err: '/dev/null') + sleep 2 + + puts "Running underscore.string test suite." + result1 = system %{phantomjs ./test/run-qunit.js "http://localhost:4000/test/test.html"} + + puts "Running Underscore test suite." + result2 = system %{phantomjs ./test/run-qunit.js "http://localhost:4000/test/test_underscore/test.html"} + + Process.kill 'INT', pid + + exit(result1 && result2 ? 0 : 1) +end \ No newline at end of file diff --git a/node_modules/underscore.string/dist/underscore.string.min.js b/node_modules/underscore.string/dist/underscore.string.min.js new file mode 100644 index 0000000..cd436e1 --- /dev/null +++ b/node_modules/underscore.string/dist/underscore.string.min.js @@ -0,0 +1 @@ +(function(a){"use strict";var b=String.prototype.trim,c=String.prototype.trimRight,d=String.prototype.trimLeft,e=function(a){return a*1||0},f=function(a,b,c){a+="",b=~~b;for(var d=[];b>0;d[--b]=a);return d.join(c==null?"":c)},g=function(a){return Array.prototype.slice.call(a)},h=function(a){return a!=null?"["+m.escapeRegExp(""+a)+"]":"\\s"},i={lt:"<",gt:">",quot:'"',apos:"'",amp:"&"},j={};for(var k in i)j[i[k]]=k;var l=function(){function a(a){return Object.prototype.toString.call(a).slice(8,-1).toLowerCase()}var b=f,c=function(){return c.cache.hasOwnProperty(arguments[0])||(c.cache[arguments[0]]=c.parse(arguments[0])),c.format.call(null,c.cache[arguments[0]],arguments)};return c.format=function(c,d){var e=1,f=c.length,g="",h,i=[],j,k,m,n,o,p;for(j=0;j=0?"+"+h:h,o=m[4]?m[4]=="0"?"0":m[4].charAt(1):" ",p=m[6]-String(h).length,n=m[6]?b(o,p):"",i.push(m[5]?h+n:n+h)}}return i.join("")},c.cache={},c.parse=function(a){var b=a,c=[],d=[],e=0;while(b){if((c=/^[^\x25]+/.exec(b))!==null)d.push(c[0]);else if((c=/^\x25{2}/.exec(b))!==null)d.push("%");else{if((c=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(b))===null)throw new Error("[_.sprintf] huh?");if(c[2]){e|=1;var f=[],g=c[2],h=[];if((h=/^([a-z_][a-z_\d]*)/i.exec(g))===null)throw new Error("[_.sprintf] huh?");f.push(h[1]);while((g=g.substring(h[0].length))!=="")if((h=/^\.([a-z_][a-z_\d]*)/i.exec(g))!==null)f.push(h[1]);else{if((h=/^\[(\d+)\]/.exec(g))===null)throw new Error("[_.sprintf] huh?");f.push(h[1])}c[2]=f}else e|=2;if(e===3)throw new Error("[_.sprintf] mixing positional and named placeholders is not (yet) supported");d.push(c)}b=b.substring(c[0].length)}return d},c}(),m={VERSION:"2.1.1",isBlank:function(a){return/^\s*$/.test(a)},stripTags:function(a){return(""+a).replace(/<\/?[^>]+>/g,"")},capitalize:function(a){return a+="",a.charAt(0).toUpperCase()+a.substring(1)},chop:function(a,b){a+="",b=~~b||a.length;var c=[];for(var d=0;d"']/g,function(a){return"&"+j[a]+";"})},unescapeHTML:function(a){return(""+a).replace(/\&([^;]+);/g,function(a,b){var c;return b in i?i[b]:(c=b.match(/^#x([\da-fA-F]+)$/))?String.fromCharCode(parseInt(c[1],16)):(c=b.match(/^#(\d+)$/))?String.fromCharCode(~~c[1]):a})},escapeRegExp:function(a){return a.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1")},insert:function(a,b,c){var d=m.chars(a);return d.splice(~~b,0,""+c),d.join("")},include:function(a,b){return!!~(""+a).indexOf(b)},join:function(){var a=g(arguments);return a.join(a.shift())},lines:function(a){return(""+a).split("\n")},reverse:function(a){return m.chars(a).reverse().join("")},splice:function(a,b,c,d){var e=m.chars(a);return e.splice(~~b,~~c,d),e.join("")},startsWith:function(a,b){return a+="",b+="",a.length>=b.length&&a.substring(0,b.length)===b},endsWith:function(a,b){return a+="",b+="",a.length>=b.length&&a.substring(a.length-b.length)===b},succ:function(a){a+="";var b=m.chars(a);return b.splice(a.length-1,1,String.fromCharCode(a.charCodeAt(a.length-1)+1)),b.join("")},titleize:function(a){return(""+a).replace(/\b./g,function(a){return a.toUpperCase()})},camelize:function(a){return m.trim(a).replace(/[-_\s]+(.)?/g,function(a,b){return b&&b.toUpperCase()})},underscored:function(a){return m.trim(a).replace(/([a-z\d])([A-Z]+)/g,"$1_$2").replace(/[-\s]+/g,"_").toLowerCase()},dasherize:function(a){return m.trim(a).replace(/[_\s]+/g,"-").replace(/([A-Z])/g,"-$1").replace(/-+/g,"-").toLowerCase()},classify:function(a){return a+="",m.titleize(a.replace(/_/g," ")).replace(/\s/g,"")},humanize:function(a){return m.capitalize(this.underscored(a).replace(/_id$/,"").replace(/_/g," "))},trim:function(a,c){return a+="",!c&&b?b.call(a):(c=h(c),a.replace(new RegExp("^"+c+"+|"+c+"+$","g"),""))},ltrim:function(a,b){return a+="",!b&&d?d.call(a):(b=h(b),a.replace(new RegExp("^"+b+"+"),""))},rtrim:function(a,b){return a+="",!b&&c?c.call(a):(b=h(b),a.replace(new RegExp(b+"+$"),""))},truncate:function(a,b,c){return a+="",c=c||"...",b=~~b,a.length>b?a.slice(0,b)+c:a},prune:function(a,b,c){a+="",b=~~b,c=c!=null?""+c:"...";var d,e,f=a.replace(/\W/g,function(a){return a.toUpperCase()!==a.toLowerCase()?"A":" "});return e=f.charAt(b),d=f.slice(0,b),e&&e.match(/\S/)&&(d=d.replace(/\s\S+$/,"")),d=m.rtrim(d),(d+c).length>a.length?a:a.substring(0,d.length)+c},words:function(a,b){return m.trim(a,b).split(b||/\s+/)},pad:function(a,b,c,d){a+="";var e=0;b=~~b,c?c.length>1&&(c=c.charAt(0)):c=" ";switch(d){case"right":return e=b-a.length,a+f(c,e);case"both":return e=b-a.length,f(c,Math.ceil(e/2))+a+f(c,Math.floor(e/2));default:return e=b-a.length,f(c,e)+a}},lpad:function(a,b,c){return m.pad(a,b,c)},rpad:function(a,b,c){return m.pad(a,b,c,"right")},lrpad:function(a,b,c){return m.pad(a,b,c,"both")},sprintf:l,vsprintf:function(a,b){return b.unshift(a),l.apply(null,b)},toNumber:function(a,b){a+="";var c=e(e(a).toFixed(~~b));return c===0&&!a.match(/^0+$/)?Number.NaN:c},strRight:function(a,b){a+="",b=b!=null?""+b:b;var c=b?a.indexOf(b):-1;return~c?a.slice(c+b.length,a.length):a},strRightBack:function(a,b){a+="",b=b!=null?""+b:b;var c=b?a.lastIndexOf(b):-1;return~c?a.slice(c+b.length,a.length):a},strLeft:function(a,b){a+="",b=b!=null?""+b:b;var c=b?a.indexOf(b):-1;return~c?a.slice(0,c):a},strLeftBack:function(a,b){a+="",b=b!=null?""+b:b;var c=a.lastIndexOf(b);return~c?a.slice(0,c):a},toSentence:function(a,b,c){b||(b=", "),c||(c=" and ");var d=a.length,e="";for(var f=0;f +// Underscore.strings is freely distributable under the terms of the MIT license. +// Documentation: https://github.com/epeli/underscore.string +// Some code is borrowed from MooTools and Alexandru Marasteanu. + +// Version 2.2.0rc + +(function(root){ + 'use strict'; + + // Defining helper functions. + + var nativeTrim = String.prototype.trim; + var nativeTrimRight = String.prototype.trimRight; + var nativeTrimLeft = String.prototype.trimLeft; + + var parseNumber = function(source) { return source * 1 || 0; }; + + var strRepeat = function(str, qty, separator){ + // ~~var — is the fastest available way to convert anything to Integer in javascript. + // We'll use it extensively in this lib. + str += ''; qty = ~~qty; + for (var repeat = []; qty > 0; repeat[--qty] = str) {} + return repeat.join(separator == null ? '' : separator); + }; + + var slice = function(a){ + return Array.prototype.slice.call(a); + }; + + var defaultToWhiteSpace = function(characters){ + if (characters != null) { + return '[' + _s.escapeRegExp(''+characters) + ']'; + } + return '\\s'; + }; + + var escapeChars = { + lt: '<', + gt: '>', + quot: '"', + apos: "'", + amp: '&' + }; + + var reversedEscapeChars = {}; + for(var key in escapeChars){ reversedEscapeChars[escapeChars[key]] = key; } + + // sprintf() for JavaScript 0.7-beta1 + // http://www.diveintojavascript.com/projects/javascript-sprintf + // + // Copyright (c) Alexandru Marasteanu + // All rights reserved. + + var sprintf = (function() { + function get_type(variable) { + return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase(); + } + + var str_repeat = strRepeat; + + var str_format = function() { + if (!str_format.cache.hasOwnProperty(arguments[0])) { + str_format.cache[arguments[0]] = str_format.parse(arguments[0]); + } + return str_format.format.call(null, str_format.cache[arguments[0]], arguments); + }; + + str_format.format = function(parse_tree, argv) { + var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length; + for (i = 0; i < tree_length; i++) { + node_type = get_type(parse_tree[i]); + if (node_type === 'string') { + output.push(parse_tree[i]); + } + else if (node_type === 'array') { + match = parse_tree[i]; // convenience purposes only + if (match[2]) { // keyword argument + arg = argv[cursor]; + for (k = 0; k < match[2].length; k++) { + if (!arg.hasOwnProperty(match[2][k])) { + throw new Error(sprintf('[_.sprintf] property "%s" does not exist', match[2][k])); + } + arg = arg[match[2][k]]; + } + } else if (match[1]) { // positional argument (explicit) + arg = argv[match[1]]; + } + else { // positional argument (implicit) + arg = argv[cursor++]; + } + + if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) { + throw new Error(sprintf('[_.sprintf] expecting number but found %s', get_type(arg))); + } + switch (match[8]) { + case 'b': arg = arg.toString(2); break; + case 'c': arg = String.fromCharCode(arg); break; + case 'd': arg = parseInt(arg, 10); break; + case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; + case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; + case 'o': arg = arg.toString(8); break; + case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break; + case 'u': arg = Math.abs(arg); break; + case 'x': arg = arg.toString(16); break; + case 'X': arg = arg.toString(16).toUpperCase(); break; + } + arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); + pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' '; + pad_length = match[6] - String(arg).length; + pad = match[6] ? str_repeat(pad_character, pad_length) : ''; + output.push(match[5] ? arg + pad : pad + arg); + } + } + return output.join(''); + }; + + str_format.cache = {}; + + str_format.parse = function(fmt) { + var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; + while (_fmt) { + if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { + parse_tree.push(match[0]); + } + else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { + parse_tree.push('%'); + } + else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { + if (match[2]) { + arg_names |= 1; + var field_list = [], replacement_field = match[2], field_match = []; + if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { + if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + } + else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + } + else { + throw new Error('[_.sprintf] huh?'); + } + } + } + else { + throw new Error('[_.sprintf] huh?'); + } + match[2] = field_list; + } + else { + arg_names |= 2; + } + if (arg_names === 3) { + throw new Error('[_.sprintf] mixing positional and named placeholders is not (yet) supported'); + } + parse_tree.push(match); + } + else { + throw new Error('[_.sprintf] huh?'); + } + _fmt = _fmt.substring(match[0].length); + } + return parse_tree; + }; + + return str_format; + })(); + + + + // Defining underscore.string + + var _s = { + + VERSION: '2.2.0rc', + + isBlank: function(str){ + return (/^\s*$/).test(str); + }, + + stripTags: function(str){ + return (''+str).replace(/<\/?[^>]+>/g, ''); + }, + + capitalize : function(str) { + str += ''; + return str.charAt(0).toUpperCase() + str.substring(1); + }, + + chop: function(str, step){ + str = str+''; + step = ~~step || str.length; + var arr = []; + for (var i = 0; i < str.length; i += step) + arr.push(str.slice(i,i + step)); + return arr; + }, + + clean: function(str){ + return _s.strip(str).replace(/\s+/g, ' '); + }, + + count: function(str, substr){ + str += ''; substr += ''; + return str.split(substr).length - 1; + }, + + chars: function(str) { + return (''+str).split(''); + }, + + escapeHTML: function(str) { + return (''+str).replace(/[&<>"']/g, function(match){ return '&' + reversedEscapeChars[match] + ';'; }); + }, + + unescapeHTML: function(str) { + return (''+str).replace(/\&([^;]+);/g, function(entity, entityCode){ + var match; + + if (entityCode in escapeChars) { + return escapeChars[entityCode]; + } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) { + return String.fromCharCode(parseInt(match[1], 16)); + } else if (match = entityCode.match(/^#(\d+)$/)) { + return String.fromCharCode(~~match[1]); + } else { + return entity; + } + }); + }, + + escapeRegExp: function(str){ + // From MooTools core 1.2.4 + return str.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1'); + }, + + insert: function(str, i, substr){ + var arr = _s.chars(str); + arr.splice(~~i, 0, ''+substr); + return arr.join(''); + }, + + include: function(str, needle){ + return !!~(''+str).indexOf(needle); + }, + + join: function() { + var args = slice(arguments); + return args.join(args.shift()); + }, + + lines: function(str) { + return (''+str).split("\n"); + }, + + reverse: function(str){ + return _s.chars(str).reverse().join(''); + }, + + splice: function(str, i, howmany, substr){ + var arr = _s.chars(str); + arr.splice(~~i, ~~howmany, substr); + return arr.join(''); + }, + + startsWith: function(str, starts){ + str += ''; starts += ''; + return str.length >= starts.length && str.substring(0, starts.length) === starts; + }, + + endsWith: function(str, ends){ + str += ''; ends += ''; + return str.length >= ends.length && str.substring(str.length - ends.length) === ends; + }, + + succ: function(str){ + str += ''; + var arr = _s.chars(str); + arr.splice(str.length-1, 1, String.fromCharCode(str.charCodeAt(str.length-1) + 1)); + return arr.join(''); + }, + + titleize: function(str){ + return (''+str).replace(/\b./g, function(ch){ return ch.toUpperCase(); }); + }, + + camelize: function(str){ + return _s.trim(str).replace(/[-_\s]+(.)?/g, function(match, chr){ + return chr && chr.toUpperCase(); + }); + }, + + underscored: function(str){ + return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase(); + }, + + dasherize: function(str){ + return _s.trim(str).replace(/[_\s]+/g, '-').replace(/([A-Z])/g, '-$1').replace(/-+/g, '-').toLowerCase(); + }, + + classify: function(str){ + str += ''; + return _s.titleize(str.replace(/_/g, ' ')).replace(/\s/g, '') + }, + + humanize: function(str){ + return _s.capitalize(this.underscored(str).replace(/_id$/,'').replace(/_/g, ' ')); + }, + + trim: function(str, characters){ + str += ''; + if (!characters && nativeTrim) { return nativeTrim.call(str); } + characters = defaultToWhiteSpace(characters); + return str.replace(new RegExp('\^' + characters + '+|' + characters + '+$', 'g'), ''); + }, + + ltrim: function(str, characters){ + str+=''; + if (!characters && nativeTrimLeft) { + return nativeTrimLeft.call(str); + } + characters = defaultToWhiteSpace(characters); + return str.replace(new RegExp('^' + characters + '+'), ''); + }, + + rtrim: function(str, characters){ + str+=''; + if (!characters && nativeTrimRight) { + return nativeTrimRight.call(str); + } + characters = defaultToWhiteSpace(characters); + return str.replace(new RegExp(characters + '+$'), ''); + }, + + truncate: function(str, length, truncateStr){ + str += ''; truncateStr = truncateStr || '...'; + length = ~~length; + return str.length > length ? str.slice(0, length) + truncateStr : str; + }, + + /** + * _s.prune: a more elegant version of truncate + * prune extra chars, never leaving a half-chopped word. + * @author github.com/sergiokas + */ + prune: function(str, length, pruneStr){ + str += ''; length = ~~length; + pruneStr = pruneStr != null ? ''+pruneStr : '...'; + + var pruned, borderChar, template = str.replace(/\W/g, function(ch){ + return (ch.toUpperCase() !== ch.toLowerCase()) ? 'A' : ' '; + }); + + borderChar = template.charAt(length); + + pruned = template.slice(0, length); + + // Check if we're in the middle of a word + if (borderChar && borderChar.match(/\S/)) + pruned = pruned.replace(/\s\S+$/, ''); + + pruned = _s.rtrim(pruned); + + return (pruned+pruneStr).length > str.length ? str : str.substring(0, pruned.length)+pruneStr; + }, + + words: function(str, delimiter) { + return _s.trim(str, delimiter).split(delimiter || /\s+/); + }, + + pad: function(str, length, padStr, type) { + str += ''; + + var padlen = 0; + + length = ~~length; + + if (!padStr) { + padStr = ' '; + } else if (padStr.length > 1) { + padStr = padStr.charAt(0); + } + + switch(type) { + case 'right': + padlen = (length - str.length); + return str + strRepeat(padStr, padlen); + case 'both': + padlen = (length - str.length); + return strRepeat(padStr, Math.ceil(padlen/2)) + + str + + strRepeat(padStr, Math.floor(padlen/2)); + default: // 'left' + padlen = (length - str.length); + return strRepeat(padStr, padlen) + str; + } + }, + + lpad: function(str, length, padStr) { + return _s.pad(str, length, padStr); + }, + + rpad: function(str, length, padStr) { + return _s.pad(str, length, padStr, 'right'); + }, + + lrpad: function(str, length, padStr) { + return _s.pad(str, length, padStr, 'both'); + }, + + sprintf: sprintf, + + vsprintf: function(fmt, argv){ + argv.unshift(fmt); + return sprintf.apply(null, argv); + }, + + toNumber: function(str, decimals) { + str += ''; + var num = parseNumber(parseNumber(str).toFixed(~~decimals)); + return num === 0 && !str.match(/^0+$/) ? Number.NaN : num; + }, + + strRight: function(str, sep){ + str += ''; sep = sep != null ? ''+sep : sep; + var pos = !sep ? -1 : str.indexOf(sep); + return ~pos ? str.slice(pos+sep.length, str.length) : str; + }, + + strRightBack: function(str, sep){ + str += ''; sep = sep != null ? ''+sep : sep; + var pos = !sep ? -1 : str.lastIndexOf(sep); + return ~pos ? str.slice(pos+sep.length, str.length) : str; + }, + + strLeft: function(str, sep){ + str += ''; sep = sep != null ? ''+sep : sep; + var pos = !sep ? -1 : str.indexOf(sep); + return ~pos ? str.slice(0, pos) : str; + }, + + strLeftBack: function(str, sep){ + str += ''; sep = sep != null ? ''+sep : sep; + var pos = str.lastIndexOf(sep); + return ~pos ? str.slice(0, pos) : str; + }, + + toSentence: function(array, separator, lastSeparator) { + separator || (separator = ', '); + lastSeparator || (lastSeparator = ' and '); + var length = array.length, str = ''; + + for (var i = 0; i < length; i++) { + str += array[i]; + if (i === (length - 2)) { str += lastSeparator; } + else if (i < (length - 1)) { str += separator; } + } + + return str; + }, + + slugify: function(str) { + var from = "ąàáäâãćęèéëêìíïîłńòóöôõùúüûñçżź", + to = "aaaaaaceeeeeiiiilnooooouuuunczz", + regex = new RegExp(defaultToWhiteSpace(from), 'g'); + + str = (''+str).toLowerCase(); + + str = str.replace(regex, function(ch){ + var index = from.indexOf(ch); + return to.charAt(index) || '-'; + }); + + return _s.trim(str.replace(/[^\w\s-]/g, '').replace(/[-\s]+/g, '-'), '-'); + }, + + exports: function() { + var result = {}; + + for (var prop in this) { + if (!this.hasOwnProperty(prop) || ~_s.words('include contains reverse').indexOf(prop)) continue; + result[prop] = this[prop]; + } + + return result; + }, + + repeat: strRepeat + }; + + // Aliases + + _s.strip = _s.trim; + _s.lstrip = _s.ltrim; + _s.rstrip = _s.rtrim; + _s.center = _s.lrpad; + _s.rjust = _s.lpad; + _s.ljust = _s.rpad; + _s.contains = _s.include; + + // CommonJS module is defined + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + // Export module + module.exports = _s; + } + exports._s = _s; + + } else if (typeof define === 'function' && define.amd) { + // Register as a named module with AMD. + define('underscore.string', function() { + return _s; + }); + + } else { + // Integrate with Underscore.js if defined + // or create our own underscore object. + root._ = root._ || {}; + root._.string = root._.str = _s; + } + +}(this || window)); diff --git a/node_modules/underscore.string/package.json b/node_modules/underscore.string/package.json new file mode 100644 index 0000000..4dd4c9b --- /dev/null +++ b/node_modules/underscore.string/package.json @@ -0,0 +1,132 @@ +{ + "_args": [ + [ + { + "raw": "underscore.string@~2.2.1", + "scope": null, + "escapedName": "underscore.string", + "name": "underscore.string", + "rawSpec": "~2.2.1", + "spec": ">=2.2.1 <2.3.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt" + ] + ], + "_from": "underscore.string@>=2.2.1 <2.3.0", + "_id": "underscore.string@2.2.1", + "_inCache": true, + "_location": "/underscore.string", + "_npmUser": { + "name": "epeli", + "email": "esa-matti@suuronen.org" + }, + "_npmVersion": "1.2.32", + "_phantomChildren": {}, + "_requested": { + "raw": "underscore.string@~2.2.1", + "scope": null, + "escapedName": "underscore.string", + "name": "underscore.string", + "rawSpec": "~2.2.1", + "spec": ">=2.2.1 <2.3.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt", + "/grunt-legacy-util" + ], + "_resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz", + "_shasum": "d7c0fa2af5d5a1a67f4253daee98132e733f0f19", + "_shrinkwrap": null, + "_spec": "underscore.string@~2.2.1", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt", + "bugs": { + "url": "https://github.com/epeli/underscore.string/issues" + }, + "contributors": [ + { + "name": "Esa-Matti Suuronen", + "email": "esa-matti@suuronen.org", + "url": "http://esa-matti.suuronen.org/" + }, + { + "name": "Edward Tsech", + "email": "edtsech@gmail.com" + }, + { + "name": "Sasha Koss", + "email": "kossnocorp@gmail.com", + "url": "http://koss.nocorp.me/" + }, + { + "name": "Vladimir Dronnikov", + "email": "dronnikov@gmail.com" + }, + { + "name": "Pete Kruckenberg", + "email": "https://github.com/kruckenb", + "url": "" + }, + { + "name": "Paul Chavard", + "email": "paul@chavard.net", + "url": "" + }, + { + "name": "Ed Finkler", + "email": "coj@funkatron.com", + "url": "" + }, + { + "name": "Pavel Pravosud", + "email": "rwz@duckroll.ru" + } + ], + "dependencies": {}, + "description": "String manipulation extensions for Underscore.js javascript library.", + "devDependencies": {}, + "directories": { + "lib": "./lib" + }, + "dist": { + "shasum": "d7c0fa2af5d5a1a67f4253daee98132e733f0f19", + "tarball": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz" + }, + "engines": { + "node": "*" + }, + "homepage": "http://epeli.github.com/underscore.string/", + "keywords": [ + "underscore", + "string" + ], + "licenses": [ + { + "type": "MIT" + } + ], + "main": "./lib/underscore.string", + "maintainers": [ + { + "name": "edtsech", + "email": "edtsech@gmail.com" + }, + { + "name": "rwz", + "email": "rwz@duckroll.ru" + }, + { + "name": "epeli", + "email": "esa-matti@suuronen.org" + } + ], + "name": "underscore.string", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/epeli/underscore.string.git" + }, + "version": "2.2.1" +} diff --git a/node_modules/underscore.string/test/run-qunit.js b/node_modules/underscore.string/test/run-qunit.js new file mode 100644 index 0000000..326658e --- /dev/null +++ b/node_modules/underscore.string/test/run-qunit.js @@ -0,0 +1,44 @@ +function waitFor(test, complete, timeout) { + var result, start = new Date().getTime() + setInterval(function interval() { + if ((new Date().getTime() - start < timeout) && !result) { + result = test() + } else { + if (!result) { + phantom.exit(1) + } else { + complete() + clearInterval(interval) + } + } + }, 100) +} + + +var page = new WebPage() + +page.onConsoleMessage = function(msg) { + console.log(msg) +} + +page.open(phantom.args[0], function(status) { + waitFor(function() { + return page.evaluate(function(){ + var el = document.getElementById('qunit-testresult') + return el && el.innerText.match('completed') + }) + }, function() { + var failures = page.evaluate(function() { + var el = document.getElementById('qunit-testresult'), + fails = document.getElementsByClassName('fail') + + for (var i = 0; i < fails.length; i++) + console.log(fails[i].innerText) + + console.log(el.innerText) + + return parseInt(el.getElementsByClassName('failed')[0].innerHTML) + }) + phantom.exit(failures > 0 ? 1 : 0) + }, 10000) +}) \ No newline at end of file diff --git a/node_modules/underscore.string/test/speed.js b/node_modules/underscore.string/test/speed.js new file mode 100644 index 0000000..4346414 --- /dev/null +++ b/node_modules/underscore.string/test/speed.js @@ -0,0 +1,138 @@ +(function() { + + JSLitmus.test('trimNoNative', function() { + return _.trim(" foobar ", " "); + }); + + JSLitmus.test('trim', function() { + return _.trim(" foobar "); + }); + + JSLitmus.test('trim object-oriented', function() { + return _(" foobar ").trim(); + }); + + JSLitmus.test('trim jQuery', function() { + return jQuery.trim(" foobar "); + }); + + JSLitmus.test('ltrimp', function() { + return _.ltrim(" foobar ", " "); + }); + + JSLitmus.test('rtrimp', function() { + return _.rtrim(" foobar ", " "); + }); + + JSLitmus.test('startsWith', function() { + return _.startsWith("foobar", "foo"); + }); + + JSLitmus.test('endsWith', function() { + return _.endsWith("foobar", "xx"); + }); + + JSLitmus.test('chop', function(){ + return _('whitespace').chop(2); + }); + + JSLitmus.test('count', function(){ + return _('Hello worls').count('l'); + }); + + JSLitmus.test('insert', function() { + return _('Hello ').insert(6, 'world'); + }); + + JSLitmus.test('splice', function() { + return _('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli'); + }); + + JSLitmus.test('succ', function(){ + var let = 'a', alphabet = []; + + for (var i=0; i < 26; i++) { + alphabet.push(let); + let = _(let).succ(); + } + + return alphabet; + }); + + JSLitmus.test('titleize', function(){ + return _('the titleize string method').titleize(); + }); + + JSLitmus.test('truncate', function(){ + return _('Hello world').truncate(5); + }); + + JSLitmus.test('prune', function(){ + return _('Hello world').prune(5); + }); + + JSLitmus.test('isBlank', function(){ + return _('').isBlank(); + }); + + JSLitmus.test('escapeHTML', function(){ + _('
            Blah blah blah
            ').escapeHTML(); + }); + + JSLitmus.test('unescapeHTML', function(){ + _('<div>Blah blah blah</div>').unescapeHTML(); + }); + + JSLitmus.test('reverse', function(){ + _('Hello World').reverse(); + }); + + JSLitmus.test('pad default', function(){ + _('foo').pad(12); + }); + + JSLitmus.test('pad hash left', function(){ + _('foo').pad(12, '#'); + }); + + JSLitmus.test('pad hash right', function(){ + _('foo').pad(12, '#', 'right'); + }); + + JSLitmus.test('pad hash both', function(){ + _('foo').pad(12, '#', 'both'); + }); + + JSLitmus.test('pad hash both longPad', function(){ + _('foo').pad(12, 'f00f00f00', 'both'); + }); + + JSLitmus.test('toNumber', function(){ + _('10.232323').toNumber(2); + }); + + JSLitmus.test('strRight', function(){ + _('aaa_bbb_ccc').strRight('_'); + }); + + JSLitmus.test('strRightBack', function(){ + _('aaa_bbb_ccc').strRightBack('_'); + }); + + JSLitmus.test('strLeft', function(){ + _('aaa_bbb_ccc').strLeft('_'); + }); + + JSLitmus.test('strLeftBack', function(){ + _('aaa_bbb_ccc').strLeftBack('_'); + }); + + JSLitmus.test('join', function(){ + _('separator').join(1, 2, 3, 4, 5, 6, 7, 8, 'foo', 'bar', 'lol', 'wut'); + }); + + JSLitmus.test('slugify', function(){ + _("Un éléphant à l'orée du bois").slugify(); + }); + +})(); diff --git a/node_modules/underscore.string/test/strings.js b/node_modules/underscore.string/test/strings.js new file mode 100644 index 0000000..f700abf --- /dev/null +++ b/node_modules/underscore.string/test/strings.js @@ -0,0 +1,438 @@ +$(document).ready(function() { + + // Include Underscore.string methods to Underscore namespace + _.mixin(_.str.exports()); + + module("String extensions"); + + test("Strings: trim", function() { + equals(_.trim(123), "123", "Non string"); + equals(_(" foo").trim(), "foo"); + equals(_("foo ").trim(), "foo"); + equals(_(" foo ").trim(), "foo"); + equals(_(" foo ").trim(), "foo"); + equals(_(" foo ", " ").trim(), "foo", "Manually set whitespace"); + + equals(_("ffoo").trim("f"), "oo"); + equals(_("ooff").trim("f"), "oo"); + equals(_("ffooff").trim("f"), "oo"); + + + equals(_("_-foobar-_").trim("_-"), "foobar"); + + equals(_("http://foo/").trim("/"), "http://foo"); + equals(_("c:\\").trim('\\'), "c:"); + + equals(_(123).trim(), '123'); + equals(_(123).trim(3), '12'); + }); + + test("Strings: ltrim", function() { + equals(_(" foo").ltrim(), "foo"); + equals(_(" foo").ltrim(), "foo"); + equals(_("foo ").ltrim(), "foo "); + equals(_(" foo ").ltrim(), "foo "); + + + equals(_("ffoo").ltrim("f"), "oo"); + equals(_("ooff").ltrim("f"), "ooff"); + equals(_("ffooff").ltrim("f"), "ooff"); + + equals(_("_-foobar-_").ltrim("_-"), "foobar-_"); + + equals(_(123).ltrim(1), '23'); + }); + + test("Strings: rtrim", function() { + equals(_("http://foo/").rtrim("/"), "http://foo", 'clean trailing slash'); + equals(_(" foo").rtrim(), " foo"); + equals(_("foo ").rtrim(), "foo"); + equals(_("foo ").rtrim(), "foo"); + equals(_("foo bar ").rtrim(), "foo bar"); + equals(_(" foo ").rtrim(), " foo"); + + equals(_("ffoo").rtrim("f"), "ffoo"); + equals(_("ooff").rtrim("f"), "oo"); + equals(_("ffooff").rtrim("f"), "ffoo"); + + equals(_("_-foobar-_").rtrim("_-"), "_-foobar"); + + equals(_(123).rtrim(3), '12'); + }); + + test("Strings: capitalize", function() { + equals(_("fabio").capitalize(), "Fabio", 'First letter is upper case'); + equals(_.capitalize("fabio"), "Fabio", 'First letter is upper case'); + equals(_.capitalize('FOO'), 'FOO', 'Other letters unchanged'); + equals(_(123).capitalize(), "123", "Non string"); + }); + + test("Strings: join", function() { + equals(_.join("", "foo", "bar"), "foobar", 'basic join'); + equals(_.join("", 1, "foo", 2), "1foo2", 'join numbers and strings'); + equals(_.join(" ","foo", "bar"), "foo bar", 'join with spaces'); + equals(_.join("1", "2", "2"), "212", 'join number strings'); + equals(_.join(1, 2, 2), "212", 'join numbers'); + equals(_(" ").join("foo", "bar"), "foo bar", 'join object oriented'); + }); + + test("Strings: reverse", function() { + equals(_.str.reverse("foo"), "oof" ); + equals(_.str.reverse("foobar"), "raboof" ); + equals(_.str.reverse("foo bar"), "rab oof" ); + equals(_.str.reverse("saippuakauppias"), "saippuakauppias" ); + equals(_.str.reverse(123), "321", "Non string"); + equals(_.str.reverse(123.45), "54.321", "Non string"); + }); + + test("Strings: clean", function() { + equals(_(" foo bar ").clean(), "foo bar"); + equals(_(123).clean(), "123"); + }); + + test("Strings: sprintf", function() { + // Should be very tested function already. Thanks to + // http://www.diveintojavascript.com/projects/sprintf-for-javascript + equals(_.sprintf("Hello %s", "me"), "Hello me", 'basic'); + equals(_("Hello %s").sprintf("me"), "Hello me", 'object'); + equals(_("hello %s").chain().sprintf("me").capitalize().value(), "Hello me", 'Chaining works'); + equals(_.sprintf("%.1f", 1.22222), "1.2", 'round'); + equals(_.sprintf("%.1f", 1.17), "1.2", 'round 2'); + equals(_.sprintf("%(id)d - %(name)s", {id: 824, name: "Hello World"}), "824 - Hello World", 'Named replacements work'); + equals(_.sprintf("%(args[0].id)d - %(args[1].name)s", {args: [{id: 824}, {name: "Hello World"}]}), "824 - Hello World", 'Named replacements with arrays work'); + }); + + + test("Strings: vsprintf", function() { + equals(_.vsprintf("Hello %s", ["me"]), "Hello me", 'basic'); + equals(_("Hello %s").vsprintf(["me"]), "Hello me", 'object'); + equals(_("hello %s").chain().vsprintf(["me"]).capitalize().value(), "Hello me", 'Chaining works'); + equals(_.vsprintf("%.1f", [1.22222]), "1.2", 'round'); + equals(_.vsprintf("%.1f", [1.17]), "1.2", 'round 2'); + equals(_.vsprintf("%(id)d - %(name)s", [{id: 824, name: "Hello World"}]), "824 - Hello World", 'Named replacement works'); + equals(_.vsprintf("%(args[0].id)d - %(args[1].name)s", [{args: [{id: 824}, {name: "Hello World"}]}]), "824 - Hello World", 'Named replacement with arrays works'); + }); + + test("Strings: startsWith", function() { + ok(_("foobar").startsWith("foo"), 'foobar starts with foo'); + ok(!_("oobar").startsWith("foo"), 'oobar does not start with foo'); + ok(_(12345).startsWith(123), '12345 starts with 123'); + ok(!_(2345).startsWith(123), '2345 does not start with 123'); + }); + + test("Strings: endsWith", function() { + ok(_("foobar").endsWith("bar"), 'foobar ends with bar'); + ok(_.endsWith("foobar", "bar"), 'foobar ends with bar'); + ok(_.endsWith("00018-0000062.Plone.sdh264.1a7264e6912a91aa4a81b64dc5517df7b8875994.mp4", "mp4"), 'endsWith .mp4'); + ok(!_("fooba").endsWith("bar"), 'fooba does not end with bar'); + ok(_.endsWith(12345, 45), '12345 ends with 45'); + ok(!_.endsWith(12345, 6), '12345 does not end with 6'); + }); + + test("Strings: include", function() { + ok(_.str.include("foobar", "bar"), 'foobar includes bar'); + ok(!_.str.include("foobar", "buzz"), 'foobar does not includes buzz'); + ok(_.str.include(12345, 34), '12345 includes 34'); + ok(!_.str.contains(12345, 6), '12345 does not includes 6'); + }); + + test('String: chop', function(){ + ok(_('whitespace').chop(2).length === 5, "output ['wh','it','es','pa','ce']"); + ok(_('whitespace').chop(3).length === 4, "output ['whi','tes','pac','e']"); + ok(_('whitespace').chop()[0].length === 10, "output ['whitespace']"); + ok(_(12345).chop(1).length === 5, "output ['1','2','3','4','5']"); + }); + + test('String: clean', function(){ + equals(_.clean(' foo bar '), 'foo bar'); + equals(_.clean(1), '1'); + }); + + test('String: count', function(){ + equals(_('Hello world').count('l'), 3); + equals(_('Hello world').count('Hello'), 1); + equals(_('Hello world').count('foo'), 0); + equals(_('x.xx....x.x').count('x'), 5); + equals(_(12345).count(1), 1); + equals(_(11345).count(1), 2); + }); + + test('String: insert', function(){ + equals(_('Hello ').insert(6, 'Jessy'), 'Hello Jessy'); + equals(_('Hello ').insert(100, 'Jessy'), 'Hello Jessy'); + equals(_(12345).insert(6, 'Jessy'), '12345Jessy'); + }); + + test('String: splice', function(){ + equals(_('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli'), + 'https://edtsech@bitbucket.org/epeli/underscore.strings'); + equals(_.splice(12345, 1, 2, 321), '132145', 'Non strings'); + }); + + test('String: succ', function(){ + equals(_('a').succ(), 'b'); + equals(_('A').succ(), 'B'); + equals(_('+').succ(), ','); + equals(_(1).succ(), '2'); + }); + + test('String: titleize', function(){ + equals(_('the titleize string method').titleize(), 'The Titleize String Method'); + equals(_('the titleize string method').titleize(), 'The Titleize String Method'); + equals(_(123).titleize(), '123'); + }); + + test('String: camelize', function(){ + equals(_('the_camelize_string_method').camelize(), 'theCamelizeStringMethod'); + equals(_('-the-camelize-string-method').camelize(), 'TheCamelizeStringMethod'); + equals(_('the camelize string method').camelize(), 'theCamelizeStringMethod'); + equals(_(' the camelize string method').camelize(), 'theCamelizeStringMethod'); + equals(_('the camelize string method').camelize(), 'theCamelizeStringMethod'); + equals(_(123).camelize(), '123'); + }); + + test('String: underscored', function(){ + equals(_('the-underscored-string-method').underscored(), 'the_underscored_string_method'); + equals(_('theUnderscoredStringMethod').underscored(), 'the_underscored_string_method'); + equals(_('TheUnderscoredStringMethod').underscored(), 'the_underscored_string_method'); + equals(_(' the underscored string method').underscored(), 'the_underscored_string_method'); + equals(_(123).underscored(), '123'); + }); + + test('String: dasherize', function(){ + equals(_('the_dasherize_string_method').dasherize(), 'the-dasherize-string-method'); + equals(_('TheDasherizeStringMethod').dasherize(), '-the-dasherize-string-method'); + equals(_('thisIsATest').dasherize(), 'this-is-a-test'); + equals(_('this Is A Test').dasherize(), 'this-is-a-test'); + equals(_('thisIsATest123').dasherize(), 'this-is-a-test123'); + equals(_('123thisIsATest').dasherize(), '123this-is-a-test'); + equals(_('the dasherize string method').dasherize(), 'the-dasherize-string-method'); + equals(_('the dasherize string method ').dasherize(), 'the-dasherize-string-method'); + equals(_('téléphone').dasherize(), 'téléphone'); + equals(_('foo$bar').dasherize(), 'foo$bar'); + equals(_(123).dasherize(), '123'); + }); + + test('String: camelize', function(){ + equals(_.camelize('-moz-transform'), 'MozTransform'); + equals(_.camelize('webkit-transform'), 'webkitTransform'); + equals(_.camelize('under_scored'), 'underScored'); + equals(_.camelize(' with spaces'), 'withSpaces'); + }); + + test('String: join', function(){ + equals(_.join(1, 2, 3, 4), '21314'); + equals(_.join('|', 'foo', 'bar', 'baz'), 'foo|bar|baz'); + }); + + test('String: classify', function(){ + equals(_.classify(1), '1'); + equals(_('some_class_name').classify(), 'SomeClassName'); + }); + + test('String: humanize', function(){ + equals(_('the_humanize_string_method').humanize(), 'The humanize string method'); + equals(_('ThehumanizeStringMethod').humanize(), 'Thehumanize string method'); + equals(_('the humanize string method').humanize(), 'The humanize string method'); + equals(_('the humanize_id string method_id').humanize(), 'The humanize id string method'); + equals(_('the humanize string method ').humanize(), 'The humanize string method'); + equals(_(' capitalize dash-CamelCase_underscore trim ').humanize(), 'Capitalize dash camel case underscore trim'); + equals(_(123).humanize(), '123'); + }); + + test('String: truncate', function(){ + equals(_('Hello world').truncate(6, 'read more'), 'Hello read more'); + equals(_('Hello world').truncate(5), 'Hello...'); + equals(_('Hello').truncate(10), 'Hello'); + equals(_(1234567890).truncate(5), '12345...'); + }); + + test('String: prune', function(){ + equals(_('Hello, cruel world').prune(6, ' read more'), 'Hello read more'); + equals(_('Hello, world').prune(5, 'read a lot more'), 'Hello, world'); + equals(_('Hello, world').prune(5), 'Hello...'); + equals(_('Hello, world').prune(8), 'Hello...'); + equals(_('Hello, cruel world').prune(15), 'Hello, cruel...'); + equals(_('Hello world').prune(22), 'Hello world'); + equals(_('Привет, жестокий мир').prune(6, ' read more'), 'Привет read more'); + equals(_('Привет, мир').prune(6, 'read a lot more'), 'Привет, мир'); + equals(_('Привет, мир').prune(6), 'Привет...'); + equals(_('Привет, мир').prune(8), 'Привет...'); + equals(_('Привет, жестокий мир').prune(16), 'Привет, жестокий...'); + equals(_('Привет, мир').prune(22), 'Привет, мир'); + equals(_(123).prune(10), '123'); + equals(_(123).prune(1,1), '11'); + }); + + test('String: isBlank', function(){ + ok(_('').isBlank()); + ok(_(' ').isBlank()); + ok(_('\n').isBlank()); + ok(!_('a').isBlank()); + ok(!_('0').isBlank()); + ok(!_(0).isBlank()); + }); + + test('String: escapeHTML', function(){ + equals(_('
            Blah & "blah" & \'blah\'
            ').escapeHTML(), + '<div>Blah & "blah" & 'blah'</div>'); + equals(_('<').escapeHTML(), '&lt;'); + equals(_(5).escapeHTML(), '5'); + // equals(_(undefined).escapeHTML(), ''); + }); + + test('String: unescapeHTML', function(){ + equals(_('<div>Blah & "blah" & 'blah'</div>').unescapeHTML(), + '
            Blah & "blah" & \'blah\'
            '); + equals(_('&lt;').unescapeHTML(), '<'); + equals(_(''').unescapeHTML(), "'"); + equals(_(''').unescapeHTML(), "'"); + equals(_('J').unescapeHTML(), "J"); + equals(_('J').unescapeHTML(), "J"); + equals(_('J').unescapeHTML(), "J"); + equals(_('&_#39;').unescapeHTML(), "&_#39;"); + equals(_(''_;').unescapeHTML(), "'_;"); + equals(_('&#38;').unescapeHTML(), "&"); + equals(_('&amp;').unescapeHTML(), "&"); + equals(_(5).unescapeHTML(), '5'); + // equals(_(undefined).unescapeHTML(), ''); + }); + + test('String: words', function() { + equals(_("I love you!").words().length, 3); + equals(_(" I love you! ").words().length, 3); + equals(_("I_love_you!").words('_').length, 3); + equals(_("I-love-you!").words(/-/).length, 3); + equals(_(123).words().length, 1); + }); + + test('String: chars', function() { + equals(_("Hello").chars().length, 5); + equals(_(123).chars().length, 3); + }); + + test('String: lines', function() { + equals(_("Hello\nWorld").lines().length, 2); + equals(_("Hello World").lines().length, 1); + equals(_(123).lines().length, 1); + }); + + test('String: pad', function() { + equals(_("1").pad(8), ' 1'); + equals(_(1).pad(8), ' 1'); + equals(_("1").pad(8, '0'), '00000001'); + equals(_("1").pad(8, '0', 'left'), '00000001'); + equals(_("1").pad(8, '0', 'right'), '10000000'); + equals(_("1").pad(8, '0', 'both'), '00001000'); + equals(_("foo").pad(8, '0', 'both'), '000foo00'); + equals(_("foo").pad(7, '0', 'both'), '00foo00'); + equals(_("foo").pad(7, '!@$%dofjrofj', 'both'), '!!foo!!'); + }); + + test('String: lpad', function() { + equals(_("1").lpad(8), ' 1'); + equals(_(1).lpad(8), ' 1'); + equals(_("1").lpad(8, '0'), '00000001'); + equals(_("1").lpad(8, '0', 'left'), '00000001'); + }); + + test('String: rpad', function() { + equals(_("1").rpad(8), '1 '); + equals(_(1).lpad(8), ' 1'); + equals(_("1").rpad(8, '0'), '10000000'); + equals(_("foo").rpad(8, '0'), 'foo00000'); + equals(_("foo").rpad(7, '0'), 'foo0000'); + }); + + test('String: lrpad', function() { + equals(_("1").lrpad(8), ' 1 '); + equals(_(1).lrpad(8), ' 1 '); + equals(_("1").lrpad(8, '0'), '00001000'); + equals(_("foo").lrpad(8, '0'), '000foo00'); + equals(_("foo").lrpad(7, '0'), '00foo00'); + equals(_("foo").lrpad(7, '!@$%dofjrofj'), '!!foo!!'); + }); + + test('String: toNumber', function() { + deepEqual(_("not a number").toNumber(), Number.NaN); + equals(_(0).toNumber(), 0); + equals(_("0").toNumber(), 0); + equals(_("0000").toNumber(), 0); + equals(_("2.345").toNumber(), 2); + equals(_("2.345").toNumber(NaN), 2); + equals(_("2.345").toNumber(2), 2.35); + equals(_("2.344").toNumber(2), 2.34); + equals(_("2").toNumber(2), 2.00); + equals(_(2).toNumber(2), 2.00); + equals(_(-2).toNumber(), -2); + equals(_("-2").toNumber(), -2); + }); + + test('String: strRight', function() { + equals(_("This_is_a_test_string").strRight("_"), "is_a_test_string"); + equals(_("This_is_a_test_string").strRight("string"), ""); + equals(_("This_is_a_test_string").strRight(), "This_is_a_test_string"); + equals(_("This_is_a_test_string").strRight(""), "This_is_a_test_string"); + equals(_("This_is_a_test_string").strRight("-"), "This_is_a_test_string"); + equals(_(12345).strRight(2), "345"); + }); + + test('String: strRightBack', function() { + equals(_("This_is_a_test_string").strRightBack("_"), "string"); + equals(_("This_is_a_test_string").strRightBack("string"), ""); + equals(_("This_is_a_test_string").strRightBack(), "This_is_a_test_string"); + equals(_("This_is_a_test_string").strRightBack(""), "This_is_a_test_string"); + equals(_("This_is_a_test_string").strRightBack("-"), "This_is_a_test_string"); + equals(_(12345).strRightBack(2), "345"); + }); + + test('String: strLeft', function() { + equals(_("This_is_a_test_string").strLeft("_"), "This"); + equals(_("This_is_a_test_string").strLeft("This"), ""); + equals(_("This_is_a_test_string").strLeft(), "This_is_a_test_string"); + equals(_("This_is_a_test_string").strLeft(""), "This_is_a_test_string"); + equals(_("This_is_a_test_string").strLeft("-"), "This_is_a_test_string"); + equals(_(123454321).strLeft(3), "12"); + }); + + test('String: strLeftBack', function() { + equals(_("This_is_a_test_string").strLeftBack("_"), "This_is_a_test"); + equals(_("This_is_a_test_string").strLeftBack("This"), ""); + equals(_("This_is_a_test_string").strLeftBack(), "This_is_a_test_string"); + equals(_("This_is_a_test_string").strLeftBack(""), "This_is_a_test_string"); + equals(_("This_is_a_test_string").strLeftBack("-"), "This_is_a_test_string"); + equals(_(123454321).strLeftBack(3), "123454"); + }); + + test('Strings: stripTags', function() { + equals(_('a link').stripTags(), 'a link'); + equals(_('a link + + + + + + + + +

            Underscore.string Test Suite

            +

            +

            +
              +
              +

              Underscore.string Speed Suite

              + +
              + + diff --git a/node_modules/underscore.string/test/test_standalone.html b/node_modules/underscore.string/test/test_standalone.html new file mode 100644 index 0000000..9854c17 --- /dev/null +++ b/node_modules/underscore.string/test/test_standalone.html @@ -0,0 +1,18 @@ + + + + Underscore.strings Test Suite + + + + + + + + +

              Underscore.string Test Suite

              +

              +

              +
                + + diff --git a/node_modules/underscore.string/test/test_underscore/arrays.js b/node_modules/underscore.string/test/test_underscore/arrays.js new file mode 100644 index 0000000..b3b1ce1 --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/arrays.js @@ -0,0 +1,166 @@ +$(document).ready(function() { + + module("Arrays"); + + test("arrays: first", function() { + equals(_.first([1,2,3]), 1, 'can pull out the first element of an array'); + equals(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"'); + equals(_.first([1,2,3], 0).join(', '), "", 'can pass an index to first'); + equals(_.first([1,2,3], 2).join(', '), '1, 2', 'can pass an index to first'); + equals(_.first([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to first'); + var result = (function(){ return _.first(arguments); })(4, 3, 2, 1); + equals(result, 4, 'works on an arguments object.'); + result = _.map([[1,2,3],[1,2,3]], _.first); + equals(result.join(','), '1,1', 'works well with _.map'); + }); + + test("arrays: rest", function() { + var numbers = [1, 2, 3, 4]; + equals(_.rest(numbers).join(", "), "2, 3, 4", 'working rest()'); + equals(_.rest(numbers, 0).join(", "), "1, 2, 3, 4", 'working rest(0)'); + equals(_.rest(numbers, 2).join(', '), '3, 4', 'rest can take an index'); + var result = (function(){ return _(arguments).tail(); })(1, 2, 3, 4); + equals(result.join(', '), '2, 3, 4', 'aliased as tail and works on arguments object'); + result = _.map([[1,2,3],[1,2,3]], _.rest); + equals(_.flatten(result).join(','), '2,3,2,3', 'works well with _.map'); + }); + + test("arrays: initial", function() { + equals(_.initial([1,2,3,4,5]).join(", "), "1, 2, 3, 4", 'working initial()'); + equals(_.initial([1,2,3,4],2).join(", "), "1, 2", 'initial can take an index'); + var result = (function(){ return _(arguments).initial(); })(1, 2, 3, 4); + equals(result.join(", "), "1, 2, 3", 'initial works on arguments object'); + result = _.map([[1,2,3],[1,2,3]], _.initial); + equals(_.flatten(result).join(','), '1,2,1,2', 'initial works with _.map'); + }); + + test("arrays: last", function() { + equals(_.last([1,2,3]), 3, 'can pull out the last element of an array'); + equals(_.last([1,2,3], 0).join(', '), "", 'can pass an index to last'); + equals(_.last([1,2,3], 2).join(', '), '2, 3', 'can pass an index to last'); + equals(_.last([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to last'); + var result = (function(){ return _(arguments).last(); })(1, 2, 3, 4); + equals(result, 4, 'works on an arguments object'); + result = _.map([[1,2,3],[1,2,3]], _.last); + equals(result.join(','), '3,3', 'works well with _.map'); + }); + + test("arrays: compact", function() { + equals(_.compact([0, 1, false, 2, false, 3]).length, 3, 'can trim out all falsy values'); + var result = (function(){ return _(arguments).compact().length; })(0, 1, false, 2, false, 3); + equals(result, 3, 'works on an arguments object'); + }); + + test("arrays: flatten", function() { + if (window.JSON) { + var list = [1, [2], [3, [[[4]]]]]; + equals(JSON.stringify(_.flatten(list)), '[1,2,3,4]', 'can flatten nested arrays'); + equals(JSON.stringify(_.flatten(list, true)), '[1,2,3,[[[4]]]]', 'can shallowly flatten nested arrays'); + var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]); + equals(JSON.stringify(result), '[1,2,3,4]', 'works on an arguments object'); + } + }); + + test("arrays: without", function() { + var list = [1, 2, 1, 0, 3, 1, 4]; + equals(_.without(list, 0, 1).join(', '), '2, 3, 4', 'can remove all instances of an object'); + var result = (function(){ return _.without(arguments, 0, 1); })(1, 2, 1, 0, 3, 1, 4); + equals(result.join(', '), '2, 3, 4', 'works on an arguments object'); + + var list = [{one : 1}, {two : 2}]; + ok(_.without(list, {one : 1}).length == 2, 'uses real object identity for comparisons.'); + ok(_.without(list, list[0]).length == 1, 'ditto.'); + }); + + test("arrays: uniq", function() { + var list = [1, 2, 1, 3, 1, 4]; + equals(_.uniq(list).join(', '), '1, 2, 3, 4', 'can find the unique values of an unsorted array'); + + var list = [1, 1, 1, 2, 2, 3]; + equals(_.uniq(list, true).join(', '), '1, 2, 3', 'can find the unique values of a sorted array faster'); + + var list = [{name:'moe'}, {name:'curly'}, {name:'larry'}, {name:'curly'}]; + var iterator = function(value) { return value.name; }; + equals(_.map(_.uniq(list, false, iterator), iterator).join(', '), 'moe, curly, larry', 'can find the unique values of an array using a custom iterator'); + + var iterator = function(value) { return value +1; }; + var list = [1, 2, 2, 3, 4, 4]; + equals(_.uniq(list, true, iterator).join(', '), '1, 2, 3, 4', 'iterator works with sorted array'); + + var result = (function(){ return _.uniq(arguments); })(1, 2, 1, 3, 1, 4); + equals(result.join(', '), '1, 2, 3, 4', 'works on an arguments object'); + }); + + test("arrays: intersection", function() { + var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho']; + equals(_.intersection(stooges, leaders).join(''), 'moe', 'can take the set intersection of two arrays'); + equals(_(stooges).intersection(leaders).join(''), 'moe', 'can perform an OO-style intersection'); + var result = (function(){ return _.intersection(arguments, leaders); })('moe', 'curly', 'larry'); + equals(result.join(''), 'moe', 'works on an arguments object'); + }); + + test("arrays: union", function() { + var result = _.union([1, 2, 3], [2, 30, 1], [1, 40]); + equals(result.join(' '), '1 2 3 30 40', 'takes the union of a list of arrays'); + + var result = _.union([1, 2, 3], [2, 30, 1], [1, 40, [1]]); + equals(result.join(' '), '1 2 3 30 40 1', 'takes the union of a list of nested arrays'); + }); + + test("arrays: difference", function() { + var result = _.difference([1, 2, 3], [2, 30, 40]); + equals(result.join(' '), '1 3', 'takes the difference of two arrays'); + + var result = _.difference([1, 2, 3, 4], [2, 30, 40], [1, 11, 111]); + equals(result.join(' '), '3 4', 'takes the difference of three arrays'); + }); + + test('arrays: zip', function() { + var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true]; + var stooges = _.zip(names, ages, leaders); + equals(String(stooges), 'moe,30,true,larry,40,,curly,50,', 'zipped together arrays of different lengths'); + }); + + test("arrays: indexOf", function() { + var numbers = [1, 2, 3]; + numbers.indexOf = null; + equals(_.indexOf(numbers, 2), 1, 'can compute indexOf, even without the native function'); + var result = (function(){ return _.indexOf(arguments, 2); })(1, 2, 3); + equals(result, 1, 'works on an arguments object'); + equals(_.indexOf(null, 2), -1, 'handles nulls properly'); + + var numbers = [10, 20, 30, 40, 50], num = 35; + var index = _.indexOf(numbers, num, true); + equals(index, -1, '35 is not in the list'); + + numbers = [10, 20, 30, 40, 50]; num = 40; + index = _.indexOf(numbers, num, true); + equals(index, 3, '40 is in the list'); + + numbers = [1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70]; num = 40; + index = _.indexOf(numbers, num, true); + equals(index, 1, '40 is in the list'); + }); + + test("arrays: lastIndexOf", function() { + var numbers = [1, 0, 1, 0, 0, 1, 0, 0, 0]; + numbers.lastIndexOf = null; + equals(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function'); + equals(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element'); + var result = (function(){ return _.lastIndexOf(arguments, 1); })(1, 0, 1, 0, 0, 1, 0, 0, 0); + equals(result, 5, 'works on an arguments object'); + equals(_.indexOf(null, 2), -1, 'handles nulls properly'); + }); + + test("arrays: range", function() { + equals(_.range(0).join(''), '', 'range with 0 as a first argument generates an empty array'); + equals(_.range(4).join(' '), '0 1 2 3', 'range with a single positive argument generates an array of elements 0,1,2,...,n-1'); + equals(_.range(5, 8).join(' '), '5 6 7', 'range with two arguments a & b, a<b generates an array of elements a,a+1,a+2,...,b-2,b-1'); + equals(_.range(8, 5).join(''), '', 'range with two arguments a & b, b<a generates an empty array'); + equals(_.range(3, 10, 3).join(' '), '3 6 9', 'range with three arguments a & b & c, c < b-a, a < b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) < c'); + equals(_.range(3, 10, 15).join(''), '3', 'range with three arguments a & b & c, c > b-a, a < b generates an array with a single element, equal to a'); + equals(_.range(12, 7, -2).join(' '), '12 10 8', 'range with three arguments a & b & c, a > b, c < 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b'); + equals(_.range(0, -10, -1).join(' '), '0 -1 -2 -3 -4 -5 -6 -7 -8 -9', 'final example in the Python docs'); + }); + +}); diff --git a/node_modules/underscore.string/test/test_underscore/chaining.js b/node_modules/underscore.string/test/test_underscore/chaining.js new file mode 100644 index 0000000..0e3d5f3 --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/chaining.js @@ -0,0 +1,59 @@ +$(document).ready(function() { + + module("Chaining"); + + test("chaining: map/flatten/reduce", function() { + var lyrics = [ + "I'm a lumberjack and I'm okay", + "I sleep all night and I work all day", + "He's a lumberjack and he's okay", + "He sleeps all night and he works all day" + ]; + var counts = _(lyrics).chain() + .map(function(line) { return line.split(''); }) + .flatten() + .reduce(function(hash, l) { + hash[l] = hash[l] || 0; + hash[l]++; + return hash; + }, {}).value(); + ok(counts['a'] == 16 && counts['e'] == 10, 'counted all the letters in the song'); + }); + + test("chaining: select/reject/sortBy", function() { + var numbers = [1,2,3,4,5,6,7,8,9,10]; + numbers = _(numbers).chain().select(function(n) { + return n % 2 == 0; + }).reject(function(n) { + return n % 4 == 0; + }).sortBy(function(n) { + return -n; + }).value(); + equals(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers"); + }); + + test("chaining: select/reject/sortBy in functional style", function() { + var numbers = [1,2,3,4,5,6,7,8,9,10]; + numbers = _.chain(numbers).select(function(n) { + return n % 2 == 0; + }).reject(function(n) { + return n % 4 == 0; + }).sortBy(function(n) { + return -n; + }).value(); + equals(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers"); + }); + + test("chaining: reverse/concat/unshift/pop/map", function() { + var numbers = [1,2,3,4,5]; + numbers = _(numbers).chain() + .reverse() + .concat([5, 5, 5]) + .unshift(17) + .pop() + .map(function(n){ return n * 2; }) + .value(); + equals(numbers.join(', '), "34, 10, 8, 6, 4, 2, 10, 10", 'can chain together array functions.'); + }); + +}); diff --git a/node_modules/underscore.string/test/test_underscore/collections.js b/node_modules/underscore.string/test/test_underscore/collections.js new file mode 100644 index 0000000..cff9763 --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/collections.js @@ -0,0 +1,270 @@ +$(document).ready(function() { + + module("Collections"); + + test("collections: each", function() { + _.each([1, 2, 3], function(num, i) { + equals(num, i + 1, 'each iterators provide value and iteration count'); + }); + + var answers = []; + _.each([1, 2, 3], function(num){ answers.push(num * this.multiplier);}, {multiplier : 5}); + equals(answers.join(', '), '5, 10, 15', 'context object property accessed'); + + answers = []; + _.forEach([1, 2, 3], function(num){ answers.push(num); }); + equals(answers.join(', '), '1, 2, 3', 'aliased as "forEach"'); + + answers = []; + var obj = {one : 1, two : 2, three : 3}; + obj.constructor.prototype.four = 4; + _.each(obj, function(value, key){ answers.push(key); }); + equals(answers.join(", "), 'one, two, three', 'iterating over objects works, and ignores the object prototype.'); + delete obj.constructor.prototype.four; + + answer = null; + _.each([1, 2, 3], function(num, index, arr){ if (_.include(arr, num)) answer = true; }); + ok(answer, 'can reference the original collection from inside the iterator'); + + answers = 0; + _.each(null, function(){ ++answers; }); + equals(answers, 0, 'handles a null properly'); + }); + + test('collections: map', function() { + var doubled = _.map([1, 2, 3], function(num){ return num * 2; }); + equals(doubled.join(', '), '2, 4, 6', 'doubled numbers'); + + doubled = _.collect([1, 2, 3], function(num){ return num * 2; }); + equals(doubled.join(', '), '2, 4, 6', 'aliased as "collect"'); + + var tripled = _.map([1, 2, 3], function(num){ return num * this.multiplier; }, {multiplier : 3}); + equals(tripled.join(', '), '3, 6, 9', 'tripled numbers with context'); + + var doubled = _([1, 2, 3]).map(function(num){ return num * 2; }); + equals(doubled.join(', '), '2, 4, 6', 'OO-style doubled numbers'); + + var ids = _.map($('div.underscore-test').children(), function(n){ return n.id; }); + ok(_.include(ids, 'qunit-header'), 'can use collection methods on NodeLists'); + + var ids = _.map(document.images, function(n){ return n.id; }); + ok(ids[0] == 'chart_image', 'can use collection methods on HTMLCollections'); + + var ifnull = _.map(null, function(){}); + ok(_.isArray(ifnull) && ifnull.length === 0, 'handles a null properly'); + + var length = _.map(Array(2), function(v) { return v; }).length; + equals(length, 2, "can preserve a sparse array's length"); + }); + + test('collections: reduce', function() { + var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }, 0); + equals(sum, 6, 'can sum up an array'); + + var context = {multiplier : 3}; + sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num * this.multiplier; }, 0, context); + equals(sum, 18, 'can reduce with a context object'); + + sum = _.inject([1, 2, 3], function(sum, num){ return sum + num; }, 0); + equals(sum, 6, 'aliased as "inject"'); + + sum = _([1, 2, 3]).reduce(function(sum, num){ return sum + num; }, 0); + equals(sum, 6, 'OO-style reduce'); + + var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }); + equals(sum, 6, 'default initial value'); + + var ifnull; + try { + _.reduce(null, function(){}); + } catch (ex) { + ifnull = ex; + } + ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly'); + + ok(_.reduce(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); + equals(_.reduce([], function(){}, undefined), undefined, 'undefined can be passed as a special case'); + raises(function() { _.reduce([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value'); + + var sparseArray = []; + sparseArray[0] = 20; + sparseArray[2] = -5; + equals(_.reduce(sparseArray, function(a, b){ return a - b; }), 25, 'initially-sparse arrays with no memo'); + }); + + test('collections: reduceRight', function() { + var list = _.reduceRight(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); + equals(list, 'bazbarfoo', 'can perform right folds'); + + var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); + equals(list, 'bazbarfoo', 'aliased as "foldr"'); + + var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }); + equals(list, 'bazbarfoo', 'default initial value'); + + var ifnull; + try { + _.reduceRight(null, function(){}); + } catch (ex) { + ifnull = ex; + } + ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly'); + + ok(_.reduceRight(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); + + equals(_.reduceRight([], function(){}, undefined), undefined, 'undefined can be passed as a special case'); + raises(function() { _.reduceRight([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value'); + + var sparseArray = []; + sparseArray[0] = 20; + sparseArray[2] = -5; + equals(_.reduceRight(sparseArray, function(a, b){ return a - b; }), -25, 'initially-sparse arrays with no memo'); + }); + + test('collections: detect', function() { + var result = _.detect([1, 2, 3], function(num){ return num * 2 == 4; }); + equals(result, 2, 'found the first "2" and broke the loop'); + }); + + test('collections: select', function() { + var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); + equals(evens.join(', '), '2, 4, 6', 'selected each even number'); + + evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); + equals(evens.join(', '), '2, 4, 6', 'aliased as "filter"'); + }); + + test('collections: reject', function() { + var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); + equals(odds.join(', '), '1, 3, 5', 'rejected each even number'); + }); + + test('collections: all', function() { + ok(_.all([], _.identity), 'the empty set'); + ok(_.all([true, true, true], _.identity), 'all true values'); + ok(!_.all([true, false, true], _.identity), 'one false value'); + ok(_.all([0, 10, 28], function(num){ return num % 2 == 0; }), 'even numbers'); + ok(!_.all([0, 11, 28], function(num){ return num % 2 == 0; }), 'an odd number'); + ok(_.every([true, true, true], _.identity), 'aliased as "every"'); + }); + + test('collections: any', function() { + var nativeSome = Array.prototype.some; + Array.prototype.some = null; + ok(!_.any([]), 'the empty set'); + ok(!_.any([false, false, false]), 'all false values'); + ok(_.any([false, false, true]), 'one true value'); + ok(_.any([null, 0, 'yes', false]), 'a string'); + ok(!_.any([null, 0, '', false]), 'falsy values'); + ok(!_.any([1, 11, 29], function(num){ return num % 2 == 0; }), 'all odd numbers'); + ok(_.any([1, 10, 29], function(num){ return num % 2 == 0; }), 'an even number'); + ok(_.some([false, false, true]), 'aliased as "some"'); + Array.prototype.some = nativeSome; + }); + + test('collections: include', function() { + ok(_.include([1,2,3], 2), 'two is in the array'); + ok(!_.include([1,3,9], 2), 'two is not in the array'); + ok(_.contains({moe:1, larry:3, curly:9}, 3) === true, '_.include on objects checks their values'); + ok(_([1,2,3]).include(2), 'OO-style include'); + }); + + test('collections: invoke', function() { + var list = [[5, 1, 7], [3, 2, 1]]; + var result = _.invoke(list, 'sort'); + equals(result[0].join(', '), '1, 5, 7', 'first array sorted'); + equals(result[1].join(', '), '1, 2, 3', 'second array sorted'); + }); + + test('collections: invoke w/ function reference', function() { + var list = [[5, 1, 7], [3, 2, 1]]; + var result = _.invoke(list, Array.prototype.sort); + equals(result[0].join(', '), '1, 5, 7', 'first array sorted'); + equals(result[1].join(', '), '1, 2, 3', 'second array sorted'); + }); + + // Relevant when using ClojureScript + test('collections: invoke when strings have a call method', function() { + String.prototype.call = function(){return 42;} + var list = [[5, 1, 7], [3, 2, 1]]; + var s = "foo"; + equals(s.call(), 42, "call function exists"); + var result = _.invoke(list, 'sort'); + equals(result[0].join(', '), '1, 5, 7', 'first array sorted'); + equals(result[1].join(', '), '1, 2, 3', 'second array sorted'); + delete String.prototype.call; + equals(s.call, undefined, "call function removed"); + }); + + test('collections: pluck', function() { + var people = [{name : 'moe', age : 30}, {name : 'curly', age : 50}]; + equals(_.pluck(people, 'name').join(', '), 'moe, curly', 'pulls names out of objects'); + }); + + test('collections: max', function() { + equals(3, _.max([1, 2, 3]), 'can perform a regular Math.max'); + + var neg = _.max([1, 2, 3], function(num){ return -num; }); + equals(neg, 1, 'can perform a computation-based max'); + + equals(-Infinity, _.max({}), 'Maximum value of an empty object'); + equals(-Infinity, _.max([]), 'Maximum value of an empty array'); + }); + + test('collections: min', function() { + equals(1, _.min([1, 2, 3]), 'can perform a regular Math.min'); + + var neg = _.min([1, 2, 3], function(num){ return -num; }); + equals(neg, 3, 'can perform a computation-based min'); + + equals(Infinity, _.min({}), 'Minimum value of an empty object'); + equals(Infinity, _.min([]), 'Minimum value of an empty array'); + }); + + test('collections: sortBy', function() { + var people = [{name : 'curly', age : 50}, {name : 'moe', age : 30}]; + people = _.sortBy(people, function(person){ return person.age; }); + equals(_.pluck(people, 'name').join(', '), 'moe, curly', 'stooges sorted by age'); + }); + + test('collections: groupBy', function() { + var parity = _.groupBy([1, 2, 3, 4, 5, 6], function(num){ return num % 2; }); + ok('0' in parity && '1' in parity, 'created a group for each value'); + equals(parity[0].join(', '), '2, 4, 6', 'put each even number in the right group'); + + var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]; + var grouped = _.groupBy(list, 'length'); + equals(grouped['3'].join(' '), 'one two six ten'); + equals(grouped['4'].join(' '), 'four five nine'); + equals(grouped['5'].join(' '), 'three seven eight'); + }); + + test('collections: sortedIndex', function() { + var numbers = [10, 20, 30, 40, 50], num = 35; + var index = _.sortedIndex(numbers, num); + equals(index, 3, '35 should be inserted at index 3'); + }); + + test('collections: shuffle', function() { + var numbers = _.range(10); + var shuffled = _.shuffle(numbers).sort(); + notStrictEqual(numbers, shuffled, 'original object is unmodified'); + equals(shuffled.join(','), numbers.join(','), 'contains the same members before and after shuffle'); + }); + + test('collections: toArray', function() { + ok(!_.isArray(arguments), 'arguments object is not an array'); + ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array'); + var a = [1,2,3]; + ok(_.toArray(a) !== a, 'array is cloned'); + equals(_.toArray(a).join(', '), '1, 2, 3', 'cloned array contains same elements'); + + var numbers = _.toArray({one : 1, two : 2, three : 3}); + equals(numbers.join(', '), '1, 2, 3', 'object flattened into array'); + }); + + test('collections: size', function() { + equals(_.size({one : 1, two : 2, three : 3}), 3, 'can compute the size of an object'); + }); + +}); diff --git a/node_modules/underscore.string/test/test_underscore/functions.js b/node_modules/underscore.string/test/test_underscore/functions.js new file mode 100644 index 0000000..78721af --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/functions.js @@ -0,0 +1,198 @@ +$(document).ready(function() { + + module("Functions"); + + test("functions: bind", function() { + var context = {name : 'moe'}; + var func = function(arg) { return "name: " + (this.name || arg); }; + var bound = _.bind(func, context); + equals(bound(), 'name: moe', 'can bind a function to a context'); + + bound = _(func).bind(context); + equals(bound(), 'name: moe', 'can do OO-style binding'); + + bound = _.bind(func, null, 'curly'); + equals(bound(), 'name: curly', 'can bind without specifying a context'); + + func = function(salutation, name) { return salutation + ': ' + name; }; + func = _.bind(func, this, 'hello'); + equals(func('moe'), 'hello: moe', 'the function was partially applied in advance'); + + var func = _.bind(func, this, 'curly'); + equals(func(), 'hello: curly', 'the function was completely applied in advance'); + + var func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; }; + func = _.bind(func, this, 'hello', 'moe', 'curly'); + equals(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments'); + + func = function(context, message) { equals(this, context, message); }; + _.bind(func, 0, 0, 'can bind a function to `0`')(); + _.bind(func, '', '', 'can bind a function to an empty string')(); + _.bind(func, false, false, 'can bind a function to `false`')(); + + // These tests are only meaningful when using a browser without a native bind function + // To test this with a modern browser, set underscore's nativeBind to undefined + var F = function () { return this; }; + var Boundf = _.bind(F, {hello: "moe curly"}); + equal(new Boundf().hello, undefined, "function should not be bound to the context, to comply with ECMAScript 5"); + equal(Boundf().hello, "moe curly", "When called without the new operator, it's OK to be bound to the context"); + }); + + test("functions: bindAll", function() { + var curly = {name : 'curly'}, moe = { + name : 'moe', + getName : function() { return 'name: ' + this.name; }, + sayHi : function() { return 'hi: ' + this.name; } + }; + curly.getName = moe.getName; + _.bindAll(moe, 'getName', 'sayHi'); + curly.sayHi = moe.sayHi; + equals(curly.getName(), 'name: curly', 'unbound function is bound to current object'); + equals(curly.sayHi(), 'hi: moe', 'bound function is still bound to original object'); + + curly = {name : 'curly'}; + moe = { + name : 'moe', + getName : function() { return 'name: ' + this.name; }, + sayHi : function() { return 'hi: ' + this.name; } + }; + _.bindAll(moe); + curly.sayHi = moe.sayHi; + equals(curly.sayHi(), 'hi: moe', 'calling bindAll with no arguments binds all functions to the object'); + }); + + test("functions: memoize", function() { + var fib = function(n) { + return n < 2 ? n : fib(n - 1) + fib(n - 2); + }; + var fastFib = _.memoize(fib); + equals(fib(10), 55, 'a memoized version of fibonacci produces identical results'); + equals(fastFib(10), 55, 'a memoized version of fibonacci produces identical results'); + + var o = function(str) { + return str; + }; + var fastO = _.memoize(o); + equals(o('toString'), 'toString', 'checks hasOwnProperty'); + equals(fastO('toString'), 'toString', 'checks hasOwnProperty'); + }); + + asyncTest("functions: delay", 2, function() { + var delayed = false; + _.delay(function(){ delayed = true; }, 100); + setTimeout(function(){ ok(!delayed, "didn't delay the function quite yet"); }, 50); + setTimeout(function(){ ok(delayed, 'delayed the function'); start(); }, 150); + }); + + asyncTest("functions: defer", 1, function() { + var deferred = false; + _.defer(function(bool){ deferred = bool; }, true); + _.delay(function(){ ok(deferred, "deferred the function"); start(); }, 50); + }); + + asyncTest("functions: throttle", 2, function() { + var counter = 0; + var incr = function(){ counter++; }; + var throttledIncr = _.throttle(incr, 100); + throttledIncr(); throttledIncr(); throttledIncr(); + setTimeout(throttledIncr, 70); + setTimeout(throttledIncr, 120); + setTimeout(throttledIncr, 140); + setTimeout(throttledIncr, 190); + setTimeout(throttledIncr, 220); + setTimeout(throttledIncr, 240); + _.delay(function(){ ok(counter == 1, "incr was called immediately"); }, 30); + _.delay(function(){ ok(counter == 4, "incr was throttled"); start(); }, 400); + }); + + asyncTest("functions: throttle arguments", 2, function() { + var value = 0; + var update = function(val){ value = val; }; + var throttledUpdate = _.throttle(update, 100); + throttledUpdate(1); throttledUpdate(2); throttledUpdate(3); + setTimeout(function(){ throttledUpdate(4); }, 120); + setTimeout(function(){ throttledUpdate(5); }, 140); + setTimeout(function(){ throttledUpdate(6); }, 250); + _.delay(function(){ equals(value, 1, "updated to latest value"); }, 40); + _.delay(function(){ equals(value, 6, "updated to latest value"); start(); }, 400); + }); + + asyncTest("functions: throttle once", 1, function() { + var counter = 0; + var incr = function(){ counter++; }; + var throttledIncr = _.throttle(incr, 100); + throttledIncr(); + _.delay(function(){ ok(counter == 1, "incr was called once"); start(); }, 220); + }); + + asyncTest("functions: throttle twice", 1, function() { + var counter = 0; + var incr = function(){ counter++; }; + var throttledIncr = _.throttle(incr, 100); + throttledIncr(); throttledIncr(); + _.delay(function(){ ok(counter == 2, "incr was called twice"); start(); }, 220); + }); + + asyncTest("functions: debounce", 1, function() { + var counter = 0; + var incr = function(){ counter++; }; + var debouncedIncr = _.debounce(incr, 50); + debouncedIncr(); debouncedIncr(); debouncedIncr(); + setTimeout(debouncedIncr, 30); + setTimeout(debouncedIncr, 60); + setTimeout(debouncedIncr, 90); + setTimeout(debouncedIncr, 120); + setTimeout(debouncedIncr, 150); + _.delay(function(){ ok(counter == 1, "incr was debounced"); start(); }, 220); + }); + + test("functions: once", function() { + var num = 0; + var increment = _.once(function(){ num++; }); + increment(); + increment(); + equals(num, 1); + }); + + test("functions: wrap", function() { + var greet = function(name){ return "hi: " + name; }; + var backwards = _.wrap(greet, function(func, name){ return func(name) + ' ' + name.split('').reverse().join(''); }); + equals(backwards('moe'), 'hi: moe eom', 'wrapped the saluation function'); + + var inner = function(){ return "Hello "; }; + var obj = {name : "Moe"}; + obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; }); + equals(obj.hi(), "Hello Moe"); + + var noop = function(){}; + var wrapped = _.wrap(noop, function(fn){ return Array.prototype.slice.call(arguments, 0); }); + var ret = wrapped(['whats', 'your'], 'vector', 'victor'); + same(ret, [noop, ['whats', 'your'], 'vector', 'victor']); + }); + + test("functions: compose", function() { + var greet = function(name){ return "hi: " + name; }; + var exclaim = function(sentence){ return sentence + '!'; }; + var composed = _.compose(exclaim, greet); + equals(composed('moe'), 'hi: moe!', 'can compose a function that takes another'); + + composed = _.compose(greet, exclaim); + equals(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative'); + }); + + test("functions: after", function() { + var testAfter = function(afterAmount, timesCalled) { + var afterCalled = 0; + var after = _.after(afterAmount, function() { + afterCalled++; + }); + while (timesCalled--) after(); + return afterCalled; + }; + + equals(testAfter(5, 5), 1, "after(N) should fire after being called N times"); + equals(testAfter(5, 4), 0, "after(N) should not fire unless called N times"); + equals(testAfter(0, 0), 1, "after(0) should fire immediately"); + }); + +}); diff --git a/node_modules/underscore.string/test/test_underscore/objects.js b/node_modules/underscore.string/test/test_underscore/objects.js new file mode 100644 index 0000000..0105d60 --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/objects.js @@ -0,0 +1,535 @@ +$(document).ready(function() { + + module("Objects"); + + test("objects: keys", function() { + var exception = /object/; + equals(_.keys({one : 1, two : 2}).join(', '), 'one, two', 'can extract the keys from an object'); + // the test above is not safe because it relies on for-in enumeration order + var a = []; a[1] = 0; + equals(_.keys(a).join(', '), '1', 'is not fooled by sparse arrays; see issue #95'); + raises(function() { _.keys(null); }, exception, 'throws an error for `null` values'); + raises(function() { _.keys(void 0); }, exception, 'throws an error for `undefined` values'); + raises(function() { _.keys(1); }, exception, 'throws an error for number primitives'); + raises(function() { _.keys('a'); }, exception, 'throws an error for string primitives'); + raises(function() { _.keys(true); }, exception, 'throws an error for boolean primitives'); + }); + + test("objects: values", function() { + equals(_.values({one : 1, two : 2}).join(', '), '1, 2', 'can extract the values from an object'); + }); + + test("objects: functions", function() { + var obj = {a : 'dash', b : _.map, c : (/yo/), d : _.reduce}; + ok(_.isEqual(['b', 'd'], _.functions(obj)), 'can grab the function names of any passed-in object'); + + var Animal = function(){}; + Animal.prototype.run = function(){}; + equals(_.functions(new Animal).join(''), 'run', 'also looks up functions on the prototype'); + }); + + test("objects: extend", function() { + var result; + equals(_.extend({}, {a:'b'}).a, 'b', 'can extend an object with the attributes of another'); + equals(_.extend({a:'x'}, {a:'b'}).a, 'b', 'properties in source override destination'); + equals(_.extend({x:'x'}, {a:'b'}).x, 'x', 'properties not in source dont get overriden'); + result = _.extend({x:'x'}, {a:'a'}, {b:'b'}); + ok(_.isEqual(result, {x:'x', a:'a', b:'b'}), 'can extend from multiple source objects'); + result = _.extend({x:'x'}, {a:'a', x:2}, {a:'b'}); + ok(_.isEqual(result, {x:2, a:'b'}), 'extending from multiple source objects last property trumps'); + result = _.extend({}, {a: void 0, b: null}); + equals(_.keys(result).join(''), 'ab', 'extend does not copy undefined values'); + }); + + test("objects: defaults", function() { + var result; + var options = {zero: 0, one: 1, empty: "", nan: NaN, string: "string"}; + + _.defaults(options, {zero: 1, one: 10, twenty: 20}); + equals(options.zero, 0, 'value exists'); + equals(options.one, 1, 'value exists'); + equals(options.twenty, 20, 'default applied'); + + _.defaults(options, {empty: "full"}, {nan: "nan"}, {word: "word"}, {word: "dog"}); + equals(options.empty, "", 'value exists'); + ok(_.isNaN(options.nan), "NaN isn't overridden"); + equals(options.word, "word", 'new value is added, first one wins'); + }); + + test("objects: clone", function() { + var moe = {name : 'moe', lucky : [13, 27, 34]}; + var clone = _.clone(moe); + equals(clone.name, 'moe', 'the clone as the attributes of the original'); + + clone.name = 'curly'; + ok(clone.name == 'curly' && moe.name == 'moe', 'clones can change shallow attributes without affecting the original'); + + clone.lucky.push(101); + equals(_.last(moe.lucky), 101, 'changes to deep attributes are shared with the original'); + + equals(_.clone(undefined), void 0, 'non objects should not be changed by clone'); + equals(_.clone(1), 1, 'non objects should not be changed by clone'); + equals(_.clone(null), null, 'non objects should not be changed by clone'); + }); + + test("objects: isEqual", function() { + function First() { + this.value = 1; + } + First.prototype.value = 1; + function Second() { + this.value = 1; + } + Second.prototype.value = 2; + + // Basic equality and identity comparisons. + ok(_.isEqual(null, null), "`null` is equal to `null`"); + ok(_.isEqual(), "`undefined` is equal to `undefined`"); + + ok(!_.isEqual(0, -0), "`0` is not equal to `-0`"); + ok(!_.isEqual(-0, 0), "Commutative equality is implemented for `0` and `-0`"); + ok(!_.isEqual(null, undefined), "`null` is not equal to `undefined`"); + ok(!_.isEqual(undefined, null), "Commutative equality is implemented for `null` and `undefined`"); + + // String object and primitive comparisons. + ok(_.isEqual("Curly", "Curly"), "Identical string primitives are equal"); + ok(_.isEqual(new String("Curly"), new String("Curly")), "String objects with identical primitive values are equal"); + ok(_.isEqual(new String("Curly"), "Curly"), "String primitives and their corresponding object wrappers are equal"); + ok(_.isEqual("Curly", new String("Curly")), "Commutative equality is implemented for string objects and primitives"); + + ok(!_.isEqual("Curly", "Larry"), "String primitives with different values are not equal"); + ok(!_.isEqual(new String("Curly"), new String("Larry")), "String objects with different primitive values are not equal"); + ok(!_.isEqual(new String("Curly"), {toString: function(){ return "Curly"; }}), "String objects and objects with a custom `toString` method are not equal"); + + // Number object and primitive comparisons. + ok(_.isEqual(75, 75), "Identical number primitives are equal"); + ok(_.isEqual(new Number(75), new Number(75)), "Number objects with identical primitive values are equal"); + ok(_.isEqual(75, new Number(75)), "Number primitives and their corresponding object wrappers are equal"); + ok(_.isEqual(new Number(75), 75), "Commutative equality is implemented for number objects and primitives"); + ok(!_.isEqual(new Number(0), -0), "`new Number(0)` and `-0` are not equal"); + ok(!_.isEqual(0, new Number(-0)), "Commutative equality is implemented for `new Number(0)` and `-0`"); + + ok(!_.isEqual(new Number(75), new Number(63)), "Number objects with different primitive values are not equal"); + ok(!_.isEqual(new Number(63), {valueOf: function(){ return 63; }}), "Number objects and objects with a `valueOf` method are not equal"); + + // Comparisons involving `NaN`. + ok(_.isEqual(NaN, NaN), "`NaN` is equal to `NaN`"); + ok(!_.isEqual(61, NaN), "A number primitive is not equal to `NaN`"); + ok(!_.isEqual(new Number(79), NaN), "A number object is not equal to `NaN`"); + ok(!_.isEqual(Infinity, NaN), "`Infinity` is not equal to `NaN`"); + + // Boolean object and primitive comparisons. + ok(_.isEqual(true, true), "Identical boolean primitives are equal"); + ok(_.isEqual(new Boolean, new Boolean), "Boolean objects with identical primitive values are equal"); + ok(_.isEqual(true, new Boolean(true)), "Boolean primitives and their corresponding object wrappers are equal"); + ok(_.isEqual(new Boolean(true), true), "Commutative equality is implemented for booleans"); + ok(!_.isEqual(new Boolean(true), new Boolean), "Boolean objects with different primitive values are not equal"); + + // Common type coercions. + ok(!_.isEqual(true, new Boolean(false)), "Boolean objects are not equal to the boolean primitive `true`"); + ok(!_.isEqual("75", 75), "String and number primitives with like values are not equal"); + ok(!_.isEqual(new Number(63), new String(63)), "String and number objects with like values are not equal"); + ok(!_.isEqual(75, "75"), "Commutative equality is implemented for like string and number values"); + ok(!_.isEqual(0, ""), "Number and string primitives with like values are not equal"); + ok(!_.isEqual(1, true), "Number and boolean primitives with like values are not equal"); + ok(!_.isEqual(new Boolean(false), new Number(0)), "Boolean and number objects with like values are not equal"); + ok(!_.isEqual(false, new String("")), "Boolean primitives and string objects with like values are not equal"); + ok(!_.isEqual(12564504e5, new Date(2009, 9, 25)), "Dates and their corresponding numeric primitive values are not equal"); + + // Dates. + ok(_.isEqual(new Date(2009, 9, 25), new Date(2009, 9, 25)), "Date objects referencing identical times are equal"); + ok(!_.isEqual(new Date(2009, 9, 25), new Date(2009, 11, 13)), "Date objects referencing different times are not equal"); + ok(!_.isEqual(new Date(2009, 11, 13), { + getTime: function(){ + return 12606876e5; + } + }), "Date objects and objects with a `getTime` method are not equal"); + ok(!_.isEqual(new Date("Curly"), new Date("Curly")), "Invalid dates are not equal"); + + // Functions. + ok(!_.isEqual(First, Second), "Different functions with identical bodies and source code representations are not equal"); + + // RegExps. + ok(_.isEqual(/(?:)/gim, /(?:)/gim), "RegExps with equivalent patterns and flags are equal"); + ok(!_.isEqual(/(?:)/g, /(?:)/gi), "RegExps with equivalent patterns and different flags are not equal"); + ok(!_.isEqual(/Moe/gim, /Curly/gim), "RegExps with different patterns and equivalent flags are not equal"); + ok(!_.isEqual(/(?:)/gi, /(?:)/g), "Commutative equality is implemented for RegExps"); + ok(!_.isEqual(/Curly/g, {source: "Larry", global: true, ignoreCase: false, multiline: false}), "RegExps and RegExp-like objects are not equal"); + + // Empty arrays, array-like objects, and object literals. + ok(_.isEqual({}, {}), "Empty object literals are equal"); + ok(_.isEqual([], []), "Empty array literals are equal"); + ok(_.isEqual([{}], [{}]), "Empty nested arrays and objects are equal"); + ok(!_.isEqual({length: 0}, []), "Array-like objects and arrays are not equal."); + ok(!_.isEqual([], {length: 0}), "Commutative equality is implemented for array-like objects"); + + ok(!_.isEqual({}, []), "Object literals and array literals are not equal"); + ok(!_.isEqual([], {}), "Commutative equality is implemented for objects and arrays"); + + // Arrays with primitive and object values. + ok(_.isEqual([1, "Larry", true], [1, "Larry", true]), "Arrays containing identical primitives are equal"); + ok(_.isEqual([/Moe/g, new Date(2009, 9, 25)], [/Moe/g, new Date(2009, 9, 25)]), "Arrays containing equivalent elements are equal"); + + // Multi-dimensional arrays. + var a = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; + var b = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; + ok(_.isEqual(a, b), "Arrays containing nested arrays and objects are recursively compared"); + + // Overwrite the methods defined in ES 5.1 section 15.4.4. + a.forEach = a.map = a.filter = a.every = a.indexOf = a.lastIndexOf = a.some = a.reduce = a.reduceRight = null; + b.join = b.pop = b.reverse = b.shift = b.slice = b.splice = b.concat = b.sort = b.unshift = null; + + // Array elements and properties. + ok(_.isEqual(a, b), "Arrays containing equivalent elements and different non-numeric properties are equal"); + a.push("White Rocks"); + ok(!_.isEqual(a, b), "Arrays of different lengths are not equal"); + a.push("East Boulder"); + b.push("Gunbarrel Ranch", "Teller Farm"); + ok(!_.isEqual(a, b), "Arrays of identical lengths containing different elements are not equal"); + + // Sparse arrays. + ok(_.isEqual(Array(3), Array(3)), "Sparse arrays of identical lengths are equal"); + ok(!_.isEqual(Array(3), Array(6)), "Sparse arrays of different lengths are not equal when both are empty"); + + // According to the Microsoft deviations spec, section 2.1.26, JScript 5.x treats `undefined` + // elements in arrays as elisions. Thus, sparse arrays and dense arrays containing `undefined` + // values are equivalent. + if (0 in [undefined]) { + ok(!_.isEqual(Array(3), [undefined, undefined, undefined]), "Sparse and dense arrays are not equal"); + ok(!_.isEqual([undefined, undefined, undefined], Array(3)), "Commutative equality is implemented for sparse and dense arrays"); + } + + // Simple objects. + ok(_.isEqual({a: "Curly", b: 1, c: true}, {a: "Curly", b: 1, c: true}), "Objects containing identical primitives are equal"); + ok(_.isEqual({a: /Curly/g, b: new Date(2009, 11, 13)}, {a: /Curly/g, b: new Date(2009, 11, 13)}), "Objects containing equivalent members are equal"); + ok(!_.isEqual({a: 63, b: 75}, {a: 61, b: 55}), "Objects of identical sizes with different values are not equal"); + ok(!_.isEqual({a: 63, b: 75}, {a: 61, c: 55}), "Objects of identical sizes with different property names are not equal"); + ok(!_.isEqual({a: 1, b: 2}, {a: 1}), "Objects of different sizes are not equal"); + ok(!_.isEqual({a: 1}, {a: 1, b: 2}), "Commutative equality is implemented for objects"); + ok(!_.isEqual({x: 1, y: undefined}, {x: 1, z: 2}), "Objects with identical keys and different values are not equivalent"); + + // `A` contains nested objects and arrays. + a = { + name: new String("Moe Howard"), + age: new Number(77), + stooge: true, + hobbies: ["acting"], + film: { + name: "Sing a Song of Six Pants", + release: new Date(1947, 9, 30), + stars: [new String("Larry Fine"), "Shemp Howard"], + minutes: new Number(16), + seconds: 54 + } + }; + + // `B` contains equivalent nested objects and arrays. + b = { + name: new String("Moe Howard"), + age: new Number(77), + stooge: true, + hobbies: ["acting"], + film: { + name: "Sing a Song of Six Pants", + release: new Date(1947, 9, 30), + stars: [new String("Larry Fine"), "Shemp Howard"], + minutes: new Number(16), + seconds: 54 + } + }; + ok(_.isEqual(a, b), "Objects with nested equivalent members are recursively compared"); + + // Instances. + ok(_.isEqual(new First, new First), "Object instances are equal"); + ok(!_.isEqual(new First, new Second), "Objects with different constructors and identical own properties are not equal"); + ok(!_.isEqual({value: 1}, new First), "Object instances and objects sharing equivalent properties are not equal"); + ok(!_.isEqual({value: 2}, new Second), "The prototype chain of objects should not be examined"); + + // Circular Arrays. + (a = []).push(a); + (b = []).push(b); + ok(_.isEqual(a, b), "Arrays containing circular references are equal"); + a.push(new String("Larry")); + b.push(new String("Larry")); + ok(_.isEqual(a, b), "Arrays containing circular references and equivalent properties are equal"); + a.push("Shemp"); + b.push("Curly"); + ok(!_.isEqual(a, b), "Arrays containing circular references and different properties are not equal"); + + // Circular Objects. + a = {abc: null}; + b = {abc: null}; + a.abc = a; + b.abc = b; + ok(_.isEqual(a, b), "Objects containing circular references are equal"); + a.def = 75; + b.def = 75; + ok(_.isEqual(a, b), "Objects containing circular references and equivalent properties are equal"); + a.def = new Number(75); + b.def = new Number(63); + ok(!_.isEqual(a, b), "Objects containing circular references and different properties are not equal"); + + // Cyclic Structures. + a = [{abc: null}]; + b = [{abc: null}]; + (a[0].abc = a).push(a); + (b[0].abc = b).push(b); + ok(_.isEqual(a, b), "Cyclic structures are equal"); + a[0].def = "Larry"; + b[0].def = "Larry"; + ok(_.isEqual(a, b), "Cyclic structures containing equivalent properties are equal"); + a[0].def = new String("Larry"); + b[0].def = new String("Curly"); + ok(!_.isEqual(a, b), "Cyclic structures containing different properties are not equal"); + + // Complex Circular References. + a = {foo: {b: {foo: {c: {foo: null}}}}}; + b = {foo: {b: {foo: {c: {foo: null}}}}}; + a.foo.b.foo.c.foo = a; + b.foo.b.foo.c.foo = b; + ok(_.isEqual(a, b), "Cyclic structures with nested and identically-named properties are equal"); + + // Chaining. + ok(!_.isEqual(_({x: 1, y: undefined}).chain(), _({x: 1, z: 2}).chain()), 'Chained objects containing different values are not equal'); + equals(_({x: 1, y: 2}).chain().isEqual(_({x: 1, y: 2}).chain()).value(), true, '`isEqual` can be chained'); + + // Custom `isEqual` methods. + var isEqualObj = {isEqual: function (o) { return o.isEqual == this.isEqual; }, unique: {}}; + var isEqualObjClone = {isEqual: isEqualObj.isEqual, unique: {}}; + + ok(_.isEqual(isEqualObj, isEqualObjClone), 'Both objects implement identical `isEqual` methods'); + ok(_.isEqual(isEqualObjClone, isEqualObj), 'Commutative equality is implemented for objects with custom `isEqual` methods'); + ok(!_.isEqual(isEqualObj, {}), 'Objects that do not implement equivalent `isEqual` methods are not equal'); + ok(!_.isEqual({}, isEqualObj), 'Commutative equality is implemented for objects with different `isEqual` methods'); + + // Custom `isEqual` methods - comparing different types + LocalizedString = (function() { + function LocalizedString(id) { this.id = id; this.string = (this.id===10)? 'Bonjour': ''; } + LocalizedString.prototype.isEqual = function(that) { + if (_.isString(that)) return this.string == that; + else if (that instanceof LocalizedString) return this.id == that.id; + return false; + }; + return LocalizedString; + })(); + var localized_string1 = new LocalizedString(10), localized_string2 = new LocalizedString(10), localized_string3 = new LocalizedString(11); + ok(_.isEqual(localized_string1, localized_string2), 'comparing same typed instances with same ids'); + ok(!_.isEqual(localized_string1, localized_string3), 'comparing same typed instances with different ids'); + ok(_.isEqual(localized_string1, 'Bonjour'), 'comparing different typed instances with same values'); + ok(_.isEqual('Bonjour', localized_string1), 'comparing different typed instances with same values'); + ok(!_.isEqual('Bonjour', localized_string3), 'comparing two localized strings with different ids'); + ok(!_.isEqual(localized_string1, 'Au revoir'), 'comparing different typed instances with different values'); + ok(!_.isEqual('Au revoir', localized_string1), 'comparing different typed instances with different values'); + + // Custom `isEqual` methods - comparing with serialized data + Date.prototype.toJSON = function() { + return { + _type:'Date', + year:this.getUTCFullYear(), + month:this.getUTCMonth(), + day:this.getUTCDate(), + hours:this.getUTCHours(), + minutes:this.getUTCMinutes(), + seconds:this.getUTCSeconds() + }; + }; + Date.prototype.isEqual = function(that) { + var this_date_components = this.toJSON(); + var that_date_components = (that instanceof Date) ? that.toJSON() : that; + delete this_date_components['_type']; delete that_date_components['_type'] + return _.isEqual(this_date_components, that_date_components); + }; + + var date = new Date(); + var date_json = { + _type:'Date', + year:date.getUTCFullYear(), + month:date.getUTCMonth(), + day:date.getUTCDate(), + hours:date.getUTCHours(), + minutes:date.getUTCMinutes(), + seconds:date.getUTCSeconds() + }; + + ok(_.isEqual(date_json, date), 'serialized date matches date'); + ok(_.isEqual(date, date_json), 'date matches serialized date'); + }); + + test("objects: isEmpty", function() { + ok(!_([1]).isEmpty(), '[1] is not empty'); + ok(_.isEmpty([]), '[] is empty'); + ok(!_.isEmpty({one : 1}), '{one : 1} is not empty'); + ok(_.isEmpty({}), '{} is empty'); + ok(_.isEmpty(new RegExp('')), 'objects with prototype properties are empty'); + ok(_.isEmpty(null), 'null is empty'); + ok(_.isEmpty(), 'undefined is empty'); + ok(_.isEmpty(''), 'the empty string is empty'); + ok(!_.isEmpty('moe'), 'but other strings are not'); + + var obj = {one : 1}; + delete obj.one; + ok(_.isEmpty(obj), 'deleting all the keys from an object empties it'); + }); + + // Setup remote variables for iFrame tests. + var iframe = document.createElement('iframe'); + jQuery(iframe).appendTo(document.body); + var iDoc = iframe.contentDocument || iframe.contentWindow.document; + iDoc.write( + "" + ); + iDoc.close(); + + test("objects: isElement", function() { + ok(!_.isElement('div'), 'strings are not dom elements'); + ok(_.isElement($('html')[0]), 'the html tag is a DOM element'); + ok(_.isElement(iElement), 'even from another frame'); + }); + + test("objects: isArguments", function() { + var args = (function(){ return arguments; })(1, 2, 3); + ok(!_.isArguments('string'), 'a string is not an arguments object'); + ok(!_.isArguments(_.isArguments), 'a function is not an arguments object'); + ok(_.isArguments(args), 'but the arguments object is an arguments object'); + ok(!_.isArguments(_.toArray(args)), 'but not when it\'s converted into an array'); + ok(!_.isArguments([1,2,3]), 'and not vanilla arrays.'); + ok(_.isArguments(iArguments), 'even from another frame'); + }); + + test("objects: isObject", function() { + ok(_.isObject(arguments), 'the arguments object is object'); + ok(_.isObject([1, 2, 3]), 'and arrays'); + ok(_.isObject($('html')[0]), 'and DOM element'); + ok(_.isObject(iElement), 'even from another frame'); + ok(_.isObject(function () {}), 'and functions'); + ok(_.isObject(iFunction), 'even from another frame'); + ok(!_.isObject(null), 'but not null'); + ok(!_.isObject(undefined), 'and not undefined'); + ok(!_.isObject('string'), 'and not string'); + ok(!_.isObject(12), 'and not number'); + ok(!_.isObject(true), 'and not boolean'); + ok(_.isObject(new String('string')), 'but new String()'); + }); + + test("objects: isArray", function() { + ok(!_.isArray(arguments), 'the arguments object is not an array'); + ok(_.isArray([1, 2, 3]), 'but arrays are'); + ok(_.isArray(iArray), 'even from another frame'); + }); + + test("objects: isString", function() { + ok(!_.isString(document.body), 'the document body is not a string'); + ok(_.isString([1, 2, 3].join(', ')), 'but strings are'); + ok(_.isString(iString), 'even from another frame'); + }); + + test("objects: isNumber", function() { + ok(!_.isNumber('string'), 'a string is not a number'); + ok(!_.isNumber(arguments), 'the arguments object is not a number'); + ok(!_.isNumber(undefined), 'undefined is not a number'); + ok(_.isNumber(3 * 4 - 7 / 10), 'but numbers are'); + ok(_.isNumber(NaN), 'NaN *is* a number'); + ok(_.isNumber(Infinity), 'Infinity is a number'); + ok(_.isNumber(iNumber), 'even from another frame'); + ok(!_.isNumber('1'), 'numeric strings are not numbers'); + }); + + test("objects: isBoolean", function() { + ok(!_.isBoolean(2), 'a number is not a boolean'); + ok(!_.isBoolean("string"), 'a string is not a boolean'); + ok(!_.isBoolean("false"), 'the string "false" is not a boolean'); + ok(!_.isBoolean("true"), 'the string "true" is not a boolean'); + ok(!_.isBoolean(arguments), 'the arguments object is not a boolean'); + ok(!_.isBoolean(undefined), 'undefined is not a boolean'); + ok(!_.isBoolean(NaN), 'NaN is not a boolean'); + ok(!_.isBoolean(null), 'null is not a boolean'); + ok(_.isBoolean(true), 'but true is'); + ok(_.isBoolean(false), 'and so is false'); + ok(_.isBoolean(iBoolean), 'even from another frame'); + }); + + test("objects: isFunction", function() { + ok(!_.isFunction([1, 2, 3]), 'arrays are not functions'); + ok(!_.isFunction('moe'), 'strings are not functions'); + ok(_.isFunction(_.isFunction), 'but functions are'); + ok(_.isFunction(iFunction), 'even from another frame'); + }); + + test("objects: isDate", function() { + ok(!_.isDate(100), 'numbers are not dates'); + ok(!_.isDate({}), 'objects are not dates'); + ok(_.isDate(new Date()), 'but dates are'); + ok(_.isDate(iDate), 'even from another frame'); + }); + + test("objects: isRegExp", function() { + ok(!_.isRegExp(_.identity), 'functions are not RegExps'); + ok(_.isRegExp(/identity/), 'but RegExps are'); + ok(_.isRegExp(iRegExp), 'even from another frame'); + }); + + test("objects: isNaN", function() { + ok(!_.isNaN(undefined), 'undefined is not NaN'); + ok(!_.isNaN(null), 'null is not NaN'); + ok(!_.isNaN(0), '0 is not NaN'); + ok(_.isNaN(NaN), 'but NaN is'); + ok(_.isNaN(iNaN), 'even from another frame'); + }); + + test("objects: isNull", function() { + ok(!_.isNull(undefined), 'undefined is not null'); + ok(!_.isNull(NaN), 'NaN is not null'); + ok(_.isNull(null), 'but null is'); + ok(_.isNull(iNull), 'even from another frame'); + }); + + test("objects: isUndefined", function() { + ok(!_.isUndefined(1), 'numbers are defined'); + ok(!_.isUndefined(null), 'null is defined'); + ok(!_.isUndefined(false), 'false is defined'); + ok(!_.isUndefined(NaN), 'NaN is defined'); + ok(_.isUndefined(), 'nothing is undefined'); + ok(_.isUndefined(undefined), 'undefined is undefined'); + ok(_.isUndefined(iUndefined), 'even from another frame'); + }); + + if (window.ActiveXObject) { + test("objects: IE host objects", function() { + var xml = new ActiveXObject("Msxml2.DOMDocument.3.0"); + ok(!_.isNumber(xml)); + ok(!_.isBoolean(xml)); + ok(!_.isNaN(xml)); + ok(!_.isFunction(xml)); + ok(!_.isNull(xml)); + ok(!_.isUndefined(xml)); + }); + } + + test("objects: tap", function() { + var intercepted = null; + var interceptor = function(obj) { intercepted = obj; }; + var returned = _.tap(1, interceptor); + equals(intercepted, 1, "passes tapped object to interceptor"); + equals(returned, 1, "returns tapped object"); + + returned = _([1,2,3]).chain(). + map(function(n){ return n * 2; }). + max(). + tap(interceptor). + value(); + ok(returned == 6 && intercepted == 6, 'can use tapped objects in a chain'); + }); +}); diff --git a/node_modules/underscore.string/test/test_underscore/speed.js b/node_modules/underscore.string/test/test_underscore/speed.js new file mode 100644 index 0000000..86663a2 --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/speed.js @@ -0,0 +1,70 @@ +(function() { + + var numbers = []; + for (var i=0; i<1000; i++) numbers.push(i); + var objects = _.map(numbers, function(n){ return {num : n}; }); + var randomized = _.sortBy(numbers, function(){ return Math.random(); }); + + JSLitmus.test('_.each()', function() { + var timesTwo = []; + _.each(numbers, function(num){ timesTwo.push(num * 2); }); + return timesTwo; + }); + + JSLitmus.test('_(list).each()', function() { + var timesTwo = []; + _(numbers).each(function(num){ timesTwo.push(num * 2); }); + return timesTwo; + }); + + JSLitmus.test('jQuery.each()', function() { + var timesTwo = []; + jQuery.each(numbers, function(){ timesTwo.push(this * 2); }); + return timesTwo; + }); + + JSLitmus.test('_.map()', function() { + return _.map(objects, function(obj){ return obj.num; }); + }); + + JSLitmus.test('jQuery.map()', function() { + return jQuery.map(objects, function(obj){ return obj.num; }); + }); + + JSLitmus.test('_.pluck()', function() { + return _.pluck(objects, 'num'); + }); + + JSLitmus.test('_.uniq()', function() { + return _.uniq(randomized); + }); + + JSLitmus.test('_.uniq() (sorted)', function() { + return _.uniq(numbers, true); + }); + + JSLitmus.test('_.sortBy()', function() { + return _.sortBy(numbers, function(num){ return -num; }); + }); + + JSLitmus.test('_.isEqual()', function() { + return _.isEqual(numbers, randomized); + }); + + JSLitmus.test('_.keys()', function() { + return _.keys(objects); + }); + + JSLitmus.test('_.values()', function() { + return _.values(objects); + }); + + JSLitmus.test('_.intersect()', function() { + return _.intersect(numbers, randomized); + }); + + JSLitmus.test('_.range()', function() { + return _.range(1000); + }); + +})(); \ No newline at end of file diff --git a/node_modules/underscore.string/test/test_underscore/temp.js b/node_modules/underscore.string/test/test_underscore/temp.js new file mode 100644 index 0000000..68c39dc --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/temp.js @@ -0,0 +1,27 @@ +(function() { + + var func = function(){}; + var date = new Date(); + var str = "a string"; + var numbers = []; + for (var i=0; i<1000; i++) numbers.push(i); + var objects = _.map(numbers, function(n){ return {num : n}; }); + var randomized = _.sortBy(numbers, function(){ return Math.random(); }); + + JSLitmus.test('_.isNumber', function() { + return _.isNumber(1000) + }); + + JSLitmus.test('_.newIsNumber', function() { + return _.newIsNumber(1000) + }); + + JSLitmus.test('_.isNumber(NaN)', function() { + return _.isNumber(NaN) + }); + + JSLitmus.test('_.newIsNumber(NaN)', function() { + return _.newIsNumber(NaN) + }); + +})(); \ No newline at end of file diff --git a/node_modules/underscore.string/test/test_underscore/temp_tests.html b/node_modules/underscore.string/test/test_underscore/temp_tests.html new file mode 100644 index 0000000..bd34f9d --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/temp_tests.html @@ -0,0 +1,19 @@ + + + + Underscore Temporary Tests + + + + + + + +

                Underscore Temporary Tests

                +

                + A page for temporary speed tests, used for developing faster implementations + of existing Underscore methods. +

                +
                + + diff --git a/node_modules/underscore.string/test/test_underscore/test.html b/node_modules/underscore.string/test/test_underscore/test.html new file mode 100644 index 0000000..77f2f3a --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/test.html @@ -0,0 +1,43 @@ + + + + Underscore Test Suite + + + + + + + + + + + + + + + +
                +

                Underscore Test Suite

                +

                +

                +
                  +
                  +

                  Underscore Speed Suite

                  +

                  + A representative sample of the functions are benchmarked here, to provide + a sense of how fast they might run in different browsers. + Each iteration runs on an array of 1000 elements.

                  + For example, the 'intersect' test measures the number of times you can + find the intersection of two thousand-element arrays in one second. +

                  +
                  + + +
                  + + diff --git a/node_modules/underscore.string/test/test_underscore/utility.js b/node_modules/underscore.string/test/test_underscore/utility.js new file mode 100644 index 0000000..7bc5cb4 --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/utility.js @@ -0,0 +1,155 @@ +$(document).ready(function() { + + module("Utility"); + + test("utility: noConflict", function() { + var underscore = _.noConflict(); + ok(underscore.isUndefined(_), "The '_' variable has been returned to its previous state."); + var intersection = underscore.intersect([-1, 0, 1, 2], [1, 2, 3, 4]); + equals(intersection.join(', '), '1, 2', 'but the intersection function still works'); + window._ = underscore; + }); + + test("utility: identity", function() { + var moe = {name : 'moe'}; + equals(_.identity(moe), moe, 'moe is the same as his identity'); + }); + + test("utility: uniqueId", function() { + var ids = [], i = 0; + while(i++ < 100) ids.push(_.uniqueId()); + equals(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids'); + }); + + test("utility: times", function() { + var vals = []; + _.times(3, function (i) { vals.push(i); }); + ok(_.isEqual(vals, [0,1,2]), "is 0 indexed"); + // + vals = []; + _(3).times(function (i) { vals.push(i); }); + ok(_.isEqual(vals, [0,1,2]), "works as a wrapper"); + }); + + test("utility: mixin", function() { + _.mixin({ + myReverse: function(string) { + return string.split('').reverse().join(''); + } + }); + equals(_.myReverse('panacea'), 'aecanap', 'mixed in a function to _'); + equals(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper'); + }); + + test("utility: _.escape", function() { + equals(_.escape("Curly & Moe"), "Curly & Moe"); + equals(_.escape("Curly & Moe"), "Curly &amp; Moe"); + }); + + test("utility: template", function() { + var basicTemplate = _.template("<%= thing %> is gettin' on my noives!"); + var result = basicTemplate({thing : 'This'}); + equals(result, "This is gettin' on my noives!", 'can do basic attribute interpolation'); + + var sansSemicolonTemplate = _.template("A <% this %> B"); + equals(sansSemicolonTemplate(), "A B"); + + var backslashTemplate = _.template("<%= thing %> is \\ridanculous"); + equals(backslashTemplate({thing: 'This'}), "This is \\ridanculous"); + + var escapeTemplate = _.template('<%= a ? "checked=\\"checked\\"" : "" %>'); + equals(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.'); + + var fancyTemplate = _.template("
                    <% \ + for (key in people) { \ + %>
                  • <%= people[key] %>
                  • <% } %>
                  "); + result = fancyTemplate({people : {moe : "Moe", larry : "Larry", curly : "Curly"}}); + equals(result, "
                  • Moe
                  • Larry
                  • Curly
                  ", 'can run arbitrary javascript in templates'); + + var escapedCharsInJavascriptTemplate = _.template("
                    <% _.each(numbers.split('\\n'), function(item) { %>
                  • <%= item %>
                  • <% }) %>
                  "); + result = escapedCharsInJavascriptTemplate({numbers: "one\ntwo\nthree\nfour"}); + equals(result, "
                  • one
                  • two
                  • three
                  • four
                  ", 'Can use escaped characters (e.g. \\n) in Javascript'); + + var namespaceCollisionTemplate = _.template("<%= pageCount %> <%= thumbnails[pageCount] %> <% _.each(thumbnails, function(p) { %>
                  \">
                  <% }); %>"); + result = namespaceCollisionTemplate({ + pageCount: 3, + thumbnails: { + 1: "p1-thumbnail.gif", + 2: "p2-thumbnail.gif", + 3: "p3-thumbnail.gif" + } + }); + equals(result, "3 p3-thumbnail.gif
                  "); + + var noInterpolateTemplate = _.template("

                  Just some text. Hey, I know this is silly but it aids consistency.

                  "); + result = noInterpolateTemplate(); + equals(result, "

                  Just some text. Hey, I know this is silly but it aids consistency.

                  "); + + var quoteTemplate = _.template("It's its, not it's"); + equals(quoteTemplate({}), "It's its, not it's"); + + var quoteInStatementAndBody = _.template("<%\ + if(foo == 'bar'){ \ + %>Statement quotes and 'quotes'.<% } %>"); + equals(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'."); + + var withNewlinesAndTabs = _.template('This\n\t\tis: <%= x %>.\n\tok.\nend.'); + equals(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.'); + + var template = _.template("<%- value %>"); + var result = template({value: " + +``` + +## Documentation + +### Collections + +* [each](#each) +* [eachSeries](#eachSeries) +* [eachLimit](#eachLimit) +* [map](#map) +* [mapSeries](#mapSeries) +* [mapLimit](#mapLimit) +* [filter](#filter) +* [filterSeries](#filterSeries) +* [reject](#reject) +* [rejectSeries](#rejectSeries) +* [reduce](#reduce) +* [reduceRight](#reduceRight) +* [detect](#detect) +* [detectSeries](#detectSeries) +* [sortBy](#sortBy) +* [some](#some) +* [every](#every) +* [concat](#concat) +* [concatSeries](#concatSeries) + +### Control Flow + +* [series](#series) +* [parallel](#parallel) +* [parallelLimit](#parallellimittasks-limit-callback) +* [whilst](#whilst) +* [doWhilst](#doWhilst) +* [until](#until) +* [doUntil](#doUntil) +* [forever](#forever) +* [waterfall](#waterfall) +* [compose](#compose) +* [applyEach](#applyEach) +* [applyEachSeries](#applyEachSeries) +* [queue](#queue) +* [cargo](#cargo) +* [auto](#auto) +* [iterator](#iterator) +* [apply](#apply) +* [nextTick](#nextTick) +* [times](#times) +* [timesSeries](#timesSeries) + +### Utils + +* [memoize](#memoize) +* [unmemoize](#unmemoize) +* [log](#log) +* [dir](#dir) +* [noConflict](#noConflict) + + +## Collections + + + +### each(arr, iterator, callback) + +Applies an iterator function to each item in an array, in parallel. +The iterator is called with an item from the list and a callback for when it +has finished. If the iterator passes an error to this callback, the main +callback for the each function is immediately called with the error. + +Note, that since this function applies the iterator to each item in parallel +there is no guarantee that the iterator functions will complete in order. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err) which must be called once it has + completed. If no error has occured, the callback should be run without + arguments or with an explicit null argument. +* callback(err) - A callback which is called after all the iterator functions + have finished, or an error has occurred. + +__Example__ + +```js +// assuming openFiles is an array of file names and saveFile is a function +// to save the modified contents of that file: + +async.each(openFiles, saveFile, function(err){ + // if any of the saves produced an error, err would equal that error +}); +``` + +--------------------------------------- + + + +### eachSeries(arr, iterator, callback) + +The same as each only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. This means the iterator functions will complete in order. + + +--------------------------------------- + + + +### eachLimit(arr, limit, iterator, callback) + +The same as each only no more than "limit" iterators will be simultaneously +running at any time. + +Note that the items are not processed in batches, so there is no guarantee that + the first "limit" iterator functions will complete before any others are +started. + +__Arguments__ + +* arr - An array to iterate over. +* limit - The maximum number of iterators to run at any time. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err) which must be called once it has + completed. If no error has occured, the callback should be run without + arguments or with an explicit null argument. +* callback(err) - A callback which is called after all the iterator functions + have finished, or an error has occurred. + +__Example__ + +```js +// Assume documents is an array of JSON objects and requestApi is a +// function that interacts with a rate-limited REST api. + +async.eachLimit(documents, 20, requestApi, function(err){ + // if any of the saves produced an error, err would equal that error +}); +``` + +--------------------------------------- + + +### map(arr, iterator, callback) + +Produces a new array of values by mapping each value in the given array through +the iterator function. The iterator is called with an item from the array and a +callback for when it has finished processing. The callback takes 2 arguments, +an error and the transformed item from the array. If the iterator passes an +error to this callback, the main callback for the map function is immediately +called with the error. + +Note, that since this function applies the iterator to each item in parallel +there is no guarantee that the iterator functions will complete in order, however +the results array will be in the same order as the original array. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err, transformed) which must be called once + it has completed with an error (which can be null) and a transformed item. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is an array of the + transformed items from the original array. + +__Example__ + +```js +async.map(['file1','file2','file3'], fs.stat, function(err, results){ + // results is now an array of stats for each file +}); +``` + +--------------------------------------- + + +### mapSeries(arr, iterator, callback) + +The same as map only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. The results array will be in the same order as the original. + + +--------------------------------------- + + +### mapLimit(arr, limit, iterator, callback) + +The same as map only no more than "limit" iterators will be simultaneously +running at any time. + +Note that the items are not processed in batches, so there is no guarantee that + the first "limit" iterator functions will complete before any others are +started. + +__Arguments__ + +* arr - An array to iterate over. +* limit - The maximum number of iterators to run at any time. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err, transformed) which must be called once + it has completed with an error (which can be null) and a transformed item. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is an array of the + transformed items from the original array. + +__Example__ + +```js +async.mapLimit(['file1','file2','file3'], 1, fs.stat, function(err, results){ + // results is now an array of stats for each file +}); +``` + +--------------------------------------- + + +### filter(arr, iterator, callback) + +__Alias:__ select + +Returns a new array of all the values which pass an async truth test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like fs.exists. This operation is +performed in parallel, but the results array will be in the same order as the +original. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback(truthValue) which must be called with a + boolean argument once it has completed. +* callback(results) - A callback which is called after all the iterator + functions have finished. + +__Example__ + +```js +async.filter(['file1','file2','file3'], fs.exists, function(results){ + // results now equals an array of the existing files +}); +``` + +--------------------------------------- + + +### filterSeries(arr, iterator, callback) + +__alias:__ selectSeries + +The same as filter only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. The results array will be in the same order as the original. + +--------------------------------------- + + +### reject(arr, iterator, callback) + +The opposite of filter. Removes values that pass an async truth test. + +--------------------------------------- + + +### rejectSeries(arr, iterator, callback) + +The same as reject, only the iterator is applied to each item in the array +in series. + + +--------------------------------------- + + +### reduce(arr, memo, iterator, callback) + +__aliases:__ inject, foldl + +Reduces a list of values into a single value using an async iterator to return +each successive step. Memo is the initial state of the reduction. This +function only operates in series. For performance reasons, it may make sense to +split a call to this function into a parallel map, then use the normal +Array.prototype.reduce on the results. This function is for situations where +each step in the reduction needs to be async, if you can get the data before +reducing it then it's probably a good idea to do so. + +__Arguments__ + +* arr - An array to iterate over. +* memo - The initial state of the reduction. +* iterator(memo, item, callback) - A function applied to each item in the + array to produce the next step in the reduction. The iterator is passed a + callback(err, reduction) which accepts an optional error as its first + argument, and the state of the reduction as the second. If an error is + passed to the callback, the reduction is stopped and the main callback is + immediately called with the error. +* callback(err, result) - A callback which is called after all the iterator + functions have finished. Result is the reduced value. + +__Example__ + +```js +async.reduce([1,2,3], 0, function(memo, item, callback){ + // pointless async: + process.nextTick(function(){ + callback(null, memo + item) + }); +}, function(err, result){ + // result is now equal to the last value of memo, which is 6 +}); +``` + +--------------------------------------- + + +### reduceRight(arr, memo, iterator, callback) + +__Alias:__ foldr + +Same as reduce, only operates on the items in the array in reverse order. + + +--------------------------------------- + + +### detect(arr, iterator, callback) + +Returns the first value in a list that passes an async truth test. The +iterator is applied in parallel, meaning the first iterator to return true will +fire the detect callback with that result. That means the result might not be +the first item in the original array (in terms of order) that passes the test. + +If order within the original array is important then look at detectSeries. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback(truthValue) which must be called with a + boolean argument once it has completed. +* callback(result) - A callback which is called as soon as any iterator returns + true, or after all the iterator functions have finished. Result will be + the first item in the array that passes the truth test (iterator) or the + value undefined if none passed. + +__Example__ + +```js +async.detect(['file1','file2','file3'], fs.exists, function(result){ + // result now equals the first file in the list that exists +}); +``` + +--------------------------------------- + + +### detectSeries(arr, iterator, callback) + +The same as detect, only the iterator is applied to each item in the array +in series. This means the result is always the first in the original array (in +terms of array order) that passes the truth test. + + +--------------------------------------- + + +### sortBy(arr, iterator, callback) + +Sorts a list by the results of running each value through an async iterator. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err, sortValue) which must be called once it + has completed with an error (which can be null) and a value to use as the sort + criteria. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is the items from + the original array sorted by the values returned by the iterator calls. + +__Example__ + +```js +async.sortBy(['file1','file2','file3'], function(file, callback){ + fs.stat(file, function(err, stats){ + callback(err, stats.mtime); + }); +}, function(err, results){ + // results is now the original array of files sorted by + // modified date +}); +``` + +--------------------------------------- + + +### some(arr, iterator, callback) + +__Alias:__ any + +Returns true if at least one element in the array satisfies an async test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like fs.exists. Once any iterator +call returns true, the main callback is immediately called. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback(truthValue) which must be called with a + boolean argument once it has completed. +* callback(result) - A callback which is called as soon as any iterator returns + true, or after all the iterator functions have finished. Result will be + either true or false depending on the values of the async tests. + +__Example__ + +```js +async.some(['file1','file2','file3'], fs.exists, function(result){ + // if result is true then at least one of the files exists +}); +``` + +--------------------------------------- + + +### every(arr, iterator, callback) + +__Alias:__ all + +Returns true if every element in the array satisfies an async test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like fs.exists. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback(truthValue) which must be called with a + boolean argument once it has completed. +* callback(result) - A callback which is called after all the iterator + functions have finished. Result will be either true or false depending on + the values of the async tests. + +__Example__ + +```js +async.every(['file1','file2','file3'], fs.exists, function(result){ + // if result is true then every file exists +}); +``` + +--------------------------------------- + + +### concat(arr, iterator, callback) + +Applies an iterator to each item in a list, concatenating the results. Returns the +concatenated list. The iterators are called in parallel, and the results are +concatenated as they return. There is no guarantee that the results array will +be returned in the original order of the arguments passed to the iterator function. + +__Arguments__ + +* arr - An array to iterate over +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err, results) which must be called once it + has completed with an error (which can be null) and an array of results. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is an array containing + the concatenated results of the iterator function. + +__Example__ + +```js +async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){ + // files is now a list of filenames that exist in the 3 directories +}); +``` + +--------------------------------------- + + +### concatSeries(arr, iterator, callback) + +Same as async.concat, but executes in series instead of parallel. + + +## Control Flow + + +### series(tasks, [callback]) + +Run an array of functions in series, each one running once the previous +function has completed. If any functions in the series pass an error to its +callback, no more functions are run and the callback for the series is +immediately called with the value of the error. Once the tasks have completed, +the results are passed to the final callback as an array. + +It is also possible to use an object instead of an array. Each property will be +run as a function and the results will be passed to the final callback as an object +instead of an array. This can be a more readable way of handling results from +async.series. + + +__Arguments__ + +* tasks - An array or object containing functions to run, each function is passed + a callback(err, result) it must call on completion with an error (which can + be null) and an optional result value. +* callback(err, results) - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the task callbacks. + +__Example__ + +```js +async.series([ + function(callback){ + // do some stuff ... + callback(null, 'one'); + }, + function(callback){ + // do some more stuff ... + callback(null, 'two'); + } +], +// optional callback +function(err, results){ + // results is now equal to ['one', 'two'] +}); + + +// an example using an object instead of an array +async.series({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + } +}, +function(err, results) { + // results is now equal to: {one: 1, two: 2} +}); +``` + +--------------------------------------- + + +### parallel(tasks, [callback]) + +Run an array of functions in parallel, without waiting until the previous +function has completed. If any of the functions pass an error to its +callback, the main callback is immediately called with the value of the error. +Once the tasks have completed, the results are passed to the final callback as an +array. + +It is also possible to use an object instead of an array. Each property will be +run as a function and the results will be passed to the final callback as an object +instead of an array. This can be a more readable way of handling results from +async.parallel. + + +__Arguments__ + +* tasks - An array or object containing functions to run, each function is passed + a callback(err, result) it must call on completion with an error (which can + be null) and an optional result value. +* callback(err, results) - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the task callbacks. + +__Example__ + +```js +async.parallel([ + function(callback){ + setTimeout(function(){ + callback(null, 'one'); + }, 200); + }, + function(callback){ + setTimeout(function(){ + callback(null, 'two'); + }, 100); + } +], +// optional callback +function(err, results){ + // the results array will equal ['one','two'] even though + // the second function had a shorter timeout. +}); + + +// an example using an object instead of an array +async.parallel({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + } +}, +function(err, results) { + // results is now equals to: {one: 1, two: 2} +}); +``` + +--------------------------------------- + + +### parallelLimit(tasks, limit, [callback]) + +The same as parallel only the tasks are executed in parallel with a maximum of "limit" +tasks executing at any time. + +Note that the tasks are not executed in batches, so there is no guarantee that +the first "limit" tasks will complete before any others are started. + +__Arguments__ + +* tasks - An array or object containing functions to run, each function is passed + a callback(err, result) it must call on completion with an error (which can + be null) and an optional result value. +* limit - The maximum number of tasks to run at any time. +* callback(err, results) - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the task callbacks. + +--------------------------------------- + + +### whilst(test, fn, callback) + +Repeatedly call fn, while test returns true. Calls the callback when stopped, +or an error occurs. + +__Arguments__ + +* test() - synchronous truth test to perform before each execution of fn. +* fn(callback) - A function to call each time the test passes. The function is + passed a callback(err) which must be called once it has completed with an + optional error argument. +* callback(err) - A callback which is called after the test fails and repeated + execution of fn has stopped. + +__Example__ + +```js +var count = 0; + +async.whilst( + function () { return count < 5; }, + function (callback) { + count++; + setTimeout(callback, 1000); + }, + function (err) { + // 5 seconds have passed + } +); +``` + +--------------------------------------- + + +### doWhilst(fn, test, callback) + +The post check version of whilst. To reflect the difference in the order of operations `test` and `fn` arguments are switched. `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. + +--------------------------------------- + + +### until(test, fn, callback) + +Repeatedly call fn, until test returns true. Calls the callback when stopped, +or an error occurs. + +The inverse of async.whilst. + +--------------------------------------- + + +### doUntil(fn, test, callback) + +Like doWhilst except the test is inverted. Note the argument ordering differs from `until`. + +--------------------------------------- + + +### forever(fn, callback) + +Calls the asynchronous function 'fn' repeatedly, in series, indefinitely. +If an error is passed to fn's callback then 'callback' is called with the +error, otherwise it will never be called. + +--------------------------------------- + + +### waterfall(tasks, [callback]) + +Runs an array of functions in series, each passing their results to the next in +the array. However, if any of the functions pass an error to the callback, the +next function is not executed and the main callback is immediately called with +the error. + +__Arguments__ + +* tasks - An array of functions to run, each function is passed a + callback(err, result1, result2, ...) it must call on completion. The first + argument is an error (which can be null) and any further arguments will be + passed as arguments in order to the next task. +* callback(err, [results]) - An optional callback to run once all the functions + have completed. This will be passed the results of the last task's callback. + + + +__Example__ + +```js +async.waterfall([ + function(callback){ + callback(null, 'one', 'two'); + }, + function(arg1, arg2, callback){ + callback(null, 'three'); + }, + function(arg1, callback){ + // arg1 now equals 'three' + callback(null, 'done'); + } +], function (err, result) { + // result now equals 'done' +}); +``` + +--------------------------------------- + +### compose(fn1, fn2...) + +Creates a function which is a composition of the passed asynchronous +functions. Each function consumes the return value of the function that +follows. Composing functions f(), g() and h() would produce the result of +f(g(h())), only this version uses callbacks to obtain the return values. + +Each function is executed with the `this` binding of the composed function. + +__Arguments__ + +* functions... - the asynchronous functions to compose + + +__Example__ + +```js +function add1(n, callback) { + setTimeout(function () { + callback(null, n + 1); + }, 10); +} + +function mul3(n, callback) { + setTimeout(function () { + callback(null, n * 3); + }, 10); +} + +var add1mul3 = async.compose(mul3, add1); + +add1mul3(4, function (err, result) { + // result now equals 15 +}); +``` + +--------------------------------------- + +### applyEach(fns, args..., callback) + +Applies the provided arguments to each function in the array, calling the +callback after all functions have completed. If you only provide the first +argument then it will return a function which lets you pass in the +arguments as if it were a single function call. + +__Arguments__ + +* fns - the asynchronous functions to all call with the same arguments +* args... - any number of separate arguments to pass to the function +* callback - the final argument should be the callback, called when all + functions have completed processing + + +__Example__ + +```js +async.applyEach([enableSearch, updateSchema], 'bucket', callback); + +// partial application example: +async.each( + buckets, + async.applyEach([enableSearch, updateSchema]), + callback +); +``` + +--------------------------------------- + + +### applyEachSeries(arr, iterator, callback) + +The same as applyEach only the functions are applied in series. + +--------------------------------------- + + +### queue(worker, concurrency) + +Creates a queue object with the specified concurrency. Tasks added to the +queue will be processed in parallel (up to the concurrency limit). If all +workers are in progress, the task is queued until one is available. Once +a worker has completed a task, the task's callback is called. + +__Arguments__ + +* worker(task, callback) - An asynchronous function for processing a queued + task, which must call its callback(err) argument when finished, with an + optional error as an argument. +* concurrency - An integer for determining how many worker functions should be + run in parallel. + +__Queue objects__ + +The queue object returned by this function has the following properties and +methods: + +* length() - a function returning the number of items waiting to be processed. +* concurrency - an integer for determining how many worker functions should be + run in parallel. This property can be changed after a queue is created to + alter the concurrency on-the-fly. +* push(task, [callback]) - add a new task to the queue, the callback is called + once the worker has finished processing the task. + instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list. +* unshift(task, [callback]) - add a new task to the front of the queue. +* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued +* empty - a callback that is called when the last item from the queue is given to a worker +* drain - a callback that is called when the last item from the queue has returned from the worker + +__Example__ + +```js +// create a queue object with concurrency 2 + +var q = async.queue(function (task, callback) { + console.log('hello ' + task.name); + callback(); +}, 2); + + +// assign a callback +q.drain = function() { + console.log('all items have been processed'); +} + +// add some items to the queue + +q.push({name: 'foo'}, function (err) { + console.log('finished processing foo'); +}); +q.push({name: 'bar'}, function (err) { + console.log('finished processing bar'); +}); + +// add some items to the queue (batch-wise) + +q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) { + console.log('finished processing bar'); +}); + +// add some items to the front of the queue + +q.unshift({name: 'bar'}, function (err) { + console.log('finished processing bar'); +}); +``` + +--------------------------------------- + + +### cargo(worker, [payload]) + +Creates a cargo object with the specified payload. Tasks added to the +cargo will be processed altogether (up to the payload limit). If the +worker is in progress, the task is queued until it is available. Once +the worker has completed some tasks, each callback of those tasks is called. + +__Arguments__ + +* worker(tasks, callback) - An asynchronous function for processing an array of + queued tasks, which must call its callback(err) argument when finished, with + an optional error as an argument. +* payload - An optional integer for determining how many tasks should be + processed per round; if omitted, the default is unlimited. + +__Cargo objects__ + +The cargo object returned by this function has the following properties and +methods: + +* length() - a function returning the number of items waiting to be processed. +* payload - an integer for determining how many tasks should be + process per round. This property can be changed after a cargo is created to + alter the payload on-the-fly. +* push(task, [callback]) - add a new task to the queue, the callback is called + once the worker has finished processing the task. + instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list. +* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued +* empty - a callback that is called when the last item from the queue is given to a worker +* drain - a callback that is called when the last item from the queue has returned from the worker + +__Example__ + +```js +// create a cargo object with payload 2 + +var cargo = async.cargo(function (tasks, callback) { + for(var i=0; i +### auto(tasks, [callback]) + +Determines the best order for running functions based on their requirements. +Each function can optionally depend on other functions being completed first, +and each function is run as soon as its requirements are satisfied. If any of +the functions pass an error to their callback, that function will not complete +(so any other functions depending on it will not run) and the main callback +will be called immediately with the error. Functions also receive an object +containing the results of functions which have completed so far. + +Note, all functions are called with a results object as a second argument, +so it is unsafe to pass functions in the tasks object which cannot handle the +extra argument. For example, this snippet of code: + +```js +async.auto({ + readData: async.apply(fs.readFile, 'data.txt', 'utf-8') +}, callback); +``` + +will have the effect of calling readFile with the results object as the last +argument, which will fail: + +```js +fs.readFile('data.txt', 'utf-8', cb, {}); +``` + +Instead, wrap the call to readFile in a function which does not forward the +results object: + +```js +async.auto({ + readData: function(cb, results){ + fs.readFile('data.txt', 'utf-8', cb); + } +}, callback); +``` + +__Arguments__ + +* tasks - An object literal containing named functions or an array of + requirements, with the function itself the last item in the array. The key + used for each function or array is used when specifying requirements. The + function receives two arguments: (1) a callback(err, result) which must be + called when finished, passing an error (which can be null) and the result of + the function's execution, and (2) a results object, containing the results of + the previously executed functions. +* callback(err, results) - An optional callback which is called when all the + tasks have been completed. The callback will receive an error as an argument + if any tasks pass an error to their callback. Results will always be passed + but if an error occurred, no other tasks will be performed, and the results + object will only contain partial results. + + +__Example__ + +```js +async.auto({ + get_data: function(callback){ + // async code to get some data + }, + make_folder: function(callback){ + // async code to create a directory to store a file in + // this is run at the same time as getting the data + }, + write_file: ['get_data', 'make_folder', function(callback){ + // once there is some data and the directory exists, + // write the data to a file in the directory + callback(null, filename); + }], + email_link: ['write_file', function(callback, results){ + // once the file is written let's email a link to it... + // results.write_file contains the filename returned by write_file. + }] +}); +``` + +This is a fairly trivial example, but to do this using the basic parallel and +series functions would look like this: + +```js +async.parallel([ + function(callback){ + // async code to get some data + }, + function(callback){ + // async code to create a directory to store a file in + // this is run at the same time as getting the data + } +], +function(err, results){ + async.series([ + function(callback){ + // once there is some data and the directory exists, + // write the data to a file in the directory + }, + function(callback){ + // once the file is written let's email a link to it... + } + ]); +}); +``` + +For a complicated series of async tasks using the auto function makes adding +new tasks much easier and makes the code more readable. + + +--------------------------------------- + + +### iterator(tasks) + +Creates an iterator function which calls the next function in the array, +returning a continuation to call the next one after that. It's also possible to +'peek' the next iterator by doing iterator.next(). + +This function is used internally by the async module but can be useful when +you want to manually control the flow of functions in series. + +__Arguments__ + +* tasks - An array of functions to run. + +__Example__ + +```js +var iterator = async.iterator([ + function(){ sys.p('one'); }, + function(){ sys.p('two'); }, + function(){ sys.p('three'); } +]); + +node> var iterator2 = iterator(); +'one' +node> var iterator3 = iterator2(); +'two' +node> iterator3(); +'three' +node> var nextfn = iterator2.next(); +node> nextfn(); +'three' +``` + +--------------------------------------- + + +### apply(function, arguments..) + +Creates a continuation function with some arguments already applied, a useful +shorthand when combined with other control flow functions. Any arguments +passed to the returned function are added to the arguments originally passed +to apply. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to automatically apply when the + continuation is called. + +__Example__ + +```js +// using apply + +async.parallel([ + async.apply(fs.writeFile, 'testfile1', 'test1'), + async.apply(fs.writeFile, 'testfile2', 'test2'), +]); + + +// the same process without using apply + +async.parallel([ + function(callback){ + fs.writeFile('testfile1', 'test1', callback); + }, + function(callback){ + fs.writeFile('testfile2', 'test2', callback); + } +]); +``` + +It's possible to pass any number of additional arguments when calling the +continuation: + +```js +node> var fn = async.apply(sys.puts, 'one'); +node> fn('two', 'three'); +one +two +three +``` + +--------------------------------------- + + +### nextTick(callback) + +Calls the callback on a later loop around the event loop. In node.js this just +calls process.nextTick, in the browser it falls back to setImmediate(callback) +if available, otherwise setTimeout(callback, 0), which means other higher priority +events may precede the execution of the callback. + +This is used internally for browser-compatibility purposes. + +__Arguments__ + +* callback - The function to call on a later loop around the event loop. + +__Example__ + +```js +var call_order = []; +async.nextTick(function(){ + call_order.push('two'); + // call_order now equals ['one','two'] +}); +call_order.push('one') +``` + + +### times(n, callback) + +Calls the callback n times and accumulates results in the same manner +you would use with async.map. + +__Arguments__ + +* n - The number of times to run the function. +* callback - The function to call n times. + +__Example__ + +```js +// Pretend this is some complicated async factory +var createUser = function(id, callback) { + callback(null, { + id: 'user' + id + }) +} +// generate 5 users +async.times(5, function(n, next){ + createUser(n, function(err, user) { + next(err, user) + }) +}, function(err, users) { + // we should now have 5 users +}); +``` + + +### timesSeries(n, callback) + +The same as times only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. The results array will be in the same order as the original. + + +## Utils + + +### memoize(fn, [hasher]) + +Caches the results of an async function. When creating a hash to store function +results against, the callback is omitted from the hash and an optional hash +function can be used. + +The cache of results is exposed as the `memo` property of the function returned +by `memoize`. + +__Arguments__ + +* fn - the function you to proxy and cache results from. +* hasher - an optional function for generating a custom hash for storing + results, it has all the arguments applied to it apart from the callback, and + must be synchronous. + +__Example__ + +```js +var slow_fn = function (name, callback) { + // do something + callback(null, result); +}; +var fn = async.memoize(slow_fn); + +// fn can now be used as if it were slow_fn +fn('some name', function () { + // callback +}); +``` + + +### unmemoize(fn) + +Undoes a memoized function, reverting it to the original, unmemoized +form. Comes handy in tests. + +__Arguments__ + +* fn - the memoized function + + +### log(function, arguments) + +Logs the result of an async function to the console. Only works in node.js or +in browsers that support console.log and console.error (such as FF and Chrome). +If multiple arguments are returned from the async function, console.log is +called on each argument in order. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to apply to the function. + +__Example__ + +```js +var hello = function(name, callback){ + setTimeout(function(){ + callback(null, 'hello ' + name); + }, 1000); +}; +``` +```js +node> async.log(hello, 'world'); +'hello world' +``` + +--------------------------------------- + + +### dir(function, arguments) + +Logs the result of an async function to the console using console.dir to +display the properties of the resulting object. Only works in node.js or +in browsers that support console.dir and console.error (such as FF and Chrome). +If multiple arguments are returned from the async function, console.dir is +called on each argument in order. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to apply to the function. + +__Example__ + +```js +var hello = function(name, callback){ + setTimeout(function(){ + callback(null, {hello: name}); + }, 1000); +}; +``` +```js +node> async.dir(hello, 'world'); +{hello: 'world'} +``` + +--------------------------------------- + + +### noConflict() + +Changes the value of async back to its original value, returning a reference to the +async object. diff --git a/node_modules/utile/node_modules/async/component.json b/node_modules/utile/node_modules/async/component.json new file mode 100644 index 0000000..bbb0115 --- /dev/null +++ b/node_modules/utile/node_modules/async/component.json @@ -0,0 +1,11 @@ +{ + "name": "async", + "repo": "caolan/async", + "description": "Higher-order functions and common patterns for asynchronous code", + "version": "0.1.23", + "keywords": [], + "dependencies": {}, + "development": {}, + "main": "lib/async.js", + "scripts": [ "lib/async.js" ] +} diff --git a/node_modules/utile/node_modules/async/lib/async.js b/node_modules/utile/node_modules/async/lib/async.js new file mode 100644 index 0000000..1eebb15 --- /dev/null +++ b/node_modules/utile/node_modules/async/lib/async.js @@ -0,0 +1,958 @@ +/*global setImmediate: false, setTimeout: false, console: false */ +(function () { + + var async = {}; + + // global on the server, window in the browser + var root, previous_async; + + root = this; + if (root != null) { + previous_async = root.async; + } + + async.noConflict = function () { + root.async = previous_async; + return async; + }; + + function only_once(fn) { + var called = false; + return function() { + if (called) throw new Error("Callback was already called."); + called = true; + fn.apply(root, arguments); + } + } + + //// cross-browser compatiblity functions //// + + var _each = function (arr, iterator) { + if (arr.forEach) { + return arr.forEach(iterator); + } + for (var i = 0; i < arr.length; i += 1) { + iterator(arr[i], i, arr); + } + }; + + var _map = function (arr, iterator) { + if (arr.map) { + return arr.map(iterator); + } + var results = []; + _each(arr, function (x, i, a) { + results.push(iterator(x, i, a)); + }); + return results; + }; + + var _reduce = function (arr, iterator, memo) { + if (arr.reduce) { + return arr.reduce(iterator, memo); + } + _each(arr, function (x, i, a) { + memo = iterator(memo, x, i, a); + }); + return memo; + }; + + var _keys = function (obj) { + if (Object.keys) { + return Object.keys(obj); + } + var keys = []; + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + keys.push(k); + } + } + return keys; + }; + + //// exported async module functions //// + + //// nextTick implementation with browser-compatible fallback //// + if (typeof process === 'undefined' || !(process.nextTick)) { + if (typeof setImmediate === 'function') { + async.nextTick = function (fn) { + // not a direct alias for IE10 compatibility + setImmediate(fn); + }; + async.setImmediate = async.nextTick; + } + else { + async.nextTick = function (fn) { + setTimeout(fn, 0); + }; + async.setImmediate = async.nextTick; + } + } + else { + async.nextTick = process.nextTick; + if (typeof setImmediate !== 'undefined') { + async.setImmediate = function (fn) { + // not a direct alias for IE10 compatibility + setImmediate(fn); + }; + } + else { + async.setImmediate = async.nextTick; + } + } + + async.each = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); + } + var completed = 0; + _each(arr, function (x) { + iterator(x, only_once(function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed >= arr.length) { + callback(null); + } + } + })); + }); + }; + async.forEach = async.each; + + async.eachSeries = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); + } + var completed = 0; + var iterate = function () { + iterator(arr[completed], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed >= arr.length) { + callback(null); + } + else { + iterate(); + } + } + }); + }; + iterate(); + }; + async.forEachSeries = async.eachSeries; + + async.eachLimit = function (arr, limit, iterator, callback) { + var fn = _eachLimit(limit); + fn.apply(null, [arr, iterator, callback]); + }; + async.forEachLimit = async.eachLimit; + + var _eachLimit = function (limit) { + + return function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length || limit <= 0) { + return callback(); + } + var completed = 0; + var started = 0; + var running = 0; + + (function replenish () { + if (completed >= arr.length) { + return callback(); + } + + while (running < limit && started < arr.length) { + started += 1; + running += 1; + iterator(arr[started - 1], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + running -= 1; + if (completed >= arr.length) { + callback(); + } + else { + replenish(); + } + } + }); + } + })(); + }; + }; + + + var doParallel = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.each].concat(args)); + }; + }; + var doParallelLimit = function(limit, fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [_eachLimit(limit)].concat(args)); + }; + }; + var doSeries = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.eachSeries].concat(args)); + }; + }; + + + var _asyncMap = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (err, v) { + results[x.index] = v; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + }; + async.map = doParallel(_asyncMap); + async.mapSeries = doSeries(_asyncMap); + async.mapLimit = function (arr, limit, iterator, callback) { + return _mapLimit(limit)(arr, iterator, callback); + }; + + var _mapLimit = function(limit) { + return doParallelLimit(limit, _asyncMap); + }; + + // reduce only has a series version, as doing reduce in parallel won't + // work in many situations. + async.reduce = function (arr, memo, iterator, callback) { + async.eachSeries(arr, function (x, callback) { + iterator(memo, x, function (err, v) { + memo = v; + callback(err); + }); + }, function (err) { + callback(err, memo); + }); + }; + // inject alias + async.inject = async.reduce; + // foldl alias + async.foldl = async.reduce; + + async.reduceRight = function (arr, memo, iterator, callback) { + var reversed = _map(arr, function (x) { + return x; + }).reverse(); + async.reduce(reversed, memo, iterator, callback); + }; + // foldr alias + async.foldr = async.reduceRight; + + var _filter = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.filter = doParallel(_filter); + async.filterSeries = doSeries(_filter); + // select alias + async.select = async.filter; + async.selectSeries = async.filterSeries; + + var _reject = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (!v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.reject = doParallel(_reject); + async.rejectSeries = doSeries(_reject); + + var _detect = function (eachfn, arr, iterator, main_callback) { + eachfn(arr, function (x, callback) { + iterator(x, function (result) { + if (result) { + main_callback(x); + main_callback = function () {}; + } + else { + callback(); + } + }); + }, function (err) { + main_callback(); + }); + }; + async.detect = doParallel(_detect); + async.detectSeries = doSeries(_detect); + + async.some = function (arr, iterator, main_callback) { + async.each(arr, function (x, callback) { + iterator(x, function (v) { + if (v) { + main_callback(true); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(false); + }); + }; + // any alias + async.any = async.some; + + async.every = function (arr, iterator, main_callback) { + async.each(arr, function (x, callback) { + iterator(x, function (v) { + if (!v) { + main_callback(false); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(true); + }); + }; + // all alias + async.all = async.every; + + async.sortBy = function (arr, iterator, callback) { + async.map(arr, function (x, callback) { + iterator(x, function (err, criteria) { + if (err) { + callback(err); + } + else { + callback(null, {value: x, criteria: criteria}); + } + }); + }, function (err, results) { + if (err) { + return callback(err); + } + else { + var fn = function (left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }; + callback(null, _map(results.sort(fn), function (x) { + return x.value; + })); + } + }); + }; + + async.auto = function (tasks, callback) { + callback = callback || function () {}; + var keys = _keys(tasks); + if (!keys.length) { + return callback(null); + } + + var results = {}; + + var listeners = []; + var addListener = function (fn) { + listeners.unshift(fn); + }; + var removeListener = function (fn) { + for (var i = 0; i < listeners.length; i += 1) { + if (listeners[i] === fn) { + listeners.splice(i, 1); + return; + } + } + }; + var taskComplete = function () { + _each(listeners.slice(0), function (fn) { + fn(); + }); + }; + + addListener(function () { + if (_keys(results).length === keys.length) { + callback(null, results); + callback = function () {}; + } + }); + + _each(keys, function (k) { + var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; + var taskCallback = function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + if (err) { + var safeResults = {}; + _each(_keys(results), function(rkey) { + safeResults[rkey] = results[rkey]; + }); + safeResults[k] = args; + callback(err, safeResults); + // stop subsequent errors hitting callback multiple times + callback = function () {}; + } + else { + results[k] = args; + async.setImmediate(taskComplete); + } + }; + var requires = task.slice(0, Math.abs(task.length - 1)) || []; + var ready = function () { + return _reduce(requires, function (a, x) { + return (a && results.hasOwnProperty(x)); + }, true) && !results.hasOwnProperty(k); + }; + if (ready()) { + task[task.length - 1](taskCallback, results); + } + else { + var listener = function () { + if (ready()) { + removeListener(listener); + task[task.length - 1](taskCallback, results); + } + }; + addListener(listener); + } + }); + }; + + async.waterfall = function (tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor !== Array) { + var err = new Error('First argument to waterfall must be an array of functions'); + return callback(err); + } + if (!tasks.length) { + return callback(); + } + var wrapIterator = function (iterator) { + return function (err) { + if (err) { + callback.apply(null, arguments); + callback = function () {}; + } + else { + var args = Array.prototype.slice.call(arguments, 1); + var next = iterator.next(); + if (next) { + args.push(wrapIterator(next)); + } + else { + args.push(callback); + } + async.setImmediate(function () { + iterator.apply(null, args); + }); + } + }; + }; + wrapIterator(async.iterator(tasks))(); + }; + + var _parallel = function(eachfn, tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor === Array) { + eachfn.map(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + eachfn.each(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.parallel = function (tasks, callback) { + _parallel({ map: async.map, each: async.each }, tasks, callback); + }; + + async.parallelLimit = function(tasks, limit, callback) { + _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback); + }; + + async.series = function (tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor === Array) { + async.mapSeries(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + async.eachSeries(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.iterator = function (tasks) { + var makeCallback = function (index) { + var fn = function () { + if (tasks.length) { + tasks[index].apply(null, arguments); + } + return fn.next(); + }; + fn.next = function () { + return (index < tasks.length - 1) ? makeCallback(index + 1): null; + }; + return fn; + }; + return makeCallback(0); + }; + + async.apply = function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + return function () { + return fn.apply( + null, args.concat(Array.prototype.slice.call(arguments)) + ); + }; + }; + + var _concat = function (eachfn, arr, fn, callback) { + var r = []; + eachfn(arr, function (x, cb) { + fn(x, function (err, y) { + r = r.concat(y || []); + cb(err); + }); + }, function (err) { + callback(err, r); + }); + }; + async.concat = doParallel(_concat); + async.concatSeries = doSeries(_concat); + + async.whilst = function (test, iterator, callback) { + if (test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.whilst(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.doWhilst = function (iterator, test, callback) { + iterator(function (err) { + if (err) { + return callback(err); + } + if (test()) { + async.doWhilst(iterator, test, callback); + } + else { + callback(); + } + }); + }; + + async.until = function (test, iterator, callback) { + if (!test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.until(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.doUntil = function (iterator, test, callback) { + iterator(function (err) { + if (err) { + return callback(err); + } + if (!test()) { + async.doUntil(iterator, test, callback); + } + else { + callback(); + } + }); + }; + + async.queue = function (worker, concurrency) { + if (concurrency === undefined) { + concurrency = 1; + } + function _insert(q, data, pos, callback) { + if(data.constructor !== Array) { + data = [data]; + } + _each(data, function(task) { + var item = { + data: task, + callback: typeof callback === 'function' ? callback : null + }; + + if (pos) { + q.tasks.unshift(item); + } else { + q.tasks.push(item); + } + + if (q.saturated && q.tasks.length === concurrency) { + q.saturated(); + } + async.setImmediate(q.process); + }); + } + + var workers = 0; + var q = { + tasks: [], + concurrency: concurrency, + saturated: null, + empty: null, + drain: null, + push: function (data, callback) { + _insert(q, data, false, callback); + }, + unshift: function (data, callback) { + _insert(q, data, true, callback); + }, + process: function () { + if (workers < q.concurrency && q.tasks.length) { + var task = q.tasks.shift(); + if (q.empty && q.tasks.length === 0) { + q.empty(); + } + workers += 1; + var next = function () { + workers -= 1; + if (task.callback) { + task.callback.apply(task, arguments); + } + if (q.drain && q.tasks.length + workers === 0) { + q.drain(); + } + q.process(); + }; + var cb = only_once(next); + worker(task.data, cb); + } + }, + length: function () { + return q.tasks.length; + }, + running: function () { + return workers; + } + }; + return q; + }; + + async.cargo = function (worker, payload) { + var working = false, + tasks = []; + + var cargo = { + tasks: tasks, + payload: payload, + saturated: null, + empty: null, + drain: null, + push: function (data, callback) { + if(data.constructor !== Array) { + data = [data]; + } + _each(data, function(task) { + tasks.push({ + data: task, + callback: typeof callback === 'function' ? callback : null + }); + if (cargo.saturated && tasks.length === payload) { + cargo.saturated(); + } + }); + async.setImmediate(cargo.process); + }, + process: function process() { + if (working) return; + if (tasks.length === 0) { + if(cargo.drain) cargo.drain(); + return; + } + + var ts = typeof payload === 'number' + ? tasks.splice(0, payload) + : tasks.splice(0); + + var ds = _map(ts, function (task) { + return task.data; + }); + + if(cargo.empty) cargo.empty(); + working = true; + worker(ds, function () { + working = false; + + var args = arguments; + _each(ts, function (data) { + if (data.callback) { + data.callback.apply(null, args); + } + }); + + process(); + }); + }, + length: function () { + return tasks.length; + }, + running: function () { + return working; + } + }; + return cargo; + }; + + var _console_fn = function (name) { + return function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + fn.apply(null, args.concat([function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (typeof console !== 'undefined') { + if (err) { + if (console.error) { + console.error(err); + } + } + else if (console[name]) { + _each(args, function (x) { + console[name](x); + }); + } + } + }])); + }; + }; + async.log = _console_fn('log'); + async.dir = _console_fn('dir'); + /*async.info = _console_fn('info'); + async.warn = _console_fn('warn'); + async.error = _console_fn('error');*/ + + async.memoize = function (fn, hasher) { + var memo = {}; + var queues = {}; + hasher = hasher || function (x) { + return x; + }; + var memoized = function () { + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + var key = hasher.apply(null, args); + if (key in memo) { + callback.apply(null, memo[key]); + } + else if (key in queues) { + queues[key].push(callback); + } + else { + queues[key] = [callback]; + fn.apply(null, args.concat([function () { + memo[key] = arguments; + var q = queues[key]; + delete queues[key]; + for (var i = 0, l = q.length; i < l; i++) { + q[i].apply(null, arguments); + } + }])); + } + }; + memoized.memo = memo; + memoized.unmemoized = fn; + return memoized; + }; + + async.unmemoize = function (fn) { + return function () { + return (fn.unmemoized || fn).apply(null, arguments); + }; + }; + + async.times = function (count, iterator, callback) { + var counter = []; + for (var i = 0; i < count; i++) { + counter.push(i); + } + return async.map(counter, iterator, callback); + }; + + async.timesSeries = function (count, iterator, callback) { + var counter = []; + for (var i = 0; i < count; i++) { + counter.push(i); + } + return async.mapSeries(counter, iterator, callback); + }; + + async.compose = function (/* functions... */) { + var fns = Array.prototype.reverse.call(arguments); + return function () { + var that = this; + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + async.reduce(fns, args, function (newargs, fn, cb) { + fn.apply(that, newargs.concat([function () { + var err = arguments[0]; + var nextargs = Array.prototype.slice.call(arguments, 1); + cb(err, nextargs); + }])) + }, + function (err, results) { + callback.apply(that, [err].concat(results)); + }); + }; + }; + + var _applyEach = function (eachfn, fns /*args...*/) { + var go = function () { + var that = this; + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + return eachfn(fns, function (fn, cb) { + fn.apply(that, args.concat([cb])); + }, + callback); + }; + if (arguments.length > 2) { + var args = Array.prototype.slice.call(arguments, 2); + return go.apply(this, args); + } + else { + return go; + } + }; + async.applyEach = doParallel(_applyEach); + async.applyEachSeries = doSeries(_applyEach); + + async.forever = function (fn, callback) { + function next(err) { + if (err) { + if (callback) { + return callback(err); + } + throw err; + } + fn(next); + } + next(); + }; + + // AMD / RequireJS + if (typeof define !== 'undefined' && define.amd) { + define([], function () { + return async; + }); + } + // Node.js + else if (typeof module !== 'undefined' && module.exports) { + module.exports = async; + } + // included directly via + +``` + +## Documentation + +### Collections + +* [each](#each) +* [eachSeries](#eachSeries) +* [eachLimit](#eachLimit) +* [map](#map) +* [mapSeries](#mapSeries) +* [mapLimit](#mapLimit) +* [filter](#filter) +* [filterSeries](#filterSeries) +* [reject](#reject) +* [rejectSeries](#rejectSeries) +* [reduce](#reduce) +* [reduceRight](#reduceRight) +* [detect](#detect) +* [detectSeries](#detectSeries) +* [sortBy](#sortBy) +* [some](#some) +* [every](#every) +* [concat](#concat) +* [concatSeries](#concatSeries) + +### Control Flow + +* [series](#series) +* [parallel](#parallel) +* [parallelLimit](#parallellimittasks-limit-callback) +* [whilst](#whilst) +* [doWhilst](#doWhilst) +* [until](#until) +* [doUntil](#doUntil) +* [forever](#forever) +* [waterfall](#waterfall) +* [compose](#compose) +* [applyEach](#applyEach) +* [applyEachSeries](#applyEachSeries) +* [queue](#queue) +* [cargo](#cargo) +* [auto](#auto) +* [iterator](#iterator) +* [apply](#apply) +* [nextTick](#nextTick) +* [times](#times) +* [timesSeries](#timesSeries) + +### Utils + +* [memoize](#memoize) +* [unmemoize](#unmemoize) +* [log](#log) +* [dir](#dir) +* [noConflict](#noConflict) + + +## Collections + + + +### each(arr, iterator, callback) + +Applies an iterator function to each item in an array, in parallel. +The iterator is called with an item from the list and a callback for when it +has finished. If the iterator passes an error to this callback, the main +callback for the each function is immediately called with the error. + +Note, that since this function applies the iterator to each item in parallel +there is no guarantee that the iterator functions will complete in order. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err) which must be called once it has + completed. If no error has occured, the callback should be run without + arguments or with an explicit null argument. +* callback(err) - A callback which is called after all the iterator functions + have finished, or an error has occurred. + +__Example__ + +```js +// assuming openFiles is an array of file names and saveFile is a function +// to save the modified contents of that file: + +async.each(openFiles, saveFile, function(err){ + // if any of the saves produced an error, err would equal that error +}); +``` + +--------------------------------------- + + + +### eachSeries(arr, iterator, callback) + +The same as each only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. This means the iterator functions will complete in order. + + +--------------------------------------- + + + +### eachLimit(arr, limit, iterator, callback) + +The same as each only no more than "limit" iterators will be simultaneously +running at any time. + +Note that the items are not processed in batches, so there is no guarantee that + the first "limit" iterator functions will complete before any others are +started. + +__Arguments__ + +* arr - An array to iterate over. +* limit - The maximum number of iterators to run at any time. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err) which must be called once it has + completed. If no error has occured, the callback should be run without + arguments or with an explicit null argument. +* callback(err) - A callback which is called after all the iterator functions + have finished, or an error has occurred. + +__Example__ + +```js +// Assume documents is an array of JSON objects and requestApi is a +// function that interacts with a rate-limited REST api. + +async.eachLimit(documents, 20, requestApi, function(err){ + // if any of the saves produced an error, err would equal that error +}); +``` + +--------------------------------------- + + +### map(arr, iterator, callback) + +Produces a new array of values by mapping each value in the given array through +the iterator function. The iterator is called with an item from the array and a +callback for when it has finished processing. The callback takes 2 arguments, +an error and the transformed item from the array. If the iterator passes an +error to this callback, the main callback for the map function is immediately +called with the error. + +Note, that since this function applies the iterator to each item in parallel +there is no guarantee that the iterator functions will complete in order, however +the results array will be in the same order as the original array. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err, transformed) which must be called once + it has completed with an error (which can be null) and a transformed item. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is an array of the + transformed items from the original array. + +__Example__ + +```js +async.map(['file1','file2','file3'], fs.stat, function(err, results){ + // results is now an array of stats for each file +}); +``` + +--------------------------------------- + + +### mapSeries(arr, iterator, callback) + +The same as map only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. The results array will be in the same order as the original. + + +--------------------------------------- + + +### mapLimit(arr, limit, iterator, callback) + +The same as map only no more than "limit" iterators will be simultaneously +running at any time. + +Note that the items are not processed in batches, so there is no guarantee that + the first "limit" iterator functions will complete before any others are +started. + +__Arguments__ + +* arr - An array to iterate over. +* limit - The maximum number of iterators to run at any time. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err, transformed) which must be called once + it has completed with an error (which can be null) and a transformed item. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is an array of the + transformed items from the original array. + +__Example__ + +```js +async.mapLimit(['file1','file2','file3'], 1, fs.stat, function(err, results){ + // results is now an array of stats for each file +}); +``` + +--------------------------------------- + + +### filter(arr, iterator, callback) + +__Alias:__ select + +Returns a new array of all the values which pass an async truth test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like fs.exists. This operation is +performed in parallel, but the results array will be in the same order as the +original. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback(truthValue) which must be called with a + boolean argument once it has completed. +* callback(results) - A callback which is called after all the iterator + functions have finished. + +__Example__ + +```js +async.filter(['file1','file2','file3'], fs.exists, function(results){ + // results now equals an array of the existing files +}); +``` + +--------------------------------------- + + +### filterSeries(arr, iterator, callback) + +__alias:__ selectSeries + +The same as filter only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. The results array will be in the same order as the original. + +--------------------------------------- + + +### reject(arr, iterator, callback) + +The opposite of filter. Removes values that pass an async truth test. + +--------------------------------------- + + +### rejectSeries(arr, iterator, callback) + +The same as reject, only the iterator is applied to each item in the array +in series. + + +--------------------------------------- + + +### reduce(arr, memo, iterator, callback) + +__aliases:__ inject, foldl + +Reduces a list of values into a single value using an async iterator to return +each successive step. Memo is the initial state of the reduction. This +function only operates in series. For performance reasons, it may make sense to +split a call to this function into a parallel map, then use the normal +Array.prototype.reduce on the results. This function is for situations where +each step in the reduction needs to be async, if you can get the data before +reducing it then it's probably a good idea to do so. + +__Arguments__ + +* arr - An array to iterate over. +* memo - The initial state of the reduction. +* iterator(memo, item, callback) - A function applied to each item in the + array to produce the next step in the reduction. The iterator is passed a + callback(err, reduction) which accepts an optional error as its first + argument, and the state of the reduction as the second. If an error is + passed to the callback, the reduction is stopped and the main callback is + immediately called with the error. +* callback(err, result) - A callback which is called after all the iterator + functions have finished. Result is the reduced value. + +__Example__ + +```js +async.reduce([1,2,3], 0, function(memo, item, callback){ + // pointless async: + process.nextTick(function(){ + callback(null, memo + item) + }); +}, function(err, result){ + // result is now equal to the last value of memo, which is 6 +}); +``` + +--------------------------------------- + + +### reduceRight(arr, memo, iterator, callback) + +__Alias:__ foldr + +Same as reduce, only operates on the items in the array in reverse order. + + +--------------------------------------- + + +### detect(arr, iterator, callback) + +Returns the first value in a list that passes an async truth test. The +iterator is applied in parallel, meaning the first iterator to return true will +fire the detect callback with that result. That means the result might not be +the first item in the original array (in terms of order) that passes the test. + +If order within the original array is important then look at detectSeries. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback(truthValue) which must be called with a + boolean argument once it has completed. +* callback(result) - A callback which is called as soon as any iterator returns + true, or after all the iterator functions have finished. Result will be + the first item in the array that passes the truth test (iterator) or the + value undefined if none passed. + +__Example__ + +```js +async.detect(['file1','file2','file3'], fs.exists, function(result){ + // result now equals the first file in the list that exists +}); +``` + +--------------------------------------- + + +### detectSeries(arr, iterator, callback) + +The same as detect, only the iterator is applied to each item in the array +in series. This means the result is always the first in the original array (in +terms of array order) that passes the truth test. + + +--------------------------------------- + + +### sortBy(arr, iterator, callback) + +Sorts a list by the results of running each value through an async iterator. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err, sortValue) which must be called once it + has completed with an error (which can be null) and a value to use as the sort + criteria. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is the items from + the original array sorted by the values returned by the iterator calls. + +__Example__ + +```js +async.sortBy(['file1','file2','file3'], function(file, callback){ + fs.stat(file, function(err, stats){ + callback(err, stats.mtime); + }); +}, function(err, results){ + // results is now the original array of files sorted by + // modified date +}); +``` + +--------------------------------------- + + +### some(arr, iterator, callback) + +__Alias:__ any + +Returns true if at least one element in the array satisfies an async test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like fs.exists. Once any iterator +call returns true, the main callback is immediately called. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback(truthValue) which must be called with a + boolean argument once it has completed. +* callback(result) - A callback which is called as soon as any iterator returns + true, or after all the iterator functions have finished. Result will be + either true or false depending on the values of the async tests. + +__Example__ + +```js +async.some(['file1','file2','file3'], fs.exists, function(result){ + // if result is true then at least one of the files exists +}); +``` + +--------------------------------------- + + +### every(arr, iterator, callback) + +__Alias:__ all + +Returns true if every element in the array satisfies an async test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like fs.exists. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback(truthValue) which must be called with a + boolean argument once it has completed. +* callback(result) - A callback which is called after all the iterator + functions have finished. Result will be either true or false depending on + the values of the async tests. + +__Example__ + +```js +async.every(['file1','file2','file3'], fs.exists, function(result){ + // if result is true then every file exists +}); +``` + +--------------------------------------- + + +### concat(arr, iterator, callback) + +Applies an iterator to each item in a list, concatenating the results. Returns the +concatenated list. The iterators are called in parallel, and the results are +concatenated as they return. There is no guarantee that the results array will +be returned in the original order of the arguments passed to the iterator function. + +__Arguments__ + +* arr - An array to iterate over +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback(err, results) which must be called once it + has completed with an error (which can be null) and an array of results. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is an array containing + the concatenated results of the iterator function. + +__Example__ + +```js +async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){ + // files is now a list of filenames that exist in the 3 directories +}); +``` + +--------------------------------------- + + +### concatSeries(arr, iterator, callback) + +Same as async.concat, but executes in series instead of parallel. + + +## Control Flow + + +### series(tasks, [callback]) + +Run an array of functions in series, each one running once the previous +function has completed. If any functions in the series pass an error to its +callback, no more functions are run and the callback for the series is +immediately called with the value of the error. Once the tasks have completed, +the results are passed to the final callback as an array. + +It is also possible to use an object instead of an array. Each property will be +run as a function and the results will be passed to the final callback as an object +instead of an array. This can be a more readable way of handling results from +async.series. + + +__Arguments__ + +* tasks - An array or object containing functions to run, each function is passed + a callback(err, result) it must call on completion with an error (which can + be null) and an optional result value. +* callback(err, results) - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the task callbacks. + +__Example__ + +```js +async.series([ + function(callback){ + // do some stuff ... + callback(null, 'one'); + }, + function(callback){ + // do some more stuff ... + callback(null, 'two'); + } +], +// optional callback +function(err, results){ + // results is now equal to ['one', 'two'] +}); + + +// an example using an object instead of an array +async.series({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + } +}, +function(err, results) { + // results is now equal to: {one: 1, two: 2} +}); +``` + +--------------------------------------- + + +### parallel(tasks, [callback]) + +Run an array of functions in parallel, without waiting until the previous +function has completed. If any of the functions pass an error to its +callback, the main callback is immediately called with the value of the error. +Once the tasks have completed, the results are passed to the final callback as an +array. + +It is also possible to use an object instead of an array. Each property will be +run as a function and the results will be passed to the final callback as an object +instead of an array. This can be a more readable way of handling results from +async.parallel. + + +__Arguments__ + +* tasks - An array or object containing functions to run, each function is passed + a callback(err, result) it must call on completion with an error (which can + be null) and an optional result value. +* callback(err, results) - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the task callbacks. + +__Example__ + +```js +async.parallel([ + function(callback){ + setTimeout(function(){ + callback(null, 'one'); + }, 200); + }, + function(callback){ + setTimeout(function(){ + callback(null, 'two'); + }, 100); + } +], +// optional callback +function(err, results){ + // the results array will equal ['one','two'] even though + // the second function had a shorter timeout. +}); + + +// an example using an object instead of an array +async.parallel({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + } +}, +function(err, results) { + // results is now equals to: {one: 1, two: 2} +}); +``` + +--------------------------------------- + + +### parallelLimit(tasks, limit, [callback]) + +The same as parallel only the tasks are executed in parallel with a maximum of "limit" +tasks executing at any time. + +Note that the tasks are not executed in batches, so there is no guarantee that +the first "limit" tasks will complete before any others are started. + +__Arguments__ + +* tasks - An array or object containing functions to run, each function is passed + a callback(err, result) it must call on completion with an error (which can + be null) and an optional result value. +* limit - The maximum number of tasks to run at any time. +* callback(err, results) - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the task callbacks. + +--------------------------------------- + + +### whilst(test, fn, callback) + +Repeatedly call fn, while test returns true. Calls the callback when stopped, +or an error occurs. + +__Arguments__ + +* test() - synchronous truth test to perform before each execution of fn. +* fn(callback) - A function to call each time the test passes. The function is + passed a callback(err) which must be called once it has completed with an + optional error argument. +* callback(err) - A callback which is called after the test fails and repeated + execution of fn has stopped. + +__Example__ + +```js +var count = 0; + +async.whilst( + function () { return count < 5; }, + function (callback) { + count++; + setTimeout(callback, 1000); + }, + function (err) { + // 5 seconds have passed + } +); +``` + +--------------------------------------- + + +### doWhilst(fn, test, callback) + +The post check version of whilst. To reflect the difference in the order of operations `test` and `fn` arguments are switched. `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. + +--------------------------------------- + + +### until(test, fn, callback) + +Repeatedly call fn, until test returns true. Calls the callback when stopped, +or an error occurs. + +The inverse of async.whilst. + +--------------------------------------- + + +### doUntil(fn, test, callback) + +Like doWhilst except the test is inverted. Note the argument ordering differs from `until`. + +--------------------------------------- + + +### forever(fn, callback) + +Calls the asynchronous function 'fn' repeatedly, in series, indefinitely. +If an error is passed to fn's callback then 'callback' is called with the +error, otherwise it will never be called. + +--------------------------------------- + + +### waterfall(tasks, [callback]) + +Runs an array of functions in series, each passing their results to the next in +the array. However, if any of the functions pass an error to the callback, the +next function is not executed and the main callback is immediately called with +the error. + +__Arguments__ + +* tasks - An array of functions to run, each function is passed a + callback(err, result1, result2, ...) it must call on completion. The first + argument is an error (which can be null) and any further arguments will be + passed as arguments in order to the next task. +* callback(err, [results]) - An optional callback to run once all the functions + have completed. This will be passed the results of the last task's callback. + + + +__Example__ + +```js +async.waterfall([ + function(callback){ + callback(null, 'one', 'two'); + }, + function(arg1, arg2, callback){ + callback(null, 'three'); + }, + function(arg1, callback){ + // arg1 now equals 'three' + callback(null, 'done'); + } +], function (err, result) { + // result now equals 'done' +}); +``` + +--------------------------------------- + +### compose(fn1, fn2...) + +Creates a function which is a composition of the passed asynchronous +functions. Each function consumes the return value of the function that +follows. Composing functions f(), g() and h() would produce the result of +f(g(h())), only this version uses callbacks to obtain the return values. + +Each function is executed with the `this` binding of the composed function. + +__Arguments__ + +* functions... - the asynchronous functions to compose + + +__Example__ + +```js +function add1(n, callback) { + setTimeout(function () { + callback(null, n + 1); + }, 10); +} + +function mul3(n, callback) { + setTimeout(function () { + callback(null, n * 3); + }, 10); +} + +var add1mul3 = async.compose(mul3, add1); + +add1mul3(4, function (err, result) { + // result now equals 15 +}); +``` + +--------------------------------------- + +### applyEach(fns, args..., callback) + +Applies the provided arguments to each function in the array, calling the +callback after all functions have completed. If you only provide the first +argument then it will return a function which lets you pass in the +arguments as if it were a single function call. + +__Arguments__ + +* fns - the asynchronous functions to all call with the same arguments +* args... - any number of separate arguments to pass to the function +* callback - the final argument should be the callback, called when all + functions have completed processing + + +__Example__ + +```js +async.applyEach([enableSearch, updateSchema], 'bucket', callback); + +// partial application example: +async.each( + buckets, + async.applyEach([enableSearch, updateSchema]), + callback +); +``` + +--------------------------------------- + + +### applyEachSeries(arr, iterator, callback) + +The same as applyEach only the functions are applied in series. + +--------------------------------------- + + +### queue(worker, concurrency) + +Creates a queue object with the specified concurrency. Tasks added to the +queue will be processed in parallel (up to the concurrency limit). If all +workers are in progress, the task is queued until one is available. Once +a worker has completed a task, the task's callback is called. + +__Arguments__ + +* worker(task, callback) - An asynchronous function for processing a queued + task, which must call its callback(err) argument when finished, with an + optional error as an argument. +* concurrency - An integer for determining how many worker functions should be + run in parallel. + +__Queue objects__ + +The queue object returned by this function has the following properties and +methods: + +* length() - a function returning the number of items waiting to be processed. +* concurrency - an integer for determining how many worker functions should be + run in parallel. This property can be changed after a queue is created to + alter the concurrency on-the-fly. +* push(task, [callback]) - add a new task to the queue, the callback is called + once the worker has finished processing the task. + instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list. +* unshift(task, [callback]) - add a new task to the front of the queue. +* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued +* empty - a callback that is called when the last item from the queue is given to a worker +* drain - a callback that is called when the last item from the queue has returned from the worker + +__Example__ + +```js +// create a queue object with concurrency 2 + +var q = async.queue(function (task, callback) { + console.log('hello ' + task.name); + callback(); +}, 2); + + +// assign a callback +q.drain = function() { + console.log('all items have been processed'); +} + +// add some items to the queue + +q.push({name: 'foo'}, function (err) { + console.log('finished processing foo'); +}); +q.push({name: 'bar'}, function (err) { + console.log('finished processing bar'); +}); + +// add some items to the queue (batch-wise) + +q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) { + console.log('finished processing bar'); +}); + +// add some items to the front of the queue + +q.unshift({name: 'bar'}, function (err) { + console.log('finished processing bar'); +}); +``` + +--------------------------------------- + + +### cargo(worker, [payload]) + +Creates a cargo object with the specified payload. Tasks added to the +cargo will be processed altogether (up to the payload limit). If the +worker is in progress, the task is queued until it is available. Once +the worker has completed some tasks, each callback of those tasks is called. + +__Arguments__ + +* worker(tasks, callback) - An asynchronous function for processing an array of + queued tasks, which must call its callback(err) argument when finished, with + an optional error as an argument. +* payload - An optional integer for determining how many tasks should be + processed per round; if omitted, the default is unlimited. + +__Cargo objects__ + +The cargo object returned by this function has the following properties and +methods: + +* length() - a function returning the number of items waiting to be processed. +* payload - an integer for determining how many tasks should be + process per round. This property can be changed after a cargo is created to + alter the payload on-the-fly. +* push(task, [callback]) - add a new task to the queue, the callback is called + once the worker has finished processing the task. + instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list. +* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued +* empty - a callback that is called when the last item from the queue is given to a worker +* drain - a callback that is called when the last item from the queue has returned from the worker + +__Example__ + +```js +// create a cargo object with payload 2 + +var cargo = async.cargo(function (tasks, callback) { + for(var i=0; i +### auto(tasks, [callback]) + +Determines the best order for running functions based on their requirements. +Each function can optionally depend on other functions being completed first, +and each function is run as soon as its requirements are satisfied. If any of +the functions pass an error to their callback, that function will not complete +(so any other functions depending on it will not run) and the main callback +will be called immediately with the error. Functions also receive an object +containing the results of functions which have completed so far. + +Note, all functions are called with a results object as a second argument, +so it is unsafe to pass functions in the tasks object which cannot handle the +extra argument. For example, this snippet of code: + +```js +async.auto({ + readData: async.apply(fs.readFile, 'data.txt', 'utf-8') +}, callback); +``` + +will have the effect of calling readFile with the results object as the last +argument, which will fail: + +```js +fs.readFile('data.txt', 'utf-8', cb, {}); +``` + +Instead, wrap the call to readFile in a function which does not forward the +results object: + +```js +async.auto({ + readData: function(cb, results){ + fs.readFile('data.txt', 'utf-8', cb); + } +}, callback); +``` + +__Arguments__ + +* tasks - An object literal containing named functions or an array of + requirements, with the function itself the last item in the array. The key + used for each function or array is used when specifying requirements. The + function receives two arguments: (1) a callback(err, result) which must be + called when finished, passing an error (which can be null) and the result of + the function's execution, and (2) a results object, containing the results of + the previously executed functions. +* callback(err, results) - An optional callback which is called when all the + tasks have been completed. The callback will receive an error as an argument + if any tasks pass an error to their callback. Results will always be passed + but if an error occurred, no other tasks will be performed, and the results + object will only contain partial results. + + +__Example__ + +```js +async.auto({ + get_data: function(callback){ + // async code to get some data + }, + make_folder: function(callback){ + // async code to create a directory to store a file in + // this is run at the same time as getting the data + }, + write_file: ['get_data', 'make_folder', function(callback){ + // once there is some data and the directory exists, + // write the data to a file in the directory + callback(null, filename); + }], + email_link: ['write_file', function(callback, results){ + // once the file is written let's email a link to it... + // results.write_file contains the filename returned by write_file. + }] +}); +``` + +This is a fairly trivial example, but to do this using the basic parallel and +series functions would look like this: + +```js +async.parallel([ + function(callback){ + // async code to get some data + }, + function(callback){ + // async code to create a directory to store a file in + // this is run at the same time as getting the data + } +], +function(err, results){ + async.series([ + function(callback){ + // once there is some data and the directory exists, + // write the data to a file in the directory + }, + function(callback){ + // once the file is written let's email a link to it... + } + ]); +}); +``` + +For a complicated series of async tasks using the auto function makes adding +new tasks much easier and makes the code more readable. + + +--------------------------------------- + + +### iterator(tasks) + +Creates an iterator function which calls the next function in the array, +returning a continuation to call the next one after that. It's also possible to +'peek' the next iterator by doing iterator.next(). + +This function is used internally by the async module but can be useful when +you want to manually control the flow of functions in series. + +__Arguments__ + +* tasks - An array of functions to run. + +__Example__ + +```js +var iterator = async.iterator([ + function(){ sys.p('one'); }, + function(){ sys.p('two'); }, + function(){ sys.p('three'); } +]); + +node> var iterator2 = iterator(); +'one' +node> var iterator3 = iterator2(); +'two' +node> iterator3(); +'three' +node> var nextfn = iterator2.next(); +node> nextfn(); +'three' +``` + +--------------------------------------- + + +### apply(function, arguments..) + +Creates a continuation function with some arguments already applied, a useful +shorthand when combined with other control flow functions. Any arguments +passed to the returned function are added to the arguments originally passed +to apply. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to automatically apply when the + continuation is called. + +__Example__ + +```js +// using apply + +async.parallel([ + async.apply(fs.writeFile, 'testfile1', 'test1'), + async.apply(fs.writeFile, 'testfile2', 'test2'), +]); + + +// the same process without using apply + +async.parallel([ + function(callback){ + fs.writeFile('testfile1', 'test1', callback); + }, + function(callback){ + fs.writeFile('testfile2', 'test2', callback); + } +]); +``` + +It's possible to pass any number of additional arguments when calling the +continuation: + +```js +node> var fn = async.apply(sys.puts, 'one'); +node> fn('two', 'three'); +one +two +three +``` + +--------------------------------------- + + +### nextTick(callback) + +Calls the callback on a later loop around the event loop. In node.js this just +calls process.nextTick, in the browser it falls back to setImmediate(callback) +if available, otherwise setTimeout(callback, 0), which means other higher priority +events may precede the execution of the callback. + +This is used internally for browser-compatibility purposes. + +__Arguments__ + +* callback - The function to call on a later loop around the event loop. + +__Example__ + +```js +var call_order = []; +async.nextTick(function(){ + call_order.push('two'); + // call_order now equals ['one','two'] +}); +call_order.push('one') +``` + + +### times(n, callback) + +Calls the callback n times and accumulates results in the same manner +you would use with async.map. + +__Arguments__ + +* n - The number of times to run the function. +* callback - The function to call n times. + +__Example__ + +```js +// Pretend this is some complicated async factory +var createUser = function(id, callback) { + callback(null, { + id: 'user' + id + }) +} +// generate 5 users +async.times(5, function(n, next){ + createUser(n, function(err, user) { + next(err, user) + }) +}, function(err, users) { + // we should now have 5 users +}); +``` + + +### timesSeries(n, callback) + +The same as times only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. The results array will be in the same order as the original. + + +## Utils + + +### memoize(fn, [hasher]) + +Caches the results of an async function. When creating a hash to store function +results against, the callback is omitted from the hash and an optional hash +function can be used. + +The cache of results is exposed as the `memo` property of the function returned +by `memoize`. + +__Arguments__ + +* fn - the function you to proxy and cache results from. +* hasher - an optional function for generating a custom hash for storing + results, it has all the arguments applied to it apart from the callback, and + must be synchronous. + +__Example__ + +```js +var slow_fn = function (name, callback) { + // do something + callback(null, result); +}; +var fn = async.memoize(slow_fn); + +// fn can now be used as if it were slow_fn +fn('some name', function () { + // callback +}); +``` + + +### unmemoize(fn) + +Undoes a memoized function, reverting it to the original, unmemoized +form. Comes handy in tests. + +__Arguments__ + +* fn - the memoized function + + +### log(function, arguments) + +Logs the result of an async function to the console. Only works in node.js or +in browsers that support console.log and console.error (such as FF and Chrome). +If multiple arguments are returned from the async function, console.log is +called on each argument in order. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to apply to the function. + +__Example__ + +```js +var hello = function(name, callback){ + setTimeout(function(){ + callback(null, 'hello ' + name); + }, 1000); +}; +``` +```js +node> async.log(hello, 'world'); +'hello world' +``` + +--------------------------------------- + + +### dir(function, arguments) + +Logs the result of an async function to the console using console.dir to +display the properties of the resulting object. Only works in node.js or +in browsers that support console.dir and console.error (such as FF and Chrome). +If multiple arguments are returned from the async function, console.dir is +called on each argument in order. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to apply to the function. + +__Example__ + +```js +var hello = function(name, callback){ + setTimeout(function(){ + callback(null, {hello: name}); + }, 1000); +}; +``` +```js +node> async.dir(hello, 'world'); +{hello: 'world'} +``` + +--------------------------------------- + + +### noConflict() + +Changes the value of async back to its original value, returning a reference to the +async object. diff --git a/node_modules/winston/node_modules/async/component.json b/node_modules/winston/node_modules/async/component.json new file mode 100644 index 0000000..bbb0115 --- /dev/null +++ b/node_modules/winston/node_modules/async/component.json @@ -0,0 +1,11 @@ +{ + "name": "async", + "repo": "caolan/async", + "description": "Higher-order functions and common patterns for asynchronous code", + "version": "0.1.23", + "keywords": [], + "dependencies": {}, + "development": {}, + "main": "lib/async.js", + "scripts": [ "lib/async.js" ] +} diff --git a/node_modules/winston/node_modules/async/lib/async.js b/node_modules/winston/node_modules/async/lib/async.js new file mode 100644 index 0000000..1eebb15 --- /dev/null +++ b/node_modules/winston/node_modules/async/lib/async.js @@ -0,0 +1,958 @@ +/*global setImmediate: false, setTimeout: false, console: false */ +(function () { + + var async = {}; + + // global on the server, window in the browser + var root, previous_async; + + root = this; + if (root != null) { + previous_async = root.async; + } + + async.noConflict = function () { + root.async = previous_async; + return async; + }; + + function only_once(fn) { + var called = false; + return function() { + if (called) throw new Error("Callback was already called."); + called = true; + fn.apply(root, arguments); + } + } + + //// cross-browser compatiblity functions //// + + var _each = function (arr, iterator) { + if (arr.forEach) { + return arr.forEach(iterator); + } + for (var i = 0; i < arr.length; i += 1) { + iterator(arr[i], i, arr); + } + }; + + var _map = function (arr, iterator) { + if (arr.map) { + return arr.map(iterator); + } + var results = []; + _each(arr, function (x, i, a) { + results.push(iterator(x, i, a)); + }); + return results; + }; + + var _reduce = function (arr, iterator, memo) { + if (arr.reduce) { + return arr.reduce(iterator, memo); + } + _each(arr, function (x, i, a) { + memo = iterator(memo, x, i, a); + }); + return memo; + }; + + var _keys = function (obj) { + if (Object.keys) { + return Object.keys(obj); + } + var keys = []; + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + keys.push(k); + } + } + return keys; + }; + + //// exported async module functions //// + + //// nextTick implementation with browser-compatible fallback //// + if (typeof process === 'undefined' || !(process.nextTick)) { + if (typeof setImmediate === 'function') { + async.nextTick = function (fn) { + // not a direct alias for IE10 compatibility + setImmediate(fn); + }; + async.setImmediate = async.nextTick; + } + else { + async.nextTick = function (fn) { + setTimeout(fn, 0); + }; + async.setImmediate = async.nextTick; + } + } + else { + async.nextTick = process.nextTick; + if (typeof setImmediate !== 'undefined') { + async.setImmediate = function (fn) { + // not a direct alias for IE10 compatibility + setImmediate(fn); + }; + } + else { + async.setImmediate = async.nextTick; + } + } + + async.each = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); + } + var completed = 0; + _each(arr, function (x) { + iterator(x, only_once(function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed >= arr.length) { + callback(null); + } + } + })); + }); + }; + async.forEach = async.each; + + async.eachSeries = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); + } + var completed = 0; + var iterate = function () { + iterator(arr[completed], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed >= arr.length) { + callback(null); + } + else { + iterate(); + } + } + }); + }; + iterate(); + }; + async.forEachSeries = async.eachSeries; + + async.eachLimit = function (arr, limit, iterator, callback) { + var fn = _eachLimit(limit); + fn.apply(null, [arr, iterator, callback]); + }; + async.forEachLimit = async.eachLimit; + + var _eachLimit = function (limit) { + + return function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length || limit <= 0) { + return callback(); + } + var completed = 0; + var started = 0; + var running = 0; + + (function replenish () { + if (completed >= arr.length) { + return callback(); + } + + while (running < limit && started < arr.length) { + started += 1; + running += 1; + iterator(arr[started - 1], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + running -= 1; + if (completed >= arr.length) { + callback(); + } + else { + replenish(); + } + } + }); + } + })(); + }; + }; + + + var doParallel = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.each].concat(args)); + }; + }; + var doParallelLimit = function(limit, fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [_eachLimit(limit)].concat(args)); + }; + }; + var doSeries = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.eachSeries].concat(args)); + }; + }; + + + var _asyncMap = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (err, v) { + results[x.index] = v; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + }; + async.map = doParallel(_asyncMap); + async.mapSeries = doSeries(_asyncMap); + async.mapLimit = function (arr, limit, iterator, callback) { + return _mapLimit(limit)(arr, iterator, callback); + }; + + var _mapLimit = function(limit) { + return doParallelLimit(limit, _asyncMap); + }; + + // reduce only has a series version, as doing reduce in parallel won't + // work in many situations. + async.reduce = function (arr, memo, iterator, callback) { + async.eachSeries(arr, function (x, callback) { + iterator(memo, x, function (err, v) { + memo = v; + callback(err); + }); + }, function (err) { + callback(err, memo); + }); + }; + // inject alias + async.inject = async.reduce; + // foldl alias + async.foldl = async.reduce; + + async.reduceRight = function (arr, memo, iterator, callback) { + var reversed = _map(arr, function (x) { + return x; + }).reverse(); + async.reduce(reversed, memo, iterator, callback); + }; + // foldr alias + async.foldr = async.reduceRight; + + var _filter = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.filter = doParallel(_filter); + async.filterSeries = doSeries(_filter); + // select alias + async.select = async.filter; + async.selectSeries = async.filterSeries; + + var _reject = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (!v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.reject = doParallel(_reject); + async.rejectSeries = doSeries(_reject); + + var _detect = function (eachfn, arr, iterator, main_callback) { + eachfn(arr, function (x, callback) { + iterator(x, function (result) { + if (result) { + main_callback(x); + main_callback = function () {}; + } + else { + callback(); + } + }); + }, function (err) { + main_callback(); + }); + }; + async.detect = doParallel(_detect); + async.detectSeries = doSeries(_detect); + + async.some = function (arr, iterator, main_callback) { + async.each(arr, function (x, callback) { + iterator(x, function (v) { + if (v) { + main_callback(true); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(false); + }); + }; + // any alias + async.any = async.some; + + async.every = function (arr, iterator, main_callback) { + async.each(arr, function (x, callback) { + iterator(x, function (v) { + if (!v) { + main_callback(false); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(true); + }); + }; + // all alias + async.all = async.every; + + async.sortBy = function (arr, iterator, callback) { + async.map(arr, function (x, callback) { + iterator(x, function (err, criteria) { + if (err) { + callback(err); + } + else { + callback(null, {value: x, criteria: criteria}); + } + }); + }, function (err, results) { + if (err) { + return callback(err); + } + else { + var fn = function (left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }; + callback(null, _map(results.sort(fn), function (x) { + return x.value; + })); + } + }); + }; + + async.auto = function (tasks, callback) { + callback = callback || function () {}; + var keys = _keys(tasks); + if (!keys.length) { + return callback(null); + } + + var results = {}; + + var listeners = []; + var addListener = function (fn) { + listeners.unshift(fn); + }; + var removeListener = function (fn) { + for (var i = 0; i < listeners.length; i += 1) { + if (listeners[i] === fn) { + listeners.splice(i, 1); + return; + } + } + }; + var taskComplete = function () { + _each(listeners.slice(0), function (fn) { + fn(); + }); + }; + + addListener(function () { + if (_keys(results).length === keys.length) { + callback(null, results); + callback = function () {}; + } + }); + + _each(keys, function (k) { + var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; + var taskCallback = function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + if (err) { + var safeResults = {}; + _each(_keys(results), function(rkey) { + safeResults[rkey] = results[rkey]; + }); + safeResults[k] = args; + callback(err, safeResults); + // stop subsequent errors hitting callback multiple times + callback = function () {}; + } + else { + results[k] = args; + async.setImmediate(taskComplete); + } + }; + var requires = task.slice(0, Math.abs(task.length - 1)) || []; + var ready = function () { + return _reduce(requires, function (a, x) { + return (a && results.hasOwnProperty(x)); + }, true) && !results.hasOwnProperty(k); + }; + if (ready()) { + task[task.length - 1](taskCallback, results); + } + else { + var listener = function () { + if (ready()) { + removeListener(listener); + task[task.length - 1](taskCallback, results); + } + }; + addListener(listener); + } + }); + }; + + async.waterfall = function (tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor !== Array) { + var err = new Error('First argument to waterfall must be an array of functions'); + return callback(err); + } + if (!tasks.length) { + return callback(); + } + var wrapIterator = function (iterator) { + return function (err) { + if (err) { + callback.apply(null, arguments); + callback = function () {}; + } + else { + var args = Array.prototype.slice.call(arguments, 1); + var next = iterator.next(); + if (next) { + args.push(wrapIterator(next)); + } + else { + args.push(callback); + } + async.setImmediate(function () { + iterator.apply(null, args); + }); + } + }; + }; + wrapIterator(async.iterator(tasks))(); + }; + + var _parallel = function(eachfn, tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor === Array) { + eachfn.map(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + eachfn.each(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.parallel = function (tasks, callback) { + _parallel({ map: async.map, each: async.each }, tasks, callback); + }; + + async.parallelLimit = function(tasks, limit, callback) { + _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback); + }; + + async.series = function (tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor === Array) { + async.mapSeries(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + async.eachSeries(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.iterator = function (tasks) { + var makeCallback = function (index) { + var fn = function () { + if (tasks.length) { + tasks[index].apply(null, arguments); + } + return fn.next(); + }; + fn.next = function () { + return (index < tasks.length - 1) ? makeCallback(index + 1): null; + }; + return fn; + }; + return makeCallback(0); + }; + + async.apply = function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + return function () { + return fn.apply( + null, args.concat(Array.prototype.slice.call(arguments)) + ); + }; + }; + + var _concat = function (eachfn, arr, fn, callback) { + var r = []; + eachfn(arr, function (x, cb) { + fn(x, function (err, y) { + r = r.concat(y || []); + cb(err); + }); + }, function (err) { + callback(err, r); + }); + }; + async.concat = doParallel(_concat); + async.concatSeries = doSeries(_concat); + + async.whilst = function (test, iterator, callback) { + if (test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.whilst(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.doWhilst = function (iterator, test, callback) { + iterator(function (err) { + if (err) { + return callback(err); + } + if (test()) { + async.doWhilst(iterator, test, callback); + } + else { + callback(); + } + }); + }; + + async.until = function (test, iterator, callback) { + if (!test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.until(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.doUntil = function (iterator, test, callback) { + iterator(function (err) { + if (err) { + return callback(err); + } + if (!test()) { + async.doUntil(iterator, test, callback); + } + else { + callback(); + } + }); + }; + + async.queue = function (worker, concurrency) { + if (concurrency === undefined) { + concurrency = 1; + } + function _insert(q, data, pos, callback) { + if(data.constructor !== Array) { + data = [data]; + } + _each(data, function(task) { + var item = { + data: task, + callback: typeof callback === 'function' ? callback : null + }; + + if (pos) { + q.tasks.unshift(item); + } else { + q.tasks.push(item); + } + + if (q.saturated && q.tasks.length === concurrency) { + q.saturated(); + } + async.setImmediate(q.process); + }); + } + + var workers = 0; + var q = { + tasks: [], + concurrency: concurrency, + saturated: null, + empty: null, + drain: null, + push: function (data, callback) { + _insert(q, data, false, callback); + }, + unshift: function (data, callback) { + _insert(q, data, true, callback); + }, + process: function () { + if (workers < q.concurrency && q.tasks.length) { + var task = q.tasks.shift(); + if (q.empty && q.tasks.length === 0) { + q.empty(); + } + workers += 1; + var next = function () { + workers -= 1; + if (task.callback) { + task.callback.apply(task, arguments); + } + if (q.drain && q.tasks.length + workers === 0) { + q.drain(); + } + q.process(); + }; + var cb = only_once(next); + worker(task.data, cb); + } + }, + length: function () { + return q.tasks.length; + }, + running: function () { + return workers; + } + }; + return q; + }; + + async.cargo = function (worker, payload) { + var working = false, + tasks = []; + + var cargo = { + tasks: tasks, + payload: payload, + saturated: null, + empty: null, + drain: null, + push: function (data, callback) { + if(data.constructor !== Array) { + data = [data]; + } + _each(data, function(task) { + tasks.push({ + data: task, + callback: typeof callback === 'function' ? callback : null + }); + if (cargo.saturated && tasks.length === payload) { + cargo.saturated(); + } + }); + async.setImmediate(cargo.process); + }, + process: function process() { + if (working) return; + if (tasks.length === 0) { + if(cargo.drain) cargo.drain(); + return; + } + + var ts = typeof payload === 'number' + ? tasks.splice(0, payload) + : tasks.splice(0); + + var ds = _map(ts, function (task) { + return task.data; + }); + + if(cargo.empty) cargo.empty(); + working = true; + worker(ds, function () { + working = false; + + var args = arguments; + _each(ts, function (data) { + if (data.callback) { + data.callback.apply(null, args); + } + }); + + process(); + }); + }, + length: function () { + return tasks.length; + }, + running: function () { + return working; + } + }; + return cargo; + }; + + var _console_fn = function (name) { + return function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + fn.apply(null, args.concat([function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (typeof console !== 'undefined') { + if (err) { + if (console.error) { + console.error(err); + } + } + else if (console[name]) { + _each(args, function (x) { + console[name](x); + }); + } + } + }])); + }; + }; + async.log = _console_fn('log'); + async.dir = _console_fn('dir'); + /*async.info = _console_fn('info'); + async.warn = _console_fn('warn'); + async.error = _console_fn('error');*/ + + async.memoize = function (fn, hasher) { + var memo = {}; + var queues = {}; + hasher = hasher || function (x) { + return x; + }; + var memoized = function () { + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + var key = hasher.apply(null, args); + if (key in memo) { + callback.apply(null, memo[key]); + } + else if (key in queues) { + queues[key].push(callback); + } + else { + queues[key] = [callback]; + fn.apply(null, args.concat([function () { + memo[key] = arguments; + var q = queues[key]; + delete queues[key]; + for (var i = 0, l = q.length; i < l; i++) { + q[i].apply(null, arguments); + } + }])); + } + }; + memoized.memo = memo; + memoized.unmemoized = fn; + return memoized; + }; + + async.unmemoize = function (fn) { + return function () { + return (fn.unmemoized || fn).apply(null, arguments); + }; + }; + + async.times = function (count, iterator, callback) { + var counter = []; + for (var i = 0; i < count; i++) { + counter.push(i); + } + return async.map(counter, iterator, callback); + }; + + async.timesSeries = function (count, iterator, callback) { + var counter = []; + for (var i = 0; i < count; i++) { + counter.push(i); + } + return async.mapSeries(counter, iterator, callback); + }; + + async.compose = function (/* functions... */) { + var fns = Array.prototype.reverse.call(arguments); + return function () { + var that = this; + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + async.reduce(fns, args, function (newargs, fn, cb) { + fn.apply(that, newargs.concat([function () { + var err = arguments[0]; + var nextargs = Array.prototype.slice.call(arguments, 1); + cb(err, nextargs); + }])) + }, + function (err, results) { + callback.apply(that, [err].concat(results)); + }); + }; + }; + + var _applyEach = function (eachfn, fns /*args...*/) { + var go = function () { + var that = this; + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + return eachfn(fns, function (fn, cb) { + fn.apply(that, args.concat([cb])); + }, + callback); + }; + if (arguments.length > 2) { + var args = Array.prototype.slice.call(arguments, 2); + return go.apply(this, args); + } + else { + return go; + } + }; + async.applyEach = doParallel(_applyEach); + async.applyEachSeries = doSeries(_applyEach); + + async.forever = function (fn, callback) { + function next(err) { + if (err) { + if (callback) { + return callback(err); + } + throw err; + } + fn(next); + } + next(); + }; + + // AMD / RequireJS + if (typeof define !== 'undefined' && define.amd) { + define([], function () { + return async; + }); + } + // Node.js + else if (typeof module !== 'undefined' && module.exports) { + module.exports = async; + } + // included directly via

                  5OONuA?9Iq6T2!C~+h^9WEbT8Yd3~;$Ax|JA{$I?$;h~~WH&h0;>;ml4} zo?deXx~``Y>4-f0jSw{{ERuq$9C4NIrKU2uBrjqYrx_Kn^=MQKEf8Wi>Q3MRVd|$% z!mG6Ki1k1_mBKw+%-eKVs?5Fa?@LBzX_g#EEU1qr=OIuia(6KRbjcm~KQDDeibFtS ztXW>>naVXr&)N-rvsLMRA!o4A3L8zG=BA_(#IVL<*%-ng>$h^BUNFQl&Pn5)>}FK& zYSgQDINaE6z*=Whx*fQ8(IM3}a-#zvWrt61spG6yt!E|r_0N3!@RCp38bF%H$XT|c z)*)l^97Wm`;aLgq3l*Q?(rHph00&%xpn^arX~ueEx8sfgaD#PdTkKWYsF)EEpJ7il z1~LGDgtl;h1J~u-ipe4@oJQ$})2N=|dcRZo#Upx#bbNJD(J_PmpyJmwwV;%N%__q3 zC!4puAz-;_VEbrl1hPZs4>1+7g28eK7$o4506qF+fS%77a7si%LwnG_(tc)gYOd^* zx@st|GFzIWx-HQ8FHZFcWnVFU3}Jlb!Ni1;dlIWu$%d#&i)uF8Q)DZ_Ab?>wb5E9c z>fU7AY;(}Yi&<3h)Wv9)DsfMd=9+3!R!57>50!JcA~x^5$`&|Qv6x|2xgqWNW+aJ; zB0x8vt@T;-`^^3}$&w>Y^;1iJwW_sPE3LJ9dh<_wx7-C3b{l=No^+(8X!b-Mr=e(( z!@X_teW9L zWUq$4s)6X~E7r{*nwF}fG>UOmPLY_>dSx>d>JQwMu}y=As3}*9%w!R#AGVsuq9&Cd z==hAEr;@BX@00qUTJvK^XqzpPrl(WZTjGpc7`AEH;mDDjJ7bL*OF!KJWqK7H1LLO9 zDr@c|sJ~5jTQnOjx$0L=`7hvKmi&~^QqbKkpVGVS#+6~a+-l~KMN^D1i6RUYVhx-r z1&{F(coz{)m|!)Vn295R>F(;-7?*~D0CCsf(N>;+_&Cxs>-%j|M|HBo)kv_(OD~@c zLpj^z$~NP8!W7semz3(!wp$ z$U0?Rn8>F&#??K3d}-INT*#&en$5#CjeOK3bo;AMr+g~tO?9S_!+5<|D$H*j)KzlF zIyU4g%0r+eVD}C62aGy3-%aFHhPZ5WKK$10c1u5KW@EP+gm;oi211X1cMU_smWQ+54E4so>5-=U~9ArEg5)^gtONZNYyaHdM6X=0X&t>KwM zxmH#xKqs;60SC7ljCs^qXV#_NyCJwldk;Ew7Ko^&)sz=hxaxa`DJm;2(R@s^Cc)+- zl0jk=M7x2=0~zbV9q|Maa)dNQ5Oh2i-ec<>Q_O3PTdnGhT&|`UT2v)z(lk;$xc3&u z2_P{iyA#)_60@0{J;MJ0ltl^-Eg`?!irFr-^miHvu5^*sPe(puYK08(Oc-UAhfs2Z zw@!nK9wZU5`Xec|tsoI_r5+)*IMsZx(^V$ZM@dsfUsFpx!kN_?vDs1AFpj`R6V=$T zJ=l^(!&2_+y};@PxNGP0RpP`JMu11YYP6Qg&vWz78pt)^KA?TLNhjSA38>Xpwb*3Y zFPKz&?N)E_;x5pq0!py5TVCgGj#UgK2;(Y>OJ}xo+pc;Hb?e4)H!9LNr5b)ag`MPd zq6Q75G?Sd*0hVRylbm%KAD<0lWYY>AqAf3X(zmPJazd9FE>xvrlXz(&o++7`c8n0O z8fPSZ;f>uuGOSn=?#iZS1`0Ux(x#-#NmDdXrA$m6c8;6JzW{;avL?vi%`3H_+H|g> zu7-i*qSSPg%?-zBr#@tJKnckU>GOs%ahwtu0;fWVkA({8(Zb3-sddhi)i)Zr>#ai5 zbC!-O$u$j*{{UA7ViFmiS&}%Vf>HvpV(_TJIA!U?o?Jvfeu_QY97A}aZl9`q4gUR4 zaMo2c)HgaLcBYzYm8d94dN}s}@2ds`mdYnjzqk$wVHFz>GamL;7M6S{@yUM*TKkz+ z`VB_~Y&vewAz4n)gKuQo2gnx znj`?Y^0yYiJu`p@U!NQKWUhE3H!ZpSs5C9$B-(b@U1q6O^XaC(z5zX(Ytoz%-y`S6 zqYF{sI53gIHBoJ5Fxl{Wr*9DzR()~H%Dd$aIkdDY9Sk>kDrvr_%ahBHdws+6^qwcktTdp*88qWUnPYoQ`D=Jh)&TdhJaZ1E00FFIa%1THcletbZqZQMp3rISt)OpMt-4u4W zOe|GqXs$0)8tn4kmYd92Q~|YpCvx;2;Ag4p!gdfi+5Z3~I#|NU1-~?croz=%w|W|u zm`tl9M^wRP6P%egp;462VUpPIz~>E7qhr&C+N;JTg~Xe6{Dg;@FjUj&YF3y@iUyF}qx4JTnse~=*aN-^E#fW!fe{{Zv;Tmnq$uUTtdPYng4|zHCEANzDHOdrl;YlmV%Y8H1u!@ z+sz9+tt%;U67MR5p=TS20|v}9Nv1&Je#oxaKl++a{5S5Mbf+?{mWoIxuCJr?k_w81 zV9D5$6qAy3)4vgOA37}74A2QgRp;%GP}JM)7TZM)(uUtOHMKJ8L*-G`vNC{@DIkcK zdogywJ68%jo0@JKcTsgB80XEx&zpLiMBi_6+$`6wUQ%6Jc_`W|P4!kEA|(;WpETeC zszBOEDpx&o#)Dik-Df$j4ls*82)T2lxzDfe<4`V3-5Rlt7O|2>_KuS+AyjXDk%CYj)AfC{;2jJPBLrN?<_tM^Zq`oMU5>m zJ};;8s$Yxm7m)J)icLGGOqG|}06>r-b_~oB6+rvaGZ3nyxj#-aD^zwchKn$JlgV%4 zFwMfZynWs8=9{@+;I~HGG;-=rcw1)Gda~shtFET1sgj0cgo9l-6t z99q{>!vJ2x?~mhcB1EWEsaqEE+71@^``dG`AtL49DYU+b)t3!t%G>2{*!HR^lBY@B zXL^c8l33YdG0x=65CmkY-Z9uO3l3@3s_Lw4W%i%QuYG`Qf*5{gzmV{xTs;odf>A@fgBSryNrWwIKlN@y&pM@`Qd&Pp}@wNN5 zVaa0sZMlRN2;prw@K|cAeEmFBP$8V zn5?6yVeSD1NFamMaUoQPWp&gICb(v8l74Ahjq=HEx?53Zr!3LPrUKPbFaYg&e~AZR zJD&dlJ}SgCNPBnssnK(;$8D!XAZ6IwNx}IOgTQFDfx`DaJ-A6Nkn9SipmVqq7-W8& zAegCesGc~P7HMKrleHve7|(2Hfd2s6R?b}14;1r6iwqLFAW-mU)9;>#`}m9Q3VbmA z<{}n`gIm*CZWkRLd7!t*u+s*jtf8lxTG42{{NHPuW-7 z4rl6G5BxXonC*Ok=3EU}YBWV$^3?GLYMyEw>+C6Q7BH7Bsp-Ijoj;6Wm!yRf<3r2W+wS1NrfW zT%X`?Vvcgs^8&XM9t2h5%&A-{^1pJ*nHd3gU%jo)sgK=a#VfT<7qdKn;`if zE~pD>Wfsn3%Tw!bB?^xd94>fX-$_^7T;8RyStWY9ma3$P8C~Q%m;g6_f#Wsiq>65I zg?#|RbG5K}DmSZniDdB;HBOk*HJ4i}#a~Zxt*?u6K~GB`m?x=VtO0F@%Z#3-u<`j-y72aJ!}lsgfMbmZ$!GiX?c>l)p~Y@rlEvMJ50fe7-n2|9lwzO01i27mn5#8 zngo{BL2d)ZjJQypVdb=~nX0 zk35n{j8%`CvZ=wxLyn{BI&eC zZGA@it5>DDr4)Bq;-Wu7zYkK-XYVe=cm!;ZW?%g4H31CbS4B+$xJDh;ub3H<==P-CKpASusGX1tp_FokGlU?asFE2TFW~r{f z)W#rRDN8nROUT5Zsb*#%btQ=7mKax(d&8;IiCsypMWZ;@HQFxTK|V=F`Pdu#h4`KYHo`V`#s2VwOpRY`3j9{7FLjOPuimb*$^(qw5C zN@rG$4mT2{4l1umzN-Z>E+h!zc2mMu6xiofFwhB;uvAAz=o@D!thW6fYLHD^TO(aB zwcz!tk$o}6lm3Yb+N0>r_nh(USUe!YurvLRzW6UK#o|sXp{cO29KR=ZUHnsDq`6%H zc?(lhws&{jexLmLaYtyr!Kkj!Wyw`)u4iIoa#wfola(Xbam*9C=oEt8a};*?A&70- zxH|`9?~~K~c)g|sDhp)FSMik-lIjt`_cDb)rZ{p*Pn0Iw3Mk-@Fp{yisYvUC#RAIG zq}p>)U$p!p8&%S}j+{y6wIp%}rg#3ai24cok)N*A6QWZ$nU5o=OAUi_< zeJlV6BoWx~^y-&*4dp@XXoodHHC^KSq%@*d+iBwv)HBk}J1?4GR$O6+-SuRzP)2^Z z;h9=V4cS{#fnXVqs4B9QQQv4ALHTsy)E4_)$*lf-k<-&o?w|uzNfkn<&wNO&gPaVE ze7IUA5{p!tR_#435*rv-c-7fj-DHadjP_x;etmdwLxhC`V+ZbsS!1(q(!09k_8(8> zz$>6KVM=tBZ1720Pe>AK`KjDfz~p-0*a7Z-pFD7~hmRJDw>{LV7gI3n5!HJJv#hO# zp=M>2y0WsoF_51;BLXr$M07ug778@lLxV((5U$4JT*p&=M-c5nC+?f|E%JMu2~Sh- za)@6jVWFmof)r(mjwL6d_dH)DpkM_kJZ0HoRq8yYCj|jwTRc?iEo4TwKK)d?_f?W~7C?X64b1wQK4VoX)k+|- zTRsY!4=jW;)PbS1h?EzE&04)>Y8uKG=gX_^(3vD%4qSShZp?1k4 z$rS`F4pVBWCqF_->GA}gLqNP7X-rUpr4(Lf}S0X!!V!I+yVHKpbP=$4xOkyO<7DmK;}*ru}IWsFNT4Fv*8 z3|amal1UY$?0s8QA7SoBb#}1B$Q@B^!#=2*Y;%VYE%YmzHtVF6{Z&N0I;r4*NI`11 zKBB6qjlCNb9;*@B!}9mx%ZW_^ZqpSIuA+vju40tb(s{qVEI}*PS06HVoP9Wfk{~IF z3VCwo8{F7ahLxd_Olcq;>v6da3w+JL$6qu5akuP1qTaPz8TzE^382Y!OZ8NoMPW7Ueq%;pr6oAT$CrK22;gN;_^&gK9x=7J(p5-Mn zp}LLabYK~>4_uOc_*2bB5Z_s8Yi5+Eg}y&^MC?@{2cQ6Cl5zDI`SDkF5rY!_!fLWv zr@BW_mbgvA;WF&o0|Vu$$Ek@pQb_uA{#OfVhIyIIx;@eI9>J`mrWMUyYPm@o39b~Z ztW28*;?bW=jOXNW@5OZK3ShJ=@feq49o{$z$f2V}a$T8%2)2GRp-qatP>3dQt9ms z^$P6QYN@2Dm&+q;B0^Y}C$i{ZCVSng|pL z72A0S)IIwBdhyR=9t+@Vx*Q`2WTC8Z0T3i(cU|gw{{YjB=zxx0L;aH40>h?xd8#>; zbVXaO&hVOE*)flNu_#n|Rxg*B@&HfD5%TI4M~wMNjR5L@i21Eb6khfc!JscQrdIy| zGi~gzh09fG{{WAi%#^Z9TP)MYBxBG4)Q*D~=s44E1(7ajCz{1Qr&vQ-P_zw!Bj~?4 zkktqfZ$6HUxbL5*1A?zfyyH_O#j*pD+pyszoh|bdWRM>5Rv|e(x5mT!;{)^I!eW-k zCg{N<42QAz;@y-{PeNa>mg}rEwtIwhbrr1`5=x=Eh4#-)#1n#j`g`$hK`rU*s@Pzn zJwGSxm3In@rF8;aE|pTXMD;a8dl?wyl~ILWr#%M(5K6XTNU3x+I*cN!51_{lmx^q~ zEE-apFT66tx%S~gS*)~H=vx)ZSK{qdb%b>ud?CNTg$dK0qfgRXqYzQiQ_(^X`M6_M z1M&lh3M5@j?2!eMGyAi&XDqn<_?S*qt)!va($p=<1$H%sP1{Y_sC1QXukWg;|R%Ml;la zN`)C65p&l(R^QvF$`$e6Re-29(zULa8R{{$UCZFPWA!ASr2Nkubiflbk47+W`J(P+pZ!O+fbgxSVk4szol4p z1Tf;1)@#QRK1Ro=`Hv(?t{I1W4+9>0gUI}kRe5zZm%57dp53P{x{iue-5pI;Cz~W* zrVSAxhuvV^56`|a$4Jmfv4zSP2AC^{CCmDl=jF#fx>d0T)&6`W$;#82Dyrzlf6Ag^ zA7Au~`^5c9mHz;1gp%J&bN>J}lq7UH&vA|>9HK&)P`ygMJ3~8DR7O%rB~hKO4p%=h zoDK?WWGV}y>e^cCh1%IkT^I_rFr>RfWGN%4{EkQEz|LuD%2dGwNK0doV+DafE+U;~ zN-$g!PtQCuaJHhLZ&1h8f5(PSwm}}&^nh@Bk-|z8g4)UEqcRB)uXzRtIl<~Ul%*1$ z;I_3y2lp{MAoP@%0R2vSjw2~Vs-4arOjljCRdn_%Ty(EA%_T>la56^j-C31(lBAQ^ zHa>&55tQQEsD-nay3dzT)LlN(qqNb$JlWj5j)SnyHuvm5LBvQ0P^JoHy6ai1F6mnu z(j&43sQ7=~tjr0+;9~@WGvBDs3|gifH%epX9yfWWqB6(*AQCU(k%Nz}GsH6SPtdFP z;bWTi&UEOyTMb<`ZB_Et5|~z7sa~PYGVUTd5lJkhXX z0_O{#Rf$^!@IYY@5EI5-`$X30Iyy}Y%nN?2iki7;E-P)Ks4)4j3riY`qx+}IhBzJe zu-%j^!&b!ijmj02FwUgx&xK4ZGzoFKQNl=7c}DP0u*v@b59h!v8Jq$=<{C=&@kV2y zs;zQH`msog0KtJ-B)L=m@||7D+PlY0ou>onc<0wgDTh4|^Wi5-Y3dr5YI?L8dTA11 zK41`k!};)&C6!dBmg7|j1(FHgH3PmfcAwK6I!V&eM_W-<5+gVu{lNW5{67zVCJ6;Z zfNZU=EmYI!${KN0wJ!$cV5^TWB#^o8e-q!Y%Za?^Ih8;~l$;Wyrd0Rz@e3!>edd#% zq@Qz+8aN~t$j(otPJO@U!xbq?mUoLRp>gtI+l2`ww(9Bp;!qWn1FU^NEO6Y@rv()t zZz#csK)dmg`F7$d(j!3i5|T-Xp7}kvkWtYgzUfJ>wz{fSDg^PA+|daa2j;8@KbYb~ zN^KQo=4T{f<>eGrQ{Ad1dYLxIPvu9DxGY_;H*M%ZIKdLIRiMfkynkk$jJ{NC zz%r&h#UN+ZgM-lIaT!z5ST78EHkVS}#bDNUeI+Fk^Ch^jnd?MjsWHH#4A=(;cmVg$ z8F<$Wxl3n;!g}hoFon%_W*>bK&zX^H%daH4qs_Z@$u%B}thLFeY3p^ZQI_>bN$~+( zK!5;`BTKu~SnT!$kV(O_D@2(hcP8<)sxdV?$H-^{kO6bynbFwpI4lWJdJ;2(kET!R ze!OTPl;2Ep{#a>knyTY*qqXU&nqMxmR(2+M$pV;#Q?^F?z#fGGInPcGqeDurATrZ`rdHjS$wVDT%LBfB{+t9(p%@jB@H?Zl^|J6egQ(<& zrm`E7*|hb$cH(Op15H%pun?q?gwOHH4?>(uknsb}H9$M36TquCs4ufebd*ISg*|bc zalQZ=u5!m!&hBpOy;-X@7s2Xl{Y~fKRaOXF5mQqFpp=FL#BnIjFp4`wGpvXJv3#T-*ST+e>n5`@RKLaCvs338Nx}O z-CG&_&khPmgGJ0ry){WI(A*=6vPIYwda^yvJ7*n1KKSBA@F6%7QEQi+(4*A!a8p)Q zg}8u2KHaL|b|iZ?JB}jPN{g5QmZ|!yCIMV$*zoEQy%{I*_8c*?No_oBA?>(<*dE+8 zl<=LXt*rzgp=lM)PJTo1_Th?nPc-z~@e88H#~`VE5U2Cc3dturOJ_tAG8V^K2k8fkbQItjG z)r$2tu(mAr6JHC;sv)j{e4^PHExFJhxadwkd=FafAQ)EDaBHN6GVx!kZu9DSELGPk zYV|@Y8Y^vD%}Er5Y#?lRj7T@#!Pv zPX&Nb#ak^1btMlfY_t}QGfjB6H59bh8WV3VOC(}Ol18g?3bQF-LyVre9^7;^^D=`# zZ1U^HbJYtSS8W-wMmJr~cgyW8W zsSa^15Ens65YQZCqt_~`g{gUS9U}ZSEY#6W?V+w$%C zamfGxfV$F4jFgz3ow#(%J>G@E>IVrVvZFHDsN@}dsbz$L><-so?|;*TnQfyUXjSsn zwt>`x(}qr#p%I?tN8!`;;w4BGvX1jD9ZE?XIuvh9sUe0v_(@8iS-IDLu|W(pwe3?9 zHhj9M)sT;uZ19AHW+$@atK^=T&VF1X=WLiYv2|wY z8O=0pBwkAtQqh(NYY~#9`{St3(~AnFD2}+mrK1c6;nQjB`f&(PD|x!_Rsc#t>QR>& z{PV(u@|8nzBMj*#&7nf7cON5@f#0VIB^1`W9^ZevwN*tb$XQi#@q&5`VCO%l50n(j zJvT1x^d$LIK@Ktk#yfoa0m3W^2PVmM{1nAlz)GIIv7R7UqzVe^3jI%O7YZk$t`zc2 z#7tl;lCFLBlYmAtK3`5ES_-o@p)y*Mw_8?KFvU}DJxWK$~oh!IMU*cRQMDSv49 zc57pq9{&I;!GLvBE_ghHqu;7FbF-M5Pe*dzqwLLle1dkOG=w0QP2gbQQ~4_v?2H1y z;2phG04o0g={}>{7~)T#;>z#-S9ZeU#(~s-YoGPJtG!)ql=nNlmfbyWt3x$3S89bx zq(X8EQmV9pPq8SfM{bzl?(h>RD1^S>5?XGW9*_}GsRbNMBqM76?y_J`4_p=LjtQiE zOg#SSs)?lG$f6}=vd>cfQ#v9YfGUDIanqO!l@fGRhneda^xET53W(CHWlJa>ozxfo zTPO45j-+LQcDR5AS7p&f8?WMcwG6fc=^suKNp+-(ku3o^H6RG{?JDHQ`sJ7Xz7l2S zJn+*;pHntE07~`x@RO%YB=+eXrF;|0&(T^rwr%U*7&#;5!zT(sY0wFLt0_-=qJo$* zt4UZHBvO5ffPQ1K#|$Km6A+BLd&9PkdI)Ojue01iP|Wnzkw*)D2Wf16d`vfrftf_z zAImK@qpA|7(`tq)ow!=59j2ED*gF%9kLu%v0WPX#NU9ZABri+?Iv@CU;gU*H5@i{| z`3w`oCrTi1yo9F-Ev(1%HJf}t=6Vfb`E%ZHuQLWx#cYH4Ma3`)(PTPPU%6Z7GTN)shz zB<`+ENsQwp<3EAVw-q^A3s#oYcMS)r=|(okubjb#g(EIUl5EMQm31+9$ zw>=TeT`Om5s!3`nF08S*l_rhRDpauCyOE9y90EpL0P%eLNSqyaWKSeIAztb&k zLc~iTbAng%{{S93Vp}&0mX0M;erCvzt7R*IJ{}Np^Vm4#DSQjI#Qy-4``JYa$l}y0 z*gFBjNqxDK)TFB~sYv!CsNp1>ZwiTctvK4PD=-7wJ%7CLl1bJ~zDG~543coCy;M_d z5aKeOn0NeshlYgmo+vNZJB>sX{{R~#j_d$eV~>|#kox0Ay(}e{o36`=7nQ{i;g|qj)x)FoKBZ7H^ z%Uc~>YTj!41_FWd@7o+P3FSv>ows-E?0@IOM+C)TE0;r@ zjQbyMCuG{FUbDIUENL1(WrA9H9-!=T(xZM}N?`;ITA8Qat<>mS>6a4K(Ee0o_xSdq7l= self.length) { + self.ended = true; + return self.emit('end'); + } + var end = Math.min(self.offset + self.trickle, self.length); + var c = self.chunk.slice(self.offset, end); + self.offset += c.length; + self.emit('data', c); + process.nextTick(emit); + } +}; + +SlowStream.prototype.end = function(chunk) { + // walk over the chunk in blocks. + var self = this; + self.chunk = chunk; + self.length = chunk.length; + self.resume(); + return self.ended; +}; + + + +// for each of the files, make sure that compressing and +// decompressing results in the same data, for every combination +// of the options set above. +var tape = require('tape'); + +Object.keys(tests).forEach(function(file) { + var test = tests[file]; + chunkSize.forEach(function(chunkSize) { + trickle.forEach(function(trickle) { + windowBits.forEach(function(windowBits) { + level.forEach(function(level) { + memLevel.forEach(function(memLevel) { + strategy.forEach(function(strategy) { + zlibPairs.forEach(function(pair) { + var Def = pair[0]; + var Inf = pair[1]; + var opts = { + level: level, + windowBits: windowBits, + memLevel: memLevel, + strategy: strategy + }; + + var msg = file + ' ' + + chunkSize + ' ' + + JSON.stringify(opts) + ' ' + + Def.name + ' -> ' + Inf.name; + + tape('zlib ' + msg, function(t) { + t.plan(1); + + var def = new Def(opts); + var inf = new Inf(opts); + var ss = new SlowStream(trickle); + var buf = new BufferStream(); + + // verify that the same exact buffer comes out the other end. + buf.on('data', function(c) { + t.deepEqual(c, test); + }); + + // the magic happens here. + ss.pipe(def).pipe(inf).pipe(buf); + ss.end(test); + }); + }); + }); + }); + }); + }); + }); + }); +}); diff --git a/node_modules/builtin-modules/builtin-modules.json b/node_modules/builtin-modules/builtin-modules.json new file mode 100644 index 0000000..72670f6 --- /dev/null +++ b/node_modules/builtin-modules/builtin-modules.json @@ -0,0 +1,35 @@ +[ + "assert", + "buffer", + "child_process", + "cluster", + "console", + "constants", + "crypto", + "dgram", + "dns", + "domain", + "events", + "fs", + "http", + "https", + "module", + "net", + "os", + "path", + "process", + "punycode", + "querystring", + "readline", + "repl", + "stream", + "string_decoder", + "timers", + "tls", + "tty", + "url", + "util", + "v8", + "vm", + "zlib" +] diff --git a/node_modules/builtin-modules/index.js b/node_modules/builtin-modules/index.js new file mode 100644 index 0000000..9ef35ab --- /dev/null +++ b/node_modules/builtin-modules/index.js @@ -0,0 +1,10 @@ +'use strict'; + +var blacklist = [ + 'freelist', + 'sys' +]; + +module.exports = Object.keys(process.binding('natives')).filter(function (el) { + return !/^_|^internal|\//.test(el) && blacklist.indexOf(el) === -1; +}).sort(); diff --git a/node_modules/builtin-modules/license b/node_modules/builtin-modules/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/builtin-modules/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/builtin-modules/package.json b/node_modules/builtin-modules/package.json new file mode 100644 index 0000000..4eb30b1 --- /dev/null +++ b/node_modules/builtin-modules/package.json @@ -0,0 +1,104 @@ +{ + "_args": [ + [ + { + "raw": "builtin-modules@^1.0.0", + "scope": null, + "escapedName": "builtin-modules", + "name": "builtin-modules", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/is-builtin-module" + ] + ], + "_from": "builtin-modules@>=1.0.0 <2.0.0", + "_id": "builtin-modules@1.1.1", + "_inCache": true, + "_location": "/builtin-modules", + "_nodeVersion": "5.3.0", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "3.3.12", + "_phantomChildren": {}, + "_requested": { + "raw": "builtin-modules@^1.0.0", + "scope": null, + "escapedName": "builtin-modules", + "name": "builtin-modules", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/is-builtin-module" + ], + "_resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "_shasum": "270f076c5a72c02f5b65a47df94c5fe3a278892f", + "_shrinkwrap": null, + "_spec": "builtin-modules@^1.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/is-builtin-module", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/builtin-modules/issues" + }, + "dependencies": {}, + "description": "List of the Node.js builtin modules", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "270f076c5a72c02f5b65a47df94c5fe3a278892f", + "tarball": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js", + "static.js", + "builtin-modules.json" + ], + "gitHead": "0ea253452b1d8cb3a70d16464f909dbc0bc370fe", + "homepage": "https://github.com/sindresorhus/builtin-modules#readme", + "keywords": [ + "builtin", + "built-in", + "builtins", + "node", + "modules", + "core", + "bundled", + "list", + "array", + "names" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "builtin-modules", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/builtin-modules.git" + }, + "scripts": { + "make": "node make.js", + "test": "xo && ava" + }, + "version": "1.1.1" +} diff --git a/node_modules/builtin-modules/readme.md b/node_modules/builtin-modules/readme.md new file mode 100644 index 0000000..f1894b1 --- /dev/null +++ b/node_modules/builtin-modules/readme.md @@ -0,0 +1,41 @@ +# builtin-modules [![Build Status](https://travis-ci.org/sindresorhus/builtin-modules.svg?branch=master)](https://travis-ci.org/sindresorhus/builtin-modules) + +> List of the Node.js builtin modules + +The list is just a [JSON file](builtin-modules.json) and can be used wherever. + + +## Install + +``` +$ npm install --save builtin-modules +``` + + +## Usage + +```js +var builtinModules = require('builtin-modules'); + +console.log(builinModules); +//=> ['assert', 'buffer', ...] +``` + + +## API + +Returns an array of builtin modules fetched from the running Node.js version. + +### Static list + +This module also comes bundled with a static array of builtin modules generated from the latest Node.js version. You can get it with `require('builtin-modules/static');` + + +## Related + +- [is-builtin-module](https://github.com/sindresorhus/is-builtin-module) - Check if a string matches the name of a Node.js builtin module + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/builtin-modules/static.js b/node_modules/builtin-modules/static.js new file mode 100644 index 0000000..9508f8f --- /dev/null +++ b/node_modules/builtin-modules/static.js @@ -0,0 +1,2 @@ +'use strict'; +module.exports = require('./builtin-modules.json'); diff --git a/node_modules/camelcase-keys/index.js b/node_modules/camelcase-keys/index.js new file mode 100644 index 0000000..0eca08c --- /dev/null +++ b/node_modules/camelcase-keys/index.js @@ -0,0 +1,12 @@ +'use strict'; +var mapObj = require('map-obj'); +var camelCase = require('camelcase'); + +module.exports = function (input, options) { + options = options || {}; + var exclude = options.exclude || []; + return mapObj(input, function (key, val) { + key = exclude.indexOf(key) === -1 ? camelCase(key) : key; + return [key, val]; + }); +}; diff --git a/node_modules/camelcase-keys/license b/node_modules/camelcase-keys/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/camelcase-keys/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/camelcase-keys/package.json b/node_modules/camelcase-keys/package.json new file mode 100644 index 0000000..5471b30 --- /dev/null +++ b/node_modules/camelcase-keys/package.json @@ -0,0 +1,119 @@ +{ + "_args": [ + [ + { + "raw": "camelcase-keys@^2.0.0", + "scope": null, + "escapedName": "camelcase-keys", + "name": "camelcase-keys", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/meow" + ] + ], + "_from": "camelcase-keys@>=2.0.0 <3.0.0", + "_id": "camelcase-keys@2.1.0", + "_inCache": true, + "_location": "/camelcase-keys", + "_nodeVersion": "4.3.0", + "_npmOperationalInternal": { + "host": "packages-13-west.internal.npmjs.com", + "tmp": "tmp/camelcase-keys-2.1.0.tgz_1458051723517_0.14490422373637557" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.14.12", + "_phantomChildren": {}, + "_requested": { + "raw": "camelcase-keys@^2.0.0", + "scope": null, + "escapedName": "camelcase-keys", + "name": "camelcase-keys", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/meow" + ], + "_resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "_shasum": "308beeaffdf28119051efa1d932213c91b8f92e7", + "_shrinkwrap": null, + "_spec": "camelcase-keys@^2.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/meow", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/camelcase-keys/issues" + }, + "dependencies": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "description": "Convert object keys to camelCase", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "308beeaffdf28119051efa1d932213c91b8f92e7", + "tarball": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "d92dfb3b5eb2985d62839cdd44672f01139d1822", + "homepage": "https://github.com/sindresorhus/camelcase-keys", + "keywords": [ + "map", + "obj", + "object", + "key", + "keys", + "value", + "values", + "val", + "iterate", + "camelcase", + "camel-case", + "camel", + "case", + "dash", + "hyphen", + "dot", + "underscore", + "separator", + "string", + "text", + "convert" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "camelcase-keys", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/camelcase-keys.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "2.1.0" +} diff --git a/node_modules/camelcase-keys/readme.md b/node_modules/camelcase-keys/readme.md new file mode 100644 index 0000000..ca37328 --- /dev/null +++ b/node_modules/camelcase-keys/readme.md @@ -0,0 +1,54 @@ +# camelcase-keys [![Build Status](https://travis-ci.org/sindresorhus/camelcase-keys.svg?branch=master)](https://travis-ci.org/sindresorhus/camelcase-keys) + +> Convert object keys to camelCase using [`camelcase`](https://github.com/sindresorhus/camelcase) + + +## Install + +``` +$ npm install --save camelcase-keys +``` + + +## Usage + +```js +const camelcaseKeys = require('camelcase-keys'); + +camelcaseKeys({'foo-bar': true}); +//=> {fooBar: true} + + +const argv = require('minimist')(process.argv.slice(2)); +//=> {_: [], 'foo-bar': true} + +camelcaseKeys(argv); +//=> {_: [], fooBar: true} +``` + + +## API + +### camelcaseKeys(input, [options]) + +#### input + +Type: `object` + +Object to camelCase. + +#### options + +Type: `object` + +##### exclude + +Type: `array` +Default: `[]` + +Exclude keys from being camelCased. + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/camelcase/index.js b/node_modules/camelcase/index.js new file mode 100644 index 0000000..929facb --- /dev/null +++ b/node_modules/camelcase/index.js @@ -0,0 +1,56 @@ +'use strict'; + +function preserveCamelCase(str) { + var isLastCharLower = false; + + for (var i = 0; i < str.length; i++) { + var c = str.charAt(i); + + if (isLastCharLower && (/[a-zA-Z]/).test(c) && c.toUpperCase() === c) { + str = str.substr(0, i) + '-' + str.substr(i); + isLastCharLower = false; + i++; + } else { + isLastCharLower = (c.toLowerCase() === c); + } + } + + return str; +} + +module.exports = function () { + var str = [].map.call(arguments, function (str) { + return str.trim(); + }).filter(function (str) { + return str.length; + }).join('-'); + + if (!str.length) { + return ''; + } + + if (str.length === 1) { + return str; + } + + if (!(/[_.\- ]+/).test(str)) { + if (str === str.toUpperCase()) { + return str.toLowerCase(); + } + + if (str[0] !== str[0].toLowerCase()) { + return str[0].toLowerCase() + str.slice(1); + } + + return str; + } + + str = preserveCamelCase(str); + + return str + .replace(/^[_.\- ]+/, '') + .toLowerCase() + .replace(/[_.\- ]+(\w|$)/g, function (m, p1) { + return p1.toUpperCase(); + }); +}; diff --git a/node_modules/camelcase/license b/node_modules/camelcase/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/camelcase/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/camelcase/package.json b/node_modules/camelcase/package.json new file mode 100644 index 0000000..ee969e4 --- /dev/null +++ b/node_modules/camelcase/package.json @@ -0,0 +1,107 @@ +{ + "_args": [ + [ + { + "raw": "camelcase@^2.0.0", + "scope": null, + "escapedName": "camelcase", + "name": "camelcase", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/camelcase-keys" + ] + ], + "_from": "camelcase@>=2.0.0 <3.0.0", + "_id": "camelcase@2.1.1", + "_inCache": true, + "_location": "/camelcase", + "_nodeVersion": "4.3.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/camelcase-2.1.1.tgz_1457803836074_0.4515206723008305" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.14.12", + "_phantomChildren": {}, + "_requested": { + "raw": "camelcase@^2.0.0", + "scope": null, + "escapedName": "camelcase", + "name": "camelcase", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/camelcase-keys" + ], + "_resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "_shasum": "7c1d16d679a1bbe59ca02cacecfb011e201f5a1f", + "_shrinkwrap": null, + "_spec": "camelcase@^2.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/camelcase-keys", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/camelcase/issues" + }, + "dependencies": {}, + "description": "Convert a dash/dot/underscore/space separated string to camelCase: foo-bar → fooBar", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "7c1d16d679a1bbe59ca02cacecfb011e201f5a1f", + "tarball": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "35c9c8abce5b9cc9defe534ab25823dc6383180f", + "homepage": "https://github.com/sindresorhus/camelcase", + "keywords": [ + "camelcase", + "camel-case", + "camel", + "case", + "dash", + "hyphen", + "dot", + "underscore", + "separator", + "string", + "text", + "convert" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "camelcase", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/camelcase.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "2.1.1" +} diff --git a/node_modules/camelcase/readme.md b/node_modules/camelcase/readme.md new file mode 100644 index 0000000..080b2a1 --- /dev/null +++ b/node_modules/camelcase/readme.md @@ -0,0 +1,57 @@ +# camelcase [![Build Status](https://travis-ci.org/sindresorhus/camelcase.svg?branch=master)](https://travis-ci.org/sindresorhus/camelcase) + +> Convert a dash/dot/underscore/space separated string to camelCase: `foo-bar` → `fooBar` + + +## Install + +``` +$ npm install --save camelcase +``` + + +## Usage + +```js +const camelCase = require('camelcase'); + +camelCase('foo-bar'); +//=> 'fooBar' + +camelCase('foo_bar'); +//=> 'fooBar' + +camelCase('Foo-Bar'); +//=> 'fooBar' + +camelCase('--foo.bar'); +//=> 'fooBar' + +camelCase('__foo__bar__'); +//=> 'fooBar' + +camelCase('foo bar'); +//=> 'fooBar' + +console.log(process.argv[3]); +//=> '--foo-bar' +camelCase(process.argv[3]); +//=> 'fooBar' + +camelCase('foo', 'bar'); +//=> 'fooBar' + +camelCase('__foo__', '--bar'); +//=> 'fooBar' +``` + + +## Related + +- [decamelize](https://github.com/sindresorhus/decamelize) - The inverse of this module +- [uppercamelcase](https://github.com/SamVerschueren/uppercamelcase) - Like this module, but to PascalCase instead of camelCase + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/center-align/LICENSE b/node_modules/center-align/LICENSE new file mode 100644 index 0000000..65f90ac --- /dev/null +++ b/node_modules/center-align/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/center-align/README.md b/node_modules/center-align/README.md new file mode 100644 index 0000000..cbcf3be --- /dev/null +++ b/node_modules/center-align/README.md @@ -0,0 +1,74 @@ +# center-align [![NPM version](https://badge.fury.io/js/center-align.svg)](http://badge.fury.io/js/center-align) + +> Center-align the text in a string. + +Install with [npm](https://www.npmjs.com/) + +```sh +$ npm i center-align --save +``` + +## Usage + +```js +var centerAlign = require('center-align'); +``` + +**Example** + +If used on the following: + +``` +Lorem ipsum dolor sit amet, +consectetur adipiscing +elit, sed do eiusmod tempor incididunt +ut labore et dolore +magna aliqua. Ut enim ad minim +veniam, quis +``` + +The result would be: + +``` + Lorem ipsum dolor sit amet, + consectetur adipiscing +elit, sed do eiusmod tempor incididunt + ut labore et dolore + magna aliqua. Ut enim ad minim + veniam, quis +``` + +## Related projects + +* [align-text](https://www.npmjs.com/package/align-text): Align the text in a string. | [homepage](https://github.com/jonschlinkert/align-text) +* [justified](https://www.npmjs.com/package/justified): Wrap words to a specified length and justified the text. | [homepage](https://github.com/jonschlinkert/justified) +* [right-align](https://www.npmjs.com/package/right-align): Right-align the text in a string. | [homepage](https://github.com/jonschlinkert/right-align) +* [word-wrap](https://www.npmjs.com/package/word-wrap): Wrap words to a specified length. | [homepage](https://github.com/jonschlinkert/word-wrap) + +## Running tests + +Install dev dependencies: + +```sh +$ npm i -d && npm test +``` + +## Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/center-align/issues/new). + +## Author + +**Jon Schlinkert** + ++ [github/jonschlinkert](https://github.com/jonschlinkert) ++ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License + +Copyright © 2015 Jon Schlinkert +Released under the MIT license. + +*** + +_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on October 27, 2015._ \ No newline at end of file diff --git a/node_modules/center-align/index.js b/node_modules/center-align/index.js new file mode 100644 index 0000000..c6ed54a --- /dev/null +++ b/node_modules/center-align/index.js @@ -0,0 +1,16 @@ +/*! + * center-align + * + * Copycenter (c) 2015, Jon Schlinkert. + * Licensed under the MIT License. + */ + +'use strict'; + +var utils = require('./utils'); + +module.exports = function centerAlign(val) { + return utils.align(val, function (len, longest) { + return Math.floor((longest - len) / 2); + }); +}; diff --git a/node_modules/center-align/package.json b/node_modules/center-align/package.json new file mode 100644 index 0000000..32bfe11 --- /dev/null +++ b/node_modules/center-align/package.json @@ -0,0 +1,121 @@ +{ + "_args": [ + [ + { + "raw": "center-align@^0.1.1", + "scope": null, + "escapedName": "center-align", + "name": "center-align", + "rawSpec": "^0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/cliui" + ] + ], + "_from": "center-align@>=0.1.1 <0.2.0", + "_id": "center-align@0.1.3", + "_inCache": true, + "_location": "/center-align", + "_nodeVersion": "5.3.0", + "_npmOperationalInternal": { + "host": "packages-9-west.internal.npmjs.com", + "tmp": "tmp/center-align-0.1.3.tgz_1454366538829_0.9471865000668913" + }, + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.3.12", + "_phantomChildren": {}, + "_requested": { + "raw": "center-align@^0.1.1", + "scope": null, + "escapedName": "center-align", + "name": "center-align", + "rawSpec": "^0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/cliui" + ], + "_resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "_shasum": "aa0d32629b6ee972200411cbd4461c907bc2b7ad", + "_shrinkwrap": null, + "_spec": "center-align@^0.1.1", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/cliui", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/center-align/issues" + }, + "dependencies": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + }, + "description": "Center-align the text in a string.", + "devDependencies": { + "mocha": "^2.2.0" + }, + "directories": {}, + "dist": { + "shasum": "aa0d32629b6ee972200411cbd4461c907bc2b7ad", + "tarball": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js", + "utils.js" + ], + "gitHead": "5c5fab5012fceaa3e21a00162958c0ed11109419", + "homepage": "https://github.com/jonschlinkert/center-align", + "keywords": [ + "align", + "align-center", + "center", + "center-align", + "right", + "right-align", + "text", + "typography" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "doowb", + "email": "brian.woodward@gmail.com" + }, + { + "name": "jonschlinkert", + "email": "github@sellside.com" + } + ], + "name": "center-align", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/center-align.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "related": { + "description": "", + "list": [ + "align-text", + "right-align", + "justified", + "word-wrap" + ] + } + }, + "version": "0.1.3" +} diff --git a/node_modules/center-align/utils.js b/node_modules/center-align/utils.js new file mode 100644 index 0000000..aead6d2 --- /dev/null +++ b/node_modules/center-align/utils.js @@ -0,0 +1,40 @@ +'use strict'; + +/** + * Lazily-required module dependencies (makes the application + * faster) + */ + +var utils = require('lazy-cache')(require); + +/** + * Temporarily re-assign `require` to trick browserify and + * webpack into reconizing lazy dependencies. + * + * This tiny bit of ugliness has the huge dual advantage of + * only loading modules that are actually called at some + * point in the lifecycle of the application, whilst also + * allowing browserify and webpack to find modules that + * are depended on but never actually called. + */ + +var fn = require; +require = utils; + +/** + * Lazily required module dependencies + */ + +require('align-text', 'align'); + +/** + * Restore `require` + */ + +require = fn; + +/** + * Expose `utils` modules + */ + +module.exports = utils; diff --git a/node_modules/chalk/index.js b/node_modules/chalk/index.js new file mode 100644 index 0000000..2d85a91 --- /dev/null +++ b/node_modules/chalk/index.js @@ -0,0 +1,116 @@ +'use strict'; +var escapeStringRegexp = require('escape-string-regexp'); +var ansiStyles = require('ansi-styles'); +var stripAnsi = require('strip-ansi'); +var hasAnsi = require('has-ansi'); +var supportsColor = require('supports-color'); +var defineProps = Object.defineProperties; +var isSimpleWindowsTerm = process.platform === 'win32' && !/^xterm/i.test(process.env.TERM); + +function Chalk(options) { + // detect mode if not set manually + this.enabled = !options || options.enabled === undefined ? supportsColor : options.enabled; +} + +// use bright blue on Windows as the normal blue color is illegible +if (isSimpleWindowsTerm) { + ansiStyles.blue.open = '\u001b[94m'; +} + +var styles = (function () { + var ret = {}; + + Object.keys(ansiStyles).forEach(function (key) { + ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); + + ret[key] = { + get: function () { + return build.call(this, this._styles.concat(key)); + } + }; + }); + + return ret; +})(); + +var proto = defineProps(function chalk() {}, styles); + +function build(_styles) { + var builder = function () { + return applyStyle.apply(builder, arguments); + }; + + builder._styles = _styles; + builder.enabled = this.enabled; + // __proto__ is used because we must return a function, but there is + // no way to create a function with a different prototype. + /* eslint-disable no-proto */ + builder.__proto__ = proto; + + return builder; +} + +function applyStyle() { + // support varags, but simply cast to string in case there's only one arg + var args = arguments; + var argsLen = args.length; + var str = argsLen !== 0 && String(arguments[0]); + + if (argsLen > 1) { + // don't slice `arguments`, it prevents v8 optimizations + for (var a = 1; a < argsLen; a++) { + str += ' ' + args[a]; + } + } + + if (!this.enabled || !str) { + return str; + } + + var nestedStyles = this._styles; + var i = nestedStyles.length; + + // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, + // see https://github.com/chalk/chalk/issues/58 + // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. + var originalDim = ansiStyles.dim.open; + if (isSimpleWindowsTerm && (nestedStyles.indexOf('gray') !== -1 || nestedStyles.indexOf('grey') !== -1)) { + ansiStyles.dim.open = ''; + } + + while (i--) { + var code = ansiStyles[nestedStyles[i]]; + + // Replace any instances already present with a re-opening code + // otherwise only the part of the string until said closing code + // will be colored, and the rest will simply be 'plain'. + str = code.open + str.replace(code.closeRe, code.open) + code.close; + } + + // Reset the original 'dim' if we changed it to work around the Windows dimmed gray issue. + ansiStyles.dim.open = originalDim; + + return str; +} + +function init() { + var ret = {}; + + Object.keys(styles).forEach(function (name) { + ret[name] = { + get: function () { + return build.call(this, [name]); + } + }; + }); + + return ret; +} + +defineProps(Chalk.prototype, init()); + +module.exports = new Chalk(); +module.exports.styles = ansiStyles; +module.exports.hasColor = hasAnsi; +module.exports.stripColor = stripAnsi; +module.exports.supportsColor = supportsColor; diff --git a/node_modules/chalk/license b/node_modules/chalk/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/chalk/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/chalk/package.json b/node_modules/chalk/package.json new file mode 100644 index 0000000..05ae886 --- /dev/null +++ b/node_modules/chalk/package.json @@ -0,0 +1,146 @@ +{ + "_args": [ + [ + { + "raw": "chalk@^1.0.0", + "scope": null, + "escapedName": "chalk", + "name": "chalk", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "/home/vagrant/projects/legislature-tracker/node_modules/grunt-contrib-concat" + ] + ], + "_from": "chalk@>=1.0.0 <2.0.0", + "_id": "chalk@1.1.3", + "_inCache": true, + "_location": "/chalk", + "_nodeVersion": "0.10.32", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/chalk-1.1.3.tgz_1459210604109_0.3892582862172276" + }, + "_npmUser": { + "name": "qix", + "email": "i.am.qix@gmail.com" + }, + "_npmVersion": "2.14.2", + "_phantomChildren": {}, + "_requested": { + "raw": "chalk@^1.0.0", + "scope": null, + "escapedName": "chalk", + "name": "chalk", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/grunt-contrib-concat", + "/grunt-contrib-copy", + "/grunt-contrib-jshint", + "/grunt-contrib-jst", + "/grunt-contrib-uglify", + "/grunt-sftp-deploy/grunt-legacy-log-utils", + "/maxmin" + ], + "_resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "_shasum": "a8115c55e4a702fe4d150abd3872822a7e09fc98", + "_shrinkwrap": null, + "_spec": "chalk@^1.0.0", + "_where": "/home/vagrant/projects/legislature-tracker/node_modules/grunt-contrib-concat", + "bugs": { + "url": "https://github.com/chalk/chalk/issues" + }, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "description": "Terminal string styling done right. Much color.", + "devDependencies": { + "coveralls": "^2.11.2", + "matcha": "^0.6.0", + "mocha": "*", + "nyc": "^3.0.0", + "require-uncached": "^1.0.2", + "resolve-from": "^1.0.0", + "semver": "^4.3.3", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "a8115c55e4a702fe4d150abd3872822a7e09fc98", + "tarball": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "0d8d8c204eb87a4038219131ad4d8369c9f59d24", + "homepage": "https://github.com/chalk/chalk#readme", + "keywords": [ + "color", + "colour", + "colors", + "terminal", + "console", + "cli", + "string", + "str", + "ansi", + "style", + "styles", + "tty", + "formatting", + "rgb", + "256", + "shell", + "xterm", + "log", + "logging", + "command-line", + "text" + ], + "license": "MIT", + "maintainers": [ + { + "name": "qix", + "email": "i.am.qix@gmail.com" + }, + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + { + "name": "unicorn", + "email": "sindresorhus+unicorn@gmail.com" + } + ], + "name": "chalk", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/chalk/chalk.git" + }, + "scripts": { + "bench": "matcha benchmark.js", + "coverage": "nyc npm test && nyc report", + "coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls", + "test": "xo && mocha" + }, + "version": "1.1.3", + "xo": { + "envs": [ + "node", + "mocha" + ] + } +} diff --git a/node_modules/chalk/readme.md b/node_modules/chalk/readme.md new file mode 100644 index 0000000..5cf111e --- /dev/null +++ b/node_modules/chalk/readme.md @@ -0,0 +1,213 @@ +